From: wangdi Date: Sat, 16 Nov 2013 09:19:02 +0000 (-0800) Subject: LU-1187 utils: add lfs setdirstripe/getdirstripe X-Git-Tag: 2.3.61~49 X-Git-Url: https://git.whamcloud.com/?p=fs%2Flustre-release.git;a=commitdiff_plain;h=2ad263c602f315a6a4b1c7b545eb17d045cce6b0 LU-1187 utils: add lfs setdirstripe/getdirstripe 1.Add lfs setdirstripe/mkdir/getdirstripe to create remote directory. 2.Add lfs rm_entry to just remove the entry of remote directory. Change-Id: Idaecfbb9dd97e3ae9fbc70e5b902a91a7b2ed18e Signed-off-by: Wang Di Reviewed-on: http://review.whamcloud.com/4341 Reviewed-by: Andreas Dilger Tested-by: Hudson Tested-by: Maloo Reviewed-by: Alex Zhuravlev --- diff --git a/lustre/include/lustre/lustre_idl.h b/lustre/include/lustre/lustre_idl.h index d701085..8283931 100644 --- a/lustre/include/lustre/lustre_idl.h +++ b/lustre/include/lustre/lustre_idl.h @@ -1878,14 +1878,14 @@ typedef enum { */ typedef enum { - REINT_SETATTR = 1, - REINT_CREATE = 2, - REINT_LINK = 3, - REINT_UNLINK = 4, - REINT_RENAME = 5, - REINT_OPEN = 6, - REINT_SETXATTR = 7, -// REINT_CLOSE = 8, + REINT_SETATTR = 1, + REINT_CREATE = 2, + REINT_LINK = 3, + REINT_UNLINK = 4, + REINT_RENAME = 5, + REINT_OPEN = 6, + REINT_SETXATTR = 7, + REINT_RMENTRY = 8, // REINT_WRITE = 9, REINT_MAX } mds_reint_t, mdt_reint_t; diff --git a/lustre/include/lustre/lustre_user.h b/lustre/include/lustre/lustre_user.h index d15974e..9f1766a 100644 --- a/lustre/include/lustre/lustre_user.h +++ b/lustre/include/lustre/lustre_user.h @@ -109,6 +109,40 @@ struct obd_statfs { __u32 os_spare9; }; +/** + * File IDentifier. + * + * FID is a cluster-wide unique identifier of a file or an object (stripe). + * FIDs are never reused. + **/ +struct lu_fid { + /** + * FID sequence. Sequence is a unit of migration: all files (objects) + * with FIDs from a given sequence are stored on the same server. + * Lustre should support 2^64 objects, so even if each sequence + * has only a single object we can still enumerate 2^64 objects. + **/ + __u64 f_seq; + /* FID number within sequence. */ + __u32 f_oid; + /** + * FID version, used to distinguish different versions (in the sense + * of snapshots, etc.) of the same file system object. Not currently + * used. + **/ + __u32 f_ver; +}; + +struct filter_fid { + struct lu_fid ff_parent; /* ff_parent.f_ver == file stripe number */ + __u64 ff_objid; + __u64 ff_seq; +}; + +/* Userspace should treat lu_fid as opaque, and only use the following methods + * to print or parse them. Other functions (e.g. compare, swab) could be moved + * here from lustre_idl.h if needed. */ +typedef struct lu_fid lustre_fid; /* * The ioctl naming rules: @@ -168,6 +202,10 @@ struct obd_statfs { struct hsm_current_action) /* see for ioctl numbers 221-232 */ +#define LL_IOC_LMV_SETSTRIPE _IOWR('f', 240, struct lmv_user_md) +#define LL_IOC_LMV_GETSTRIPE _IOWR('f', 241, struct lmv_user_md) +#define LL_IOC_REMOVE_ENTRY _IOWR('f', 242, __u64) + #define LL_STATFS_LMV 1 #define LL_STATFS_LOV 2 #define LL_STATFS_NODELAY 4 @@ -205,6 +243,9 @@ struct obd_statfs { #define LOV_USER_MAGIC_JOIN_V1 0x0BD20BD0 #define LOV_USER_MAGIC_V3 0x0BD30BD0 +#define LMV_MAGIC_V1 0x0CD10CD0 /*normal stripe lmv magic */ +#define LMV_USER_MAGIC 0x0CD20CD0 /*default lmv magic*/ + #define LOV_PATTERN_RAID0 0x001 #define LOV_PATTERN_RAID1 0x002 #define LOV_PATTERN_FIRST 0x100 @@ -287,6 +328,41 @@ struct lov_user_mds_data_v3 { } __attribute__((packed)); #endif +/* keep this to be the same size as lov_user_ost_data_v1 */ +struct lmv_user_mds_data { + struct lu_fid lum_fid; + __u32 lum_padding; + __u32 lum_mds; +}; + +/* lum_type */ +enum { + LMV_STRIPE_TYPE = 0, + LMV_DEFAULT_TYPE = 1, +}; + +#define lmv_user_md lmv_user_md_v1 +struct lmv_user_md_v1 { + __u32 lum_magic; /* must be the first field */ + __u32 lum_stripe_count; /* dirstripe count */ + __u32 lum_stripe_offset; /* MDT idx for default dirstripe */ + __u32 lum_hash_type; /* Dir stripe policy */ + __u32 lum_type; /* LMV type: default or normal */ + __u32 lum_padding1; + __u32 lum_padding2; + __u32 lum_padding3; + char lum_pool_name[LOV_MAXPOOLNAME]; + struct lmv_user_mds_data lum_objects[0]; +}; + +static inline int lmv_user_md_size(int stripes, int lmm_magic) +{ + return sizeof(struct lmv_user_md) + + stripes * sizeof(struct lmv_user_mds_data); +} + +extern void lustre_swab_lmv_user_md(struct lmv_user_md *lum); + struct ll_recreate_obj { __u64 lrc_id; __u32 lrc_ost_idx; @@ -349,41 +425,6 @@ static inline void obd_uuid2fsname(char *buf, char *uuid, int buflen) *p = '\0'; } -/** - * File IDentifier. - * - * FID is a cluster-wide unique identifier of a file or an object (stripe). - * FIDs are never reused. - */ -struct lu_fid { - /** - * FID sequence. Sequence is a unit of migration: all files (objects) - * with FIDs from a given sequence are stored on the same server. - * Lustre should support 2^64 objects, so even if each sequence - * has only a single object we can still enumerate 2^64 objects. - */ - __u64 f_seq; - /** FID number within sequence. */ - __u32 f_oid; - /** - * FID version, used to distinguish different versions (in the sense - * of snapshots, etc.) of the same file system object. Not currently - * used. - */ - __u32 f_ver; -}; - -struct filter_fid { - struct lu_fid ff_parent; /* ff_parent.f_ver == file stripe number */ - __u64 ff_objid; - __u64 ff_seq; -}; - -/* Userspace should treat lu_fid as opaque, and only use the following methods - to print or parse them. Other functions (e.g. compare, swab) could be moved - here from lustre_idl.h if needed. */ -typedef struct lu_fid lustre_fid; - /* printf display format e.g. printf("file FID is "DFID"\n", PFID(fid)); */ #define DFID_NOBRACE LPX64":0x%x:0x%x" diff --git a/lustre/include/lustre/lustreapi.h b/lustre/include/lustre/lustreapi.h index c7a2bb1..949a34a 100644 --- a/lustre/include/lustre/lustreapi.h +++ b/lustre/include/lustre/lustreapi.h @@ -163,11 +163,14 @@ struct find_param { int *mdtindexes; int file_mdtindex; - int lumlen; - struct lov_user_mds_data *lmd; + int lumlen; + struct lov_user_mds_data *lmd; char poolname[LOV_MAXPOOLNAME + 1]; + int fp_lmv_count; + struct lmv_user_md *fp_lmv_md; + unsigned long long stripesize; unsigned long long stripesize_units; unsigned long long stripecount; @@ -186,6 +189,10 @@ 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_create_pool(const char *name, int flags, int stripe_offset, + int stripe_count, int stripe_pattern, + char *poolname); +int llapi_direntry_remove(char *dname); extern int llapi_obd_statfs(char *path, __u32 type, __u32 index, struct obd_statfs *stat_buf, struct obd_uuid *uuid_buf); diff --git a/lustre/include/obd.h b/lustre/include/obd.h index 7b50f69..3be4105 100644 --- a/lustre/include/obd.h +++ b/lustre/include/obd.h @@ -1248,21 +1248,32 @@ struct md_op_data { /* Size-on-MDS epoch and flags. */ __u64 op_ioepoch; - __u32 op_flags; + __u32 op_flags; /* Capa fields */ struct obd_capa *op_capa1; struct obd_capa *op_capa2; /* Various operation flags. */ - __u32 op_bias; + __u32 op_bias; /* Operation type */ - __u32 op_opc; + __u32 op_opc; /* Used by readdir */ - __u32 op_npages; - __u64 op_offset; + __u64 op_offset; + + /* Used by readdir */ + __u32 op_npages; + + /* used to transfer info between the stacks of MD client + * see enum op_cli_flags */ + __u32 op_cli_flags; +}; + +enum op_cli_flags { + CLI_SET_MEA = 1 << 0, + CLI_RM_ENTRY = 1 << 1, }; struct md_enqueue_info; diff --git a/lustre/llite/dir.c b/lustre/llite/dir.c index 76d1fb1..0a677f9 100644 --- a/lustre/llite/dir.c +++ b/lustre/llite/dir.c @@ -661,6 +661,36 @@ int ll_send_mgc_param(struct obd_export *mgc, char *string) return rc; } +int ll_dir_setdirstripe(struct inode *dir, struct lmv_user_md *lump, + char *filename) +{ + struct ptlrpc_request *request = NULL; + struct md_op_data *op_data; + struct ll_sb_info *sbi = ll_i2sbi(dir); + int mode; + int err; + + ENTRY; + + mode = (0755 & (S_IRWXUGO|S_ISVTX) & ~current->fs->umask) | S_IFDIR; + op_data = ll_prep_md_op_data(NULL, dir, NULL, filename, + strlen(filename), mode, LUSTRE_OPC_MKDIR, + lump); + if (IS_ERR(op_data)) + GOTO(err_exit, err = PTR_ERR(op_data)); + + op_data->op_cli_flags |= CLI_SET_MEA; + err = md_create(sbi->ll_md_exp, op_data, lump, sizeof(*lump), mode, + cfs_curproc_fsuid(), cfs_curproc_fsgid(), + cfs_curproc_cap_pack(), 0, &request); + ll_finish_md_op_data(op_data); + if (err) + GOTO(err_exit, err); +err_exit: + ptlrpc_req_finished(request); + return err; +} + int ll_dir_setstripe(struct inode *inode, struct lov_user_md *lump, int set_default) { @@ -685,22 +715,22 @@ int ll_dir_setstripe(struct inode *inode, struct lov_user_md *lump, lustre_swab_lov_user_md_v1(lump); lum_size = sizeof(struct lov_user_md_v1); break; - } + } case LOV_USER_MAGIC_V3: { if (lump->lmm_magic != cpu_to_le32(LOV_USER_MAGIC_V3)) lustre_swab_lov_user_md_v3( (struct lov_user_md_v3 *)lump); lum_size = sizeof(struct lov_user_md_v3); break; - } + } default: { CDEBUG(D_IOCTL, "bad userland LOV MAGIC:" " %#08x != %#08x nor %#08x\n", lump->lmm_magic, LOV_USER_MAGIC_V1, LOV_USER_MAGIC_V3); RETURN(-EINVAL); - } - } + } + } } else { lum_size = sizeof(struct lov_user_md_v1); } @@ -710,6 +740,9 @@ int ll_dir_setstripe(struct inode *inode, struct lov_user_md *lump, if (IS_ERR(op_data)) RETURN(PTR_ERR(op_data)); + if (lump != NULL && lump->lmm_magic == cpu_to_le32(LMV_USER_MAGIC)) + op_data->op_cli_flags |= CLI_SET_MEA; + /* swabbing is done in lov_setstripe() on server side */ rc = md_setattr(sbi->ll_md_exp, op_data, lump, lum_size, NULL, 0, &req, NULL); @@ -1262,6 +1295,51 @@ out_free: obd_ioctl_freedata(buf, len); return rc; } + case LL_IOC_LMV_SETSTRIPE: { + struct lmv_user_md *lum; + char *buf = NULL; + char *filename; + int namelen = 0; + int lumlen = 0; + int len; + int rc; + + rc = obd_ioctl_getdata(&buf, &len, (void *)arg); + if (rc) + RETURN(rc); + + data = (void *)buf; + if (data->ioc_inlbuf1 == NULL || data->ioc_inlbuf2 == NULL || + data->ioc_inllen1 == 0 || data->ioc_inllen2 == 0) + GOTO(lmv_out_free, rc = -EINVAL); + + filename = data->ioc_inlbuf1; + namelen = data->ioc_inllen1; + + if (namelen < 1) { + CDEBUG(D_INFO, "IOC_MDC_LOOKUP missing filename\n"); + GOTO(lmv_out_free, rc = -EINVAL); + } + lum = (struct lmv_user_md *)data->ioc_inlbuf2; + lumlen = data->ioc_inllen2; + + if (lum->lum_magic != LMV_USER_MAGIC || + lumlen != sizeof(*lum)) { + CERROR("%s: wrong lum magic %x or size %d: rc = %d\n", + filename, lum->lum_magic, lumlen, -EFAULT); + GOTO(lmv_out_free, rc = -EINVAL); + } + + /** + * ll_dir_setdirstripe will be used to set dir stripe + * mdc_create--->mdt_reint_create (with dirstripe) + */ + rc = ll_dir_setdirstripe(inode, lum, filename); +lmv_out_free: + obd_ioctl_freedata(buf, len); + 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; @@ -1277,7 +1355,7 @@ out_free: if (cfs_copy_from_user(lumv1, lumv1p, sizeof(*lumv1))) RETURN(-EFAULT); - if (lumv1->lmm_magic == LOV_USER_MAGIC_V3) { + if ((lumv1->lmm_magic == LOV_USER_MAGIC_V3) ) { if (cfs_copy_from_user(&lumv3, lumv3p, sizeof(lumv3))) RETURN(-EFAULT); } @@ -1290,6 +1368,70 @@ 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))) + RETURN(-EFAULT); + + if (lum.lum_magic != LMV_MAGIC_V1) + RETURN(-EINVAL); + + lum_size = lmv_user_md_size(1, LMV_MAGIC_V1); + OBD_ALLOC(tmp, lum_size); + if (tmp == NULL) + GOTO(free_lmv, rc = -ENOMEM); + + memcpy(tmp, &lum, sizeof(lum)); + tmp->lum_type = LMV_STRIPE_TYPE; + 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); + } + case LL_IOC_REMOVE_ENTRY: { + char *filename = NULL; + int namelen = 0; + int rc; + + /* Here is a little hack to avoid sending REINT_RMENTRY to + * unsupported server, which might crash the server(LU-2730), + * Because both LVB_TYPE and REINT_RMENTRY will be supported + * on 2.4, we use OBD_CONNECT_LVB_TYPE to detect whether the + * server will support REINT_RMENTRY XXX*/ + if (!(exp_connect_flags(sbi->ll_md_exp) & OBD_CONNECT_LVB_TYPE)) + return -ENOTSUPP; + + filename = getname((const char *)arg); + if (IS_ERR(filename)) + RETURN(PTR_ERR(filename)); + + namelen = strlen(filename); + if (namelen < 1) + GOTO(out_rmdir, rc = -EINVAL); + + rc = ll_rmdir_entry(inode, filename, namelen); +out_rmdir: + if (filename) + putname(filename); + RETURN(rc); + } case LL_IOC_OBD_STATFS: RETURN(ll_obd_statfs(inode, (void *)arg)); case LL_IOC_LOV_GETSTRIPE: @@ -1727,7 +1869,6 @@ out_free: OBD_FREE_PTR(copy); RETURN(rc); } - default: RETURN(obd_iocontrol(cmd, sbi->ll_dt_exp, 0, NULL, (void *)arg)); diff --git a/lustre/llite/llite_internal.h b/lustre/llite/llite_internal.h index ee76a52..3460658 100644 --- a/lustre/llite/llite_internal.h +++ b/lustre/llite/llite_internal.h @@ -685,6 +685,7 @@ struct lookup_intent *ll_convert_intent(struct open_intent *oit, int lookup_flags); #endif struct dentry *ll_splice_alias(struct inode *inode, struct dentry *de); +int ll_rmdir_entry(struct inode *dir, char *name, int namelen); /* llite/rw.c */ int ll_prepare_write(struct file *, struct page *, unsigned from, unsigned to); @@ -769,7 +770,7 @@ 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 **lmm, +int ll_dir_getstripe(struct inode *inode, struct lov_mds_md **lmmp, int *lmm_size, struct ptlrpc_request **request); #ifdef HAVE_FILE_FSYNC_4ARGS int ll_fsync(struct file *file, loff_t start, loff_t end, int data); diff --git a/lustre/llite/llite_lib.c b/lustre/llite/llite_lib.c index f19b571..501fb38 100644 --- a/lustre/llite/llite_lib.c +++ b/lustre/llite/llite_lib.c @@ -2306,6 +2306,7 @@ struct md_op_data * ll_prep_md_op_data(struct md_op_data *op_data, op_data->op_fsgid = cfs_curproc_fsgid(); op_data->op_cap = cfs_curproc_cap_pack(); op_data->op_bias = 0; + op_data->op_cli_flags = 0; if ((opc == LUSTRE_OPC_CREATE) && (name != NULL) && filename_is_volatile(name, namelen, NULL)) op_data->op_bias |= MDS_CREATE_VOLATILE; diff --git a/lustre/llite/namei.c b/lustre/llite/namei.c index 5d3f67b..f52a890 100644 --- a/lustre/llite/namei.c +++ b/lustre/llite/namei.c @@ -1138,6 +1138,35 @@ static int ll_rmdir_generic(struct inode *dir, struct dentry *dparent, RETURN(rc); } +/** + * Remove dir entry + **/ +int ll_rmdir_entry(struct inode *dir, char *name, int namelen) +{ + struct ptlrpc_request *request = NULL; + struct md_op_data *op_data; + int rc; + ENTRY; + + CDEBUG(D_VFSTRACE, "VFS Op:name=%.*s,dir=%lu/%u(%p)\n", + namelen, name, dir->i_ino, dir->i_generation, dir); + + op_data = ll_prep_md_op_data(NULL, dir, NULL, name, strlen(name), + S_IFDIR, LUSTRE_OPC_ANY, NULL); + if (IS_ERR(op_data)) + RETURN(PTR_ERR(op_data)); + op_data->op_cli_flags |= CLI_RM_ENTRY; + rc = md_unlink(ll_i2sbi(dir)->ll_md_exp, op_data, &request); + ll_finish_md_op_data(op_data); + if (rc == 0) { + ll_update_times(request, dir); + ll_stats_ops_tally(ll_i2sbi(dir), LPROC_LL_RMDIR, 1); + } + + ptlrpc_req_finished(request); + RETURN(rc); +} + int ll_objects_destroy(struct ptlrpc_request *request, struct inode *dir) { struct mdt_body *body; diff --git a/lustre/lmv/lmv_obd.c b/lustre/lmv/lmv_obd.c index c8fda0a..763a6b1 100644 --- a/lustre/lmv/lmv_obd.c +++ b/lustre/lmv/lmv_obd.c @@ -962,13 +962,41 @@ static int lmv_placement_policy(struct obd_device *obd, struct md_op_data *op_data, mdsno_t *mds) { + struct lmv_obd *lmv = &obd->u.lmv; + ENTRY; + LASSERT(mds != NULL); - /* Allocate new fid on target according to to different - * QOS policy. In DNE phase I, llite should always tell - * which MDT where the dir will be located */ - *mds = op_data->op_mds; + if (lmv->desc.ld_tgt_count == 1) { + *mds = 0; + RETURN(0); + } + /** + * If stripe_offset is provided during setdirstripe + * (setdirstripe -i xx), xx MDS will be choosen. + */ + if (op_data->op_cli_flags & CLI_SET_MEA) { + struct lmv_user_md *lum; + + lum = (struct lmv_user_md *)op_data->op_data; + if (lum->lum_type == LMV_STRIPE_TYPE && + lum->lum_stripe_offset != -1) { + if (lum->lum_stripe_offset >= lmv->desc.ld_tgt_count) { + CERROR("%s: Stripe_offset %d > MDT count %d:" + " rc = %d\n", obd->obd_name, + lum->lum_stripe_offset, + lmv->desc.ld_tgt_count, -ERANGE); + RETURN(-ERANGE); + } + *mds = lum->lum_stripe_offset; + RETURN(0); + } + } + + /* Allocate new fid on target according to operation type and parent + * home mds. */ + *mds = op_data->op_mds; RETURN(0); } diff --git a/lustre/mdc/mdc_lib.c b/lustre/mdc/mdc_lib.c index 13d055e..6486db3 100644 --- a/lustre/mdc/mdc_lib.c +++ b/lustre/mdc/mdc_lib.c @@ -371,14 +371,15 @@ void mdc_setattr_pack(struct ptlrpc_request *req, struct md_op_data *op_data, void mdc_unlink_pack(struct ptlrpc_request *req, struct md_op_data *op_data) { - struct mdt_rec_unlink *rec; - char *tmp; - - CLASSERT(sizeof(struct mdt_rec_reint) == sizeof(struct mdt_rec_unlink)); - rec = req_capsule_client_get(&req->rq_pill, &RMF_REC_REINT); - LASSERT (rec != NULL); + struct mdt_rec_unlink *rec; + char *tmp; + + CLASSERT(sizeof(struct mdt_rec_reint) == sizeof(struct mdt_rec_unlink)); + rec = req_capsule_client_get(&req->rq_pill, &RMF_REC_REINT); + LASSERT(rec != NULL); - rec->ul_opcode = REINT_UNLINK; + rec->ul_opcode = op_data->op_cli_flags & CLI_RM_ENTRY ? + REINT_RMENTRY : REINT_UNLINK; rec->ul_fsuid = op_data->op_fsuid; rec->ul_fsgid = op_data->op_fsgid; rec->ul_cap = op_data->op_cap; diff --git a/lustre/ptlrpc/pack_generic.c b/lustre/ptlrpc/pack_generic.c index 6de2ad3..19786ca 100644 --- a/lustre/ptlrpc/pack_generic.c +++ b/lustre/ptlrpc/pack_generic.c @@ -2126,6 +2126,26 @@ void lustre_swab_lmv_stripe_md (struct lmv_stripe_md *mea) CLASSERT(offsetof(typeof(*mea), mea_padding) != 0); } +void lustre_swab_lmv_user_md(struct lmv_user_md *lum) +{ + int i; + + __swab32s(&lum->lum_magic); + __swab32s(&lum->lum_stripe_count); + __swab32s(&lum->lum_stripe_offset); + __swab32s(&lum->lum_hash_type); + __swab32s(&lum->lum_type); + CLASSERT(offsetof(typeof(*lum), lum_padding1) != 0); + CLASSERT(offsetof(typeof(*lum), lum_padding2) != 0); + CLASSERT(offsetof(typeof(*lum), lum_padding3) != 0); + + for (i = 0; i < lum->lum_stripe_count; i++) { + __swab32s(&lum->lum_objects[i].lum_mds); + lustre_swab_lu_fid(&lum->lum_objects[i].lum_fid); + } + +} +EXPORT_SYMBOL(lustre_swab_lmv_user_md); static void print_lum (struct lov_user_md *lum) { diff --git a/lustre/ptlrpc/wiretest.c b/lustre/ptlrpc/wiretest.c index 0de4e26..433a206 100644 --- a/lustre/ptlrpc/wiretest.c +++ b/lustre/ptlrpc/wiretest.c @@ -195,7 +195,9 @@ void lustre_assert_wire_constants(void) (long long)REINT_OPEN); LASSERTF(REINT_SETXATTR == 7, "found %lld\n", (long long)REINT_SETXATTR); - LASSERTF(REINT_MAX == 8, "found %lld\n", + LASSERTF(REINT_RMENTRY == 8, "found %lld\n", + (long long)REINT_RMENTRY); + LASSERTF(REINT_MAX == 9, "found %lld\n", (long long)REINT_MAX); LASSERTF(DISP_IT_EXECD == 0x00000001UL, "found 0x%.8xUL\n", (unsigned)DISP_IT_EXECD); diff --git a/lustre/utils/lfs.c b/lustre/utils/lfs.c index 7662063..e180ffb 100644 --- a/lustre/utils/lfs.c +++ b/lustre/utils/lfs.c @@ -78,6 +78,9 @@ static int lfs_setstripe(int argc, char **argv); static int lfs_find(int argc, char **argv); static int lfs_getstripe(int argc, char **argv); +static int lfs_getdirstripe(int argc, char **argv); +static int lfs_setdirstripe(int argc, char **argv); +static int lfs_rmentry(int argc, char **argv); static int lfs_osts(int argc, char **argv); static int lfs_mdts(int argc, char **argv); static int lfs_df(int argc, char **argv); @@ -141,6 +144,27 @@ command_t cmdlist[] = { " [--pool|-p] [--stripe-size|-S] [--directory|-d]\n" " [--mdt-index|-M] [--recursive|-r] [--raw|-R]\n" " ..."}, + {"setdirstripe", lfs_setdirstripe, 0, + "To create a remote directory on a specified MDT.\n" + "usage: setdirstripe <--index|-i mdt_index> \n" + "\tmdt_index: MDT index of first stripe\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] ..."}, + {"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" + "usage: mkdir <--index|-i mdt_index> \n" + "\tmdt_index: MDT index of the remote directory.\n"}, + {"rm_entry", lfs_rmentry, 0, + "To remove the name entry of the remote directory. Note: This\n" + "command will only delete the name entry, i.e. the remote directory\n" + "will become inaccessable after this command. This can only be done\n" + "by the administrator\n" + "usage: rm_entry \n"}, {"pool_list", lfs_poollist, 0, "List pools or pool OSTs\n" "usage: pool_list [.] | \n"}, @@ -919,7 +943,8 @@ err: return ret; } -static int lfs_getstripe(int argc, char **argv) +static int lfs_getstripe_internal(int argc, char **argv, + struct find_param *param) { struct option long_opts[] = { #if LUSTRE_VERSION >= OBD_OCD_VERSION(2,9,50,0) @@ -974,127 +999,126 @@ static int lfs_getstripe(int argc, char **argv) {0, 0, 0, 0} }; int c, rc; - struct find_param param = { 0 }; - param.maxdepth = 1; - optind = 0; - while ((c = getopt_long(argc, argv, "cdghiMoO:pqrRsSv", - long_opts, NULL)) != -1) { - switch (c) { - case 'O': - if (param.obduuid) { - fprintf(stderr, - "error: %s: only one obduuid allowed", - argv[0]); - return CMD_HELP; - } - param.obduuid = (struct obd_uuid *)optarg; - break; - case 'q': - param.quiet++; - break; - case 'd': - param.maxdepth = 0; - break; - case 'r': - param.recursive = 1; - break; - case 'v': - param.verbose = VERBOSE_ALL | VERBOSE_DETAIL; - break; - case 'c': + param->maxdepth = 1; + optind = 0; + while ((c = getopt_long(argc, argv, "cdghiMoO:pqrRsSv", + long_opts, NULL)) != -1) { + switch (c) { + case 'O': + if (param->obduuid) { + fprintf(stderr, + "error: %s: only one obduuid allowed", + argv[0]); + return CMD_HELP; + } + param->obduuid = (struct obd_uuid *)optarg; + break; + case 'q': + param->quiet++; + break; + case 'd': + param->maxdepth = 0; + break; + case 'r': + param->recursive = 1; + break; + case 'v': + param->verbose = VERBOSE_ALL | VERBOSE_DETAIL; + break; + case 'c': #if LUSTRE_VERSION >= OBD_OCD_VERSION(2,9,50,0) #warning "remove deprecated --count option" #elif LUSTRE_VERSION >= OBD_OCD_VERSION(2,6,50,0) - if (strcmp(argv[optind - 1], "--count") == 0) - fprintf(stderr, "warning: '--count' deprecated," - " use '--stripe-count' instead\n"); + if (strcmp(argv[optind - 1], "--count") == 0) + fprintf(stderr, "warning: '--count' deprecated," + " use '--stripe-count' instead\n"); #endif - if (!(param.verbose & VERBOSE_DETAIL)) { - param.verbose |= VERBOSE_COUNT; - param.maxdepth = 0; - } - break; - case 's': + if (!(param->verbose & VERBOSE_DETAIL)) { + param->verbose |= VERBOSE_COUNT; + param->maxdepth = 0; + } + break; + case 's': #if LUSTRE_VERSION >= OBD_OCD_VERSION(2,9,50,0) #warning "remove deprecated --size option" #elif LUSTRE_VERSION >= OBD_OCD_VERSION(2,6,50,0) - fprintf(stderr, "warning: '--size|-s' deprecated, " - "use '--stripe-size|-S' instead\n"); + fprintf(stderr, "warning: '--size|-s' deprecated, " + "use '--stripe-size|-S' instead\n"); #endif - case 'S': - if (!(param.verbose & VERBOSE_DETAIL)) { - param.verbose |= VERBOSE_SIZE; - param.maxdepth = 0; - } - break; - case 'o': + case 'S': + if (!(param->verbose & VERBOSE_DETAIL)) { + param->verbose |= VERBOSE_SIZE; + param->maxdepth = 0; + } + break; + case 'o': #if LUSTRE_VERSION >= OBD_OCD_VERSION(2,4,50,0) - fprintf(stderr, "warning: '--offset|-o' deprecated, " - "use '--stripe-index|-i' instead\n"); + fprintf(stderr, "warning: '--offset|-o' deprecated, " + "use '--stripe-index|-i' instead\n"); #else - if (strcmp(argv[optind - 1], "--offset") == 0) - /* need --stripe-index established first */ - fprintf(stderr, "warning: '--offset' deprecated" - ", use '--index' instead\n"); + if (strcmp(argv[optind - 1], "--offset") == 0) + /* need --stripe-index established first */ + fprintf(stderr, "warning: '--offset' deprecated" + ", use '--index' instead\n"); #endif - case 'i': + case 'i': #if LUSTRE_VERSION >= OBD_OCD_VERSION(2,9,50,0) #warning "remove deprecated --offset and --index options" #elif LUSTRE_VERSION >= OBD_OCD_VERSION(2,6,50,0) - if (strcmp(argv[optind - 1], "--index") == 0) - fprintf(stderr, "warning: '--index' deprecated" - ", use '--stripe-index' instead\n"); + if (strcmp(argv[optind - 1], "--index") == 0) + fprintf(stderr, "warning: '--index' deprecated" + ", use '--stripe-index' instead\n"); #endif - if (!(param.verbose & VERBOSE_DETAIL)) { - param.verbose |= VERBOSE_OFFSET; - param.maxdepth = 0; - } - break; - case 'p': - if (!(param.verbose & VERBOSE_DETAIL)) { - param.verbose |= VERBOSE_POOL; - param.maxdepth = 0; - } - break; - case 'g': - if (!(param.verbose & VERBOSE_DETAIL)) { - param.verbose |= VERBOSE_GENERATION; - param.maxdepth = 0; - } - break; - case 'M': - if (!(param.verbose & VERBOSE_DETAIL)) - param.maxdepth = 0; - param.verbose |= VERBOSE_MDTINDEX; - break; - case 'R': - param.raw = 1; - break; - default: - return CMD_HELP; - } - } + if (!(param->verbose & VERBOSE_DETAIL)) { + param->verbose |= VERBOSE_OFFSET; + param->maxdepth = 0; + } + break; + case 'p': + if (!(param->verbose & VERBOSE_DETAIL)) { + param->verbose |= VERBOSE_POOL; + param->maxdepth = 0; + } + break; + case 'g': + if (!(param->verbose & VERBOSE_DETAIL)) { + param->verbose |= VERBOSE_GENERATION; + param->maxdepth = 0; + } + break; + case 'M': + if (!(param->verbose & VERBOSE_DETAIL)) + param->maxdepth = 0; + param->verbose |= VERBOSE_MDTINDEX; + break; + case 'R': + param->raw = 1; + break; + default: + return CMD_HELP; + } + } - if (optind >= argc) - return CMD_HELP; + if (optind >= argc) + return CMD_HELP; - if (param.recursive) - param.maxdepth = -1; + if (param->recursive) + param->maxdepth = -1; - if (!param.verbose) - param.verbose = VERBOSE_ALL; - if (param.quiet) - param.verbose = VERBOSE_OBJID; + if (!param->verbose) + param->verbose = VERBOSE_ALL; + if (param->quiet) + param->verbose = VERBOSE_OBJID; - do { - rc = llapi_getstripe(argv[optind], ¶m); - } while (++optind < argc && !rc); + do { + rc = llapi_getstripe(argv[optind], param); + } while (++optind < argc && !rc); - if (rc) - fprintf(stderr, "error: %s failed for %s.\n", - argv[0], argv[optind - 1]); - return rc; + if (rc) + fprintf(stderr, "error: %s failed for %s.\n", + argv[0], argv[optind - 1]); + return rc; } static int lfs_tgts(int argc, char **argv) @@ -1135,6 +1159,117 @@ static int lfs_tgts(int argc, char **argv) return rc; } +static int lfs_getstripe(int argc, char **argv) +{ + struct find_param param = { 0 }; + return lfs_getstripe_internal(argc, argv, ¶m); +} + +/* functions */ +static int lfs_getdirstripe(int argc, char **argv) +{ + struct find_param param = { 0 }; + + param.get_lmv = 1; + return lfs_getstripe_internal(argc, argv, ¶m); +} + +/* functions */ +static int lfs_setdirstripe(int argc, char **argv) +{ + char *dname; + int result; + int st_offset, st_count; + char *end; + int c; + char *stripe_off_arg = NULL; + int flags = 0; + + struct option long_opts[] = { + {"index", required_argument, 0, 'i'}, + {0, 0, 0, 0} + }; + + st_offset = -1; + st_count = 1; + optind = 0; + while ((c = getopt_long(argc, argv, "i:o", + long_opts, NULL)) >= 0) { + switch (c) { + case 0: + /* Long options. */ + break; + case 'i': + stripe_off_arg = optarg; + break; + default: + fprintf(stderr, "error: %s: option '%s' " + "unrecognized\n", + argv[0], argv[optind - 1]); + return CMD_HELP; + } + } + + if (optind == argc) { + fprintf(stderr, "error: %s: missing dirname\n", + argv[0]); + return CMD_HELP; + } + + dname = argv[optind]; + if (stripe_off_arg == NULL) { + fprintf(stderr, "error: %s: missing stripe_off.\n", + argv[0]); + return CMD_HELP; + } + /* get the stripe offset */ + st_offset = strtoul(stripe_off_arg, &end, 0); + if (*end != '\0') { + fprintf(stderr, "error: %s: bad stripe offset '%s'\n", + argv[0], stripe_off_arg); + return CMD_HELP; + } + do { + result = llapi_dir_create_pool(dname, flags, st_offset, + st_count, 0, NULL); + if (result) { + fprintf(stderr, "error: %s: create stripe dir '%s' " + "failed\n", argv[0], dname); + break; + } + dname = argv[++optind]; + } while (dname != NULL); + + return result; +} + +/* functions */ +static int lfs_rmentry(int argc, char **argv) +{ + char *dname; + int index; + int result = 0; + + if (argc <= 1) { + fprintf(stderr, "error: %s: missing dirname\n", + argv[0]); + return CMD_HELP; + } + + index = 1; + dname = argv[index]; + while (dname != NULL) { + result = llapi_direntry_remove(dname); + if (result) { + fprintf(stderr, "error: %s: remove dir entry '%s' " + "failed\n", argv[0], dname); + break; + } + dname = argv[++index]; + } + return result; +} + static int lfs_osts(int argc, char **argv) { return lfs_tgts(argc, argv); diff --git a/lustre/utils/liblustreapi.c b/lustre/utils/liblustreapi.c index 48a1453..f23f11f 100644 --- a/lustre/utils/liblustreapi.c +++ b/lustre/utils/liblustreapi.c @@ -61,6 +61,7 @@ #include #include #include +#include /* for dirname() */ #ifdef HAVE_LINUX_UNISTD_H #include #else @@ -647,6 +648,124 @@ int llapi_file_create_pool(const char *name, unsigned long long stripe_size, return 0; } +/** + * In DNE phase I, only stripe_offset will be used in this function. + * stripe_count, stripe_pattern and pool_name will be supported later. + */ +int llapi_dir_create_pool(const char *name, int flags, int stripe_offset, + int stripe_count, int stripe_pattern, char *pool_name) +{ + struct lmv_user_md lmu = { 0 }; + struct obd_ioctl_data data = { 0 }; + char rawbuf[8192]; + char *buf = rawbuf; + char *dirpath = NULL; + char *namepath = NULL; + char *dir; + char *filename; + int fd = -1; + int rc; + + dirpath = strdup(name); + namepath = strdup(name); + if (!dirpath || !namepath) + return -ENOMEM; + + lmu.lum_magic = LMV_USER_MAGIC; + lmu.lum_stripe_offset = stripe_offset; + lmu.lum_stripe_count = stripe_count; + lmu.lum_hash_type = stripe_pattern; + if (pool_name != NULL) { + if (strlen(pool_name) >= LOV_MAXPOOLNAME) { + llapi_err_noerrno(LLAPI_MSG_ERROR, + "error LL_IOC_LMV_SETSTRIPE '%s' : too large" + "pool name: %s", name, pool_name); + GOTO(out, rc = -E2BIG); + } + memcpy(lmu.lum_pool_name, pool_name, strlen(pool_name)); + } + + filename = basename(namepath); + lmu.lum_type = LMV_STRIPE_TYPE; + dir = dirname(dirpath); + + data.ioc_inlbuf1 = (char *)filename; + data.ioc_inllen1 = strlen(filename) + 1; + data.ioc_inlbuf2 = (char *)&lmu; + data.ioc_inllen2 = sizeof(struct lmv_user_md); + rc = obd_ioctl_pack(&data, &buf, sizeof(rawbuf)); + if (rc) { + llapi_error(LLAPI_MSG_ERROR, rc, + "error: LL_IOC_LMV_SETSTRIPE pack failed '%s'.", + name); + GOTO(out, rc); + } + + fd = open(dir, O_DIRECTORY | O_RDONLY); + if (fd < 0) { + rc = -errno; + llapi_error(LLAPI_MSG_ERROR, rc, "unable to open '%s'", name); + GOTO(out, rc); + } + + if (ioctl(fd, LL_IOC_LMV_SETSTRIPE, buf)) { + 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); +out: + free(dirpath); + free(namepath); + return rc; +} + +int llapi_direntry_remove(char *dname) +{ + char *dirpath = NULL; + char *namepath = NULL; + char *dir; + char *filename; + int fd = -1; + int rc = 0; + + dirpath = strdup(dname); + namepath = strdup(dname); + if (!dirpath || !namepath) + return -ENOMEM; + + filename = basename(namepath); + + dir = dirname(dirpath); + + fd = open(dir, O_DIRECTORY | O_RDONLY); + if (fd < 0) { + rc = -errno; + llapi_error(LLAPI_MSG_ERROR, rc, "unable to open '%s'", + filename); + GOTO(out, rc); + } + + if (ioctl(fd, LL_IOC_REMOVE_ENTRY, filename)) { + char *errmsg = strerror(errno); + llapi_err_noerrno(LLAPI_MSG_ERROR, + "error on ioctl "LPX64" for '%s' (%d): %s", + (__u64)LL_IOC_LMV_SETSTRIPE, filename, + fd, errmsg); + } +out: + free(dirpath); + free(namepath); + if (fd != -1) + close(fd); + return rc; +} + /* * Find the fsname, the full path, and/or an open fd. * Either the fsname or path must not be NULL @@ -1121,14 +1240,23 @@ typedef int (semantic_func_t)(char *path, DIR *parent, DIR *d, static int common_param_init(struct find_param *param, char *path) { - param->lumlen = get_mds_md_size(path); - param->lmd = malloc(sizeof(lstat_t) + param->lumlen); - if (param->lmd == NULL) { - llapi_error(LLAPI_MSG_ERROR, -ENOMEM, - "error: allocation of %d bytes for ioctl", - sizeof(lstat_t) + param->lumlen); - return -ENOMEM; - } + param->lumlen = get_mds_md_size(path); + param->lmd = malloc(sizeof(lstat_t) + param->lumlen); + if (param->lmd == NULL) { + llapi_error(LLAPI_MSG_ERROR, -ENOMEM, + "error: allocation of %d bytes for ioctl", + sizeof(lstat_t) + param->lumlen); + return -ENOMEM; + } + + param->fp_lmv_count = 256; + param->fp_lmv_md = malloc(lmv_user_md_size(256, LMV_MAGIC_V1)); + if (param->fp_lmv_md == NULL) { + llapi_error(LLAPI_MSG_ERROR, -ENOMEM, + "error: allocation of %d bytes for ioctl", + lmv_user_md_size(256, LMV_MAGIC_V1)); + return -ENOMEM; + } param->got_uuids = 0; param->obdindexes = NULL; @@ -1139,11 +1267,14 @@ static int common_param_init(struct find_param *param, char *path) static void find_param_fini(struct find_param *param) { - if (param->obdindexes) - free(param->obdindexes); + if (param->obdindexes) + free(param->obdindexes); + + if (param->lmd) + free(param->lmd); - if (param->lmd) - free(param->lmd); + if (param->fp_lmv_md) + free(param->fp_lmv_md); } static int cb_common_fini(char *path, DIR *parent, DIR *d, void *data, @@ -1172,6 +1303,17 @@ static DIR *opendir_parent(char *path) return parent; } +static int cb_get_dirstripe(char *path, DIR *d, struct find_param *param) +{ + struct lmv_user_md *lmv = (struct lmv_user_md *)param->fp_lmv_md; + int ret = 0; + + lmv->lum_stripe_count = param->fp_lmv_count; + lmv->lum_magic = LMV_MAGIC_V1; + ret = ioctl(dirfd(d), LL_IOC_LMV_GETSTRIPE, lmv); + return ret; +} + static int get_lmd_info(char *path, DIR *parent, DIR *dir, struct lov_user_mds_data *lmd, int lumlen) { @@ -1216,14 +1358,14 @@ static int get_lmd_info(char *path, DIR *parent, DIR *dir, "%s ioctl failed for %s.", dir ? "LL_IOC_MDC_GETINFO" : "IOC_MDC_GETFILEINFO", path); - } else { - ret = -errno; - llapi_error(LLAPI_MSG_ERROR, ret, - "error: %s: IOC_MDC_GETFILEINFO failed for %s", - __func__, path); - } - } - return ret; + } else { + ret = -errno; + llapi_error(LLAPI_MSG_ERROR, ret, + "error: %s: IOC_MDC_GETFILEINFO failed for %s", + __func__, path); + } + } + return ret; } int llapi_mds_getfileinfo(char *path, DIR *parent, @@ -1235,13 +1377,14 @@ int llapi_mds_getfileinfo(char *path, DIR *parent, } static int llapi_semantic_traverse(char *path, int size, DIR *parent, - semantic_func_t sem_init, - semantic_func_t sem_fini, void *data, - cfs_dirent_t *de) + semantic_func_t sem_init, + semantic_func_t sem_fini, void *data, + cfs_dirent_t *de) { - cfs_dirent_t *dent; - int len, ret; - DIR *d, *p = NULL; + struct find_param *param = (struct find_param *)data; + cfs_dirent_t *dent; + int len, ret; + DIR *d, *p = NULL; ret = 0; len = strlen(path); @@ -1262,11 +1405,11 @@ static int llapi_semantic_traverse(char *path, int size, DIR *parent, if (sem_init && (ret = sem_init(path, parent ?: p, d, data, de))) goto err; - if (!d) - GOTO(out, ret = 0); + if (!d || (param->get_lmv && !param->recursive)) + GOTO(out, ret = 0); - while ((dent = readdir64(d)) != NULL) { - ((struct find_param *)data)->have_fileinfo = 0; + while ((dent = readdir64(d)) != NULL) { + param->have_fileinfo = 0; if (!strcmp(dent->d_name, ".") || !strcmp(dent->d_name, "..")) continue; @@ -1286,20 +1429,17 @@ static int llapi_semantic_traverse(char *path, int size, DIR *parent, strcat(path, dent->d_name); if (dent->d_type == DT_UNKNOWN) { - lstat_t *st = &((struct find_param *)data)->lmd->lmd_st; + lstat_t *st = ¶m->lmd->lmd_st; - ret = llapi_mds_getfileinfo(path, d, - ((struct find_param *)data)->lmd); + ret = llapi_mds_getfileinfo(path, d, param->lmd); if (ret == 0) { - ((struct find_param *)data)->have_fileinfo = 1; - dent->d_type = - llapi_filetype_dir_table[st->st_mode & - S_IFMT]; - } + dent->d_type = + llapi_filetype_dir_table[st->st_mode & + S_IFMT]; + } if (ret == -ENOENT) continue; - } - + } switch (dent->d_type) { case DT_UNKNOWN: llapi_err_noerrno(LLAPI_MSG_ERROR, @@ -2033,10 +2173,89 @@ void lov_dump_user_lmm_v1v3(struct lov_user_md *lum, char *pool_name, } } -void llapi_lov_dump_user_lmm(struct find_param *param, - char *path, int is_dir) +void lmv_dump_user_lmm(struct lmv_user_md *lum, char *pool_name, + char *path, int obdindex, int depth, int verbose) { - switch(*(__u32 *)¶m->lmd->lmd_lmm) { /* lum->lmm_magic */ + struct lmv_user_mds_data *objects = lum->lum_objects; + char *prefix = lum->lum_magic == LMV_USER_MAGIC ? "(Default)" : ""; + int i, obdstripe = 0; + + if (obdindex != OBD_NOT_FOUND) { + for (i = 0; i < lum->lum_stripe_count; i++) { + if (obdindex == objects[i].lum_mds) { + llapi_printf(LLAPI_MSG_NORMAL, "%s%s\n", prefix, + path); + obdstripe = 1; + break; + } + } + } else { + obdstripe = 1; + } + + /* show all information default */ + if (!verbose) { + if (lum->lum_magic == LMV_USER_MAGIC) + verbose = VERBOSE_POOL | VERBOSE_COUNT | VERBOSE_OFFSET; + else + 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); + + if (verbose & VERBOSE_COUNT) { + if (verbose & ~VERBOSE_COUNT) + llapi_printf(LLAPI_MSG_NORMAL, "lmv_stripe_count: "); + llapi_printf(LLAPI_MSG_NORMAL, "%u\n", + (int)lum->lum_stripe_count); + } + + if (verbose & VERBOSE_OFFSET) { + if (verbose & ~VERBOSE_OFFSET) + llapi_printf(LLAPI_MSG_NORMAL, "lmv_stripe_offset: "); + llapi_printf(LLAPI_MSG_NORMAL, "%d\n", + (int)lum->lum_stripe_offset); + } + + if (verbose & VERBOSE_OBJID) { + if ((obdstripe == 1)) + llapi_printf(LLAPI_MSG_NORMAL, + "\tmdtidx\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", + idx, PFID(fid), + obdindex == idx ? " *" : ""); + } + + } + + if ((verbose & VERBOSE_POOL) && (pool_name[0] != '\0')) { + if (verbose & ~VERBOSE_POOL) + llapi_printf(LLAPI_MSG_NORMAL, "%slmv_pool: ", + prefix); + llapi_printf(LLAPI_MSG_NORMAL, "%s%c ", pool_name, ' '); + } + llapi_printf(LLAPI_MSG_NORMAL, "\n"); +} + +void llapi_lov_dump_user_lmm(struct find_param *param, char *path, int is_dir) +{ + __u32 magic; + + if (param->get_lmv) + magic = (__u32)param->fp_lmv_md->lum_magic; + else + magic = *(__u32 *)¶m->lmd->lmd_lmm; /* lum->lmm_magic */ + + switch (magic) { case LOV_USER_MAGIC_V1: lov_dump_user_lmm_v1v3(¶m->lmd->lmd_lmm, NULL, param->lmd->lmd_lmm.lmm_objects, @@ -2058,13 +2277,26 @@ void llapi_lov_dump_user_lmm(struct find_param *param, param->verbose, param->raw); break; } - default: - llapi_printf(LLAPI_MSG_NORMAL, "unknown lmm_magic: %#x " - "(expecting one of %#x %#x %#x)\n", - *(__u32 *)¶m->lmd->lmd_lmm, - LOV_USER_MAGIC_V1, LOV_USER_MAGIC_V3); - return; - } + case LMV_MAGIC_V1: + case LMV_USER_MAGIC: { + char pool_name[LOV_MAXPOOLNAME + 1]; + struct lmv_user_md *lum; + + lum = (struct lmv_user_md *)param->fp_lmv_md; + strncpy(pool_name, lum->lum_pool_name, LOV_MAXPOOLNAME); + lmv_dump_user_lmm(lum, pool_name, path, + param->obdindex, param->maxdepth, + param->verbose); + break; + } + default: + llapi_printf(LLAPI_MSG_NORMAL, "unknown lmm_magic: %#x " + "(expecting one of %#x %#x %#x %#x)\n", + *(__u32 *)¶m->lmd->lmd_lmm, + LOV_USER_MAGIC_V1, LOV_USER_MAGIC_V3, + LMV_USER_MAGIC, LMV_MAGIC_V1); + return; + } } int llapi_file_get_stripe(const char *path, struct lov_user_md *lum) @@ -2734,18 +2966,30 @@ static int cb_getstripe(char *path, DIR *parent, DIR *d, void *data, return ret; } - if (d) { - ret = ioctl(dirfd(d), LL_IOC_LOV_GETSTRIPE, - (void *)¶m->lmd->lmd_lmm); - } else if (parent) { - char *fname = strrchr(path, '/'); - fname = (fname == NULL ? path : fname + 1); + if (d) { + if (param->get_lmv) { + ret = cb_get_dirstripe(path, d, param); + } else { + ret = ioctl(dirfd(d), LL_IOC_LOV_GETSTRIPE, + (void *)¶m->lmd->lmd_lmm); + } - strncpy((char *)¶m->lmd->lmd_lmm, fname, param->lumlen); + } else if (parent) { + char *fname = strrchr(path, '/'); + fname = (fname == NULL ? path : fname + 1); - ret = ioctl(dirfd(parent), IOC_MDC_GETFILESTRIPE, - (void *)¶m->lmd->lmd_lmm); - } + if (param->get_lmv) { + llapi_printf(LLAPI_MSG_NORMAL, + "%s get dirstripe information for file\n", + path); + goto out; + } + + strncpy((char *)¶m->lmd->lmd_lmm, fname, param->lumlen); + + ret = ioctl(dirfd(parent), IOC_MDC_GETFILESTRIPE, + (void *)¶m->lmd->lmd_lmm); + } if (ret) { if (errno == ENODATA && d != NULL) { @@ -2765,7 +3009,7 @@ static int cb_getstripe(char *path, DIR *parent, DIR *d, void *data, goto dump; } else if (errno == ENODATA && parent != NULL) { - if (!param->obduuid) + if (!param->obduuid && !param->mdtuuid) llapi_printf(LLAPI_MSG_NORMAL, "%s has no stripe info\n", path); goto out; diff --git a/lustre/utils/req-layout.c b/lustre/utils/req-layout.c index df296b5..711eace 100644 --- a/lustre/utils/req-layout.c +++ b/lustre/utils/req-layout.c @@ -97,6 +97,7 @@ #define dump_obdo NULL #define dump_ost_body NULL #define dump_rcs NULL +#define lustre_swab_lmv_user_md NULL /* * Yes, include .c file. diff --git a/lustre/utils/wirecheck.c b/lustre/utils/wirecheck.c index aa8e879..e087797 100644 --- a/lustre/utils/wirecheck.c +++ b/lustre/utils/wirecheck.c @@ -2175,6 +2175,7 @@ main(int argc, char **argv) CHECK_VALUE(REINT_RENAME); CHECK_VALUE(REINT_OPEN); CHECK_VALUE(REINT_SETXATTR); + CHECK_VALUE(REINT_RMENTRY); CHECK_VALUE(REINT_MAX); CHECK_VALUE_X(DISP_IT_EXECD); diff --git a/lustre/utils/wiretest.c b/lustre/utils/wiretest.c index bb70dbb..834aa81 100644 --- a/lustre/utils/wiretest.c +++ b/lustre/utils/wiretest.c @@ -203,7 +203,9 @@ void lustre_assert_wire_constants(void) (long long)REINT_OPEN); LASSERTF(REINT_SETXATTR == 7, "found %lld\n", (long long)REINT_SETXATTR); - LASSERTF(REINT_MAX == 8, "found %lld\n", + LASSERTF(REINT_RMENTRY == 8, "found %lld\n", + (long long)REINT_RMENTRY); + LASSERTF(REINT_MAX == 9, "found %lld\n", (long long)REINT_MAX); LASSERTF(DISP_IT_EXECD == 0x00000001UL, "found 0x%.8xUL\n", (unsigned)DISP_IT_EXECD);