Whamcloud - gitweb
LU-5150 acl: 'cp -rp' set empty default ACL
[fs/lustre-release.git] / lustre / mdd / mdd_object.c
index 9e86b9e..b415f4b 100644 (file)
@@ -49,7 +49,6 @@
 #include <lprocfs_status.h>
 /* fid_be_cpu(), fid_cpu_to_be(). */
 #include <lustre_fid.h>
-#include <obd_lov.h>
 #include <lustre_idmap.h>
 #include <lustre_param.h>
 #include <lustre_mds.h>
 #include "mdd_internal.h"
 
 static const struct lu_object_operations mdd_lu_obj_ops;
-extern struct kmem_cache *mdd_object_kmem;
 
 static int mdd_xattr_get(const struct lu_env *env,
                          struct md_object *obj, struct lu_buf *buf,
                          const char *name);
 
-int mdd_data_get(const struct lu_env *env, struct mdd_object *obj,
-                 void **data)
-{
-        if (mdd_object_exists(obj) == 0) {
-                CERROR("%s: object "DFID" not found: rc = -2\n",
-                       mdd_obj_dev_name(obj), PFID(mdd_object_fid(obj)));
-                return -ENOENT;
-        }
-        mdo_data_get(env, obj, data);
-        return 0;
-}
-
 int mdd_la_get(const struct lu_env *env, struct mdd_object *obj,
                struct lu_attr *la, struct lustre_capa *capa)
 {
@@ -88,7 +74,7 @@ int mdd_la_get(const struct lu_env *env, struct mdd_object *obj,
         return mdo_attr_get(env, obj, la, capa);
 }
 
-static void mdd_flags_xlate(struct mdd_object *obj, __u32 flags)
+void mdd_flags_xlate(struct mdd_object *obj, __u32 flags)
 {
         obj->mod_flags &= ~(APPEND_OBJ|IMMUTE_OBJ);
 
@@ -109,17 +95,6 @@ struct mdd_thread_info *mdd_env_info(const struct lu_env *env)
         return info;
 }
 
-const struct lu_name *mdd_name_get_const(const struct lu_env *env,
-                                        const void *area, ssize_t len)
-{
-       struct lu_name *lname;
-
-       lname = &mdd_env_info(env)->mti_name;
-       lname->ln_name = area;
-       lname->ln_namelen = len;
-       return lname;
-}
-
 struct lu_buf *mdd_buf_get(const struct lu_env *env, void *area, ssize_t len)
 {
        struct lu_buf *buf;
@@ -142,25 +117,25 @@ const struct lu_buf *mdd_buf_get_const(const struct lu_env *env,
 }
 
 struct lu_object *mdd_object_alloc(const struct lu_env *env,
-                                   const struct lu_object_header *hdr,
-                                   struct lu_device *d)
+                                  const struct lu_object_header *hdr,
+                                  struct lu_device *d)
 {
-        struct mdd_object *mdd_obj;
-
-       OBD_SLAB_ALLOC_PTR_GFP(mdd_obj, mdd_object_kmem, __GFP_IO);
-        if (mdd_obj != NULL) {
-                struct lu_object *o;
-
-                o = mdd2lu_obj(mdd_obj);
-                lu_object_init(o, NULL, d);
-                mdd_obj->mod_obj.mo_ops = &mdd_obj_ops;
-                mdd_obj->mod_obj.mo_dir_ops = &mdd_dir_ops;
-                mdd_obj->mod_count = 0;
-                o->lo_ops = &mdd_lu_obj_ops;
-                return o;
-        } else {
-                return NULL;
-        }
+       struct mdd_object *mdd_obj;
+
+       OBD_SLAB_ALLOC_PTR_GFP(mdd_obj, mdd_object_kmem, GFP_NOFS);
+       if (mdd_obj != NULL) {
+               struct lu_object *o;
+
+               o = mdd2lu_obj(mdd_obj);
+               lu_object_init(o, NULL, d);
+               mdd_obj->mod_obj.mo_ops = &mdd_obj_ops;
+               mdd_obj->mod_obj.mo_dir_ops = &mdd_dir_ops;
+               mdd_obj->mod_count = 0;
+               o->lo_ops = &mdd_lu_obj_ops;
+               return o;
+       } else {
+               return NULL;
+       }
 }
 
 static int mdd_object_init(const struct lu_env *env, struct lu_object *o,
@@ -286,8 +261,8 @@ static int mdd_xattr_get(const struct lu_env *env,
  * Permission check is done when open,
  * no need check again.
  */
-static int mdd_readlink(const struct lu_env *env, struct md_object *obj,
-                        struct lu_buf *buf)
+int mdd_readlink(const struct lu_env *env, struct md_object *obj,
+                struct lu_buf *buf)
 {
         struct mdd_object *mdd_obj = md2mdd_obj(obj);
         struct dt_object  *next;
@@ -302,7 +277,10 @@ static int mdd_readlink(const struct lu_env *env, struct md_object *obj,
         }
 
         next = mdd_object_child(mdd_obj);
-        mdd_read_lock(env, mdd_obj, MOR_TGT_CHILD);
+       LASSERT(next != NULL);
+       LASSERT(next->do_body_ops != NULL);
+       LASSERT(next->do_body_ops->dbo_read != NULL);
+       mdd_read_lock(env, mdd_obj, MOR_TGT_CHILD);
         rc = next->do_body_ops->dbo_read(env, next, buf, &pos,
                                          mdd_object_capa(env, mdd_obj));
         mdd_read_unlock(env, mdd_obj);
@@ -332,10 +310,10 @@ int mdd_declare_object_create_internal(const struct lu_env *env,
                                       struct mdd_object *c,
                                       struct lu_attr *attr,
                                       struct thandle *handle,
-                                      const struct md_op_spec *spec)
+                                      const struct md_op_spec *spec,
+                                      struct dt_allocation_hint *hint)
 {
         struct dt_object_format *dof = &mdd_env_info(env)->mti_dof;
-       struct dt_allocation_hint *hint = &mdd_env_info(env)->mti_hint;
         const struct dt_index_features *feat = spec->sp_feat;
         int rc;
         ENTRY;
@@ -364,10 +342,10 @@ int mdd_declare_object_create_internal(const struct lu_env *env,
 
 int mdd_object_create_internal(const struct lu_env *env, struct mdd_object *p,
                               struct mdd_object *c, struct lu_attr *attr,
-                               struct thandle *handle,
-                               const struct md_op_spec *spec)
+                              struct thandle *handle,
+                              const struct md_op_spec *spec,
+                              struct dt_allocation_hint *hint)
 {
-        struct dt_allocation_hint *hint = &mdd_env_info(env)->mti_hint;
         struct dt_object_format *dof = &mdd_env_info(env)->mti_dof;
         int rc;
         ENTRY;
@@ -702,8 +680,8 @@ int mdd_changelog_data_store(const struct lu_env *env, struct mdd_device *mdd,
        RETURN(rc);
 }
 
-int mdd_changelog(const struct lu_env *env, enum changelog_rec_type type,
-                  int flags, struct md_object *obj)
+static int mdd_changelog(const struct lu_env *env, enum changelog_rec_type type,
+                        int flags, struct md_object *obj)
 {
         struct thandle *handle;
         struct mdd_object *mdd_obj = md2mdd_obj(obj);
@@ -750,19 +728,19 @@ static int mdd_attr_set_changelog(const struct lu_env *env,
         struct mdd_device *mdd = mdo2mdd(obj);
         int bits, type = 0;
 
-        bits = (valid & ~(LA_CTIME|LA_MTIME|LA_ATIME)) ? 1 << CL_SETATTR : 0;
+       bits =  (valid & LA_SIZE)  ? 1 << CL_TRUNC : 0;
+       bits |= (valid & ~(LA_CTIME|LA_MTIME|LA_ATIME)) ? 1 << CL_SETATTR : 0;
         bits |= (valid & LA_MTIME) ? 1 << CL_MTIME : 0;
         bits |= (valid & LA_CTIME) ? 1 << CL_CTIME : 0;
         bits |= (valid & LA_ATIME) ? 1 << CL_ATIME : 0;
         bits = bits & mdd->mdd_cl.mc_mask;
+       /* This is an implementation limit rather than a protocol limit */
+       CLASSERT(CL_LAST <= sizeof(int) * 8);
         if (bits == 0)
                 return 0;
 
         /* The record type is the lowest non-masked set bit */
-        while (bits && ((bits & 1) == 0)) {
-                bits = bits >> 1;
-                type++;
-        }
+       type = __ffs(bits);
 
         /* FYI we only store the first CLF_FLAGMASK bits of la_valid */
         return mdd_changelog_data_store(env, mdd, type, (int)valid,
@@ -1020,6 +998,9 @@ free:
        return(rc);
 }
 
+static int mdd_xattr_del(const struct lu_env *env, struct md_object *obj,
+                        const char *name);
+
 /**
  * The caller should guarantee to update the object ctime
  * after xattr_set if needed.
@@ -1039,14 +1020,29 @@ static int mdd_xattr_set(const struct lu_env *env, struct md_object *obj,
        if (rc)
                RETURN(rc);
 
-       if (!strcmp(name, XATTR_NAME_ACL_ACCESS)) {
-               rc = mdd_acl_set(env, mdd_obj, attr, buf, fl);
+       rc = mdd_xattr_sanity_check(env, mdd_obj, attr);
+       if (rc)
                RETURN(rc);
+
+       if (strcmp(name, XATTR_NAME_ACL_ACCESS) == 0 ||
+           strcmp(name, XATTR_NAME_ACL_DEFAULT) == 0) {
+               struct posix_acl *acl;
+
+               /* user may set empty ACL, which should be treated as removing
+                * ACL. */
+               acl = posix_acl_from_xattr(&init_user_ns, buf->lb_buf,
+                                          buf->lb_len);
+               if (acl == NULL) {
+                       rc = mdd_xattr_del(env, obj, name);
+                       RETURN(rc);
+               }
+               posix_acl_release(acl);
        }
 
-       rc = mdd_xattr_sanity_check(env, mdd_obj, attr);
-       if (rc)
+       if (!strcmp(name, XATTR_NAME_ACL_ACCESS)) {
+               rc = mdd_acl_set(env, mdd_obj, attr, buf, fl);
                RETURN(rc);
+       }
 
        handle = mdd_trans_create(env, mdd);
        if (IS_ERR(handle))
@@ -1118,8 +1114,8 @@ static int mdd_declare_xattr_del(const struct lu_env *env,
  * The caller should guarantee to update the object ctime
  * after xattr_set if needed.
  */
-int mdd_xattr_del(const struct lu_env *env, struct md_object *obj,
-                  const char *name)
+static int mdd_xattr_del(const struct lu_env *env, struct md_object *obj,
+                        const char *name)
 {
        struct mdd_object *mdd_obj = md2mdd_obj(obj);
        struct lu_attr *attr = MDD_ENV_VAR(env, cattr);
@@ -1175,12 +1171,11 @@ stop:
  * read lov EA of an object
  * return the lov EA in an allocated lu_buf
  */
-static int mdd_get_lov_ea(const struct lu_env *env,
-                         struct mdd_object *obj,
-                         struct lu_buf *lmm_buf)
+int mdd_get_lov_ea(const struct lu_env *env, struct mdd_object *obj,
+                  struct lu_buf *lmm_buf)
 {
        struct lu_buf   *buf = &mdd_env_info(env)->mti_big_buf;
-       int              rc, sz;
+       int              rc, bufsize;
        ENTRY;
 
 repeat:
@@ -1198,27 +1193,27 @@ repeat:
        }
 
        if (rc < 0)
-               GOTO(out, rc);
+               RETURN(rc);
 
        if (rc == 0)
-               GOTO(out, rc = -ENODATA);
+               RETURN(-ENODATA);
 
-       sz = rc;
+       bufsize = rc;
        if (memcmp(buf, &LU_BUF_NULL, sizeof(*buf)) == 0) {
                /* mti_big_buf was not allocated, so we have to
                 * allocate it based on the ea size */
                buf = lu_buf_check_and_alloc(&mdd_env_info(env)->mti_big_buf,
-                                            sz);
+                                            bufsize);
                if (buf->lb_buf == NULL)
                        GOTO(out, rc = -ENOMEM);
                goto repeat;
        }
 
-       lu_buf_alloc(lmm_buf, sz);
+       lu_buf_alloc(lmm_buf, bufsize);
        if (lmm_buf->lb_buf == NULL)
                GOTO(out, rc = -ENOMEM);
 
-       memcpy(lmm_buf->lb_buf, buf->lb_buf, sz);
+       memcpy(lmm_buf->lb_buf, buf->lb_buf, bufsize);
        rc = 0;
        EXIT;
 
@@ -1564,9 +1559,9 @@ stop:
 
 void mdd_object_make_hint(const struct lu_env *env, struct mdd_object *parent,
                          struct mdd_object *child, const struct lu_attr *attr,
-                         const struct md_op_spec *spec)
+                         const struct md_op_spec *spec,
+                         struct dt_allocation_hint *hint)
 {
-       struct dt_allocation_hint *hint = &mdd_env_info(env)->mti_hint;
        struct dt_object *np = parent ?  mdd_object_child(parent) : NULL;
        struct dt_object *nc = mdd_object_child(child);
 
@@ -1583,7 +1578,7 @@ void mdd_object_make_hint(const struct lu_env *env, struct mdd_object *parent,
                hint->dah_eadata_len = 0;
        }
 
-       CDEBUG(D_INFO, DFID" eadata %p, len %d\n", PFID(mdd_object_fid(child)),
+       CDEBUG(D_INFO, DFID" eadata %p len %d\n", PFID(mdd_object_fid(child)),
               hint->dah_eadata, hint->dah_eadata_len);
        /* @hint will be initialized by underlying device. */
        nc->do_ops->do_ah_init(env, hint, np, nc, attr->la_mode & S_IFMT);
@@ -1693,25 +1688,6 @@ static int mdd_open(const struct lu_env *env, struct md_object *obj,
        return rc;
 }
 
-int mdd_declare_object_kill(const struct lu_env *env, struct mdd_object *obj,
-                            struct md_attr *ma, struct thandle *handle)
-{
-        return mdo_declare_destroy(env, obj, handle);
-}
-
-/* return md_attr back,
- * if it is last unlink then return lov ea + llog cookie*/
-int mdd_object_kill(const struct lu_env *env, struct mdd_object *obj,
-                    struct md_attr *ma, struct thandle *handle)
-{
-       int rc;
-        ENTRY;
-
-       rc = mdo_destroy(env, obj, handle);
-
-        RETURN(rc);
-}
-
 static int mdd_declare_close(const struct lu_env *env,
                              struct mdd_object *obj,
                              struct md_attr *ma,
@@ -1891,6 +1867,7 @@ static int mdd_dir_page_build(const struct lu_env *env, union lu_page *lp,
        __u64                    hash = 0;
        struct lu_dirent        *ent;
        struct lu_dirent        *last = NULL;
+       struct lu_fid            fid;
        int                      first = 1;
 
         memset(area, 0, sizeof (*dp));
@@ -1927,6 +1904,12 @@ static int mdd_dir_page_build(const struct lu_env *env, union lu_page *lp,
                         /* osd might not able to pack all attributes,
                          * so recheck rec length */
                         recsize = le16_to_cpu(ent->lde_reclen);
+
+                       if (le32_to_cpu(ent->lde_attrs) & LUDA_FID) {
+                               fid_le_to_cpu(&fid, &ent->lde_fid);
+                               if (fid_is_dot_lustre(&fid))
+                                       goto next;
+                       }
                 } else {
                         result = (last != NULL) ? 0 :-EINVAL;
                         goto out;
@@ -2011,6 +1994,7 @@ int mdd_readpage(const struct lu_env *env, struct md_object *obj,
                         * No pages were processed, mark this for first page
                         * and send back.
                         */
+                       dp->ldp_hash_end = cpu_to_le64(MDS_DIR_END_OFF);
                        dp->ldp_flags = cpu_to_le32(LDF_EMPTY);
                        rc = min_t(unsigned int, LU_PAGE_SIZE, rdpg->rp_count);
                }
@@ -2025,27 +2009,40 @@ out_unlock:
 
 static int mdd_object_sync(const struct lu_env *env, struct md_object *obj)
 {
-        struct mdd_object *mdd_obj = md2mdd_obj(obj);
+       struct mdd_object *mdd_obj = md2mdd_obj(obj);
 
-        if (mdd_object_exists(mdd_obj) == 0) {
-                CERROR("%s: object "DFID" not found: rc = -2\n",
-                       mdd_obj_dev_name(mdd_obj),PFID(mdd_object_fid(mdd_obj)));
-                return -ENOENT;
-        }
-        return dt_object_sync(env, mdd_object_child(mdd_obj));
+       if (mdd_object_exists(mdd_obj) == 0) {
+               int rc = -ENOENT;
+
+               CERROR("%s: object "DFID" not found: rc = %d\n",
+                      mdd_obj_dev_name(mdd_obj),
+                      PFID(mdd_object_fid(mdd_obj)), rc);
+               return rc;
+       }
+       return dt_object_sync(env, mdd_object_child(mdd_obj),
+                             0, OBD_OBJECT_EOF);
 }
 
 static int mdd_object_lock(const struct lu_env *env,
                           struct md_object *obj,
                           struct lustre_handle *lh,
                           struct ldlm_enqueue_info *einfo,
-                          void *policy)
+                          ldlm_policy_data_t *policy)
 {
        struct mdd_object *mdd_obj = md2mdd_obj(obj);
        return dt_object_lock(env, mdd_object_child(mdd_obj), lh,
                              einfo, policy);
 }
 
+static int mdd_object_unlock(const struct lu_env *env,
+                            struct md_object *obj,
+                            struct ldlm_enqueue_info *einfo,
+                            ldlm_policy_data_t *policy)
+{
+       struct mdd_object *mdd_obj = md2mdd_obj(obj);
+       return dt_object_unlock(env, mdd_object_child(mdd_obj), einfo, policy);
+}
+
 const struct md_object_operations mdd_obj_ops = {
        .moo_permission         = mdd_permission,
        .moo_attr_get           = mdd_attr_get,
@@ -2063,4 +2060,5 @@ const struct md_object_operations mdd_obj_ops = {
        .moo_capa_get           = mdd_capa_get,
        .moo_object_sync        = mdd_object_sync,
        .moo_object_lock        = mdd_object_lock,
+       .moo_object_unlock      = mdd_object_unlock,
 };