From: Christian Brauner <brauner@kernel.org>
To: Amir Goldstein <amir73il@gmail.com>
Cc: Jan Kara <jack@suse.cz>, Jens Axboe <axboe@kernel.dk>,
linux-fsdevel@vger.kernel.org
Subject: Re: [PATCH 07/10] fsnotify: lazy attach fsnotify_sb_info state to sb
Date: Wed, 20 Mar 2024 09:47:46 +0100 [thread overview]
Message-ID: <20240320-einblick-wimmeln-8fba6416c874@brauner> (raw)
In-Reply-To: <20240317184154.1200192-8-amir73il@gmail.com>
On Sun, Mar 17, 2024 at 08:41:51PM +0200, Amir Goldstein wrote:
> Define a container struct fsnotify_sb_info to hold per-sb state,
> including the reference to sb marks connector.
>
> Allocate the fsnotify_sb_info state before attaching connector to any
> object on the sb and free it only when killing sb.
>
> This state is going to be used for storing per priority watched objects
> counters.
>
> Suggested-by: Jan Kara <jack@suse.cz>
> Signed-off-by: Amir Goldstein <amir73il@gmail.com>
> ---
> fs/notify/fsnotify.c | 16 +++++++++++++---
> fs/notify/fsnotify.h | 9 ++++++++-
> fs/notify/mark.c | 32 +++++++++++++++++++++++++++++++-
> include/linux/fs.h | 8 ++++----
> include/linux/fsnotify_backend.h | 17 +++++++++++++++++
> 5 files changed, 73 insertions(+), 9 deletions(-)
>
> diff --git a/fs/notify/fsnotify.c b/fs/notify/fsnotify.c
> index 503e7c75e777..fb3f36bc6ea9 100644
> --- a/fs/notify/fsnotify.c
> +++ b/fs/notify/fsnotify.c
> @@ -89,11 +89,18 @@ static void fsnotify_unmount_inodes(struct super_block *sb)
>
> void fsnotify_sb_delete(struct super_block *sb)
> {
> + struct fsnotify_sb_info *sbinfo = fsnotify_sb_info(sb);
> +
> + /* Were any marks ever added to any object on this sb? */
> + if (!sbinfo)
> + return;
> +
> fsnotify_unmount_inodes(sb);
> fsnotify_clear_marks_by_sb(sb);
> /* Wait for outstanding object references from connectors */
> wait_var_event(fsnotify_sb_watched_objects(sb),
> !atomic_long_read(fsnotify_sb_watched_objects(sb)));
> + kfree(sbinfo);
> }
>
> /*
> @@ -489,6 +496,7 @@ int fsnotify(__u32 mask, const void *data, int data_type, struct inode *dir,
> {
> const struct path *path = fsnotify_data_path(data, data_type);
> struct super_block *sb = fsnotify_data_sb(data, data_type);
> + struct fsnotify_sb_info *sbinfo = fsnotify_sb_info(sb);
> struct fsnotify_iter_info iter_info = {};
> struct mount *mnt = NULL;
> struct inode *inode2 = NULL;
> @@ -525,7 +533,7 @@ int fsnotify(__u32 mask, const void *data, int data_type, struct inode *dir,
> * SRCU because we have no references to any objects and do not
> * need SRCU to keep them "alive".
> */
> - if (!sb->s_fsnotify_marks &&
> + if ((!sbinfo || !sbinfo->sb_marks) &&
> (!mnt || !mnt->mnt_fsnotify_marks) &&
> (!inode || !inode->i_fsnotify_marks) &&
> (!inode2 || !inode2->i_fsnotify_marks))
> @@ -552,8 +560,10 @@ int fsnotify(__u32 mask, const void *data, int data_type, struct inode *dir,
>
> iter_info.srcu_idx = srcu_read_lock(&fsnotify_mark_srcu);
>
> - iter_info.marks[FSNOTIFY_ITER_TYPE_SB] =
> - fsnotify_first_mark(&sb->s_fsnotify_marks);
> + if (sbinfo) {
> + iter_info.marks[FSNOTIFY_ITER_TYPE_SB] =
> + fsnotify_first_mark(&sbinfo->sb_marks);
> + }
> if (mnt) {
> iter_info.marks[FSNOTIFY_ITER_TYPE_VFSMOUNT] =
> fsnotify_first_mark(&mnt->mnt_fsnotify_marks);
> diff --git a/fs/notify/fsnotify.h b/fs/notify/fsnotify.h
> index 8b73ad45cc71..378f9ec6d64b 100644
> --- a/fs/notify/fsnotify.h
> +++ b/fs/notify/fsnotify.h
> @@ -53,6 +53,13 @@ static inline struct super_block *fsnotify_connector_sb(
> return fsnotify_object_sb(conn->obj, conn->type);
> }
>
> +static inline fsnotify_connp_t *fsnotify_sb_marks(struct super_block *sb)
> +{
> + struct fsnotify_sb_info *sbinfo = fsnotify_sb_info(sb);
> +
> + return sbinfo ? &sbinfo->sb_marks : NULL;
> +}
> +
> /* destroy all events sitting in this groups notification queue */
> extern void fsnotify_flush_notify(struct fsnotify_group *group);
>
> @@ -78,7 +85,7 @@ static inline void fsnotify_clear_marks_by_mount(struct vfsmount *mnt)
> /* run the list of all marks associated with sb and destroy them */
> static inline void fsnotify_clear_marks_by_sb(struct super_block *sb)
> {
> - fsnotify_destroy_marks(&sb->s_fsnotify_marks);
> + fsnotify_destroy_marks(fsnotify_sb_marks(sb));
> }
>
> /*
> diff --git a/fs/notify/mark.c b/fs/notify/mark.c
> index 0b703f9e6344..db053e0e218d 100644
> --- a/fs/notify/mark.c
> +++ b/fs/notify/mark.c
> @@ -105,7 +105,7 @@ static fsnotify_connp_t *fsnotify_object_connp(void *obj, int obj_type)
> case FSNOTIFY_OBJ_TYPE_VFSMOUNT:
> return &real_mount(obj)->mnt_fsnotify_marks;
> case FSNOTIFY_OBJ_TYPE_SB:
> - return &((struct super_block *)obj)->s_fsnotify_marks;
> + return fsnotify_sb_marks(obj);
> default:
> return NULL;
> }
> @@ -568,6 +568,26 @@ int fsnotify_compare_groups(struct fsnotify_group *a, struct fsnotify_group *b)
> return -1;
> }
>
> +static int fsnotify_attach_info_to_sb(struct super_block *sb)
> +{
> + struct fsnotify_sb_info *sbinfo;
> +
> + /* sb info is freed on fsnotify_sb_delete() */
> + sbinfo = kzalloc(sizeof(*sbinfo), GFP_KERNEL);
> + if (!sbinfo)
> + return -ENOMEM;
> +
> + /*
> + * cmpxchg() provides the barrier so that callers of fsnotify_sb_info()
> + * will observe an initialized structure
> + */
> + if (cmpxchg(&sb->s_fsnotify_info, NULL, sbinfo)) {
> + /* Someone else created sbinfo for us */
> + kfree(sbinfo);
> + }
Alternatively, you could consider using wait_var_event() to let
concurrent attachers wait for s_fsnotify_info to be initialized using a
sentinel value to indicate that the caller should wait. But not sure if
it's worth it.
next prev parent reply other threads:[~2024-03-20 8:47 UTC|newest]
Thread overview: 25+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-03-17 18:41 [PATCH 00/10] Further reduce overhead of fsnotify permission hooks Amir Goldstein
2024-03-17 18:41 ` [PATCH 01/10] fsnotify: rename fsnotify_{get,put}_sb_connectors() Amir Goldstein
2024-03-27 10:01 ` Jan Kara
2024-03-27 10:05 ` Amir Goldstein
2024-03-17 18:41 ` [PATCH 02/10] fsnotify: create helpers to get sb and connp from object Amir Goldstein
2024-03-20 8:28 ` Christian Brauner
2024-03-20 8:34 ` Amir Goldstein
2024-03-20 9:57 ` Jan Kara
2024-03-17 18:41 ` [PATCH 03/10] fsnotify: create a wrapper fsnotify_find_inode_mark() Amir Goldstein
2024-03-17 18:41 ` [PATCH 04/10] fanotify: merge two checks regarding add of ignore mark Amir Goldstein
2024-03-17 18:41 ` [PATCH 05/10] fsnotify: pass object pointer and type to fsnotify mark helpers Amir Goldstein
2024-03-17 18:41 ` [PATCH 06/10] fsnotify: create helper fsnotify_update_sb_watchers() Amir Goldstein
2024-03-17 18:41 ` [PATCH 07/10] fsnotify: lazy attach fsnotify_sb_info state to sb Amir Goldstein
2024-03-20 8:47 ` Christian Brauner [this message]
2024-03-20 9:37 ` Amir Goldstein
2024-03-20 9:51 ` Jan Kara
2024-03-20 10:13 ` Christian Brauner
2024-03-17 18:41 ` [PATCH 08/10] fsnotify: move s_fsnotify_connectors into fsnotify_sb_info Amir Goldstein
2024-03-20 9:00 ` Christian Brauner
2024-03-17 18:41 ` [PATCH 09/10] fsnotify: use an enum for group priority constants Amir Goldstein
2024-03-17 18:41 ` [PATCH 10/10] fsnotify: optimize the case of no permission event watchers Amir Goldstein
2024-03-19 9:59 ` [PATCH 00/10] Further reduce overhead of fsnotify permission hooks Amir Goldstein
2024-04-04 14:34 ` Jan Kara
2024-04-04 14:41 ` Amir Goldstein
2024-04-04 15:53 ` Jan Kara
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=20240320-einblick-wimmeln-8fba6416c874@brauner \
--to=brauner@kernel.org \
--cc=amir73il@gmail.com \
--cc=axboe@kernel.dk \
--cc=jack@suse.cz \
--cc=linux-fsdevel@vger.kernel.org \
/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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox