*/
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;
__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:
struct hsm_current_action)
/* see <lustre_lib.h> 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
#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
} __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;
*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"
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;
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);
/* 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;
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)
{
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);
}
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);
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;
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);
}
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:
OBD_FREE_PTR(copy);
RETURN(rc);
}
-
default:
RETURN(obd_iocontrol(cmd, sbi->ll_dt_exp, 0, NULL,
(void *)arg));
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);
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);
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;
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;
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);
}
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;
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)
{
(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);
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);
" [--pool|-p] [--stripe-size|-S] [--directory|-d]\n"
" [--mdt-index|-M] [--recursive|-r] [--raw|-R]\n"
" <directory|filename> ..."},
+ {"setdirstripe", lfs_setdirstripe, 0,
+ "To create a remote directory on a specified MDT.\n"
+ "usage: setdirstripe <--index|-i mdt_index> <dir>\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 <uuid>] [--quiet|-q] [--verbose|-v]\n"
+ " [--count|-c ] [--index|-i ] [--raw|-R]\n"
+ " [--recursive | -r] <dir> ..."},
+ {"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> <dir>\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 <dir>\n"},
{"pool_list", lfs_poollist, 0,
"List pools or pool OSTs\n"
"usage: pool_list <fsname>[.<pool>] | <pathname>\n"},
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)
{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)
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);
#include <sys/xattr.h>
#include <fnmatch.h>
#include <glob.h>
+#include <libgen.h> /* for dirname() */
#ifdef HAVE_LINUX_UNISTD_H
#include <linux/unistd.h>
#else
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
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;
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,
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)
{
"%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,
}
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);
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;
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,
}
}
-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,
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)
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) {
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;
#define dump_obdo NULL
#define dump_ost_body NULL
#define dump_rcs NULL
+#define lustre_swab_lmv_user_md NULL
/*
* Yes, include .c file.
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);
(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);