diff options
Diffstat (limited to 'fs/dcache.c')
-rw-r--r-- | fs/dcache.c | 24 |
1 files changed, 16 insertions, 8 deletions
diff --git a/fs/dcache.c b/fs/dcache.c index 635c2aa427ed..3ee588d5f585 100644 --- a/fs/dcache.c +++ b/fs/dcache.c | |||
@@ -1759,10 +1759,8 @@ static int prepend(char **buffer, int *buflen, const char *str, | |||
1759 | 1759 | ||
1760 | /** | 1760 | /** |
1761 | * d_path - return the path of a dentry | 1761 | * d_path - return the path of a dentry |
1762 | * @dentry: dentry to report | 1762 | * @path: the dentry/vfsmount to report |
1763 | * @vfsmnt: vfsmnt to which the dentry belongs | 1763 | * @root: root vfsmnt/dentry (may be modified by this function) |
1764 | * @root: root dentry | ||
1765 | * @rootmnt: vfsmnt to which the root dentry belongs | ||
1766 | * @buffer: buffer to return value in | 1764 | * @buffer: buffer to return value in |
1767 | * @buflen: buffer length | 1765 | * @buflen: buffer length |
1768 | * | 1766 | * |
@@ -1772,10 +1770,15 @@ static int prepend(char **buffer, int *buflen, const char *str, | |||
1772 | * Returns the buffer or an error code if the path was too long. | 1770 | * Returns the buffer or an error code if the path was too long. |
1773 | * | 1771 | * |
1774 | * "buflen" should be positive. Caller holds the dcache_lock. | 1772 | * "buflen" should be positive. Caller holds the dcache_lock. |
1773 | * | ||
1774 | * If path is not reachable from the supplied root, then the value of | ||
1775 | * root is changed (without modifying refcounts). | ||
1775 | */ | 1776 | */ |
1776 | static char *__d_path(struct dentry *dentry, struct vfsmount *vfsmnt, | 1777 | char *__d_path(const struct path *path, struct path *root, |
1777 | struct path *root, char *buffer, int buflen) | 1778 | char *buffer, int buflen) |
1778 | { | 1779 | { |
1780 | struct dentry *dentry = path->dentry; | ||
1781 | struct vfsmount *vfsmnt = path->mnt; | ||
1779 | char * end = buffer+buflen; | 1782 | char * end = buffer+buflen; |
1780 | char * retval; | 1783 | char * retval; |
1781 | 1784 | ||
@@ -1824,6 +1827,8 @@ global_root: | |||
1824 | if (prepend(&retval, &buflen, dentry->d_name.name, | 1827 | if (prepend(&retval, &buflen, dentry->d_name.name, |
1825 | dentry->d_name.len) != 0) | 1828 | dentry->d_name.len) != 0) |
1826 | goto Elong; | 1829 | goto Elong; |
1830 | root->mnt = vfsmnt; | ||
1831 | root->dentry = dentry; | ||
1827 | return retval; | 1832 | return retval; |
1828 | Elong: | 1833 | Elong: |
1829 | return ERR_PTR(-ENAMETOOLONG); | 1834 | return ERR_PTR(-ENAMETOOLONG); |
@@ -1846,6 +1851,7 @@ char *d_path(struct path *path, char *buf, int buflen) | |||
1846 | { | 1851 | { |
1847 | char *res; | 1852 | char *res; |
1848 | struct path root; | 1853 | struct path root; |
1854 | struct path tmp; | ||
1849 | 1855 | ||
1850 | /* | 1856 | /* |
1851 | * We have various synthetic filesystems that never get mounted. On | 1857 | * We have various synthetic filesystems that never get mounted. On |
@@ -1862,7 +1868,8 @@ char *d_path(struct path *path, char *buf, int buflen) | |||
1862 | path_get(&root); | 1868 | path_get(&root); |
1863 | read_unlock(¤t->fs->lock); | 1869 | read_unlock(¤t->fs->lock); |
1864 | spin_lock(&dcache_lock); | 1870 | spin_lock(&dcache_lock); |
1865 | res = __d_path(path->dentry, path->mnt, &root, buf, buflen); | 1871 | tmp = root; |
1872 | res = __d_path(path, &tmp, buf, buflen); | ||
1866 | spin_unlock(&dcache_lock); | 1873 | spin_unlock(&dcache_lock); |
1867 | path_put(&root); | 1874 | path_put(&root); |
1868 | return res; | 1875 | return res; |
@@ -1970,9 +1977,10 @@ asmlinkage long sys_getcwd(char __user *buf, unsigned long size) | |||
1970 | spin_lock(&dcache_lock); | 1977 | spin_lock(&dcache_lock); |
1971 | if (pwd.dentry->d_parent == pwd.dentry || !d_unhashed(pwd.dentry)) { | 1978 | if (pwd.dentry->d_parent == pwd.dentry || !d_unhashed(pwd.dentry)) { |
1972 | unsigned long len; | 1979 | unsigned long len; |
1980 | struct path tmp = root; | ||
1973 | char * cwd; | 1981 | char * cwd; |
1974 | 1982 | ||
1975 | cwd = __d_path(pwd.dentry, pwd.mnt, &root, page, PAGE_SIZE); | 1983 | cwd = __d_path(&pwd, &tmp, page, PAGE_SIZE); |
1976 | spin_unlock(&dcache_lock); | 1984 | spin_unlock(&dcache_lock); |
1977 | 1985 | ||
1978 | error = PTR_ERR(cwd); | 1986 | error = PTR_ERR(cwd); |