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

Commit 5133cd75 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull fsnotify updates from Jan Kara:
 "The branch contains mainly a rework of fsnotify infrastructure fixing
  a shortcoming that we have waited for response to fanotify permission
  events with SRCU read lock held and when the process consuming events
  was slow to respond the kernel has stalled.

  It also contains several cleanups of unnecessary indirections in
  fsnotify framework and a bugfix from Amir fixing leakage of kernel
  internal errno to userspace"

* 'fsnotify' of git://git.kernel.org/pub/scm/linux/kernel/git/jack/linux-fs: (37 commits)
  fanotify: don't expose EOPENSTALE to userspace
  fsnotify: remove a stray unlock
  fsnotify: Move ->free_mark callback to fsnotify_ops
  fsnotify: Add group pointer in fsnotify_init_mark()
  fsnotify: Drop inode_mark.c
  fsnotify: Remove fsnotify_find_{inode|vfsmount}_mark()
  fsnotify: Remove fsnotify_detach_group_marks()
  fsnotify: Rename fsnotify_clear_marks_by_group_flags()
  fsnotify: Inline fsnotify_clear_{inode|vfsmount}_mark_group()
  fsnotify: Remove fsnotify_recalc_{inode|vfsmount}_mask()
  fsnotify: Remove fsnotify_set_mark_{,ignored_}mask_locked()
  fanotify: Release SRCU lock when waiting for userspace response
  fsnotify: Pass fsnotify_iter_info into handle_event handler
  fsnotify: Provide framework for dropping SRCU lock in ->handle_event
  fsnotify: Remove special handling of mark destruction on group shutdown
  fsnotify: Detach mark from object list when last reference is dropped
  fsnotify: Move queueing of mark for destruction into fsnotify_put_mark()
  inotify: Do not drop mark reference under idr_lock
  fsnotify: Free fsnotify_mark_connector when there is no mark attached
  fsnotify: Lock object list with connector lock
  ...
parents 7b66f132 4ff33aaf
Loading
Loading
Loading
Loading
+0 −3
Original line number Diff line number Diff line
@@ -371,9 +371,6 @@ void inode_init_once(struct inode *inode)
	INIT_LIST_HEAD(&inode->i_lru);
	address_space_init_once(&inode->i_data);
	i_size_ordered_init(inode);
#ifdef CONFIG_FSNOTIFY
	INIT_HLIST_HEAD(&inode->i_fsnotify_marks);
#endif
}
EXPORT_SYMBOL(inode_init_once);

+1 −1
Original line number Diff line number Diff line
@@ -59,7 +59,7 @@ struct mount {
	struct mountpoint *mnt_mp;	/* where is it mounted */
	struct hlist_node mnt_mp_list;	/* list mounts with the same mountpoint */
#ifdef CONFIG_FSNOTIFY
	struct hlist_head mnt_fsnotify_marks;
	struct fsnotify_mark_connector __rcu *mnt_fsnotify_marks;
	__u32 mnt_fsnotify_mask;
#endif
	int mnt_id;			/* mount identifier */
+0 −3
Original line number Diff line number Diff line
@@ -236,9 +236,6 @@ static struct mount *alloc_vfsmnt(const char *name)
		INIT_LIST_HEAD(&mnt->mnt_slave_list);
		INIT_LIST_HEAD(&mnt->mnt_slave);
		INIT_HLIST_NODE(&mnt->mnt_mp_list);
#ifdef CONFIG_FSNOTIFY
		INIT_HLIST_HEAD(&mnt->mnt_fsnotify_marks);
#endif
		init_fs_pin(&mnt->mnt_umount, drop_mountpoint);
	}
	return mnt;
+2 −2
Original line number Diff line number Diff line
obj-$(CONFIG_FSNOTIFY)		+= fsnotify.o notification.o group.o inode_mark.o \
				   mark.o vfsmount_mark.o fdinfo.o
obj-$(CONFIG_FSNOTIFY)		+= fsnotify.o notification.o group.o mark.o \
				   fdinfo.o

obj-y			+= dnotify/
obj-y			+= inotify/
+11 −14
Original line number Diff line number Diff line
@@ -52,7 +52,7 @@ struct dnotify_mark {
 */
static void dnotify_recalc_inode_mask(struct fsnotify_mark *fsn_mark)
{
	__u32 new_mask, old_mask;
	__u32 new_mask = 0;
	struct dnotify_struct *dn;
	struct dnotify_mark *dn_mark  = container_of(fsn_mark,
						     struct dnotify_mark,
@@ -60,17 +60,13 @@ static void dnotify_recalc_inode_mask(struct fsnotify_mark *fsn_mark)

	assert_spin_locked(&fsn_mark->lock);

	old_mask = fsn_mark->mask;
	new_mask = 0;
	for (dn = dn_mark->dn; dn != NULL; dn = dn->dn_next)
		new_mask |= (dn->dn_mask & ~FS_DN_MULTISHOT);
	fsnotify_set_mark_mask_locked(fsn_mark, new_mask);

	if (old_mask == new_mask)
	if (fsn_mark->mask == new_mask)
		return;
	fsn_mark->mask = new_mask;

	if (fsn_mark->inode)
		fsnotify_recalc_inode_mask(fsn_mark->inode);
	fsnotify_recalc_mask(fsn_mark->connector);
}

/*
@@ -86,7 +82,8 @@ static int dnotify_handle_event(struct fsnotify_group *group,
				struct fsnotify_mark *inode_mark,
				struct fsnotify_mark *vfsmount_mark,
				u32 mask, const void *data, int data_type,
				const unsigned char *file_name, u32 cookie)
				const unsigned char *file_name, u32 cookie,
				struct fsnotify_iter_info *iter_info)
{
	struct dnotify_mark *dn_mark;
	struct dnotify_struct *dn;
@@ -138,6 +135,7 @@ static void dnotify_free_mark(struct fsnotify_mark *fsn_mark)

static struct fsnotify_ops dnotify_fsnotify_ops = {
	.handle_event = dnotify_handle_event,
	.free_mark = dnotify_free_mark,
};

/*
@@ -160,7 +158,7 @@ void dnotify_flush(struct file *filp, fl_owner_t id)
	if (!S_ISDIR(inode->i_mode))
		return;

	fsn_mark = fsnotify_find_inode_mark(dnotify_group, inode);
	fsn_mark = fsnotify_find_mark(&inode->i_fsnotify_marks, dnotify_group);
	if (!fsn_mark)
		return;
	dn_mark = container_of(fsn_mark, struct dnotify_mark, fsn_mark);
@@ -308,7 +306,7 @@ int fcntl_dirnotify(int fd, struct file *filp, unsigned long arg)

	/* set up the new_fsn_mark and new_dn_mark */
	new_fsn_mark = &new_dn_mark->fsn_mark;
	fsnotify_init_mark(new_fsn_mark, dnotify_free_mark);
	fsnotify_init_mark(new_fsn_mark, dnotify_group);
	new_fsn_mark->mask = mask;
	new_dn_mark->dn = NULL;

@@ -316,13 +314,12 @@ int fcntl_dirnotify(int fd, struct file *filp, unsigned long arg)
	mutex_lock(&dnotify_group->mark_mutex);

	/* add the new_fsn_mark or find an old one. */
	fsn_mark = fsnotify_find_inode_mark(dnotify_group, inode);
	fsn_mark = fsnotify_find_mark(&inode->i_fsnotify_marks, dnotify_group);
	if (fsn_mark) {
		dn_mark = container_of(fsn_mark, struct dnotify_mark, fsn_mark);
		spin_lock(&fsn_mark->lock);
	} else {
		fsnotify_add_mark_locked(new_fsn_mark, dnotify_group, inode,
					 NULL, 0);
		fsnotify_add_mark_locked(new_fsn_mark, inode, NULL, 0);
		spin_lock(&new_fsn_mark->lock);
		fsn_mark = new_fsn_mark;
		dn_mark = new_dn_mark;
Loading