Commit be285c712bbbe5db43e503782fbef2bfeaa345f9
Committed by
Al Viro
1 parent
f9f48ec72b
Exists in
master
and in
7 other branches
[patch 3/3] vfs: make d_path() consistent across mount operations
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 for the whole duration of __d_path(). Signed-off-by: Andreas Gruenbacher <agruen@suse.de> Signed-off-by: John Johansen <jjohansen@suse.de> Signed-off-by: Miklos Szeredi <mszeredi@suse.cz> Acked-by: Christoph Hellwig <hch@infradead.org> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Showing 1 changed file with 7 additions and 5 deletions Side-by-side Diff
fs/dcache.c
... | ... | @@ -1782,6 +1782,7 @@ |
1782 | 1782 | char * end = buffer+buflen; |
1783 | 1783 | char * retval; |
1784 | 1784 | |
1785 | + spin_lock(&vfsmount_lock); | |
1785 | 1786 | prepend(&end, &buflen, "\0", 1); |
1786 | 1787 | if (!IS_ROOT(dentry) && d_unhashed(dentry) && |
1787 | 1788 | (prepend(&end, &buflen, " (deleted)", 10) != 0)) |
1788 | 1789 | |
1789 | 1790 | |
... | ... | @@ -1800,14 +1801,11 @@ |
1800 | 1801 | break; |
1801 | 1802 | if (dentry == vfsmnt->mnt_root || IS_ROOT(dentry)) { |
1802 | 1803 | /* Global root? */ |
1803 | - spin_lock(&vfsmount_lock); | |
1804 | 1804 | if (vfsmnt->mnt_parent == vfsmnt) { |
1805 | - spin_unlock(&vfsmount_lock); | |
1806 | 1805 | goto global_root; |
1807 | 1806 | } |
1808 | 1807 | dentry = vfsmnt->mnt_mountpoint; |
1809 | 1808 | vfsmnt = vfsmnt->mnt_parent; |
1810 | - spin_unlock(&vfsmount_lock); | |
1811 | 1809 | continue; |
1812 | 1810 | } |
1813 | 1811 | parent = dentry->d_parent; |
... | ... | @@ -1820,6 +1818,8 @@ |
1820 | 1818 | dentry = parent; |
1821 | 1819 | } |
1822 | 1820 | |
1821 | +out: | |
1822 | + spin_unlock(&vfsmount_lock); | |
1823 | 1823 | return retval; |
1824 | 1824 | |
1825 | 1825 | global_root: |
1826 | 1826 | |
... | ... | @@ -1829,9 +1829,11 @@ |
1829 | 1829 | goto Elong; |
1830 | 1830 | root->mnt = vfsmnt; |
1831 | 1831 | root->dentry = dentry; |
1832 | - return retval; | |
1832 | + goto out; | |
1833 | + | |
1833 | 1834 | Elong: |
1834 | - return ERR_PTR(-ENAMETOOLONG); | |
1835 | + retval = ERR_PTR(-ENAMETOOLONG); | |
1836 | + goto out; | |
1835 | 1837 | } |
1836 | 1838 | |
1837 | 1839 | /** |