diff options
Diffstat (limited to 'fs/dcache.c')
-rw-r--r-- | fs/dcache.c | 136 |
1 files changed, 98 insertions, 38 deletions
diff --git a/fs/dcache.c b/fs/dcache.c index d1bf5d8aeb5a..0e73aa0a0e8b 100644 --- a/fs/dcache.c +++ b/fs/dcache.c | |||
@@ -21,7 +21,6 @@ | |||
21 | #include <linux/fsnotify.h> | 21 | #include <linux/fsnotify.h> |
22 | #include <linux/slab.h> | 22 | #include <linux/slab.h> |
23 | #include <linux/init.h> | 23 | #include <linux/init.h> |
24 | #include <linux/smp_lock.h> | ||
25 | #include <linux/hash.h> | 24 | #include <linux/hash.h> |
26 | #include <linux/cache.h> | 25 | #include <linux/cache.h> |
27 | #include <linux/module.h> | 26 | #include <linux/module.h> |
@@ -121,6 +120,28 @@ static void dentry_iput(struct dentry * dentry) | |||
121 | } | 120 | } |
122 | } | 121 | } |
123 | 122 | ||
123 | /** | ||
124 | * d_kill - kill dentry and return parent | ||
125 | * @dentry: dentry to kill | ||
126 | * | ||
127 | * Called with dcache_lock and d_lock, releases both. The dentry must | ||
128 | * already be unhashed and removed from the LRU. | ||
129 | * | ||
130 | * If this is the root of the dentry tree, return NULL. | ||
131 | */ | ||
132 | static struct dentry *d_kill(struct dentry *dentry) | ||
133 | { | ||
134 | struct dentry *parent; | ||
135 | |||
136 | list_del(&dentry->d_u.d_child); | ||
137 | dentry_stat.nr_dentry--; /* For d_free, below */ | ||
138 | /*drops the locks, at that point nobody can reach this dentry */ | ||
139 | dentry_iput(dentry); | ||
140 | parent = dentry->d_parent; | ||
141 | d_free(dentry); | ||
142 | return dentry == parent ? NULL : parent; | ||
143 | } | ||
144 | |||
124 | /* | 145 | /* |
125 | * This is dput | 146 | * This is dput |
126 | * | 147 | * |
@@ -189,28 +210,17 @@ repeat: | |||
189 | 210 | ||
190 | unhash_it: | 211 | unhash_it: |
191 | __d_drop(dentry); | 212 | __d_drop(dentry); |
192 | 213 | kill_it: | |
193 | kill_it: { | 214 | /* If dentry was on d_lru list |
194 | struct dentry *parent; | 215 | * delete it from there |
195 | 216 | */ | |
196 | /* If dentry was on d_lru list | 217 | if (!list_empty(&dentry->d_lru)) { |
197 | * delete it from there | 218 | list_del(&dentry->d_lru); |
198 | */ | 219 | dentry_stat.nr_unused--; |
199 | if (!list_empty(&dentry->d_lru)) { | ||
200 | list_del(&dentry->d_lru); | ||
201 | dentry_stat.nr_unused--; | ||
202 | } | ||
203 | list_del(&dentry->d_u.d_child); | ||
204 | dentry_stat.nr_dentry--; /* For d_free, below */ | ||
205 | /*drops the locks, at that point nobody can reach this dentry */ | ||
206 | dentry_iput(dentry); | ||
207 | parent = dentry->d_parent; | ||
208 | d_free(dentry); | ||
209 | if (dentry == parent) | ||
210 | return; | ||
211 | dentry = parent; | ||
212 | goto repeat; | ||
213 | } | 220 | } |
221 | dentry = d_kill(dentry); | ||
222 | if (dentry) | ||
223 | goto repeat; | ||
214 | } | 224 | } |
215 | 225 | ||
216 | /** | 226 | /** |
@@ -371,22 +381,40 @@ restart: | |||
371 | * Throw away a dentry - free the inode, dput the parent. This requires that | 381 | * Throw away a dentry - free the inode, dput the parent. This requires that |
372 | * the LRU list has already been removed. | 382 | * the LRU list has already been removed. |
373 | * | 383 | * |
384 | * If prune_parents is true, try to prune ancestors as well. | ||
385 | * | ||
374 | * Called with dcache_lock, drops it and then regains. | 386 | * Called with dcache_lock, drops it and then regains. |
375 | * Called with dentry->d_lock held, drops it. | 387 | * Called with dentry->d_lock held, drops it. |
376 | */ | 388 | */ |
377 | static void prune_one_dentry(struct dentry * dentry) | 389 | static void prune_one_dentry(struct dentry * dentry, int prune_parents) |
378 | { | 390 | { |
379 | struct dentry * parent; | ||
380 | |||
381 | __d_drop(dentry); | 391 | __d_drop(dentry); |
382 | list_del(&dentry->d_u.d_child); | 392 | dentry = d_kill(dentry); |
383 | dentry_stat.nr_dentry--; /* For d_free, below */ | 393 | if (!prune_parents) { |
384 | dentry_iput(dentry); | 394 | dput(dentry); |
385 | parent = dentry->d_parent; | 395 | spin_lock(&dcache_lock); |
386 | d_free(dentry); | 396 | return; |
387 | if (parent != dentry) | 397 | } |
388 | dput(parent); | 398 | |
399 | /* | ||
400 | * Prune ancestors. Locking is simpler than in dput(), | ||
401 | * because dcache_lock needs to be taken anyway. | ||
402 | */ | ||
389 | spin_lock(&dcache_lock); | 403 | spin_lock(&dcache_lock); |
404 | while (dentry) { | ||
405 | if (!atomic_dec_and_lock(&dentry->d_count, &dentry->d_lock)) | ||
406 | return; | ||
407 | |||
408 | if (dentry->d_op && dentry->d_op->d_delete) | ||
409 | dentry->d_op->d_delete(dentry); | ||
410 | if (!list_empty(&dentry->d_lru)) { | ||
411 | list_del(&dentry->d_lru); | ||
412 | dentry_stat.nr_unused--; | ||
413 | } | ||
414 | __d_drop(dentry); | ||
415 | dentry = d_kill(dentry); | ||
416 | spin_lock(&dcache_lock); | ||
417 | } | ||
390 | } | 418 | } |
391 | 419 | ||
392 | /** | 420 | /** |
@@ -394,6 +422,7 @@ static void prune_one_dentry(struct dentry * dentry) | |||
394 | * @count: number of entries to try and free | 422 | * @count: number of entries to try and free |
395 | * @sb: if given, ignore dentries for other superblocks | 423 | * @sb: if given, ignore dentries for other superblocks |
396 | * which are being unmounted. | 424 | * which are being unmounted. |
425 | * @prune_parents: if true, try to prune ancestors as well in one go | ||
397 | * | 426 | * |
398 | * Shrink the dcache. This is done when we need | 427 | * Shrink the dcache. This is done when we need |
399 | * more memory, or simply when we need to unmount | 428 | * more memory, or simply when we need to unmount |
@@ -404,7 +433,7 @@ static void prune_one_dentry(struct dentry * dentry) | |||
404 | * all the dentries are in use. | 433 | * all the dentries are in use. |
405 | */ | 434 | */ |
406 | 435 | ||
407 | static void prune_dcache(int count, struct super_block *sb) | 436 | static void prune_dcache(int count, struct super_block *sb, int prune_parents) |
408 | { | 437 | { |
409 | spin_lock(&dcache_lock); | 438 | spin_lock(&dcache_lock); |
410 | for (; count ; count--) { | 439 | for (; count ; count--) { |
@@ -464,7 +493,7 @@ static void prune_dcache(int count, struct super_block *sb) | |||
464 | * without taking the s_umount lock (I already hold it). | 493 | * without taking the s_umount lock (I already hold it). |
465 | */ | 494 | */ |
466 | if (sb && dentry->d_sb == sb) { | 495 | if (sb && dentry->d_sb == sb) { |
467 | prune_one_dentry(dentry); | 496 | prune_one_dentry(dentry, prune_parents); |
468 | continue; | 497 | continue; |
469 | } | 498 | } |
470 | /* | 499 | /* |
@@ -479,7 +508,7 @@ static void prune_dcache(int count, struct super_block *sb) | |||
479 | s_umount = &dentry->d_sb->s_umount; | 508 | s_umount = &dentry->d_sb->s_umount; |
480 | if (down_read_trylock(s_umount)) { | 509 | if (down_read_trylock(s_umount)) { |
481 | if (dentry->d_sb->s_root != NULL) { | 510 | if (dentry->d_sb->s_root != NULL) { |
482 | prune_one_dentry(dentry); | 511 | prune_one_dentry(dentry, prune_parents); |
483 | up_read(s_umount); | 512 | up_read(s_umount); |
484 | continue; | 513 | continue; |
485 | } | 514 | } |
@@ -550,7 +579,7 @@ repeat: | |||
550 | spin_unlock(&dentry->d_lock); | 579 | spin_unlock(&dentry->d_lock); |
551 | continue; | 580 | continue; |
552 | } | 581 | } |
553 | prune_one_dentry(dentry); | 582 | prune_one_dentry(dentry, 1); |
554 | cond_resched_lock(&dcache_lock); | 583 | cond_resched_lock(&dcache_lock); |
555 | goto repeat; | 584 | goto repeat; |
556 | } | 585 | } |
@@ -829,7 +858,7 @@ void shrink_dcache_parent(struct dentry * parent) | |||
829 | int found; | 858 | int found; |
830 | 859 | ||
831 | while ((found = select_parent(parent)) != 0) | 860 | while ((found = select_parent(parent)) != 0) |
832 | prune_dcache(found, parent->d_sb); | 861 | prune_dcache(found, parent->d_sb, 1); |
833 | } | 862 | } |
834 | 863 | ||
835 | /* | 864 | /* |
@@ -849,7 +878,7 @@ static int shrink_dcache_memory(int nr, gfp_t gfp_mask) | |||
849 | if (nr) { | 878 | if (nr) { |
850 | if (!(gfp_mask & __GFP_FS)) | 879 | if (!(gfp_mask & __GFP_FS)) |
851 | return -1; | 880 | return -1; |
852 | prune_dcache(nr, NULL); | 881 | prune_dcache(nr, NULL, 1); |
853 | } | 882 | } |
854 | return (dentry_stat.nr_unused / 100) * sysctl_vfs_cache_pressure; | 883 | return (dentry_stat.nr_unused / 100) * sysctl_vfs_cache_pressure; |
855 | } | 884 | } |
@@ -1823,6 +1852,16 @@ char * d_path(struct dentry *dentry, struct vfsmount *vfsmnt, | |||
1823 | struct vfsmount *rootmnt; | 1852 | struct vfsmount *rootmnt; |
1824 | struct dentry *root; | 1853 | struct dentry *root; |
1825 | 1854 | ||
1855 | /* | ||
1856 | * We have various synthetic filesystems that never get mounted. On | ||
1857 | * these filesystems dentries are never used for lookup purposes, and | ||
1858 | * thus don't need to be hashed. They also don't need a name until a | ||
1859 | * user wants to identify the object in /proc/pid/fd/. The little hack | ||
1860 | * below allows us to generate a name for these objects on demand: | ||
1861 | */ | ||
1862 | if (dentry->d_op && dentry->d_op->d_dname) | ||
1863 | return dentry->d_op->d_dname(dentry, buf, buflen); | ||
1864 | |||
1826 | read_lock(¤t->fs->lock); | 1865 | read_lock(¤t->fs->lock); |
1827 | rootmnt = mntget(current->fs->rootmnt); | 1866 | rootmnt = mntget(current->fs->rootmnt); |
1828 | root = dget(current->fs->root); | 1867 | root = dget(current->fs->root); |
@@ -1836,6 +1875,27 @@ char * d_path(struct dentry *dentry, struct vfsmount *vfsmnt, | |||
1836 | } | 1875 | } |
1837 | 1876 | ||
1838 | /* | 1877 | /* |
1878 | * Helper function for dentry_operations.d_dname() members | ||
1879 | */ | ||
1880 | char *dynamic_dname(struct dentry *dentry, char *buffer, int buflen, | ||
1881 | const char *fmt, ...) | ||
1882 | { | ||
1883 | va_list args; | ||
1884 | char temp[64]; | ||
1885 | int sz; | ||
1886 | |||
1887 | va_start(args, fmt); | ||
1888 | sz = vsnprintf(temp, sizeof(temp), fmt, args) + 1; | ||
1889 | va_end(args); | ||
1890 | |||
1891 | if (sz > sizeof(temp) || sz > buflen) | ||
1892 | return ERR_PTR(-ENAMETOOLONG); | ||
1893 | |||
1894 | buffer += buflen - sz; | ||
1895 | return memcpy(buffer, temp, sz); | ||
1896 | } | ||
1897 | |||
1898 | /* | ||
1839 | * NOTE! The user-level library version returns a | 1899 | * NOTE! The user-level library version returns a |
1840 | * character pointer. The kernel system call just | 1900 | * character pointer. The kernel system call just |
1841 | * returns the length of the buffer filled (which | 1901 | * returns the length of the buffer filled (which |