Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 1e6cb723 authored by Amir Goldstein's avatar Amir Goldstein Committed by Jan Kara
Browse files

fsnotify: add super block object type



Add the infrastructure to attach a mark to a super_block struct
and detach all attached marks when super block is destroyed.

This is going to be used by fanotify backend to setup super block
marks.

Signed-off-by: default avatarAmir Goldstein <amir73il@gmail.com>
Signed-off-by: default avatarJan Kara <jack@suse.cz>
parent 9bdda4e9
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -131,6 +131,11 @@ static void fanotify_fdinfo(struct seq_file *m, struct fsnotify_mark *mark)

		seq_printf(m, "fanotify mnt_id:%x mflags:%x mask:%x ignored_mask:%x\n",
			   mnt->mnt_id, mflags, mark->mask, mark->ignored_mask);
	} else if (mark->connector->type == FSNOTIFY_OBJ_TYPE_SB) {
		struct super_block *sb = fsnotify_conn_sb(mark->connector);

		seq_printf(m, "fanotify sdev:%x mflags:%x mask:%x ignored_mask:%x\n",
			   sb->s_dev, mflags, mark->mask, mark->ignored_mask);
	}
}

+7 −1
Original line number Diff line number Diff line
@@ -48,7 +48,7 @@ void __fsnotify_vfsmount_delete(struct vfsmount *mnt)
 * Called during unmount with no locks held, so needs to be safe against
 * concurrent modifiers. We temporarily drop sb->s_inode_list_lock and CAN block.
 */
void fsnotify_unmount_inodes(struct super_block *sb)
static void fsnotify_unmount_inodes(struct super_block *sb)
{
	struct inode *inode, *iput_inode = NULL;

@@ -98,6 +98,12 @@ void fsnotify_unmount_inodes(struct super_block *sb)
		iput(iput_inode);
}

void fsnotify_sb_delete(struct super_block *sb)
{
	fsnotify_unmount_inodes(sb);
	fsnotify_clear_marks_by_sb(sb);
}

/*
 * Given an inode, first check if we care what happens to our children.  Inotify
 * and dnotify both tell their parents about events.  If we care about any event
+11 −0
Original line number Diff line number Diff line
@@ -21,6 +21,12 @@ static inline struct mount *fsnotify_conn_mount(
	return container_of(conn->obj, struct mount, mnt_fsnotify_marks);
}

static inline struct super_block *fsnotify_conn_sb(
				struct fsnotify_mark_connector *conn)
{
	return container_of(conn->obj, struct super_block, s_fsnotify_marks);
}

/* destroy all events sitting in this groups notification queue */
extern void fsnotify_flush_notify(struct fsnotify_group *group);

@@ -43,6 +49,11 @@ static inline void fsnotify_clear_marks_by_mount(struct vfsmount *mnt)
{
	fsnotify_destroy_marks(&real_mount(mnt)->mnt_fsnotify_marks);
}
/* 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);
}
/* Wait until all marks queued for destruction are destroyed */
extern void fsnotify_wait_marks_destroyed(void);

+4 −0
Original line number Diff line number Diff line
@@ -115,6 +115,8 @@ static __u32 *fsnotify_conn_mask_p(struct fsnotify_mark_connector *conn)
		return &fsnotify_conn_inode(conn)->i_fsnotify_mask;
	else if (conn->type == FSNOTIFY_OBJ_TYPE_VFSMOUNT)
		return &fsnotify_conn_mount(conn)->mnt_fsnotify_mask;
	else if (conn->type == FSNOTIFY_OBJ_TYPE_SB)
		return &fsnotify_conn_sb(conn)->s_fsnotify_mask;
	return NULL;
}

@@ -192,6 +194,8 @@ static struct inode *fsnotify_detach_connector_from_object(
		inode->i_fsnotify_mask = 0;
	} else if (conn->type == FSNOTIFY_OBJ_TYPE_VFSMOUNT) {
		fsnotify_conn_mount(conn)->mnt_fsnotify_mask = 0;
	} else if (conn->type == FSNOTIFY_OBJ_TYPE_SB) {
		fsnotify_conn_sb(conn)->s_fsnotify_mask = 0;
	}

	rcu_assign_pointer(*(conn->obj), NULL);
+1 −1
Original line number Diff line number Diff line
@@ -442,7 +442,7 @@ void generic_shutdown_super(struct super_block *sb)
		sync_filesystem(sb);
		sb->s_flags &= ~SB_ACTIVE;

		fsnotify_unmount_inodes(sb);
		fsnotify_sb_delete(sb);
		cgroup_writeback_umount();

		evict_inodes(sb);
Loading