diff options
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); } |