diff options
author | Amir Goldstein <amir73il@gmail.com> | 2018-04-20 16:10:52 -0700 |
---|---|---|
committer | Jan Kara <jack@suse.cz> | 2018-05-18 14:58:22 +0200 |
commit | 47d9c7cc457adc5d6d8ca966482a51459f81e852 (patch) | |
tree | 5022fd69ab92a6f522b55ddb69b9ea2b22d84590 /fs/notify/fsnotify.c | |
parent | d9a6f30bb89309a7f2473028a00b83b020049cb4 (diff) | |
download | lwn-47d9c7cc457adc5d6d8ca966482a51459f81e852.tar.gz lwn-47d9c7cc457adc5d6d8ca966482a51459f81e852.zip |
fsnotify: generalize iteration of marks by object type
Make some code that handles marks of object types inode and vfsmount
generic, so it can handle other object types.
Introduce fsnotify_foreach_obj_type macro to iterate marks by object type
and fsnotify_iter_{should|set}_report_type macros to set/test report_mask.
This is going to be used for adding mark of another object type
(super block mark).
Signed-off-by: Amir Goldstein <amir73il@gmail.com>
Signed-off-by: Jan Kara <jack@suse.cz>
Diffstat (limited to 'fs/notify/fsnotify.c')
-rw-r--r-- | fs/notify/fsnotify.c | 52 |
1 files changed, 28 insertions, 24 deletions
diff --git a/fs/notify/fsnotify.c b/fs/notify/fsnotify.c index 98e91037b11d..bc9a51480156 100644 --- a/fs/notify/fsnotify.c +++ b/fs/notify/fsnotify.c @@ -269,25 +269,29 @@ static struct fsnotify_mark *fsnotify_next_mark(struct fsnotify_mark *mark) static unsigned int fsnotify_iter_select_report_types( struct fsnotify_iter_info *iter_info) { - struct fsnotify_mark *inode_mark = iter_info->inode_mark; - struct fsnotify_mark *vfsmount_mark = iter_info->vfsmount_mark; - int cmp; + struct fsnotify_group *max_prio_group = NULL; + struct fsnotify_mark *mark; + int type; + + /* Choose max prio group among groups of all queue heads */ + fsnotify_foreach_obj_type(type) { + mark = iter_info->marks[type]; + if (mark && + fsnotify_compare_groups(max_prio_group, mark->group) > 0) + max_prio_group = mark->group; + } - if (!inode_mark && !vfsmount_mark) + if (!max_prio_group) return 0; - if (inode_mark && vfsmount_mark) { - cmp = fsnotify_compare_groups(inode_mark->group, - vfsmount_mark->group); - } else { - cmp = inode_mark ? -1 : 1; - } - + /* Set the report mask for marks from same group as max prio group */ iter_info->report_mask = 0; - if (cmp <= 0) - iter_info->report_mask |= FSNOTIFY_OBJ_TYPE_INODE_FL; - if (cmp >= 0) - iter_info->report_mask |= FSNOTIFY_OBJ_TYPE_VFSMOUNT_FL; + fsnotify_foreach_obj_type(type) { + mark = iter_info->marks[type]; + if (mark && + fsnotify_compare_groups(max_prio_group, mark->group) == 0) + fsnotify_iter_set_report_type(iter_info, type); + } return iter_info->report_mask; } @@ -298,13 +302,13 @@ static unsigned int fsnotify_iter_select_report_types( */ static void fsnotify_iter_next(struct fsnotify_iter_info *iter_info) { - if (iter_info->report_mask & FSNOTIFY_OBJ_TYPE_INODE_FL) - iter_info->inode_mark = - fsnotify_next_mark(iter_info->inode_mark); + int type; - if (iter_info->report_mask & FSNOTIFY_OBJ_TYPE_VFSMOUNT_FL) - iter_info->vfsmount_mark = - fsnotify_next_mark(iter_info->vfsmount_mark); + fsnotify_foreach_obj_type(type) { + if (fsnotify_iter_should_report_type(iter_info, type)) + iter_info->marks[type] = + fsnotify_next_mark(iter_info->marks[type]); + } } /* @@ -351,15 +355,15 @@ int fsnotify(struct inode *to_tell, __u32 mask, const void *data, int data_is, if ((mask & FS_MODIFY) || (test_mask & to_tell->i_fsnotify_mask)) { - iter_info.inode_mark = + iter_info.marks[FSNOTIFY_OBJ_TYPE_INODE] = fsnotify_first_mark(&to_tell->i_fsnotify_marks); } if (mnt && ((mask & FS_MODIFY) || (test_mask & mnt->mnt_fsnotify_mask))) { - iter_info.inode_mark = + iter_info.marks[FSNOTIFY_OBJ_TYPE_INODE] = fsnotify_first_mark(&to_tell->i_fsnotify_marks); - iter_info.vfsmount_mark = + iter_info.marks[FSNOTIFY_OBJ_TYPE_VFSMOUNT] = fsnotify_first_mark(&mnt->mnt_fsnotify_marks); } |