diff options
author | Eric W. Biederman <ebiederm@xmission.com> | 2014-02-13 12:39:37 -0500 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2014-10-09 02:38:57 -0400 |
commit | 1ffe46d11cc88479797b262f60d92e5fb461b411 (patch) | |
tree | a2a710d4440ab248d0f57a064207068aad6342bc | |
parent | 9b053f3207e8887fed88162a339fdd4001abcdb2 (diff) |
vfs: Merge check_submounts_and_drop and d_invalidate
Now that d_invalidate is the only caller of check_submounts_and_drop,
expand check_submounts_and_drop inline in d_invalidate.
Reviewed-by: Miklos Szeredi <miklos@szeredi.hu>
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
-rw-r--r-- | fs/dcache.c | 55 | ||||
-rw-r--r-- | include/linux/dcache.h | 1 |
2 files changed, 22 insertions, 34 deletions
diff --git a/fs/dcache.c b/fs/dcache.c index 484114a4db93..5e02b9eee6b1 100644 --- a/fs/dcache.c +++ b/fs/dcache.c | |||
@@ -645,32 +645,6 @@ kill_it: | |||
645 | } | 645 | } |
646 | EXPORT_SYMBOL(dput); | 646 | EXPORT_SYMBOL(dput); |
647 | 647 | ||
648 | /** | ||
649 | * d_invalidate - invalidate a dentry | ||
650 | * @dentry: dentry to invalidate | ||
651 | * | ||
652 | * Try to invalidate the dentry if it turns out to be | ||
653 | * possible. If there are reasons not to delete it | ||
654 | * return -EBUSY. On success return 0. | ||
655 | * | ||
656 | * no dcache lock. | ||
657 | */ | ||
658 | |||
659 | int d_invalidate(struct dentry * dentry) | ||
660 | { | ||
661 | /* | ||
662 | * If it's already been dropped, return OK. | ||
663 | */ | ||
664 | spin_lock(&dentry->d_lock); | ||
665 | if (d_unhashed(dentry)) { | ||
666 | spin_unlock(&dentry->d_lock); | ||
667 | return 0; | ||
668 | } | ||
669 | spin_unlock(&dentry->d_lock); | ||
670 | |||
671 | return check_submounts_and_drop(dentry); | ||
672 | } | ||
673 | EXPORT_SYMBOL(d_invalidate); | ||
674 | 648 | ||
675 | /* This must be called with d_lock held */ | 649 | /* This must be called with d_lock held */ |
676 | static inline void __dget_dlock(struct dentry *dentry) | 650 | static inline void __dget_dlock(struct dentry *dentry) |
@@ -1190,7 +1164,7 @@ EXPORT_SYMBOL(have_submounts); | |||
1190 | * reachable (e.g. NFS can unhash a directory dentry and then the complete | 1164 | * reachable (e.g. NFS can unhash a directory dentry and then the complete |
1191 | * subtree can become unreachable). | 1165 | * subtree can become unreachable). |
1192 | * | 1166 | * |
1193 | * Only one of check_submounts_and_drop() and d_set_mounted() must succeed. For | 1167 | * Only one of d_invalidate() and d_set_mounted() must succeed. For |
1194 | * this reason take rename_lock and d_lock on dentry and ancestors. | 1168 | * this reason take rename_lock and d_lock on dentry and ancestors. |
1195 | */ | 1169 | */ |
1196 | int d_set_mounted(struct dentry *dentry) | 1170 | int d_set_mounted(struct dentry *dentry) |
@@ -1199,7 +1173,7 @@ int d_set_mounted(struct dentry *dentry) | |||
1199 | int ret = -ENOENT; | 1173 | int ret = -ENOENT; |
1200 | write_seqlock(&rename_lock); | 1174 | write_seqlock(&rename_lock); |
1201 | for (p = dentry->d_parent; !IS_ROOT(p); p = p->d_parent) { | 1175 | for (p = dentry->d_parent; !IS_ROOT(p); p = p->d_parent) { |
1202 | /* Need exclusion wrt. check_submounts_and_drop() */ | 1176 | /* Need exclusion wrt. d_invalidate() */ |
1203 | spin_lock(&p->d_lock); | 1177 | spin_lock(&p->d_lock); |
1204 | if (unlikely(d_unhashed(p))) { | 1178 | if (unlikely(d_unhashed(p))) { |
1205 | spin_unlock(&p->d_lock); | 1179 | spin_unlock(&p->d_lock); |
@@ -1369,18 +1343,33 @@ static void check_and_drop(void *_data) | |||
1369 | } | 1343 | } |
1370 | 1344 | ||
1371 | /** | 1345 | /** |
1372 | * check_submounts_and_drop - detach submounts, prune dcache, and drop | 1346 | * d_invalidate - detach submounts, prune dcache, and drop |
1347 | * @dentry: dentry to invalidate (aka detach, prune and drop) | ||
1348 | * | ||
1349 | * Try to invalidate the dentry if it turns out to be | ||
1350 | * possible. If there are reasons not to delete it | ||
1351 | * return -EBUSY. On success return 0. | ||
1352 | * | ||
1353 | * no dcache lock. | ||
1373 | * | 1354 | * |
1374 | * The final d_drop is done as an atomic operation relative to | 1355 | * The final d_drop is done as an atomic operation relative to |
1375 | * rename_lock ensuring there are no races with d_set_mounted. This | 1356 | * rename_lock ensuring there are no races with d_set_mounted. This |
1376 | * ensures there are no unhashed dentries on the path to a mountpoint. | 1357 | * ensures there are no unhashed dentries on the path to a mountpoint. |
1377 | * | ||
1378 | * @dentry: dentry to detach, prune and drop | ||
1379 | */ | 1358 | */ |
1380 | int check_submounts_and_drop(struct dentry *dentry) | 1359 | int d_invalidate(struct dentry *dentry) |
1381 | { | 1360 | { |
1382 | int ret = 0; | 1361 | int ret = 0; |
1383 | 1362 | ||
1363 | /* | ||
1364 | * If it's already been dropped, return OK. | ||
1365 | */ | ||
1366 | spin_lock(&dentry->d_lock); | ||
1367 | if (d_unhashed(dentry)) { | ||
1368 | spin_unlock(&dentry->d_lock); | ||
1369 | return 0; | ||
1370 | } | ||
1371 | spin_unlock(&dentry->d_lock); | ||
1372 | |||
1384 | /* Negative dentries can be dropped without further checks */ | 1373 | /* Negative dentries can be dropped without further checks */ |
1385 | if (!dentry->d_inode) { | 1374 | if (!dentry->d_inode) { |
1386 | d_drop(dentry); | 1375 | d_drop(dentry); |
@@ -1414,7 +1403,7 @@ int check_submounts_and_drop(struct dentry *dentry) | |||
1414 | out: | 1403 | out: |
1415 | return ret; | 1404 | return ret; |
1416 | } | 1405 | } |
1417 | EXPORT_SYMBOL(check_submounts_and_drop); | 1406 | EXPORT_SYMBOL(d_invalidate); |
1418 | 1407 | ||
1419 | /** | 1408 | /** |
1420 | * __d_alloc - allocate a dcache entry | 1409 | * __d_alloc - allocate a dcache entry |
diff --git a/include/linux/dcache.h b/include/linux/dcache.h index 75a227cc7ce2..595af29ad145 100644 --- a/include/linux/dcache.h +++ b/include/linux/dcache.h | |||
@@ -269,7 +269,6 @@ extern void d_prune_aliases(struct inode *); | |||
269 | 269 | ||
270 | /* test whether we have any submounts in a subdir tree */ | 270 | /* test whether we have any submounts in a subdir tree */ |
271 | extern int have_submounts(struct dentry *); | 271 | extern int have_submounts(struct dentry *); |
272 | extern int check_submounts_and_drop(struct dentry *); | ||
273 | 272 | ||
274 | /* | 273 | /* |
275 | * This adds the entry to the hash queues. | 274 | * This adds the entry to the hash queues. |