Re: [PATCH v2 24/36] fs: add ksys_unlink() wrapper; remove in-kernel calls to sys_unlink()

From: Dominik Brodowski
Date: Sat Mar 17 2018 - 13:22:38 EST


On Thu, Mar 15, 2018 at 09:21:39PM +0100, Arnd Bergmann wrote:
> On Thu, Mar 15, 2018 at 8:05 PM, Dominik Brodowski
> <linux@xxxxxxxxxxxxxxxxxxxx> wrote:
> > Using this wrapper allows us to avoid the in-kernel calls to the
> > sys_unlink() syscall.
> >
> > Cc: Al Viro <viro@xxxxxxxxxxxxxxxxxx>
> > Cc: Andrew Morton <akpm@xxxxxxxxxxxxxxxxxxxx>
> > Signed-off-by: Dominik Brodowski <linux@xxxxxxxxxxxxxxxxxxxx>
> > ---
> > include/linux/syscalls.h | 11 +++++++++++
> > init/do_mounts.h | 2 +-
> > init/do_mounts_initrd.c | 4 ++--
> > init/do_mounts_rd.c | 2 +-
> > init/initramfs.c | 4 ++--
> > 5 files changed, 17 insertions(+), 6 deletions(-)
> >
> > diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h
> > index 8f0f99702e7a..31aea3873de7 100644
> > --- a/include/linux/syscalls.h
> > +++ b/include/linux/syscalls.h
> > @@ -971,4 +971,15 @@ int ksys_chdir(const char __user *filename);
> > int ksys_sync_file_range(int fd, loff_t offset, loff_t nbytes,
> > unsigned int flags);
> >
> > +/*
> > + * The following kernel syscall equivalents are just wrappers to fs-internal
> > + * functions. Therefore, provide stubs to be inlined at the callsites.
> > + */
> > +extern long do_unlinkat(int dfd, struct filename *name);
> > +
> > +static inline long ksys_unlink(const char __user *pathname)
> > +{
> > + return do_unlinkat(AT_FDCWD, getname(pathname));
> > +}
>
> Why does this take a __user pointer?
>
> > static inline int create_dev(char *name, dev_t dev)
> > {
> > - sys_unlink(name);
> > + ksys_unlink(name);
> > return sys_mknod(name, S_IFBLK|0600, new_encode_dev(dev));
> > }
> >
> > diff --git a/init/do_mounts_initrd.c b/init/do_mounts_initrd.c
> > index c19d9070134e..784576b633fd 100644
> > --- a/init/do_mounts_initrd.c
> > +++ b/init/do_mounts_initrd.c
> > @@ -128,11 +128,11 @@ bool __init initrd_load(void)
> > * mounted in the normal path.
> > */
> > if (rd_load_image("/initrd.image") && ROOT_DEV != Root_RAM0) {
> > - sys_unlink("/initrd.image");
> > + ksys_unlink("/initrd.image");
> > handle_initrd();
> > return true;
> > }
> > }
> > - sys_unlink("/initrd.image");
> > + ksys_unlink("/initrd.image");
> > return false;
>
> In all callers we seem to have regular kernel strings, so I think
> you should skip the getname() and change the argument to
> a regular pointer.

In line with my explanations in other messages, I have added the following
paragraph to the commit message:

In the near future, all callers of ksys_unlink() should be converted to
call do_unlinkat() directly or, at least, to operate on regular kernel
pointers.

Thanks,
Dominik