summaryrefslogtreecommitdiffstats
path: root/fs/overlayfs/inode.c
diff options
context:
space:
mode:
authorMiklos Szeredi2018-07-18 15:44:41 +0200
committerMiklos Szeredi2018-07-18 15:44:41 +0200
commit5812160eb50925d19c54be979c72d335fee17dbd (patch)
treef8e335159ecb1193219803c15829bc0591d30523 /fs/overlayfs/inode.c
parentovl: copy up inode flags (diff)
downloadkernel-qcow2-linux-5812160eb50925d19c54be979c72d335fee17dbd.tar.gz
kernel-qcow2-linux-5812160eb50925d19c54be979c72d335fee17dbd.tar.xz
kernel-qcow2-linux-5812160eb50925d19c54be979c72d335fee17dbd.zip
Revert "Revert "ovl: get_write_access() in truncate""
This reverts commit 31c3a7069593b072bd57192b63b62f9a7e994e9a. Re-add functionality dealing with i_writecount on truncate to overlayfs. This patch shouldn't have any observable effects, since we just re-assert the writecout that vfs_truncate() already got for us. This is in preparation for moving overlay functionality out of the VFS. Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
Diffstat (limited to 'fs/overlayfs/inode.c')
-rw-r--r--fs/overlayfs/inode.c21
1 files changed, 21 insertions, 0 deletions
diff --git a/fs/overlayfs/inode.c b/fs/overlayfs/inode.c
index 0fa48d5644e2..3f1e5bd0ba87 100644
--- a/fs/overlayfs/inode.c
+++ b/fs/overlayfs/inode.c
@@ -39,10 +39,27 @@ int ovl_setattr(struct dentry *dentry, struct iattr *attr)
if (err)
goto out;
+ if (attr->ia_valid & ATTR_SIZE) {
+ struct inode *realinode = d_inode(ovl_dentry_real(dentry));
+
+ err = -ETXTBSY;
+ if (atomic_read(&realinode->i_writecount) < 0)
+ goto out_drop_write;
+ }
+
err = ovl_copy_up(dentry);
if (!err) {
+ struct inode *winode = NULL;
+
upperdentry = ovl_dentry_upper(dentry);
+ if (attr->ia_valid & ATTR_SIZE) {
+ winode = d_inode(upperdentry);
+ err = get_write_access(winode);
+ if (err)
+ goto out_drop_write;
+ }
+
if (attr->ia_valid & (ATTR_KILL_SUID|ATTR_KILL_SGID))
attr->ia_valid &= ~ATTR_MODE;
@@ -53,7 +70,11 @@ int ovl_setattr(struct dentry *dentry, struct iattr *attr)
if (!err)
ovl_copyattr(upperdentry->d_inode, dentry->d_inode);
inode_unlock(upperdentry->d_inode);
+
+ if (winode)
+ put_write_access(winode);
}
+out_drop_write:
ovl_drop_write(dentry);
out:
return err;