[PATCH][SRU][Disco] UBUNTU: SAUCE: shiftfs: fix buggy unlink logic
Christian Brauner
christian.brauner at ubuntu.com
Thu Aug 29 18:45:07 UTC 2019
BugLink: https://bugs.launchpad.net/bugs/1841977
The way we messed with setting i_nlink was brittle and wrong. We used to
set the i_nlink of the shiftfs dentry to be deleted to the i_nlink count
of the underlay dentry of the directory it resided in which makes no
sense whatsoever. We also missed drop_nlink() which is crucial since
i_nlink affects whether a dentry is cleaned up on dput().
With this I cannot reproduce the bug anymore where shiftfs misleads zfs
into believing that a deleted file can not be removed from disk because
it is still referenced.
Fixes: commit 87011da41961 ("shiftfs: rework and extend")
Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
fs/shiftfs.c | 15 ++++++++++-----
1 file changed, 10 insertions(+), 5 deletions(-)
diff --git a/fs/shiftfs.c b/fs/shiftfs.c
index 57e04a02d74c..084aa7a25566 100644
--- a/fs/shiftfs.c
+++ b/fs/shiftfs.c
@@ -585,6 +585,7 @@ static int shiftfs_rm(struct inode *dir, struct dentry *dentry, bool rmdir)
{
struct dentry *lowerd = dentry->d_fsdata;
struct inode *loweri = dir->i_private;
+ struct inode *inode = d_inode(dentry);
int err;
const struct cred *oldcred;
@@ -594,15 +595,19 @@ static int shiftfs_rm(struct inode *dir, struct dentry *dentry, bool rmdir)
err = vfs_rmdir(loweri, lowerd);
else
err = vfs_unlink(loweri, lowerd, NULL);
- inode_unlock(loweri);
revert_creds(oldcred);
- shiftfs_copyattr(loweri, dir);
- set_nlink(d_inode(dentry), loweri->i_nlink);
- if (!err)
+ if (!err) {
d_drop(dentry);
- set_nlink(dir, loweri->i_nlink);
+ if (rmdir)
+ clear_nlink(inode);
+ else
+ drop_nlink(inode);
+ }
+ inode_unlock(loweri);
+
+ shiftfs_copyattr(loweri, dir);
return err;
}
--
2.23.0
More information about the kernel-team
mailing list