mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-30 03:27:44 -04:00
fs: add file_dentry()
This series fixes bugs in nfs and ext4 due to 4bacc9c923 ("overlayfs:
Make f_path always point to the overlay and f_inode to the underlay").
Regular files opened on overlayfs will result in the file being opened on
the underlying filesystem, while f_path points to the overlayfs
mount/dentry.
This confuses filesystems which get the dentry from struct file and assume
it's theirs.
Add a new helper, file_dentry() [*], to get the filesystem's own dentry
from the file. This checks file->f_path.dentry->d_flags against
DCACHE_OP_REAL, and returns file->f_path.dentry if DCACHE_OP_REAL is not
set (this is the common, non-overlayfs case).
In the uncommon case it will call into overlayfs's ->d_real() to get the
underlying dentry, matching file_inode(file).
The reason we need to check against the inode is that if the file is copied
up while being open, d_real() would return the upper dentry, while the open
file comes from the lower dentry.
[*] If possible, it's better simply to use file_inode() instead.
Signed-off-by: Miklos Szeredi <[email protected]>
Signed-off-by: Theodore Ts'o <[email protected]>
Tested-by: Goldwyn Rodrigues <[email protected]>
Reviewed-by: Trond Myklebust <[email protected]>
Cc: <[email protected]> # v4.2
Cc: David Howells <[email protected]>
Cc: Al Viro <[email protected]>
Cc: Daniel Axtens <[email protected]>
This commit is contained in:
parent
c9af28fdd4
commit
d101a12595
4 changed files with 57 additions and 1 deletions
|
|
@ -1667,7 +1667,8 @@ void d_set_d_op(struct dentry *dentry, const struct dentry_operations *op)
|
|||
DCACHE_OP_REVALIDATE |
|
||||
DCACHE_OP_WEAK_REVALIDATE |
|
||||
DCACHE_OP_DELETE |
|
||||
DCACHE_OP_SELECT_INODE));
|
||||
DCACHE_OP_SELECT_INODE |
|
||||
DCACHE_OP_REAL));
|
||||
dentry->d_op = op;
|
||||
if (!op)
|
||||
return;
|
||||
|
|
@ -1685,6 +1686,8 @@ void d_set_d_op(struct dentry *dentry, const struct dentry_operations *op)
|
|||
dentry->d_flags |= DCACHE_OP_PRUNE;
|
||||
if (op->d_select_inode)
|
||||
dentry->d_flags |= DCACHE_OP_SELECT_INODE;
|
||||
if (op->d_real)
|
||||
dentry->d_flags |= DCACHE_OP_REAL;
|
||||
|
||||
}
|
||||
EXPORT_SYMBOL(d_set_d_op);
|
||||
|
|
|
|||
Loading…
Reference in a new issue