diff options
| author | Al Viro <viro@zeniv.linux.org.uk> | 2016-07-24 16:36:04 -0400 |
|---|---|---|
| committer | Al Viro <viro@zeniv.linux.org.uk> | 2016-07-24 16:36:04 -0400 |
| commit | 17648b871d3cecf310f55ce8c6ce5821d135f6ec (patch) | |
| tree | e4c43b59acdd43d9d68ec553016e08042899a0d7 | |
| parent | f4fdace94722cd4ca60bf72816de01ab911c45d8 (diff) | |
| parent | 550dce01dd606c88a837138aa448ccd367fb0cbb (diff) | |
Merge branch 'test.d_iput' into work.misc
| -rw-r--r-- | fs/dcache.c | 45 |
1 files changed, 10 insertions, 35 deletions
diff --git a/fs/dcache.c b/fs/dcache.c index 484a52db99ba..d5beef01cdfc 100644 --- a/fs/dcache.c +++ b/fs/dcache.c | |||
| @@ -334,44 +334,21 @@ static inline void dentry_rcuwalk_invalidate(struct dentry *dentry) | |||
| 334 | 334 | ||
| 335 | /* | 335 | /* |
| 336 | * Release the dentry's inode, using the filesystem | 336 | * Release the dentry's inode, using the filesystem |
| 337 | * d_iput() operation if defined. Dentry has no refcount | 337 | * d_iput() operation if defined. |
| 338 | * and is unhashed. | ||
| 339 | */ | ||
| 340 | static void dentry_iput(struct dentry * dentry) | ||
| 341 | __releases(dentry->d_lock) | ||
| 342 | __releases(dentry->d_inode->i_lock) | ||
| 343 | { | ||
| 344 | struct inode *inode = dentry->d_inode; | ||
| 345 | if (inode) { | ||
| 346 | __d_clear_type_and_inode(dentry); | ||
| 347 | hlist_del_init(&dentry->d_u.d_alias); | ||
| 348 | spin_unlock(&dentry->d_lock); | ||
| 349 | spin_unlock(&inode->i_lock); | ||
| 350 | if (!inode->i_nlink) | ||
| 351 | fsnotify_inoderemove(inode); | ||
| 352 | if (dentry->d_op && dentry->d_op->d_iput) | ||
| 353 | dentry->d_op->d_iput(dentry, inode); | ||
| 354 | else | ||
| 355 | iput(inode); | ||
| 356 | } else { | ||
| 357 | spin_unlock(&dentry->d_lock); | ||
| 358 | } | ||
| 359 | } | ||
| 360 | |||
| 361 | /* | ||
| 362 | * Release the dentry's inode, using the filesystem | ||
| 363 | * d_iput() operation if defined. dentry remains in-use. | ||
| 364 | */ | 338 | */ |
| 365 | static void dentry_unlink_inode(struct dentry * dentry) | 339 | static void dentry_unlink_inode(struct dentry * dentry) |
| 366 | __releases(dentry->d_lock) | 340 | __releases(dentry->d_lock) |
| 367 | __releases(dentry->d_inode->i_lock) | 341 | __releases(dentry->d_inode->i_lock) |
| 368 | { | 342 | { |
| 369 | struct inode *inode = dentry->d_inode; | 343 | struct inode *inode = dentry->d_inode; |
| 344 | bool hashed = !d_unhashed(dentry); | ||
| 370 | 345 | ||
| 371 | raw_write_seqcount_begin(&dentry->d_seq); | 346 | if (hashed) |
| 347 | raw_write_seqcount_begin(&dentry->d_seq); | ||
| 372 | __d_clear_type_and_inode(dentry); | 348 | __d_clear_type_and_inode(dentry); |
| 373 | hlist_del_init(&dentry->d_u.d_alias); | 349 | hlist_del_init(&dentry->d_u.d_alias); |
| 374 | raw_write_seqcount_end(&dentry->d_seq); | 350 | if (hashed) |
| 351 | raw_write_seqcount_end(&dentry->d_seq); | ||
| 375 | spin_unlock(&dentry->d_lock); | 352 | spin_unlock(&dentry->d_lock); |
| 376 | spin_unlock(&inode->i_lock); | 353 | spin_unlock(&inode->i_lock); |
| 377 | if (!inode->i_nlink) | 354 | if (!inode->i_nlink) |
| @@ -572,12 +549,10 @@ static void __dentry_kill(struct dentry *dentry) | |||
| 572 | dentry_unlist(dentry, parent); | 549 | dentry_unlist(dentry, parent); |
| 573 | if (parent) | 550 | if (parent) |
| 574 | spin_unlock(&parent->d_lock); | 551 | spin_unlock(&parent->d_lock); |
| 575 | dentry_iput(dentry); | 552 | if (dentry->d_inode) |
| 576 | /* | 553 | dentry_unlink_inode(dentry); |
| 577 | * dentry_iput drops the locks, at which point nobody (except | 554 | else |
| 578 | * transient RCU lookups) can reach this dentry. | 555 | spin_unlock(&dentry->d_lock); |
| 579 | */ | ||
| 580 | BUG_ON(dentry->d_lockref.count > 0); | ||
| 581 | this_cpu_dec(nr_dentry); | 556 | this_cpu_dec(nr_dentry); |
| 582 | if (dentry->d_op && dentry->d_op->d_release) | 557 | if (dentry->d_op && dentry->d_op->d_release) |
| 583 | dentry->d_op->d_release(dentry); | 558 | dentry->d_op->d_release(dentry); |
