diff options
author | Amir Goldstein <amir73il@gmail.com> | 2023-07-20 11:51:21 +0200 |
---|---|---|
committer | Amir Goldstein <amir73il@gmail.com> | 2023-10-30 23:12:57 +0100 |
commit | 162d06444070c12827d604a2cb6b6bd98d48cbb0 (patch) | |
tree | aa5ac2ffb3dce2d74c3fb7812b3ea37abca90a99 /fs/overlayfs/util.c | |
parent | ovl: split ovl_want_write() into two helpers (diff) | |
download | linux-162d06444070c12827d604a2cb6b6bd98d48cbb0.tar.xz linux-162d06444070c12827d604a2cb6b6bd98d48cbb0.zip |
ovl: reorder ovl_want_write() after ovl_inode_lock()
Make the locking order of ovl_inode_lock() strictly between the two
vfs stacked layers, i.e.:
- ovl vfs locks: sb_writers, inode_lock, ...
- ovl_inode_lock
- upper vfs locks: sb_writers, inode_lock, ...
To that effect, move ovl_want_write() into the helpers ovl_nlink_start()
and ovl_copy_up_start which currently take the ovl_inode_lock() after
ovl_want_write().
Signed-off-by: Amir Goldstein <amir73il@gmail.com>
Diffstat (limited to '')
-rw-r--r-- | fs/overlayfs/util.c | 34 |
1 files changed, 27 insertions, 7 deletions
diff --git a/fs/overlayfs/util.c b/fs/overlayfs/util.c index 80f20ca85344..af11c83b7a25 100644 --- a/fs/overlayfs/util.c +++ b/fs/overlayfs/util.c @@ -676,16 +676,26 @@ int ovl_copy_up_start(struct dentry *dentry, int flags) int err; err = ovl_inode_lock_interruptible(inode); - if (!err && ovl_already_copied_up_locked(dentry, flags)) { + if (err) + return err; + + if (ovl_already_copied_up_locked(dentry, flags)) err = 1; /* Already copied up */ - ovl_inode_unlock(inode); - } + else + err = ovl_want_write(dentry); + if (err) + goto out_unlock; + + return 0; +out_unlock: + ovl_inode_unlock(inode); return err; } void ovl_copy_up_end(struct dentry *dentry) { + ovl_drop_write(dentry); ovl_inode_unlock(d_inode(dentry)); } @@ -1088,8 +1098,12 @@ int ovl_nlink_start(struct dentry *dentry) if (err) return err; + err = ovl_want_write(dentry); + if (err) + goto out_unlock; + if (d_is_dir(dentry) || !ovl_test_flag(OVL_INDEX, inode)) - goto out; + return 0; old_cred = ovl_override_creds(dentry->d_sb); /* @@ -1100,10 +1114,15 @@ int ovl_nlink_start(struct dentry *dentry) */ err = ovl_set_nlink_upper(dentry); revert_creds(old_cred); - -out: if (err) - ovl_inode_unlock(inode); + goto out_drop_write; + + return 0; + +out_drop_write: + ovl_drop_write(dentry); +out_unlock: + ovl_inode_unlock(inode); return err; } @@ -1120,6 +1139,7 @@ void ovl_nlink_end(struct dentry *dentry) revert_creds(old_cred); } + ovl_drop_write(dentry); ovl_inode_unlock(inode); } |