Re: [PATCH v2 08/20] fsnotify: generalize iteration of marks by object type

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Wed, Apr 18, 2018 at 11:34 AM, Jan Kara <jack@xxxxxxx> wrote:
> On Tue 17-04-18 22:11:04, Amir Goldstein wrote:
>> On Tue, Apr 17, 2018 at 8:01 PM, Jan Kara <jack@xxxxxxx> wrote:
>> > On Thu 05-04-18 16:18:09, Amir Goldstein wrote:
>> >> Make some code that handles marks of object types inode and vfsmount
>> >> generic, so it can handle other object types.
>> >>
>> >> Introduce foreach_obj_type macros to iterate marks by object type
>> >> with or without consulting a type mask.
>> >>
>> >> This is going to be used for adding mark of another object type
>> >> (super block mark).
>> >>
>> >> Signed-off-by: Amir Goldstein <amir73il@xxxxxxxxx>
>> >> ---
>> >>  fs/notify/fsnotify.c             | 54 ++++++++++++++++++++++++----------------
>> >>  fs/notify/mark.c                 | 23 +++++++++++------
>> >>  include/linux/fsnotify_backend.h | 38 +++++++++++++++++++++-------
>> >>  3 files changed, 76 insertions(+), 39 deletions(-)
>> >>
>> >> diff --git a/fs/notify/fsnotify.c b/fs/notify/fsnotify.c
>> >> index 665f681dd913..1759121db50d 100644
>> >> --- a/fs/notify/fsnotify.c
>> >> +++ b/fs/notify/fsnotify.c
>> >> @@ -263,21 +263,31 @@ static struct fsnotify_mark *fsnotify_next_mark(struct fsnotify_mark *mark)
>> >>  /*
>> >>   * iter_info is a multi head priority queue of marks.
>> >>   * fsnotify_iter_first() picks a subset of marks from queue heads, all with the
>> >> - * same priority and clears the type_mask for other marks.
>> >> + * same group and clears the type_mask for other marks.
>> >>   * Returns the type_mask of the chosen subset.
>> >>   */
>> >>  static unsigned int fsnotify_iter_first(struct fsnotify_iter_info *iter_info)
>> >>  {
>> >> -     struct fsnotify_mark *inode_mark = iter_info->inode_mark;
>> >> -     struct fsnotify_mark *vfsmount_mark = iter_info->vfsmount_mark;
>> >> -
>> >> -     if (inode_mark && vfsmount_mark) {
>> >> -             int cmp = fsnotify_compare_groups(inode_mark->group,
>> >> -                                               vfsmount_mark->group);
>> >> -             if (cmp > 0)
>> >> -                     iter_info->type_mask &= ~FSNOTIFY_OBJ_TYPE_INODE_FL;
>> >> -             else if (cmp < 0)
>> >> -                     iter_info->type_mask &= ~FSNOTIFY_OBJ_TYPE_VFSMOUNT_FL;
>> >> +     struct fsnotify_group *max_prio_group = NULL;
>> >> +     unsigned int type_mask = iter_info->type_mask;
>> >> +     struct fsnotify_mark *mark;
>> >> +     int type;
>> >> +
>> >> +     if (!type_mask || is_power_of_2(type_mask))
>> >> +             return type_mask;
>> >> +
>> >> +     /* Choose max prio group among groups of all queue heads */
>> >> +     fsnotify_iter_foreach_obj_type_mark(iter_info, type, mark) {
>> >
>> > Does this macro really bring any benefit over:
>> >
>> >         fsnotify_foreach_obj_type(type) {
>> >                 mark = iter_info->marks[type];
>>
>> You mean:
>>        mark = fsnotify_iter_type_mark(info, type, mark);
>>
>> Which is non NULL only if type was selected.
>
> Hum, probably but it seems a bit confusing (and thus error prone in the
> long term). So how about making fsnotify_iter_next() just advancing mark
> pointers based on report_mask (to move over marks that were already
> reported) and then clearing report_mask.

OK, but no need to clear report_mask in fsnotify_iter_next(), because
select_report_types will recalculate the report mask.

> fsnotify_iter_select_report_types() would the walk over iter_info->marks
> array, consider all non-NULL entries for reporting, select among them
> those with the highest priority, and set report_mask appropriately.
> That way we won't even need fsnotify_iter_set_{inode|vfsmount}_mark()
> macros.

Right.

>
>> Needs a better name??
>> How about fsnotify_iter_test_type_mark() to counter
>> fsnotify_iter_set_type_mark()?
>
> If there are not many places, that need fsnotify_iter_type_mark() (which
> currently it seems there are not), then I'd just make it
> fsnotify_iter_should_report_type(iter, type) which returns bool - whether
> that type should be reported to or not. And then just explicitely use
> iter->marks[type] if type should be reported. IMO fsnotify_iter_type_mark()
> does not offer much advantage over this as you have to test for mark being
> NULL anyway.
>

I left convenience macros:
fsnotify_iter_should_report_type(iter, type)
fsnotify_iter_set_report_type(iter, type)
fsnotify_iter_set_report_type_mark(iter, type, mark)

> If there are many places that need fsnotify_iter_type_mark(), then I guess
> we could provide iteration only over types that should be reported. Does
> that sound good?
>

Yes, result looks much better IMO.
Rabased on your for_test branch and push to
https://github.com/amir73il/linux/commits/fanotify_sb

Thanks!
Amir.



[Index of Archives]     [Linux Ext4 Filesystem]     [Union Filesystem]     [Filesystem Testing]     [Ceph Users]     [Ecryptfs]     [AutoFS]     [Kernel Newbies]     [Share Photos]     [Security]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux Cachefs]     [Reiser Filesystem]     [Linux RAID]     [Samba]     [Device Mapper]     [CEPH Development]

  Powered by Linux