The path that __d_path() computes can become slightly inconsistent when it
races with mount operations: it grabs the vfsmount_lock when traversing mount
points, but immediately drops it again, only to re-grab it when it reaches the
next mount point. The result is that the filename computed is not always
consisent, and the file may never have had that name. (This is unlikely, but
still possible.)
Fix this by grabbing the vfsmount_lock when the first mount point is reached,
and holding onto it until the d_cache lookup is completed.
Signed-off-by: Andreas Gruenbacher <[email protected]>
---
fs/dcache.c | 14 ++++++++------
1 file changed, 8 insertions(+), 6 deletions(-)
--- a/fs/dcache.c
+++ b/fs/dcache.c
@@ -1754,7 +1754,7 @@ static char *__d_path(struct dentry *den
struct dentry *root, struct vfsmount *rootmnt,
char *buffer, int buflen, int fail_deleted)
{
- int namelen, is_slash;
+ int namelen, is_slash, vfsmount_locked = 0;
if (buflen < 2)
return ERR_PTR(-ENAMETOOLONG);
@@ -1777,14 +1777,14 @@ static char *__d_path(struct dentry *den
struct dentry * parent;
if (dentry == vfsmnt->mnt_root || IS_ROOT(dentry)) {
- spin_lock(&vfsmount_lock);
- if (vfsmnt->mnt_parent == vfsmnt) {
- spin_unlock(&vfsmount_lock);
- goto global_root;
+ if (!vfsmount_locked) {
+ spin_lock(&vfsmount_lock);
+ vfsmount_locked = 1;
}
+ if (vfsmnt->mnt_parent == vfsmnt)
+ goto global_root;
dentry = vfsmnt->mnt_mountpoint;
vfsmnt = vfsmnt->mnt_parent;
- spin_unlock(&vfsmount_lock);
continue;
}
parent = dentry->d_parent;
@@ -1803,6 +1803,8 @@ static char *__d_path(struct dentry *den
*--buffer = '/';
out:
+ if (vfsmount_locked)
+ spin_unlock(&vfsmount_lock);
spin_unlock(&dcache_lock);
return buffer;
--
Andreas Gruenbacher <[email protected]>
SUSE Labs, SUSE LINUX Products GmbH
GF: Markus Rex, HRB 16746 (AG Nuernberg)
GPG: AF77 FAD1 1819 D442 400F 4BC8 409A 6903 4FDD EE02
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[Index of Archives]
[Kernel Newbies]
[Netfilter]
[Bugtraq]
[Photo]
[Stuff]
[Gimp]
[Yosemite News]
[MIPS Linux]
[ARM Linux]
[Linux Security]
[Linux RAID]
[Video 4 Linux]
[Linux for the blind]
[Linux Resources]