From 3c216b9767ddbfd34b2633d6fe0a539281d73b73 Mon Sep 17 00:00:00 2001 From: wang di Date: Wed, 31 Jul 2013 10:46:09 -0700 Subject: [PATCH] LU-3531 llite: fix "lfs getdirstripe" to show stripe info Fix "lfs getdirstripe", so it can show layout information of striped directory [root@testnode tests]# ../utils/lfs getdirstripe /mnt/lustre/test1 /mnt/lustre/test1 lmv_stripe_count: 2 lmv_stripe_offset: 0 mdtidx FID[seq:oid:ver] 0 [0x280000400:0x1:0x0] 1 [0x2c0000400:0x1:0x0] Signed-off-by: wang di Change-Id: I586f78ee2e0c35d8c3ed10726d5f5e12a4b543e7 Reviewed-on: http://review.whamcloud.com/7228 Tested-by: Jenkins Tested-by: Maloo Reviewed-by: Andreas Dilger Reviewed-by: John L. Hammond Reviewed-by: Alex Zhuravlev Reviewed-by: Oleg Drokin --- lustre/include/lustre/lustre_idl.h | 6 +- lustre/include/lustre/lustre_user.h | 1 + lustre/include/lustre/lustreapi.h | 6 +- lustre/include/md_object.h | 23 +-- lustre/llite/dir.c | 309 ++++++++++++++++++++++++------------ lustre/llite/llite_internal.h | 5 +- lustre/llite/xattr.c | 27 ++-- lustre/lod/lod_internal.h | 2 +- lustre/lod/lod_object.c | 107 ++++++++++++- lustre/mdt/mdt_handler.c | 107 +++++++++---- lustre/mdt/mdt_internal.h | 1 + lustre/mdt/mdt_lib.c | 45 +++++- lustre/mdt/mdt_reint.c | 10 ++ lustre/ptlrpc/pack_generic.c | 25 +++ lustre/utils/lfs.c | 34 +++- lustre/utils/liblustreapi.c | 92 ++++++++--- 16 files changed, 596 insertions(+), 204 deletions(-) diff --git a/lustre/include/lustre/lustre_idl.h b/lustre/include/lustre/lustre_idl.h index 0bee2f3..0f0bf41 100644 --- a/lustre/include/lustre/lustre_idl.h +++ b/lustre/include/lustre/lustre_idl.h @@ -1688,7 +1688,7 @@ static inline void lmm_oi_cpu_to_le(struct ost_id *dst_oi, #define XATTR_NAME_LOV "trusted.lov" #define XATTR_NAME_LMA "trusted.lma" #define XATTR_NAME_LMV "trusted.lmv" -#define XATTR_NAME_DEFALT_LMV "trusted.dmv" +#define XATTR_NAME_DEFAULT_LMV "trusted.dmv" #define XATTR_NAME_LINK "trusted.link" #define XATTR_NAME_FID "trusted.fid" #define XATTR_NAME_VERSION "trusted.version" @@ -1780,6 +1780,8 @@ static inline __u32 lov_mds_md_size(__u16 stripes, __u32 lmm_magic) #define OBD_MD_FLDATAVERSION (0x0010000000000000ULL) /* iversion sum */ #define OBD_MD_FLRELEASED (0x0020000000000000ULL) /* file released */ +#define OBD_MD_DEFAULT_MEA (0x0040000000000000ULL) /* default MEA */ + #define OBD_MD_FLGETATTR (OBD_MD_FLID | OBD_MD_FLATIME | OBD_MD_FLMTIME | \ OBD_MD_FLCTIME | OBD_MD_FLSIZE | OBD_MD_FLBLKSZ | \ OBD_MD_FLMODE | OBD_MD_FLTYPE | OBD_MD_FLUID | \ @@ -2735,6 +2737,8 @@ union lmv_mds_md { struct lmv_user_md lmv_user_md; }; +extern void lustre_swab_lmv_mds_md(union lmv_mds_md *lmm); + static inline int lmv_mds_md_size(int stripe_count, unsigned int lmm_magic) { switch (lmm_magic) { diff --git a/lustre/include/lustre/lustre_user.h b/lustre/include/lustre/lustre_user.h index 3a02c4e..4aa218d 100644 --- a/lustre/include/lustre/lustre_user.h +++ b/lustre/include/lustre/lustre_user.h @@ -266,6 +266,7 @@ struct ost_id { #define LL_IOC_SET_LEASE _IOWR('f', 243, long) #define LL_IOC_GET_LEASE _IO('f', 244) #define LL_IOC_HSM_IMPORT _IOWR('f', 245, struct hsm_user_import) +#define LL_IOC_LMV_SET_DEFAULT_STRIPE _IOWR('f', 246, struct lmv_user_md) #define LL_STATFS_LMV 1 #define LL_STATFS_LOV 2 diff --git a/lustre/include/lustre/lustreapi.h b/lustre/include/lustre/lustreapi.h index 9426014..8f7d103 100644 --- a/lustre/include/lustre/lustreapi.h +++ b/lustre/include/lustre/lustreapi.h @@ -160,7 +160,8 @@ struct find_param { check_stripecount:1, /* LOV stripe count */ exclude_stripecount:1, check_layout:1, - exclude_layout:1; + exclude_layout:1, + get_default_lmv:1; /* Get default LMV */ int verbose; int quiet; @@ -214,6 +215,9 @@ extern int llapi_getstripe(char *path, struct find_param *param); extern int llapi_find(char *path, struct find_param *param); extern int llapi_file_fget_mdtidx(int fd, int *mdtidx); +extern int llapi_dir_set_default_lmv_stripe(const char *name, int stripe_offset, + int stripe_count, int stripe_pattern, + const char *pool_name); extern int llapi_dir_create_pool(const char *name, int flags, int stripe_offset, int stripe_count, int stripe_pattern, const char *poolname); diff --git a/lustre/include/md_object.h b/lustre/include/md_object.h index 5839517..e85d956 100644 --- a/lustre/include/md_object.h +++ b/lustre/include/md_object.h @@ -71,17 +71,18 @@ struct md_quota *md_quota(const struct lu_env *env); /** metadata attributes */ enum ma_valid { - MA_INODE = (1 << 0), - MA_LOV = (1 << 1), - MA_COOKIE = (1 << 2), - MA_FLAGS = (1 << 3), - MA_LMV = (1 << 4), - MA_ACL_DEF = (1 << 5), - MA_LOV_DEF = (1 << 6), - MA_LAY_GEN = (1 << 7), - MA_HSM = (1 << 8), - MA_SOM = (1 << 9), - MA_PFID = (1 << 10) + MA_INODE = (1 << 0), + MA_LOV = (1 << 1), + MA_COOKIE = (1 << 2), + MA_FLAGS = (1 << 3), + MA_LMV = (1 << 4), + MA_ACL_DEF = (1 << 5), + MA_LOV_DEF = (1 << 6), + MA_LAY_GEN = (1 << 7), + MA_HSM = (1 << 8), + MA_SOM = (1 << 9), + MA_PFID = (1 << 10), + MA_LMV_DEF = (1 << 11) }; typedef enum { diff --git a/lustre/llite/dir.c b/lustre/llite/dir.c index b97edda..c579304 100644 --- a/lustre/llite/dir.c +++ b/lustre/llite/dir.c @@ -443,6 +443,13 @@ int ll_dir_setstripe(struct inode *inode, struct lov_user_md *lump, 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", @@ -514,73 +521,113 @@ end: 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); } /* @@ -588,25 +635,7 @@ out: */ 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)); } /** @@ -1087,6 +1116,22 @@ lmv_out_free: 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; @@ -1116,41 +1161,96 @@ lmv_out_free: 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; @@ -1201,9 +1301,10 @@ out_rmdir: 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, diff --git a/lustre/llite/llite_internal.h b/lustre/llite/llite_internal.h index c4e5f39..59ecdfb 100644 --- a/lustre/llite/llite_internal.h +++ b/lustre/llite/llite_internal.h @@ -838,8 +838,9 @@ int ll_lov_getstripe_ea_info(struct inode *inode, const char *filename, struct ptlrpc_request **request); int ll_dir_setstripe(struct inode *inode, struct lov_user_md *lump, int set_default); -int ll_dir_getstripe(struct inode *inode, struct lov_mds_md **lmmp, - int *lmm_size, struct ptlrpc_request **request); +int ll_dir_getstripe(struct inode *inode, void **lmmp, + int *lmm_size, struct ptlrpc_request **request, + obd_valid valid); #ifdef HAVE_FILE_FSYNC_4ARGS int ll_fsync(struct file *file, loff_t start, loff_t end, int data); #elif defined(HAVE_FILE_FSYNC_2ARGS) diff --git a/lustre/llite/xattr.c b/lustre/llite/xattr.c index 3db8073..bde8a35 100644 --- a/lustre/llite/xattr.c +++ b/lustre/llite/xattr.c @@ -476,15 +476,15 @@ ssize_t ll_getxattr(struct dentry *dentry, const char *name, lsm = ccc_inode_lsm_get(inode); if (lsm == NULL) { - if (S_ISDIR(inode->i_mode)) { - rc = ll_dir_getstripe(inode, &lmm, - &lmmsize, &request); - } else { - rc = -ENODATA; - } - } else { - /* LSM is present already after lookup/getattr call. - * we need to grab layout lock once it is implemented */ + if (S_ISDIR(inode->i_mode)) { + rc = ll_dir_getstripe(inode, (void **)&lmm, + &lmmsize, &request, 0); + } else { + rc = -ENODATA; + } + } else { + /* LSM is present already after lookup/getattr call. + * we need to grab layout lock once it is implemented */ rc = obd_packmd(ll_i2dtexp(inode), &lmm, lsm); lmmsize = rc; } @@ -571,10 +571,11 @@ ssize_t ll_listxattr(struct dentry *dentry, char *buffer, size_t size) } if (S_ISREG(inode->i_mode)) { if (!ll_i2info(inode)->lli_has_smd) - rc2 = -1; - } else if (S_ISDIR(inode->i_mode)) { - rc2 = ll_dir_getstripe(inode, &lmm, &lmmsize, &request); - } + rc2 = -1; + } else if (S_ISDIR(inode->i_mode)) { + rc2 = ll_dir_getstripe(inode, (void **)&lmm, &lmmsize, &request, + 0); + } if (rc2 < 0) { GOTO(out, rc2 = 0); diff --git a/lustre/lod/lod_internal.h b/lustre/lod/lod_internal.h index 3647791..b98caf2 100644 --- a/lustre/lod/lod_internal.h +++ b/lustre/lod/lod_internal.h @@ -387,7 +387,7 @@ lod_get_lmv_ea(const struct lu_env *env, struct lod_object *lo) static inline int lod_get_default_lmv_ea(const struct lu_env *env, struct lod_object *lo) { - return lod_get_ea(env, lo, XATTR_NAME_DEFALT_LMV); + return lod_get_ea(env, lo, XATTR_NAME_DEFAULT_LMV); } void lod_fix_desc(struct lov_desc *desc); diff --git a/lustre/lod/lod_object.c b/lustre/lod/lod_object.c index 3f2a5e5..ba83d07 100644 --- a/lustre/lod/lod_object.c +++ b/lustre/lod/lod_object.c @@ -902,8 +902,40 @@ static int lod_declare_xattr_set(const struct lu_env *env, attr->la_mode = S_IFREG; } rc = lod_declare_striped_object(env, dt, attr, buf, th); - if (rc) + } else if (S_ISDIR(mode)) { + struct lod_device *d = lu2lod_dev(dt->do_lu.lo_dev); + struct lod_object *lo = lod_dt_obj(dt); + int i; + + if (strcmp(name, XATTR_NAME_DEFAULT_LMV) == 0) { + struct lmv_user_md_v1 *lum; + + LASSERT(buf != NULL && buf->lb_buf != NULL); + lum = buf->lb_buf; + rc = lod_verify_md_striping(d, lum); + if (rc != 0) + RETURN(rc); + } + + rc = dt_declare_xattr_set(env, next, buf, name, fl, th); + if (rc != 0) + RETURN(rc); + + /* set xattr to each stripes, if needed */ + rc = lod_load_striping(env, lo); + if (rc != 0) RETURN(rc); + + if (lo->ldo_stripenr == 0) + RETURN(rc); + + for (i = 0; i < lo->ldo_stripenr; i++) { + LASSERT(lo->ldo_stripe[i]); + rc = dt_declare_xattr_set(env, lo->ldo_stripe[i], buf, + name, fl, th); + if (rc != 0) + break; + } } else { rc = dt_declare_xattr_set(env, next, buf, name, fl, th); } @@ -974,6 +1006,53 @@ static int lod_xattr_set_lov_on_dir(const struct lu_env *env, RETURN(rc); } +static int lod_xattr_set_default_lmv_on_dir(const struct lu_env *env, + struct dt_object *dt, + const struct lu_buf *buf, + const char *name, int fl, + struct thandle *th, + struct lustre_capa *capa) +{ + struct dt_object *next = dt_object_child(dt); + struct lod_object *l = lod_dt_obj(dt); + struct lmv_user_md_v1 *lum; + int rc; + ENTRY; + + LASSERT(buf != NULL && buf->lb_buf != NULL); + lum = buf->lb_buf; + + CDEBUG(D_OTHER, "set default stripe_count # %u stripe_offset %d\n", + le32_to_cpu(lum->lum_stripe_count), + (int)le32_to_cpu(lum->lum_stripe_offset)); + + if (LMVEA_DELETE_VALUES((le32_to_cpu(lum->lum_stripe_count)), + le32_to_cpu(lum->lum_stripe_offset)) && + le32_to_cpu(lum->lum_magic) == LMV_USER_MAGIC) { + rc = dt_xattr_del(env, next, name, th, capa); + if (rc == -ENODATA) + rc = 0; + } else { + rc = dt_xattr_set(env, next, buf, name, fl, th, capa); + if (rc != 0) + RETURN(rc); + + /* Update default stripe cache */ + if (l->ldo_dir_stripe == NULL) { + OBD_ALLOC_PTR(l->ldo_dir_stripe); + if (l->ldo_dir_stripe == NULL) + RETURN(-ENOMEM); + } + + l->ldo_dir_striping_cached = 0; + l->ldo_dir_def_striping_set = 1; + l->ldo_dir_def_stripenr = + le32_to_cpu(lum->lum_stripe_count) - 1; + } + + RETURN(rc); +} + static int lod_xattr_set_lmv(const struct lu_env *env, struct dt_object *dt, const struct lu_buf *buf, const char *name, int fl, struct thandle *th, @@ -1071,9 +1150,11 @@ static int lod_xattr_set(const struct lu_env *env, const char *name, int fl, struct thandle *th, struct lustre_capa *capa) { + struct lod_object *lo = lod_dt_obj(dt); struct dt_object *next = dt_object_child(dt); __u32 attr; int rc; + int i; ENTRY; attr = dt->do_lu.lo_header->loh_attr & S_IFMT; @@ -1092,7 +1173,11 @@ static int lod_xattr_set(const struct lu_env *env, } else { rc = lod_striping_create(env, dt, NULL, NULL, th); } - RETURN(rc); + } else if (strcmp(name, XATTR_NAME_DEFAULT_LMV) == 0) { + if (!S_ISDIR(attr)) + RETURN(-ENOTDIR); + rc = lod_xattr_set_default_lmv_on_dir(env, dt, buf, name, fl, + th, capa); } else { /* * behave transparantly for all other EAs @@ -1100,6 +1185,20 @@ static int lod_xattr_set(const struct lu_env *env, rc = dt_xattr_set(env, next, buf, name, fl, th, capa); } + if (rc != 0 || !S_ISDIR(attr)) + RETURN(rc); + + if (lo->ldo_stripenr == 0) + RETURN(rc); + + for (i = 0; i < lo->ldo_stripenr; i++) { + LASSERT(lo->ldo_stripe[i]); + rc = dt_xattr_set(env, lo->ldo_stripe[i], buf, name, fl, th, + capa); + if (rc != 0) + break; + } + RETURN(rc); } @@ -1622,11 +1721,11 @@ int lod_dir_striping_create_internal(const struct lu_env *env, info->lti_buf.lb_len = sizeof(*v1); if (declare) rc = dt_declare_xattr_set(env, next, &info->lti_buf, - XATTR_NAME_DEFALT_LMV, 0, + XATTR_NAME_DEFAULT_LMV, 0, th); else rc = dt_xattr_set(env, next, &info->lti_buf, - XATTR_NAME_DEFALT_LMV, 0, th, + XATTR_NAME_DEFAULT_LMV, 0, th, BYPASS_CAPA); if (rc != 0) RETURN(rc); diff --git a/lustre/mdt/mdt_handler.c b/lustre/mdt/mdt_handler.c index 22326e6..17340d0 100644 --- a/lustre/mdt/mdt_handler.c +++ b/lustre/mdt/mdt_handler.c @@ -521,31 +521,66 @@ static int mdt_big_xattr_get(struct mdt_thread_info *info, struct mdt_object *o, RETURN(rc); } -int mdt_attr_get_lov(struct mdt_thread_info *info, - struct mdt_object *o, struct md_attr *ma) +static int mdt_stripe_get(struct mdt_thread_info *info, struct mdt_object *o, + struct md_attr *ma, char *name) { struct md_object *next = mdt_object_child(o); struct lu_buf *buf = &info->mti_buf; int rc; - buf->lb_buf = ma->ma_lmm; - buf->lb_len = ma->ma_lmm_size; - rc = mo_xattr_get(info->mti_env, next, buf, XATTR_NAME_LOV); + if (strcmp(name, XATTR_NAME_LOV) == 0) { + buf->lb_buf = ma->ma_lmm; + buf->lb_len = ma->ma_lmm_size; + LASSERT(!(ma->ma_valid & MA_LOV)); + } else if (strcmp(name, XATTR_NAME_LMV) == 0) { + buf->lb_buf = ma->ma_lmv; + buf->lb_len = ma->ma_lmv_size; + LASSERT(!(ma->ma_valid & MA_LMV)); + } else if (strcmp(name, XATTR_NAME_DEFAULT_LMV) == 0) { + buf->lb_buf = ma->ma_lmv; + buf->lb_len = ma->ma_lmv_size; + LASSERT(!(ma->ma_valid & MA_LMV_DEF)); + } else { + return -EINVAL; + } + rc = mo_xattr_get(info->mti_env, next, buf, name); if (rc > 0) { - ma->ma_lmm_size = rc; - ma->ma_valid |= MA_LOV; + if (strcmp(name, XATTR_NAME_LOV) == 0) { + ma->ma_lmm_size = rc; + ma->ma_valid |= MA_LOV; + } else if (strcmp(name, XATTR_NAME_LMV) == 0) { + ma->ma_lmv_size = rc; + ma->ma_valid |= MA_LMV; + } else if (strcmp(name, XATTR_NAME_DEFAULT_LMV) == 0) { + ma->ma_lmv_size = rc; + ma->ma_valid |= MA_LMV_DEF; + } + rc = 0; } else if (rc == -ENODATA) { /* no LOV EA */ rc = 0; } else if (rc == -ERANGE) { - rc = mdt_big_xattr_get(info, o, XATTR_NAME_LOV); + /* Default LMV has fixed size, so it must be able to fit + * in the original buffer */ + if (strcmp(name, XATTR_NAME_DEFAULT_LMV) == 0) + return rc; + rc = mdt_big_xattr_get(info, o, name); if (rc > 0) { info->mti_big_lmm_used = 1; - ma->ma_valid |= MA_LOV; - ma->ma_lmm = info->mti_big_lmm; - ma->ma_lmm_size = rc; + if (!strcmp(name, XATTR_NAME_LOV)) { + ma->ma_valid |= MA_LOV; + ma->ma_lmm = info->mti_big_lmm; + ma->ma_lmm_size = rc; + } else if (!strcmp(name, XATTR_NAME_LMV)) { + ma->ma_valid |= MA_LMV; + ma->ma_lmv = info->mti_big_lmm; + ma->ma_lmv_size = rc; + } else { + return -EINVAL; + } + /* update mdt_max_mdsize so all clients * will be aware about that */ if (info->mti_mdt->mdt_max_mdsize < rc) @@ -634,23 +669,21 @@ int mdt_attr_get_complex(struct mdt_thread_info *info, } if (need & MA_LOV && (S_ISREG(mode) || S_ISDIR(mode))) { - rc = mdt_attr_get_lov(info, o, ma); + rc = mdt_stripe_get(info, o, ma, XATTR_NAME_LOV); if (rc) GOTO(out, rc); } if (need & MA_LMV && S_ISDIR(mode)) { - buf->lb_buf = ma->ma_lmv; - buf->lb_len = ma->ma_lmv_size; - rc2 = mo_xattr_get(env, next, buf, XATTR_NAME_LMV); - if (rc2 > 0) { - ma->ma_lmv_size = rc2; - ma->ma_valid |= MA_LMV; - } else if (rc2 == -ENODATA) { - /* no LMV EA */ - ma->ma_lmv_size = 0; - } else - GOTO(out, rc = rc2); + rc = mdt_stripe_get(info, o, ma, XATTR_NAME_LMV); + if (rc != 0) + GOTO(out, rc); + } + + if (need & MA_LMV_DEF && S_ISDIR(mode)) { + rc = mdt_stripe_get(info, o, ma, XATTR_NAME_DEFAULT_LMV); + if (rc != 0) + GOTO(out, rc); } if (need & MA_SOM && S_ISREG(mode)) { @@ -750,13 +783,17 @@ static int mdt_getattr_internal(struct mdt_thread_info *info, /* If it is dir object and client require MEA, then we got MEA */ if (S_ISDIR(lu_object_attr(&next->mo_lu)) && - reqbody->valid & OBD_MD_MEA) { + (reqbody->valid & (OBD_MD_MEA | OBD_MD_DEFAULT_MEA))) { /* Assumption: MDT_MD size is enough for lmv size. */ ma->ma_lmv = buffer->lb_buf; ma->ma_lmv_size = buffer->lb_len; ma->ma_need = MA_INODE; - if (ma->ma_lmv_size > 0) - ma->ma_need |= MA_LMV; + if (ma->ma_lmv_size > 0) { + if (reqbody->valid & OBD_MD_MEA) + ma->ma_need |= MA_LMV; + else if (reqbody->valid & OBD_MD_DEFAULT_MEA) + ma->ma_need |= MA_LMV_DEF; + } } else { ma->ma_lmm = buffer->lb_buf; ma->ma_lmm_size = buffer->lb_len; @@ -806,7 +843,7 @@ static int mdt_getattr_internal(struct mdt_thread_info *info, root = mdt_object_find(env, mdt, &rootfid); if (IS_ERR(root)) RETURN(PTR_ERR(root)); - rc = mdt_attr_get_lov(info, root, ma); + rc = mdt_stripe_get(info, root, ma, XATTR_NAME_LOV); mdt_object_put(info->mti_env, root); if (unlikely(rc)) { CERROR("%s: getattr error for "DFID": rc = %d\n", @@ -831,11 +868,17 @@ static int mdt_getattr_internal(struct mdt_thread_info *info, else repbody->valid |= OBD_MD_FLEASIZE; } - if (ma->ma_valid & MA_LMV) { - LASSERT(S_ISDIR(la->la_mode)); - repbody->eadatasize = ma->ma_lmv_size; - repbody->valid |= (OBD_MD_FLDIREA|OBD_MD_MEA); - } + if (ma->ma_valid & MA_LMV) { + LASSERT(S_ISDIR(la->la_mode)); + mdt_dump_lmv(D_INFO, ma->ma_lmv); + repbody->eadatasize = ma->ma_lmv_size; + repbody->valid |= (OBD_MD_FLDIREA|OBD_MD_MEA); + } + if (ma->ma_valid & MA_LMV_DEF) { + LASSERT(S_ISDIR(la->la_mode)); + repbody->eadatasize = ma->ma_lmv_size; + repbody->valid |= (OBD_MD_FLDIREA|OBD_MD_DEFAULT_MEA); + } } else if (S_ISLNK(la->la_mode) && reqbody->valid & OBD_MD_LINKNAME) { buffer->lb_buf = ma->ma_lmm; diff --git a/lustre/mdt/mdt_internal.h b/lustre/mdt/mdt_internal.h index d548988..79c6bcd 100644 --- a/lustre/mdt/mdt_internal.h +++ b/lustre/mdt/mdt_internal.h @@ -770,6 +770,7 @@ const struct lu_buf *mdt_buf_const(const struct lu_env *env, const void *area, ssize_t len); void mdt_dump_lmm(int level, const struct lov_mds_md *lmm); +void mdt_dump_lmv(unsigned int level, const union lmv_mds_md *lmv); int mdt_check_ucred(struct mdt_thread_info *); int mdt_init_ucred(struct mdt_thread_info *, struct mdt_body *); diff --git a/lustre/mdt/mdt_lib.c b/lustre/mdt/mdt_lib.c index 08d4809..e2cd8b1 100644 --- a/lustre/mdt/mdt_lib.c +++ b/lustre/mdt/mdt_lib.c @@ -555,6 +555,24 @@ void mdt_dump_lmm(int level, const struct lov_mds_md *lmm) } } +void mdt_dump_lmv(unsigned int level, const union lmv_mds_md *lmv) +{ + const struct lmv_mds_md_v1 *lmm1; + int i; + + lmm1 = &lmv->lmv_md_v1; + CDEBUG(level, "magic 0x%08X, master %#X stripe_count %#x\n", + le32_to_cpu(lmm1->lmv_magic), + le32_to_cpu(lmm1->lmv_master_mdt_index), + le32_to_cpu(lmm1->lmv_stripe_count)); + for (i = 0; i < le32_to_cpu(lmm1->lmv_stripe_count); i++) { + struct lu_fid fid; + + fid_le_to_cpu(&fid, &lmm1->lmv_stripe_fids[i]); + CDEBUG(level, "idx %u subobj "DFID"\n", i, PFID(&fid)); + } +} + /* Shrink and/or grow reply buffers */ int mdt_fix_reply(struct mdt_thread_info *info) { @@ -946,15 +964,26 @@ static int mdt_setattr_unpack(struct mdt_thread_info *info) rr->rr_eadata = req_capsule_client_get(pill, &RMF_EADATA); rr->rr_eadatalen = req_capsule_get_size(pill, &RMF_EADATA, RCL_CLIENT); - ma->ma_lmm_size = rr->rr_eadatalen; - if (ma->ma_lmm_size > 0) { - ma->ma_lmm = (void *)rr->rr_eadata; - ma->ma_valid |= MA_LOV; - } - } + if (rr->rr_eadatalen > 0) { + const struct lmv_user_md *lum; + + lum = rr->rr_eadata; + /* Sigh ma_valid(from req) does not indicate whether + * it will set LOV/LMV EA, so we have to check magic */ + if (le32_to_cpu(lum->lum_magic) == LMV_USER_MAGIC) { + ma->ma_valid |= MA_LMV; + ma->ma_lmv = (void *)rr->rr_eadata; + ma->ma_lmv_size = rr->rr_eadatalen; + } else { + ma->ma_valid |= MA_LOV; + ma->ma_lmm = (void *)rr->rr_eadata; + ma->ma_lmm_size = rr->rr_eadatalen; + } + } + } - rc = mdt_dlmreq_unpack(info); - RETURN(rc); + rc = mdt_dlmreq_unpack(info); + RETURN(rc); } static int mdt_hsm_release_unpack(struct mdt_thread_info *info) diff --git a/lustre/mdt/mdt_reint.c b/lustre/mdt/mdt_reint.c index e3ffad0..98c2ad5 100644 --- a/lustre/mdt/mdt_reint.c +++ b/lustre/mdt/mdt_reint.c @@ -615,6 +615,16 @@ static int mdt_reint_setattr(struct mdt_thread_info *info, buf, XATTR_NAME_LOV, 0); if (rc) GOTO(out_put, rc); + } else if ((ma->ma_valid & MA_LMV) && (ma->ma_valid & MA_INODE)) { + struct lu_buf *buf = &info->mti_buf; + + LASSERT(ma->ma_attr.la_valid == 0); + buf->lb_buf = ma->ma_lmv; + buf->lb_len = ma->ma_lmv_size; + rc = mo_xattr_set(info->mti_env, mdt_object_child(mo), + buf, XATTR_NAME_DEFAULT_LMV, 0); + if (rc) + GOTO(out_put, rc); } else LBUG(); diff --git a/lustre/ptlrpc/pack_generic.c b/lustre/ptlrpc/pack_generic.c index 77e92a2..97390de 100644 --- a/lustre/ptlrpc/pack_generic.c +++ b/lustre/ptlrpc/pack_generic.c @@ -2120,6 +2120,31 @@ void lustre_swab_lmv_desc (struct lmv_desc *ld) /* uuid endian insensitive */ } +/* This structure is always in little-endian */ +static void lustre_swab_lmv_mds_md_v1(struct lmv_mds_md_v1 *lmm1) +{ + int i; + + __swab32s(&lmm1->lmv_magic); + __swab32s(&lmm1->lmv_stripe_count); + __swab32s(&lmm1->lmv_master_mdt_index); + __swab32s(&lmm1->lmv_hash_type); + __swab32s(&lmm1->lmv_layout_version); + for (i = 0; i < lmm1->lmv_stripe_count; i++) + lustre_swab_lu_fid(&lmm1->lmv_stripe_fids[i]); +} + +void lustre_swab_lmv_mds_md(union lmv_mds_md *lmm) +{ + switch (lmm->lmv_magic) { + case LMV_MAGIC_V1: + lustre_swab_lmv_mds_md_v1(&lmm->lmv_md_v1); + break; + default: + break; + } +} + void lustre_swab_lmv_user_md(struct lmv_user_md *lum) { int i; diff --git a/lustre/utils/lfs.c b/lustre/utils/lfs.c index 3e2752f..2a05146 100644 --- a/lustre/utils/lfs.c +++ b/lustre/utils/lfs.c @@ -156,16 +156,18 @@ command_t cmdlist[] = { {"setdirstripe", lfs_setdirstripe, 0, "To create a remote directory on a specified MDT.\n" "usage: setdirstripe <--count|-c stripe_count>\n" - "[--index|-i mdt_index] [--hash-type|-t hash_type] \n" + "[--index|-i mdt_index] [--hash-type|-t hash_type]\n" + "[--default_stripe|-D ] \n" "\tstripe_count: stripe count of the striped directory\n" "\tmdt_index: MDT index of first stripe\n" - "\thash_type: hash type of the striped directory\n"}, + "\thash_type: hash type of the striped directory\n" + "\tdefault_stripe: set default dirstripe of the directory\n"}, {"getdirstripe", lfs_getdirstripe, 0, "To list the striping info for a given directory\n" "or recursively for all directories in a directory tree.\n" "usage: getdirstripe [--obd|-O ] [--quiet|-q] [--verbose|-v]\n" " [--count|-c ] [--index|-i ] [--raw|-R]\n" - " [--recursive | -r] ..."}, + " [--recursive | -r] [ --default_stripe | -D ] "}, {"mkdir", lfs_setdirstripe, 0, "To create a remote directory on a specified MDT. And this can only\n" "be done on MDT0 by administrator.\n" @@ -1239,6 +1241,7 @@ static int lfs_getstripe_internal(int argc, char **argv, {"stripe-count", no_argument, 0, 'c'}, {"stripe_count", no_argument, 0, 'c'}, {"directory", no_argument, 0, 'd'}, + {"default", no_argument, 0, 'D'}, {"generation", no_argument, 0, 'g'}, #if LUSTRE_VERSION_CODE < OBD_OCD_VERSION(2, 9, 53, 0) /* This formerly implied "stripe-index", but was explicitly @@ -1278,7 +1281,7 @@ static int lfs_getstripe_internal(int argc, char **argv, param->maxdepth = 1; optind = 0; - while ((c = getopt_long(argc, argv, "cdghiLMoO:pqrRsSv", + while ((c = getopt_long(argc, argv, "cdDghiLMoO:pqrRsSv", long_opts, NULL)) != -1) { switch (c) { case 'O': @@ -1296,6 +1299,9 @@ static int lfs_getstripe_internal(int argc, char **argv, case 'd': param->maxdepth = 0; break; + case 'D': + param->get_default_lmv = 1; + break; case 'r': param->recursive = 1; break; @@ -1460,18 +1466,19 @@ static int lfs_setdirstripe(int argc, char **argv) char *stripe_offset_opt = NULL; char *stripe_count_opt = NULL; char *stripe_hash_opt = NULL; - int flags = 0; + int default_stripe = 0; struct option long_opts[] = { {"count", required_argument, 0, 'c'}, {"index", required_argument, 0, 'i'}, {"hash-type", required_argument, 0, 't'}, + {"default_stripe", required_argument, 0, 'D'}, {0, 0, 0, 0} }; optind = 0; - while ((c = getopt_long(argc, argv, "c:i:t:", long_opts, NULL)) >= 0) { + while ((c = getopt_long(argc, argv, "c:Di:t:", long_opts, NULL)) >= 0) { switch (c) { case 0: /* Long options. */ @@ -1479,6 +1486,9 @@ static int lfs_setdirstripe(int argc, char **argv) case 'c': stripe_count_opt = optarg; break; + case 'D': + default_stripe = 1; + break; case 'i': stripe_offset_opt = optarg; break; @@ -1538,8 +1548,16 @@ static int lfs_setdirstripe(int argc, char **argv) dname = argv[optind]; do { - result = llapi_dir_create_pool(dname, flags, stripe_offset, - stripe_count, hash_type, NULL); + if (default_stripe == 1) { + result = llapi_dir_set_default_lmv_stripe(dname, + stripe_offset, stripe_count, + hash_type, NULL); + } else { + result = llapi_dir_create_pool(dname, 0, stripe_offset, + stripe_count, hash_type, + NULL); + } + if (result) { fprintf(stderr, "error: %s: create stripe dir '%s' " "failed\n", argv[0], dname); diff --git a/lustre/utils/liblustreapi.c b/lustre/utils/liblustreapi.c index 11b0a54..64d9595 100644 --- a/lustre/utils/liblustreapi.c +++ b/lustre/utils/liblustreapi.c @@ -792,6 +792,50 @@ int llapi_file_create_pool(const char *name, unsigned long long stripe_size, return 0; } +int llapi_dir_set_default_lmv_stripe(const char *name, int stripe_offset, + int stripe_count, int stripe_pattern, + const char *pool_name) +{ + struct lmv_user_md lum = { 0 }; + int fd; + int rc = 0; + + lum.lum_magic = LMV_USER_MAGIC; + lum.lum_stripe_offset = stripe_offset; + lum.lum_stripe_count = stripe_count; + lum.lum_hash_type = stripe_pattern; + if (pool_name != NULL) { + if (strlen(pool_name) >= sizeof(lum.lum_pool_name)) { + llapi_err_noerrno(LLAPI_MSG_ERROR, + "error LL_IOC_LMV_SET_DEFAULT_STRIPE '%s'" + ": too large pool name: %s", name, pool_name); + return -E2BIG; + } + strncpy(lum.lum_pool_name, pool_name, strlen(pool_name)); + } + + fd = open(name, O_DIRECTORY | O_RDONLY); + if (fd < 0) { + rc = -errno; + llapi_error(LLAPI_MSG_ERROR, rc, "unable to open '%s'", name); + return rc; + } + + rc = ioctl(fd, LL_IOC_LMV_SET_DEFAULT_STRIPE, &lum); + if (rc < 0) { + char *errmsg = "stripe already set"; + rc = -errno; + if (errno != EEXIST && errno != EALREADY) + errmsg = strerror(errno); + + llapi_err_noerrno(LLAPI_MSG_ERROR, + "error on LL_IOC_LMV_SETSTRIPE '%s' (%d): %s", + name, fd, errmsg); + } + close(fd); + return rc; +} + int llapi_dir_create_pool(const char *name, int flags, int stripe_offset, int stripe_count, int stripe_pattern, const char *pool_name) @@ -1460,8 +1504,12 @@ static int cb_get_dirstripe(char *path, DIR *d, struct find_param *param) int ret = 0; lmv->lum_stripe_count = param->fp_lmv_count; - lmv->lum_magic = LMV_MAGIC_V1; + if (param->get_default_lmv) + lmv->lum_magic = LMV_USER_MAGIC; + else + lmv->lum_magic = LMV_MAGIC_V1; ret = ioctl(dirfd(d), LL_IOC_LMV_GETSTRIPE, lmv); + return ret; } @@ -2379,11 +2427,8 @@ void lmv_dump_user_lmm(struct lmv_user_md *lum, char *pool_name, verbose = VERBOSE_OBJID; } - if (lum->lum_magic == LMV_USER_MAGIC) - verbose &= ~VERBOSE_OBJID; - if (depth && path && ((verbose != VERBOSE_OBJID))) - llapi_printf(LLAPI_MSG_NORMAL, "%s\n", path); + llapi_printf(LLAPI_MSG_NORMAL, "%s%s\n", prefix, path); if (verbose & VERBOSE_COUNT) { if (verbose & ~VERBOSE_COUNT) @@ -2399,16 +2444,16 @@ void lmv_dump_user_lmm(struct lmv_user_md *lum, char *pool_name, (int)lum->lum_stripe_offset); } - if (verbose & VERBOSE_OBJID) { + if (verbose & VERBOSE_OBJID && lum->lum_magic != LMV_USER_MAGIC) { if ((obdstripe == 1)) llapi_printf(LLAPI_MSG_NORMAL, - "\tmdtidx\t\t FID[seq:oid:ver]\n"); + "mdtidx\t\t FID[seq:oid:ver]\n"); for (i = 0; i < lum->lum_stripe_count; i++) { int idx = objects[i].lum_mds; struct lu_fid *fid = &objects[i].lum_fid; if ((obdindex == OBD_NOT_FOUND) || (obdindex == idx)) llapi_printf(LLAPI_MSG_NORMAL, - "\t%6u\t\t "DFID"\t\t%s\n", + "%6u\t\t "DFID"\t\t%s\n", idx, PFID(fid), obdindex == idx ? " *" : ""); } @@ -2428,7 +2473,7 @@ void llapi_lov_dump_user_lmm(struct find_param *param, char *path, int is_dir) { __u32 magic; - if (param->get_lmv) + if (param->get_lmv || param->get_default_lmv) magic = (__u32)param->fp_lmv_md->lum_magic; else magic = *(__u32 *)¶m->lmd->lmd_lmm; /* lum->lmm_magic */ @@ -3156,7 +3201,7 @@ static int cb_getstripe(char *path, DIR *parent, DIR *d, void *data, } if (d) { - if (param->get_lmv) { + if (param->get_lmv || param->get_default_lmv) { ret = cb_get_dirstripe(path, d, param); } else { ret = ioctl(dirfd(d), LL_IOC_LOV_GETSTRIPE, @@ -3188,15 +3233,24 @@ static int cb_getstripe(char *path, DIR *parent, DIR *d, void *data, * a check later on in the code path. * The object_seq needs to be set for the "(Default)" * prefix to be displayed. */ - struct lov_user_md *lmm = ¶m->lmd->lmd_lmm; - lmm->lmm_magic = LOV_USER_MAGIC_V1; - if (!param->raw) - ostid_set_seq(&lmm->lmm_oi, - FID_SEQ_LOV_DEFAULT); - lmm->lmm_stripe_count = 0; - lmm->lmm_stripe_size = 0; - lmm->lmm_stripe_offset = -1; - goto dump; + if (param->get_default_lmv) { + struct lmv_user_md *lum = param->fp_lmv_md; + + lum->lum_magic = LMV_USER_MAGIC; + lum->lum_stripe_count = 0; + lum->lum_stripe_offset = -1; + goto dump; + } else { + struct lov_user_md *lmm = ¶m->lmd->lmd_lmm; + lmm->lmm_magic = LOV_USER_MAGIC_V1; + if (!param->raw) + ostid_set_seq(&lmm->lmm_oi, + FID_SEQ_LOV_DEFAULT); + lmm->lmm_stripe_count = 0; + lmm->lmm_stripe_size = 0; + lmm->lmm_stripe_offset = -1; + goto dump; + } } else if (errno == ENODATA && parent != NULL) { if (!param->obduuid && !param->mdtuuid) llapi_printf(LLAPI_MSG_NORMAL, -- 1.8.3.1