[patch-2.3.99-pre9-2] fs/super.c cleanup

From: Tigran Aivazian (tigran@veritas.com)
Date: Fri May 19 2000 - 07:38:15 EDT

  • Next message: Riley Williams: "Re: max ext2 fs size"

    Hi Linus,

    This patch does:

    1) copy_mount_options() greatly simplified (by Ben <kernel@kvack.org> but
       we discussed this and I noticed a bug in copy_mount_options() so I
       took the liberty of including it here - sorry if you already have it -
       I thought the patch was lost :)

    2) do_sys_mount() declarations were wrong in many places - all of them
       removed and put a single correct declaration in <linux/fs.h>. Also
       renamed it to do_mount() as it is the implementation of sys_mount() -
       to have a symmetry with sys_umount()/do_umount(). (also makes many
       lines shorter to have mercy on people in 80x25 Universe :)

    3) 'sb' local variable (and its initialization) in sys_umount() removed.

    4) optimized do_mount() by removing zero-initializations of
       data_page/dev_page/type_page - all set to 0 unconditionally inside
       copy_mount_options().

    5) decreased the length of holding big kernel lock in do_mount().

    Tested.

    Regards,
    Tigran

    diff -urN -X dontdiff linux/arch/alpha/kernel/osf_sys.c cleanup/arch/alpha/kernel/osf_sys.c
    --- linux/arch/alpha/kernel/osf_sys.c Sat May 13 09:32:02 2000
    +++ cleanup/arch/alpha/kernel/osf_sys.c Fri May 19 12:06:32 2000
    @@ -42,7 +42,6 @@
     #include <asm/hwrpb.h>
     #include <asm/processor.h>
     
    -extern long do_sys_mount(char *, char *, char *, int, void *);
     extern int do_pipe(int *);
     
     extern asmlinkage int sys_swapon(const char *specialfile, int swap_flags);
    @@ -377,7 +376,7 @@
             retval = PTR_ERR(devname);
             if (IS_ERR(devname))
                     goto out;
    - retval = do_sys_mount(devname, dirname, "ext2", flags, NULL);
    + retval = do_mount(devname, dirname, "ext2", flags, NULL);
             putname(devname);
     out:
             return retval;
    @@ -396,7 +395,7 @@
             retval = PTR_ERR(devname);
             if (IS_ERR(devname))
                     goto out;
    - retval = do_sys_mount(devname, dirname, "iso9660", flags, NULL);
    + retval = do_mount(devname, dirname, "iso9660", flags, NULL);
             putname(devname);
     out:
             return retval;
    @@ -409,7 +408,7 @@
             if (copy_from_user(&tmp, args, sizeof(tmp)))
                     return -EFAULT;
     
    - return do_sys_mount("", dirname, "proc", flags, NULL);
    + return do_mount("", dirname, "proc", flags, NULL);
     }
     
     asmlinkage int osf_mount(unsigned long typenr, char *path, int flag, void *data)
    diff -urN -X dontdiff linux/arch/ia64/ia32/sys_ia32.c cleanup/arch/ia64/ia32/sys_ia32.c
    --- linux/arch/ia64/ia32/sys_ia32.c Thu Apr 27 09:01:29 2000
    +++ cleanup/arch/ia64/ia32/sys_ia32.c Fri May 19 12:06:32 2000
    @@ -2735,8 +2735,6 @@
     
     extern asmlinkage long sys_mount(char * dev_name, char * dir_name, char * type,
                                     unsigned long new_flags, void *data);
    -extern long do_sys_mount(char * dev_name, char * dir_name, char * type,
    - unsigned long new_flags, void *data);
     
     #define SMBFS_NAME "smbfs"
     #define NCPFS_NAME "ncpfs"
    @@ -2784,7 +2782,7 @@
                             do_smb_super_data_conv((void *)data_page);
                     else
                             panic("The problem is here...");
    - err = do_sys_mount((char *)dev_page, (char *)dir_page,
    + err = do_mount((char *)dev_page, (char *)dir_page,
                                     (char *)type_page, new_flags,
                                     (void *)data_page);
                     if(data_page)
    diff -urN -X dontdiff linux/arch/sparc/kernel/sys_sunos.c cleanup/arch/sparc/kernel/sys_sunos.c
    --- linux/arch/sparc/kernel/sys_sunos.c Sat May 13 09:32:09 2000
    +++ cleanup/arch/sparc/kernel/sys_sunos.c Fri May 19 12:06:32 2000
    @@ -634,7 +634,6 @@
     
     extern dev_t get_unnamed_dev(void);
     extern void put_unnamed_dev(dev_t);
    -extern asmlinkage long do_sys_mount(char *, char *, char *, int, void *);
     extern asmlinkage int sys_connect(int fd, struct sockaddr *uservaddr, int addrlen);
     extern asmlinkage int sys_socket(int family, int type, int protocol);
     extern asmlinkage int sys_bind(int fd, struct sockaddr *umyaddr, int addrlen);
    @@ -754,7 +753,7 @@
             linux_nfs_mount.hostname [255] = 0;
             putname (the_name);
             
    - return do_sys_mount ("", dir_name, "nfs", linux_flags, &linux_nfs_mount);
    + return do_mount ("", dir_name, "nfs", linux_flags, &linux_nfs_mount);
     }
     
     asmlinkage int
    @@ -814,7 +813,7 @@
             ret = PTR_ERR(dev_fname);
             if (IS_ERR(dev_fname))
                     goto out2;
    - ret = do_sys_mount(dev_fname, dir_page, type_page, linux_flags, NULL);
    + ret = do_mount(dev_fname, dir_page, type_page, linux_flags, NULL);
             if (dev_fname)
                     putname(dev_fname);
     out2:
    diff -urN -X dontdiff linux/arch/sparc64/kernel/sys_sparc32.c cleanup/arch/sparc64/kernel/sys_sparc32.c
    --- linux/arch/sparc64/kernel/sys_sparc32.c Sat May 13 09:32:11 2000
    +++ cleanup/arch/sparc64/kernel/sys_sparc32.c Fri May 19 12:06:32 2000
    @@ -1742,9 +1742,6 @@
             return 0;
     }
     
    -extern long do_sys_mount(char * dev_page, char * dir_page, char * type_page,
    - unsigned long new_flags, char * data_page);
    -
     #define SMBFS_NAME "smbfs"
     #define NCPFS_NAME "ncpfs"
     
    @@ -1784,7 +1781,7 @@
                     goto dev_out;
     
             if (!is_smb && !is_ncp) {
    - err = do_sys_mount((char*)dev_page, (char*)dir_page,
    + err = do_mount((char*)dev_page, (char*)dir_page,
                                     (char*)type_page, new_flags, (char*)data_page);
             } else {
                     if (is_ncp)
    @@ -1792,7 +1789,7 @@
                     else
                             do_smb_super_data_conv((void *)data_page);
     
    - err = do_sys_mount((char*)dev_page, (char*)dir_page,
    + err = do_mount((char*)dev_page, (char*)dir_page,
                                     (char*)type_page, new_flags, (char*)data_page);
             }
             free_page(dir_page);
    diff -urN -X dontdiff linux/arch/sparc64/kernel/sys_sunos32.c cleanup/arch/sparc64/kernel/sys_sunos32.c
    --- linux/arch/sparc64/kernel/sys_sunos32.c Sat May 13 09:32:11 2000
    +++ cleanup/arch/sparc64/kernel/sys_sunos32.c Fri May 19 12:06:32 2000
    @@ -598,7 +598,6 @@
             char *netname; /* server's netname */
     };
     
    -extern long do_sys_mount(const char *, const char *, char *, int, void *);
     extern dev_t get_unnamed_dev(void);
     extern void put_unnamed_dev(dev_t);
     extern asmlinkage int sys_mount(char *, char *, char *, unsigned long, void *);
    @@ -727,7 +726,7 @@
             linux_nfs_mount.hostname [255] = 0;
             putname (the_name);
             
    - return do_sys_mount ("", dir_name, "nfs", linux_flags, &linux_nfs_mount);
    + return do_mount ("", dir_name, "nfs", linux_flags, &linux_nfs_mount);
     }
     
     /* XXXXXXXXXXXXXXXXXXXX */
    @@ -787,7 +786,7 @@
             ret = PTR_ERR(dev_fname);
             if (IS_ERR(dev_fname))
                     goto out2;
    - ret = do_sys_mount(dev_fname, dir_page, type_page, linux_flags, NULL);
    + ret = do_mount(dev_fname, dir_page, type_page, linux_flags, NULL);
             if (dev_fname)
                     putname(dev_fname);
     out2:
    diff -urN -X dontdiff linux/fs/devfs/base.c cleanup/fs/devfs/base.c
    --- linux/fs/devfs/base.c Fri May 19 12:31:09 2000
    +++ cleanup/fs/devfs/base.c Fri May 19 12:06:54 2000
    @@ -3569,11 +3569,9 @@
     void __init mount_devfs_fs (void)
     {
         int err;
    - extern long do_sys_mount (char *dev_name, char *dir_name,
    - char *type, int flags, void *data);
     
         if ( (boot_options & OPTION_NOMOUNT) ) return;
    - err = do_sys_mount ("none", "/dev", "devfs", 0, "");
    + err = do_mount ("none", "/dev", "devfs", 0, "");
         if (err == 0) printk ("Mounted devfs on /dev\n");
         else printk ("Warning: unable to mount devfs, err: %d\n", err);
     } /* End Function mount_devfs_fs */
    diff -urN -X dontdiff linux/fs/super.c cleanup/fs/super.c
    --- linux/fs/super.c Fri May 19 12:31:09 2000
    +++ cleanup/fs/super.c Fri May 19 12:32:48 2000
    @@ -1020,7 +1020,6 @@
             struct nameidata nd;
             char *kname;
             int retval;
    - struct super_block *sb;
     
             if (!capable(CAP_SYS_ADMIN))
                     return -EPERM;
    @@ -1036,7 +1035,6 @@
             putname(kname);
             if (retval)
                     goto out;
    - sb = nd.dentry->d_inode->i_sb;
             retval = -EINVAL;
             if (nd.dentry!=nd.mnt->mnt_root)
                     goto dput_and_out;
    @@ -1143,31 +1141,29 @@
             return retval;
     }
     
    -static int copy_mount_options (const void * data, unsigned long *where)
    +static int copy_mount_options (const void *data, unsigned long *where)
     {
             int i;
             unsigned long page;
    - struct vm_area_struct * vma;
     
             *where = 0;
             if (!data)
                     return 0;
     
    - vma = find_vma(current->mm, (unsigned long) data);
    - if (!vma || (unsigned long) data < vma->vm_start)
    - return -EFAULT;
    - if (!(vma->vm_flags & VM_READ))
    - return -EFAULT;
    - i = vma->vm_end - (unsigned long) data;
    - if (PAGE_SIZE <= (unsigned long) i)
    - i = PAGE_SIZE-1;
    - if (!(page = __get_free_page(GFP_KERNEL))) {
    + if (!(page = __get_free_page(GFP_KERNEL)))
                     return -ENOMEM;
    - }
    - if (copy_from_user((void *) page,data,i)) {
    +
    + /* We only care that *some* data at the address the user
    + * gave us is valid. Just in case, we'll zero
    + * the remainder of the page.
    + */
    + i = copy_from_user((void *)page, data, PAGE_SIZE);
    + if (i == PAGE_SIZE) {
                     free_page(page);
                     return -EFAULT;
             }
    + if (i)
    + memset((char *)page + PAGE_SIZE - i, 0, i);
             *where = page;
             return 0;
     }
    @@ -1186,7 +1182,7 @@
      * aren't used, as the syscall assumes we are talking to an older
      * version that didn't understand them.
      */
    -long do_sys_mount(char * dev_name, char * dir_name, char *type_page,
    +long do_mount(char * dev_name, char * dir_name, char *type_page,
                       unsigned long new_flags, void *data_page)
     {
             struct file_system_type * fstype;
    @@ -1279,26 +1275,24 @@
                               unsigned long new_flags, void * data)
     {
             int retval;
    - unsigned long data_page = 0;
    - unsigned long type_page = 0;
    - unsigned long dev_page = 0;
    + unsigned long data_page;
    + unsigned long type_page;
    + unsigned long dev_page;
             char *dir_page;
     
    - lock_kernel();
             retval = copy_mount_options (type, &type_page);
             if (retval < 0)
    - goto out;
    + return retval;
     
             /* copy_mount_options allows a NULL user pointer,
              * and just returns zero in that case. But if we
              * allow the type to be NULL we will crash.
              * Previously we did not check this case.
              */
    - if (type_page == 0) {
    - retval = -EINVAL;
    - goto out;
    - }
    + if (type_page == 0)
    + return -EINVAL;
     
    + lock_kernel();
             dir_page = getname(dir_name);
             retval = PTR_ERR(dir_page);
             if (IS_ERR(dir_page))
    @@ -1309,7 +1303,7 @@
                     goto out2;
             retval = copy_mount_options (data, &data_page);
             if (retval >= 0) {
    - retval = do_sys_mount((char*)dev_page,dir_page,(char*)type_page,
    + retval = do_mount((char*)dev_page,dir_page,(char*)type_page,
                                           new_flags, (void*)data_page);
                     free_page(data_page);
             }
    @@ -1318,7 +1312,6 @@
             putname(dir_page);
     out1:
             free_page(type_page);
    -out:
             unlock_kernel();
             return retval;
     }
    diff -urN -X dontdiff linux/include/linux/fs.h cleanup/include/linux/fs.h
    --- linux/include/linux/fs.h Sat May 13 09:32:40 2000
    +++ cleanup/include/linux/fs.h Fri May 19 12:16:25 2000
    @@ -794,6 +794,8 @@
     extern struct vfsmount *kern_mount(struct file_system_type *);
     extern void kern_umount(struct vfsmount *);
     extern int may_umount(struct vfsmount *);
    +extern long do_mount(char *, char *, char *, unsigned long, void *);
    +
     
     extern int vfs_statfs(struct super_block *, struct statfs *);
     

    -
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.rutgers.edu
    Please read the FAQ at http://www.tux.org/lkml/



    This archive was generated by hypermail 2b29 : Fri May 19 2000 - 07:42:43 EDT