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); |