Whamcloud - gitweb
LU-5150 acl: 'cp -rp' set empty default ACL
[fs/lustre-release.git] / lustre / mdd / mdd_object.c
index 462b2b5..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)
 {
@@ -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;
@@ -705,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);
@@ -753,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,
@@ -1023,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.
@@ -1042,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))
@@ -1121,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);
@@ -1695,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,
@@ -1893,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));
@@ -1929,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;
@@ -2013,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);
                }
@@ -2027,14 +2009,18 @@ 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,