Skip to content

Commit 4053d25

Browse files
committed
orangefs: rework posix acl handling when creating new filesystem objects
When creating new filesytem objects orangefs used to create posix acls after it had created and inserted a new inode. This made it necessary to all posix_acl_chmod() on the newly created inode in case the mode of the inode would be changed by the posix acls. Instead of doing it this way calculate the correct mode directly before actually creating the inode. So we first create posix acls, then pass the mode that posix acls mandate into the orangefs getattr helper and calculate the correct mode. This is needed so we can simply change posix_acl_chmod() to take a dentry instead of an inode argument in the next patch. Reviewed-by: Christoph Hellwig <[email protected]> Signed-off-by: Christian Brauner (Microsoft) <[email protected]>
1 parent 9abf231 commit 4053d25

File tree

4 files changed

+50
-54
lines changed

4 files changed

+50
-54
lines changed

fs/orangefs/acl.c

Lines changed: 2 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -64,8 +64,7 @@ struct posix_acl *orangefs_get_acl(struct inode *inode, int type, bool rcu)
6464
return acl;
6565
}
6666

67-
static int __orangefs_set_acl(struct inode *inode, struct posix_acl *acl,
68-
int type)
67+
int __orangefs_set_acl(struct inode *inode, struct posix_acl *acl, int type)
6968
{
7069
int error = 0;
7170
void *value = NULL;
@@ -153,46 +152,7 @@ int orangefs_set_acl(struct user_namespace *mnt_userns, struct inode *inode,
153152
rc = __orangefs_set_acl(inode, acl, type);
154153

155154
if (!rc && (iattr.ia_valid == ATTR_MODE))
156-
rc = __orangefs_setattr(inode, &iattr);
155+
rc = __orangefs_setattr_mode(inode, &iattr);
157156

158157
return rc;
159158
}
160-
161-
int orangefs_init_acl(struct inode *inode, struct inode *dir)
162-
{
163-
struct posix_acl *default_acl, *acl;
164-
umode_t mode = inode->i_mode;
165-
struct iattr iattr;
166-
int error = 0;
167-
168-
error = posix_acl_create(dir, &mode, &default_acl, &acl);
169-
if (error)
170-
return error;
171-
172-
if (default_acl) {
173-
error = __orangefs_set_acl(inode, default_acl,
174-
ACL_TYPE_DEFAULT);
175-
posix_acl_release(default_acl);
176-
} else {
177-
inode->i_default_acl = NULL;
178-
}
179-
180-
if (acl) {
181-
if (!error)
182-
error = __orangefs_set_acl(inode, acl, ACL_TYPE_ACCESS);
183-
posix_acl_release(acl);
184-
} else {
185-
inode->i_acl = NULL;
186-
}
187-
188-
/* If mode of the inode was changed, then do a forcible ->setattr */
189-
if (mode != inode->i_mode) {
190-
memset(&iattr, 0, sizeof iattr);
191-
inode->i_mode = mode;
192-
iattr.ia_mode = mode;
193-
iattr.ia_valid |= ATTR_MODE;
194-
__orangefs_setattr(inode, &iattr);
195-
}
196-
197-
return error;
198-
}

fs/orangefs/inode.c

Lines changed: 36 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -828,15 +828,22 @@ int __orangefs_setattr(struct inode *inode, struct iattr *iattr)
828828
spin_unlock(&inode->i_lock);
829829
mark_inode_dirty(inode);
830830

831-
if (iattr->ia_valid & ATTR_MODE)
832-
/* change mod on a file that has ACLs */
833-
ret = posix_acl_chmod(&init_user_ns, inode, inode->i_mode);
834-
835831
ret = 0;
836832
out:
837833
return ret;
838834
}
839835

836+
int __orangefs_setattr_mode(struct inode *inode, struct iattr *iattr)
837+
{
838+
int ret;
839+
840+
ret = __orangefs_setattr(inode, iattr);
841+
/* change mode on a file that has ACLs */
842+
if (!ret && (iattr->ia_valid & ATTR_MODE))
843+
ret = posix_acl_chmod(&init_user_ns, inode, inode->i_mode);
844+
return ret;
845+
}
846+
840847
/*
841848
* Change attributes of an object referenced by dentry.
842849
*/
@@ -849,7 +856,7 @@ int orangefs_setattr(struct user_namespace *mnt_userns, struct dentry *dentry,
849856
ret = setattr_prepare(&init_user_ns, dentry, iattr);
850857
if (ret)
851858
goto out;
852-
ret = __orangefs_setattr(d_inode(dentry), iattr);
859+
ret = __orangefs_setattr_mode(d_inode(dentry), iattr);
853860
sync_inode_metadata(d_inode(dentry), 1);
854861
out:
855862
gossip_debug(GOSSIP_INODE_DEBUG, "orangefs_setattr: returning %d\n",
@@ -1097,8 +1104,9 @@ struct inode *orangefs_iget(struct super_block *sb,
10971104
* Allocate an inode for a newly created file and insert it into the inode hash.
10981105
*/
10991106
struct inode *orangefs_new_inode(struct super_block *sb, struct inode *dir,
1100-
int mode, dev_t dev, struct orangefs_object_kref *ref)
1107+
umode_t mode, dev_t dev, struct orangefs_object_kref *ref)
11011108
{
1109+
struct posix_acl *acl = NULL, *default_acl = NULL;
11021110
unsigned long hash = orangefs_handle_hash(ref);
11031111
struct inode *inode;
11041112
int error;
@@ -1115,27 +1123,47 @@ struct inode *orangefs_new_inode(struct super_block *sb, struct inode *dir,
11151123
if (!inode)
11161124
return ERR_PTR(-ENOMEM);
11171125

1126+
error = posix_acl_create(dir, &mode, &default_acl, &acl);
1127+
if (error)
1128+
goto out_iput;
1129+
11181130
orangefs_set_inode(inode, ref);
11191131
inode->i_ino = hash; /* needed for stat etc */
11201132

1121-
error = orangefs_inode_getattr(inode, ORANGEFS_GETATTR_NEW);
1133+
error = __orangefs_inode_getattr(inode, mode, ORANGEFS_GETATTR_NEW);
11221134
if (error)
11231135
goto out_iput;
11241136

11251137
orangefs_init_iops(inode);
11261138
inode->i_rdev = dev;
11271139

1140+
if (default_acl) {
1141+
error = __orangefs_set_acl(inode, default_acl,
1142+
ACL_TYPE_DEFAULT);
1143+
if (error)
1144+
goto out_iput;
1145+
}
1146+
1147+
if (acl) {
1148+
error = __orangefs_set_acl(inode, acl, ACL_TYPE_ACCESS);
1149+
if (error)
1150+
goto out_iput;
1151+
}
1152+
11281153
error = insert_inode_locked4(inode, hash, orangefs_test_inode, ref);
11291154
if (error < 0)
11301155
goto out_iput;
11311156

11321157
gossip_debug(GOSSIP_INODE_DEBUG,
11331158
"Initializing ACL's for inode %pU\n",
11341159
get_khandle_from_ino(inode));
1135-
orangefs_init_acl(inode, dir);
1160+
posix_acl_release(acl);
1161+
posix_acl_release(default_acl);
11361162
return inode;
11371163

11381164
out_iput:
11391165
iput(inode);
1166+
posix_acl_release(acl);
1167+
posix_acl_release(default_acl);
11401168
return ERR_PTR(error);
11411169
}

fs/orangefs/orangefs-kernel.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -103,13 +103,13 @@ enum orangefs_vfs_op_states {
103103
#define ORANGEFS_CACHE_CREATE_FLAGS 0
104104
#endif
105105

106-
extern int orangefs_init_acl(struct inode *inode, struct inode *dir);
107106
extern const struct xattr_handler *orangefs_xattr_handlers[];
108107

109108
extern struct posix_acl *orangefs_get_acl(struct inode *inode, int type, bool rcu);
110109
extern int orangefs_set_acl(struct user_namespace *mnt_userns,
111110
struct inode *inode, struct posix_acl *acl,
112111
int type);
112+
int __orangefs_set_acl(struct inode *inode, struct posix_acl *acl, int type);
113113

114114
/*
115115
* orangefs data structures
@@ -356,11 +356,12 @@ void fsid_key_table_finalize(void);
356356
vm_fault_t orangefs_page_mkwrite(struct vm_fault *);
357357
struct inode *orangefs_new_inode(struct super_block *sb,
358358
struct inode *dir,
359-
int mode,
359+
umode_t mode,
360360
dev_t dev,
361361
struct orangefs_object_kref *ref);
362362

363363
int __orangefs_setattr(struct inode *, struct iattr *);
364+
int __orangefs_setattr_mode(struct inode *inode, struct iattr *iattr);
364365
int orangefs_setattr(struct user_namespace *, struct dentry *, struct iattr *);
365366

366367
int orangefs_getattr(struct user_namespace *mnt_userns, const struct path *path,
@@ -422,6 +423,7 @@ int orangefs_inode_setxattr(struct inode *inode,
422423
#define ORANGEFS_GETATTR_SIZE 2
423424

424425
int orangefs_inode_getattr(struct inode *, int);
426+
int __orangefs_inode_getattr(struct inode *inode, umode_t mode, int flags);
425427

426428
int orangefs_inode_check_changed(struct inode *inode);
427429

fs/orangefs/orangefs-utils.c

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -233,7 +233,7 @@ static int orangefs_inode_is_stale(struct inode *inode,
233233
return 0;
234234
}
235235

236-
int orangefs_inode_getattr(struct inode *inode, int flags)
236+
int __orangefs_inode_getattr(struct inode *inode, umode_t mode, int flags)
237237
{
238238
struct orangefs_inode_s *orangefs_inode = ORANGEFS_I(inode);
239239
struct orangefs_kernel_op_s *new_op;
@@ -369,7 +369,8 @@ int orangefs_inode_getattr(struct inode *inode, int flags)
369369

370370
/* special case: mark the root inode as sticky */
371371
inode->i_mode = type | (is_root_handle(inode) ? S_ISVTX : 0) |
372-
orangefs_inode_perms(&new_op->downcall.resp.getattr.attributes);
372+
orangefs_inode_perms(&new_op->downcall.resp.getattr.attributes) |
373+
mode;
373374

374375
orangefs_inode->getattr_time = jiffies +
375376
orangefs_getattr_timeout_msecs*HZ/1000;
@@ -381,6 +382,11 @@ int orangefs_inode_getattr(struct inode *inode, int flags)
381382
return ret;
382383
}
383384

385+
int orangefs_inode_getattr(struct inode *inode, int flags)
386+
{
387+
return __orangefs_inode_getattr(inode, 0, flags);
388+
}
389+
384390
int orangefs_inode_check_changed(struct inode *inode)
385391
{
386392
struct orangefs_inode_s *orangefs_inode = ORANGEFS_I(inode);

0 commit comments

Comments
 (0)