Whamcloud - gitweb
LU-5150 acl: 'cp -rp' set empty default ACL
[fs/lustre-release.git] / lustre / mdd / mdd_object.c
index d0b9e22..b415f4b 100644 (file)
@@ -998,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.
@@ -1021,6 +1024,21 @@ 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) == 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);
+       }
+
        if (!strcmp(name, XATTR_NAME_ACL_ACCESS)) {
                rc = mdd_acl_set(env, mdd_obj, attr, buf, fl);
                RETURN(rc);
@@ -1849,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));
@@ -1885,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;
@@ -1969,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);
                }