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 : Tue May 23 2000 - 21:00:17 EST