Whamcloud - gitweb
LU-1187 utils: add lfs setdirstripe/getdirstripe
authorwangdi <di.wang@whamcloud.com>
Sat, 16 Nov 2013 09:19:02 +0000 (01:19 -0800)
committerOleg Drokin <oleg.drokin@intel.com>
Sat, 2 Feb 2013 22:24:49 +0000 (17:24 -0500)
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 <di.wang@intel.com>
Reviewed-on: http://review.whamcloud.com/4341
Reviewed-by: Andreas Dilger <andreas.dilger@intel.com>
Tested-by: Hudson
Tested-by: Maloo <whamcloud.maloo@gmail.com>
Reviewed-by: Alex Zhuravlev <alexey.zhuravlev@intel.com>
17 files changed:
lustre/include/lustre/lustre_idl.h
lustre/include/lustre/lustre_user.h
lustre/include/lustre/lustreapi.h
lustre/include/obd.h
lustre/llite/dir.c
lustre/llite/llite_internal.h
lustre/llite/llite_lib.c
lustre/llite/namei.c
lustre/lmv/lmv_obd.c
lustre/mdc/mdc_lib.c
lustre/ptlrpc/pack_generic.c
lustre/ptlrpc/wiretest.c
lustre/utils/lfs.c
lustre/utils/liblustreapi.c
lustre/utils/req-layout.c
lustre/utils/wirecheck.c
lustre/utils/wiretest.c

index d701085..8283931 100644 (file)
@@ -1878,14 +1878,14 @@ typedef enum {
  */
 
 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;
 //      REINT_WRITE    = 9,
         REINT_MAX
 } mds_reint_t, mdt_reint_t;
index d15974e..9f1766a 100644 (file)
@@ -109,6 +109,40 @@ struct obd_statfs {
         __u32           os_spare9;
 };
 
         __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:
 
 /*
  * The ioctl naming rules:
@@ -168,6 +202,10 @@ struct obd_statfs {
                                                struct hsm_current_action)
 /* see <lustre_lib.h> for ioctl numbers 221-232 */
 
                                                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 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 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
 #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
 
 } __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;
 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';
 }
 
            *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"
 /* printf display format
    e.g. printf("file FID is "DFID"\n", PFID(fid)); */
 #define DFID_NOBRACE LPX64":0x%x:0x%x"
index c7a2bb1..949a34a 100644 (file)
@@ -163,11 +163,14 @@ struct find_param {
         int                    *mdtindexes;
         int                     file_mdtindex;
 
         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];
 
 
         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;
         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_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);
 extern int llapi_obd_statfs(char *path, __u32 type, __u32 index,
                      struct obd_statfs *stat_buf,
                      struct obd_uuid *uuid_buf);
index 7b50f69..3be4105 100644 (file)
@@ -1248,21 +1248,32 @@ struct md_op_data {
 
         /* Size-on-MDS epoch and flags. */
         __u64                   op_ioepoch;
 
         /* 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. */
 
         /* Capa fields */
         struct obd_capa        *op_capa1;
         struct obd_capa        *op_capa2;
 
         /* Various operation flags. */
-        __u32                   op_bias;
+       __u32                   op_bias;
 
         /* Operation type */
 
         /* Operation type */
-        __u32                   op_opc;
+       __u32                   op_opc;
 
         /* Used by readdir */
 
         /* 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;
 };
 
 struct md_enqueue_info;
index 76d1fb1..0a677f9 100644 (file)
@@ -661,6 +661,36 @@ int ll_send_mgc_param(struct obd_export *mgc, char *string)
         return rc;
 }
 
         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)
 {
 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;
                                 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;
                 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);
                 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);
         }
         } 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 (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);
         /* 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;
         }
                 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;
         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 (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);
                 }
                         if (cfs_copy_from_user(&lumv3, lumv3p, sizeof(lumv3)))
                                 RETURN(-EFAULT);
                 }
@@ -1290,6 +1368,70 @@ out_free:
 
                 RETURN(rc);
         }
 
                 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:
         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);
        }
                OBD_FREE_PTR(copy);
                RETURN(rc);
        }
-
        default:
                RETURN(obd_iocontrol(cmd, sbi->ll_dt_exp, 0, NULL,
                                     (void *)arg));
        default:
                RETURN(obd_iocontrol(cmd, sbi->ll_dt_exp, 0, NULL,
                                     (void *)arg));
index ee76a52..3460658 100644 (file)
@@ -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 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);
 
 /* 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);
                              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);
                      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);
index f19b571..501fb38 100644 (file)
@@ -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_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;
        if ((opc == LUSTRE_OPC_CREATE) && (name != NULL) &&
             filename_is_volatile(name, namelen, NULL))
                op_data->op_bias |= MDS_CREATE_VOLATILE;
index 5d3f67b..f52a890 100644 (file)
@@ -1138,6 +1138,35 @@ static int ll_rmdir_generic(struct inode *dir, struct dentry *dparent,
         RETURN(rc);
 }
 
         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;
 int ll_objects_destroy(struct ptlrpc_request *request, struct inode *dir)
 {
         struct mdt_body *body;
index c8fda0a..763a6b1 100644 (file)
@@ -962,13 +962,41 @@ static int lmv_placement_policy(struct obd_device *obd,
                                 struct md_op_data *op_data,
                                 mdsno_t *mds)
 {
                                 struct md_op_data *op_data,
                                 mdsno_t *mds)
 {
+       struct lmv_obd          *lmv = &obd->u.lmv;
+       ENTRY;
+
        LASSERT(mds != NULL);
 
        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);
 }
 
        RETURN(0);
 }
 
index 13d055e..6486db3 100644 (file)
@@ -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)
 {
 
 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;
         rec->ul_fsuid   = op_data->op_fsuid;
         rec->ul_fsgid   = op_data->op_fsgid;
         rec->ul_cap     = op_data->op_cap;
index 6de2ad3..19786ca 100644 (file)
@@ -2126,6 +2126,26 @@ void lustre_swab_lmv_stripe_md (struct lmv_stripe_md *mea)
         CLASSERT(offsetof(typeof(*mea), mea_padding) != 0);
 }
 
         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)
 {
 
 static void print_lum (struct lov_user_md *lum)
 {
index 0de4e26..433a206 100644 (file)
@@ -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);
                 (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);
                 (long long)REINT_MAX);
        LASSERTF(DISP_IT_EXECD == 0x00000001UL, "found 0x%.8xUL\n",
                (unsigned)DISP_IT_EXECD);
index 7662063..e180ffb 100644 (file)
@@ -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_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);
 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"
          "                 <directory|filename> ..."},
          "                 [--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"},
         {"pool_list", lfs_poollist, 0,
          "List pools or pool OSTs\n"
          "usage: pool_list <fsname>[.<pool>] | <pathname>\n"},
@@ -919,7 +943,8 @@ err:
         return ret;
 }
 
         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)
 {
         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;
                 {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 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
 #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)
 #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
 #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)
 #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
 #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
 #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 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
 #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], &param);
-        } 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)
 }
 
 static int lfs_tgts(int argc, char **argv)
@@ -1135,6 +1159,117 @@ static int lfs_tgts(int argc, char **argv)
         return rc;
 }
 
         return rc;
 }
 
+static int lfs_getstripe(int argc, char **argv)
+{
+       struct find_param param = { 0 };
+       return lfs_getstripe_internal(argc, argv, &param);
+}
+
+/* functions */
+static int lfs_getdirstripe(int argc, char **argv)
+{
+       struct find_param param = { 0 };
+
+       param.get_lmv = 1;
+       return lfs_getstripe_internal(argc, argv, &param);
+}
+
+/* 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);
 static int lfs_osts(int argc, char **argv)
 {
         return lfs_tgts(argc, argv);
index 48a1453..f23f11f 100644 (file)
@@ -61,6 +61,7 @@
 #include <sys/xattr.h>
 #include <fnmatch.h>
 #include <glob.h>
 #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
 #ifdef HAVE_LINUX_UNISTD_H
 #include <linux/unistd.h>
 #else
@@ -647,6 +648,124 @@ int llapi_file_create_pool(const char *name, unsigned long long stripe_size,
         return 0;
 }
 
         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
 /*
  * 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)
 {
 
 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;
 
        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)
 {
 
 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,
 }
 
 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;
 }
 
         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)
 {
 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);
                                     "%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,
 }
 
 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,
 }
 
 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);
 
         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 (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;
 
                 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) {
                 strcat(path, dent->d_name);
 
                 if (dent->d_type == DT_UNKNOWN) {
-                        lstat_t *st = &((struct find_param *)data)->lmd->lmd_st;
+                       lstat_t *st = &param->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) {
                         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;
                         if (ret == -ENOENT)
                                 continue;
-                }
-
+               }
                 switch (dent->d_type) {
                 case DT_UNKNOWN:
                         llapi_err_noerrno(LLAPI_MSG_ERROR,
                 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 *)&param->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 *)&param->lmd->lmd_lmm; /* lum->lmm_magic */
+
+       switch (magic) {
         case LOV_USER_MAGIC_V1:
                 lov_dump_user_lmm_v1v3(&param->lmd->lmd_lmm, NULL,
                                        param->lmd->lmd_lmm.lmm_objects,
         case LOV_USER_MAGIC_V1:
                 lov_dump_user_lmm_v1v3(&param->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;
         }
                                        param->verbose, param->raw);
                 break;
         }
-        default:
-                llapi_printf(LLAPI_MSG_NORMAL, "unknown lmm_magic:  %#x "
-                             "(expecting one of %#x %#x %#x)\n",
-                             *(__u32 *)&param->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 *)&param->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)
 }
 
 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;
         }
 
                         return ret;
         }
 
-        if (d) {
-                ret = ioctl(dirfd(d), LL_IOC_LOV_GETSTRIPE,
-                            (void *)&param->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 *)&param->lmd->lmd_lmm);
+               }
 
 
-                strncpy((char *)&param->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 *)&param->lmd->lmd_lmm);
-        }
+               if (param->get_lmv) {
+                       llapi_printf(LLAPI_MSG_NORMAL,
+                                    "%s get dirstripe information for file\n",
+                                    path);
+                       goto out;
+               }
+
+               strncpy((char *)&param->lmd->lmd_lmm, fname, param->lumlen);
+
+               ret = ioctl(dirfd(parent), IOC_MDC_GETFILESTRIPE,
+                           (void *)&param->lmd->lmd_lmm);
+       }
 
         if (ret) {
                 if (errno == ENODATA && d != NULL) {
 
         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) {
                         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;
                                 llapi_printf(LLAPI_MSG_NORMAL,
                                              "%s has no stripe info\n", path);
                         goto out;
index df296b5..711eace 100644 (file)
@@ -97,6 +97,7 @@
 #define dump_obdo NULL
 #define dump_ost_body NULL
 #define dump_rcs NULL
 #define dump_obdo NULL
 #define dump_ost_body NULL
 #define dump_rcs NULL
+#define lustre_swab_lmv_user_md NULL
 
 /*
  * Yes, include .c file.
 
 /*
  * Yes, include .c file.
index aa8e879..e087797 100644 (file)
@@ -2175,6 +2175,7 @@ main(int argc, char **argv)
        CHECK_VALUE(REINT_RENAME);
        CHECK_VALUE(REINT_OPEN);
        CHECK_VALUE(REINT_SETXATTR);
        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);
        CHECK_VALUE(REINT_MAX);
 
        CHECK_VALUE_X(DISP_IT_EXECD);
index bb70dbb..834aa81 100644 (file)
@@ -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);
                 (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);
                 (long long)REINT_MAX);
        LASSERTF(DISP_IT_EXECD == 0x00000001UL, "found 0x%.8xUL\n",
                (unsigned)DISP_IT_EXECD);