lum_size = sizeof(struct lov_user_md_v3);
break;
}
+ case LMV_USER_MAGIC: {
+ if (lump->lmm_magic != cpu_to_le32(LMV_USER_MAGIC))
+ lustre_swab_lmv_user_md(
+ (struct lmv_user_md *)lump);
+ lum_size = sizeof(struct lmv_user_md);
+ break;
+ }
default: {
CDEBUG(D_IOCTL, "bad userland LOV MAGIC:"
" %#08x != %#08x nor %#08x\n",
RETURN(rc);
}
-int ll_dir_getstripe(struct inode *inode, struct lov_mds_md **lmmp,
- int *lmm_size, struct ptlrpc_request **request)
+/**
+ * This function will be used to get default LOV/LMV/Default LMV
+ * @valid will be used to indicate which stripe it will retrieve
+ * OBD_MD_MEA LMV stripe EA
+ * OBD_MD_DEFAULT_MEA Default LMV stripe EA
+ * otherwise Default LOV EA.
+ * Each time, it can only retrieve 1 stripe EA
+ **/
+int ll_dir_getstripe(struct inode *inode, void **plmm, int *plmm_size,
+ struct ptlrpc_request **request, obd_valid valid)
{
- struct ll_sb_info *sbi = ll_i2sbi(inode);
- struct mdt_body *body;
- struct lov_mds_md *lmm = NULL;
- struct ptlrpc_request *req = NULL;
- int rc, lmmsize;
- struct md_op_data *op_data;
+ struct ll_sb_info *sbi = ll_i2sbi(inode);
+ struct mdt_body *body;
+ struct lov_mds_md *lmm = NULL;
+ struct ptlrpc_request *req = NULL;
+ int rc, lmm_size;
+ struct md_op_data *op_data;
+ ENTRY;
- rc = ll_get_max_mdsize(sbi, &lmmsize);
- if (rc)
- RETURN(rc);
+ rc = ll_get_max_mdsize(sbi, &lmm_size);
+ if (rc)
+ RETURN(rc);
- op_data = ll_prep_md_op_data(NULL, inode, NULL, NULL,
- 0, lmmsize, LUSTRE_OPC_ANY,
- NULL);
- if (IS_ERR(op_data))
- RETURN(PTR_ERR(op_data));
+ op_data = ll_prep_md_op_data(NULL, inode, NULL, NULL,
+ 0, lmm_size, LUSTRE_OPC_ANY,
+ NULL);
+ if (IS_ERR(op_data))
+ RETURN(PTR_ERR(op_data));
- op_data->op_valid = OBD_MD_FLEASIZE | OBD_MD_FLDIREA;
- rc = md_getattr(sbi->ll_md_exp, op_data, &req);
- ll_finish_md_op_data(op_data);
- if (rc < 0) {
+ op_data->op_valid = valid | OBD_MD_FLEASIZE | OBD_MD_FLDIREA;
+ rc = md_getattr(sbi->ll_md_exp, op_data, &req);
+ ll_finish_md_op_data(op_data);
+ if (rc < 0) {
CDEBUG(D_INFO, "md_getattr failed on inode "
DFID": rc %d\n", PFID(ll_inode2fid(inode)), rc);
- GOTO(out, rc);
- }
+ GOTO(out, rc);
+ }
- body = req_capsule_server_get(&req->rq_pill, &RMF_MDT_BODY);
- LASSERT(body != NULL);
+ body = req_capsule_server_get(&req->rq_pill, &RMF_MDT_BODY);
+ LASSERT(body != NULL);
- lmmsize = body->eadatasize;
+ lmm_size = body->eadatasize;
- if (!(body->valid & (OBD_MD_FLEASIZE | OBD_MD_FLDIREA)) ||
- lmmsize == 0) {
- GOTO(out, rc = -ENODATA);
- }
+ if (!(body->valid & (OBD_MD_FLEASIZE | OBD_MD_FLDIREA)) ||
+ lmm_size == 0) {
+ GOTO(out, rc = -ENODATA);
+ }
- lmm = req_capsule_server_sized_get(&req->rq_pill,
- &RMF_MDT_MD, lmmsize);
- LASSERT(lmm != NULL);
-
- /*
- * This is coming from the MDS, so is probably in
- * little endian. We convert it to host endian before
- * passing it to userspace.
- */
- /* We don't swab objects for directories */
- switch (le32_to_cpu(lmm->lmm_magic)) {
- case LOV_MAGIC_V1:
- if (LOV_MAGIC != cpu_to_le32(LOV_MAGIC))
- lustre_swab_lov_user_md_v1((struct lov_user_md_v1 *)lmm);
- break;
- case LOV_MAGIC_V3:
- if (LOV_MAGIC != cpu_to_le32(LOV_MAGIC))
- lustre_swab_lov_user_md_v3((struct lov_user_md_v3 *)lmm);
- break;
- default:
- CERROR("unknown magic: %lX\n", (unsigned long)lmm->lmm_magic);
- rc = -EPROTO;
- }
+ lmm = req_capsule_server_sized_get(&req->rq_pill,
+ &RMF_MDT_MD, lmm_size);
+ LASSERT(lmm != NULL);
+
+ /*
+ * This is coming from the MDS, so is probably in
+ * little endian. We convert it to host endian before
+ * passing it to userspace.
+ */
+ /* We don't swab objects for directories */
+ switch (le32_to_cpu(lmm->lmm_magic)) {
+ case LOV_MAGIC_V1:
+ if (LOV_MAGIC != cpu_to_le32(LOV_MAGIC))
+ lustre_swab_lov_user_md_v1((struct lov_user_md_v1 *)lmm);
+ break;
+ case LOV_MAGIC_V3:
+ if (LOV_MAGIC != cpu_to_le32(LOV_MAGIC))
+ lustre_swab_lov_user_md_v3((struct lov_user_md_v3 *)lmm);
+ break;
+ case LMV_MAGIC:
+ if (LOV_MAGIC != cpu_to_le32(LOV_MAGIC))
+ lustre_swab_lmv_mds_md((union lmv_mds_md *)lmm);
+ break;
+ case LMV_USER_MAGIC:
+ if (LMV_USER_MAGIC != cpu_to_le32(LMV_USER_MAGIC))
+ lustre_swab_lmv_user_md((struct lmv_user_md *)lmm);
+ break;
+ default:
+ CERROR("unknown magic: %lX\n", (unsigned long)lmm->lmm_magic);
+ rc = -EPROTO;
+ }
out:
- *lmmp = lmm;
- *lmm_size = lmmsize;
- *request = req;
- return rc;
+ *plmm = lmm;
+ *plmm_size = lmm_size;
+ *request = req;
+ return rc;
+}
+
+static int ll_get_mdt_idx_by_fid(struct ll_sb_info *sbi,
+ const struct lu_fid *fid)
+{
+ struct md_op_data *op_data;
+ int rc;
+ int mdt_index;
+ ENTRY;
+
+ OBD_ALLOC_PTR(op_data);
+ if (op_data == NULL)
+ RETURN(-ENOMEM);
+
+ op_data->op_flags |= MF_GET_MDT_IDX;
+ op_data->op_fid1 = *fid;
+ rc = md_getattr(sbi->ll_md_exp, op_data, NULL);
+ mdt_index = op_data->op_mds;
+ OBD_FREE_PTR(op_data);
+ if (rc < 0)
+ RETURN(rc);
+
+ RETURN(mdt_index);
}
/*
*/
int ll_get_mdt_idx(struct inode *inode)
{
- struct ll_sb_info *sbi = ll_i2sbi(inode);
- struct md_op_data *op_data;
- int rc, mdtidx;
- ENTRY;
-
- op_data = ll_prep_md_op_data(NULL, inode, NULL, NULL, 0,
- 0, LUSTRE_OPC_ANY, NULL);
- if (IS_ERR(op_data))
- RETURN(PTR_ERR(op_data));
-
- op_data->op_flags |= MF_GET_MDT_IDX;
- rc = md_getattr(sbi->ll_md_exp, op_data, NULL);
- mdtidx = op_data->op_mds;
- ll_finish_md_op_data(op_data);
- if (rc < 0) {
- CDEBUG(D_INFO, "md_getattr_name: %d\n", rc);
- RETURN(rc);
- }
- return mdtidx;
+ return ll_get_mdt_idx_by_fid(ll_i2sbi(inode), ll_inode2fid(inode));
}
/**
RETURN(rc);
}
+ case LL_IOC_LMV_SET_DEFAULT_STRIPE: {
+ struct lmv_user_md lum;
+ struct lmv_user_md __user *ulump =
+ (struct lmv_user_md __user *)arg;
+ int rc;
+
+ if (copy_from_user(&lum, ulump, sizeof(lum)))
+ RETURN(-EFAULT);
+
+ if (lum.lum_magic != LMV_USER_MAGIC)
+ RETURN(-EINVAL);
+
+ rc = ll_dir_setstripe(inode, (struct lov_user_md *)&lum, 0);
+
+ RETURN(rc);
+ }
case LL_IOC_LOV_SETSTRIPE: {
struct lov_user_md_v3 lumv3;
struct lov_user_md_v1 *lumv1 = (struct lov_user_md_v1 *)&lumv3;
RETURN(rc);
}
case LL_IOC_LMV_GETSTRIPE: {
- struct lmv_user_md *lump = (struct lmv_user_md *)arg;
- struct lmv_user_md lum;
- struct lmv_user_md *tmp;
- int lum_size;
- int rc = 0;
- int mdtindex;
-
- if (copy_from_user(&lum, lump, sizeof(struct lmv_user_md)))
+ struct lmv_user_md __user *ulmv =
+ (struct lmv_user_md __user *)arg;
+ struct lmv_user_md lum;
+ struct ptlrpc_request *request = NULL;
+ union lmv_mds_md *lmm = NULL;
+ int lmmsize;
+ obd_valid valid = 0;
+ struct lmv_user_md *tmp = NULL;
+ int mdt_index;
+ int lum_size;
+ int stripe_count;
+ int i;
+ int rc;
+
+ if (copy_from_user(&lum, ulmv, sizeof(*ulmv)))
RETURN(-EFAULT);
- if (lum.lum_magic != LMV_MAGIC_V1)
+ /* lum_magic will indicate which stripe the ioctl will like
+ * to get, LMV_MAGIC_V1 is for normal LMV stripe, LMV_USER_MAGIC
+ * is for default LMV stripe */
+ if (lum.lum_magic == LMV_MAGIC_V1)
+ valid |= OBD_MD_MEA;
+ else if (lum.lum_magic == LMV_USER_MAGIC)
+ valid |= OBD_MD_DEFAULT_MEA;
+ else
RETURN(-EINVAL);
- lum_size = lmv_user_md_size(1, LMV_MAGIC_V1);
+ rc = ll_dir_getstripe(inode, (void **)&lmm, &lmmsize, &request,
+ valid);
+ if (rc != 0 && rc != -ENODATA)
+ GOTO(finish_req, rc);
+
+ /* Get default LMV EA */
+ if (lum.lum_magic == LMV_USER_MAGIC) {
+ if (rc != 0)
+ GOTO(finish_req, rc);
+
+ if (lmmsize > sizeof(*ulmv))
+ GOTO(finish_req, rc = -EINVAL);
+
+ if (copy_to_user(ulmv, lmm, lmmsize))
+ GOTO(finish_req, rc = -EFAULT);
+
+ GOTO(finish_req, rc);
+ }
+
+ /* Get normal LMV EA */
+ if (rc == -ENODATA) {
+ stripe_count = 1;
+ } else {
+ LASSERT(lmm != NULL);
+ stripe_count = lmv_mds_md_stripe_count_get(lmm);
+ }
+
+ lum_size = lmv_user_md_size(stripe_count, LMV_MAGIC_V1);
OBD_ALLOC(tmp, lum_size);
if (tmp == NULL)
- GOTO(free_lmv, rc = -ENOMEM);
+ GOTO(finish_req, rc = -ENOMEM);
- memcpy(tmp, &lum, sizeof(lum));
+ tmp->lum_magic = LMV_MAGIC_V1;
tmp->lum_stripe_count = 1;
- mdtindex = ll_get_mdt_idx(inode);
- if (mdtindex < 0)
- GOTO(free_lmv, rc = -ENOMEM);
-
- tmp->lum_stripe_offset = mdtindex;
- tmp->lum_objects[0].lum_mds = mdtindex;
- memcpy(&tmp->lum_objects[0].lum_fid, ll_inode2fid(inode),
- sizeof(struct lu_fid));
- if (copy_to_user((void *)arg, tmp, lum_size))
- GOTO(free_lmv, rc = -EFAULT);
-free_lmv:
- if (tmp)
- OBD_FREE(tmp, lum_size);
- RETURN(rc);
+ mdt_index = ll_get_mdt_idx(inode);
+ if (mdt_index < 0)
+ GOTO(out_tmp, rc = -ENOMEM);
+ tmp->lum_stripe_offset = mdt_index;
+ tmp->lum_objects[0].lum_mds = mdt_index;
+ tmp->lum_objects[0].lum_fid = *ll_inode2fid(inode);
+ for (i = 1; i < stripe_count; i++) {
+ struct lmv_mds_md_v1 *lmm1;
+
+ lmm1 = &lmm->lmv_md_v1;
+ mdt_index = ll_get_mdt_idx_by_fid(sbi,
+ &lmm1->lmv_stripe_fids[i]);
+ if (mdt_index < 0)
+ GOTO(out_tmp, rc = mdt_index);
+
+ tmp->lum_objects[i].lum_mds = mdt_index;
+ tmp->lum_objects[i].lum_fid = lmm1->lmv_stripe_fids[i];
+ tmp->lum_stripe_count++;
+ }
+
+ if (copy_to_user(ulmv, tmp, lum_size))
+ GOTO(out_tmp, rc = -EFAULT);
+out_tmp:
+ OBD_FREE(tmp, lum_size);
+finish_req:
+ ptlrpc_req_finished(request);
+ return rc;
}
+
case LL_IOC_REMOVE_ENTRY: {
char *filename = NULL;
int namelen = 0;
rc = ll_lov_getstripe_ea_info(inode, filename, &lmm,
&lmmsize, &request);
- } else {
- rc = ll_dir_getstripe(inode, &lmm, &lmmsize, &request);
- }
+ } else {
+ rc = ll_dir_getstripe(inode, (void **)&lmm, &lmmsize,
+ &request, 0);
+ }
if (request) {
body = req_capsule_server_get(&request->rq_pill,