Whamcloud - gitweb
LU-5823 clio: add coo_getstripe interface 52/12452/19
authorBobi Jam <bobijam.xu@intel.com>
Tue, 28 Oct 2014 03:30:38 +0000 (11:30 +0800)
committerOleg Drokin <oleg.drokin@intel.com>
Thu, 18 Dec 2014 00:32:56 +0000 (00:32 +0000)
Use cl_object_operations::coo_getstripe() to handle
LL_IOC_LOV_GETSTRIPE ops.

Signed-off-by: Bobi Jam <bobijam.xu@intel.com>
Change-Id: Iee0d007f773ead35434eb88e7ca2f31c0bc42c11
Reviewed-on: http://review.whamcloud.com/12452
Reviewed-by: John L. Hammond <john.hammond@intel.com>
Tested-by: Jenkins
Tested-by: Maloo <hpdd-maloo@intel.com>
Reviewed-by: Jinshan Xiong <jinshan.xiong@intel.com>
Reviewed-by: Oleg Drokin <oleg.drokin@intel.com>
lustre/include/cl_object.h
lustre/llite/file.c
lustre/llite/llite_internal.h
lustre/lov/lov_cl_internal.h
lustre/lov/lov_internal.h
lustre/lov/lov_obd.c
lustre/lov/lov_object.c
lustre/lov/lov_pack.c
lustre/obdclass/cl_object.c

index 862d092..c2c3b2d 100644 (file)
@@ -394,6 +394,11 @@ struct cl_object_operations {
         * mainly pages and locks.
         */
        int (*coo_prune)(const struct lu_env *env, struct cl_object *obj);
         * mainly pages and locks.
         */
        int (*coo_prune)(const struct lu_env *env, struct cl_object *obj);
+       /**
+        * Object getstripe method.
+        */
+       int (*coo_getstripe)(const struct lu_env *env, struct cl_object *obj,
+                            struct lov_user_md __user *lum);
 };
 
 /**
 };
 
 /**
@@ -448,6 +453,7 @@ struct cl_object_header {
        list_for_each_entry_reverse((slice),                            \
                                    &(obj)->co_lu.lo_header->loh_layers,\
                                    co_lu.lo_linkage)
        list_for_each_entry_reverse((slice),                            \
                                    &(obj)->co_lu.lo_header->loh_layers,\
                                    co_lu.lo_linkage)
+
 /** @} cl_object */
 
 #define CL_PAGE_EOF ((pgoff_t)~0ull)
 /** @} cl_object */
 
 #define CL_PAGE_EOF ((pgoff_t)~0ull)
@@ -2258,6 +2264,8 @@ int  cl_conf_set          (const struct lu_env *env, struct cl_object *obj,
                            const struct cl_object_conf *conf);
 int  cl_object_prune      (const struct lu_env *env, struct cl_object *obj);
 void cl_object_kill       (const struct lu_env *env, struct cl_object *obj);
                            const struct cl_object_conf *conf);
 int  cl_object_prune      (const struct lu_env *env, struct cl_object *obj);
 void cl_object_kill       (const struct lu_env *env, struct cl_object *obj);
+int  cl_object_getstripe(const struct lu_env *env, struct cl_object *obj,
+                        struct lov_user_md __user *lum);
 
 /**
  * Returns true, iff \a o0 and \a o1 are slices of the same object.
 
 /**
  * Returns true, iff \a o0 and \a o1 are slices of the same object.
index 723bf92..d1ca438 100644 (file)
@@ -1581,6 +1581,23 @@ static int ll_lov_setea(struct inode *inode, struct file *file,
        RETURN(rc);
 }
 
        RETURN(rc);
 }
 
+static int ll_file_getstripe(struct inode *inode,
+                            struct lov_user_md __user *lum)
+{
+       struct lu_env   *env;
+       int             refcheck;
+       int             rc;
+       ENTRY;
+
+       env = cl_env_get(&refcheck);
+       if (IS_ERR(env))
+               RETURN(PTR_ERR(env));
+
+       rc = cl_object_getstripe(env, ll_i2info(inode)->lli_clob, lum);
+       cl_env_put(env, &refcheck);
+       RETURN(rc);
+}
+
 static int ll_lov_setstripe(struct inode *inode, struct file *file,
                            unsigned long arg)
 {
 static int ll_lov_setstripe(struct inode *inode, struct file *file,
                            unsigned long arg)
 {
@@ -1597,36 +1614,18 @@ static int ll_lov_setstripe(struct inode *inode, struct file *file,
        lum_size = rc;
        rc = ll_lov_setstripe_ea_info(inode, file, flags, klum, lum_size);
        if (rc == 0) {
        lum_size = rc;
        rc = ll_lov_setstripe_ea_info(inode, file, flags, klum, lum_size);
        if (rc == 0) {
-               struct lov_stripe_md *lsm;
                __u32 gen;
 
                put_user(0, &lum->lmm_stripe_count);
 
                ll_layout_refresh(inode, &gen);
                __u32 gen;
 
                put_user(0, &lum->lmm_stripe_count);
 
                ll_layout_refresh(inode, &gen);
-               lsm = ccc_inode_lsm_get(inode);
-               rc = obd_iocontrol(LL_IOC_LOV_GETSTRIPE, ll_i2dtexp(inode),
-                                  0, lsm, lum);
-               ccc_inode_lsm_put(inode, lsm);
+               rc = ll_file_getstripe(inode, (struct lov_user_md __user *)arg);
        }
 
        OBD_FREE(klum, lum_size);
        RETURN(rc);
 }
 
        }
 
        OBD_FREE(klum, lum_size);
        RETURN(rc);
 }
 
-static int ll_lov_getstripe(struct inode *inode, unsigned long arg)
-{
-       struct lov_stripe_md *lsm;
-       int rc = -ENODATA;
-       ENTRY;
-
-       lsm = ccc_inode_lsm_get(inode);
-       if (lsm != NULL)
-               rc = obd_iocontrol(LL_IOC_LOV_GETSTRIPE, ll_i2dtexp(inode), 0,
-                                  lsm, (void __user *)arg);
-       ccc_inode_lsm_put(inode, lsm);
-       RETURN(rc);
-}
-
 static int
 ll_get_grouplock(struct inode *inode, struct file *file, unsigned long arg)
 {
 static int
 ll_get_grouplock(struct inode *inode, struct file *file, unsigned long arg)
 {
@@ -2324,8 +2323,9 @@ ll_file_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
                fput(file2);
                RETURN(rc);
        }
                fput(file2);
                RETURN(rc);
        }
-        case LL_IOC_LOV_GETSTRIPE:
-                RETURN(ll_lov_getstripe(inode, arg));
+       case LL_IOC_LOV_GETSTRIPE:
+               RETURN(ll_file_getstripe(inode,
+                                        (struct lov_user_md __user *)arg));
         case FSFILT_IOC_FIEMAP:
                 RETURN(ll_ioctl_fiemap(inode, arg));
         case FSFILT_IOC_GETFLAGS:
         case FSFILT_IOC_FIEMAP:
                 RETURN(ll_ioctl_fiemap(inode, arg));
         case FSFILT_IOC_GETFLAGS:
index 2ce7639..60c44da 100644 (file)
@@ -260,7 +260,7 @@ struct ll_inode_info {
          *      some of the following members can be moved into u.f.
          */
        bool                            lli_has_smd;
          *      some of the following members can be moved into u.f.
          */
        bool                            lli_has_smd;
-       struct cl_object               *lli_clob;
+       struct cl_object                *lli_clob;
 
        /* mutex to request for layout lock exclusively. */
        struct mutex                    lli_layout_mutex;
 
        /* mutex to request for layout lock exclusively. */
        struct mutex                    lli_layout_mutex;
index 93bec95..c136dce 100644 (file)
@@ -767,6 +767,10 @@ static inline struct lov_layout_raid0 *lov_r0(struct lov_object *lov)
        return &lov->u.raid0;
 }
 
        return &lov->u.raid0;
 }
 
+/* lov_pack.c */
+int lov_getstripe(struct lov_object *obj, struct lov_stripe_md *lsm,
+                 struct lov_user_md __user *lump);
+
 /** @} lov */
 
 #endif
 /** @} lov */
 
 #endif
index 5d5b793..c7814e1 100644 (file)
@@ -195,8 +195,6 @@ int lov_packmd(struct obd_export *exp, struct lov_mds_md **lmm,
                struct lov_stripe_md *lsm);
 int lov_unpackmd(struct obd_export *exp, struct lov_stripe_md **lsmp,
                  struct lov_mds_md *lmm, int lmm_bytes);
                struct lov_stripe_md *lsm);
 int lov_unpackmd(struct obd_export *exp, struct lov_stripe_md **lsmp,
                  struct lov_mds_md *lmm, int lmm_bytes);
-int lov_getstripe(struct obd_export *exp,
-                 struct lov_stripe_md *lsm, struct lov_user_md __user *lump);
 int lov_alloc_memmd(struct lov_stripe_md **lsmp, __u16 stripe_count,
                     int pattern, int magic);
 int lov_free_memmd(struct lov_stripe_md **lsmp);
 int lov_alloc_memmd(struct lov_stripe_md **lsmp, __u16 stripe_count,
                     int pattern, int magic);
 int lov_free_memmd(struct lov_stripe_md **lsmp);
index 7f3cd20..200abda 100644 (file)
@@ -1430,9 +1430,6 @@ static int lov_iocontrol(unsigned int cmd, struct obd_export *exp, int len,
                 obd_ioctl_freedata(buf, len);
                 break;
         }
                 obd_ioctl_freedata(buf, len);
                 break;
         }
-       case LL_IOC_LOV_GETSTRIPE:
-               rc = lov_getstripe(exp, karg, uarg);
-               break;
         case OBD_IOC_QUOTACTL: {
                 struct if_quotactl *qctl = karg;
                 struct lov_tgt_desc *tgt = NULL;
         case OBD_IOC_QUOTACTL: {
                 struct if_quotactl *qctl = karg;
                 struct lov_tgt_desc *tgt = NULL;
index f7ef365..718d035 100644 (file)
@@ -80,6 +80,29 @@ struct lov_layout_operations {
 
 static int lov_layout_wait(const struct lu_env *env, struct lov_object *lov);
 
 
 static int lov_layout_wait(const struct lu_env *env, struct lov_object *lov);
 
+struct lov_stripe_md *lov_lsm_get(struct cl_object *clobj)
+{
+       struct lu_object *luobj;
+       struct lov_stripe_md *lsm = NULL;
+
+       if (clobj == NULL)
+               return NULL;
+
+       luobj = lu_object_locate(&cl_object_header(clobj)->coh_lu,
+                                &lov_device_type);
+       if (luobj != NULL)
+               lsm = lov_lsm_addref(lu2lov(luobj));
+       return lsm;
+}
+EXPORT_SYMBOL(lov_lsm_get);
+
+void lov_lsm_put(struct cl_object *unused, struct lov_stripe_md *lsm)
+{
+       if (lsm != NULL)
+               lov_free_memmd(&lsm);
+}
+EXPORT_SYMBOL(lov_lsm_put);
+
 /*****************************************************************************
  *
  * Lov object layout operations.
 /*****************************************************************************
  *
  * Lov object layout operations.
@@ -917,13 +940,31 @@ int lov_lock_init(const struct lu_env *env, struct cl_object *obj,
                                    io);
 }
 
                                    io);
 }
 
+static int lov_object_getstripe(const struct lu_env *env, struct cl_object *obj,
+                               struct lov_user_md __user *lum)
+{
+       struct lov_object       *lov = cl2lov(obj);
+       struct lov_stripe_md    *lsm;
+       int                     rc = 0;
+       ENTRY;
+
+       lsm = lov_lsm_addref(lov);
+       if (lsm == NULL)
+               RETURN(-ENODATA);
+
+       rc = lov_getstripe(cl2lov(obj), lsm, lum);
+       lov_lsm_put(obj, lsm);
+       RETURN(rc);
+}
+
 static const struct cl_object_operations lov_ops = {
         .coo_page_init = lov_page_init,
         .coo_lock_init = lov_lock_init,
         .coo_io_init   = lov_io_init,
         .coo_attr_get  = lov_attr_get,
         .coo_attr_set  = lov_attr_set,
 static const struct cl_object_operations lov_ops = {
         .coo_page_init = lov_page_init,
         .coo_lock_init = lov_lock_init,
         .coo_io_init   = lov_io_init,
         .coo_attr_get  = lov_attr_get,
         .coo_attr_set  = lov_attr_set,
-        .coo_conf_set  = lov_conf_set
+       .coo_conf_set  = lov_conf_set,
+       .coo_getstripe = lov_object_getstripe
 };
 
 static const struct lu_object_operations lov_lu_obj_ops = {
 };
 
 static const struct lu_object_operations lov_lu_obj_ops = {
@@ -975,29 +1016,6 @@ struct lov_stripe_md *lov_lsm_addref(struct lov_object *lov)
        return lsm;
 }
 
        return lsm;
 }
 
-struct lov_stripe_md *lov_lsm_get(struct cl_object *clobj)
-{
-       struct lu_object *luobj;
-       struct lov_stripe_md *lsm = NULL;
-
-       if (clobj == NULL)
-               return NULL;
-
-       luobj = lu_object_locate(&cl_object_header(clobj)->coh_lu,
-                                &lov_device_type);
-       if (luobj != NULL)
-               lsm = lov_lsm_addref(lu2lov(luobj));
-       return lsm;
-}
-EXPORT_SYMBOL(lov_lsm_get);
-
-void lov_lsm_put(struct cl_object *unused, struct lov_stripe_md *lsm)
-{
-       if (lsm != NULL)
-               lov_free_memmd(&lsm);
-}
-EXPORT_SYMBOL(lov_lsm_put);
-
 int lov_read_and_clear_async_rc(struct cl_object *clob)
 {
        struct lu_object *luobj;
 int lov_read_and_clear_async_rc(struct cl_object *clob)
 {
        struct lu_object *luobj;
index 3c6f7c9..d4e6c71 100644 (file)
@@ -49,6 +49,7 @@
 #include <lustre/lustre_user.h>
 
 #include "lov_internal.h"
 #include <lustre/lustre_user.h>
 
 #include "lov_internal.h"
+#include "lov_cl_internal.h"
 
 void lov_dump_lmm_common(int level, void *lmmp)
 {
 
 void lov_dump_lmm_common(int level, void *lmmp)
 {
@@ -128,11 +129,9 @@ void lov_dump_lmm(int level, void *lmm)
  *     LOVs properly.  For now lov_mds_md_size() just assumes one obd_id
  *     per stripe.
  */
  *     LOVs properly.  For now lov_mds_md_size() just assumes one obd_id
  *     per stripe.
  */
-int lov_packmd(struct obd_export *exp, struct lov_mds_md **lmmp,
-               struct lov_stripe_md *lsm)
+static int lov_obd_packmd(struct lov_obd *lov, struct lov_mds_md **lmmp,
+                         struct lov_stripe_md *lsm)
 {
 {
-        struct obd_device *obd = class_exp2obd(exp);
-        struct lov_obd *lov = &obd->u.lov;
         struct lov_mds_md_v1 *lmmv1;
         struct lov_mds_md_v3 *lmmv3;
         __u16 stripe_count;
         struct lov_mds_md_v1 *lmmv1;
         struct lov_mds_md_v3 *lmmv3;
         __u16 stripe_count;
@@ -243,6 +242,15 @@ int lov_packmd(struct obd_export *exp, struct lov_mds_md **lmmp,
        RETURN(lmm_size);
 }
 
        RETURN(lmm_size);
 }
 
+int lov_packmd(struct obd_export *exp, struct lov_mds_md **lmmp,
+              struct lov_stripe_md *lsm)
+{
+       struct obd_device *obd = class_exp2obd(exp);
+       struct lov_obd *lov = &obd->u.lov;
+
+       return lov_obd_packmd(lov, lmmp, lsm);
+}
+
 /* Find the max stripecount we should use */
 __u16 lov_get_stripecnt(struct lov_obd *lov, __u32 magic, __u16 stripe_count)
 {
 /* Find the max stripecount we should use */
 __u16 lov_get_stripecnt(struct lov_obd *lov, __u32 magic, __u16 stripe_count)
 {
@@ -407,78 +415,79 @@ int lov_unpackmd(struct obd_export *exp,  struct lov_stripe_md **lsmp,
  * the maximum number of OST indices which will fit in the user buffer.
  * lmm_magic must be LOV_USER_MAGIC.
  */
  * the maximum number of OST indices which will fit in the user buffer.
  * lmm_magic must be LOV_USER_MAGIC.
  */
-int lov_getstripe(struct obd_export *exp, struct lov_stripe_md *lsm,
+int lov_getstripe(struct lov_object *obj, struct lov_stripe_md *lsm,
                  struct lov_user_md __user *lump)
 {
                  struct lov_user_md __user *lump)
 {
-        /*
-         * XXX huge struct allocated on stack.
-         */
-        /* we use lov_user_md_v3 because it is larger than lov_user_md_v1 */
-        struct lov_user_md_v3 lum;
-        struct lov_mds_md *lmmk = NULL;
-        int rc, lmm_size;
-        int lum_size;
-        ENTRY;
-
-        if (!lsm)
-                RETURN(-ENODATA);
+       /*
+        * XXX huge struct allocated on stack.
+        */
+       /* we use lov_user_md_v3 because it is larger than lov_user_md_v1 */
+       struct lov_obd          *lov;
+       struct lov_mds_md       *lmmk = NULL;
+       struct lov_user_md_v3   lum;
+       int                     rc;
+       int                     lmmk_size;
+       int                     lmm_size;
+       int                     lum_size;
+       ENTRY;
 
 
-        /* we only need the header part from user space to get lmm_magic and
-         * lmm_stripe_count, (the header part is common to v1 and v3) */
-        lum_size = sizeof(struct lov_user_md_v1);
+       /* we only need the header part from user space to get lmm_magic and
+        * lmm_stripe_count, (the header part is common to v1 and v3) */
+       lum_size = sizeof(struct lov_user_md_v1);
        if (copy_from_user(&lum, lump, lum_size))
        if (copy_from_user(&lum, lump, lum_size))
-                GOTO(out_set, rc = -EFAULT);
+               GOTO(out, rc = -EFAULT);
 
        if (lum.lmm_magic != LOV_USER_MAGIC_V1 &&
            lum.lmm_magic != LOV_USER_MAGIC_V3 &&
            lum.lmm_magic != LOV_USER_MAGIC_SPECIFIC)
 
        if (lum.lmm_magic != LOV_USER_MAGIC_V1 &&
            lum.lmm_magic != LOV_USER_MAGIC_V3 &&
            lum.lmm_magic != LOV_USER_MAGIC_SPECIFIC)
-               GOTO(out_set, rc = -EINVAL);
+               GOTO(out, rc = -EINVAL);
 
 
-        if (lum.lmm_stripe_count &&
-            (lum.lmm_stripe_count < lsm->lsm_stripe_count)) {
-                /* Return right size of stripe to user */
-                lum.lmm_stripe_count = lsm->lsm_stripe_count;
+       if (lum.lmm_stripe_count &&
+           (lum.lmm_stripe_count < lsm->lsm_stripe_count)) {
+               /* Return right size of stripe to user */
+               lum.lmm_stripe_count = lsm->lsm_stripe_count;
                rc = copy_to_user(lump, &lum, lum_size);
                rc = copy_to_user(lump, &lum, lum_size);
-                GOTO(out_set, rc = -EOVERFLOW);
-        }
-        rc = lov_packmd(exp, &lmmk, lsm);
-        if (rc < 0)
-                GOTO(out_set, rc);
-        lmm_size = rc;
-        rc = 0;
-
-        /* FIXME: Bug 1185 - copy fields properly when structs change */
-        /* struct lov_user_md_v3 and struct lov_mds_md_v3 must be the same */
-        CLASSERT(sizeof(lum) == sizeof(struct lov_mds_md_v3));
-        CLASSERT(sizeof lum.lmm_objects[0] == sizeof lmmk->lmm_objects[0]);
-
-        if ((cpu_to_le32(LOV_MAGIC) != LOV_MAGIC) &&
-            ((lmmk->lmm_magic == cpu_to_le32(LOV_MAGIC_V1)) ||
-            (lmmk->lmm_magic == cpu_to_le32(LOV_MAGIC_V3)))) {
-                lustre_swab_lov_mds_md(lmmk);
-                lustre_swab_lov_user_md_objects(
-                                (struct lov_user_ost_data*)lmmk->lmm_objects,
-                                lmmk->lmm_stripe_count);
-        }
-        if (lum.lmm_magic == LOV_USER_MAGIC) {
-                /* User request for v1, we need skip lmm_pool_name */
-                if (lmmk->lmm_magic == LOV_MAGIC_V3) {
+               GOTO(out, rc = -EOVERFLOW);
+       }
+       lov = lu2lov_dev(obj->lo_cl.co_lu.lo_dev)->ld_lov;
+       rc = lov_obd_packmd(lov, &lmmk, lsm);
+       if (rc < 0)
+               GOTO(out, rc);
+       lmmk_size = lmm_size = rc;
+       rc = 0;
+
+       /* FIXME: Bug 1185 - copy fields properly when structs change */
+       /* struct lov_user_md_v3 and struct lov_mds_md_v3 must be the same */
+       CLASSERT(sizeof(lum) == sizeof(struct lov_mds_md_v3));
+       CLASSERT(sizeof lum.lmm_objects[0] == sizeof lmmk->lmm_objects[0]);
+
+       if ((cpu_to_le32(LOV_MAGIC) != LOV_MAGIC) &&
+           ((lmmk->lmm_magic == cpu_to_le32(LOV_MAGIC_V1)) ||
+           (lmmk->lmm_magic == cpu_to_le32(LOV_MAGIC_V3)))) {
+               lustre_swab_lov_mds_md(lmmk);
+               lustre_swab_lov_user_md_objects(
+                               (struct lov_user_ost_data *)lmmk->lmm_objects,
+                               lmmk->lmm_stripe_count);
+       }
+       if (lum.lmm_magic == LOV_USER_MAGIC) {
+               /* User request for v1, we need skip lmm_pool_name */
+               if (lmmk->lmm_magic == LOV_MAGIC_V3) {
                        memmove(((struct lov_mds_md_v1 *)lmmk)->lmm_objects,
                                ((struct lov_mds_md_v3 *)lmmk)->lmm_objects,
                        memmove(((struct lov_mds_md_v1 *)lmmk)->lmm_objects,
                                ((struct lov_mds_md_v3 *)lmmk)->lmm_objects,
-                                lmmk->lmm_stripe_count *
-                                sizeof(struct lov_ost_data_v1));
-                        lmm_size -= LOV_MAXPOOLNAME;
-                }
-        } else {
-                /* if v3 we just have to update the lum_size */
-                lum_size = sizeof(struct lov_user_md_v3);
-        }
+                               lmmk->lmm_stripe_count *
+                               sizeof(struct lov_ost_data_v1));
+                       lmm_size -= LOV_MAXPOOLNAME;
+               }
+       } else {
+               /* if v3 we just have to update the lum_size */
+               lum_size = sizeof(struct lov_user_md_v3);
+       }
 
 
-        /* User wasn't expecting this many OST entries */
-        if (lum.lmm_stripe_count == 0)
-                lmm_size = lum_size;
-        else if (lum.lmm_stripe_count < lmmk->lmm_stripe_count)
-                GOTO(out_set, rc = -EOVERFLOW);
+       /* User wasn't expecting this many OST entries */
+       if (lum.lmm_stripe_count == 0)
+               lmm_size = lum_size;
+       else if (lum.lmm_stripe_count < lmmk->lmm_stripe_count)
+               GOTO(out_free, rc = -EOVERFLOW);
        /*
         * Have a difference between lov_mds_md & lov_user_md.
         * So we have to re-order the data before copy to user.
        /*
         * Have a difference between lov_mds_md & lov_user_md.
         * So we have to re-order the data before copy to user.
@@ -490,7 +499,8 @@ int lov_getstripe(struct obd_export *exp, struct lov_stripe_md *lsm,
        if (copy_to_user(lump, lmmk, lmm_size))
                rc = -EFAULT;
 
        if (copy_to_user(lump, lmmk, lmm_size))
                rc = -EFAULT;
 
-       obd_free_diskmd(exp, &lmmk);
-out_set:
+out_free:
+       OBD_FREE_LARGE(lmmk, lmmk_size);
+out:
        RETURN(rc);
 }
        RETURN(rc);
 }
index c37bcd0..97978f8 100644 (file)
@@ -341,6 +341,28 @@ int cl_object_prune(const struct lu_env *env, struct cl_object *obj)
 EXPORT_SYMBOL(cl_object_prune);
 
 /**
 EXPORT_SYMBOL(cl_object_prune);
 
 /**
+ * Get stripe information of this object.
+ */
+int cl_object_getstripe(const struct lu_env *env, struct cl_object *obj,
+                       struct lov_user_md __user *uarg)
+{
+       struct lu_object_header *top;
+       int                     result = 0;
+       ENTRY;
+
+       top = obj->co_lu.lo_header;
+       list_for_each_entry(obj, &top->loh_layers, co_lu.lo_linkage) {
+               if (obj->co_ops->coo_getstripe != NULL) {
+                       result = obj->co_ops->coo_getstripe(env, obj, uarg);
+                       if (result != 0)
+                               break;
+               }
+       }
+       RETURN(result);
+}
+EXPORT_SYMBOL(cl_object_getstripe);
+
+/**
  * Helper function removing all object locks, and marking object for
  * deletion. All object pages must have been deleted at this point.
  *
  * Helper function removing all object locks, and marking object for
  * deletion. All object pages must have been deleted at this point.
  *