From: Jan Kara <jack@suse.cz>
To: Amir Goldstein <amir73il@gmail.com>
Cc: Jan Kara <jack@suse.cz>,
linux-fsdevel <linux-fsdevel@vger.kernel.org>,
Lino Sanfilippo <LinoSanfilippo@gmx.de>,
Miklos Szeredi <miklos@szeredi.hu>,
Paul Moore <paul@paul-moore.com>
Subject: Re: [PATCH 10/22] fsnotify: Detach mark from object list when last reference is dropped
Date: Fri, 23 Dec 2016 14:42:12 +0100 [thread overview]
Message-ID: <20161223134212.GF22679@quack2.suse.cz> (raw)
In-Reply-To: <CAOQ4uxhN0nj-GDZvdd0W161E=wQVfopkXkasJ8=h3CS2Zpw+TQ@mail.gmail.com>
On Fri 23-12-16 12:51:28, Amir Goldstein wrote:
> On Thu, Dec 22, 2016 at 11:15 AM, Jan Kara <jack@suse.cz> wrote:
> > Instead of removing mark from object list from fsnotify_detach_mark(),
> > remove the mark when last reference to the mark is dropped. This will
> > allow fanotify to wait for userspace response to event without having to
> > hold onto fsnotify_mark_srcu.
> >
> > Signed-off-by: Jan Kara <jack@suse.cz>
> > ---
> ...
>
> +/* Called with mark->obj_list_head->lock held, releases it */
> +static void fsnotify_detach_from_object(struct fsnotify_mark *mark)
> {
>
> IMO, the implicit release in this function makes the code using it hard
> to read and maintain. Please consider splitting it into 2 functions
> to be called from code that explicitly unlocks, e.g.:
>
> free_list = fsnotify_detach_from_object_locked(mark, &inode);
> spin_unlock(&list->lock);
> if (inode)
> iput(inode);
> if (free_list)
> fsnotify_free_list(list);
Maybe I'll instead move atomic_dec_and_lock() into
fsnotify_detach_from_object(). I'll just have to find good name for that
function.
> ...
> > + inode = fsnotify_detach_list_from_object(list);
> > free_list = true;
> > } else
> > __fsnotify_recalc_mask(list);
> > mark->obj_list_head = NULL;
> > spin_unlock(&list->lock);
> >
> > + if (inode)
> > + iput(inode);
> > +
>
> Question: if list is holding inode anyway, what's the use of
> FSNOTIFY_MARK_FLAG_OBJECT_PINNED?
> or maybe you are removing it later on in the series?
It is removed (maybe later, but certainly I remember dropping it).
> ...
> > + /*
> > + * We have to be careful since we can race with e.g.
> > + * fsnotify_clear_marks_by_group() and once we drop the list->lock, the
> > + * list can get modified. However we are holding mark reference and
> > + * thus our mark cannot be removed from obj_list so we can continue
> > + * iteration after regaining list->lock.
> > + */
> > + hlist_for_each_entry(mark, &list->list, obj_list) {
> > fsnotify_get_mark(mark);
> > - fsnotify_put_list(list);
> > + spin_unlock(&list->lock);
> > + if (old_mark)
> > + fsnotify_put_mark(old_mark);
> > + old_mark = mark;
> > fsnotify_destroy_mark(mark, mark->group);
> > - fsnotify_put_mark(mark);
> > + spin_lock(&list->lock);
> > }
> > + /*
> > + * Detach list from object now so that we don't pin inode until all
> > + * mark references get dropped. It would lead to strange results such
> > + * as delaying inode deletion or blocking unmount.
> > + */
> > + inode = fsnotify_detach_list_from_object(list);
> > + fsnotify_put_list(list);
> > + if (inode)
> > + iput(inode);
> > + if (old_mark)
> > + fsnotify_put_mark(old_mark);
>
> I must be missing something subtle here. I don't see where the list->lock
> is unlocked.
fsnotify_put_list() - fsnotify_grab_list() will get list->lock,
fsnotify_put_list() drops it.
> Also, I am not sure if you placed put old_mark after
> fsnotify_put_list
> for a reason. If you did, I did not find that reason in the comments. If you
> didn't I think it would be more appropriate after the list iteration
> ends, although
> it appear that put old_mark should be called after list->lock unlock.
Exactly. You have to drop mark reference after unlocking list for obvious
reasons.
> > diff --git a/include/linux/fsnotify_backend.h b/include/linux/fsnotify_backend.h
> > index 6086fc7ff6df..76b3c34172c7 100644
> > --- a/include/linux/fsnotify_backend.h
> > +++ b/include/linux/fsnotify_backend.h
> > @@ -244,9 +244,9 @@ struct fsnotify_mark {
> > struct list_head g_list;
> > /* Protects inode / mnt pointers, flags, masks */
> > spinlock_t lock;
> > - /* List of marks for inode / vfsmount [obj_list_head->lock] */
> > + /* List of marks for inode / vfsmount [obj_list_head->lock, mark ref] */
> > struct hlist_node obj_list;
> > - /* Head of list of marks for an object [mark->lock, group->mark_mutex] */
> > + /* Head of list of marks for an object [mark ref] */
> > struct fsnotify_mark_list *obj_list_head;
>
> What is the meaning of [mark ref] here?
> If the mark is on the obj_list its refcount is already elevated.
> I thought it's the mark that is holding a ref on the list_head (or tap
> if you accept my suggestion)
> and not the other way around.
So [mark ref] here means that if you hold mark reference, obj_list_head
cannot change and mark is pinned in the object list. Probably I can put
more detailed explanation above the structure declaration.
Honza
--
Jan Kara <jack@suse.com>
SUSE Labs, CR
next prev parent reply other threads:[~2016-12-23 13:43 UTC|newest]
Thread overview: 80+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-12-22 9:15 [PATCH 0/22] fsnotify: Avoid SRCU stalls with fanotify permission events Jan Kara
2016-12-22 9:15 ` [PATCH 01/22] fsnotify: Remove unnecessary tests when showing fdinfo Jan Kara
2016-12-22 12:59 ` Amir Goldstein
2016-12-22 15:16 ` Jan Kara
2016-12-22 15:54 ` Amir Goldstein
2016-12-22 9:15 ` [PATCH 02/22] inotify: Remove inode pointers from debug messages Jan Kara
2016-12-22 15:31 ` Amir Goldstein
2016-12-22 9:15 ` [PATCH 03/22] fanotify: Move recalculation of inode / vfsmount mask under mark_mutex Jan Kara
2016-12-22 16:27 ` Amir Goldstein
2016-12-22 17:31 ` Jan Kara
2016-12-22 19:08 ` Amir Goldstein
2016-12-22 9:15 ` [PATCH 04/22] fsnotify: Remove fsnotify_duplicate_mark() Jan Kara
2016-12-22 23:13 ` Paul Moore
2016-12-23 13:22 ` Jan Kara
2016-12-23 14:01 ` Paul Moore
2016-12-22 9:15 ` [PATCH 05/22] audit: Fix sleep in atomic Jan Kara
2016-12-22 23:18 ` Paul Moore
2016-12-23 13:24 ` Jan Kara
2016-12-23 14:17 ` Paul Moore
2016-12-26 16:33 ` Paul Moore
2017-01-02 18:21 ` Jan Kara
2017-01-03 21:11 ` Paul Moore
2017-01-03 21:11 ` Paul Moore
2017-01-04 8:50 ` Jan Kara
2017-01-05 2:14 ` Paul Moore
2016-12-22 9:15 ` [PATCH 06/22] audit: Abstract hash key handling Jan Kara
2016-12-22 23:27 ` Paul Moore
2016-12-23 13:27 ` Jan Kara
2016-12-23 14:13 ` Paul Moore
2017-01-03 17:34 ` Jan Kara
2017-01-05 2:06 ` Paul Moore
2016-12-22 9:15 ` [PATCH 07/22] fsnotify: Update comments Jan Kara
2016-12-23 4:45 ` Amir Goldstein
2016-12-22 9:15 ` [PATCH 08/22] fsnotify: Attach marks to object via dedicated head structure Jan Kara
2016-12-23 5:48 ` Amir Goldstein
2016-12-23 13:34 ` Jan Kara
2017-01-04 13:38 ` Jan Kara
2017-01-04 15:29 ` Amir Goldstein
2016-12-22 9:15 ` [PATCH 09/22] inotify: Do not drop mark reference under idr_lock Jan Kara
2016-12-23 8:04 ` Amir Goldstein
2016-12-22 9:15 ` [PATCH 10/22] fsnotify: Detach mark from object list when last reference is dropped Jan Kara
2016-12-23 10:51 ` Amir Goldstein
2016-12-23 13:42 ` Jan Kara [this message]
2016-12-22 9:15 ` [PATCH 11/22] fsnotify: Remove special handling of mark destruction on group shutdown Jan Kara
2016-12-23 12:12 ` Amir Goldstein
2016-12-23 13:31 ` Jan Kara
2016-12-22 9:15 ` [PATCH 12/22] fsnotify: Move queueing of mark for destruction into fsnotify_put_mark() Jan Kara
2016-12-26 14:15 ` Amir Goldstein
2017-01-04 10:28 ` Jan Kara
2017-01-04 12:22 ` Jan Kara
2016-12-22 9:15 ` [PATCH 13/22] fsnotify: Provide framework for dropping SRCU lock in ->handle_event Jan Kara
2016-12-26 15:01 ` Amir Goldstein
2016-12-26 15:11 ` Amir Goldstein
2017-01-04 9:03 ` Jan Kara
2017-01-04 10:50 ` Amir Goldstein
2017-01-04 11:45 ` Jan Kara
2016-12-26 18:37 ` Amir Goldstein
2016-12-22 9:15 ` [PATCH 14/22] fsnotify: Pass SRCU index into handle_event handler Jan Kara
2016-12-26 15:13 ` Amir Goldstein
2016-12-22 9:15 ` [PATCH 15/22] fanotify: Release SRCU lock when waiting for userspace response Jan Kara
2016-12-26 15:22 ` Amir Goldstein
2017-01-04 9:05 ` Jan Kara
2016-12-22 9:15 ` [PATCH 16/22] fsnotify: Remove fsnotify_set_mark_{,ignored_}mask_locked() Jan Kara
2016-12-26 16:42 ` Amir Goldstein
2016-12-22 9:15 ` [PATCH 17/22] fsnotify: Remove fsnotify_recalc_{inode|vfsmount}_mask() Jan Kara
2016-12-26 16:44 ` Amir Goldstein
2016-12-22 9:15 ` [PATCH 18/22] fsnotify: Inline fsnotify_clear_{inode|vfsmount|_mark_group() Jan Kara
2016-12-26 16:57 ` Amir Goldstein
2017-01-04 9:28 ` Jan Kara
2016-12-22 9:15 ` [PATCH 19/22] fsnotify: Remove fsnotify_find_{inode|vfsmount}_mark() Jan Kara
2016-12-26 17:14 ` Amir Goldstein
2016-12-22 9:15 ` [PATCH 20/22] fsnotify: Drop inode_mark.c Jan Kara
2016-12-26 17:15 ` Amir Goldstein
2016-12-22 9:15 ` [PATCH 21/22] fsnotify: Add group pointer in fsnotify_init_mark() Jan Kara
2016-12-26 17:34 ` Amir Goldstein
2016-12-22 9:15 ` [PATCH 22/22] fsnotify: Move ->free_mark callback to fsnotify_ops Jan Kara
2016-12-26 17:39 ` Amir Goldstein
2016-12-22 20:58 ` [PATCH 0/22] fsnotify: Avoid SRCU stalls with fanotify permission events Paul Moore
2016-12-22 21:05 ` Amir Goldstein
2016-12-22 23:04 ` Paul Moore
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20161223134212.GF22679@quack2.suse.cz \
--to=jack@suse.cz \
--cc=LinoSanfilippo@gmx.de \
--cc=amir73il@gmail.com \
--cc=linux-fsdevel@vger.kernel.org \
--cc=miklos@szeredi.hu \
--cc=paul@paul-moore.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.