4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 only,
8 * as published by the Free Software Foundation.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License version 2 for more details. A copy is
14 * included in the COPYING file that accompanied this code.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 * Copyright (c) 2012, Intel Corporation.
24 * Use is subject to license terms.
25 * Copyright (c) 2011, 2012 Commissariat a l'energie atomique et aux energies
29 * lustre/mdt/mdt_hsm.c
31 * Lustre Metadata Target (mdt) request handler
33 * Author: Aurelien Degremont <aurelien.degremont@cea.fr>
34 * Author: JC Lafoucriere <jacques-charles.lafoucriere@cea.fr>
38 # define EXPORT_SYMTAB
40 #define DEBUG_SUBSYSTEM S_MDS
42 #include "mdt_internal.h"
45 * fake functions, will be replace by real one with HSM Coordinator patch
48 int mdt_hsm_copytool_send(struct obd_export *exp)
53 static int mdt_hsm_coordinator_update(struct mdt_thread_info *info,
54 struct hsm_progress_kernel *pgs)
59 static int mdt_hsm_agent_register_mask(struct mdt_thread_info *info,
60 struct obd_uuid *uuid,
66 static int mdt_hsm_agent_unregister(struct mdt_thread_info *info,
67 struct obd_uuid *uuid)
73 * Update on-disk HSM attributes.
75 int mdt_hsm_attr_set(struct mdt_thread_info *info, struct mdt_object *obj,
78 struct md_object *next = mdt_object_child(obj);
79 struct lu_buf *buf = &info->mti_buf;
80 struct hsm_attrs *attrs;
84 attrs = (struct hsm_attrs *)info->mti_xattr_buf;
85 CLASSERT(sizeof(info->mti_xattr_buf) >= sizeof(*attrs));
87 /* pack HSM attributes */
88 lustre_hsm2buf(info->mti_xattr_buf, mh);
90 /* update SOM attributes */
92 buf->lb_len = sizeof(*attrs);
93 rc = mo_xattr_set(info->mti_env, next, buf, XATTR_NAME_HSM, 0);
99 * Extract information coming from a copytool and asks coordinator to update
100 * a request status depending on the update content.
102 * Copytools could use this to report failure in their process.
104 * This is HSM_PROGRESS RPC handler.
106 int mdt_hsm_progress(struct mdt_thread_info *info)
108 struct hsm_progress_kernel *hpk;
112 hpk = req_capsule_client_get(info->mti_pill, &RMF_MDS_HSM_PROGRESS);
115 CDEBUG(D_HSM, "Progress on "DFID": len="LPU64" err=%d\n",
116 PFID(&hpk->hpk_fid), hpk->hpk_extent.length, hpk->hpk_errval);
119 CDEBUG(D_HSM, "Copytool progress on "DFID" failed (%d); %s.\n",
120 PFID(&hpk->hpk_fid), hpk->hpk_errval,
121 hpk->hpk_flags & HP_FLAG_RETRY ? "will retry" : "fatal");
123 if (hpk->hpk_flags & HP_FLAG_COMPLETED)
124 CDEBUG(D_HSM, "Finished "DFID" (%d) cancel cookie="LPX64"\n",
125 PFID(&hpk->hpk_fid), hpk->hpk_errval, hpk->hpk_cookie);
127 rc = mdt_hsm_coordinator_update(info, hpk);
132 int mdt_hsm_ct_register(struct mdt_thread_info *info)
134 struct ptlrpc_request *req = mdt_info_req(info);
139 archives = req_capsule_client_get(info->mti_pill, &RMF_MDS_HSM_ARCHIVE);
142 /* XXX: directly include this function here? */
143 rc = mdt_hsm_agent_register_mask(info, &req->rq_export->exp_client_uuid,
149 int mdt_hsm_ct_unregister(struct mdt_thread_info *info)
151 struct ptlrpc_request *req = mdt_info_req(info);
155 /* XXX: directly include this function here? */
156 rc = mdt_hsm_agent_unregister(info, &req->rq_export->exp_client_uuid);
163 * Retrieve the current HSM flags, archive id and undergoing HSM requests for
164 * the fid provided in RPC body.
166 * Current requests are read from coordinator states.
168 * This is MDS_HSM_STATE_GET RPC handler.
170 int mdt_hsm_state_get(struct mdt_thread_info *info)
172 struct mdt_object *obj = info->mti_object;
173 struct md_attr *ma = &info->mti_attr;
174 struct hsm_user_state *hus;
175 struct mdt_lock_handle *lh;
179 lh = &info->mti_lh[MDT_LH_CHILD];
180 mdt_lock_reg_init(lh, LCK_PR);
181 rc = mdt_object_lock(info, obj, lh, MDS_INODELOCK_LOOKUP,
186 /* Only valid if client is remote */
187 rc = mdt_init_ucred(info, (struct mdt_body *)info->mti_body);
189 GOTO(out_unlock, rc = err_serious(rc));
192 ma->ma_need = MA_HSM;
193 rc = mdt_attr_get_complex(info, obj, ma);
197 if (req_capsule_get_size(info->mti_pill, &RMF_CAPA1, RCL_CLIENT))
198 mdt_set_capainfo(info, 0, &info->mti_body->fid1,
199 req_capsule_client_get(info->mti_pill, &RMF_CAPA1));
201 hus = req_capsule_server_get(info->mti_pill, &RMF_HSM_USER_STATE);
204 /* Current HSM flags */
205 hus->hus_states = ma->ma_hsm.mh_flags;
206 hus->hus_archive_id = ma->ma_hsm.mh_arch_id;
210 mdt_exit_ucred(info);
212 mdt_object_unlock(info, obj, lh, 1);
217 * Change HSM state and archive number of a file.
219 * Archive number is changed iif the value is not 0.
220 * The new flagset that will be computed should result in a coherent state.
221 * This function checks that are flags are compatible.
223 * This is MDS_HSM_STATE_SET RPC handler.
225 int mdt_hsm_state_set(struct mdt_thread_info *info)
227 struct mdt_object *obj = info->mti_object;
228 struct md_attr *ma = &info->mti_attr;
229 struct hsm_state_set *hss;
230 struct mdt_lock_handle *lh;
235 lh = &info->mti_lh[MDT_LH_CHILD];
236 mdt_lock_reg_init(lh, LCK_PW);
237 rc = mdt_object_lock(info, obj, lh, MDS_INODELOCK_LOOKUP,
242 /* Only valid if client is remote */
243 rc = mdt_init_ucred(info, (struct mdt_body *)info->mti_body);
245 GOTO(out_obj, rc = err_serious(rc));
247 /* Read current HSM info */
249 ma->ma_need = MA_HSM;
250 rc = mdt_attr_get_complex(info, obj, ma);
254 hss = req_capsule_client_get(info->mti_pill, &RMF_HSM_STATE_SET);
257 if (req_capsule_get_size(info->mti_pill, &RMF_CAPA1, RCL_CLIENT))
258 mdt_set_capainfo(info, 0, &info->mti_body->fid1,
259 req_capsule_client_get(info->mti_pill, &RMF_CAPA1));
261 /* Change HSM flags depending on provided masks */
262 if (hss->hss_valid & HSS_SETMASK)
263 ma->ma_hsm.mh_flags |= hss->hss_setmask;
264 if (hss->hss_valid & HSS_CLEARMASK)
265 ma->ma_hsm.mh_flags &= ~hss->hss_clearmask;
267 /* Change archive_id if provided. */
268 if (hss->hss_valid & HSS_ARCHIVE_ID) {
269 if (!(ma->ma_hsm.mh_flags & HS_EXISTS)) {
270 CDEBUG(D_HSM, "Could not set an archive number for "
271 DFID "if HSM EXISTS flag is not set.\n",
272 PFID(&info->mti_body->fid1));
275 ma->ma_hsm.mh_arch_id = hss->hss_archive_id;
278 /* Check for inconsistant HSM flagset.
279 * DIRTY without EXISTS: no dirty if no archive was created.
280 * DIRTY and RELEASED: a dirty file could not be released.
281 * RELEASED without ARCHIVED: do not release a non-archived file.
282 * LOST without ARCHIVED: cannot lost a non-archived file.
284 flags = ma->ma_hsm.mh_flags;
285 if (((flags & HS_DIRTY) && !(flags & HS_EXISTS)) ||
286 ((flags & HS_RELEASED) && (flags & HS_DIRTY)) ||
287 ((flags & HS_RELEASED) && !(flags & HS_ARCHIVED)) ||
288 ((flags & HS_LOST) && !(flags & HS_ARCHIVED))) {
289 CDEBUG(D_HSM, "Incompatible flag change on "DFID
291 PFID(&info->mti_body->fid1), flags);
292 GOTO(out_ucred, rc = -EINVAL);
295 /* Save the modified flags */
296 rc = mdt_hsm_attr_set(info, obj, &ma->ma_hsm);
303 mdt_exit_ucred(info);
305 mdt_object_unlock(info, obj, lh, 1);