Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/sage/ceph...
[sfrench/cifs-2.6.git] / fs / ceph / dir.c
index b6c59eaa4f64356ba069219551c78870035d74d9..e6d63f8f98c0a79891396313c0b0d1252e1ef0fb 100644 (file)
@@ -682,17 +682,22 @@ static int ceph_mknod(struct inode *dir, struct dentry *dentry,
        struct ceph_fs_client *fsc = ceph_sb_to_client(dir->i_sb);
        struct ceph_mds_client *mdsc = fsc->mdsc;
        struct ceph_mds_request *req;
+       struct ceph_acls_info acls = {};
        int err;
 
        if (ceph_snap(dir) != CEPH_NOSNAP)
                return -EROFS;
 
+       err = ceph_pre_init_acls(dir, &mode, &acls);
+       if (err < 0)
+               return err;
+
        dout("mknod in dir %p dentry %p mode 0%ho rdev %d\n",
             dir, dentry, mode, rdev);
        req = ceph_mdsc_create_request(mdsc, CEPH_MDS_OP_MKNOD, USE_AUTH_MDS);
        if (IS_ERR(req)) {
-               d_drop(dentry);
-               return PTR_ERR(req);
+               err = PTR_ERR(req);
+               goto out;
        }
        req->r_dentry = dget(dentry);
        req->r_num_caps = 2;
@@ -701,15 +706,20 @@ static int ceph_mknod(struct inode *dir, struct dentry *dentry,
        req->r_args.mknod.rdev = cpu_to_le32(rdev);
        req->r_dentry_drop = CEPH_CAP_FILE_SHARED;
        req->r_dentry_unless = CEPH_CAP_FILE_EXCL;
+       if (acls.pagelist) {
+               req->r_pagelist = acls.pagelist;
+               acls.pagelist = NULL;
+       }
        err = ceph_mdsc_do_request(mdsc, dir, req);
        if (!err && !req->r_reply_info.head->is_dentry)
                err = ceph_handle_notrace_create(dir, dentry);
        ceph_mdsc_put_request(req);
-
+out:
        if (!err)
-               ceph_init_acl(dentry, dentry->d_inode, dir);
+               ceph_init_inode_acls(dentry->d_inode, &acls);
        else
                d_drop(dentry);
+       ceph_release_acls_info(&acls);
        return err;
 }
 
@@ -733,8 +743,8 @@ static int ceph_symlink(struct inode *dir, struct dentry *dentry,
        dout("symlink in dir %p dentry %p to '%s'\n", dir, dentry, dest);
        req = ceph_mdsc_create_request(mdsc, CEPH_MDS_OP_SYMLINK, USE_AUTH_MDS);
        if (IS_ERR(req)) {
-               d_drop(dentry);
-               return PTR_ERR(req);
+               err = PTR_ERR(req);
+               goto out;
        }
        req->r_dentry = dget(dentry);
        req->r_num_caps = 2;
@@ -746,9 +756,8 @@ static int ceph_symlink(struct inode *dir, struct dentry *dentry,
        if (!err && !req->r_reply_info.head->is_dentry)
                err = ceph_handle_notrace_create(dir, dentry);
        ceph_mdsc_put_request(req);
-       if (!err)
-               ceph_init_acl(dentry, dentry->d_inode, dir);
-       else
+out:
+       if (err)
                d_drop(dentry);
        return err;
 }
@@ -758,6 +767,7 @@ static int ceph_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
        struct ceph_fs_client *fsc = ceph_sb_to_client(dir->i_sb);
        struct ceph_mds_client *mdsc = fsc->mdsc;
        struct ceph_mds_request *req;
+       struct ceph_acls_info acls = {};
        int err = -EROFS;
        int op;
 
@@ -772,6 +782,12 @@ static int ceph_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
        } else {
                goto out;
        }
+
+       mode |= S_IFDIR;
+       err = ceph_pre_init_acls(dir, &mode, &acls);
+       if (err < 0)
+               goto out;
+
        req = ceph_mdsc_create_request(mdsc, op, USE_AUTH_MDS);
        if (IS_ERR(req)) {
                err = PTR_ERR(req);
@@ -784,15 +800,20 @@ static int ceph_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
        req->r_args.mkdir.mode = cpu_to_le32(mode);
        req->r_dentry_drop = CEPH_CAP_FILE_SHARED;
        req->r_dentry_unless = CEPH_CAP_FILE_EXCL;
+       if (acls.pagelist) {
+               req->r_pagelist = acls.pagelist;
+               acls.pagelist = NULL;
+       }
        err = ceph_mdsc_do_request(mdsc, dir, req);
        if (!err && !req->r_reply_info.head->is_dentry)
                err = ceph_handle_notrace_create(dir, dentry);
        ceph_mdsc_put_request(req);
 out:
        if (!err)
-               ceph_init_acl(dentry, dentry->d_inode, dir);
+               ceph_init_inode_acls(dentry->d_inode, &acls);
        else
                d_drop(dentry);
+       ceph_release_acls_info(&acls);
        return err;
 }