Commit 25b229df authored by Al Viro's avatar Al Viro
Browse files

fsnotify(): switch to passing const struct qstr * for file_name



Note that in fnsotify_move() and fsnotify_link() we are guaranteed
that dentry->d_name won't change during the fsnotify() evaluation
(by having the parent directory locked exclusive), so we don't
need to fetch dentry->d_name.name in the callers.  In fsnotify_dirent()
the same stability of dentry->d_name is also true, but it's a bit
more convoluted - there is one callchain (devpts_pty_new() ->
fsnotify_create() -> fsnotify_dirent()) where the parent is _not_
locked, but on devpts ->d_name of everything is unchanging; it
has neither explicit nor implicit renames.

Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
parent f4ec3a3d
Loading
Loading
Loading
Loading
+4 −2
Original line number Diff line number Diff line
@@ -885,6 +885,7 @@ repeat:
	list_for_each_entry(info, &kernfs_root(kn)->supers, node) {
		struct kernfs_node *parent;
		struct inode *inode;
		struct qstr name;

		/*
		 * We want fsnotify_modify() on @kn but as the
@@ -896,6 +897,7 @@ repeat:
		if (!inode)
			continue;

		name = (struct qstr)QSTR_INIT(kn->name, strlen(kn->name));
		parent = kernfs_get_parent(kn);
		if (parent) {
			struct inode *p_inode;
@@ -903,7 +905,7 @@ repeat:
			p_inode = ilookup(info->sb, parent->id.ino);
			if (p_inode) {
				fsnotify(p_inode, FS_MODIFY | FS_EVENT_ON_CHILD,
					 inode, FSNOTIFY_EVENT_INODE, kn->name, 0);
					 inode, FSNOTIFY_EVENT_INODE, &name, 0);
				iput(p_inode);
			}

@@ -911,7 +913,7 @@ repeat:
		}

		fsnotify(inode, FS_MODIFY, inode, FSNOTIFY_EVENT_INODE,
			 kn->name, 0);
			 &name, 0);
		iput(inode);
	}

+4 −4
Original line number Diff line number Diff line
@@ -179,10 +179,10 @@ int __fsnotify_parent(const struct path *path, struct dentry *dentry, __u32 mask
		take_dentry_name_snapshot(&name, dentry);
		if (path)
			ret = fsnotify(p_inode, mask, path, FSNOTIFY_EVENT_PATH,
				       name.name.name, 0);
				       &name.name, 0);
		else
			ret = fsnotify(p_inode, mask, dentry->d_inode, FSNOTIFY_EVENT_INODE,
				       name.name.name, 0);
				       &name.name, 0);
		release_dentry_name_snapshot(&name);
	}

@@ -325,7 +325,7 @@ static void fsnotify_iter_next(struct fsnotify_iter_info *iter_info)
 * notification event in whatever means they feel necessary.
 */
int fsnotify(struct inode *to_tell, __u32 mask, const void *data, int data_is,
	     const unsigned char *file_name, u32 cookie)
	     const struct qstr *file_name, u32 cookie)
{
	struct fsnotify_iter_info iter_info = {};
	struct super_block *sb = to_tell->i_sb;
@@ -379,7 +379,7 @@ int fsnotify(struct inode *to_tell, __u32 mask, const void *data, int data_is,
	 */
	while (fsnotify_iter_select_report_types(&iter_info)) {
		ret = send_to_group(to_tell, mask, data, data_is, cookie,
				    file_name, &iter_info);
				    file_name->name, &iter_info);

		if (ret && (mask & ALL_FSNOTIFY_PERM_EVENTS))
			goto out;
+5 −5
Original line number Diff line number Diff line
@@ -27,7 +27,7 @@ static inline int fsnotify_dirent(struct inode *dir, struct dentry *dentry,
				  __u32 mask)
{
	return fsnotify(dir, mask, d_inode(dentry), FSNOTIFY_EVENT_INODE,
			dentry->d_name.name, 0);
			&dentry->d_name, 0);
}

/* Notify this dentry's parent about a child's events. */
@@ -111,7 +111,7 @@ static inline void fsnotify_move(struct inode *old_dir, struct inode *new_dir,
	__u32 old_dir_mask = FS_MOVED_FROM;
	__u32 new_dir_mask = FS_MOVED_TO;
	__u32 mask = FS_MOVE_SELF;
	const unsigned char *new_name = moved->d_name.name;
	const struct qstr *new_name = &moved->d_name;

	if (old_dir == new_dir)
		old_dir_mask |= FS_DN_RENAME;
@@ -122,7 +122,7 @@ static inline void fsnotify_move(struct inode *old_dir, struct inode *new_dir,
		mask |= FS_ISDIR;
	}

	fsnotify(old_dir, old_dir_mask, source, FSNOTIFY_EVENT_INODE, old_name->name,
	fsnotify(old_dir, old_dir_mask, source, FSNOTIFY_EVENT_INODE, old_name,
		 fs_cookie);
	fsnotify(new_dir, new_dir_mask, source, FSNOTIFY_EVENT_INODE, new_name,
		 fs_cookie);
@@ -178,7 +178,7 @@ static inline void fsnotify_nameremove(struct dentry *dentry, int isdir)
	take_dentry_name_snapshot(&name, dentry);

	fsnotify(d_inode(parent), mask, d_inode(dentry), FSNOTIFY_EVENT_INODE,
		 name.name.name, 0);
		 &name.name, 0);

	release_dentry_name_snapshot(&name);
	dput(parent);
@@ -218,7 +218,7 @@ static inline void fsnotify_link(struct inode *dir, struct inode *inode, struct
	fsnotify_link_count(inode);
	audit_inode_child(dir, new_dentry, AUDIT_TYPE_CHILD_CREATE);

	fsnotify(dir, FS_CREATE, inode, FSNOTIFY_EVENT_INODE, new_dentry->d_name.name, 0);
	fsnotify(dir, FS_CREATE, inode, FSNOTIFY_EVENT_INODE, &new_dentry->d_name, 0);
}

/*
+2 −2
Original line number Diff line number Diff line
@@ -350,7 +350,7 @@ struct fsnotify_mark {

/* main fsnotify call to send events */
extern int fsnotify(struct inode *to_tell, __u32 mask, const void *data, int data_is,
		    const unsigned char *name, u32 cookie);
		    const struct qstr *name, u32 cookie);
extern int __fsnotify_parent(const struct path *path, struct dentry *dentry, __u32 mask);
extern void __fsnotify_inode_delete(struct inode *inode);
extern void __fsnotify_vfsmount_delete(struct vfsmount *mnt);
@@ -505,7 +505,7 @@ static inline void fsnotify_init_event(struct fsnotify_event *event,
#else

static inline int fsnotify(struct inode *to_tell, __u32 mask, const void *data, int data_is,
			   const unsigned char *name, u32 cookie)
			   const struct qstr *name, u32 cookie)
{
	return 0;
}