* [PATCH] fanotify: dont destroy mark when ignore mask is cleared @ 2010-11-22 17:52 Lino Sanfilippo 2010-11-23 19:51 ` Eric Paris 0 siblings, 1 reply; 6+ messages in thread From: Lino Sanfilippo @ 2010-11-22 17:52 UTC (permalink / raw) To: eparis; +Cc: linux-kernel, linux-fsdevel In mark_remove_from_mask() the mark is destroyed regardless of whether the event mask or ignore mask is cleared. We should only destroy the mark if the event mask is cleared. Signed-off-by: Lino Sanfilippo <LinoSanfilippo@gmx.de> --- fs/notify/fanotify/fanotify_user.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) Please apply this after patch "Dont allow a mask of 0 if setting or removing a mark" which i sent today. diff --git a/fs/notify/fanotify/fanotify_user.c b/fs/notify/fanotify/fanotify_user.c index 207cdeb..c9143a0 100644 --- a/fs/notify/fanotify/fanotify_user.c +++ b/fs/notify/fanotify/fanotify_user.c @@ -518,7 +518,7 @@ static __u32 fanotify_mark_remove_from_mask(struct fsnotify_mark *fsn_mark, } spin_unlock(&fsn_mark->lock); - if (!(oldmask & ~mask)) + if (!(flags & FAN_MARK_IGNORED_MASK) && !(oldmask & ~mask)) fsnotify_destroy_mark(fsn_mark); return mask & oldmask; -- 1.5.6.5 ^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH] fanotify: dont destroy mark when ignore mask is cleared 2010-11-22 17:52 [PATCH] fanotify: dont destroy mark when ignore mask is cleared Lino Sanfilippo @ 2010-11-23 19:51 ` Eric Paris 2010-11-24 12:31 ` Lino Sanfilippo 0 siblings, 1 reply; 6+ messages in thread From: Eric Paris @ 2010-11-23 19:51 UTC (permalink / raw) To: Lino Sanfilippo; +Cc: linux-kernel, linux-fsdevel On Mon, 2010-11-22 at 18:52 +0100, Lino Sanfilippo wrote: > In mark_remove_from_mask() the mark is destroyed regardless of whether the > event mask or ignore mask is cleared. We should only destroy the mark if the > event mask is cleared. > > Signed-off-by: Lino Sanfilippo <LinoSanfilippo@gmx.de> Hmmmm, really I'm not sure if that is right either (but it's certainly closer) What about something like: diff --git a/fs/notify/fanotify/fanotify_user.c b/fs/notify/fanotify/fanotify_user.c index 81df3ad..29fbf17 100644 --- a/fs/notify/fanotify/fanotify_user.c +++ b/fs/notify/fanotify/fanotify_user.c @@ -527,7 +527,7 @@ static __u32 fanotify_mark_remove_from_mask(struct fsnotify_mark *fsn_mark, } spin_unlock(&fsn_mark->lock); - if (!(oldmask & ~mask)) + if (!fsn_mark->mask && !fsn_mark->ignored_mask) fsnotify_destroy_mark(fsn_mark); return mask & oldmask; ^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH] fanotify: dont destroy mark when ignore mask is cleared 2010-11-23 19:51 ` Eric Paris @ 2010-11-24 12:31 ` Lino Sanfilippo 2010-11-29 20:45 ` Eric Paris 0 siblings, 1 reply; 6+ messages in thread From: Lino Sanfilippo @ 2010-11-24 12:31 UTC (permalink / raw) To: Eric Paris; +Cc: linux-kernel, linux-fsdevel On Tue, Nov 23, 2010 at 02:51:19PM -0500, Eric Paris wrote: > > Hmmmm, really I'm not sure if that is right either (but it's certainly > closer) What about something like: > > diff --git a/fs/notify/fanotify/fanotify_user.c b/fs/notify/fanotify/fanotify_user.c > index 81df3ad..29fbf17 100644 > --- a/fs/notify/fanotify/fanotify_user.c > +++ b/fs/notify/fanotify/fanotify_user.c > @@ -527,7 +527,7 @@ static __u32 fanotify_mark_remove_from_mask(struct fsnotify_mark *fsn_mark, > } > spin_unlock(&fsn_mark->lock); > > - if (!(oldmask & ~mask)) > + if (!fsn_mark->mask && !fsn_mark->ignored_mask) > fsnotify_destroy_mark(fsn_mark); > > return mask & oldmask; > > Yep, youre right, we should also check the ignore mask before we destroy the mark. BUT: 1. There is this flag FAN_MARK_ONDIR which is set implicitly in the ignore mask whenever it has not explicitly been set by the user (see fanotify_mark_add_to_mask()). If that flag has been set the ignore mask will never get cleared unless the user does something like fanotify_mark(fd, FAN_MARK_REMOVE | FAN_MARK_IGNORED_MASK, FAN_MARK_ONDIR,...) which presumes that he knows that this flag has been set. Btw.: every time a user _forgets_ to explicitly set FAN_MARK_ONDIR, it will be set in the ignored mask and thus events on dirs are skipped. Thus calls like fanotify_mark(fd, FAN_MARK_ADD, FAN_MARK_ONDIR, ...) /* get dir events */ fanotify_mark(fd, FAN_MARK_ADD, ...) /* add mark for some kind of event */ will result in dir events being ignored by the second call to fanotify_mark(), although the user has requested those events in his first call. This is very likely not what the user expected. Is there a reason why ONDIR is set implicitly in the ignore mask? Otherwise i would suggest to not set it implicitly in mark->ignored_mask, but to set it in mark->mask if requested by the user. Then we could ignore dir events as long as the flag has not been set there. 2. I just realized that we cant simply call destroy_mark() if the masks are 0. There may be one or more concurrent processes calling fsnotify_find_inode_mark() (see fanotify_add_inode_mark()) and get the mark we are about to destroy at the same time. I will take a closer look at it, but it seems to be difficult to me to safely call destroy_mark() as long as we are not in the context of fanotify_release() (in which we dont have to deal with concurrency like that any more). ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH] fanotify: dont destroy mark when ignore mask is cleared 2010-11-24 12:31 ` Lino Sanfilippo @ 2010-11-29 20:45 ` Eric Paris 0 siblings, 0 replies; 6+ messages in thread From: Eric Paris @ 2010-11-29 20:45 UTC (permalink / raw) To: Lino Sanfilippo; +Cc: linux-kernel, linux-fsdevel On Wed, 2010-11-24 at 13:31 +0100, Lino Sanfilippo wrote: > 2. I just realized that we cant simply call destroy_mark() if the masks are 0. > There may be one or more concurrent processes calling fsnotify_find_inode_mark() > (see fanotify_add_inode_mark()) and get the mark we are about to destroy at the > same time. > > I will take a closer look at it, but it seems to be difficult to me to safely > call destroy_mark() as long as we are not in the context of fanotify_release() (in > which we dont have to deal with concurrency like that any more). I guess it is a question of safe vs racy. Yes it is safe, nothing will explode or panic. But we might have a race between one task removing an event type causing the mask to go to 0 and we should destroy the mark and another task adding an event type. If it raced just right we might destroy the mark after the second task added to it. I guess we really need to serialize fsnotify_mark() per group to solve the race... Do you want to take a stab at fixing these things or should I? -Eric ^ permalink raw reply [flat|nested] 6+ messages in thread
[parent not found: <20101130121635.277910@gmx.net>]
* Re: [PATCH] fanotify: dont destroy mark when ignore mask is cleared [not found] <20101130121635.277910@gmx.net> @ 2010-11-30 15:59 ` Lino Sanfilippo 2010-11-30 16:19 ` Eric Paris 0 siblings, 1 reply; 6+ messages in thread From: Lino Sanfilippo @ 2010-11-30 15:59 UTC (permalink / raw) To: eparis; +Cc: linux-kernel, linux-fsdevel On Tue, Nov 30, 2010 at 01:16:35PM +0100, Lino Sanfilippo wrote: > I guess it is a question of safe vs racy. Yes it is safe, nothing will > explode or panic. But we might have a race between one task removing an > event type causing the mask to go to 0 and we should destroy the mark > and another task adding an event type. If it raced just right we might > destroy the mark after the second task added to it. I guess we really > need to serialize fsnotify_mark() per group to solve the race... > > Do you want to take a stab at fixing these things or should I? > > -Eric IMHO the right thing to serialize this would be to do LOCK(groups->mark_lock) - get the inode mark - set the marks mask - possibly destroy the mask UNLOCK(groups->mark_lock) But we cant do this since setting the marks mask requires the lock of the mark - which would mean an incorrect lock order according to fsnotify_add_mark(): mark->lock group->mark_lock inode->i_lock What we could do very easily is use another mutex instead (use an existing one like the groups notification_mutex, or a completely new one) which is responsible for synchronising add_mark()/remove_mark(). If that solution is ok I'll prepare the patches for it. Otherwise i am not sure how to solve this... Lino ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH] fanotify: dont destroy mark when ignore mask is cleared 2010-11-30 15:59 ` Lino Sanfilippo @ 2010-11-30 16:19 ` Eric Paris 0 siblings, 0 replies; 6+ messages in thread From: Eric Paris @ 2010-11-30 16:19 UTC (permalink / raw) To: Lino Sanfilippo; +Cc: linux-kernel, linux-fsdevel On Tue, 2010-11-30 at 16:59 +0100, Lino Sanfilippo wrote: > On Tue, Nov 30, 2010 at 01:16:35PM +0100, Lino Sanfilippo wrote: > > > I guess it is a question of safe vs racy. Yes it is safe, nothing will > > explode or panic. But we might have a race between one task removing an > > event type causing the mask to go to 0 and we should destroy the mark > > and another task adding an event type. If it raced just right we might > > destroy the mark after the second task added to it. I guess we really > > need to serialize fsnotify_mark() per group to solve the race... > > > > Do you want to take a stab at fixing these things or should I? > > > > -Eric > > IMHO the right thing to serialize this would be to do > > LOCK(groups->mark_lock) > - get the inode mark > - set the marks mask > - possibly destroy the mask > UNLOCK(groups->mark_lock) > > But we cant do this since setting the marks mask requires the lock of the mark > - which would mean an incorrect lock order according to fsnotify_add_mark(): > > mark->lock > group->mark_lock > inode->i_lock > > What we could do very easily is use another mutex instead (use an existing one like the > groups notification_mutex, or a completely new one) which is responsible for synchronising > add_mark()/remove_mark(). I'd think a new per group mutex would be the right way to go. I'm not sure how I feel about notification_mutex. I guess you can go ahead and overload it and we can split it off later if someone finds it to be a performance blocker. -Eric ^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2010-11-30 16:19 UTC | newest] Thread overview: 6+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2010-11-22 17:52 [PATCH] fanotify: dont destroy mark when ignore mask is cleared Lino Sanfilippo 2010-11-23 19:51 ` Eric Paris 2010-11-24 12:31 ` Lino Sanfilippo 2010-11-29 20:45 ` Eric Paris [not found] <20101130121635.277910@gmx.net> 2010-11-30 15:59 ` Lino Sanfilippo 2010-11-30 16:19 ` Eric Paris
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).