filename_renameat2() replaces do_renameat2(); unlike the latter, it does not drop filename references - these days it can be just as easily arranged in the caller. Signed-off-by: Al Viro --- Documentation/filesystems/porting.rst | 8 ++++++++ fs/internal.h | 2 +- fs/namei.c | 21 +++++++++++---------- io_uring/fs.c | 7 ++++--- 4 files changed, 24 insertions(+), 14 deletions(-) diff --git a/Documentation/filesystems/porting.rst b/Documentation/filesystems/porting.rst index 3397937ed838..577f7f952a51 100644 --- a/Documentation/filesystems/porting.rst +++ b/Documentation/filesystems/porting.rst @@ -1334,3 +1334,11 @@ end_creating() and the parent will be unlocked precisely when necessary. kill_litter_super() is gone; convert to DCACHE_PERSISTENT use (as all in-tree filesystems have done). + +--- + +**mandatory** + +do_renameat2() is gone; filename_renameat2() replaces it. The difference +is that the former used to consume filename references; the latter does +not. diff --git a/fs/internal.h b/fs/internal.h index 4c4d2733c47a..5047cfbb8c93 100644 --- a/fs/internal.h +++ b/fs/internal.h @@ -57,7 +57,7 @@ extern int filename_lookup(int dfd, struct filename *name, unsigned flags, int do_rmdir(int dfd, struct filename *name); int do_unlinkat(int dfd, struct filename *name); int may_linkat(struct mnt_idmap *idmap, const struct path *link); -int do_renameat2(int olddfd, struct filename *oldname, int newdfd, +int filename_renameat2(int olddfd, struct filename *oldname, int newdfd, struct filename *newname, unsigned int flags); int do_mkdirat(int dfd, struct filename *name, umode_t mode); int do_mknodat(int dfd, struct filename *name, umode_t mode, unsigned int dev); diff --git a/fs/namei.c b/fs/namei.c index 7418a4e725da..c54beaf193e0 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -5980,11 +5980,9 @@ int vfs_rename(struct renamedata *rd) } EXPORT_SYMBOL(vfs_rename); -int do_renameat2(int olddfd, struct filename *__from, int newdfd, - struct filename *__to, unsigned int flags) +int filename_renameat2(int olddfd, struct filename *from, + int newdfd, struct filename *to, unsigned int flags) { - CLASS(filename_consume, from)(__from); - CLASS(filename_consume, to)(__to); struct renamedata rd; struct path old_path, new_path; struct qstr old_last, new_last; @@ -6088,21 +6086,24 @@ int do_renameat2(int olddfd, struct filename *__from, int newdfd, SYSCALL_DEFINE5(renameat2, int, olddfd, const char __user *, oldname, int, newdfd, const char __user *, newname, unsigned int, flags) { - return do_renameat2(olddfd, getname(oldname), newdfd, getname(newname), - flags); + CLASS(filename, old)(oldname); + CLASS(filename, new)(newname); + return filename_renameat2(olddfd, old, newdfd, new, flags); } SYSCALL_DEFINE4(renameat, int, olddfd, const char __user *, oldname, int, newdfd, const char __user *, newname) { - return do_renameat2(olddfd, getname(oldname), newdfd, getname(newname), - 0); + CLASS(filename, old)(oldname); + CLASS(filename, new)(newname); + return filename_renameat2(olddfd, old, newdfd, new, 0); } SYSCALL_DEFINE2(rename, const char __user *, oldname, const char __user *, newname) { - return do_renameat2(AT_FDCWD, getname(oldname), AT_FDCWD, - getname(newname), 0); + CLASS(filename, old)(oldname); + CLASS(filename, new)(newname); + return filename_renameat2(AT_FDCWD, old, AT_FDCWD, new, 0); } int readlink_copy(char __user *buffer, int buflen, const char *link, int linklen) diff --git a/io_uring/fs.c b/io_uring/fs.c index c04c6282210a..e5829d112c9e 100644 --- a/io_uring/fs.c +++ b/io_uring/fs.c @@ -82,13 +82,14 @@ int io_renameat_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe) int io_renameat(struct io_kiocb *req, unsigned int issue_flags) { struct io_rename *ren = io_kiocb_to_cmd(req, struct io_rename); + CLASS(filename_complete_delayed, old)(&ren->oldpath); + CLASS(filename_complete_delayed, new)(&ren->newpath); int ret; WARN_ON_ONCE(issue_flags & IO_URING_F_NONBLOCK); - ret = do_renameat2(ren->old_dfd, complete_getname(&ren->oldpath), - ren->new_dfd, complete_getname(&ren->newpath), - ren->flags); + ret = filename_renameat2(ren->old_dfd, old, + ren->new_dfd, new, ren->flags); req->flags &= ~REQ_F_NEED_CLEANUP; io_req_set_res(req, ret, 0); -- 2.47.3 similar to previous commit; replacement is filename_linkat() Signed-off-by: Al Viro --- Documentation/filesystems/porting.rst | 6 +++--- fs/init.c | 5 +++-- fs/internal.h | 2 +- fs/namei.c | 17 +++++++++-------- io_uring/fs.c | 5 +++-- 5 files changed, 19 insertions(+), 16 deletions(-) diff --git a/Documentation/filesystems/porting.rst b/Documentation/filesystems/porting.rst index 577f7f952a51..8ecbc41d6d82 100644 --- a/Documentation/filesystems/porting.rst +++ b/Documentation/filesystems/porting.rst @@ -1339,6 +1339,6 @@ in-tree filesystems have done). **mandatory** -do_renameat2() is gone; filename_renameat2() replaces it. The difference -is that the former used to consume filename references; the latter does -not. +do_{link,renameat2}() are gone; filename_{link,renameat2}() replaces those. +The difference is that the former used to consume filename references; +the latter do not. diff --git a/fs/init.c b/fs/init.c index da6500d2ee98..f46e54552931 100644 --- a/fs/init.c +++ b/fs/init.c @@ -145,8 +145,9 @@ int __init init_mknod(const char *filename, umode_t mode, unsigned int dev) int __init init_link(const char *oldname, const char *newname) { - return do_linkat(AT_FDCWD, getname_kernel(oldname), - AT_FDCWD, getname_kernel(newname), 0); + CLASS(filename_kernel, old)(oldname); + CLASS(filename_kernel, new)(newname); + return filename_linkat(AT_FDCWD, old, AT_FDCWD, new, 0); } int __init init_symlink(const char *oldname, const char *newname) diff --git a/fs/internal.h b/fs/internal.h index 5047cfbb8c93..c9b70c2716d1 100644 --- a/fs/internal.h +++ b/fs/internal.h @@ -62,7 +62,7 @@ int filename_renameat2(int olddfd, struct filename *oldname, int newdfd, int do_mkdirat(int dfd, struct filename *name, umode_t mode); int do_mknodat(int dfd, struct filename *name, umode_t mode, unsigned int dev); int do_symlinkat(struct filename *from, int newdfd, struct filename *to); -int do_linkat(int olddfd, struct filename *old, int newdfd, +int filename_linkat(int olddfd, struct filename *old, int newdfd, struct filename *new, int flags); int vfs_tmpfile(struct mnt_idmap *idmap, const struct path *parentpath, diff --git a/fs/namei.c b/fs/namei.c index c54beaf193e0..1f003ac9470e 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -5685,12 +5685,10 @@ EXPORT_SYMBOL(vfs_link); * We don't follow them on the oldname either to be compatible * with linux 2.0, and to avoid hard-linking to directories * and other special files. --ADM - */ -int do_linkat(int olddfd, struct filename *__old, int newdfd, - struct filename *__new, int flags) +*/ +int filename_linkat(int olddfd, struct filename *old, + int newdfd, struct filename *new, int flags) { - CLASS(filename_consume, old)(__old); - CLASS(filename_consume, new)(__new); struct mnt_idmap *idmap; struct dentry *new_dentry; struct path old_path, new_path; @@ -5756,13 +5754,16 @@ int do_linkat(int olddfd, struct filename *__old, int newdfd, SYSCALL_DEFINE5(linkat, int, olddfd, const char __user *, oldname, int, newdfd, const char __user *, newname, int, flags) { - return do_linkat(olddfd, getname_uflags(oldname, flags), - newdfd, getname(newname), flags); + CLASS(filename_uflags, old)(oldname, flags); + CLASS(filename, new)(newname); + return filename_linkat(olddfd, old, newdfd, new, flags); } SYSCALL_DEFINE2(link, const char __user *, oldname, const char __user *, newname) { - return do_linkat(AT_FDCWD, getname(oldname), AT_FDCWD, getname(newname), 0); + CLASS(filename, old)(oldname); + CLASS(filename, new)(newname); + return filename_linkat(AT_FDCWD, old, AT_FDCWD, new, 0); } /** diff --git a/io_uring/fs.c b/io_uring/fs.c index e5829d112c9e..e39cd1ca1942 100644 --- a/io_uring/fs.c +++ b/io_uring/fs.c @@ -280,12 +280,13 @@ int io_linkat_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe) int io_linkat(struct io_kiocb *req, unsigned int issue_flags) { struct io_link *lnk = io_kiocb_to_cmd(req, struct io_link); + CLASS(filename_complete_delayed, old)(&lnk->oldpath); + CLASS(filename_complete_delayed, new)(&lnk->newpath); int ret; WARN_ON_ONCE(issue_flags & IO_URING_F_NONBLOCK); - ret = do_linkat(lnk->old_dfd, complete_getname(&lnk->oldpath), - lnk->new_dfd, complete_getname(&lnk->newpath), lnk->flags); + ret = filename_linkat(lnk->old_dfd, old, lnk->new_dfd, new, lnk->flags); req->flags &= ~REQ_F_NEED_CLEANUP; io_req_set_res(req, ret, 0); -- 2.47.3 similar to previous commit; replacement is filename_symlinkat() Signed-off-by: Al Viro --- Documentation/filesystems/porting.rst | 6 +++--- fs/init.c | 5 +++-- fs/internal.h | 2 +- fs/namei.c | 12 +++++++----- io_uring/fs.c | 5 +++-- 5 files changed, 17 insertions(+), 13 deletions(-) diff --git a/Documentation/filesystems/porting.rst b/Documentation/filesystems/porting.rst index 8ecbc41d6d82..c44c351bc297 100644 --- a/Documentation/filesystems/porting.rst +++ b/Documentation/filesystems/porting.rst @@ -1339,6 +1339,6 @@ in-tree filesystems have done). **mandatory** -do_{link,renameat2}() are gone; filename_{link,renameat2}() replaces those. -The difference is that the former used to consume filename references; -the latter do not. +do_{link,symlink,renameat2}() are gone; filename_...() counterparts +replace those. The difference is that the former used to consume +filename references; the latter do not. diff --git a/fs/init.c b/fs/init.c index f46e54552931..a54ef750ffe3 100644 --- a/fs/init.c +++ b/fs/init.c @@ -152,8 +152,9 @@ int __init init_link(const char *oldname, const char *newname) int __init init_symlink(const char *oldname, const char *newname) { - return do_symlinkat(getname_kernel(oldname), AT_FDCWD, - getname_kernel(newname)); + CLASS(filename_kernel, old)(oldname); + CLASS(filename_kernel, new)(newname); + return filename_symlinkat(old, AT_FDCWD, new); } int __init init_unlink(const char *pathname) diff --git a/fs/internal.h b/fs/internal.h index c9b70c2716d1..4a63b89c02d7 100644 --- a/fs/internal.h +++ b/fs/internal.h @@ -61,7 +61,7 @@ int filename_renameat2(int olddfd, struct filename *oldname, int newdfd, struct filename *newname, unsigned int flags); int do_mkdirat(int dfd, struct filename *name, umode_t mode); int do_mknodat(int dfd, struct filename *name, umode_t mode, unsigned int dev); -int do_symlinkat(struct filename *from, int newdfd, struct filename *to); +int filename_symlinkat(struct filename *from, int newdfd, struct filename *to); int filename_linkat(int olddfd, struct filename *old, int newdfd, struct filename *new, int flags); int vfs_tmpfile(struct mnt_idmap *idmap, diff --git a/fs/namei.c b/fs/namei.c index 1f003ac9470e..338e2934c520 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -5541,10 +5541,8 @@ int vfs_symlink(struct mnt_idmap *idmap, struct inode *dir, } EXPORT_SYMBOL(vfs_symlink); -int do_symlinkat(struct filename *__from, int newdfd, struct filename *__to) +int filename_symlinkat(struct filename *from, int newdfd, struct filename *to) { - CLASS(filename_consume, from)(__from); - CLASS(filename_consume, to)(__to); int error; struct dentry *dentry; struct path path; @@ -5578,12 +5576,16 @@ int do_symlinkat(struct filename *__from, int newdfd, struct filename *__to) SYSCALL_DEFINE3(symlinkat, const char __user *, oldname, int, newdfd, const char __user *, newname) { - return do_symlinkat(getname(oldname), newdfd, getname(newname)); + CLASS(filename, old)(oldname); + CLASS(filename, new)(newname); + return filename_symlinkat(old, newdfd, new); } SYSCALL_DEFINE2(symlink, const char __user *, oldname, const char __user *, newname) { - return do_symlinkat(getname(oldname), AT_FDCWD, getname(newname)); + CLASS(filename, old)(oldname); + CLASS(filename, new)(newname); + return filename_symlinkat(old, AT_FDCWD, new); } /** diff --git a/io_uring/fs.c b/io_uring/fs.c index e39cd1ca1942..cd4d88d37795 100644 --- a/io_uring/fs.c +++ b/io_uring/fs.c @@ -233,12 +233,13 @@ int io_symlinkat_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe) int io_symlinkat(struct io_kiocb *req, unsigned int issue_flags) { struct io_link *sl = io_kiocb_to_cmd(req, struct io_link); + CLASS(filename_complete_delayed, old)(&sl->oldpath); + CLASS(filename_complete_delayed, new)(&sl->newpath); int ret; WARN_ON_ONCE(issue_flags & IO_URING_F_NONBLOCK); - ret = do_symlinkat(complete_getname(&sl->oldpath), sl->new_dfd, - complete_getname(&sl->newpath)); + ret = filename_symlinkat(old, sl->new_dfd, new); req->flags &= ~REQ_F_NEED_CLEANUP; io_req_set_res(req, ret, 0); -- 2.47.3 similar to previous commit; replacement is filename_mkdirat() Signed-off-by: Al Viro --- Documentation/filesystems/porting.rst | 2 +- fs/init.c | 3 ++- fs/internal.h | 2 +- fs/namei.c | 9 +++++---- io_uring/fs.c | 3 ++- 5 files changed, 11 insertions(+), 8 deletions(-) diff --git a/Documentation/filesystems/porting.rst b/Documentation/filesystems/porting.rst index c44c351bc297..ace0607fe39c 100644 --- a/Documentation/filesystems/porting.rst +++ b/Documentation/filesystems/porting.rst @@ -1339,6 +1339,6 @@ in-tree filesystems have done). **mandatory** -do_{link,symlink,renameat2}() are gone; filename_...() counterparts +do_{mkdir,link,symlink,renameat2}() are gone; filename_...() counterparts replace those. The difference is that the former used to consume filename references; the latter do not. diff --git a/fs/init.c b/fs/init.c index a54ef750ffe3..9a550ba4802f 100644 --- a/fs/init.c +++ b/fs/init.c @@ -164,7 +164,8 @@ int __init init_unlink(const char *pathname) int __init init_mkdir(const char *pathname, umode_t mode) { - return do_mkdirat(AT_FDCWD, getname_kernel(pathname), mode); + CLASS(filename_kernel, name)(pathname); + return filename_mkdirat(AT_FDCWD, name, mode); } int __init init_rmdir(const char *pathname) diff --git a/fs/internal.h b/fs/internal.h index 4a63b89c02d7..03638008d84a 100644 --- a/fs/internal.h +++ b/fs/internal.h @@ -59,7 +59,7 @@ int do_unlinkat(int dfd, struct filename *name); int may_linkat(struct mnt_idmap *idmap, const struct path *link); int filename_renameat2(int olddfd, struct filename *oldname, int newdfd, struct filename *newname, unsigned int flags); -int do_mkdirat(int dfd, struct filename *name, umode_t mode); +int filename_mkdirat(int dfd, struct filename *name, umode_t mode); int do_mknodat(int dfd, struct filename *name, umode_t mode, unsigned int dev); int filename_symlinkat(struct filename *from, int newdfd, struct filename *to); int filename_linkat(int olddfd, struct filename *old, int newdfd, diff --git a/fs/namei.c b/fs/namei.c index 338e2934c520..e3252d4abce4 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -5171,9 +5171,8 @@ struct dentry *vfs_mkdir(struct mnt_idmap *idmap, struct inode *dir, } EXPORT_SYMBOL(vfs_mkdir); -int do_mkdirat(int dfd, struct filename *__name, umode_t mode) +int filename_mkdirat(int dfd, struct filename *name, umode_t mode) { - CLASS(filename_consume, name)(__name); struct dentry *dentry; struct path path; int error; @@ -5208,12 +5207,14 @@ int do_mkdirat(int dfd, struct filename *__name, umode_t mode) SYSCALL_DEFINE3(mkdirat, int, dfd, const char __user *, pathname, umode_t, mode) { - return do_mkdirat(dfd, getname(pathname), mode); + CLASS(filename, name)(pathname); + return filename_mkdirat(dfd, name, mode); } SYSCALL_DEFINE2(mkdir, const char __user *, pathname, umode_t, mode) { - return do_mkdirat(AT_FDCWD, getname(pathname), mode); + CLASS(filename, name)(pathname); + return filename_mkdirat(AT_FDCWD, name, mode); } /** diff --git a/io_uring/fs.c b/io_uring/fs.c index cd4d88d37795..40541b539e0d 100644 --- a/io_uring/fs.c +++ b/io_uring/fs.c @@ -182,11 +182,12 @@ int io_mkdirat_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe) int io_mkdirat(struct io_kiocb *req, unsigned int issue_flags) { struct io_mkdir *mkd = io_kiocb_to_cmd(req, struct io_mkdir); + CLASS(filename_complete_delayed, name)(&mkd->filename); int ret; WARN_ON_ONCE(issue_flags & IO_URING_F_NONBLOCK); - ret = do_mkdirat(mkd->dfd, complete_getname(&mkd->filename), mkd->mode); + ret = filename_mkdirat(mkd->dfd, name, mkd->mode); req->flags &= ~REQ_F_NEED_CLEANUP; io_req_set_res(req, ret, 0); -- 2.47.3 similar to previous commit; replacement is filename_mknodat() Signed-off-by: Al Viro --- Documentation/filesystems/porting.rst | 6 +++--- fs/init.c | 3 ++- fs/internal.h | 2 +- fs/namei.c | 11 ++++++----- 4 files changed, 12 insertions(+), 10 deletions(-) diff --git a/Documentation/filesystems/porting.rst b/Documentation/filesystems/porting.rst index ace0607fe39c..7e68a148dd1e 100644 --- a/Documentation/filesystems/porting.rst +++ b/Documentation/filesystems/porting.rst @@ -1339,6 +1339,6 @@ in-tree filesystems have done). **mandatory** -do_{mkdir,link,symlink,renameat2}() are gone; filename_...() counterparts -replace those. The difference is that the former used to consume -filename references; the latter do not. +do_{mkdir,mknod,link,symlink,renameat2}() are gone; filename_...() +counterparts replace those. The difference is that the former used +to consume filename references; the latter do not. diff --git a/fs/init.c b/fs/init.c index 9a550ba4802f..543444c1d79e 100644 --- a/fs/init.c +++ b/fs/init.c @@ -140,7 +140,8 @@ int __init init_stat(const char *filename, struct kstat *stat, int flags) int __init init_mknod(const char *filename, umode_t mode, unsigned int dev) { - return do_mknodat(AT_FDCWD, getname_kernel(filename), mode, dev); + CLASS(filename_kernel, name)(filename); + return filename_mknodat(AT_FDCWD, name, mode, dev); } int __init init_link(const char *oldname, const char *newname) diff --git a/fs/internal.h b/fs/internal.h index 03638008d84a..02b5dec13ff3 100644 --- a/fs/internal.h +++ b/fs/internal.h @@ -60,7 +60,7 @@ int may_linkat(struct mnt_idmap *idmap, const struct path *link); int filename_renameat2(int olddfd, struct filename *oldname, int newdfd, struct filename *newname, unsigned int flags); int filename_mkdirat(int dfd, struct filename *name, umode_t mode); -int do_mknodat(int dfd, struct filename *name, umode_t mode, unsigned int dev); +int filename_mknodat(int dfd, struct filename *name, umode_t mode, unsigned int dev); int filename_symlinkat(struct filename *from, int newdfd, struct filename *to); int filename_linkat(int olddfd, struct filename *old, int newdfd, struct filename *new, int flags); diff --git a/fs/namei.c b/fs/namei.c index e3252d4abce4..1aa19dde50e4 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -5038,10 +5038,9 @@ static int may_mknod(umode_t mode) } } -int do_mknodat(int dfd, struct filename *__name, umode_t mode, - unsigned int dev) +int filename_mknodat(int dfd, struct filename *name, umode_t mode, + unsigned int dev) { - CLASS(filename_consume, name)(__name); struct delegated_inode di = { }; struct mnt_idmap *idmap; struct dentry *dentry; @@ -5095,12 +5094,14 @@ int do_mknodat(int dfd, struct filename *__name, umode_t mode, SYSCALL_DEFINE4(mknodat, int, dfd, const char __user *, filename, umode_t, mode, unsigned int, dev) { - return do_mknodat(dfd, getname(filename), mode, dev); + CLASS(filename, name)(filename); + return filename_mknodat(dfd, name, mode, dev); } SYSCALL_DEFINE3(mknod, const char __user *, filename, umode_t, mode, unsigned, dev) { - return do_mknodat(AT_FDCWD, getname(filename), mode, dev); + CLASS(filename, name)(filename); + return filename_mknodat(AT_FDCWD, name, mode, dev); } /** -- 2.47.3 similar to previous commit; replacements are filename_{unlinkat,rmdir}() Signed-off-by: Al Viro --- Documentation/filesystems/porting.rst | 6 +++--- fs/coredump.c | 3 ++- fs/init.c | 6 ++++-- fs/internal.h | 4 ++-- fs/namei.c | 17 +++++++++-------- io_uring/fs.c | 5 +++-- 6 files changed, 23 insertions(+), 18 deletions(-) diff --git a/Documentation/filesystems/porting.rst b/Documentation/filesystems/porting.rst index 7e68a148dd1e..2b4dddfe6c66 100644 --- a/Documentation/filesystems/porting.rst +++ b/Documentation/filesystems/porting.rst @@ -1339,6 +1339,6 @@ in-tree filesystems have done). **mandatory** -do_{mkdir,mknod,link,symlink,renameat2}() are gone; filename_...() -counterparts replace those. The difference is that the former used -to consume filename references; the latter do not. +do_{mkdir,mknod,link,symlink,renameat2,rmdir,unlink}() are gone; filename_...() +counterparts replace those. The difference is that the former used to consume +filename references; the latter do not. diff --git a/fs/coredump.c b/fs/coredump.c index 8feb9c1cf83d..d9597610a6ca 100644 --- a/fs/coredump.c +++ b/fs/coredump.c @@ -895,11 +895,12 @@ static bool coredump_file(struct core_name *cn, struct coredump_params *cprm, * privs and don't want to unlink another user's coredump. */ if (!coredump_force_suid_safe(cprm)) { + CLASS(filename_kernel, name)(cn->corename); /* * If it doesn't exist, that's fine. If there's some * other problem, we'll catch it at the filp_open(). */ - do_unlinkat(AT_FDCWD, getname_kernel(cn->corename)); + filename_unlinkat(AT_FDCWD, name); } /* diff --git a/fs/init.c b/fs/init.c index 543444c1d79e..ea528b020cd1 100644 --- a/fs/init.c +++ b/fs/init.c @@ -160,7 +160,8 @@ int __init init_symlink(const char *oldname, const char *newname) int __init init_unlink(const char *pathname) { - return do_unlinkat(AT_FDCWD, getname_kernel(pathname)); + CLASS(filename_kernel, name)(pathname); + return filename_unlinkat(AT_FDCWD, name); } int __init init_mkdir(const char *pathname, umode_t mode) @@ -171,7 +172,8 @@ int __init init_mkdir(const char *pathname, umode_t mode) int __init init_rmdir(const char *pathname) { - return do_rmdir(AT_FDCWD, getname_kernel(pathname)); + CLASS(filename_kernel, name)(pathname); + return filename_rmdir(AT_FDCWD, name); } int __init init_utimes(char *filename, struct timespec64 *ts) diff --git a/fs/internal.h b/fs/internal.h index 02b5dec13ff3..4821f8b8fdda 100644 --- a/fs/internal.h +++ b/fs/internal.h @@ -54,8 +54,8 @@ extern int finish_clean_context(struct fs_context *fc); */ extern int filename_lookup(int dfd, struct filename *name, unsigned flags, struct path *path, const struct path *root); -int do_rmdir(int dfd, struct filename *name); -int do_unlinkat(int dfd, struct filename *name); +int filename_rmdir(int dfd, struct filename *name); +int filename_unlinkat(int dfd, struct filename *name); int may_linkat(struct mnt_idmap *idmap, const struct path *link); int filename_renameat2(int olddfd, struct filename *oldname, int newdfd, struct filename *newname, unsigned int flags); diff --git a/fs/namei.c b/fs/namei.c index 1aa19dde50e4..42b33bb0f892 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -5278,9 +5278,8 @@ int vfs_rmdir(struct mnt_idmap *idmap, struct inode *dir, } EXPORT_SYMBOL(vfs_rmdir); -int do_rmdir(int dfd, struct filename *__name) +int filename_rmdir(int dfd, struct filename *name) { - CLASS(filename_consume, name)(__name); int error; struct dentry *dentry; struct path path; @@ -5338,7 +5337,8 @@ int do_rmdir(int dfd, struct filename *__name) SYSCALL_DEFINE1(rmdir, const char __user *, pathname) { - return do_rmdir(AT_FDCWD, getname(pathname)); + CLASS(filename, name)(pathname); + return filename_rmdir(AT_FDCWD, name); } /** @@ -5420,9 +5420,8 @@ EXPORT_SYMBOL(vfs_unlink); * writeout happening, and we don't want to prevent access to the directory * while waiting on the I/O. */ -int do_unlinkat(int dfd, struct filename *__name) +int filename_unlinkat(int dfd, struct filename *name) { - CLASS(filename_consume, name)(__name); int error; struct dentry *dentry; struct path path; @@ -5489,14 +5488,16 @@ SYSCALL_DEFINE3(unlinkat, int, dfd, const char __user *, pathname, int, flag) if ((flag & ~AT_REMOVEDIR) != 0) return -EINVAL; + CLASS(filename, name)(pathname); if (flag & AT_REMOVEDIR) - return do_rmdir(dfd, getname(pathname)); - return do_unlinkat(dfd, getname(pathname)); + return filename_rmdir(dfd, name); + return filename_unlinkat(dfd, name); } SYSCALL_DEFINE1(unlink, const char __user *, pathname) { - return do_unlinkat(AT_FDCWD, getname(pathname)); + CLASS(filename, name)(pathname); + return filename_unlinkat(AT_FDCWD, name); } /** diff --git a/io_uring/fs.c b/io_uring/fs.c index 40541b539e0d..d0580c754bf8 100644 --- a/io_uring/fs.c +++ b/io_uring/fs.c @@ -134,14 +134,15 @@ int io_unlinkat_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe) int io_unlinkat(struct io_kiocb *req, unsigned int issue_flags) { struct io_unlink *un = io_kiocb_to_cmd(req, struct io_unlink); + CLASS(filename_complete_delayed, name)(&un->filename); int ret; WARN_ON_ONCE(issue_flags & IO_URING_F_NONBLOCK); if (un->flags & AT_REMOVEDIR) - ret = do_rmdir(un->dfd, complete_getname(&un->filename)); + ret = filename_rmdir(un->dfd, name); else - ret = do_unlinkat(un->dfd, complete_getname(&un->filename)); + ret = filename_unlinkat(un->dfd, name); req->flags &= ~REQ_F_NEED_CLEANUP; io_req_set_res(req, ret, 0); -- 2.47.3 All of them are wrappers for do_execveat_common() and each has exactly one caller. The only difference is in the way they are constructing argv/envp arguments for do_execveat_common() and that's easy to do with less boilerplate. Signed-off-by: Al Viro --- fs/exec.c | 80 +++++++++++++------------------------------------------ 1 file changed, 19 insertions(+), 61 deletions(-) diff --git a/fs/exec.c b/fs/exec.c index 902561a878ff..4e192d7b7e71 100644 --- a/fs/exec.c +++ b/fs/exec.c @@ -1893,59 +1893,6 @@ int kernel_execve(const char *kernel_filename, return bprm_execve(bprm); } -static int do_execve(struct filename *filename, - const char __user *const __user *__argv, - const char __user *const __user *__envp) -{ - struct user_arg_ptr argv = { .ptr.native = __argv }; - struct user_arg_ptr envp = { .ptr.native = __envp }; - return do_execveat_common(AT_FDCWD, filename, argv, envp, 0); -} - -static int do_execveat(int fd, struct filename *filename, - const char __user *const __user *__argv, - const char __user *const __user *__envp, - int flags) -{ - struct user_arg_ptr argv = { .ptr.native = __argv }; - struct user_arg_ptr envp = { .ptr.native = __envp }; - - return do_execveat_common(fd, filename, argv, envp, flags); -} - -#ifdef CONFIG_COMPAT -static int compat_do_execve(struct filename *filename, - const compat_uptr_t __user *__argv, - const compat_uptr_t __user *__envp) -{ - struct user_arg_ptr argv = { - .is_compat = true, - .ptr.compat = __argv, - }; - struct user_arg_ptr envp = { - .is_compat = true, - .ptr.compat = __envp, - }; - return do_execveat_common(AT_FDCWD, filename, argv, envp, 0); -} - -static int compat_do_execveat(int fd, struct filename *filename, - const compat_uptr_t __user *__argv, - const compat_uptr_t __user *__envp, - int flags) -{ - struct user_arg_ptr argv = { - .is_compat = true, - .ptr.compat = __argv, - }; - struct user_arg_ptr envp = { - .is_compat = true, - .ptr.compat = __envp, - }; - return do_execveat_common(fd, filename, argv, envp, flags); -} -#endif - void set_binfmt(struct linux_binfmt *new) { struct mm_struct *mm = current->mm; @@ -1970,12 +1917,18 @@ void set_dumpable(struct mm_struct *mm, int value) __mm_flags_set_mask_dumpable(mm, value); } +static inline struct user_arg_ptr native_arg(const char __user *const __user *p) +{ + return (struct user_arg_ptr){.ptr.native = p}; +} + SYSCALL_DEFINE3(execve, const char __user *, filename, const char __user *const __user *, argv, const char __user *const __user *, envp) { - return do_execve(getname(filename), argv, envp); + return do_execveat_common(AT_FDCWD, getname(filename), + native_arg(argv), native_arg(envp), 0); } SYSCALL_DEFINE5(execveat, @@ -1984,17 +1937,23 @@ SYSCALL_DEFINE5(execveat, const char __user *const __user *, envp, int, flags) { - return do_execveat(fd, - getname_uflags(filename, flags), - argv, envp, flags); + return do_execveat_common(fd, getname_uflags(filename, flags), + native_arg(argv), native_arg(envp), flags); } #ifdef CONFIG_COMPAT + +static inline struct user_arg_ptr compat_arg(const compat_uptr_t __user *p) +{ + return (struct user_arg_ptr){.is_compat = true, .ptr.compat = p}; +} + COMPAT_SYSCALL_DEFINE3(execve, const char __user *, filename, const compat_uptr_t __user *, argv, const compat_uptr_t __user *, envp) { - return compat_do_execve(getname(filename), argv, envp); + return do_execveat_common(AT_FDCWD, getname(filename), + compat_arg(argv), compat_arg(envp), 0); } COMPAT_SYSCALL_DEFINE5(execveat, int, fd, @@ -2003,9 +1962,8 @@ COMPAT_SYSCALL_DEFINE5(execveat, int, fd, const compat_uptr_t __user *, envp, int, flags) { - return compat_do_execveat(fd, - getname_uflags(filename, flags), - argv, envp, flags); + return do_execveat_common(fd, getname_uflags(filename, flags), + compat_arg(argv), compat_arg(envp), flags); } #endif -- 2.47.3 ... and convert its callers to CLASS(filename...) Signed-off-by: Al Viro --- fs/exec.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/fs/exec.c b/fs/exec.c index 4e192d7b7e71..3405c754da80 100644 --- a/fs/exec.c +++ b/fs/exec.c @@ -1775,12 +1775,11 @@ static int bprm_execve(struct linux_binprm *bprm) return retval; } -static int do_execveat_common(int fd, struct filename *__filename, +static int do_execveat_common(int fd, struct filename *filename, struct user_arg_ptr argv, struct user_arg_ptr envp, int flags) { - CLASS(filename_consume, filename)(__filename); int retval; /* @@ -1927,7 +1926,8 @@ SYSCALL_DEFINE3(execve, const char __user *const __user *, argv, const char __user *const __user *, envp) { - return do_execveat_common(AT_FDCWD, getname(filename), + CLASS(filename, name)(filename); + return do_execveat_common(AT_FDCWD, name, native_arg(argv), native_arg(envp), 0); } @@ -1937,7 +1937,8 @@ SYSCALL_DEFINE5(execveat, const char __user *const __user *, envp, int, flags) { - return do_execveat_common(fd, getname_uflags(filename, flags), + CLASS(filename_uflags, name)(filename, flags); + return do_execveat_common(fd, name, native_arg(argv), native_arg(envp), flags); } @@ -1952,7 +1953,8 @@ COMPAT_SYSCALL_DEFINE3(execve, const char __user *, filename, const compat_uptr_t __user *, argv, const compat_uptr_t __user *, envp) { - return do_execveat_common(AT_FDCWD, getname(filename), + CLASS(filename, name)(filename); + return do_execveat_common(AT_FDCWD, name, compat_arg(argv), compat_arg(envp), 0); } @@ -1962,7 +1964,8 @@ COMPAT_SYSCALL_DEFINE5(execveat, int, fd, const compat_uptr_t __user *, envp, int, flags) { - return do_execveat_common(fd, getname_uflags(filename, flags), + CLASS(filename_uflags, name)(filename, flags); + return do_execveat_common(fd, name, compat_arg(argv), compat_arg(envp), flags); } #endif -- 2.47.3