aboutsummaryrefslogtreecommitdiffstats
path: root/fs/dcache.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/dcache.c')
-rw-r--r--fs/dcache.c39
1 files changed, 29 insertions, 10 deletions
diff --git a/fs/dcache.c b/fs/dcache.c
index 86d4db15473e..9f2c13417969 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}
@@ -2049,16 +2051,12 @@ char *dynamic_dname(struct dentry *dentry, char *buffer, int buflen,
2049/* 2051/*
2050 * Write full pathname from the root of the filesystem into the buffer. 2052 * Write full pathname from the root of the filesystem into the buffer.
2051 */ 2053 */
2052char *dentry_path(struct dentry *dentry, char *buf, int buflen) 2054char *__dentry_path(struct dentry *dentry, char *buf, int buflen)
2053{ 2055{
2054 char *end = buf + buflen; 2056 char *end = buf + buflen;
2055 char *retval; 2057 char *retval;
2056 2058
2057 spin_lock(&dcache_lock);
2058 prepend(&end, &buflen, "\0", 1); 2059 prepend(&end, &buflen, "\0", 1);
2059 if (d_unlinked(dentry) &&
2060 (prepend(&end, &buflen, "//deleted", 9) != 0))
2061 goto Elong;
2062 if (buflen < 1) 2060 if (buflen < 1)
2063 goto Elong; 2061 goto Elong;
2064 /* Get '/' right */ 2062 /* Get '/' right */
@@ -2076,7 +2074,28 @@ char *dentry_path(struct dentry *dentry, char *buf, int buflen)
2076 retval = end; 2074 retval = end;
2077 dentry = parent; 2075 dentry = parent;
2078 } 2076 }
2077 return retval;
2078Elong:
2079 return ERR_PTR(-ENAMETOOLONG);
2080}
2081EXPORT_SYMBOL(__dentry_path);
2082
2083char *dentry_path(struct dentry *dentry, char *buf, int buflen)
2084{
2085 char *p = NULL;
2086 char *retval;
2087
2088 spin_lock(&dcache_lock);
2089 if (d_unlinked(dentry)) {
2090 p = buf + buflen;
2091 if (prepend(&p, &buflen, "//deleted", 10) != 0)
2092 goto Elong;
2093 buflen++;
2094 }
2095 retval = __dentry_path(dentry, buf, buflen);
2079 spin_unlock(&dcache_lock); 2096 spin_unlock(&dcache_lock);
2097 if (!IS_ERR(retval) && p)
2098 *p = '/'; /* restore '/' overriden with '\0' */
2080 return retval; 2099 return retval;
2081Elong: 2100Elong:
2082 spin_unlock(&dcache_lock); 2101 spin_unlock(&dcache_lock);