diff options
author | Kent Overstreet <kent.overstreet@linux.dev> | 2023-05-28 03:44:38 -0400 |
---|---|---|
committer | Kent Overstreet <kent.overstreet@linux.dev> | 2023-10-22 17:10:03 -0400 |
commit | 5ff10c0a04c4217b24997d9b127c50602d717ab3 (patch) | |
tree | d592cefa8d5e799cea24da9325f311f4bfabece6 /fs/bcachefs/acl.c | |
parent | d95dd378c207ddec7551cce2e047e6067c3c27ab (diff) | |
download | lwn-5ff10c0a04c4217b24997d9b127c50602d717ab3.tar.gz lwn-5ff10c0a04c4217b24997d9b127c50602d717ab3.zip |
bcachefs: Convert acl.c to allocate_dropping_locks()
More work to avoid allocating memory with btree locks held.
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
Diffstat (limited to 'fs/bcachefs/acl.c')
-rw-r--r-- | fs/bcachefs/acl.c | 23 |
1 files changed, 16 insertions, 7 deletions
diff --git a/fs/bcachefs/acl.c b/fs/bcachefs/acl.c index 3fe108bc2f08..ce7a460fb308 100644 --- a/fs/bcachefs/acl.c +++ b/fs/bcachefs/acl.c @@ -35,12 +35,14 @@ static inline int acl_to_xattr_type(int type) /* * Convert from filesystem to in-memory representation. */ -static struct posix_acl *bch2_acl_from_disk(const void *value, size_t size) +static struct posix_acl *bch2_acl_from_disk(struct btree_trans *trans, + const void *value, size_t size) { const void *p, *end = value + size; struct posix_acl *acl; struct posix_acl_entry *out; unsigned count = 0; + int ret; if (!value) return NULL; @@ -81,9 +83,14 @@ static struct posix_acl *bch2_acl_from_disk(const void *value, size_t size) if (!count) return NULL; - acl = posix_acl_alloc(count, GFP_KERNEL); + acl = allocate_dropping_locks(trans, ret, + posix_acl_alloc(count, _gfp)); if (!acl) return ERR_PTR(-ENOMEM); + if (ret) { + kfree(acl); + return ERR_PTR(ret); + } out = acl->a_entries; @@ -234,8 +241,6 @@ retry: &X_SEARCH(acl_to_xattr_type(type), "", 0), 0); if (ret) { - if (bch2_err_matches(ret, BCH_ERR_transaction_restart)) - goto retry; if (!bch2_err_matches(ret, ENOENT)) acl = ERR_PTR(ret); goto out; @@ -249,12 +254,15 @@ retry: } xattr = bkey_s_c_to_xattr(k); - acl = bch2_acl_from_disk(xattr_val(xattr.v), + acl = bch2_acl_from_disk(&trans, xattr_val(xattr.v), le16_to_cpu(xattr.v->x_val_len)); if (!IS_ERR(acl)) set_cached_acl(&inode->v, type, acl); out: + if (bch2_err_matches(PTR_ERR_OR_ZERO(acl), BCH_ERR_transaction_restart)) + goto retry; + bch2_trans_iter_exit(&trans, &iter); bch2_trans_exit(&trans); return acl; @@ -375,13 +383,14 @@ int bch2_acl_chmod(struct btree_trans *trans, subvol_inum inum, if (ret) goto err; - acl = bch2_acl_from_disk(xattr_val(xattr.v), + acl = bch2_acl_from_disk(trans, xattr_val(xattr.v), le16_to_cpu(xattr.v->x_val_len)); ret = PTR_ERR_OR_ZERO(acl); if (IS_ERR_OR_NULL(acl)) goto err; - ret = __posix_acl_chmod(&acl, GFP_KERNEL, mode); + ret = allocate_dropping_locks_errcode(trans, + __posix_acl_chmod(&acl, _gfp, mode)); if (ret) goto err; |