patch-2.1.45 linux/arch/sparc64/kernel/sys_sparc32.c

Next file: linux/arch/sparc64/kernel/sys_sunos32.c
Previous file: linux/arch/sparc64/kernel/sunos_ioctl32.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.1.44/linux/arch/sparc64/kernel/sys_sparc32.c linux/arch/sparc64/kernel/sys_sparc32.c
@@ -1,4 +1,4 @@
-/* $Id: sys_sparc32.c,v 1.42 1997/07/05 09:52:36 davem Exp $
+/* $Id: sys_sparc32.c,v 1.43 1997/07/17 02:20:45 davem Exp $
  * sys_sparc32.c: Conversion between 32bit and 64bit native syscalls.
  *
  * Copyright (C) 1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
@@ -759,14 +759,29 @@
 asmlinkage long sys32_readv(int fd, u32 vector, u32 count)
 {
 	struct file *file;
+	struct dentry *dentry;
 	struct inode *inode;
 	long err = -EBADF;
 
 	lock_kernel();
-	if (fd >= NR_OPEN || !(file = current->files->fd[fd]) || !(inode=file->f_inode))
+	if(fd >= NR_OPEN)
 		goto out;
-	if (!(file->f_mode & 1))
+
+	file = current->files->fd[fd];
+	if(!file)
+		goto out;
+
+	if(!(file->f_mode & 1))
+		goto out;
+
+	dentry = file->f_dentry;
+	if(!dentry)
+		goto out;
+
+	inode = dentry->d_inode;
+	if(!inode)
 		goto out;
+
 	err = do_readv_writev32(VERIFY_WRITE, inode, file,
 				(struct iovec32 *)A(vector), count);
 out:
@@ -778,13 +793,28 @@
 {
 	int error = -EBADF;
 	struct file *file;
+	struct dentry *dentry;
 	struct inode *inode;
 
 	lock_kernel();
-	if (fd >= NR_OPEN || !(file = current->files->fd[fd]) || !(inode=file->f_inode))
+	if(fd >= NR_OPEN)
+		goto out;
+
+	file = current->files->fd[fd];
+	if(!file)
+		goto out;
+
+	if(!(file->f_mode & 2))
+		goto out;
+
+	dentry = file->f_dentry;
+	if(!dentry)
 		goto out;
-	if (!(file->f_mode & 2))
+
+	inode = dentry->d_inode;
+	if(!inode)
 		goto out;
+
 	down(&inode->i_sem);
 	error = do_readv_writev32(VERIFY_READ, inode, file,
 				(struct iovec32 *)A(vector), count);
@@ -833,21 +863,34 @@
 {
 	int error = -EBADF;
 	struct file * file;
+	struct dentry * dentry;
+	struct inode * inode;
 	struct readdir_callback32 buf;
 
 	lock_kernel();
-	if (fd >= NR_OPEN || !(file = current->files->fd[fd]))
+	if(fd >= NR_OPEN)
 		goto out;
-	error = -ENOTDIR;
-	if (!file->f_op || !file->f_op->readdir)
+
+	file = current->files->fd[fd];
+	if(!file)
 		goto out;
-	error = verify_area(VERIFY_WRITE, (void *)A(dirent),
-			    sizeof(struct old_linux_dirent32));
-	if (error)
+
+	dentry = file->f_dentry;
+	if(!dentry)
 		goto out;
+
+	inode = dentry->d_inode;
+	if(!inode)
+		goto out;
+
 	buf.count = 0;
 	buf.dirent = (struct old_linux_dirent32 *)A(dirent);
-	error = file->f_op->readdir(file->f_inode, file, &buf, fillonedir);
+
+	error = -ENOTDIR;
+	if (!file->f_op || !file->f_op->readdir)
+		goto out;
+
+	error = file->f_op->readdir(inode, file, &buf, fillonedir);
 	if (error < 0)
 		goto out;
 	error = buf.count;
@@ -897,30 +940,43 @@
 asmlinkage int sys32_getdents(unsigned int fd, u32 dirent, unsigned int count)
 {
 	struct file * file;
+	struct dentry * dentry;
+	struct inode *inode;
 	struct linux_dirent32 * lastdirent;
 	struct getdents_callback32 buf;
 	int error = -EBADF;
 
 	lock_kernel();
-	if (fd >= NR_OPEN || !(file = current->files->fd[fd]))
+	if(fd >= NR_OPEN)
 		goto out;
-	error = -ENOTDIR;
-	if (!file->f_op || !file->f_op->readdir)
+
+	file = current->files->fd[fd];
+	if(!file)
 		goto out;
-	error = verify_area(VERIFY_WRITE, (void *)A(dirent), count);
-	if (error)
+
+	dentry = file->f_dentry;
+	if(!dentry)
 		goto out;
+
+	inode = dentry->d_inode;
+	if(!inode)
+		goto out;
+
 	buf.current_dir = (struct linux_dirent32 *) A(dirent);
 	buf.previous = NULL;
 	buf.count = count;
 	buf.error = 0;
-	error = file->f_op->readdir(file->f_inode, file, &buf, filldir);
+
+	error = -ENOTDIR;
+	if (!file->f_op || !file->f_op->readdir)
+		goto out;
+
+	error = file->f_op->readdir(inode, file, &buf, filldir);
 	if (error < 0)
 		goto out;
 	lastdirent = buf.previous;
-	if (!lastdirent) {
-		error = buf.error;
-	} else {
+	error = buf.error;
+	if(lastdirent) {
 		put_user(file->f_pos, &lastdirent->d_off);
 		error = count - buf.count;
 	}
@@ -1725,11 +1781,11 @@
 		return NULL;
 	}
 
-	inode = file->f_inode;
+	inode = file->f_dentry->d_inode;
 	if (!inode || !inode->i_sock || !socki_lookup(inode))
 	{
 		*err = -ENOTSOCK;
-		fput(file,inode);
+		fput(file);
 		return NULL;
 	}
 
@@ -1738,7 +1794,7 @@
 
 extern __inline__ void sockfd_put(struct socket *sock)
 {
-	fput(sock->file,sock->inode);
+	fput(sock->file);
 }
 
 struct msghdr32 {
@@ -2168,25 +2224,33 @@
 do_execve32(char * filename, u32 * argv, u32 * envp, struct pt_regs * regs)
 {
 	struct linux_binprm bprm;
+	struct dentry * dentry;
 	int retval;
 	int i;
 
 	bprm.p = PAGE_SIZE*MAX_ARG_PAGES-sizeof(void *);
 	for (i=0 ; i<MAX_ARG_PAGES ; i++)	/* clear page-table */
 		bprm.page[i] = 0;
-	retval = open_namei(filename, 0, 0, &bprm.inode, NULL);
-	if (retval)
+
+	dentry = open_namei(filename, 0, 0);
+	retval = PTR_ERR(dentry);
+	if (IS_ERR(dentry))
 		return retval;
+
+	bprm.dentry = dentry;
 	bprm.filename = filename;
 	bprm.sh_bang = 0;
 	bprm.java = 0;
 	bprm.loader = 0;
 	bprm.exec = 0;
-	bprm.dont_iput = 0;
-	if ((bprm.argc = count32(argv)) < 0)
+	if ((bprm.argc = count32(argv)) < 0) {
+		dput(dentry);
 		return bprm.argc;
-	if ((bprm.envc = count32(envp)) < 0)
+	}
+	if ((bprm.envc = count32(envp)) < 0) {
+		dput(dentry);
 		return bprm.envc;
+	}
 
 	retval = prepare_binprm(&bprm);
 	
@@ -2206,8 +2270,9 @@
 		return retval;
 
 	/* Something went wrong, return the inode and free the argument pages*/
-	if(!bprm.dont_iput)
-		iput(bprm.inode);
+	if(bprm.dentry)
+		dput(bprm.dentry);
+
 	for (i=0 ; i<MAX_ARG_PAGES ; i++)
 		free_page(bprm.page[i]);
 	return(retval);
@@ -2226,17 +2291,22 @@
         if((u32)regs->u_regs[UREG_G1] == 0)
                 base = 1;
 
-        error = getname((char *)(unsigned long)(u32)regs->u_regs[base + UREG_I0], &filename);
-        if(error)
-                return error;
+	lock_kernel();
+        filename = getname((char *)(unsigned long)(u32)regs->u_regs[base + UREG_I0]);
+	error = PTR_ERR(filename);
+        if(IS_ERR(filename))
+                goto out;
         error = do_execve32(filename,
         	(u32 *)A((u32)regs->u_regs[base + UREG_I1]),
         	(u32 *)A((u32)regs->u_regs[base + UREG_I2]), regs);
         putname(filename);
+
 	if(!error) {
 		fprs_write(0);
 		regs->fprs = 0;
 	}
+out:
+	unlock_kernel();
         return error;
 }
 

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov