From ab1152dd5650d35da6f0f6d3c0cc18f86fdc0725 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Fri, 15 Mar 2019 22:58:11 -0400 Subject: unexport d_alloc_pseudo() No modular uses since introducion of alloc_file_pseudo(), and the only non-modular user not in alloc_file_pseudo() had actually been wrong - should've been d_alloc_anon(). Signed-off-by: Al Viro --- Documentation/filesystems/porting | 5 +++++ fs/dcache.c | 4 +++- fs/internal.h | 1 + include/linux/dcache.h | 1 - 4 files changed, 9 insertions(+), 2 deletions(-) diff --git a/Documentation/filesystems/porting b/Documentation/filesystems/porting index a60fa516d4cb..7ed8188e7047 100644 --- a/Documentation/filesystems/porting +++ b/Documentation/filesystems/porting @@ -643,3 +643,8 @@ in your dentry operations instead. DCACHE_RCUACCESS is gone; having an RCU delay on dentry freeing is the default. DCACHE_NORCU opts out, and only d_alloc_pseudo() has any business doing so. +-- +[mandatory] + d_alloc_pseudo() is internal-only; uses outside of alloc_file_pseudo() are + very suspect (and won't work in modules). Such uses are very likely to + be misspelled d_alloc_anon(). diff --git a/fs/dcache.c b/fs/dcache.c index c663c602f9ef..6dd58ced8236 100644 --- a/fs/dcache.c +++ b/fs/dcache.c @@ -1742,6 +1742,9 @@ struct dentry *d_alloc_cursor(struct dentry * parent) * never be anyone's children or parents. Unlike all other * dentries, these will not have RCU delay between dropping the * last reference and freeing them. + * + * The only user is alloc_file_pseudo() and that's what should + * be considered a public interface. Don't use directly. */ struct dentry *d_alloc_pseudo(struct super_block *sb, const struct qstr *name) { @@ -1750,7 +1753,6 @@ struct dentry *d_alloc_pseudo(struct super_block *sb, const struct qstr *name) dentry->d_flags |= DCACHE_NORCU; return dentry; } -EXPORT_SYMBOL(d_alloc_pseudo); struct dentry *d_alloc_name(struct dentry *parent, const char *name) { diff --git a/fs/internal.h b/fs/internal.h index 2e7362837a6e..8102032432cf 100644 --- a/fs/internal.h +++ b/fs/internal.h @@ -155,6 +155,7 @@ extern struct dentry *__d_alloc(struct super_block *, const struct qstr *); extern int d_set_mounted(struct dentry *dentry); extern long prune_dcache_sb(struct super_block *sb, struct shrink_control *sc); extern struct dentry *d_alloc_cursor(struct dentry *); +extern struct dentry * d_alloc_pseudo(struct super_block *, const struct qstr *); /* * read_write.c diff --git a/include/linux/dcache.h b/include/linux/dcache.h index 6e1e8e6602c6..2f044e232e1b 100644 --- a/include/linux/dcache.h +++ b/include/linux/dcache.h @@ -235,7 +235,6 @@ extern void d_set_d_op(struct dentry *dentry, const struct dentry_operations *op /* allocate/de-allocate */ extern struct dentry * d_alloc(struct dentry *, const struct qstr *); extern struct dentry * d_alloc_anon(struct super_block *); -extern struct dentry * d_alloc_pseudo(struct super_block *, const struct qstr *); extern struct dentry * d_alloc_parallel(struct dentry *, const struct qstr *, wait_queue_head_t *); extern struct dentry * d_splice_alias(struct inode *, struct dentry *); -- cgit v1.2.3-59-g8ed1b From 357ab5b5d240a284b261a62451e838dd9f76e6b9 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Fri, 22 Mar 2019 23:26:22 -0400 Subject: nsfs: unobfuscate 1) IS_ERR(p) && PTR_ERR(p) == -E... is spelled p == ERR_PTR(-E...) 2) yes, you can open-code do-while and sometimes there's even a good reason to do so. Not in this case, though. Signed-off-by: Al Viro --- fs/nsfs.c | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/fs/nsfs.c b/fs/nsfs.c index 30d150a4f0c6..e3bf08c5af41 100644 --- a/fs/nsfs.c +++ b/fs/nsfs.c @@ -105,17 +105,16 @@ slow: void *ns_get_path_cb(struct path *path, ns_get_path_helper_t *ns_get_cb, void *private_data) { - struct ns_common *ns; void *ret; -again: - ns = ns_get_cb(private_data); - if (!ns) - return ERR_PTR(-ENOENT); + do { + struct ns_common *ns = ns_get_cb(private_data); + if (!ns) + return ERR_PTR(-ENOENT); + + ret = __ns_get_path(path, ns); + } while (ret == ERR_PTR(-EAGAIN)); - ret = __ns_get_path(path, ns); - if (IS_ERR(ret) && PTR_ERR(ret) == -EAGAIN) - goto again; return ret; } @@ -154,7 +153,7 @@ int open_related_ns(struct ns_common *ns, if (fd < 0) return fd; - while (1) { + do { struct ns_common *relative; relative = get_ns(ns); @@ -164,10 +163,8 @@ int open_related_ns(struct ns_common *ns, } err = __ns_get_path(&path, relative); - if (IS_ERR(err) && PTR_ERR(err) == -EAGAIN) - continue; - break; - } + } while (err == ERR_PTR(-EAGAIN)); + if (IS_ERR(err)) { put_unused_fd(fd); return PTR_ERR(err); -- cgit v1.2.3-59-g8ed1b From 1d8b29fdb7ef39bd76bcd7a7f516938163097b0e Mon Sep 17 00:00:00 2001 From: Al Viro Date: Tue, 2 Apr 2019 09:42:50 -0400 Subject: sysv: bury the broken "quietly truncate the long filenames" logics It's contrary to the normal semantics, only sysv and adfs try to do that (on any other filesystem you'll get -ENAMETOOLONG instead of quiet truncation) and nobody actually uses that - it got accidentally broken 5 years ago and nobody noticed. Time to bury it... Signed-off-by: Al Viro --- fs/sysv/namei.c | 15 --------------- fs/sysv/super.c | 3 --- fs/sysv/sysv.h | 3 --- 3 files changed, 21 deletions(-) diff --git a/fs/sysv/namei.c b/fs/sysv/namei.c index 4d5d20491ffd..ea2414b385ec 100644 --- a/fs/sysv/namei.c +++ b/fs/sysv/namei.c @@ -28,21 +28,6 @@ static int add_nondir(struct dentry *dentry, struct inode *inode) return err; } -static int sysv_hash(const struct dentry *dentry, struct qstr *qstr) -{ - /* Truncate the name in place, avoids having to define a compare - function. */ - if (qstr->len > SYSV_NAMELEN) { - qstr->len = SYSV_NAMELEN; - qstr->hash = full_name_hash(dentry, qstr->name, qstr->len); - } - return 0; -} - -const struct dentry_operations sysv_dentry_operations = { - .d_hash = sysv_hash, -}; - static struct dentry *sysv_lookup(struct inode * dir, struct dentry * dentry, unsigned int flags) { struct inode * inode = NULL; diff --git a/fs/sysv/super.c b/fs/sysv/super.c index 89765ddfb738..d3b2f54d6449 100644 --- a/fs/sysv/super.c +++ b/fs/sysv/super.c @@ -312,7 +312,6 @@ static int complete_read_super(struct super_block *sb, int silent, int size) flavour_setup[sbi->s_type](sbi, &sb->s_max_links); - sbi->s_truncate = 1; sbi->s_ndatazones = sbi->s_nzones - sbi->s_firstdatazone; sbi->s_inodes_per_block = bsize >> 6; sbi->s_inodes_per_block_1 = (bsize >> 6)-1; @@ -334,8 +333,6 @@ static int complete_read_super(struct super_block *sb, int silent, int size) sb->s_op = &sysv_sops; if (sbi->s_forced_ro) sb->s_flags |= SB_RDONLY; - if (sbi->s_truncate) - sb->s_d_op = &sysv_dentry_operations; root_inode = sysv_iget(sb, SYSV_ROOT_INO); if (IS_ERR(root_inode)) { printk("SysV FS: get root inode failed\n"); diff --git a/fs/sysv/sysv.h b/fs/sysv/sysv.h index e913698779c0..1cff585526b1 100644 --- a/fs/sysv/sysv.h +++ b/fs/sysv/sysv.h @@ -23,8 +23,6 @@ struct sysv_sb_info { struct super_block *s_sb; /* VFS superblock */ int s_type; /* file system type: FSTYPE_{XENIX|SYSV|COH} */ char s_bytesex; /* bytesex (le/be/pdp) */ - char s_truncate; /* if 1: names > SYSV_NAMELEN chars are truncated */ - /* if 0: they are disallowed (ENAMETOOLONG) */ unsigned int s_inodes_per_block; /* number of inodes per block */ unsigned int s_inodes_per_block_1; /* inodes_per_block - 1 */ unsigned int s_inodes_per_block_bits; /* log2(inodes_per_block) */ @@ -166,7 +164,6 @@ extern const struct file_operations sysv_file_operations; extern const struct file_operations sysv_dir_operations; extern const struct address_space_operations sysv_aops; extern const struct super_operations sysv_sops; -extern const struct dentry_operations sysv_dentry_operations; enum { -- cgit v1.2.3-59-g8ed1b From 230c6402b1b305c21c91b56cd9de95a608898506 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Fri, 26 Apr 2019 13:07:27 -0400 Subject: ovl_lookup_real_one(): don't bother with strlen() Signed-off-by: Al Viro --- fs/dcache.c | 14 ++++++-------- fs/debugfs/inode.c | 2 +- fs/namei.c | 2 +- fs/notify/fsnotify.c | 4 ++-- fs/overlayfs/export.c | 2 +- include/linux/dcache.h | 2 +- include/linux/fsnotify.h | 2 +- 7 files changed, 13 insertions(+), 15 deletions(-) diff --git a/fs/dcache.c b/fs/dcache.c index 6dd58ced8236..982d97bbb72c 100644 --- a/fs/dcache.c +++ b/fs/dcache.c @@ -284,25 +284,23 @@ static inline int dname_external(const struct dentry *dentry) void take_dentry_name_snapshot(struct name_snapshot *name, struct dentry *dentry) { spin_lock(&dentry->d_lock); + name->name = dentry->d_name; if (unlikely(dname_external(dentry))) { - struct external_name *p = external_name(dentry); - atomic_inc(&p->u.count); - spin_unlock(&dentry->d_lock); - name->name = p->name; + atomic_inc(&external_name(dentry)->u.count); } else { memcpy(name->inline_name, dentry->d_iname, dentry->d_name.len + 1); - spin_unlock(&dentry->d_lock); - name->name = name->inline_name; + name->name.name = name->inline_name; } + spin_unlock(&dentry->d_lock); } EXPORT_SYMBOL(take_dentry_name_snapshot); void release_dentry_name_snapshot(struct name_snapshot *name) { - if (unlikely(name->name != name->inline_name)) { + if (unlikely(name->name.name != name->inline_name)) { struct external_name *p; - p = container_of(name->name, struct external_name, name[0]); + p = container_of(name->name.name, struct external_name, name[0]); if (unlikely(atomic_dec_and_test(&p->u.count))) kfree_rcu(p, u.head); } diff --git a/fs/debugfs/inode.c b/fs/debugfs/inode.c index 95b5e78c22b1..f7064048d271 100644 --- a/fs/debugfs/inode.c +++ b/fs/debugfs/inode.c @@ -819,7 +819,7 @@ struct dentry *debugfs_rename(struct dentry *old_dir, struct dentry *old_dentry, goto exit; } d_move(old_dentry, dentry); - fsnotify_move(d_inode(old_dir), d_inode(new_dir), old_name.name, + fsnotify_move(d_inode(old_dir), d_inode(new_dir), old_name.name.name, d_is_dir(old_dentry), NULL, old_dentry); release_dentry_name_snapshot(&old_name); diff --git a/fs/namei.c b/fs/namei.c index dede0147b3f6..c96713077326 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -4498,7 +4498,7 @@ out: inode_unlock(target); dput(new_dentry); if (!error) { - fsnotify_move(old_dir, new_dir, old_name.name, is_dir, + fsnotify_move(old_dir, new_dir, old_name.name.name, is_dir, !(flags & RENAME_EXCHANGE) ? target : NULL, old_dentry); if (flags & RENAME_EXCHANGE) { fsnotify_move(new_dir, old_dir, old_dentry->d_name.name, diff --git a/fs/notify/fsnotify.c b/fs/notify/fsnotify.c index df06f3da166c..fb22f76329ae 100644 --- a/fs/notify/fsnotify.c +++ b/fs/notify/fsnotify.c @@ -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, 0); + name.name.name, 0); else ret = fsnotify(p_inode, mask, dentry->d_inode, FSNOTIFY_EVENT_INODE, - name.name, 0); + name.name.name, 0); release_dentry_name_snapshot(&name); } diff --git a/fs/overlayfs/export.c b/fs/overlayfs/export.c index 54e5d17d7f3e..cc1c9e5606ba 100644 --- a/fs/overlayfs/export.c +++ b/fs/overlayfs/export.c @@ -398,7 +398,7 @@ static struct dentry *ovl_lookup_real_one(struct dentry *connected, * pointer because we hold no lock on the real dentry. */ take_dentry_name_snapshot(&name, real); - this = lookup_one_len(name.name, connected, strlen(name.name)); + this = lookup_one_len(name.name.name, connected, name.name.len); err = PTR_ERR(this); if (IS_ERR(this)) { goto fail; diff --git a/include/linux/dcache.h b/include/linux/dcache.h index 2f044e232e1b..73c3a8f90580 100644 --- a/include/linux/dcache.h +++ b/include/linux/dcache.h @@ -593,7 +593,7 @@ static inline struct inode *d_real_inode(const struct dentry *dentry) } struct name_snapshot { - const unsigned char *name; + struct qstr name; unsigned char inline_name[DNAME_INLINE_LEN]; }; void take_dentry_name_snapshot(struct name_snapshot *, struct dentry *); diff --git a/include/linux/fsnotify.h b/include/linux/fsnotify.h index 09587e2860b5..e09cfff69bb2 100644 --- a/include/linux/fsnotify.h +++ b/include/linux/fsnotify.h @@ -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, 0); + name.name.name, 0); release_dentry_name_snapshot(&name); dput(parent); -- cgit v1.2.3-59-g8ed1b From f4ec3a3d43bcdcf6295af9f3715a5a33f59bb6ce Mon Sep 17 00:00:00 2001 From: Al Viro Date: Fri, 26 Apr 2019 13:21:24 -0400 Subject: switch fsnotify_move() to passing const struct qstr * for old_name note that in the second (RENAME_EXCHANGE) call of fsnotify_move() in vfs_rename() the old_dentry->d_name is guaranteed to be unchanged throughout the evaluation of fsnotify_move() (by the fact that the parent directory is locked exclusive), so we don't need to fetch old_dentry->d_name.name in the caller. Signed-off-by: Al Viro --- fs/debugfs/inode.c | 2 +- fs/namei.c | 4 ++-- include/linux/fsnotify.h | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/fs/debugfs/inode.c b/fs/debugfs/inode.c index f7064048d271..8b8225211a14 100644 --- a/fs/debugfs/inode.c +++ b/fs/debugfs/inode.c @@ -819,7 +819,7 @@ struct dentry *debugfs_rename(struct dentry *old_dir, struct dentry *old_dentry, goto exit; } d_move(old_dentry, dentry); - fsnotify_move(d_inode(old_dir), d_inode(new_dir), old_name.name.name, + fsnotify_move(d_inode(old_dir), d_inode(new_dir), &old_name.name, d_is_dir(old_dentry), NULL, old_dentry); release_dentry_name_snapshot(&old_name); diff --git a/fs/namei.c b/fs/namei.c index c96713077326..5ebd64b21970 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -4498,10 +4498,10 @@ out: inode_unlock(target); dput(new_dentry); if (!error) { - fsnotify_move(old_dir, new_dir, old_name.name.name, is_dir, + fsnotify_move(old_dir, new_dir, &old_name.name, is_dir, !(flags & RENAME_EXCHANGE) ? target : NULL, old_dentry); if (flags & RENAME_EXCHANGE) { - fsnotify_move(new_dir, old_dir, old_dentry->d_name.name, + fsnotify_move(new_dir, old_dir, &old_dentry->d_name, new_is_dir, NULL, new_dentry); } } diff --git a/include/linux/fsnotify.h b/include/linux/fsnotify.h index e09cfff69bb2..f816bd29b82c 100644 --- a/include/linux/fsnotify.h +++ b/include/linux/fsnotify.h @@ -102,7 +102,7 @@ static inline void fsnotify_link_count(struct inode *inode) * fsnotify_move - file old_name at old_dir was moved to new_name at new_dir */ static inline void fsnotify_move(struct inode *old_dir, struct inode *new_dir, - const unsigned char *old_name, + const struct qstr *old_name, int isdir, struct inode *target, struct dentry *moved) { @@ -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, + fsnotify(old_dir, old_dir_mask, source, FSNOTIFY_EVENT_INODE, old_name->name, fs_cookie); fsnotify(new_dir, new_dir_mask, source, FSNOTIFY_EVENT_INODE, new_name, fs_cookie); -- cgit v1.2.3-59-g8ed1b From 25b229dff4ffffd0fad2dd409faf1e2ae4d94866 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Fri, 26 Apr 2019 13:37:25 -0400 Subject: 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: Al Viro --- fs/kernfs/file.c | 6 ++++-- fs/notify/fsnotify.c | 8 ++++---- include/linux/fsnotify.h | 10 +++++----- include/linux/fsnotify_backend.h | 4 ++-- 4 files changed, 15 insertions(+), 13 deletions(-) diff --git a/fs/kernfs/file.c b/fs/kernfs/file.c index ae948aaa4c53..553ce0a92b05 100644 --- a/fs/kernfs/file.c +++ b/fs/kernfs/file.c @@ -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); } diff --git a/fs/notify/fsnotify.c b/fs/notify/fsnotify.c index fb22f76329ae..9cbb5ae11d2f 100644 --- a/fs/notify/fsnotify.c +++ b/fs/notify/fsnotify.c @@ -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; diff --git a/include/linux/fsnotify.h b/include/linux/fsnotify.h index f816bd29b82c..0c0ef3078a22 100644 --- a/include/linux/fsnotify.h +++ b/include/linux/fsnotify.h @@ -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); } /* diff --git a/include/linux/fsnotify_backend.h b/include/linux/fsnotify_backend.h index dfc28fcb4de8..7eb7821766d5 100644 --- a/include/linux/fsnotify_backend.h +++ b/include/linux/fsnotify_backend.h @@ -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; } -- cgit v1.2.3-59-g8ed1b From e43e9c339a78a0978f4ce473f645cedc05e6a57c Mon Sep 17 00:00:00 2001 From: Al Viro Date: Fri, 26 Apr 2019 13:51:03 -0400 Subject: fsnotify: switch send_to_group() and ->handle_event to const struct qstr * note that conditions surrounding accesses to dname in audit_watch_handle_event() and audit_mark_handle_event() guarantee that dname won't have been NULL. Signed-off-by: Al Viro --- fs/notify/dnotify/dnotify.c | 2 +- fs/notify/fanotify/fanotify.c | 2 +- fs/notify/fsnotify.c | 4 ++-- fs/notify/inotify/inotify.h | 2 +- fs/notify/inotify/inotify_fsnotify.c | 6 +++--- include/linux/fsnotify_backend.h | 2 +- kernel/audit_fsnotify.c | 4 ++-- kernel/audit_tree.c | 2 +- kernel/audit_watch.c | 6 +++--- 9 files changed, 15 insertions(+), 15 deletions(-) diff --git a/fs/notify/dnotify/dnotify.c b/fs/notify/dnotify/dnotify.c index 58d77dc696eb..250369d6901d 100644 --- a/fs/notify/dnotify/dnotify.c +++ b/fs/notify/dnotify/dnotify.c @@ -81,7 +81,7 @@ static void dnotify_recalc_inode_mask(struct fsnotify_mark *fsn_mark) static int dnotify_handle_event(struct fsnotify_group *group, struct inode *inode, u32 mask, const void *data, int data_type, - const unsigned char *file_name, u32 cookie, + const struct qstr *file_name, u32 cookie, struct fsnotify_iter_info *iter_info) { struct fsnotify_mark *inode_mark = fsnotify_iter_inode_mark(iter_info); diff --git a/fs/notify/fanotify/fanotify.c b/fs/notify/fanotify/fanotify.c index 6b9c27548997..a34d7e003d7d 100644 --- a/fs/notify/fanotify/fanotify.c +++ b/fs/notify/fanotify/fanotify.c @@ -361,7 +361,7 @@ static __kernel_fsid_t fanotify_get_fsid(struct fsnotify_iter_info *iter_info) static int fanotify_handle_event(struct fsnotify_group *group, struct inode *inode, u32 mask, const void *data, int data_type, - const unsigned char *file_name, u32 cookie, + const struct qstr *file_name, u32 cookie, struct fsnotify_iter_info *iter_info) { int ret = 0; diff --git a/fs/notify/fsnotify.c b/fs/notify/fsnotify.c index 9cbb5ae11d2f..5433e37fb0c5 100644 --- a/fs/notify/fsnotify.c +++ b/fs/notify/fsnotify.c @@ -195,7 +195,7 @@ EXPORT_SYMBOL_GPL(__fsnotify_parent); static int send_to_group(struct inode *to_tell, __u32 mask, const void *data, int data_is, u32 cookie, - const unsigned char *file_name, + const struct qstr *file_name, struct fsnotify_iter_info *iter_info) { struct fsnotify_group *group = NULL; @@ -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->name, &iter_info); + file_name, &iter_info); if (ret && (mask & ALL_FSNOTIFY_PERM_EVENTS)) goto out; diff --git a/fs/notify/inotify/inotify.h b/fs/notify/inotify/inotify.h index 74ae60305189..3f246f7b8a92 100644 --- a/fs/notify/inotify/inotify.h +++ b/fs/notify/inotify/inotify.h @@ -27,7 +27,7 @@ extern void inotify_ignored_and_remove_idr(struct fsnotify_mark *fsn_mark, extern int inotify_handle_event(struct fsnotify_group *group, struct inode *inode, u32 mask, const void *data, int data_type, - const unsigned char *file_name, u32 cookie, + const struct qstr *file_name, u32 cookie, struct fsnotify_iter_info *iter_info); extern const struct fsnotify_ops inotify_fsnotify_ops; diff --git a/fs/notify/inotify/inotify_fsnotify.c b/fs/notify/inotify/inotify_fsnotify.c index ff30abd6a49b..e87f012cbff7 100644 --- a/fs/notify/inotify/inotify_fsnotify.c +++ b/fs/notify/inotify/inotify_fsnotify.c @@ -67,7 +67,7 @@ static int inotify_merge(struct list_head *list, int inotify_handle_event(struct fsnotify_group *group, struct inode *inode, u32 mask, const void *data, int data_type, - const unsigned char *file_name, u32 cookie, + const struct qstr *file_name, u32 cookie, struct fsnotify_iter_info *iter_info) { struct fsnotify_mark *inode_mark = fsnotify_iter_inode_mark(iter_info); @@ -89,7 +89,7 @@ int inotify_handle_event(struct fsnotify_group *group, return 0; } if (file_name) { - len = strlen(file_name); + len = strlen(file_name->name); alloc_len += len + 1; } @@ -129,7 +129,7 @@ int inotify_handle_event(struct fsnotify_group *group, event->sync_cookie = cookie; event->name_len = len; if (len) - strcpy(event->name, file_name); + strcpy(event->name, file_name->name); ret = fsnotify_add_event(group, fsn_event, inotify_merge); if (ret) { diff --git a/include/linux/fsnotify_backend.h b/include/linux/fsnotify_backend.h index 7eb7821766d5..c28f6ed1f59b 100644 --- a/include/linux/fsnotify_backend.h +++ b/include/linux/fsnotify_backend.h @@ -117,7 +117,7 @@ struct fsnotify_ops { int (*handle_event)(struct fsnotify_group *group, struct inode *inode, u32 mask, const void *data, int data_type, - const unsigned char *file_name, u32 cookie, + const struct qstr *file_name, u32 cookie, struct fsnotify_iter_info *iter_info); void (*free_group_priv)(struct fsnotify_group *group); void (*freeing_mark)(struct fsnotify_mark *mark, struct fsnotify_group *group); diff --git a/kernel/audit_fsnotify.c b/kernel/audit_fsnotify.c index 37ae95cfb7f4..fb241805569c 100644 --- a/kernel/audit_fsnotify.c +++ b/kernel/audit_fsnotify.c @@ -164,7 +164,7 @@ static void audit_autoremove_mark_rule(struct audit_fsnotify_mark *audit_mark) static int audit_mark_handle_event(struct fsnotify_group *group, struct inode *to_tell, u32 mask, const void *data, int data_type, - const unsigned char *dname, u32 cookie, + const struct qstr *dname, u32 cookie, struct fsnotify_iter_info *iter_info) { struct fsnotify_mark *inode_mark = fsnotify_iter_inode_mark(iter_info); @@ -188,7 +188,7 @@ static int audit_mark_handle_event(struct fsnotify_group *group, } if (mask & (FS_CREATE|FS_MOVED_TO|FS_DELETE|FS_MOVED_FROM)) { - if (audit_compare_dname_path(dname, audit_mark->path, AUDIT_NAME_FULL)) + if (audit_compare_dname_path(dname->name, audit_mark->path, AUDIT_NAME_FULL)) return 0; audit_update_mark(audit_mark, inode); } else if (mask & (FS_DELETE_SELF|FS_UNMOUNT|FS_MOVE_SELF)) diff --git a/kernel/audit_tree.c b/kernel/audit_tree.c index abfb112f26aa..e49c912f862d 100644 --- a/kernel/audit_tree.c +++ b/kernel/audit_tree.c @@ -1040,7 +1040,7 @@ static void evict_chunk(struct audit_chunk *chunk) static int audit_tree_handle_event(struct fsnotify_group *group, struct inode *to_tell, u32 mask, const void *data, int data_type, - const unsigned char *file_name, u32 cookie, + const struct qstr *file_name, u32 cookie, struct fsnotify_iter_info *iter_info) { return 0; diff --git a/kernel/audit_watch.c b/kernel/audit_watch.c index e8d1adeb2223..3c12fd5b680e 100644 --- a/kernel/audit_watch.c +++ b/kernel/audit_watch.c @@ -482,7 +482,7 @@ void audit_remove_watch_rule(struct audit_krule *krule) static int audit_watch_handle_event(struct fsnotify_group *group, struct inode *to_tell, u32 mask, const void *data, int data_type, - const unsigned char *dname, u32 cookie, + const struct qstr *dname, u32 cookie, struct fsnotify_iter_info *iter_info) { struct fsnotify_mark *inode_mark = fsnotify_iter_inode_mark(iter_info); @@ -507,9 +507,9 @@ static int audit_watch_handle_event(struct fsnotify_group *group, } if (mask & (FS_CREATE|FS_MOVED_TO) && inode) - audit_update_watch(parent, dname, inode->i_sb->s_dev, inode->i_ino, 0); + audit_update_watch(parent, dname->name, inode->i_sb->s_dev, inode->i_ino, 0); else if (mask & (FS_DELETE|FS_MOVED_FROM)) - audit_update_watch(parent, dname, AUDIT_DEV_UNSET, AUDIT_INO_UNSET, 1); + audit_update_watch(parent, dname->name, AUDIT_DEV_UNSET, AUDIT_INO_UNSET, 1); else if (mask & (FS_DELETE_SELF|FS_UNMOUNT|FS_MOVE_SELF)) audit_remove_parent_watches(parent); -- cgit v1.2.3-59-g8ed1b From ce163918cd330158eb1a4c2a8fddec6b2e7d6d74 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Fri, 26 Apr 2019 13:55:21 -0400 Subject: inotify_handle_event(): don't bother with strlen() Signed-off-by: Al Viro --- fs/notify/inotify/inotify_fsnotify.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/notify/inotify/inotify_fsnotify.c b/fs/notify/inotify/inotify_fsnotify.c index e87f012cbff7..7e8b131029f8 100644 --- a/fs/notify/inotify/inotify_fsnotify.c +++ b/fs/notify/inotify/inotify_fsnotify.c @@ -89,7 +89,7 @@ int inotify_handle_event(struct fsnotify_group *group, return 0; } if (file_name) { - len = strlen(file_name->name); + len = file_name->len; alloc_len += len + 1; } -- cgit v1.2.3-59-g8ed1b From 6921d4ebe418e7cce9f65c1f38c93ea82a1f546c Mon Sep 17 00:00:00 2001 From: Al Viro Date: Fri, 26 Apr 2019 14:09:49 -0400 Subject: audit_update_watch(): switch to const struct qstr * Signed-off-by: Al Viro --- kernel/audit_watch.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/kernel/audit_watch.c b/kernel/audit_watch.c index 3c12fd5b680e..d832ce9df065 100644 --- a/kernel/audit_watch.c +++ b/kernel/audit_watch.c @@ -255,18 +255,19 @@ static void audit_watch_log_rule_change(struct audit_krule *r, struct audit_watc /* Update inode info in audit rules based on filesystem event. */ static void audit_update_watch(struct audit_parent *parent, - const char *dname, dev_t dev, + const struct qstr *dname, dev_t dev, unsigned long ino, unsigned invalidating) { struct audit_watch *owatch, *nwatch, *nextw; struct audit_krule *r, *nextr; struct audit_entry *oentry, *nentry; + const unsigned char *name = dname->name; mutex_lock(&audit_filter_mutex); /* Run all of the watches on this parent looking for the one that * matches the given dname */ list_for_each_entry_safe(owatch, nextw, &parent->watches, wlist) { - if (audit_compare_dname_path(dname, owatch->path, + if (audit_compare_dname_path(name, owatch->path, AUDIT_NAME_FULL)) continue; @@ -507,9 +508,9 @@ static int audit_watch_handle_event(struct fsnotify_group *group, } if (mask & (FS_CREATE|FS_MOVED_TO) && inode) - audit_update_watch(parent, dname->name, inode->i_sb->s_dev, inode->i_ino, 0); + audit_update_watch(parent, dname, inode->i_sb->s_dev, inode->i_ino, 0); else if (mask & (FS_DELETE|FS_MOVED_FROM)) - audit_update_watch(parent, dname->name, AUDIT_DEV_UNSET, AUDIT_INO_UNSET, 1); + audit_update_watch(parent, dname, AUDIT_DEV_UNSET, AUDIT_INO_UNSET, 1); else if (mask & (FS_DELETE_SELF|FS_UNMOUNT|FS_MOVE_SELF)) audit_remove_parent_watches(parent); -- cgit v1.2.3-59-g8ed1b From 795d673af1afae8146ac3070a2d77cfae5287c43 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Fri, 26 Apr 2019 14:11:05 -0400 Subject: audit_compare_dname_path(): switch to const struct qstr * Signed-off-by: Al Viro --- kernel/audit.h | 2 +- kernel/audit_fsnotify.c | 2 +- kernel/audit_watch.c | 3 +-- kernel/auditfilter.c | 6 +++--- kernel/auditsc.c | 4 ++-- 5 files changed, 8 insertions(+), 9 deletions(-) diff --git a/kernel/audit.h b/kernel/audit.h index 958d5b8fc1b3..2071725a999f 100644 --- a/kernel/audit.h +++ b/kernel/audit.h @@ -231,7 +231,7 @@ extern int audit_comparator(const u32 left, const u32 op, const u32 right); extern int audit_uid_comparator(kuid_t left, u32 op, kuid_t right); extern int audit_gid_comparator(kgid_t left, u32 op, kgid_t right); extern int parent_len(const char *path); -extern int audit_compare_dname_path(const char *dname, const char *path, int plen); +extern int audit_compare_dname_path(const struct qstr *dname, const char *path, int plen); extern struct sk_buff *audit_make_reply(int seq, int type, int done, int multi, const void *payload, int size); extern void audit_panic(const char *message); diff --git a/kernel/audit_fsnotify.c b/kernel/audit_fsnotify.c index fb241805569c..b5737b826951 100644 --- a/kernel/audit_fsnotify.c +++ b/kernel/audit_fsnotify.c @@ -188,7 +188,7 @@ static int audit_mark_handle_event(struct fsnotify_group *group, } if (mask & (FS_CREATE|FS_MOVED_TO|FS_DELETE|FS_MOVED_FROM)) { - if (audit_compare_dname_path(dname->name, audit_mark->path, AUDIT_NAME_FULL)) + if (audit_compare_dname_path(dname, audit_mark->path, AUDIT_NAME_FULL)) return 0; audit_update_mark(audit_mark, inode); } else if (mask & (FS_DELETE_SELF|FS_UNMOUNT|FS_MOVE_SELF)) diff --git a/kernel/audit_watch.c b/kernel/audit_watch.c index d832ce9df065..b50c574223fa 100644 --- a/kernel/audit_watch.c +++ b/kernel/audit_watch.c @@ -261,13 +261,12 @@ static void audit_update_watch(struct audit_parent *parent, struct audit_watch *owatch, *nwatch, *nextw; struct audit_krule *r, *nextr; struct audit_entry *oentry, *nentry; - const unsigned char *name = dname->name; mutex_lock(&audit_filter_mutex); /* Run all of the watches on this parent looking for the one that * matches the given dname */ list_for_each_entry_safe(owatch, nextw, &parent->watches, wlist) { - if (audit_compare_dname_path(name, owatch->path, + if (audit_compare_dname_path(dname, owatch->path, AUDIT_NAME_FULL)) continue; diff --git a/kernel/auditfilter.c b/kernel/auditfilter.c index 63f8b3f26fab..f9fff93c3351 100644 --- a/kernel/auditfilter.c +++ b/kernel/auditfilter.c @@ -1290,12 +1290,12 @@ int parent_len(const char *path) * @parentlen: length of the parent if known. Passing in AUDIT_NAME_FULL * here indicates that we must compute this value. */ -int audit_compare_dname_path(const char *dname, const char *path, int parentlen) +int audit_compare_dname_path(const struct qstr *dname, const char *path, int parentlen) { int dlen, pathlen; const char *p; - dlen = strlen(dname); + dlen = dname->len; pathlen = strlen(path); if (pathlen < dlen) return 1; @@ -1306,7 +1306,7 @@ int audit_compare_dname_path(const char *dname, const char *path, int parentlen) p = path + parentlen; - return strncmp(p, dname, dlen); + return strncmp(p, dname->name, dlen); } int audit_filter(int msgtype, unsigned int listtype) diff --git a/kernel/auditsc.c b/kernel/auditsc.c index d1eab1d4a930..92d0ae63febd 100644 --- a/kernel/auditsc.c +++ b/kernel/auditsc.c @@ -2045,7 +2045,7 @@ void __audit_inode_child(struct inode *parent, { struct audit_context *context = audit_context(); struct inode *inode = d_backing_inode(dentry); - const char *dname = dentry->d_name.name; + const struct qstr *dname = &dentry->d_name; struct audit_names *n, *found_parent = NULL, *found_child = NULL; struct audit_entry *e; struct list_head *list = &audit_filter_list[AUDIT_FILTER_FS]; @@ -2099,7 +2099,7 @@ void __audit_inode_child(struct inode *parent, (n->type != type && n->type != AUDIT_TYPE_UNKNOWN)) continue; - if (!strcmp(dname, n->name->name) || + if (!strcmp(dname->name, n->name->name) || !audit_compare_dname_path(dname, n->name->name, found_parent ? found_parent->name_len : -- cgit v1.2.3-59-g8ed1b