Skip to content

Commit 63997e9

Browse files
author
Al Viro
committed
split invalidate_inodes()
Pull removal of fsnotify marks into generic_shutdown_super(). Split umount-time work into a new function - evict_inodes(). Make sure that invalidate_inodes() will be able to cope with I_FREEING once we change locking in iput(). Signed-off-by: Al Viro <[email protected]>
1 parent 9843b76 commit 63997e9

File tree

4 files changed

+51
-6
lines changed

4 files changed

+51
-6
lines changed

fs/inode.c

Lines changed: 44 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -477,6 +477,49 @@ static void dispose_list(struct list_head *head)
477477
}
478478
}
479479

480+
/**
481+
* evict_inodes - evict all evictable inodes for a superblock
482+
* @sb: superblock to operate on
483+
*
484+
* Make sure that no inodes with zero refcount are retained. This is
485+
* called by superblock shutdown after having MS_ACTIVE flag removed,
486+
* so any inode reaching zero refcount during or after that call will
487+
* be immediately evicted.
488+
*/
489+
void evict_inodes(struct super_block *sb)
490+
{
491+
struct inode *inode, *next;
492+
LIST_HEAD(dispose);
493+
494+
down_write(&iprune_sem);
495+
496+
spin_lock(&inode_lock);
497+
list_for_each_entry_safe(inode, next, &sb->s_inodes, i_sb_list) {
498+
if (atomic_read(&inode->i_count))
499+
continue;
500+
501+
if (inode->i_state & (I_NEW | I_FREEING | I_WILL_FREE)) {
502+
WARN_ON(1);
503+
continue;
504+
}
505+
506+
inode->i_state |= I_FREEING;
507+
508+
/*
509+
* Move the inode off the IO lists and LRU once I_FREEING is
510+
* set so that it won't get moved back on there if it is dirty.
511+
*/
512+
list_move(&inode->i_lru, &dispose);
513+
list_del_init(&inode->i_wb_list);
514+
if (!(inode->i_state & (I_DIRTY | I_SYNC)))
515+
percpu_counter_dec(&nr_inodes_unused);
516+
}
517+
spin_unlock(&inode_lock);
518+
519+
dispose_list(&dispose);
520+
up_write(&iprune_sem);
521+
}
522+
480523
/**
481524
* invalidate_inodes - attempt to free all inodes on a superblock
482525
* @sb: superblock to operate on
@@ -493,9 +536,8 @@ int invalidate_inodes(struct super_block *sb)
493536
down_write(&iprune_sem);
494537

495538
spin_lock(&inode_lock);
496-
fsnotify_unmount_inodes(&sb->s_inodes);
497539
list_for_each_entry_safe(inode, next, &sb->s_inodes, i_sb_list) {
498-
if (inode->i_state & I_NEW)
540+
if (inode->i_state & (I_NEW | I_FREEING | I_WILL_FREE))
499541
continue;
500542
if (atomic_read(&inode->i_count)) {
501543
busy = 1;

fs/internal.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,4 +106,5 @@ extern void release_open_intent(struct nameidata *);
106106
* inode.c
107107
*/
108108
extern int get_nr_dirty_inodes(void);
109+
extern int evict_inodes(struct super_block *);
109110
extern int invalidate_inodes(struct super_block *);

fs/notify/inode_mark.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,7 @@ void fsnotify_unmount_inodes(struct list_head *list)
240240
{
241241
struct inode *inode, *next_i, *need_iput = NULL;
242242

243+
spin_lock(&inode_lock);
243244
list_for_each_entry_safe(inode, next_i, list, i_sb_list) {
244245
struct inode *need_iput_tmp;
245246

@@ -297,4 +298,5 @@ void fsnotify_unmount_inodes(struct list_head *list)
297298

298299
spin_lock(&inode_lock);
299300
}
301+
spin_unlock(&inode_lock);
300302
}

fs/super.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -273,14 +273,14 @@ void generic_shutdown_super(struct super_block *sb)
273273
get_fs_excl();
274274
sb->s_flags &= ~MS_ACTIVE;
275275

276-
/* bad name - it should be evict_inodes() */
277-
invalidate_inodes(sb);
276+
fsnotify_unmount_inodes(&sb->s_inodes);
277+
278+
evict_inodes(sb);
278279

279280
if (sop->put_super)
280281
sop->put_super(sb);
281282

282-
/* Forget any remaining inodes */
283-
if (invalidate_inodes(sb)) {
283+
if (!list_empty(&sb->s_inodes)) {
284284
printk("VFS: Busy inodes after unmount of %s. "
285285
"Self-destruct in 5 seconds. Have a nice day...\n",
286286
sb->s_id);

0 commit comments

Comments
 (0)