lkml.org 
[lkml]   [2016]   [Mar]   [18]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH v6 2/4] fsnotify: Simplify inode iteration on umount
    Date
    From: Jan Kara <jack@suse.cz>

    fsnotify_unmount_inodes() played complex tricks to pin next inode in the
    sb->s_inodes list when iterating over all inodes. If we switch to
    keeping current inode pinned somewhat longer, we can make the code much
    simpler and standard.

    Signed-off-by: Jan Kara <jack@suse.cz>
    Signed-off-by: Waiman Long <Waiman.Long@hpe.com>
    ---
    fs/notify/inode_mark.c | 45 +++++++++------------------------------------
    1 files changed, 9 insertions(+), 36 deletions(-)

    diff --git a/fs/notify/inode_mark.c b/fs/notify/inode_mark.c
    index 741077d..a364524 100644
    --- a/fs/notify/inode_mark.c
    +++ b/fs/notify/inode_mark.c
    @@ -150,12 +150,10 @@ int fsnotify_add_inode_mark(struct fsnotify_mark *mark,
    */
    void fsnotify_unmount_inodes(struct super_block *sb)
    {
    - struct inode *inode, *next_i, *need_iput = NULL;
    + struct inode *inode, *iput_inode = NULL;

    spin_lock(&sb->s_inode_list_lock);
    - list_for_each_entry_safe(inode, next_i, &sb->s_inodes, i_sb_list) {
    - struct inode *need_iput_tmp;
    -
    + list_for_each_entry(inode, &sb->s_inodes, i_sb_list) {
    /*
    * We cannot __iget() an inode in state I_FREEING,
    * I_WILL_FREE, or I_NEW which is fine because by that point
    @@ -178,49 +176,24 @@ void fsnotify_unmount_inodes(struct super_block *sb)
    continue;
    }

    - need_iput_tmp = need_iput;
    - need_iput = NULL;
    -
    - /* In case fsnotify_inode_delete() drops a reference. */
    - if (inode != need_iput_tmp)
    - __iget(inode);
    - else
    - need_iput_tmp = NULL;
    + __iget(inode);
    spin_unlock(&inode->i_lock);
    -
    - /* In case the dropping of a reference would nuke next_i. */
    - while (&next_i->i_sb_list != &sb->s_inodes) {
    - spin_lock(&next_i->i_lock);
    - if (!(next_i->i_state & (I_FREEING | I_WILL_FREE)) &&
    - atomic_read(&next_i->i_count)) {
    - __iget(next_i);
    - need_iput = next_i;
    - spin_unlock(&next_i->i_lock);
    - break;
    - }
    - spin_unlock(&next_i->i_lock);
    - next_i = list_next_entry(next_i, i_sb_list);
    - }
    -
    - /*
    - * We can safely drop s_inode_list_lock here because either
    - * we actually hold references on both inode and next_i or
    - * end of list. Also no new inodes will be added since the
    - * umount has begun.
    - */
    spin_unlock(&sb->s_inode_list_lock);

    - if (need_iput_tmp)
    - iput(need_iput_tmp);
    + if (iput_inode)
    + iput(iput_inode);

    /* for each watch, send FS_UNMOUNT and then remove it */
    fsnotify(inode, FS_UNMOUNT, inode, FSNOTIFY_EVENT_INODE, NULL, 0);

    fsnotify_inode_delete(inode);

    - iput(inode);
    + iput_inode = inode;

    spin_lock(&sb->s_inode_list_lock);
    }
    spin_unlock(&sb->s_inode_list_lock);
    +
    + if (iput_inode)
    + iput(iput_inode);
    }
    --
    1.7.1
    \
     
     \ /
      Last update: 2016-03-18 21:21    [W:2.075 / U:0.044 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site