patch-2.4.0-test6 linux/arch/sparc64/kernel/sys_sparc32.c
Next file: linux/arch/sparc64/kernel/sys_sunos32.c
Previous file: linux/arch/sparc64/kernel/sys_sparc.c
Back to the patch index
Back to the overall index
- Lines: 407
- Date:
Wed Aug 9 13:49:56 2000
- Orig file:
v2.4.0-test5/linux/arch/sparc64/kernel/sys_sparc32.c
- Orig date:
Thu Jul 27 17:38:00 2000
diff -u --recursive --new-file v2.4.0-test5/linux/arch/sparc64/kernel/sys_sparc32.c linux/arch/sparc64/kernel/sys_sparc32.c
@@ -1,4 +1,4 @@
-/* $Id: sys_sparc32.c,v 1.156 2000/07/13 10:59:13 davem Exp $
+/* $Id: sys_sparc32.c,v 1.159 2000/08/08 02:47:50 davem Exp $
* sys_sparc32.c: Conversion between 32bit and 64bit native syscalls.
*
* Copyright (C) 1997,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
@@ -253,45 +253,6 @@
return high2lowgid(current->egid);
}
-/* In order to reduce some races, while at the same time doing additional
- * checking and hopefully speeding things up, we copy filenames to the
- * kernel data space before using them..
- *
- * POSIX.1 2.4: an empty pathname is invalid (ENOENT).
- */
-static inline int do_getname32(const char *filename, char *page)
-{
- int retval;
-
- /* 32bit pointer will be always far below TASK_SIZE :)) */
- retval = strncpy_from_user((char *)page, (char *)filename, PAGE_SIZE);
- if (retval > 0) {
- if (retval < PAGE_SIZE)
- return 0;
- return -ENAMETOOLONG;
- } else if (!retval)
- retval = -ENOENT;
- return retval;
-}
-
-char * getname32(const char *filename)
-{
- char *tmp, *result;
-
- result = ERR_PTR(-ENOMEM);
- tmp = __getname();
- if (tmp) {
- int retval = do_getname32(filename, tmp);
-
- result = tmp;
- if (retval < 0) {
- putname(tmp);
- result = ERR_PTR(retval);
- }
- }
- return result;
-}
-
/* 32-bit timeval and related flotsam. */
struct timeval32
@@ -799,7 +760,6 @@
{
int version, err;
- lock_kernel();
version = call >> 16; /* hack for backward compatibility */
call &= 0xffff;
@@ -861,7 +821,6 @@
err = -EINVAL;
out:
- unlock_kernel();
return err;
}
@@ -953,7 +912,7 @@
return sys_quotactl(cmd, special,
id, (caddr_t)addr);
}
- spec = getname32 (special);
+ spec = getname (special);
err = PTR_ERR(spec);
if (IS_ERR(spec)) return err;
old_fs = get_fs ();
@@ -998,7 +957,7 @@
mm_segment_t old_fs = get_fs();
char *pth;
- pth = getname32 (path);
+ pth = getname (path);
ret = PTR_ERR(pth);
if (!IS_ERR(pth)) {
set_fs (KERNEL_DS);
@@ -1064,7 +1023,7 @@
if (get_user (t.actime, ×->actime) ||
__get_user (t.modtime, ×->modtime))
return -EFAULT;
- filenam = getname32 (filename);
+ filenam = getname (filename);
ret = PTR_ERR(filenam);
if (!IS_ERR(filenam)) {
old_fs = get_fs();
@@ -1078,7 +1037,8 @@
struct iovec32 { u32 iov_base; __kernel_size_t32 iov_len; };
-typedef ssize_t (*IO_fn_t)(struct file *, char *, size_t, loff_t *);
+typedef ssize_t (*io_fn_t)(struct file *, char *, size_t, loff_t *);
+typedef ssize_t (*iov_fn_t)(struct file *, const struct iovec *, unsigned long, loff_t *);
static long do_readv_writev32(int type, struct file *file,
const struct iovec32 *vector, u32 count)
@@ -1088,14 +1048,15 @@
struct iovec *iov=iovstack, *ivp;
struct inode *inode;
long retval, i;
- IO_fn_t fn;
+ io_fn_t fn;
+ iov_fn_t fnv;
/* First get the "struct iovec" from user memory and
* verify all the pointers
*/
if (!count)
return 0;
- if(verify_area(VERIFY_READ, vector, sizeof(struct iovec32)*count))
+ if (verify_area(VERIFY_READ, vector, sizeof(struct iovec32)*count))
return -EFAULT;
if (count > UIO_MAXIOV)
return -EINVAL;
@@ -1127,33 +1088,19 @@
retval = locks_verify_area((type == VERIFY_WRITE
? FLOCK_VERIFY_READ : FLOCK_VERIFY_WRITE),
inode, file, file->f_pos, tot_len);
- if (retval) {
- if (iov != iovstack)
- kfree(iov);
- return retval;
- }
+ if (retval)
+ goto out;
- /* Then do the actual IO. Note that sockets need to be handled
- * specially as they have atomicity guarantees and can handle
- * iovec's natively
- */
- if (inode->i_sock) {
- int err;
- err = sock_readv_writev(type, inode, file, iov, count, tot_len);
- if (iov != iovstack)
- kfree(iov);
- return err;
+ /* VERIFY_WRITE actually means a read, as we write to user space */
+ fnv = (type == VERIFY_WRITE ? file->f_op->readv : file->f_op->writev);
+ if (fnv) {
+ retval = fnv(file, iov, count, &file->f_pos);
+ goto out;
}
- if (!file->f_op) {
- if (iov != iovstack)
- kfree(iov);
- return -EINVAL;
- }
- /* VERIFY_WRITE actually means a read, as we write to user space */
- fn = file->f_op->read;
- if (type == VERIFY_READ)
- fn = (IO_fn_t) file->f_op->write;
+ fn = (type == VERIFY_WRITE ? file->f_op->read :
+ (io_fn_t) file->f_op->write);
+
ivp = iov;
while (count > 0) {
void * base;
@@ -1165,17 +1112,18 @@
count--;
nr = fn(file, base, len, &file->f_pos);
if (nr < 0) {
- if (retval)
- break;
- retval = nr;
+ if (!retval)
+ retval = nr;
break;
}
retval += nr;
if (nr != len)
break;
}
+out:
if (iov != iovstack)
kfree(iov);
+
return retval;
}
@@ -1188,7 +1136,8 @@
if(!file)
goto bad_file;
- if (file->f_op && file->f_op->read && (file->f_mode & FMODE_READ))
+ if (file->f_op && (file->f_mode & FMODE_READ) &&
+ (file->f_op->readv || file->f_op->read))
ret = do_readv_writev32(VERIFY_WRITE, file, vector, count);
fput(file);
@@ -1204,7 +1153,8 @@
file = fget(fd);
if(!file)
goto bad_file;
- if (file->f_op && file->f_op->write && (file->f_mode & FMODE_WRITE))
+ if (file->f_op && (file->f_mode & FMODE_WRITE) &&
+ (file->f_op->writev || file->f_op->write))
ret = do_readv_writev32(VERIFY_READ, file, vector, count);
fput(file);
@@ -1572,6 +1522,16 @@
return err;
}
+/* Perhaps this belongs in fs.h or similar. -DaveM */
+static __inline__ int
+do_revalidate(struct dentry *dentry)
+{
+ struct inode * inode = dentry->d_inode;
+ if (inode->i_op && inode->i_op->revalidate)
+ return inode->i_op->revalidate(dentry);
+ return 0;
+}
+
asmlinkage int sys32_newstat(char * filename, struct stat32 *statbuf)
{
struct nameidata nd;
@@ -1579,16 +1539,9 @@
error = user_path_walk(filename, &nd);
if (!error) {
- struct inode *inode = nd.dentry->d_inode;
-
- if (inode->i_op &&
- inode->i_op->revalidate)
- error = inode->i_op->revalidate(nd.dentry);
- else
- error = 0;
+ error = do_revalidate(nd.dentry);
if (!error)
- error = cp_new_stat32(inode, statbuf);
-
+ error = cp_new_stat32(nd.dentry->d_inode, statbuf);
path_release(&nd);
}
return error;
@@ -1601,15 +1554,9 @@
error = user_path_walk_link(filename, &nd);
if (!error) {
- struct inode *inode = nd.dentry->d_inode;
-
- if (inode->i_op &&
- inode->i_op->revalidate)
- error = inode->i_op->revalidate(nd.dentry);
- else
- error = 0;
+ error = do_revalidate(nd.dentry);
if (!error)
- error = cp_new_stat32(inode, statbuf);
+ error = cp_new_stat32(nd.dentry->d_inode, statbuf);
path_release(&nd);
}
@@ -1623,16 +1570,11 @@
f = fget(fd);
if (f) {
- struct inode *inode = f->f_dentry->d_inode;
+ struct dentry * dentry = f->f_dentry;
- if (inode->i_op &&
- inode->i_op->revalidate)
- err = inode->i_op->revalidate(f->f_dentry);
- else
- err = 0;
+ err = do_revalidate(dentry);
if (!err)
- err = cp_new_stat32(inode, statbuf);
-
+ err = cp_new_stat32(dentry->d_inode, statbuf);
fput(f);
}
return err;
@@ -1738,7 +1680,6 @@
is_smb = is_ncp = 0;
- lock_kernel();
err = copy_mount_stuff_to_kernel((const void *)type, &type_page);
if (err)
goto out;
@@ -1764,16 +1705,20 @@
goto dev_out;
if (!is_smb && !is_ncp) {
+ lock_kernel();
err = do_mount((char*)dev_page, (char*)dir_page,
(char*)type_page, new_flags, (char*)data_page);
+ unlock_kernel();
} else {
if (is_ncp)
do_ncp_super_data_conv((void *)data_page);
else
do_smb_super_data_conv((void *)data_page);
+ lock_kernel();
err = do_mount((char*)dev_page, (char*)dir_page,
(char*)type_page, new_flags, (char*)data_page);
+ unlock_kernel();
}
free_page(dir_page);
@@ -1787,7 +1732,6 @@
free_page(type_page);
out:
- unlock_kernel();
return err;
}
@@ -2234,34 +2178,9 @@
24 for IPv6,
about 80 for AX.25 */
-/* XXX These as well... */
-extern __inline__ struct socket *socki_lookup(struct inode *inode)
-{
- return &inode->u.socket_i;
-}
-
-extern __inline__ struct socket *sockfd_lookup(int fd, int *err)
-{
- struct file *file;
- struct inode *inode;
-
- if (!(file = fget(fd)))
- {
- *err = -EBADF;
- return NULL;
- }
-
- inode = file->f_dentry->d_inode;
- if (!inode || !inode->i_sock || !socki_lookup(inode))
- {
- *err = -ENOTSOCK;
- fput(file);
- return NULL;
- }
-
- return socki_lookup(inode);
-}
+extern struct socket *sockfd_lookup(int fd, int *err);
+/* XXX This as well... */
extern __inline__ void sockfd_put(struct socket *sock)
{
fput(sock->file);
@@ -2678,7 +2597,6 @@
}
kern_msg.msg_flags = user_flags;
- lock_kernel();
sock = sockfd_lookup(fd, &err);
if (sock != NULL) {
if (sock->file->f_flags & O_NONBLOCK)
@@ -2686,7 +2604,6 @@
err = sock_sendmsg(sock, &kern_msg, total_len);
sockfd_put(sock);
}
- unlock_kernel();
/* N.B. Use kfree here, as kern_msg.msg_controllen might change? */
if(ctl_buf != ctl)
@@ -2725,7 +2642,6 @@
cmsg_ptr = (unsigned long) kern_msg.msg_control;
kern_msg.msg_flags = 0;
- lock_kernel();
sock = sockfd_lookup(fd, &err);
if (sock != NULL) {
struct scm_cookie scm;
@@ -2762,7 +2678,6 @@
}
sockfd_put(sock);
}
- unlock_kernel();
if(uaddr != NULL && err >= 0)
err = move_addr_to_user(addr, kern_msg.msg_namelen, uaddr, uaddr_len);
@@ -3084,7 +2999,7 @@
if((u32)regs->u_regs[UREG_G1] == 0)
base = 1;
- filename = getname32((char *)AA(regs->u_regs[base + UREG_I0]));
+ filename = getname((char *)AA(regs->u_regs[base + UREG_I0]));
error = PTR_ERR(filename);
if(IS_ERR(filename))
goto out;
@@ -3926,7 +3841,7 @@
mm_segment_t old_fs;
int ret;
- kfilename = getname32(filename);
+ kfilename = getname(filename);
ret = PTR_ERR(kfilename);
if (!IS_ERR(kfilename)) {
if (tvs) {
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)