Skip to content

Commit 6cbfdf8

Browse files
Miklos Szeredibrauner
authored andcommitted
posix_acl: make posix_acl_to_xattr() alloc the buffer
Without exception all caller do that. So move the allocation into the helper. This reduces boilerplate and removes unnecessary error checking. Signed-off-by: Miklos Szeredi <mszeredi@redhat.com> Link: https://patch.msgid.link/20260115122341.556026-1-mszeredi@redhat.com Signed-off-by: Christian Brauner <brauner@kernel.org>
1 parent 88ec797 commit 6cbfdf8

10 files changed

Lines changed: 53 additions & 97 deletions

File tree

fs/9p/acl.c

Lines changed: 3 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -167,17 +167,11 @@ int v9fs_iop_set_acl(struct mnt_idmap *idmap, struct dentry *dentry,
167167
if (retval)
168168
goto err_out;
169169

170-
size = posix_acl_xattr_size(acl->a_count);
171-
172-
value = kzalloc(size, GFP_NOFS);
170+
value = posix_acl_to_xattr(&init_user_ns, acl, &size, GFP_NOFS);
173171
if (!value) {
174172
retval = -ENOMEM;
175173
goto err_out;
176174
}
177-
178-
retval = posix_acl_to_xattr(&init_user_ns, acl, value, size);
179-
if (retval < 0)
180-
goto err_out;
181175
}
182176

183177
/*
@@ -257,13 +251,10 @@ static int v9fs_set_acl(struct p9_fid *fid, int type, struct posix_acl *acl)
257251
return 0;
258252

259253
/* Set a setxattr request to server */
260-
size = posix_acl_xattr_size(acl->a_count);
261-
buffer = kmalloc(size, GFP_KERNEL);
254+
buffer = posix_acl_to_xattr(&init_user_ns, acl, &size, GFP_KERNEL);
262255
if (!buffer)
263256
return -ENOMEM;
264-
retval = posix_acl_to_xattr(&init_user_ns, acl, buffer, size);
265-
if (retval < 0)
266-
goto err_free_out;
257+
267258
switch (type) {
268259
case ACL_TYPE_ACCESS:
269260
name = XATTR_NAME_POSIX_ACL_ACCESS;
@@ -275,7 +266,6 @@ static int v9fs_set_acl(struct p9_fid *fid, int type, struct posix_acl *acl)
275266
BUG();
276267
}
277268
retval = v9fs_fid_xattr_set(fid, name, buffer, size, 0);
278-
err_free_out:
279269
kfree(buffer);
280270
return retval;
281271
}

fs/btrfs/acl.c

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,8 @@ struct posix_acl *btrfs_get_acl(struct inode *inode, int type, bool rcu)
5757
int __btrfs_set_acl(struct btrfs_trans_handle *trans, struct inode *inode,
5858
struct posix_acl *acl, int type)
5959
{
60-
int ret, size = 0;
60+
int ret;
61+
size_t size = 0;
6162
const char *name;
6263
char AUTO_KFREE(value);
6364

@@ -77,20 +78,15 @@ int __btrfs_set_acl(struct btrfs_trans_handle *trans, struct inode *inode,
7778
if (acl) {
7879
unsigned int nofs_flag;
7980

80-
size = posix_acl_xattr_size(acl->a_count);
8181
/*
8282
* We're holding a transaction handle, so use a NOFS memory
8383
* allocation context to avoid deadlock if reclaim happens.
8484
*/
8585
nofs_flag = memalloc_nofs_save();
86-
value = kmalloc(size, GFP_KERNEL);
86+
value = posix_acl_to_xattr(&init_user_ns, acl, &size, GFP_KERNEL);
8787
memalloc_nofs_restore(nofs_flag);
8888
if (!value)
8989
return -ENOMEM;
90-
91-
ret = posix_acl_to_xattr(&init_user_ns, acl, value, size);
92-
if (ret < 0)
93-
return ret;
9490
}
9591

9692
if (trans)

fs/ceph/acl.c

Lines changed: 22 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,8 @@ struct posix_acl *ceph_get_acl(struct inode *inode, int type, bool rcu)
9090
int ceph_set_acl(struct mnt_idmap *idmap, struct dentry *dentry,
9191
struct posix_acl *acl, int type)
9292
{
93-
int ret = 0, size = 0;
93+
int ret = 0;
94+
size_t size = 0;
9495
const char *name = NULL;
9596
char *value = NULL;
9697
struct iattr newattrs;
@@ -126,16 +127,11 @@ int ceph_set_acl(struct mnt_idmap *idmap, struct dentry *dentry,
126127
}
127128

128129
if (acl) {
129-
size = posix_acl_xattr_size(acl->a_count);
130-
value = kmalloc(size, GFP_NOFS);
130+
value = posix_acl_to_xattr(&init_user_ns, acl, &size, GFP_NOFS);
131131
if (!value) {
132132
ret = -ENOMEM;
133133
goto out;
134134
}
135-
136-
ret = posix_acl_to_xattr(&init_user_ns, acl, value, size);
137-
if (ret < 0)
138-
goto out_free;
139135
}
140136

141137
if (new_mode != old_mode) {
@@ -172,7 +168,7 @@ int ceph_pre_init_acls(struct inode *dir, umode_t *mode,
172168
struct posix_acl *acl, *default_acl;
173169
size_t val_size1 = 0, val_size2 = 0;
174170
struct ceph_pagelist *pagelist = NULL;
175-
void *tmp_buf = NULL;
171+
void *tmp_buf1 = NULL, *tmp_buf2 = NULL;
176172
int err;
177173

178174
err = posix_acl_create(dir, mode, &default_acl, &acl);
@@ -192,15 +188,7 @@ int ceph_pre_init_acls(struct inode *dir, umode_t *mode,
192188
if (!default_acl && !acl)
193189
return 0;
194190

195-
if (acl)
196-
val_size1 = posix_acl_xattr_size(acl->a_count);
197-
if (default_acl)
198-
val_size2 = posix_acl_xattr_size(default_acl->a_count);
199-
200191
err = -ENOMEM;
201-
tmp_buf = kmalloc(max(val_size1, val_size2), GFP_KERNEL);
202-
if (!tmp_buf)
203-
goto out_err;
204192
pagelist = ceph_pagelist_alloc(GFP_KERNEL);
205193
if (!pagelist)
206194
goto out_err;
@@ -213,34 +201,39 @@ int ceph_pre_init_acls(struct inode *dir, umode_t *mode,
213201

214202
if (acl) {
215203
size_t len = strlen(XATTR_NAME_POSIX_ACL_ACCESS);
204+
205+
err = -ENOMEM;
206+
tmp_buf1 = posix_acl_to_xattr(&init_user_ns, acl,
207+
&val_size1, GFP_KERNEL);
208+
if (!tmp_buf1)
209+
goto out_err;
216210
err = ceph_pagelist_reserve(pagelist, len + val_size1 + 8);
217211
if (err)
218212
goto out_err;
219213
ceph_pagelist_encode_string(pagelist, XATTR_NAME_POSIX_ACL_ACCESS,
220214
len);
221-
err = posix_acl_to_xattr(&init_user_ns, acl,
222-
tmp_buf, val_size1);
223-
if (err < 0)
224-
goto out_err;
225215
ceph_pagelist_encode_32(pagelist, val_size1);
226-
ceph_pagelist_append(pagelist, tmp_buf, val_size1);
216+
ceph_pagelist_append(pagelist, tmp_buf1, val_size1);
227217
}
228218
if (default_acl) {
229219
size_t len = strlen(XATTR_NAME_POSIX_ACL_DEFAULT);
220+
221+
err = -ENOMEM;
222+
tmp_buf2 = posix_acl_to_xattr(&init_user_ns, default_acl,
223+
&val_size2, GFP_KERNEL);
224+
if (!tmp_buf2)
225+
goto out_err;
230226
err = ceph_pagelist_reserve(pagelist, len + val_size2 + 8);
231227
if (err)
232228
goto out_err;
233229
ceph_pagelist_encode_string(pagelist,
234230
XATTR_NAME_POSIX_ACL_DEFAULT, len);
235-
err = posix_acl_to_xattr(&init_user_ns, default_acl,
236-
tmp_buf, val_size2);
237-
if (err < 0)
238-
goto out_err;
239231
ceph_pagelist_encode_32(pagelist, val_size2);
240-
ceph_pagelist_append(pagelist, tmp_buf, val_size2);
232+
ceph_pagelist_append(pagelist, tmp_buf2, val_size2);
241233
}
242234

243-
kfree(tmp_buf);
235+
kfree(tmp_buf1);
236+
kfree(tmp_buf2);
244237

245238
as_ctx->acl = acl;
246239
as_ctx->default_acl = default_acl;
@@ -250,7 +243,8 @@ int ceph_pre_init_acls(struct inode *dir, umode_t *mode,
250243
out_err:
251244
posix_acl_release(acl);
252245
posix_acl_release(default_acl);
253-
kfree(tmp_buf);
246+
kfree(tmp_buf1);
247+
kfree(tmp_buf2);
254248
if (pagelist)
255249
ceph_pagelist_release(pagelist);
256250
return err;

fs/fuse/acl.c

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -122,20 +122,16 @@ int fuse_set_acl(struct mnt_idmap *idmap, struct dentry *dentry,
122122
* them to be refreshed the next time they are used,
123123
* and it also updates i_ctime.
124124
*/
125-
size_t size = posix_acl_xattr_size(acl->a_count);
125+
size_t size;
126126
void *value;
127127

128-
if (size > PAGE_SIZE)
129-
return -E2BIG;
130-
131-
value = kmalloc(size, GFP_KERNEL);
128+
value = posix_acl_to_xattr(fc->user_ns, acl, &size, GFP_KERNEL);
132129
if (!value)
133130
return -ENOMEM;
134131

135-
ret = posix_acl_to_xattr(fc->user_ns, acl, value, size);
136-
if (ret < 0) {
132+
if (size > PAGE_SIZE) {
137133
kfree(value);
138-
return ret;
134+
return -E2BIG;
139135
}
140136

141137
/*

fs/gfs2/acl.c

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -83,21 +83,14 @@ struct posix_acl *gfs2_get_acl(struct inode *inode, int type, bool rcu)
8383
int __gfs2_set_acl(struct inode *inode, struct posix_acl *acl, int type)
8484
{
8585
int error;
86-
size_t len;
87-
char *data;
86+
size_t len = 0;
87+
char *data = NULL;
8888
const char *name = gfs2_acl_name(type);
8989

9090
if (acl) {
91-
len = posix_acl_xattr_size(acl->a_count);
92-
data = kmalloc(len, GFP_NOFS);
91+
data = posix_acl_to_xattr(&init_user_ns, acl, &len, GFP_NOFS);
9392
if (data == NULL)
9493
return -ENOMEM;
95-
error = posix_acl_to_xattr(&init_user_ns, acl, data, len);
96-
if (error < 0)
97-
goto out;
98-
} else {
99-
data = NULL;
100-
len = 0;
10194
}
10295

10396
error = __gfs2_xattr_set(inode, name, data, len, 0, GFS2_EATYPE_SYS);

fs/jfs/acl.c

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ static int __jfs_set_acl(tid_t tid, struct inode *inode, int type,
6161
{
6262
char *ea_name;
6363
int rc;
64-
int size = 0;
64+
size_t size = 0;
6565
char *value = NULL;
6666

6767
switch (type) {
@@ -76,16 +76,11 @@ static int __jfs_set_acl(tid_t tid, struct inode *inode, int type,
7676
}
7777

7878
if (acl) {
79-
size = posix_acl_xattr_size(acl->a_count);
80-
value = kmalloc(size, GFP_KERNEL);
79+
value = posix_acl_to_xattr(&init_user_ns, acl, &size, GFP_KERNEL);
8180
if (!value)
8281
return -ENOMEM;
83-
rc = posix_acl_to_xattr(&init_user_ns, acl, value, size);
84-
if (rc < 0)
85-
goto out;
8682
}
8783
rc = __jfs_setxattr(tid, inode, ea_name, value, size, 0);
88-
out:
8984
kfree(value);
9085

9186
if (!rc)

fs/ntfs3/xattr.c

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -641,13 +641,9 @@ static noinline int ntfs_set_acl_ex(struct mnt_idmap *idmap,
641641
value = NULL;
642642
flags = XATTR_REPLACE;
643643
} else {
644-
size = posix_acl_xattr_size(acl->a_count);
645-
value = kmalloc(size, GFP_NOFS);
644+
value = posix_acl_to_xattr(&init_user_ns, acl, &size, GFP_NOFS);
646645
if (!value)
647646
return -ENOMEM;
648-
err = posix_acl_to_xattr(&init_user_ns, acl, value, size);
649-
if (err < 0)
650-
goto out;
651647
flags = 0;
652648
}
653649

fs/orangefs/acl.c

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -90,14 +90,9 @@ int __orangefs_set_acl(struct inode *inode, struct posix_acl *acl, int type)
9090
type);
9191

9292
if (acl) {
93-
size = posix_acl_xattr_size(acl->a_count);
94-
value = kmalloc(size, GFP_KERNEL);
93+
value = posix_acl_to_xattr(&init_user_ns, acl, &size, GFP_KERNEL);
9594
if (!value)
9695
return -ENOMEM;
97-
98-
error = posix_acl_to_xattr(&init_user_ns, acl, value, size);
99-
if (error < 0)
100-
goto out;
10196
}
10297

10398
gossip_debug(GOSSIP_ACL_DEBUG,
@@ -111,7 +106,6 @@ int __orangefs_set_acl(struct inode *inode, struct posix_acl *acl, int type)
111106
*/
112107
error = orangefs_inode_setxattr(inode, name, value, size, 0);
113108

114-
out:
115109
kfree(value);
116110
if (!error)
117111
set_cached_acl(inode, type, acl);

fs/posix_acl.c

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -829,19 +829,19 @@ EXPORT_SYMBOL (posix_acl_from_xattr);
829829
/*
830830
* Convert from in-memory to extended attribute representation.
831831
*/
832-
int
832+
void *
833833
posix_acl_to_xattr(struct user_namespace *user_ns, const struct posix_acl *acl,
834-
void *buffer, size_t size)
834+
size_t *sizep, gfp_t gfp)
835835
{
836-
struct posix_acl_xattr_header *ext_acl = buffer;
836+
struct posix_acl_xattr_header *ext_acl;
837837
struct posix_acl_xattr_entry *ext_entry;
838-
int real_size, n;
838+
size_t size;
839+
int n;
839840

840-
real_size = posix_acl_xattr_size(acl->a_count);
841-
if (!buffer)
842-
return real_size;
843-
if (real_size > size)
844-
return -ERANGE;
841+
size = posix_acl_xattr_size(acl->a_count);
842+
ext_acl = kmalloc(size, gfp);
843+
if (!ext_acl)
844+
return NULL;
845845

846846
ext_entry = (void *)(ext_acl + 1);
847847
ext_acl->a_version = cpu_to_le32(POSIX_ACL_XATTR_VERSION);
@@ -864,7 +864,8 @@ posix_acl_to_xattr(struct user_namespace *user_ns, const struct posix_acl *acl,
864864
break;
865865
}
866866
}
867-
return real_size;
867+
*sizep = size;
868+
return ext_acl;
868869
}
869870
EXPORT_SYMBOL (posix_acl_to_xattr);
870871

include/linux/posix_acl_xattr.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,9 @@ posix_acl_from_xattr(struct user_namespace *user_ns, const void *value,
4444
}
4545
#endif
4646

47-
int posix_acl_to_xattr(struct user_namespace *user_ns,
48-
const struct posix_acl *acl, void *buffer, size_t size);
47+
extern void *posix_acl_to_xattr(struct user_namespace *user_ns, const struct posix_acl *acl,
48+
size_t *sizep, gfp_t gfp);
49+
4950
static inline const char *posix_acl_xattr_name(int type)
5051
{
5152
switch (type) {

0 commit comments

Comments
 (0)