From ff0ebee239ce3461cab68ebb8e1a359fc34329de Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sun, 14 Jul 2019 12:18:05 -0400 Subject: [PATCH 01/11] filename_lookup(): audit_inode() argument is always 0 We hadn't been passing LOOKUP_PARENT in flags to that thing since filename_parentat() had been split off back in 2015. Signed-off-by: Al Viro --- fs/namei.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/namei.c b/fs/namei.c index 209c51a5226c..83e5fb3fad76 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -2350,7 +2350,7 @@ int filename_lookup(int dfd, struct filename *name, unsigned flags, retval = path_lookupat(&nd, flags | LOOKUP_REVAL, path); if (likely(!retval)) - audit_inode(name, path->dentry, flags & LOOKUP_PARENT); + audit_inode(name, path->dentry, 0); restore_nameidata(); putname(name); return retval; From 39145f5f0cc924b494ad55a2bc9c1b4969b5a038 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sun, 14 Jul 2019 12:19:57 -0400 Subject: [PATCH 02/11] filename_mountpoint(): make LOOKUP_NO_EVAL unconditional there user_path_mountpoint_at() always gets it and the reasons to have it there (i.e. in umount(2)) apply to kern_path_mountpoint() callers as well. Signed-off-by: Al Viro --- fs/namei.c | 2 +- fs/namespace.c | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/fs/namei.c b/fs/namei.c index 83e5fb3fad76..5b8c72dc0217 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -2718,7 +2718,7 @@ filename_mountpoint(int dfd, struct filename *name, struct path *path, if (unlikely(error == -ESTALE)) error = path_mountpoint(&nd, flags | LOOKUP_REVAL, path); if (likely(!error)) - audit_inode(name, path->dentry, flags & LOOKUP_NO_EVAL); + audit_inode(name, path->dentry, LOOKUP_NO_EVAL); restore_nameidata(); putname(name); return error; diff --git a/fs/namespace.c b/fs/namespace.c index 6464ea4acba9..697f8820dff5 100644 --- a/fs/namespace.c +++ b/fs/namespace.c @@ -1675,8 +1675,6 @@ int ksys_umount(char __user *name, int flags) if (!(flags & UMOUNT_NOFOLLOW)) lookup_flags |= LOOKUP_FOLLOW; - lookup_flags |= LOOKUP_NO_EVAL; - retval = user_path_mountpoint_at(AT_FDCWD, name, lookup_flags, &path); if (retval) goto out; From c9b07eab0c8760bdd4cf8624c482ee145a322a3b Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sun, 14 Jul 2019 13:22:27 -0400 Subject: [PATCH 03/11] audit_inode(): switch to passing AUDIT_INODE_... don't bother with remapping LOOKUP_... values - all callers pass constants and we can just as well pass the right ones from the very beginning. Signed-off-by: Al Viro --- fs/namei.c | 6 +++--- include/linux/audit.h | 20 +++++++------------- 2 files changed, 10 insertions(+), 16 deletions(-) diff --git a/fs/namei.c b/fs/namei.c index 5b8c72dc0217..3fca26398bc2 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -2391,7 +2391,7 @@ static struct filename *filename_parentat(int dfd, struct filename *name, if (likely(!retval)) { *last = nd.last; *type = nd.last_type; - audit_inode(name, parent->dentry, LOOKUP_PARENT); + audit_inode(name, parent->dentry, AUDIT_INODE_PARENT); } else { putname(name); name = ERR_PTR(retval); @@ -2718,7 +2718,7 @@ filename_mountpoint(int dfd, struct filename *name, struct path *path, if (unlikely(error == -ESTALE)) error = path_mountpoint(&nd, flags | LOOKUP_REVAL, path); if (likely(!error)) - audit_inode(name, path->dentry, LOOKUP_NO_EVAL); + audit_inode(name, path->dentry, AUDIT_INODE_NOEVAL); restore_nameidata(); putname(name); return error; @@ -3299,7 +3299,7 @@ static int do_last(struct nameidata *nd, if (error) return error; - audit_inode(nd->name, dir, LOOKUP_PARENT); + audit_inode(nd->name, dir, AUDIT_INODE_PARENT); /* trailing slashes? */ if (unlikely(nd->last.name[nd->last.len])) return -EISDIR; diff --git a/include/linux/audit.h b/include/linux/audit.h index 97d0925454df..543763ab0354 100644 --- a/include/linux/audit.h +++ b/include/linux/audit.h @@ -252,6 +252,10 @@ static inline int audit_signal_info(int sig, struct task_struct *t) #define audit_is_compat(arch) false #endif +#define AUDIT_INODE_PARENT 1 /* dentry represents the parent */ +#define AUDIT_INODE_HIDDEN 2 /* audit record should be hidden */ +#define AUDIT_INODE_NOEVAL 4 /* audit record incomplete */ + #ifdef CONFIG_AUDITSYSCALL #include /* for syscall_get_arch() */ @@ -265,9 +269,6 @@ extern void __audit_syscall_exit(int ret_success, long ret_value); extern struct filename *__audit_reusename(const __user char *uptr); extern void __audit_getname(struct filename *name); -#define AUDIT_INODE_PARENT 1 /* dentry represents the parent */ -#define AUDIT_INODE_HIDDEN 2 /* audit record should be hidden */ -#define AUDIT_INODE_NOEVAL 4 /* audit record incomplete */ extern void __audit_inode(struct filename *name, const struct dentry *dentry, unsigned int flags); extern void __audit_file(const struct file *); @@ -328,16 +329,9 @@ static inline void audit_getname(struct filename *name) } static inline void audit_inode(struct filename *name, const struct dentry *dentry, - unsigned int flags) { - if (unlikely(!audit_dummy_context())) { - unsigned int aflags = 0; - - if (flags & LOOKUP_PARENT) - aflags |= AUDIT_INODE_PARENT; - if (flags & LOOKUP_NO_EVAL) - aflags |= AUDIT_INODE_NOEVAL; + unsigned int aflags) { + if (unlikely(!audit_dummy_context())) __audit_inode(name, dentry, aflags); - } } static inline void audit_file(struct file *file) { @@ -561,7 +555,7 @@ static inline void __audit_inode_child(struct inode *parent, { } static inline void audit_inode(struct filename *name, const struct dentry *dentry, - unsigned int parent) + unsigned int aflags) { } static inline void audit_file(struct file *file) { From fbb7d9d56d167247f2eb7261038385cab1073c37 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sun, 14 Jul 2019 13:24:54 -0400 Subject: [PATCH 04/11] kill LOOKUP_NO_EVAL, don't bother including namei.h from audit.h The former has no users left; the latter was only to get LOOKUP_... values to remapper in audit_inode() and that's an ex-parrot now. All places that use symbols from namei.h include it either directly or (in a few cases) via a local header, like fs/autofs/autofs_i.h Signed-off-by: Al Viro --- fs/nfs/nfstrace.h | 2 -- include/linux/audit.h | 1 - include/linux/namei.h | 2 -- 3 files changed, 5 deletions(-) diff --git a/fs/nfs/nfstrace.h b/fs/nfs/nfstrace.h index 976d4089e267..361cc10d6f95 100644 --- a/fs/nfs/nfstrace.h +++ b/fs/nfs/nfstrace.h @@ -207,7 +207,6 @@ TRACE_DEFINE_ENUM(LOOKUP_PARENT); TRACE_DEFINE_ENUM(LOOKUP_REVAL); TRACE_DEFINE_ENUM(LOOKUP_RCU); TRACE_DEFINE_ENUM(LOOKUP_NO_REVAL); -TRACE_DEFINE_ENUM(LOOKUP_NO_EVAL); TRACE_DEFINE_ENUM(LOOKUP_OPEN); TRACE_DEFINE_ENUM(LOOKUP_CREATE); TRACE_DEFINE_ENUM(LOOKUP_EXCL); @@ -226,7 +225,6 @@ TRACE_DEFINE_ENUM(LOOKUP_DOWN); { LOOKUP_REVAL, "REVAL" }, \ { LOOKUP_RCU, "RCU" }, \ { LOOKUP_NO_REVAL, "NO_REVAL" }, \ - { LOOKUP_NO_EVAL, "NO_EVAL" }, \ { LOOKUP_OPEN, "OPEN" }, \ { LOOKUP_CREATE, "CREATE" }, \ { LOOKUP_EXCL, "EXCL" }, \ diff --git a/include/linux/audit.h b/include/linux/audit.h index 543763ab0354..aee3dc9eb378 100644 --- a/include/linux/audit.h +++ b/include/linux/audit.h @@ -11,7 +11,6 @@ #include #include -#include /* LOOKUP_* */ #include #define AUDIT_INO_UNSET ((unsigned long)-1) diff --git a/include/linux/namei.h b/include/linux/namei.h index 9138b4471dbf..ac665cbc659f 100644 --- a/include/linux/namei.h +++ b/include/linux/namei.h @@ -25,7 +25,6 @@ enum {LAST_NORM, LAST_ROOT, LAST_DOT, LAST_DOTDOT, LAST_BIND}; * - dentry cache is untrusted; force a real lookup * - suppress terminal automount * - skip revalidation - * - don't fetch xattrs on audit_inode */ #define LOOKUP_FOLLOW 0x0001 #define LOOKUP_DIRECTORY 0x0002 @@ -35,7 +34,6 @@ enum {LAST_NORM, LAST_ROOT, LAST_DOT, LAST_DOTDOT, LAST_BIND}; #define LOOKUP_REVAL 0x0020 #define LOOKUP_RCU 0x0040 #define LOOKUP_NO_REVAL 0x0080 -#define LOOKUP_NO_EVAL 0x0100 /* * Intent data From 6b61aed06a3b0eb8e8d49142ddd1e101a064444d Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sun, 14 Jul 2019 14:00:23 -0400 Subject: [PATCH 05/11] namei.h: get the comments on LOOKUP_... in sync with reality Signed-off-by: Al Viro --- include/linux/namei.h | 42 ++++++++++++++++-------------------------- 1 file changed, 16 insertions(+), 26 deletions(-) diff --git a/include/linux/namei.h b/include/linux/namei.h index ac665cbc659f..1a504fc7994f 100644 --- a/include/linux/namei.h +++ b/include/linux/namei.h @@ -16,37 +16,27 @@ enum { MAX_NESTED_LINKS = 8 }; */ enum {LAST_NORM, LAST_ROOT, LAST_DOT, LAST_DOTDOT, LAST_BIND}; -/* - * The bitmask for a lookup event: - * - follow links at the end - * - require a directory - * - ending slashes ok even for nonexistent files - * - internal "there are more path components" flag - * - dentry cache is untrusted; force a real lookup - * - suppress terminal automount - * - skip revalidation - */ -#define LOOKUP_FOLLOW 0x0001 -#define LOOKUP_DIRECTORY 0x0002 -#define LOOKUP_AUTOMOUNT 0x0004 +/* pathwalk mode */ +#define LOOKUP_FOLLOW 0x0001 /* follow links at the end */ +#define LOOKUP_DIRECTORY 0x0002 /* require a directory */ +#define LOOKUP_AUTOMOUNT 0x0004 /* force terminal automount */ +#define LOOKUP_EMPTY 0x4000 /* accept empty path [user_... only] */ +#define LOOKUP_DOWN 0x8000 /* follow mounts in the starting point */ +#define LOOKUP_REVAL 0x0020 /* tell ->d_revalidate() to trust no cache */ +#define LOOKUP_RCU 0x0040 /* RCU pathwalk mode; semi-internal */ + +/* These tell filesystem methods that we are dealing with the final component... */ +#define LOOKUP_OPEN 0x0100 /* ... in open */ +#define LOOKUP_CREATE 0x0200 /* ... in object creation */ +#define LOOKUP_EXCL 0x0400 /* ... in exclusive creation */ +#define LOOKUP_RENAME_TARGET 0x0800 /* ... in destination of rename() */ + +/* internal use only */ #define LOOKUP_PARENT 0x0010 -#define LOOKUP_REVAL 0x0020 -#define LOOKUP_RCU 0x0040 #define LOOKUP_NO_REVAL 0x0080 - -/* - * Intent data - */ -#define LOOKUP_OPEN 0x0100 -#define LOOKUP_CREATE 0x0200 -#define LOOKUP_EXCL 0x0400 -#define LOOKUP_RENAME_TARGET 0x0800 - #define LOOKUP_JUMPED 0x1000 #define LOOKUP_ROOT 0x2000 -#define LOOKUP_EMPTY 0x4000 -#define LOOKUP_DOWN 0x8000 extern int path_pts(struct path *path); From ce6595a28a15c874aee374757dcd08f537d7b24d Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sun, 14 Jul 2019 16:42:44 -0400 Subject: [PATCH 06/11] kill the last users of user_{path,lpath,path_dir}() old wrappers with few callers remaining; put them out of their misery... Signed-off-by: Al Viro --- fs/coda/pioctl.c | 7 ++----- fs/namespace.c | 8 +++++--- fs/xfs/xfs_ioctl.c | 2 +- include/linux/namei.h | 16 ---------------- 4 files changed, 8 insertions(+), 25 deletions(-) diff --git a/fs/coda/pioctl.c b/fs/coda/pioctl.c index 644d48c12ce8..3aec27e5eb82 100644 --- a/fs/coda/pioctl.c +++ b/fs/coda/pioctl.c @@ -63,11 +63,8 @@ static long coda_pioctl(struct file *filp, unsigned int cmd, * Look up the pathname. Note that the pathname is in * user memory, and namei takes care of this */ - if (data.follow) - error = user_path(data.path, &path); - else - error = user_lpath(data.path, &path); - + error = user_path_at(AT_FDCWD, data.path, + data.follow ? LOOKUP_FOLLOW : 0, &path); if (error) return error; diff --git a/fs/namespace.c b/fs/namespace.c index 697f8820dff5..b73478244356 100644 --- a/fs/namespace.c +++ b/fs/namespace.c @@ -3044,7 +3044,7 @@ long do_mount(const char *dev_name, const char __user *dir_name, return -EINVAL; /* ... and get the mountpoint */ - retval = user_path(dir_name, &path); + retval = user_path_at(AT_FDCWD, dir_name, LOOKUP_FOLLOW, &path); if (retval) return retval; @@ -3591,11 +3591,13 @@ SYSCALL_DEFINE2(pivot_root, const char __user *, new_root, if (!may_mount()) return -EPERM; - error = user_path_dir(new_root, &new); + error = user_path_at(AT_FDCWD, new_root, + LOOKUP_FOLLOW | LOOKUP_DIRECTORY, &new); if (error) goto out0; - error = user_path_dir(put_old, &old); + error = user_path_at(AT_FDCWD, put_old, + LOOKUP_FOLLOW | LOOKUP_DIRECTORY, &old); if (error) goto out1; diff --git a/fs/xfs/xfs_ioctl.c b/fs/xfs/xfs_ioctl.c index 6f7848cd5527..affa557c2337 100644 --- a/fs/xfs/xfs_ioctl.c +++ b/fs/xfs/xfs_ioctl.c @@ -67,7 +67,7 @@ xfs_find_handle( return -EBADF; inode = file_inode(f.file); } else { - error = user_lpath((const char __user *)hreq->path, &path); + error = user_path_at(AT_FDCWD, hreq->path, 0, &path); if (error) return error; inode = d_inode(path.dentry); diff --git a/include/linux/namei.h b/include/linux/namei.h index 1a504fc7994f..b7993980516e 100644 --- a/include/linux/namei.h +++ b/include/linux/namei.h @@ -48,22 +48,6 @@ static inline int user_path_at(int dfd, const char __user *name, unsigned flags, return user_path_at_empty(dfd, name, flags, path, NULL); } -static inline int user_path(const char __user *name, struct path *path) -{ - return user_path_at_empty(AT_FDCWD, name, LOOKUP_FOLLOW, path, NULL); -} - -static inline int user_lpath(const char __user *name, struct path *path) -{ - return user_path_at_empty(AT_FDCWD, name, 0, path, NULL); -} - -static inline int user_path_dir(const char __user *name, struct path *path) -{ - return user_path_at_empty(AT_FDCWD, name, - LOOKUP_FOLLOW | LOOKUP_DIRECTORY, path, NULL); -} - extern int kern_path(const char *, unsigned, struct path *); extern struct dentry *kern_path_create(int, const char *, struct path *, unsigned int); From ee594bfff389aa9105f713135211c0da736e5698 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Tue, 16 Jul 2019 21:05:36 -0400 Subject: [PATCH 07/11] fs/namei.c: new helper - legitimize_root() identical logics in unlazy_walk() and unlazy_child() Signed-off-by: Al Viro --- fs/namei.c | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/fs/namei.c b/fs/namei.c index 3fca26398bc2..2af485ddc507 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -641,6 +641,13 @@ static bool legitimize_links(struct nameidata *nd) return true; } +static bool legitimize_root(struct nameidata *nd) +{ + if (!nd->root.mnt || (nd->flags & LOOKUP_ROOT)) + return true; + return legitimize_path(nd, &nd->root, nd->root_seq); +} + /* * Path walking has 2 modes, rcu-walk and ref-walk (see * Documentation/filesystems/path-lookup.txt). In situations when we can't @@ -674,10 +681,8 @@ static int unlazy_walk(struct nameidata *nd) goto out2; if (unlikely(!legitimize_path(nd, &nd->path, nd->seq))) goto out1; - if (nd->root.mnt && !(nd->flags & LOOKUP_ROOT)) { - if (unlikely(!legitimize_path(nd, &nd->root, nd->root_seq))) - goto out; - } + if (unlikely(!legitimize_root(nd))) + goto out; rcu_read_unlock(); BUG_ON(nd->inode != parent->d_inode); return 0; @@ -736,12 +741,10 @@ static int unlazy_child(struct nameidata *nd, struct dentry *dentry, unsigned se * Sequence counts matched. Now make sure that the root is * still valid and get it if required. */ - if (nd->root.mnt && !(nd->flags & LOOKUP_ROOT)) { - if (unlikely(!legitimize_path(nd, &nd->root, nd->root_seq))) { - rcu_read_unlock(); - dput(dentry); - return -ECHILD; - } + if (unlikely(!legitimize_root(nd))) { + rcu_read_unlock(); + dput(dentry); + return -ECHILD; } rcu_read_unlock(); From 84a2bd39405ffd5fa6d6d77e408c5b9210da98de Mon Sep 17 00:00:00 2001 From: Al Viro Date: Tue, 16 Jul 2019 21:20:17 -0400 Subject: [PATCH 08/11] fs/namei.c: keep track of nd->root refcount status The rules for nd->root are messy: * if we have LOOKUP_ROOT, it doesn't contribute to refcounts * if we have LOOKUP_RCU, it doesn't contribute to refcounts * if nd->root.mnt is NULL, it doesn't contribute to refcounts * otherwise it does contribute terminate_walk() needs to drop the references if they are contributing. So everything else should be careful not to confuse it, leading to rather convoluted code. It's easier to keep track of whether we'd grabbed the reference(s) explicitly. Use a new flag for that. Don't bother with zeroing nd->root.mnt on unlazy failures and in terminate_walk - it's not needed anymore (terminate_walk() won't care and the next path_init() will zero nd->root in !LOOKUP_ROOT case anyway). Resulting rules for nd->root refcounts are much simpler: they are contributing iff LOOKUP_ROOT_GRABBED is set in nd->flags. Signed-off-by: Al Viro --- fs/namei.c | 41 +++++++++++++++-------------------------- include/linux/namei.h | 1 + 2 files changed, 16 insertions(+), 26 deletions(-) diff --git a/fs/namei.c b/fs/namei.c index 2af485ddc507..671c3c1a3425 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -596,14 +596,12 @@ static void terminate_walk(struct nameidata *nd) path_put(&nd->path); for (i = 0; i < nd->depth; i++) path_put(&nd->stack[i].link); - if (nd->root.mnt && !(nd->flags & LOOKUP_ROOT)) { + if (nd->flags & LOOKUP_ROOT_GRABBED) { path_put(&nd->root); - nd->root.mnt = NULL; + nd->flags &= ~LOOKUP_ROOT_GRABBED; } } else { nd->flags &= ~LOOKUP_RCU; - if (!(nd->flags & LOOKUP_ROOT)) - nd->root.mnt = NULL; rcu_read_unlock(); } nd->depth = 0; @@ -645,6 +643,7 @@ static bool legitimize_root(struct nameidata *nd) { if (!nd->root.mnt || (nd->flags & LOOKUP_ROOT)) return true; + nd->flags |= LOOKUP_ROOT_GRABBED; return legitimize_path(nd, &nd->root, nd->root_seq); } @@ -678,21 +677,18 @@ static int unlazy_walk(struct nameidata *nd) nd->flags &= ~LOOKUP_RCU; if (unlikely(!legitimize_links(nd))) - goto out2; - if (unlikely(!legitimize_path(nd, &nd->path, nd->seq))) goto out1; + if (unlikely(!legitimize_path(nd, &nd->path, nd->seq))) + goto out; if (unlikely(!legitimize_root(nd))) goto out; rcu_read_unlock(); BUG_ON(nd->inode != parent->d_inode); return 0; -out2: +out1: nd->path.mnt = NULL; nd->path.dentry = NULL; -out1: - if (!(nd->flags & LOOKUP_ROOT)) - nd->root.mnt = NULL; out: rcu_read_unlock(); return -ECHILD; @@ -732,21 +728,14 @@ static int unlazy_child(struct nameidata *nd, struct dentry *dentry, unsigned se */ if (unlikely(!lockref_get_not_dead(&dentry->d_lockref))) goto out; - if (unlikely(read_seqcount_retry(&dentry->d_seq, seq))) { - rcu_read_unlock(); - dput(dentry); - goto drop_root_mnt; - } + if (unlikely(read_seqcount_retry(&dentry->d_seq, seq))) + goto out_dput; /* * Sequence counts matched. Now make sure that the root is * still valid and get it if required. */ - if (unlikely(!legitimize_root(nd))) { - rcu_read_unlock(); - dput(dentry); - return -ECHILD; - } - + if (unlikely(!legitimize_root(nd))) + goto out_dput; rcu_read_unlock(); return 0; @@ -756,9 +745,10 @@ out1: nd->path.dentry = NULL; out: rcu_read_unlock(); -drop_root_mnt: - if (!(nd->flags & LOOKUP_ROOT)) - nd->root.mnt = NULL; + return -ECHILD; +out_dput: + rcu_read_unlock(); + dput(dentry); return -ECHILD; } @@ -822,6 +812,7 @@ static void set_root(struct nameidata *nd) } while (read_seqcount_retry(&fs->seq, seq)); } else { get_fs_root(fs, &nd->root); + nd->flags |= LOOKUP_ROOT_GRABBED; } } @@ -1738,8 +1729,6 @@ static int pick_link(struct nameidata *nd, struct path *link, nd->flags &= ~LOOKUP_RCU; nd->path.mnt = NULL; nd->path.dentry = NULL; - if (!(nd->flags & LOOKUP_ROOT)) - nd->root.mnt = NULL; rcu_read_unlock(); } else if (likely(unlazy_walk(nd)) == 0) error = nd_alloc_stack(nd); diff --git a/include/linux/namei.h b/include/linux/namei.h index b7993980516e..397a08ade6a2 100644 --- a/include/linux/namei.h +++ b/include/linux/namei.h @@ -37,6 +37,7 @@ enum {LAST_NORM, LAST_ROOT, LAST_DOT, LAST_DOTDOT, LAST_BIND}; #define LOOKUP_NO_REVAL 0x0080 #define LOOKUP_JUMPED 0x1000 #define LOOKUP_ROOT 0x2000 +#define LOOKUP_ROOT_GRABBED 0x0008 extern int path_pts(struct path *path); From 29dfeb0b6ae6fcfbc78040bab166215020974f65 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sat, 27 Jul 2019 16:10:56 -0400 Subject: [PATCH 09/11] hypfs: don't bother with d_delete() If that's not the last reference, d_delete() will do d_drop(). If it is, dput() immediately after it will unhash the sucker anyway, since ->d_delete() the method is always_delete_dentry(). IOW, there's no point trying to turn it into a negative hashed dentry - it won't stick around anyway. Just d_drop() it and be done with that. Signed-off-by: Al Viro --- arch/s390/hypfs/inode.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/s390/hypfs/inode.c b/arch/s390/hypfs/inode.c index ccad1398abd4..a4418fc425b8 100644 --- a/arch/s390/hypfs/inode.c +++ b/arch/s390/hypfs/inode.c @@ -76,7 +76,7 @@ static void hypfs_remove(struct dentry *dentry) else simple_unlink(d_inode(parent), dentry); } - d_delete(dentry); + d_drop(dentry); dput(dentry); inode_unlock(d_inode(parent)); } From 6effcab4da7b6a579699c2d5b9c06eb2f1fb3610 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sat, 27 Jul 2019 16:14:37 -0400 Subject: [PATCH 10/11] infiniband: don't bother with d_delete() Dentries are never retained there; d_delete() + dput() is no different from d_drop() + dput(). Signed-off-by: Al Viro --- drivers/infiniband/hw/qib/qib_fs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/infiniband/hw/qib/qib_fs.c b/drivers/infiniband/hw/qib/qib_fs.c index 41a569558a15..e336d778e076 100644 --- a/drivers/infiniband/hw/qib/qib_fs.c +++ b/drivers/infiniband/hw/qib/qib_fs.c @@ -493,7 +493,7 @@ static int remove_device_files(struct super_block *sb, remove_file(dir, "flash"); inode_unlock(d_inode(dir)); ret = simple_rmdir(d_inode(root), dir); - d_delete(dir); + d_drop(dir); dput(dir); bail: From 46c46f8df9aa425cc4d6bc89d57a6fedf83dc797 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sat, 27 Jul 2019 16:29:22 -0400 Subject: [PATCH 11/11] devpts_pty_kill(): don't bother with d_delete() we are not retaining dentries there anyway (simple_dentry_operations), so d_delete()+dput() == d_drop()+dput() Signed-off-by: Al Viro --- fs/devpts/inode.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/devpts/inode.c b/fs/devpts/inode.c index beeadca23b05..42e5a766d33c 100644 --- a/fs/devpts/inode.c +++ b/fs/devpts/inode.c @@ -622,7 +622,7 @@ void devpts_pty_kill(struct dentry *dentry) dentry->d_fsdata = NULL; drop_nlink(dentry->d_inode); fsnotify_unlink(d_inode(dentry->d_parent), dentry); - d_delete(dentry); + d_drop(dentry); dput(dentry); /* d_alloc_name() in devpts_pty_new() */ }