|
@@ -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;
|
|
|
}
|
|
|
|