diff options
Diffstat (limited to 'fs/dcache.c')
-rw-r--r-- | fs/dcache.c | 39 |
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 | */ |
537 | static void prune_dcache(int count) | 537 | static 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 | */ |
2052 | char *dentry_path(struct dentry *dentry, char *buf, int buflen) | 2054 | char *__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; | ||
2078 | Elong: | ||
2079 | return ERR_PTR(-ENAMETOOLONG); | ||
2080 | } | ||
2081 | EXPORT_SYMBOL(__dentry_path); | ||
2082 | |||
2083 | char *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; |
2081 | Elong: | 2100 | Elong: |
2082 | spin_unlock(&dcache_lock); | 2101 | spin_unlock(&dcache_lock); |