Message ID | 20210202082353.2152271-2-dkadashev@gmail.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | io_uring: add mkdirat support | expand |
On Tue, Feb 2, 2021 at 3:25 PM Dmitry Kadashev <dkadashev@gmail.com> wrote: > > Pass in the struct filename pointers instead of the user string, and > update the three callers to do the same. This is heavily based on > commit dbea8d345177 ("fs: make do_renameat2() take struct filename"). > > This behaves like do_unlinkat() and do_renameat2(). > > Cc: Al Viro <viro@zeniv.linux.org.uk> > Signed-off-by: Dmitry Kadashev <dkadashev@gmail.com> > --- > fs/internal.h | 1 + > fs/namei.c | 25 +++++++++++++++++++------ > 2 files changed, 20 insertions(+), 6 deletions(-) > > diff --git a/fs/internal.h b/fs/internal.h > index c6c85f6ad598..b10005dfaa48 100644 > --- a/fs/internal.h > +++ b/fs/internal.h > @@ -76,6 +76,7 @@ long do_unlinkat(int dfd, struct filename *name); > int may_linkat(struct path *link); > int do_renameat2(int olddfd, struct filename *oldname, int newdfd, > struct filename *newname, unsigned int flags); > +long do_mkdirat(int dfd, struct filename *name, umode_t mode); > > /* > * namespace.c > diff --git a/fs/namei.c b/fs/namei.c > index 4cae88733a5c..3657bdf1aafc 100644 > --- a/fs/namei.c > +++ b/fs/namei.c > @@ -3431,7 +3431,7 @@ struct file *do_file_open_root(struct dentry *dentry, struct vfsmount *mnt, > return file; > } > > -static struct dentry *filename_create(int dfd, struct filename *name, > +static struct dentry *__filename_create(int dfd, struct filename *name, > struct path *path, unsigned int lookup_flags) > { > struct dentry *dentry = ERR_PTR(-EEXIST); > @@ -3487,7 +3487,6 @@ static struct dentry *filename_create(int dfd, struct filename *name, > error = err2; > goto fail; > } > - putname(name); > return dentry; > fail: > dput(dentry); > @@ -3502,6 +3501,16 @@ static struct dentry *filename_create(int dfd, struct filename *name, > return dentry; > } > > +static inline struct dentry *filename_create(int dfd, struct filename *name, > + struct path *path, unsigned int lookup_flags) > +{ > + struct dentry *res = __filename_create(dfd, name, path, lookup_flags); > + > + if (!IS_ERR(res)) > + putname(name); > + return res; > +} > + > struct dentry *kern_path_create(int dfd, const char *pathname, > struct path *path, unsigned int lookup_flags) > { > @@ -3654,15 +3663,18 @@ int vfs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) > } > EXPORT_SYMBOL(vfs_mkdir); > > -static long do_mkdirat(int dfd, const char __user *pathname, umode_t mode) > +long do_mkdirat(int dfd, struct filename *name, umode_t mode) > { > struct dentry *dentry; > struct path path; > int error; > unsigned int lookup_flags = LOOKUP_DIRECTORY; > > + if (IS_ERR(name)) > + return PTR_ERR(name); > + > retry: > - dentry = user_path_create(dfd, pathname, &path, lookup_flags); > + dentry = __filename_create(dfd, name, &path, lookup_flags); > if (IS_ERR(dentry)) > return PTR_ERR(dentry); > > @@ -3676,17 +3688,18 @@ static long do_mkdirat(int dfd, const char __user *pathname, umode_t mode) > lookup_flags |= LOOKUP_REVAL; > goto retry; > } > + putname(name); > return error; > } > > SYSCALL_DEFINE3(mkdirat, int, dfd, const char __user *, pathname, umode_t, mode) > { > - return do_mkdirat(dfd, pathname, mode); > + return do_mkdirat(dfd, getname(pathname), mode); > } > > SYSCALL_DEFINE2(mkdir, const char __user *, pathname, umode_t, mode) > { > - return do_mkdirat(AT_FDCWD, pathname, mode); > + return do_mkdirat(AT_FDCWD, getname(pathname), mode); > } > > int vfs_rmdir(struct inode *dir, struct dentry *dentry) > -- > 2.30.0 Hi Al, Are you OK with this version?
diff --git a/fs/internal.h b/fs/internal.h index c6c85f6ad598..b10005dfaa48 100644 --- a/fs/internal.h +++ b/fs/internal.h @@ -76,6 +76,7 @@ long do_unlinkat(int dfd, struct filename *name); int may_linkat(struct path *link); int do_renameat2(int olddfd, struct filename *oldname, int newdfd, struct filename *newname, unsigned int flags); +long do_mkdirat(int dfd, struct filename *name, umode_t mode); /* * namespace.c diff --git a/fs/namei.c b/fs/namei.c index 4cae88733a5c..3657bdf1aafc 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -3431,7 +3431,7 @@ struct file *do_file_open_root(struct dentry *dentry, struct vfsmount *mnt, return file; } -static struct dentry *filename_create(int dfd, struct filename *name, +static struct dentry *__filename_create(int dfd, struct filename *name, struct path *path, unsigned int lookup_flags) { struct dentry *dentry = ERR_PTR(-EEXIST); @@ -3487,7 +3487,6 @@ static struct dentry *filename_create(int dfd, struct filename *name, error = err2; goto fail; } - putname(name); return dentry; fail: dput(dentry); @@ -3502,6 +3501,16 @@ static struct dentry *filename_create(int dfd, struct filename *name, return dentry; } +static inline struct dentry *filename_create(int dfd, struct filename *name, + struct path *path, unsigned int lookup_flags) +{ + struct dentry *res = __filename_create(dfd, name, path, lookup_flags); + + if (!IS_ERR(res)) + putname(name); + return res; +} + struct dentry *kern_path_create(int dfd, const char *pathname, struct path *path, unsigned int lookup_flags) { @@ -3654,15 +3663,18 @@ int vfs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) } EXPORT_SYMBOL(vfs_mkdir); -static long do_mkdirat(int dfd, const char __user *pathname, umode_t mode) +long do_mkdirat(int dfd, struct filename *name, umode_t mode) { struct dentry *dentry; struct path path; int error; unsigned int lookup_flags = LOOKUP_DIRECTORY; + if (IS_ERR(name)) + return PTR_ERR(name); + retry: - dentry = user_path_create(dfd, pathname, &path, lookup_flags); + dentry = __filename_create(dfd, name, &path, lookup_flags); if (IS_ERR(dentry)) return PTR_ERR(dentry); @@ -3676,17 +3688,18 @@ static long do_mkdirat(int dfd, const char __user *pathname, umode_t mode) lookup_flags |= LOOKUP_REVAL; goto retry; } + putname(name); return error; } SYSCALL_DEFINE3(mkdirat, int, dfd, const char __user *, pathname, umode_t, mode) { - return do_mkdirat(dfd, pathname, mode); + return do_mkdirat(dfd, getname(pathname), mode); } SYSCALL_DEFINE2(mkdir, const char __user *, pathname, umode_t, mode) { - return do_mkdirat(AT_FDCWD, pathname, mode); + return do_mkdirat(AT_FDCWD, getname(pathname), mode); } int vfs_rmdir(struct inode *dir, struct dentry *dentry)
Pass in the struct filename pointers instead of the user string, and update the three callers to do the same. This is heavily based on commit dbea8d345177 ("fs: make do_renameat2() take struct filename"). This behaves like do_unlinkat() and do_renameat2(). Cc: Al Viro <viro@zeniv.linux.org.uk> Signed-off-by: Dmitry Kadashev <dkadashev@gmail.com> --- fs/internal.h | 1 + fs/namei.c | 25 +++++++++++++++++++------ 2 files changed, 20 insertions(+), 6 deletions(-)