aboutsummaryrefslogtreecommitdiffstats
path: root/fs/dcache.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/dcache.c')
-rw-r--r--fs/dcache.c227
1 files changed, 162 insertions, 65 deletions
diff --git a/fs/dcache.c b/fs/dcache.c
index 86d4db15473e..166d35d56868 100644
--- a/fs/dcache.c
+++ b/fs/dcache.c
@@ -536,7 +536,7 @@ restart:
536 */ 536 */
537static void prune_dcache(int count) 537static void prune_dcache(int count)
538{ 538{
539 struct super_block *sb, *n; 539 struct super_block *sb, *p = NULL;
540 int w_count; 540 int w_count;
541 int unused = dentry_stat.nr_unused; 541 int unused = dentry_stat.nr_unused;
542 int prune_ratio; 542 int prune_ratio;
@@ -550,7 +550,7 @@ static void prune_dcache(int count)
550 else 550 else
551 prune_ratio = unused / count; 551 prune_ratio = unused / count;
552 spin_lock(&sb_lock); 552 spin_lock(&sb_lock);
553 list_for_each_entry_safe(sb, n, &super_blocks, s_list) { 553 list_for_each_entry(sb, &super_blocks, s_list) {
554 if (list_empty(&sb->s_instances)) 554 if (list_empty(&sb->s_instances))
555 continue; 555 continue;
556 if (sb->s_nr_dentry_unused == 0) 556 if (sb->s_nr_dentry_unused == 0)
@@ -590,14 +590,16 @@ static void prune_dcache(int count)
590 up_read(&sb->s_umount); 590 up_read(&sb->s_umount);
591 } 591 }
592 spin_lock(&sb_lock); 592 spin_lock(&sb_lock);
593 /* lock was dropped, must reset next */ 593 if (p)
594 list_safe_reset_next(sb, n, s_list); 594 __put_super(p);
595 count -= pruned; 595 count -= pruned;
596 __put_super(sb); 596 p = sb;
597 /* more work left to do? */ 597 /* more work left to do? */
598 if (count <= 0) 598 if (count <= 0)
599 break; 599 break;
600 } 600 }
601 if (p)
602 __put_super(p);
601 spin_unlock(&sb_lock); 603 spin_unlock(&sb_lock);
602 spin_unlock(&dcache_lock); 604 spin_unlock(&dcache_lock);
603} 605}
@@ -1903,48 +1905,30 @@ static int prepend_name(char **buffer, int *buflen, struct qstr *name)
1903} 1905}
1904 1906
1905/** 1907/**
1906 * __d_path - return the path of a dentry 1908 * Prepend path string to a buffer
1909 *
1907 * @path: the dentry/vfsmount to report 1910 * @path: the dentry/vfsmount to report
1908 * @root: root vfsmnt/dentry (may be modified by this function) 1911 * @root: root vfsmnt/dentry (may be modified by this function)
1909 * @buffer: buffer to return value in 1912 * @buffer: pointer to the end of the buffer
1910 * @buflen: buffer length 1913 * @buflen: pointer to buffer length
1911 *
1912 * Convert a dentry into an ASCII path name. If the entry has been deleted
1913 * the string " (deleted)" is appended. Note that this is ambiguous.
1914 * 1914 *
1915 * Returns a pointer into the buffer or an error code if the 1915 * Caller holds the dcache_lock.
1916 * path was too long.
1917 *
1918 * "buflen" should be positive. Caller holds the dcache_lock.
1919 * 1916 *
1920 * If path is not reachable from the supplied root, then the value of 1917 * If path is not reachable from the supplied root, then the value of
1921 * root is changed (without modifying refcounts). 1918 * root is changed (without modifying refcounts).
1922 */ 1919 */
1923char *__d_path(const struct path *path, struct path *root, 1920static int prepend_path(const struct path *path, struct path *root,
1924 char *buffer, int buflen) 1921 char **buffer, int *buflen)
1925{ 1922{
1926 struct dentry *dentry = path->dentry; 1923 struct dentry *dentry = path->dentry;
1927 struct vfsmount *vfsmnt = path->mnt; 1924 struct vfsmount *vfsmnt = path->mnt;
1928 char *end = buffer + buflen; 1925 bool slash = false;
1929 char *retval; 1926 int error = 0;
1930 1927
1931 spin_lock(&vfsmount_lock); 1928 spin_lock(&vfsmount_lock);
1932 prepend(&end, &buflen, "\0", 1); 1929 while (dentry != root->dentry || vfsmnt != root->mnt) {
1933 if (d_unlinked(dentry) &&
1934 (prepend(&end, &buflen, " (deleted)", 10) != 0))
1935 goto Elong;
1936
1937 if (buflen < 1)
1938 goto Elong;
1939 /* Get '/' right */
1940 retval = end-1;
1941 *retval = '/';
1942
1943 for (;;) {
1944 struct dentry * parent; 1930 struct dentry * parent;
1945 1931
1946 if (dentry == root->dentry && vfsmnt == root->mnt)
1947 break;
1948 if (dentry == vfsmnt->mnt_root || IS_ROOT(dentry)) { 1932 if (dentry == vfsmnt->mnt_root || IS_ROOT(dentry)) {
1949 /* Global root? */ 1933 /* Global root? */
1950 if (vfsmnt->mnt_parent == vfsmnt) { 1934 if (vfsmnt->mnt_parent == vfsmnt) {
@@ -1956,28 +1940,88 @@ char *__d_path(const struct path *path, struct path *root,
1956 } 1940 }
1957 parent = dentry->d_parent; 1941 parent = dentry->d_parent;
1958 prefetch(parent); 1942 prefetch(parent);
1959 if ((prepend_name(&end, &buflen, &dentry->d_name) != 0) || 1943 error = prepend_name(buffer, buflen, &dentry->d_name);
1960 (prepend(&end, &buflen, "/", 1) != 0)) 1944 if (!error)
1961 goto Elong; 1945 error = prepend(buffer, buflen, "/", 1);
1962 retval = end; 1946 if (error)
1947 break;
1948
1949 slash = true;
1963 dentry = parent; 1950 dentry = parent;
1964 } 1951 }
1965 1952
1966out: 1953out:
1954 if (!error && !slash)
1955 error = prepend(buffer, buflen, "/", 1);
1956
1967 spin_unlock(&vfsmount_lock); 1957 spin_unlock(&vfsmount_lock);
1968 return retval; 1958 return error;
1969 1959
1970global_root: 1960global_root:
1971 retval += 1; /* hit the slash */ 1961 /*
1972 if (prepend_name(&retval, &buflen, &dentry->d_name) != 0) 1962 * Filesystems needing to implement special "root names"
1973 goto Elong; 1963 * should do so with ->d_dname()
1964 */
1965 if (IS_ROOT(dentry) &&
1966 (dentry->d_name.len != 1 || dentry->d_name.name[0] != '/')) {
1967 WARN(1, "Root dentry has weird name <%.*s>\n",
1968 (int) dentry->d_name.len, dentry->d_name.name);
1969 }
1974 root->mnt = vfsmnt; 1970 root->mnt = vfsmnt;
1975 root->dentry = dentry; 1971 root->dentry = dentry;
1976 goto out; 1972 goto out;
1973}
1977 1974
1978Elong: 1975/**
1979 retval = ERR_PTR(-ENAMETOOLONG); 1976 * __d_path - return the path of a dentry
1980 goto out; 1977 * @path: the dentry/vfsmount to report
1978 * @root: root vfsmnt/dentry (may be modified by this function)
1979 * @buffer: buffer to return value in
1980 * @buflen: buffer length
1981 *
1982 * Convert a dentry into an ASCII path name.
1983 *
1984 * Returns a pointer into the buffer or an error code if the
1985 * path was too long.
1986 *
1987 * "buflen" should be positive. Caller holds the dcache_lock.
1988 *
1989 * If path is not reachable from the supplied root, then the value of
1990 * root is changed (without modifying refcounts).
1991 */
1992char *__d_path(const struct path *path, struct path *root,
1993 char *buf, int buflen)
1994{
1995 char *res = buf + buflen;
1996 int error;
1997
1998 prepend(&res, &buflen, "\0", 1);
1999 error = prepend_path(path, root, &res, &buflen);
2000 if (error)
2001 return ERR_PTR(error);
2002
2003 return res;
2004}
2005
2006/*
2007 * same as __d_path but appends "(deleted)" for unlinked files.
2008 */
2009static int path_with_deleted(const struct path *path, struct path *root,
2010 char **buf, int *buflen)
2011{
2012 prepend(buf, buflen, "\0", 1);
2013 if (d_unlinked(path->dentry)) {
2014 int error = prepend(buf, buflen, " (deleted)", 10);
2015 if (error)
2016 return error;
2017 }
2018
2019 return prepend_path(path, root, buf, buflen);
2020}
2021
2022static int prepend_unreachable(char **buffer, int *buflen)
2023{
2024 return prepend(buffer, buflen, "(unreachable)", 13);
1981} 2025}
1982 2026
1983/** 2027/**
@@ -1998,9 +2042,10 @@ Elong:
1998 */ 2042 */
1999char *d_path(const struct path *path, char *buf, int buflen) 2043char *d_path(const struct path *path, char *buf, int buflen)
2000{ 2044{
2001 char *res; 2045 char *res = buf + buflen;
2002 struct path root; 2046 struct path root;
2003 struct path tmp; 2047 struct path tmp;
2048 int error;
2004 2049
2005 /* 2050 /*
2006 * We have various synthetic filesystems that never get mounted. On 2051 * We have various synthetic filesystems that never get mounted. On
@@ -2012,19 +2057,51 @@ char *d_path(const struct path *path, char *buf, int buflen)
2012 if (path->dentry->d_op && path->dentry->d_op->d_dname) 2057 if (path->dentry->d_op && path->dentry->d_op->d_dname)
2013 return path->dentry->d_op->d_dname(path->dentry, buf, buflen); 2058 return path->dentry->d_op->d_dname(path->dentry, buf, buflen);
2014 2059
2015 read_lock(&current->fs->lock); 2060 get_fs_root(current->fs, &root);
2016 root = current->fs->root;
2017 path_get(&root);
2018 read_unlock(&current->fs->lock);
2019 spin_lock(&dcache_lock); 2061 spin_lock(&dcache_lock);
2020 tmp = root; 2062 tmp = root;
2021 res = __d_path(path, &tmp, buf, buflen); 2063 error = path_with_deleted(path, &tmp, &res, &buflen);
2064 if (error)
2065 res = ERR_PTR(error);
2022 spin_unlock(&dcache_lock); 2066 spin_unlock(&dcache_lock);
2023 path_put(&root); 2067 path_put(&root);
2024 return res; 2068 return res;
2025} 2069}
2026EXPORT_SYMBOL(d_path); 2070EXPORT_SYMBOL(d_path);
2027 2071
2072/**
2073 * d_path_with_unreachable - return the path of a dentry
2074 * @path: path to report
2075 * @buf: buffer to return value in
2076 * @buflen: buffer length
2077 *
2078 * The difference from d_path() is that this prepends "(unreachable)"
2079 * to paths which are unreachable from the current process' root.
2080 */
2081char *d_path_with_unreachable(const struct path *path, char *buf, int buflen)
2082{
2083 char *res = buf + buflen;
2084 struct path root;
2085 struct path tmp;
2086 int error;
2087
2088 if (path->dentry->d_op && path->dentry->d_op->d_dname)
2089 return path->dentry->d_op->d_dname(path->dentry, buf, buflen);
2090
2091 get_fs_root(current->fs, &root);
2092 spin_lock(&dcache_lock);
2093 tmp = root;
2094 error = path_with_deleted(path, &tmp, &res, &buflen);
2095 if (!error && !path_equal(&tmp, &root))
2096 error = prepend_unreachable(&res, &buflen);
2097 spin_unlock(&dcache_lock);
2098 path_put(&root);
2099 if (error)
2100 res = ERR_PTR(error);
2101
2102 return res;
2103}
2104
2028/* 2105/*
2029 * Helper function for dentry_operations.d_dname() members 2106 * Helper function for dentry_operations.d_dname() members
2030 */ 2107 */
@@ -2049,16 +2126,12 @@ char *dynamic_dname(struct dentry *dentry, char *buffer, int buflen,
2049/* 2126/*
2050 * Write full pathname from the root of the filesystem into the buffer. 2127 * Write full pathname from the root of the filesystem into the buffer.
2051 */ 2128 */
2052char *dentry_path(struct dentry *dentry, char *buf, int buflen) 2129char *__dentry_path(struct dentry *dentry, char *buf, int buflen)
2053{ 2130{
2054 char *end = buf + buflen; 2131 char *end = buf + buflen;
2055 char *retval; 2132 char *retval;
2056 2133
2057 spin_lock(&dcache_lock);
2058 prepend(&end, &buflen, "\0", 1); 2134 prepend(&end, &buflen, "\0", 1);
2059 if (d_unlinked(dentry) &&
2060 (prepend(&end, &buflen, "//deleted", 9) != 0))
2061 goto Elong;
2062 if (buflen < 1) 2135 if (buflen < 1)
2063 goto Elong; 2136 goto Elong;
2064 /* Get '/' right */ 2137 /* Get '/' right */
@@ -2076,7 +2149,28 @@ char *dentry_path(struct dentry *dentry, char *buf, int buflen)
2076 retval = end; 2149 retval = end;
2077 dentry = parent; 2150 dentry = parent;
2078 } 2151 }
2152 return retval;
2153Elong:
2154 return ERR_PTR(-ENAMETOOLONG);
2155}
2156EXPORT_SYMBOL(__dentry_path);
2157
2158char *dentry_path(struct dentry *dentry, char *buf, int buflen)
2159{
2160 char *p = NULL;
2161 char *retval;
2162
2163 spin_lock(&dcache_lock);
2164 if (d_unlinked(dentry)) {
2165 p = buf + buflen;
2166 if (prepend(&p, &buflen, "//deleted", 10) != 0)
2167 goto Elong;
2168 buflen++;
2169 }
2170 retval = __dentry_path(dentry, buf, buflen);
2079 spin_unlock(&dcache_lock); 2171 spin_unlock(&dcache_lock);
2172 if (!IS_ERR(retval) && p)
2173 *p = '/'; /* restore '/' overriden with '\0' */
2080 return retval; 2174 return retval;
2081Elong: 2175Elong:
2082 spin_unlock(&dcache_lock); 2176 spin_unlock(&dcache_lock);
@@ -2110,27 +2204,30 @@ SYSCALL_DEFINE2(getcwd, char __user *, buf, unsigned long, size)
2110 if (!page) 2204 if (!page)
2111 return -ENOMEM; 2205 return -ENOMEM;
2112 2206
2113 read_lock(&current->fs->lock); 2207 get_fs_root_and_pwd(current->fs, &root, &pwd);
2114 pwd = current->fs->pwd;
2115 path_get(&pwd);
2116 root = current->fs->root;
2117 path_get(&root);
2118 read_unlock(&current->fs->lock);
2119 2208
2120 error = -ENOENT; 2209 error = -ENOENT;
2121 spin_lock(&dcache_lock); 2210 spin_lock(&dcache_lock);
2122 if (!d_unlinked(pwd.dentry)) { 2211 if (!d_unlinked(pwd.dentry)) {
2123 unsigned long len; 2212 unsigned long len;
2124 struct path tmp = root; 2213 struct path tmp = root;
2125 char * cwd; 2214 char *cwd = page + PAGE_SIZE;
2215 int buflen = PAGE_SIZE;
2126 2216
2127 cwd = __d_path(&pwd, &tmp, page, PAGE_SIZE); 2217 prepend(&cwd, &buflen, "\0", 1);
2218 error = prepend_path(&pwd, &tmp, &cwd, &buflen);
2128 spin_unlock(&dcache_lock); 2219 spin_unlock(&dcache_lock);
2129 2220
2130 error = PTR_ERR(cwd); 2221 if (error)
2131 if (IS_ERR(cwd))
2132 goto out; 2222 goto out;
2133 2223
2224 /* Unreachable from current root */
2225 if (!path_equal(&tmp, &root)) {
2226 error = prepend_unreachable(&cwd, &buflen);
2227 if (error)
2228 goto out;
2229 }
2230
2134 error = -ERANGE; 2231 error = -ERANGE;
2135 len = PAGE_SIZE + page - cwd; 2232 len = PAGE_SIZE + page - cwd;
2136 if (len <= size) { 2233 if (len <= size) {