Whamcloud - gitweb
b=20984 cleanup md_op_data and add getstripe -M
authorWang Di <Tom.Wang@Sun.COM>
Mon, 22 Feb 2010 22:21:32 +0000 (14:21 -0800)
committerRobert Read <rread@sun.com>
Mon, 22 Feb 2010 22:21:32 +0000 (14:21 -0800)
i=adiger
i=robert
i=vitaly

18 files changed:
lustre/cmm/mdc_object.c
lustre/include/lustre/liblustreapi.h
lustre/include/lustre/lustre_idl.h
lustre/include/lustre/lustre_user.h
lustre/include/obd.h
lustre/include/obd_class.h
lustre/liblustre/super.c
lustre/llite/dir.c
lustre/llite/file.c
lustre/llite/llite_internal.h
lustre/llite/llite_lib.c
lustre/llite/llite_nfs.c
lustre/llite/symlink.c
lustre/lmv/lmv_obd.c
lustre/lmv/lmv_object.c
lustre/mdc/mdc_request.c
lustre/utils/lfs.c
lustre/utils/liblustreapi.c

index 18186b7..383db56 100644 (file)
@@ -255,9 +255,13 @@ static int mdc_attr_get(const struct lu_env *env, struct md_object *mo,
 
         memset(&mci->mci_opdata, 0, sizeof(mci->mci_opdata));
 
-        rc = md_getattr(mc->mc_desc.cl_exp, lu_object_fid(&mo->mo_lu),
-                        NULL, OBD_MD_FLMODE | OBD_MD_FLUID | OBD_MD_FLGID |
-                        OBD_MD_FLFLAGS | OBD_MD_FLCROSSREF, 0, &mci->mci_req);
+        memcpy(&mci->mci_opdata.op_fid1, lu_object_fid(&mo->mo_lu),
+               sizeof (struct lu_fid));
+        mci->mci_opdata.op_valid = OBD_MD_FLMODE | OBD_MD_FLUID |
+                                   OBD_MD_FLGID | OBD_MD_FLFLAGS |
+                                   OBD_MD_FLCROSSREF;
+
+        rc = md_getattr(mc->mc_desc.cl_exp, &mci->mci_opdata, &mci->mci_req);
         if (rc == 0) {
                 /* get attr from request */
                 rc = mdc_req2attr_update(env, ma);
index 6e4ec38..b47b54e 100644 (file)
@@ -126,7 +126,8 @@ struct find_param {
                         check_gid:1,
                         check_uid:1,
                         check_pool:1,
-                        exclude_pool:1;
+                        exclude_pool:1,
+                        get_mdt_index:1;
 
         int     verbose;
         int     quiet;
@@ -157,6 +158,7 @@ extern int llapi_uuid_match(char *real_uuid, char *search_uuid);
 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_obd_statfs(char *path, __u32 type, __u32 index,
                      struct obd_statfs *stat_buf,
                      struct obd_uuid *uuid_buf);
index 9e0f9e7..51d5e09 100644 (file)
@@ -1050,6 +1050,7 @@ struct lov_mds_md_v3 {            /* LOV EA mds/wire data (little-endian) */
 #define OBD_MD_MDS         (0x0000000100000000ULL) /* where an inode lives on */
 #define OBD_MD_REINT       (0x0000000200000000ULL) /* reintegrate oa */
 #define OBD_MD_MEA         (0x0000000400000000ULL) /* CMD split EA  */
+#define OBD_MD_MDTIDX      (0x0000000800000000ULL) /* Get MDT index  */
 
 #define OBD_MD_FLXATTR     (0x0000001000000000ULL) /* xattr */
 #define OBD_MD_FLXATTRLS   (0x0000002000000000ULL) /* xattr list */
index 8948c7f..07d2fc4 100644 (file)
@@ -134,6 +134,7 @@ struct obd_statfs {
 #define LL_IOC_LLOOP_INFO               _IOWR('f', 171, long)
 #define LL_IOC_LLOOP_DETACH_BYDEV       _IOWR('f', 172, long)
 #define LL_IOC_PATH2FID                 _IOR ('f', 173, long)
+#define LL_IOC_GET_MDTIDX               _IOR ('f', 174, int)
 
 #define LL_STATFS_MDC           1
 #define LL_STATFS_LOV           2
index 05db5f8..454f383 100644 (file)
@@ -1229,6 +1229,7 @@ struct md_op_data {
         unsigned int            op_attr_flags;
 #endif
 #endif
+        __u64                   op_valid;
         loff_t                  op_attr_blocks;
 
         /* Size-on-MDS epoch and flags. */
@@ -1489,12 +1490,10 @@ struct md_ops {
                          struct lookup_intent *, struct md_op_data *,
                          struct lustre_handle *, void *, int,
                          struct ptlrpc_request **, int);
-        int (*m_getattr)(struct obd_export *, const struct lu_fid *,
-                         struct obd_capa *, obd_valid, int,
+        int (*m_getattr)(struct obd_export *, struct md_op_data *,
                          struct ptlrpc_request **);
-        int (*m_getattr_name)(struct obd_export *, const struct lu_fid *,
-                              struct obd_capa *, const char *, int, obd_valid,
-                              int, __u32, struct ptlrpc_request **);
+        int (*m_getattr_name)(struct obd_export *, struct md_op_data *,
+                              struct ptlrpc_request **);
         int (*m_intent_lock)(struct obd_export *, struct md_op_data *,
                              void *, int, struct lookup_intent *, int,
                              struct ptlrpc_request **,
index f86dca8..550e0a8 100644 (file)
@@ -1741,16 +1741,14 @@ static inline int md_getstatus(struct obd_export *exp,
         RETURN(rc);
 }
 
-static inline int md_getattr(struct obd_export *exp, const struct lu_fid *fid,
-                             struct obd_capa *oc, obd_valid valid, int ea_size,
+static inline int md_getattr(struct obd_export *exp, struct md_op_data *op_data,
                              struct ptlrpc_request **request)
 {
         int rc;
         ENTRY;
         EXP_CHECK_MD_OP(exp, getattr);
         EXP_MD_COUNTER_INCREMENT(exp, getattr);
-        rc = MDP(exp->exp_obd, getattr)(exp, fid, oc, valid,
-                                        ea_size, request);
+        rc = MDP(exp->exp_obd, getattr)(exp, op_data, request);
         RETURN(rc);
 }
 
@@ -1823,17 +1821,14 @@ static inline int md_enqueue(struct obd_export *exp,
 }
 
 static inline int md_getattr_name(struct obd_export *exp,
-                                  const struct lu_fid *fid, struct obd_capa *oc,
-                                  const char *name, int namelen,
-                                  obd_valid valid, int ea_size, __u32 suppgid,
+                                  struct md_op_data *op_data,
                                   struct ptlrpc_request **request)
 {
         int rc;
         ENTRY;
         EXP_CHECK_MD_OP(exp, getattr_name);
         EXP_MD_COUNTER_INCREMENT(exp, getattr_name);
-        rc = MDP(exp->exp_obd, getattr_name)(exp, fid, oc, name, namelen,
-                                             valid, ea_size, suppgid, request);
+        rc = MDP(exp->exp_obd, getattr_name)(exp, op_data, request);
         RETURN(rc);
 }
 
index 6c53633..100f985 100644 (file)
@@ -478,6 +478,7 @@ static int llu_inode_revalidate(struct inode *inode)
                 struct lustre_md md;
                 struct ptlrpc_request *req = NULL;
                 struct llu_sb_info *sbi = llu_i2sbi(inode);
+                struct md_op_data op_data = { { 0 } };
                 unsigned long valid = OBD_MD_FLGETATTR;
                 int rc, ealen = 0;
 
@@ -487,8 +488,12 @@ static int llu_inode_revalidate(struct inode *inode)
                         ealen = obd_size_diskmd(sbi->ll_dt_exp, NULL);
                         valid |= OBD_MD_FLEASIZE;
                 }
-                rc = md_getattr(sbi->ll_md_exp, ll_inode2fid(inode),
-                                NULL, valid, ealen, &req);
+
+                llu_prep_md_op_data(&op_data, inode, NULL, NULL, 0, ealen,
+                                    LUSTRE_OPC_ANY);
+                op_data.op_valid = valid;
+
+                rc = md_getattr(sbi->ll_md_exp, &op_data, &req);
                 if (rc) {
                         CERROR("failure %d inode %llu\n", rc,
                                (long long)llu_i2stat(inode)->st_ino);
@@ -945,6 +950,7 @@ static int llu_readlink_internal(struct inode *inode,
         struct llu_sb_info *sbi = llu_i2sbi(inode);
         struct mdt_body *body;
         struct intnl_stat *st = llu_i2stat(inode);
+        struct md_op_data op_data = {{ 0 }};
         int rc, symlen = st->st_size + 1;
         ENTRY;
 
@@ -957,8 +963,11 @@ static int llu_readlink_internal(struct inode *inode,
                 RETURN(0);
         }
 
-        rc = md_getattr(sbi->ll_md_exp, ll_inode2fid(inode), NULL,
-                        OBD_MD_LINKNAME, symlen, request);
+        llu_prep_md_op_data(&op_data, inode, NULL, NULL, 0, symlen,
+                            LUSTRE_OPC_ANY);
+        op_data.op_valid = OBD_MD_LINKNAME;
+
+        rc = md_getattr(sbi->ll_md_exp, &op_data, request);
         if (rc) {
                 CERROR("inode %llu: rc = %d\n", (long long)st->st_ino, rc);
                 RETURN(rc);
@@ -1922,6 +1931,7 @@ llu_fsswop_mount(const char *source,
         char *osc = NULL, *mdc = NULL;
         int async = 1, err = -EINVAL;
         struct obd_connect_data ocd = {0,};
+        struct md_op_data op_data = {{0}};
 
         ENTRY;
 
@@ -2054,9 +2064,10 @@ llu_fsswop_mount(const char *source,
         }
         CDEBUG(D_SUPER, "rootfid "DFID"\n", PFID(&sbi->ll_root_fid));
 
+        op_data.op_fid1 = sbi->ll_root_fid;
+        op_data.op_valid = OBD_MD_FLGETATTR | OBD_MD_FLBLOCKS;
         /* fetch attr of root inode */
-        err = md_getattr(sbi->ll_md_exp, &sbi->ll_root_fid, NULL,
-                         OBD_MD_FLGETATTR | OBD_MD_FLBLOCKS, 0, &request);
+        err = md_getattr(sbi->ll_md_exp, &op_data, &request);
         if (err) {
                 CERROR("md_getattr failed for root: rc = %d\n", err);
                 GOTO(out_lock_cn_cb, err);
index 08abc40..e06432d 100644 (file)
@@ -633,17 +633,21 @@ int ll_dir_getstripe(struct inode *inode, struct lov_mds_md **lmmp,
         struct lov_mds_md *lmm = NULL;
         struct ptlrpc_request *req = NULL;
         int rc, lmmsize;
-        struct obd_capa *oc;
+        struct md_op_data *op_data;
 
         rc = ll_get_max_mdsize(sbi, &lmmsize);
         if (rc)
                 RETURN(rc);
 
-        oc = ll_mdscapa_get(inode);
-        rc = md_getattr(sbi->ll_md_exp, ll_inode2fid(inode),
-                        oc, OBD_MD_FLEASIZE | OBD_MD_FLDIREA,
-                        lmmsize, &req);
-        capa_put(oc);
+        op_data = ll_prep_md_op_data(NULL, inode, NULL, NULL,
+                                     0, lmmsize, LUSTRE_OPC_ANY,
+                                     NULL);
+        if (op_data == NULL)
+                RETURN(-ENOMEM);
+
+        op_data->op_valid = OBD_MD_FLEASIZE | OBD_MD_FLDIREA;
+        rc = md_getattr(sbi->ll_md_exp, op_data, &req);
+        ll_finish_md_op_data(op_data);
         if (rc < 0) {
                 CDEBUG(D_INFO, "md_getattr failed on inode "
                        "%lu/%u: rc %d\n", inode->i_ino,
@@ -691,6 +695,32 @@ out:
         return rc;
 }
 
+/*
+ *  Get MDT index for the inode.
+ */
+int ll_get_mdt_idx(struct inode *inode)
+{
+        struct ll_sb_info *sbi = ll_i2sbi(inode);
+        struct md_op_data *op_data;
+        int rc, mdtidx;
+        ENTRY;
+
+        op_data = ll_prep_md_op_data(NULL, inode, NULL, NULL, 0,
+                                     0, LUSTRE_OPC_ANY, NULL);
+        if (op_data == NULL)
+                RETURN(-ENOMEM);
+
+        op_data->op_valid |= OBD_MD_MDTIDX;
+        rc = md_getattr(sbi->ll_md_exp, op_data, NULL);
+        mdtidx = op_data->op_mds;
+        ll_finish_md_op_data(op_data);
+        if (rc < 0) {
+                CDEBUG(D_INFO, "md_getattr_name: %d\n", rc);
+                RETURN(rc);
+        }
+        return mdtidx;
+}
+
 static int ll_dir_ioctl(struct inode *inode, struct file *file,
                         unsigned int cmd, unsigned long arg)
 {
@@ -719,12 +749,24 @@ static int ll_dir_ioctl(struct inode *inode, struct file *file,
         case FSFILT_IOC_SETVERSION_OLD:
         case FSFILT_IOC_SETVERSION:
         */
+        case LL_IOC_GET_MDTIDX: {
+                int mdtidx;
+
+                mdtidx = ll_get_mdt_idx(inode);
+                if (mdtidx < 0)
+                        RETURN(mdtidx);
+
+                if (put_user((int)mdtidx, (int*)arg))
+                        RETURN(-EFAULT);
+
+                return 0;
+        }
         case IOC_MDC_LOOKUP: {
                 struct ptlrpc_request *request = NULL;
                 int namelen, rc, len = 0;
                 char *buf = NULL;
                 char *filename;
-                struct obd_capa *oc;
+                struct md_op_data *op_data;
 
                 rc = obd_ioctl_getdata(&buf, &len, (void *)arg);
                 if (rc)
@@ -732,27 +774,28 @@ static int ll_dir_ioctl(struct inode *inode, struct file *file,
                 data = (void *)buf;
 
                 filename = data->ioc_inlbuf1;
-                namelen = data->ioc_inllen1;
+                namelen = strlen(filename);
 
                 if (namelen < 1) {
                         CDEBUG(D_INFO, "IOC_MDC_LOOKUP missing filename\n");
-                        GOTO(out, rc = -EINVAL);
+                        GOTO(out_free, rc = -EINVAL);
                 }
 
-                oc = ll_mdscapa_get(inode);
-                rc = md_getattr_name(sbi->ll_md_exp, ll_inode2fid(inode), oc,
-                                     filename, namelen, OBD_MD_FLID, 0,
-                                     ll_i2suppgid(inode), &request);
-                capa_put(oc);
+                op_data = ll_prep_md_op_data(NULL, inode, NULL, filename, namelen,
+                                             0, LUSTRE_OPC_ANY, NULL);
+                if (op_data == NULL)
+                        GOTO(out_free, rc = -ENOMEM);
+
+                op_data->op_valid = OBD_MD_FLID;
+                rc = md_getattr_name(sbi->ll_md_exp, op_data, &request);
+                ll_finish_md_op_data(op_data);
                 if (rc < 0) {
                         CDEBUG(D_INFO, "md_getattr_name: %d\n", rc);
-                        GOTO(out, rc);
+                        GOTO(out_free, rc);
                 }
-
                 ptlrpc_req_finished(request);
-
                 EXIT;
-        out:
+out_free:
                 obd_ioctl_freedata(buf, len);
                 return rc;
         }
index 44eaaa2..2d864c1 100644 (file)
@@ -1286,19 +1286,22 @@ int ll_lov_getstripe_ea_info(struct inode *inode, const char *filename,
         struct mdt_body  *body;
         struct lov_mds_md *lmm = NULL;
         struct ptlrpc_request *req = NULL;
-        struct obd_capa *oc;
+        struct md_op_data *op_data;
         int rc, lmmsize;
 
         rc = ll_get_max_mdsize(sbi, &lmmsize);
         if (rc)
                 RETURN(rc);
 
-        oc = ll_mdscapa_get(inode);
-        rc = md_getattr_name(sbi->ll_md_exp, ll_inode2fid(inode),
-                             oc, filename, strlen(filename) + 1,
-                             OBD_MD_FLEASIZE | OBD_MD_FLDIREA, lmmsize,
-                             ll_i2suppgid(inode), &req);
-        capa_put(oc);
+        op_data = ll_prep_md_op_data(NULL, inode, NULL, filename,
+                                     strlen(filename), lmmsize,
+                                     LUSTRE_OPC_ANY, NULL);
+        if (op_data == NULL)
+                RETURN(-ENOMEM);
+
+        op_data->op_valid = OBD_MD_FLEASIZE | OBD_MD_FLDIREA;
+        rc = md_getattr_name(sbi->ll_md_exp, op_data, &req);
+        ll_finish_md_op_data(op_data);
         if (rc < 0) {
                 CDEBUG(D_INFO, "md_getattr_name failed "
                        "on %s: rc %d\n", filename, rc);
@@ -1770,6 +1773,19 @@ int ll_file_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
         case OBD_IOC_FID2PATH:
                 RETURN(ll_fid2path(ll_i2mdexp(inode), (void *)arg));
 
+        case LL_IOC_GET_MDTIDX: {
+                int mdtidx;
+
+                mdtidx = ll_get_mdt_idx(inode);
+                if (mdtidx < 0)
+                        RETURN(mdtidx);
+
+                if (put_user((int)mdtidx, (int*)arg))
+                        RETURN(-EFAULT);
+
+                RETURN(0);
+        }
+
         default: {
                 int err;
 
@@ -2124,10 +2140,9 @@ int __ll_inode_revalidate_it(struct dentry *dentry, struct lookup_intent *it,
 
                 ll_lookup_finish_locks(&oit, dentry);
         } else if (!ll_have_md_lock(dentry->d_inode, ibits)) {
-
                 struct ll_sb_info *sbi = ll_i2sbi(dentry->d_inode);
                 obd_valid valid = OBD_MD_FLGETATTR;
-                struct obd_capa *oc;
+                struct md_op_data *op_data;
                 int ealen = 0;
 
                 if (S_ISREG(inode->i_mode)) {
@@ -2136,13 +2151,19 @@ int __ll_inode_revalidate_it(struct dentry *dentry, struct lookup_intent *it,
                                 RETURN(rc);
                         valid |= OBD_MD_FLEASIZE | OBD_MD_FLMODEASIZE;
                 }
+
+                op_data = ll_prep_md_op_data(NULL, inode, NULL, NULL,
+                                             0, ealen, LUSTRE_OPC_ANY,
+                                             NULL);
+                if (op_data == NULL)
+                        RETURN(-ENOMEM);
+
+                op_data->op_valid = valid;
                 /* Once OBD_CONNECT_ATTRFID is not supported, we can't find one
                  * capa for this inode. Because we only keep capas of dirs
                  * fresh. */
-                oc = ll_mdscapa_get(inode);
-                rc = md_getattr(sbi->ll_md_exp, ll_inode2fid(inode), oc, valid,
-                                ealen, &req);
-                capa_put(oc);
+                rc = md_getattr(sbi->ll_md_exp, op_data, &req);
+                ll_finish_md_op_data(op_data);
                 if (rc) {
                         rc = ll_inode_revalidate_fini(inode, rc);
                         RETURN(rc);
index bd2fe50..00f933c 100644 (file)
@@ -573,6 +573,8 @@ extern struct file_operations ll_dir_operations;
 extern struct inode_operations ll_dir_inode_operations;
 struct page *ll_get_dir_page(struct inode *dir, __u64 hash, int exact,
                              struct ll_dir_chain *chain);
+
+int ll_get_mdt_idx(struct inode *inode);
 /* llite/namei.c */
 int ll_objects_destroy(struct ptlrpc_request *request,
                        struct inode *dir);
index 549f72e..4d117c5 100644 (file)
@@ -170,6 +170,7 @@ static int client_common_fill_super(struct super_block *sb, char *md, char *dt)
         struct ptlrpc_request *request = NULL;
         struct obd_connect_data *data = NULL;
         struct obd_uuid *uuid;
+        struct md_op_data *op_data;
         struct lustre_md lmd;
         obd_valid valid;
         int size, err, checksum;
@@ -418,10 +419,19 @@ static int client_common_fill_super(struct super_block *sb, char *md, char *dt)
         else if (sbi->ll_flags & LL_SBI_ACL)
                 valid |= OBD_MD_FLACL;
 
-        err = md_getattr(sbi->ll_md_exp, &sbi->ll_root_fid, oc, valid, 0,
-                         &request);
+        OBD_ALLOC_PTR(op_data);
+        if (op_data == NULL) 
+                GOTO(out_lock_cn_cb, err = -ENOMEM);
+
+        op_data->op_fid1 = sbi->ll_root_fid;
+        op_data->op_mode = 0;
+        op_data->op_capa1 = oc;
+        op_data->op_valid = valid;
+
+        err = md_getattr(sbi->ll_md_exp, op_data, &request);
         if (oc)
                 capa_put(oc);
+        OBD_FREE_PTR(op_data);
         if (err) {
                 CERROR("md_getattr failed for root: rc = %d\n", err);
                 GOTO(out_lock_cn_cb, err);
@@ -1770,12 +1780,17 @@ int ll_iocontrol(struct inode *inode, struct file *file,
         switch(cmd) {
         case FSFILT_IOC_GETFLAGS: {
                 struct mdt_body *body;
-                struct obd_capa *oc;
+                struct md_op_data *op_data;
 
-                oc = ll_mdscapa_get(inode);
-                rc = md_getattr(sbi->ll_md_exp, ll_inode2fid(inode), oc,
-                                OBD_MD_FLFLAGS, 0, &req);
-                capa_put(oc);
+                op_data = ll_prep_md_op_data(NULL, inode, NULL, NULL,
+                                             0, 0, LUSTRE_OPC_ANY,
+                                             NULL);
+                if (op_data == NULL)
+                        RETURN(-ENOMEM);
+
+                op_data->op_valid = OBD_MD_FLFLAGS;
+                rc = md_getattr(sbi->ll_md_exp, op_data, &req);
+                ll_finish_md_op_data(op_data);
                 if (rc) {
                         CERROR("failure %d inode %lu\n", rc, inode->i_ino);
                         RETURN(-abs(rc));
index fb6c9c1..36b60a7 100644 (file)
@@ -66,9 +66,9 @@ static struct inode *search_inode_for_lustre(struct super_block *sb,
         struct ll_sb_info     *sbi = ll_s2sbi(sb);
         struct ptlrpc_request *req = NULL;
         struct inode          *inode = NULL;
-        unsigned long         valid = 0;
         int                   eadatalen = 0;
         ino_t                 ino = cl_fid_build_ino(fid);
+        struct  md_op_data    *op_data;
         int                   rc;
         ENTRY;
 
@@ -78,16 +78,24 @@ static struct inode *search_inode_for_lustre(struct super_block *sb,
         if (rc)
                 RETURN(ERR_PTR(rc));
 
-        valid |= OBD_MD_FLEASIZE;
+        /* Because inode is NULL, ll_prep_md_op_data can not
+         * be used here. So we allocate op_data ourselves */
+        OBD_ALLOC_PTR(op_data);
+        if (op_data == NULL)
+                return ERR_PTR(-ENOMEM);
+
+        op_data->op_fid1 = *fid;
+        op_data->op_mode = eadatalen;
+        op_data->op_valid = OBD_MD_FLEASIZE;
 
         /* mds_fid2dentry ignores f_type */
-        rc = md_getattr(sbi->ll_md_exp, fid, NULL, valid, eadatalen, &req);
+        rc = md_getattr(sbi->ll_md_exp, op_data, &req);
+        OBD_FREE_PTR(op_data);
         if (rc) {
                 CERROR("can't get object attrs, fid "DFID", rc %d\n",
                        PFID(fid), rc);
                 RETURN(ERR_PTR(rc));
         }
-
         rc = ll_prep_inode(&inode, req, sb);
         ptlrpc_req_finished(req);
         if (rc)
@@ -228,7 +236,6 @@ static struct dentry *ll_get_dentry(struct super_block *sb, void *data)
         RETURN(entry);
 }
 #endif
-
 static struct dentry *ll_get_parent(struct dentry *dchild)
 {
         struct ptlrpc_request *req = NULL;
@@ -237,6 +244,7 @@ static struct dentry *ll_get_parent(struct dentry *dchild)
         struct dentry         *result = NULL;
         struct mdt_body       *body;
         static char           dotdot[] = "..";
+        struct md_op_data     *op_data;
         int                   rc;
         ENTRY;
 
@@ -244,12 +252,17 @@ static struct dentry *ll_get_parent(struct dentry *dchild)
 
         sbi = ll_s2sbi(dir->i_sb);
 
-        CDEBUG(D_INFO, "getting parent for (%lu,"DFID")\n", 
+        CDEBUG(D_INFO, "getting parent for (%lu,"DFID")\n",
                         dir->i_ino, PFID(ll_inode2fid(dir)));
 
-        rc = md_getattr_name(sbi->ll_md_exp, ll_inode2fid(dir), NULL,
-                             dotdot, strlen(dotdot) + 1, 0, 0,
-                             ll_i2suppgid(dir), &req);
+        op_data = ll_prep_md_op_data(NULL, dir, NULL, dotdot,
+                                     strlen(dotdot), 0,
+                                     LUSTRE_OPC_ANY, NULL);
+        if (op_data == NULL)
+                RETURN(ERR_PTR(-ENOMEM));
+
+        rc = md_getattr_name(sbi->ll_md_exp, op_data, &req);
+        ll_finish_md_op_data(op_data);
         if (rc) {
                 CERROR("failure %d inode %lu get parent\n", rc, dir->i_ino);
                 RETURN(ERR_PTR(rc));
@@ -257,7 +270,7 @@ static struct dentry *ll_get_parent(struct dentry *dchild)
         body = req_capsule_server_get(&req->rq_pill, &RMF_MDT_BODY);
         LASSERT(body->valid & OBD_MD_FLID);
 
-        CDEBUG(D_INFO, "parent for "DFID" is "DFID"\n", 
+        CDEBUG(D_INFO, "parent for "DFID" is "DFID"\n",
                 PFID(ll_inode2fid(dir)), PFID(&body->fid1));
 
         result = ll_iget_for_nfs(dir->i_sb, &body->fid1);
index 5cbab48..5d51215 100644 (file)
@@ -51,7 +51,7 @@ static int ll_readlink_internal(struct inode *inode,
         struct ll_sb_info *sbi = ll_i2sbi(inode);
         int rc, symlen = i_size_read(inode) + 1;
         struct mdt_body *body;
-        struct obd_capa *oc;
+        struct md_op_data *op_data;
         ENTRY;
 
         *request = NULL;
@@ -62,10 +62,11 @@ static int ll_readlink_internal(struct inode *inode,
                 RETURN(0);
         }
 
-        oc = ll_mdscapa_get(inode);
-        rc = md_getattr(sbi->ll_md_exp, ll_inode2fid(inode), oc,
-                        OBD_MD_LINKNAME, symlen, request);
-        capa_put(oc);
+        op_data = ll_prep_md_op_data(NULL, inode, NULL, NULL, 0, symlen,
+                                     LUSTRE_OPC_ANY, NULL);
+        op_data->op_valid = OBD_MD_LINKNAME;
+        rc = md_getattr(sbi->ll_md_exp, op_data, request);
+        ll_finish_md_op_data(op_data);
         if (rc) {
                 if (rc != -ENOENT)
                         CERROR("inode %lu: rc = %d\n", inode->i_ino, rc);
index 46bc2a2..58c50c3 100644 (file)
@@ -1269,8 +1269,7 @@ static int lmv_setxattr(struct obd_export *exp, const struct lu_fid *fid,
         RETURN(rc);
 }
 
-static int lmv_getattr(struct obd_export *exp, const struct lu_fid *fid,
-                       struct obd_capa *oc, obd_valid valid, int ea_size,
+static int lmv_getattr(struct obd_export *exp, struct md_op_data *op_data,
                        struct ptlrpc_request **request)
 {
         struct obd_device       *obd = exp->exp_obd;
@@ -1285,17 +1284,22 @@ static int lmv_getattr(struct obd_export *exp, const struct lu_fid *fid,
         if (rc)
                 RETURN(rc);
 
-        tgt = lmv_find_target(lmv, fid);
+        tgt = lmv_find_target(lmv, &op_data->op_fid1);
         if (IS_ERR(tgt))
                 RETURN(PTR_ERR(tgt));
 
-        rc = md_getattr(tgt->ltd_exp, fid, oc, valid, ea_size, request);
+        if (op_data->op_valid & OBD_MD_MDTIDX) {
+                op_data->op_mds = tgt->ltd_idx;
+                RETURN(0);
+        }
+
+        rc = md_getattr(tgt->ltd_exp, op_data, request);
         if (rc)
                 RETURN(rc);
 
-        obj = lmv_object_find_lock(obd, fid);
+        obj = lmv_object_find_lock(obd, &op_data->op_fid1);
 
-        CDEBUG(D_INODE, "GETATTR for "DFID" %s\n", PFID(fid),
+        CDEBUG(D_INODE, "GETATTR for "DFID" %s\n", PFID(&op_data->op_fid1),
                obj ? "(split)" : "");
 
         /*
@@ -1399,6 +1403,7 @@ int lmv_handle_split(struct obd_export *exp, const struct lu_fid *fid)
         struct lmv_tgt_desc     *tgt;
         struct lmv_object       *obj;
         struct lustre_md         md;
+        struct md_op_data       *op_data;
         int                      mealen;
         int                      rc;
         __u64                    valid;
@@ -1416,7 +1421,17 @@ int lmv_handle_split(struct obd_export *exp, const struct lu_fid *fid)
         /*
          * Time to update mea of parent fid.
          */
-        rc = md_getattr(tgt->ltd_exp, fid, NULL, valid, mealen, &req);
+
+        OBD_ALLOC_PTR(op_data);
+        if (op_data == NULL) 
+                RETURN(-ENOMEM);
+
+        op_data->op_fid1 = *fid;
+        op_data->op_mode = mealen;
+        op_data->op_valid = valid;
+
+        rc = md_getattr(tgt->ltd_exp, op_data, &req);
+        OBD_FREE_PTR(op_data);
         if (rc) {
                 CERROR("md_getattr() failed, error %d\n", rc);
                 GOTO(cleanup, rc);
@@ -1734,18 +1749,17 @@ lmv_enqueue(struct obd_export *exp, struct ldlm_enqueue_info *einfo,
 }
 
 static int
-lmv_getattr_name(struct obd_export *exp, const struct lu_fid *fid,
-                 struct obd_capa *oc, const char *name, int namelen,
-                 obd_valid valid, int ea_size, __u32 suppgid,
+lmv_getattr_name(struct obd_export *exp,struct md_op_data *op_data,
                  struct ptlrpc_request **request)
 {
         struct ptlrpc_request   *req = NULL;
         struct obd_device       *obd = exp->exp_obd;
         struct lmv_obd          *lmv = &obd->u.lmv;
-        struct lu_fid            rid = *fid;
+        struct lu_fid            rid = op_data->op_fid1;
         struct lmv_tgt_desc     *tgt;
         struct mdt_body         *body;
         struct lmv_object       *obj;
+        obd_valid                valid = op_data->op_valid;
         int                      rc;
         int                      loop = 0;
         int                      sidx;
@@ -1761,23 +1775,27 @@ repeat:
         obj = lmv_object_find(obd, &rid);
         if (obj) {
                 sidx = raw_name2idx(obj->lo_hashtype, obj->lo_objcount,
-                                       name, namelen - 1);
+                                    op_data->op_name, op_data->op_namelen);
                 rid = obj->lo_stripes[sidx].ls_fid;
                 tgt = lmv_get_target(lmv, obj->lo_stripes[sidx].ls_mds);
+                op_data->op_mds = obj->lo_stripes[sidx].ls_mds;
                 valid &= ~OBD_MD_FLCKSPLIT;
                 lmv_object_put(obj);
         } else {
                 tgt = lmv_find_target(lmv, &rid);
                 valid |= OBD_MD_FLCKSPLIT;
+                op_data->op_mds = tgt->ltd_idx;
         }
         if (IS_ERR(tgt))
                 RETURN(PTR_ERR(tgt));
 
         CDEBUG(D_INODE, "GETATTR_NAME for %*s on "DFID" - "DFID" -> mds #%d\n",
-               namelen, name, PFID(fid), PFID(&rid), tgt->ltd_idx);
+               op_data->op_namelen, op_data->op_name, PFID(&op_data->op_fid1),
+               PFID(&rid), tgt->ltd_idx);
 
-        rc = md_getattr_name(tgt->ltd_exp, &rid, oc, name, namelen, valid,
-                             ea_size, suppgid, request);
+        op_data->op_valid = valid;
+        op_data->op_fid1 = rid;
+        rc = md_getattr_name(tgt->ltd_exp, op_data, request);
         if (rc == 0) {
                 body = req_capsule_server_get(&(*request)->rq_pill,
                                               &RMF_MDT_BODY);
@@ -1794,9 +1812,11 @@ repeat:
                                 RETURN(PTR_ERR(tgt));
                         }
 
-                        rc = md_getattr_name(tgt->ltd_exp, &rid, NULL, NULL,
-                                             1, valid | OBD_MD_FLCROSSREF,
-                                             ea_size, suppgid, &req);
+                        op_data->op_fid1 = rid;
+                        op_data->op_valid |= OBD_MD_FLCROSSREF;
+                        op_data->op_namelen = 0;
+                        op_data->op_name = NULL;
+                        rc = md_getattr_name(tgt->ltd_exp, op_data, &req);
                         ptlrpc_req_finished(*request);
                         *request = req;
                 }
index 820e0d6..6b3d821 100644 (file)
@@ -329,15 +329,16 @@ struct lmv_object *lmv_object_create(struct obd_export *exp,
                PFID(fid));
 
         md.mea = NULL;
-       
+
         if (mea == NULL) {
+                struct md_op_data *op_data;
                 __u64 valid;
 
                 CDEBUG(D_INODE, "Mea isn't passed in, get it now\n");
                 mealen = lmv_get_easize(lmv);
 
-                /* 
-                 * Time to update mea of parent fid. 
+                /*
+                 * Time to update mea of parent fid.
                  */
                 md.mea = NULL;
                 valid = OBD_MD_FLEASIZE | OBD_MD_FLDIREA | OBD_MD_MEA;
@@ -346,7 +347,15 @@ struct lmv_object *lmv_object_create(struct obd_export *exp,
                 if (IS_ERR(tgt))
                         GOTO(cleanup, obj = (void *)tgt);
 
-                rc = md_getattr(tgt->ltd_exp, fid, NULL, valid, mealen, &req);
+                OBD_ALLOC_PTR(op_data);
+                if (op_data == NULL)
+                        GOTO(cleanup, obj = ERR_PTR(-ENOMEM));
+
+                op_data->op_fid1 = *fid;
+                op_data->op_mode = mealen;
+                op_data->op_valid = valid;
+                rc = md_getattr(tgt->ltd_exp, op_data, &req);
+                OBD_FREE_PTR(op_data);
                 if (rc) {
                         CERROR("md_getattr() failed, error %d\n", rc);
                         GOTO(cleanup, obj = ERR_PTR(rc));
@@ -364,8 +373,8 @@ struct lmv_object *lmv_object_create(struct obd_export *exp,
                 mea = md.mea;
         }
 
-        /* 
-         * Got mea, now create obj for it. 
+        /*
+         * Got mea, now create obj for it.
          */
         obj = __lmv_object_create(obd, fid, mea);
         if (!obj) {
index b364881..a02b180 100644 (file)
@@ -202,8 +202,7 @@ static int mdc_getattr_common(struct obd_export *exp,
         RETURN(0);
 }
 
-int mdc_getattr(struct obd_export *exp, const struct lu_fid *fid,
-                struct obd_capa *oc, obd_valid valid, int ea_size,
+int mdc_getattr(struct obd_export *exp, struct md_op_data *op_data,
                 struct ptlrpc_request **request)
 {
         struct ptlrpc_request *req;
@@ -215,7 +214,7 @@ int mdc_getattr(struct obd_export *exp, const struct lu_fid *fid,
         if (req == NULL)
                 RETURN(-ENOMEM);
 
-        mdc_set_capa_size(req, &RMF_CAPA1, oc);
+        mdc_set_capa_size(req, &RMF_CAPA1, op_data->op_capa1);
 
         rc = ptlrpc_request_pack(req, LUSTRE_MDS_VERSION, MDS_GETATTR);
         if (rc) {
@@ -223,10 +222,12 @@ int mdc_getattr(struct obd_export *exp, const struct lu_fid *fid,
                 RETURN(rc);
         }
 
-        mdc_pack_body(req, fid, oc, valid, ea_size, -1, 0);
+        mdc_pack_body(req, &op_data->op_fid1, op_data->op_capa1,
+                      op_data->op_valid, op_data->op_mode, -1, 0);
 
-        req_capsule_set_size(&req->rq_pill, &RMF_MDT_MD, RCL_SERVER, ea_size);
-        if (valid & OBD_MD_FLRMTPERM) {
+        req_capsule_set_size(&req->rq_pill, &RMF_MDT_MD, RCL_SERVER,
+                             op_data->op_mode);
+        if (op_data->op_valid & OBD_MD_FLRMTPERM) {
                 LASSERT(client_is_remote(exp));
                 req_capsule_set_size(&req->rq_pill, &RMF_ACL, RCL_SERVER,
                                      sizeof(struct mdt_remote_perm));
@@ -241,9 +242,7 @@ int mdc_getattr(struct obd_export *exp, const struct lu_fid *fid,
         RETURN(rc);
 }
 
-int mdc_getattr_name(struct obd_export *exp, const struct lu_fid *fid,
-                     struct obd_capa *oc, const char *filename, int namelen,
-                     obd_valid valid, int ea_size, __u32 suppgid,
+int mdc_getattr_name(struct obd_export *exp, struct md_op_data *op_data,
                      struct ptlrpc_request **request)
 {
         struct ptlrpc_request *req;
@@ -256,8 +255,9 @@ int mdc_getattr_name(struct obd_export *exp, const struct lu_fid *fid,
         if (req == NULL)
                 RETURN(-ENOMEM);
 
-        mdc_set_capa_size(req, &RMF_CAPA1, oc);
-        req_capsule_set_size(&req->rq_pill, &RMF_NAME, RCL_CLIENT, namelen);
+        mdc_set_capa_size(req, &RMF_CAPA1, op_data->op_capa1);
+        req_capsule_set_size(&req->rq_pill, &RMF_NAME, RCL_CLIENT,
+                             op_data->op_namelen + 1);
 
         rc = ptlrpc_request_pack(req, LUSTRE_MDS_VERSION, MDS_GETATTR_NAME);
         if (rc) {
@@ -265,15 +265,19 @@ int mdc_getattr_name(struct obd_export *exp, const struct lu_fid *fid,
                 RETURN(rc);
         }
 
-        mdc_pack_body(req, fid, oc, valid, ea_size, suppgid, 0);
+        mdc_pack_body(req, &op_data->op_fid1, op_data->op_capa1,
+                      op_data->op_valid, op_data->op_mode,
+                      op_data->op_suppgids[0], 0);
 
-        if (filename) {
+        if (op_data->op_name) {
                 char *name = req_capsule_client_get(&req->rq_pill, &RMF_NAME);
-                LASSERT(strnlen(filename, namelen) == namelen - 1);
-                memcpy(name, filename, namelen);
+                LASSERT(strnlen(op_data->op_name, op_data->op_namelen) ==
+                                op_data->op_namelen);
+                memcpy(name, op_data->op_name, op_data->op_namelen);
         }
 
-        req_capsule_set_size(&req->rq_pill, &RMF_MDT_MD, RCL_SERVER, ea_size);
+        req_capsule_set_size(&req->rq_pill, &RMF_MDT_MD, RCL_SERVER,
+                             op_data->op_mode);
         ptlrpc_request_set_replen(req);
 
         rc = mdc_getattr_common(exp, req);
index 2457ba5..6de2f29 100644 (file)
@@ -134,7 +134,7 @@ command_t cmdlist[] = {
          "usage: getstripe [--obd|-O <uuid>] [--quiet | -q] [--verbose | -v]\n"
          "                 [--count | -c ] [--size | -s ] [--index | -i ]\n"
          "                 [--offset | -o ] [--pool | -p ] [--directory | -d]\n"
-         "                 [--recursive | -r] <dir|file> ..."},
+         "                 [--mdt | -M] [--recursive | -r] <dir|file> ..."},
         {"pool_list", lfs_poollist, 0,
          "List pools or pool OSTs\n"
          "usage: pool_list <fsname>[.<pool>] | <pathname>\n"},
@@ -825,6 +825,7 @@ static int lfs_getstripe(int argc, char **argv)
                 {"pool", 0, 0, 'p'},
                 {"verbose", 0, 0, 'v'},
                 {"directory", 0, 0, 'd'},
+                {"mdt", 0, 0, 'M'},
                 {0, 0, 0, 0}
         };
         int c, rc;
@@ -832,7 +833,7 @@ static int lfs_getstripe(int argc, char **argv)
 
         param.maxdepth = 1;
         optind = 0;
-        while ((c = getopt_long(argc, argv, "cdhioO:pqrsv",
+        while ((c = getopt_long(argc, argv, "cdhiMoO:pqrsv",
                                 long_opts, NULL)) != -1) {
                 switch (c) {
                 case 'O':
@@ -878,6 +879,9 @@ static int lfs_getstripe(int argc, char **argv)
                 case 'p':
                         param.verbose |= VERBOSE_POOL;
                         break;
+                case 'M':
+                        param.get_mdt_index = 1;
+                        break;
                 case '?':
                         return CMD_HELP;
                 default:
@@ -1135,7 +1139,7 @@ static int lfs_df(int argc, char **argv)
         };
 
         optind = 0;
-        while ((c = getopt_long(argc, argv, "ihp:", long_opts, NULL)) != -1) {
+        while ((c = getopt_long(argc, argv, "hip:", long_opts, NULL)) != -1) {
                 switch (c) {
                 case 'i':
                         ishow = 1;
@@ -1644,7 +1648,7 @@ int lfs_setquota_times(int argc, char **argv)
         qctl.qc_type = UGQUOTA;
 
         optind = 0;
-        while ((c = getopt_long(argc, argv, "ugb:i:t", long_opts, NULL)) != -1) {
+        while ((c = getopt_long(argc, argv, "b:i:gtu", long_opts, NULL)) != -1) {
                 switch (c) {
                 case 'u':
                 case 'g':
@@ -1734,7 +1738,7 @@ int lfs_setquota(int argc, char **argv)
                                  * isn't reinitialized from command line */
 
         optind = 0;
-        while ((c = getopt_long(argc, argv, "u:g:b:B:i:I:", long_opts, NULL)) != -1) {
+        while ((c = getopt_long(argc, argv, "b:B:i:I:g:u:", long_opts, NULL)) != -1) {
                 switch (c) {
                 case 'u':
                 case 'g':
index b62736b..96d31e6 100644 (file)
@@ -946,18 +946,18 @@ int llapi_mds_getfileinfo(char *path, DIR *parent,
                         if (ret) {
                                 llapi_err(LLAPI_MSG_ERROR,
                                           "error: %s: lstat failed for %s",
-                                          __FUNCTION__, path);
+                                          __func__, path);
                                 return ret;
                         }
                 } else if (errno == ENOENT) {
                         llapi_err(LLAPI_MSG_WARN,
                                   "warning: %s: %s does not exist",
-                                  __FUNCTION__, path);
+                                  __func__, path);
                         return -ENOENT;
                 } else {
                         llapi_err(LLAPI_MSG_ERROR,
                                  "error: %s: IOC_MDC_GETFILEINFO failed for %s",
-                                 __FUNCTION__, path);
+                                 __func__, path);
                         return ret;
                 }
         }
@@ -980,7 +980,7 @@ static int llapi_semantic_traverse(char *path, int size, DIR *parent,
         d = opendir(path);
         if (!d && errno != ENOTDIR) {
                 llapi_err(LLAPI_MSG_ERROR, "%s: Failed to open '%s'",
-                          __FUNCTION__, path);
+                          __func__, path);
                 return -EINVAL;
         } else if (!d && !parent) {
                 /* ENOTDIR. Open the parent dir. */
@@ -1009,7 +1009,7 @@ static int llapi_semantic_traverse(char *path, int size, DIR *parent,
                 if ((len + dent->d_reclen + 2) > size) {
                         llapi_err(LLAPI_MSG_ERROR,
                                   "error: %s: string buffer is too small",
-                                  __FUNCTION__);
+                                  __func__);
                         break;
                 }
                 strcat(path, "/");
@@ -1034,7 +1034,7 @@ static int llapi_semantic_traverse(char *path, int size, DIR *parent,
                 case DT_UNKNOWN:
                         llapi_err(LLAPI_MSG_ERROR,
                                   "error: %s: '%s' is UNKNOWN type %d",
-                                  __FUNCTION__, dent->d_name, dent->d_type);
+                                  __func__, dent->d_name, dent->d_type);
                         break;
                 case DT_DIR:
                         ret = llapi_semantic_traverse(path, size, d, sem_init,
@@ -1267,7 +1267,7 @@ static int setup_obd_uuid(DIR *dir, char *dname, struct find_param *param)
         if (param->obduuid && (param->obdindex == OBD_NOT_FOUND)) {
                 llapi_err_noerrno(LLAPI_MSG_ERROR,
                                   "error: %s: unknown obduuid: %s",
-                                  __FUNCTION__, param->obduuid->uuid);
+                                  __func__, param->obduuid->uuid);
                 rc = -EINVAL;
         }
 
@@ -1324,7 +1324,7 @@ retry_get_uuids:
                         param->obdindexes[obdnum] = OBD_NOT_FOUND;
                         llapi_err_noerrno(LLAPI_MSG_ERROR,
                                           "error: %s: unknown obduuid: %s",
-                                          __FUNCTION__,
+                                          __func__,
                                           param->obduuid[obdnum].uuid);
                         ret = -EINVAL;
                 }
@@ -1722,17 +1722,17 @@ static int cb_find_init(char *path, DIR *parent, DIR *dir,
                         if (ret) {
                                 llapi_err(LLAPI_MSG_ERROR,
                                           "error: %s: lstat failed for %s",
-                                          __FUNCTION__, path);
+                                          __func__, path);
                                 return ret;
                         }
                 } else if (errno == ENOENT) {
                         llapi_err(LLAPI_MSG_WARN,
                                   "warning: %s: %s does not exist",
-                                  __FUNCTION__, path);
+                                  __func__, path);
                         goto decided;
                 } else {
                         llapi_err(LLAPI_MSG_ERROR,"error: %s: %s failed for %s",
-                                  __FUNCTION__, dir ? "LL_IOC_MDC_GETINFO" :
+                                  __func__, dir ? "LL_IOC_MDC_GETINFO" :
                                   "IOC_MDC_GETFILEINFO", path);
                         return ret;
                 }
@@ -1903,12 +1903,12 @@ obd_matches:
                         if (errno == ENOENT) {
                                 llapi_err(LLAPI_MSG_ERROR,
                                           "warning: %s: %s does not exist",
-                                          __FUNCTION__, path);
+                                          __func__, path);
                                 goto decided;
                         } else {
                                 llapi_err(LLAPI_MSG_ERROR,
                                           "%s: IOC_LOV_GETINFO on %s failed",
-                                          __FUNCTION__, path);
+                                          __func__, path);
                                 return ret;
                         }
                 }
@@ -1944,7 +1944,80 @@ decided:
 
 int llapi_find(char *path, struct find_param *param)
 {
-        return param_callback(path, cb_find_init, cb_common_fini, param);        
+        return param_callback(path, cb_find_init, cb_common_fini, param);
+}
+
+/*
+ * Get MDT number that the file/directory inode referenced
+ * by the open fd resides on.
+ * Return 0 and mdtidx on success, or -ve errno.
+ */
+int llapi_file_fget_mdtidx(int fd, int *mdtidx)
+{
+        if (ioctl(fd, LL_IOC_GET_MDTIDX, &mdtidx) < 0)
+                return -errno;
+        return 0;
+}
+
+static int cb_get_mdt_index(char *path, DIR *parent, DIR *d, void *data,
+                            cfs_dirent_t *de)
+{
+        struct find_param *param = (struct find_param *)data;
+        int ret = 0;
+        int mdtidx;
+
+        LASSERT(parent != NULL || d != NULL);
+
+        if (d) {
+                ret = llapi_file_fget_mdtidx(dirfd(d), &mdtidx);
+        } else if (parent) {
+                int fd;
+
+                fd = open(path, O_RDONLY);
+                if (fd > 0) {
+                        ret = llapi_file_fget_mdtidx(fd, &mdtidx);
+                        close(fd);
+                } else {
+                        ret = fd;
+                }
+        }
+
+        if (ret) {
+                if (errno == ENODATA) {
+                        if (!param->obduuid)
+                                llapi_printf(LLAPI_MSG_NORMAL,
+                                             "%s has no stripe info\n", path);
+                        goto out;
+                } else if (errno == ENOTTY) {
+                        llapi_err(LLAPI_MSG_ERROR,
+                                  "%s: '%s' not on a Lustre fs?",
+                                  __func__, path);
+                } else if (errno == ENOENT) {
+                        llapi_err(LLAPI_MSG_WARN,
+                                  "warning: %s: %s does not exist",
+                                  __func__, path);
+                        goto out;
+                } else {
+                        llapi_err(LLAPI_MSG_ERROR,
+                                  "error: %s: LL_IOC_GET_MDTIDX failed for %s",
+                                   __func__, path);
+                }
+                return ret;
+        }
+
+        if (param->quiet)
+                llapi_printf(LLAPI_MSG_NORMAL, "%d\n", mdtidx);
+        else
+                llapi_printf(LLAPI_MSG_NORMAL, "%s MDT index: %d\n",
+                             path, mdtidx);
+
+out:
+        /* Do not get down anymore? */
+        if (param->depth == param->maxdepth)
+                return 1;
+
+        param->depth++;
+        return 0;
 }
 
 static int cb_getstripe(char *path, DIR *parent, DIR *d, void *data,
@@ -1970,6 +2043,7 @@ static int cb_getstripe(char *path, DIR *parent, DIR *d, void *data,
                 fname = (fname == NULL ? path : fname + 1);
 
                 strncpy((char *)&param->lmd->lmd_lmm, fname, param->lumlen);
+
                 ret = ioctl(dirfd(parent), IOC_MDC_GETFILESTRIPE,
                             (void *)&param->lmd->lmd_lmm);
         }
@@ -1983,23 +2057,25 @@ static int cb_getstripe(char *path, DIR *parent, DIR *d, void *data,
                 } else if (errno == ENOTTY) {
                         llapi_err(LLAPI_MSG_ERROR,
                                   "%s: '%s' not on a Lustre fs?",
-                                  __FUNCTION__, path);
+                                  __func__, path);
                 } else if (errno == ENOENT) {
                         llapi_err(LLAPI_MSG_WARN,
                                   "warning: %s: %s does not exist",
-                                  __FUNCTION__, path);
+                                  __func__, path);
                         goto out;
                 } else {
                         llapi_err(LLAPI_MSG_ERROR,
                                   "error: %s: %s failed for %s",
-                                   __FUNCTION__, d ? "LL_IOC_LOV_GETSTRIPE" :
+                                   __func__, d ? "LL_IOC_LOV_GETSTRIPE" :
                                   "IOC_MDC_GETFILESTRIPE", path);
                 }
 
                 return ret;
         }
 
-        llapi_lov_dump_user_lmm(param, path, d ? 1 : 0);
+        if (!param->get_mdt_index)
+                llapi_lov_dump_user_lmm(param, path, d ? 1 : 0);
+
 out:
         /* Do not get down anymore? */
         if (param->depth == param->maxdepth)
@@ -2011,7 +2087,9 @@ out:
 
 int llapi_getstripe(char *path, struct find_param *param)
 {
-        return param_callback(path, cb_getstripe, cb_common_fini, param);
+        return param_callback(path, param->get_mdt_index ?
+                              cb_get_mdt_index : cb_getstripe,
+                              cb_common_fini, param);
 }
 
 int llapi_obd_statfs(char *path, __u32 type, __u32 index,
@@ -2046,7 +2124,7 @@ int llapi_obd_statfs(char *path, __u32 type, __u32 index,
         if (fd < 0) {
                 rc = errno ? -errno : -EBADF;
                 llapi_err(LLAPI_MSG_ERROR, "error: %s: opening '%s'",
-                          __FUNCTION__, path);
+                          __func__, path);
                 return rc;
         }
         rc = ioctl(fd, IOC_OBD_STATFS, (void *)rawbuf);
@@ -2297,7 +2375,7 @@ static int cb_quotachown(char *path, DIR *parent, DIR *d, void *data,
                 } else if (errno == ENOENT) {
                         llapi_err(LLAPI_MSG_ERROR,
                                   "warning: %s: %s does not exist",
-                                  __FUNCTION__, path);
+                                  __func__, path);
                         rc = 0;
                 } else if (errno != EISDIR) {
                         rc = errno;