summaryrefslogtreecommitdiffstats
path: root/arch/mips/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'arch/mips/kernel')
-rw-r--r--arch/mips/kernel/irixelf.c99
-rw-r--r--arch/mips/kernel/syscall.c13
-rw-r--r--arch/mips/kernel/syscalls.h4
-rw-r--r--arch/mips/kernel/sysirix.c287
-rw-r--r--arch/mips/kernel/sysmips.c15
5 files changed, 255 insertions, 163 deletions
diff --git a/arch/mips/kernel/irixelf.c b/arch/mips/kernel/irixelf.c
index fc0d542fc..dabd91762 100644
--- a/arch/mips/kernel/irixelf.c
+++ b/arch/mips/kernel/irixelf.c
@@ -228,7 +228,7 @@ unsigned long * create_irix_tables(char * p, int argc, int envc,
* an ELF header.
*/
static unsigned int load_irix_interp(struct elfhdr * interp_elf_ex,
- struct inode * interpreter_inode,
+ struct dentry * interpreter_dentry,
unsigned int *interp_load_addr)
{
struct file * file;
@@ -256,8 +256,8 @@ static unsigned int load_irix_interp(struct elfhdr * interp_elf_ex,
if((interp_elf_ex->e_type != ET_EXEC &&
interp_elf_ex->e_type != ET_DYN) ||
!elf_check_arch(interp_elf_ex->e_machine) ||
- (!interpreter_inode->i_op ||
- !interpreter_inode->i_op->default_file_ops->mmap)){
+ (!interpreter_dentry->d_inode->i_op ||
+ !interpreter_dentry->d_inode->i_op->default_file_ops->mmap)) {
printk("IRIX interp has bad e_type %d\n", interp_elf_ex->e_type);
return 0xffffffff;
}
@@ -288,7 +288,7 @@ static unsigned int load_irix_interp(struct elfhdr * interp_elf_ex,
return 0xffffffff;
}
- retval = read_exec(interpreter_inode, interp_elf_ex->e_phoff,
+ retval = read_exec(interpreter_dentry, interp_elf_ex->e_phoff,
(char *) elf_phdata,
sizeof(struct elf_phdr) * interp_elf_ex->e_phnum, 1);
@@ -296,7 +296,7 @@ static unsigned int load_irix_interp(struct elfhdr * interp_elf_ex,
dump_phdrs(elf_phdata, interp_elf_ex->e_phnum);
#endif
- elf_exec_fileno = open_inode(interpreter_inode, O_RDONLY);
+ elf_exec_fileno = open_dentry(interpreter_dentry, O_RDONLY);
if (elf_exec_fileno < 0) {
printk("Could not open IRIX interp inode.\n");
kfree(elf_phdata);
@@ -408,8 +408,9 @@ static int verify_binary(struct elfhdr *ehp, struct linux_binprm *bprm)
/* First of all, some simple consistency checks */
if((ehp->e_type != ET_EXEC && ehp->e_type != ET_DYN) ||
!elf_check_arch(ehp->e_machine) ||
- (!bprm->inode->i_op || !bprm->inode->i_op->default_file_ops ||
- !bprm->inode->i_op->default_file_ops->mmap)) {
+ (!bprm->dentry->d_inode->i_op ||
+ !bprm->dentry->d_inode->i_op->default_file_ops ||
+ !bprm->dentry->d_inode->i_op->default_file_ops->mmap)) {
return -ENOEXEC;
}
@@ -435,13 +436,14 @@ static int verify_binary(struct elfhdr *ehp, struct linux_binprm *bprm)
/* Look for an IRIX ELF interpreter. */
static inline int look_for_irix_interpreter(char **name,
- struct inode **interpreter_inode,
+ struct dentry **interpreter_dentry,
struct elfhdr *interp_elf_ex,
struct elf_phdr *epp,
struct linux_binprm *bprm, int pnum)
{
int i, old_fs;
int retval = -EINVAL;
+ struct dentry *dentry = NULL;
*name = NULL;
for(i = 0; i < pnum; i++, epp++) {
@@ -450,7 +452,7 @@ static inline int look_for_irix_interpreter(char **name,
/* It is illegal to have two interpreters for one executable. */
if(*name != NULL)
- goto losing;
+ goto out;
*name = (char *) kmalloc((epp->p_filesz +
strlen(IRIX_INTERP_PREFIX)),
@@ -459,26 +461,31 @@ static inline int look_for_irix_interpreter(char **name,
return -ENOMEM;
strcpy(*name, IRIX_INTERP_PREFIX);
- retval = read_exec(bprm->inode, epp->p_offset, (*name + 16),
+ retval = read_exec(bprm->dentry, epp->p_offset, (*name + 16),
epp->p_filesz, 1);
if(retval < 0)
- goto losing;
+ goto out;
old_fs = get_fs(); set_fs(get_ds());
- retval = namei(NAM_FOLLOW_LINK, *name, interpreter_inode);
+ dentry = namei(*name);
set_fs(old_fs);
- if(retval < 0)
- goto losing;
+ if(IS_ERR(dentry)) {
+ retval = PTR_ERR(dentry);
+ goto out;
+ }
- retval = read_exec(*interpreter_inode, 0, bprm->buf, 128, 1);
- if(retval < 0)
- goto losing;
+ retval = read_exec(dentry, 0, bprm->buf, 128, 1);
+ if(retval)
+ goto dput_and_out;
*interp_elf_ex = *((struct elfhdr *) bprm->buf);
}
+ *interpreter_dentry = dentry;
return 0;
-losing:
+dput_and_out:
+ dput(dentry);
+out:
kfree(*name);
return retval;
}
@@ -538,7 +545,7 @@ static inline void map_executable(struct file *fp, struct elf_phdr *epp, int pnu
}
static inline int map_interpreter(struct elf_phdr *epp, struct elfhdr *ihp,
- struct inode *iino, unsigned int *iladdr,
+ struct dentry *identry, unsigned int *iladdr,
int pnum, int old_fs,
unsigned int *eentry)
{
@@ -554,11 +561,11 @@ static inline int map_interpreter(struct elf_phdr *epp, struct elfhdr *ihp,
return -1;
set_fs(old_fs);
- *eentry = load_irix_interp(ihp, iino, iladdr);
+ *eentry = load_irix_interp(ihp, identry, iladdr);
old_fs = get_fs();
set_fs(get_ds());
- iput(iino);
+ dput(identry);
if(*eentry == 0xffffffff)
return -1;
@@ -573,7 +580,7 @@ static inline int do_load_irix_binary(struct linux_binprm * bprm,
struct pt_regs * regs)
{
struct elfhdr elf_ex, interp_elf_ex;
- struct inode *interpreter_inode;
+ struct dentry *interpreter_dentry;
struct elf_phdr *elf_phdata, *elf_ihdr, *elf_ephdr;
unsigned int load_addr, elf_bss, elf_brk;
unsigned int elf_entry, interp_load_addr = 0;
@@ -599,7 +606,7 @@ static inline int do_load_irix_binary(struct linux_binprm * bprm,
if (elf_phdata == NULL)
return -ENOMEM;
- retval = read_exec(bprm->inode, elf_ex.e_phoff, (char *) elf_phdata,
+ retval = read_exec(bprm->dentry, elf_ex.e_phoff, (char *) elf_phdata,
elf_ex.e_phentsize * elf_ex.e_phnum, 1);
if (retval < 0) {
kfree (elf_phdata);
@@ -629,7 +636,7 @@ static inline int do_load_irix_binary(struct linux_binprm * bprm,
elf_bss = 0;
elf_brk = 0;
- elf_exec_fileno = open_inode(bprm->inode, O_RDONLY);
+ elf_exec_fileno = open_dentry(bprm->dentry, O_RDONLY);
if (elf_exec_fileno < 0) {
kfree (elf_phdata);
@@ -642,7 +649,8 @@ static inline int do_load_irix_binary(struct linux_binprm * bprm,
end_code = 0;
end_data = 0;
- retval = look_for_irix_interpreter(&elf_interpreter, &interpreter_inode,
+ retval = look_for_irix_interpreter(&elf_interpreter,
+ &interpreter_dentry,
&interp_elf_ex, elf_phdata, bprm,
elf_ex.e_phnum);
if(retval) {
@@ -703,7 +711,7 @@ static inline int do_load_irix_binary(struct linux_binprm * bprm,
if(elf_interpreter) {
retval = map_interpreter(elf_phdata, &interp_elf_ex,
- interpreter_inode, &interp_load_addr,
+ interpreter_dentry, &interp_load_addr,
elf_ex.e_phnum, old_fs, &elf_entry);
kfree(elf_interpreter);
if(retval) {
@@ -795,7 +803,8 @@ static inline int do_load_irix_library(int fd)
struct file * file;
struct elfhdr elf_ex;
struct elf_phdr *elf_phdata = NULL;
- struct inode * inode;
+ struct dentry *dentry;
+ struct inode *inode;
unsigned int len;
int elf_bss;
int retval;
@@ -805,7 +814,8 @@ static inline int do_load_irix_library(int fd)
len = 0;
file = current->files->fd[fd];
- inode = file->f_inode;
+ dentry = file->f_dentry;
+ inode = dentry->d_inode;
elf_bss = 0;
if (!file || !file->f_op)
@@ -831,7 +841,8 @@ static inline int do_load_irix_library(int fd)
/* First of all, some simple consistency checks. */
if(elf_ex.e_type != ET_EXEC || elf_ex.e_phnum > 2 ||
!elf_check_arch(elf_ex.e_machine) ||
- (!inode->i_op || !inode->i_op->default_file_ops->mmap))
+ (!dentry->d_inode->i_op ||
+ !dentry->d_inode->i_op->default_file_ops->mmap))
return -ENOEXEC;
/* Now read in all of the header information. */
@@ -843,7 +854,7 @@ static inline int do_load_irix_library(int fd)
if (elf_phdata == NULL)
return -ENOMEM;
- retval = read_exec(inode, elf_ex.e_phoff, (char *) elf_phdata,
+ retval = read_exec(dentry, elf_ex.e_phoff, (char *) elf_phdata,
sizeof(struct elf_phdr) * elf_ex.e_phnum, 1);
j = 0;
@@ -973,14 +984,13 @@ unsigned long irix_mapelf(int fd, struct elf_phdr *user_phdrp, int cnt)
*/
static int dump_write(struct file *file, const void *addr, int nr)
{
- file->f_inode->i_status |= ST_MODIFIED;
- return file->f_op->write(file->f_inode, file, addr, nr) == nr;
+ return file->f_op->write(file->f_dentry->d_inode, file, addr, nr) == nr;
}
static int dump_seek(struct file *file, off_t off)
{
if (file->f_op->llseek) {
- if (file->f_op->llseek(file->f_inode, file, off, 0) != off)
+ if (file->f_op->llseek(file->f_dentry->d_inode, file, off, 0) != off)
return 0;
} else
file->f_pos = off;
@@ -1071,6 +1081,7 @@ static int irix_core_dump(long signr, struct pt_regs * regs)
{
int has_dumped = 0;
struct file file;
+ struct dentry *dentry;
struct inode *inode;
unsigned short fs;
char corefile[6+sizeof(current->comm)];
@@ -1138,30 +1149,24 @@ static int irix_core_dump(long signr, struct pt_regs * regs)
fs = get_fs();
set_fs(KERNEL_DS);
- memcpy(corefile,"core.",5);
+ memcpy(corefile,"core.", 5);
#if 0
memcpy(corefile+5,current->comm,sizeof(current->comm));
#else
corefile[4] = '\0';
#endif
- if (open_namei(corefile,O_CREAT | 2 | O_TRUNC,0600,&inode,NULL)) {
+ dentry = open_namei(corefile, O_CREAT | 2 | O_TRUNC, 0600);
+ if (IS_ERR(dentry)) {
inode = NULL;
goto end_coredump;
}
+ inode = dentry->d_inode;
if (!S_ISREG(inode->i_mode))
goto end_coredump;
if (!inode->i_op || !inode->i_op->default_file_ops)
goto end_coredump;
- file.f_mode = 3;
- file.f_flags = 0;
- file.f_count = 1;
- file.f_inode = inode;
- file.f_pos = 0;
- file.f_reada = 0;
- file.f_op = inode->i_op->default_file_ops;
- if (file.f_op->open)
- if (file.f_op->open(inode,&file))
- goto end_coredump;
+ if (init_private_file(&file, dentry, 3))
+ goto end_coredump;
if (!file.f_op->write)
goto close_coredump;
has_dumped = 1;
@@ -1330,11 +1335,11 @@ static int irix_core_dump(long signr, struct pt_regs * regs)
close_coredump:
if (file.f_op->release)
- file.f_op->release(inode,&file);
+ file.f_op->release(inode, &file);
end_coredump:
set_fs(fs);
- iput(inode);
+ dput(dentry);
#ifndef CONFIG_BINFMT_ELF
MOD_DEC_USE_COUNT;
#endif
diff --git a/arch/mips/kernel/syscall.c b/arch/mips/kernel/syscall.c
index 2faf604c7..f1b117a63 100644
--- a/arch/mips/kernel/syscall.c
+++ b/arch/mips/kernel/syscall.c
@@ -131,20 +131,21 @@ asmlinkage int sys_clone(struct pt_regs *regs)
*/
asmlinkage int sys_execve(struct pt_regs *regs)
{
- int res;
+ int error;
char * filename;
lock_kernel();
- res = getname((char *) (long)regs->regs[4], &filename);
- if (res)
+ filename = getname((char *) (long)regs->regs[4]);
+ error = PTR_ERR(filename);
+ if (IS_ERR(filename))
goto out;
- res = do_execve(filename, (char **) (long)regs->regs[5],
- (char **) (long)regs->regs[6], regs);
+ error = do_execve(filename, (char **) (long)regs->regs[5],
+ (char **) (long)regs->regs[6], regs);
putname(filename);
out:
unlock_kernel();
- return res;
+ return error;
}
/*
diff --git a/arch/mips/kernel/syscalls.h b/arch/mips/kernel/syscalls.h
index b8fc556fa..66d66ce5b 100644
--- a/arch/mips/kernel/syscalls.h
+++ b/arch/mips/kernel/syscalls.h
@@ -7,7 +7,7 @@
*
* Copyright (C) 1995, 1996, 1997 by Ralf Baechle
*
- * $Id: syscalls.h,v 1.3 1997/06/20 09:48:49 ralf Exp $
+ * $Id: syscalls.h,v 1.4 1997/06/25 20:07:40 ralf Exp $
*/
/*
@@ -208,3 +208,5 @@ SYS(sys_getresuid, 3)
SYS(sys_query_module, 5)
SYS(sys_poll, 3)
SYS(sys_nfsservctl, 3)
+SYS(sys_setresgid, 3) /* 4190 */
+SYS(sys_getresgid, 3)
diff --git a/arch/mips/kernel/sysirix.c b/arch/mips/kernel/sysirix.c
index 95a0dc1c6..e87e5084b 100644
--- a/arch/mips/kernel/sysirix.c
+++ b/arch/mips/kernel/sysirix.c
@@ -1,4 +1,4 @@
-/* $Id: sysirix.c,v 1.14 1996/07/14 01:59:51 dm Exp $
+/* $Id: sysirix.c,v 1.4 1997/07/19 19:03:18 root Exp $
* sysirix.c: IRIX system call emulation.
*
* Copyright (C) 1996 David S. Miller
@@ -652,6 +652,7 @@ struct irix_statfs {
asmlinkage int irix_statfs(const char *path, struct irix_statfs *buf,
int len, int fs_type)
{
+ struct dentry *dentry;
struct inode *inode;
struct statfs kbuf;
int error, old_fs, i;
@@ -664,20 +665,19 @@ asmlinkage int irix_statfs(const char *path, struct irix_statfs *buf,
error = verify_area(VERIFY_WRITE, buf, sizeof(struct irix_statfs));
if (error)
goto out;
- error = namei(NAM_FOLLOW_LINK, path, &inode);
- if (error)
- goto out;
- if (!inode->i_sb->s_op->statfs) {
- iput(inode);
- error = -ENOSYS;
+ dentry = namei(path);
+ error = PTR_ERR(dentry);
+ if (IS_ERR(dentry))
goto out;
- }
+ inode = dentry->d_inode;
old_fs = get_fs(); set_fs(get_ds());
- inode->i_sb->s_op->statfs(inode->i_sb, &kbuf, sizeof(struct statfs));
+ error = inode->i_sb->s_op->statfs(inode->i_sb, &kbuf,
+ sizeof(struct statfs));
set_fs(old_fs);
+ if (error)
+ goto dput_and_out;
- iput(inode);
__put_user(kbuf.f_type, &buf->f_type);
__put_user(kbuf.f_bsize, &buf->f_bsize);
__put_user(kbuf.f_frsize, &buf->f_frsize);
@@ -691,6 +691,8 @@ asmlinkage int irix_statfs(const char *path, struct irix_statfs *buf,
}
error = 0;
+dput_and_out:
+ dput(dentry);
out:
unlock_kernel();
return error;
@@ -698,7 +700,8 @@ out:
asmlinkage int irix_fstatfs(unsigned int fd, struct irix_statfs *buf)
{
- struct inode * inode;
+ struct dentry *dentry;
+ struct inode *inode;
struct statfs kbuf;
struct file *file;
int error, old_fs, i;
@@ -711,18 +714,29 @@ asmlinkage int irix_fstatfs(unsigned int fd, struct irix_statfs *buf)
error = -EBADF;
goto out;
}
- if (!(inode = file->f_inode)) {
+ if (!(dentry = file->f_dentry)) {
+ error = -ENOENT;
+ goto out;
+ }
+ if (!(inode = dentry->d_inode)) {
error = -ENOENT;
goto out;
}
+ if (!inode->i_sb) {
+ error = -ENODEV;
+ goto out;
+ }
if (!inode->i_sb->s_op->statfs) {
error = -ENOSYS;
goto out;
}
old_fs = get_fs(); set_fs(get_ds());
- inode->i_sb->s_op->statfs(inode->i_sb, &kbuf, sizeof(struct statfs));
+ error = inode->i_sb->s_op->statfs(inode->i_sb, &kbuf,
+ sizeof(struct statfs));
set_fs(old_fs);
+ if (error)
+ goto out;
__put_user(kbuf.f_type, &buf->f_type);
__put_user(kbuf.f_bsize, &buf->f_bsize);
@@ -789,13 +803,14 @@ out:
asmlinkage int irix_exec(struct pt_regs *regs)
{
int error, base = 0;
- char * filename;
+ char *filename;
lock_kernel();
if(regs->regs[2] == 1000)
base = 1;
- error = getname((char *) (long)regs->regs[base + 4], &filename);
- if (error)
+ filename = getname((char *) (long)regs->regs[base + 4]);
+ error = PTR_ERR(filename);
+ if (IS_ERR(filename))
goto out;
error = do_execve(filename, (char **) (long)regs->regs[base + 5],
(char **) 0, regs);
@@ -809,13 +824,14 @@ out:
asmlinkage int irix_exece(struct pt_regs *regs)
{
int error, base = 0;
- char * filename;
+ char *filename;
lock_kernel();
if(regs->regs[2] == 1000)
base = 1;
- error = getname((char *) (long)regs->regs[base + 4], &filename);
- if (error)
+ filename = getname((char *) (long)regs->regs[base + 4]);
+ error = PTR_ERR(filename);
+ if (IS_ERR(filename))
goto out;
error = do_execve(filename, (char **) (long)regs->regs[base + 5],
(char **) (long)regs->regs[base + 6], regs);
@@ -1380,6 +1396,7 @@ struct irix_statvfs {
asmlinkage int irix_statvfs(char *fname, struct irix_statvfs *buf)
{
+ struct dentry *dentry;
struct inode *inode;
struct statfs kbuf;
int error, old_fs, i;
@@ -1390,20 +1407,23 @@ asmlinkage int irix_statvfs(char *fname, struct irix_statvfs *buf)
error = verify_area(VERIFY_WRITE, buf, sizeof(struct irix_statvfs));
if(error)
goto out;
- error = namei(NAM_FOLLOW_LINK, fname, &inode);
- if(error)
- goto out;
- if(!inode->i_sb->s_op->statfs) {
- iput(inode);
- error = -ENOSYS;
+ dentry = namei(fname);
+ error = PTR_ERR(dentry);
+ if(!IS_ERR(dentry))
goto out;
- }
+ inode = dentry->d_inode;
+
+ error = -ENOSYS;
+ if(!inode->i_sb->s_op->statfs)
+ goto dput_and_out;
old_fs = get_fs(); set_fs(get_ds());
- inode->i_sb->s_op->statfs(inode->i_sb, &kbuf, sizeof(struct statfs));
+ error = inode->i_sb->s_op->statfs(inode->i_sb, &kbuf,
+ sizeof(struct statfs));
set_fs(old_fs);
+ if (error)
+ goto dput_and_out;
- iput(inode);
__put_user(kbuf.f_bsize, &buf->f_bsize);
__put_user(kbuf.f_frsize, &buf->f_frsize);
__put_user(kbuf.f_blocks, &buf->f_blocks);
@@ -1426,6 +1446,8 @@ asmlinkage int irix_statvfs(char *fname, struct irix_statvfs *buf)
error = 0;
+dput_and_out:
+ dput(dentry);
out:
unlock_kernel();
return error;
@@ -1433,7 +1455,8 @@ out:
asmlinkage int irix_fstatvfs(int fd, struct irix_statvfs *buf)
{
- struct inode * inode;
+ struct dentry *dentry;
+ struct inode *inode;
struct statfs kbuf;
struct file *file;
int error, old_fs, i;
@@ -1449,7 +1472,11 @@ asmlinkage int irix_fstatvfs(int fd, struct irix_statvfs *buf)
error = -EBADF;
goto out;
}
- if (!(inode = file->f_inode)) {
+ if (!(dentry = file->f_dentry)) {
+ error = -ENOENT;
+ goto out;
+ }
+ if (!(inode = dentry->d_inode)) {
error = -ENOENT;
goto out;
}
@@ -1459,8 +1486,11 @@ asmlinkage int irix_fstatvfs(int fd, struct irix_statvfs *buf)
}
old_fs = get_fs(); set_fs(get_ds());
- inode->i_sb->s_op->statfs(inode->i_sb, &kbuf, sizeof(struct statfs));
+ error = inode->i_sb->s_op->statfs(inode->i_sb, &kbuf,
+ sizeof(struct statfs));
set_fs(old_fs);
+ if (error)
+ goto out;
__put_user(kbuf.f_bsize, &buf->f_bsize);
__put_user(kbuf.f_frsize, &buf->f_frsize);
@@ -1489,26 +1519,28 @@ out:
return error;
}
-#define NOFOLLOW_LINKS NAM_FOLLOW_TRAILSLASH
-#define FOLLOW_LINKS NAM_FOLLOW_LINK
+#define NOFOLLOW_LINKS 0
+#define FOLLOW_LINKS 1
-static inline int chown_common(char *filename, uid_t user, gid_t group, int follow)
+static inline int chown_common(uid_t user, gid_t group, struct dentry *dentry)
{
struct inode * inode;
int error;
struct iattr newattrs;
- error = namei(follow, filename,&inode);
- if (error)
- return error;
- if (IS_RDONLY(inode)) {
- iput(inode);
- return -EROFS;
- }
- if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) {
- iput(inode);
- return -EPERM;
- }
+ error = PTR_ERR(dentry);
+ if (IS_ERR(dentry))
+ goto out;
+ inode = dentry->d_inode;
+
+ error = -EROFS;
+ if (IS_RDONLY(inode))
+ goto dput_and_out;
+
+ error = -EPERM;
+ if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
+ goto dput_and_out;
+
if (user == (uid_t) -1)
user = inode->i_uid;
if (group == (gid_t) -1)
@@ -1534,38 +1566,45 @@ static inline int chown_common(char *filename, uid_t user, gid_t group, int foll
newattrs.ia_mode &= ~S_ISGID;
newattrs.ia_valid |= ATTR_MODE;
}
- inode->i_dirt = 1;
if (inode->i_sb->dq_op) {
inode->i_sb->dq_op->initialize(inode, -1);
+ error = -EDQUOT;
if (inode->i_sb->dq_op->transfer(inode, &newattrs, 0))
- return -EDQUOT;
+ goto dput_and_out;
error = notify_change(inode, &newattrs);
if (error)
inode->i_sb->dq_op->transfer(inode, &newattrs, 1);
} else
error = notify_change(inode, &newattrs);
- iput(inode);
- return(error);
+
+dput_and_out:
+ dput(dentry);
+out:
+ return error;
}
-asmlinkage int irix_chown(char *fname, int uid, int gid)
+asmlinkage int irix_chown(const char *filename, int uid, int gid)
{
int retval;
+ struct dentry *dentry;
lock_kernel();
/* Do follow any and all links... */
- retval = chown_common(fname, uid, gid, FOLLOW_LINKS);
+ dentry = namei(filename);
+ retval = chown_common(uid, gid, dentry);
unlock_kernel();
return retval;
}
-asmlinkage int irix_lchown(char *fname, int uid, int gid)
+asmlinkage int irix_lchown(const char *filename, int uid, int gid)
{
int retval;
+ struct dentry *dentry;
lock_kernel();
/* Do _not_ follow any links... */
- retval = chown_common(fname, uid, gid, NOFOLLOW_LINKS);
+ dentry = lnamei(filename);
+ retval = chown_common(uid, gid, dentry);
unlock_kernel();
return retval;
}
@@ -1722,6 +1761,7 @@ struct irix_statvfs64 {
asmlinkage int irix_statvfs64(char *fname, struct irix_statvfs64 *buf)
{
+ struct dentry *dentry;
struct inode *inode;
struct statfs kbuf;
int error, old_fs, i;
@@ -1731,20 +1771,22 @@ asmlinkage int irix_statvfs64(char *fname, struct irix_statvfs64 *buf)
error = verify_area(VERIFY_WRITE, buf, sizeof(struct irix_statvfs));
if(error)
goto out;
- error = namei(NAM_FOLLOW_LINK, fname, &inode);
- if(error)
- goto out;
- if(!inode->i_sb->s_op->statfs) {
- iput(inode);
- error = -ENOSYS;
+ dentry = namei(fname);
+ error = PTR_ERR(dentry);
+ if(IS_ERR(dentry))
goto out;
- }
+ error = -ENOSYS;
+ inode = dentry->d_inode;
+ if(!inode->i_sb->s_op->statfs)
+ goto dput_and_out;
old_fs = get_fs(); set_fs(get_ds());
- inode->i_sb->s_op->statfs(inode->i_sb, &kbuf, sizeof(struct statfs));
+ error = inode->i_sb->s_op->statfs(inode->i_sb, &kbuf,
+ sizeof(struct statfs));
set_fs(old_fs);
+ if (error)
+ goto dput_and_out;
- iput(inode);
__put_user(kbuf.f_bsize, &buf->f_bsize);
__put_user(kbuf.f_frsize, &buf->f_frsize);
__put_user(kbuf.f_blocks, &buf->f_blocks);
@@ -1767,6 +1809,8 @@ asmlinkage int irix_statvfs64(char *fname, struct irix_statvfs64 *buf)
error = 0;
+dput_and_out:
+ dput(dentry);
out:
unlock_kernel();
return error;
@@ -1774,7 +1818,8 @@ out:
asmlinkage int irix_fstatvfs64(int fd, struct irix_statvfs *buf)
{
- struct inode * inode;
+ struct dentry *dentry;
+ struct inode *inode;
struct statfs kbuf;
struct file *file;
int error, old_fs, i;
@@ -1790,7 +1835,11 @@ asmlinkage int irix_fstatvfs64(int fd, struct irix_statvfs *buf)
error = -EBADF;
goto out;
}
- if (!(inode = file->f_inode)) {
+ if (!(dentry = file->f_dentry)) {
+ error = -ENOENT;
+ goto out;
+ }
+ if (!(inode = dentry->d_inode)) {
error = -ENOENT;
goto out;
}
@@ -1800,8 +1849,11 @@ asmlinkage int irix_fstatvfs64(int fd, struct irix_statvfs *buf)
}
old_fs = get_fs(); set_fs(get_ds());
- inode->i_sb->s_op->statfs(inode->i_sb, &kbuf, sizeof(struct statfs));
+ error = inode->i_sb->s_op->statfs(inode->i_sb, &kbuf,
+ sizeof(struct statfs));
set_fs(old_fs);
+ if (error)
+ goto out;
__put_user(kbuf.f_bsize, &buf->f_bsize);
__put_user(kbuf.f_frsize, &buf->f_frsize);
@@ -1927,6 +1979,8 @@ out:
asmlinkage int irix_ngetdents(unsigned int fd, void * dirent, unsigned int count, int *eob)
{
struct file *file;
+ struct dentry *dentry;
+ struct inode *inode;
struct irix_dirent32 *lastdirent;
struct irix_dirent32_callback buf;
int error;
@@ -1936,25 +1990,34 @@ asmlinkage int irix_ngetdents(unsigned int fd, void * dirent, unsigned int count
printk("[%s:%d] ngetdents(%d, %p, %d, %p) ", current->comm,
current->pid, fd, dirent, count, eob);
#endif
- if (fd >= NR_OPEN || !(file = current->files->fd[fd])) {
- error = -EBADF;
+ error = -EBADF;
+ if (fd >= NR_OPEN || !(file = current->files->fd[fd]))
goto out;
- }
- if (!file->f_op || !file->f_op->readdir) {
- error = -ENOTDIR;
+
+ dentry = file->f_dentry;
+ if (!dentry)
goto out;
- }
- if(verify_area(VERIFY_WRITE, dirent, count) ||
- verify_area(VERIFY_WRITE, eob, sizeof(*eob))) {
- error = -EFAULT;
+
+ inode = dentry->d_inode;
+ if (!inode)
goto out;
- }
+
+ error = -ENOTDIR;
+ if (!file->f_op || !file->f_op->readdir)
+ goto out;
+
+ error = -EFAULT;
+ if(!access_ok(VERIFY_WRITE, dirent, count) ||
+ !access_ok(VERIFY_WRITE, eob, sizeof(*eob)))
+ goto out;
+
__put_user(0, eob);
buf.current_dir = (struct irix_dirent32 *) dirent;
buf.previous = NULL;
buf.count = count;
buf.error = 0;
- error = file->f_op->readdir(file->f_inode, file, &buf, irix_filldir32);
+
+ error = file->f_op->readdir(inode, file, &buf, irix_filldir32);
if (error < 0)
goto out;
lastdirent = buf.previous;
@@ -2027,6 +2090,8 @@ out:
asmlinkage int irix_getdents64(int fd, void *dirent, int cnt)
{
struct file *file;
+ struct dentry *dentry;
+ struct inode *inode;
struct irix_dirent64 *lastdirent;
struct irix_dirent64_callback buf;
int error;
@@ -2036,28 +2101,35 @@ asmlinkage int irix_getdents64(int fd, void *dirent, int cnt)
printk("[%s:%d] getdents64(%d, %p, %d) ", current->comm,
current->pid, fd, dirent, cnt);
#endif
- if (fd >= NR_OPEN || !(file = current->files->fd[fd])) {
- error = -EBADF;
+ error = -EBADF;
+ if (fd >= NR_OPEN || !(file = current->files->fd[fd]))
goto out;
- }
- if (!file->f_op || !file->f_op->readdir) {
- error = -ENOTDIR;
+
+ dentry = file->f_dentry;
+ if (!dentry)
goto out;
- }
- if(verify_area(VERIFY_WRITE, dirent, cnt)) {
- error = -EFAULT;
+
+ inode = dentry->d_inode;
+ if (!inode)
goto out;
- }
- if(cnt < (sizeof(struct irix_dirent64) + 255)) {
- error = -EINVAL;
+
+ error = -ENOTDIR;
+ if (!file->f_op || !file->f_op->readdir)
+ goto out;
+
+ error = -EFAULT;
+ if(!access_ok(VERIFY_WRITE, dirent, cnt))
+ goto out;
+
+ error = -EINVAL;
+ if(cnt < (sizeof(struct irix_dirent64) + 255))
goto out;
- }
buf.curr = (struct irix_dirent64 *) dirent;
buf.previous = NULL;
buf.count = cnt;
buf.error = 0;
- error = file->f_op->readdir(file->f_inode, file, &buf, irix_filldir64);
+ error = file->f_op->readdir(inode, file, &buf, irix_filldir64);
if (error < 0)
goto out;
lastdirent = buf.previous;
@@ -2079,6 +2151,8 @@ out:
asmlinkage int irix_ngetdents64(int fd, void *dirent, int cnt, int *eob)
{
struct file *file;
+ struct dentry *dentry;
+ struct inode *inode;
struct irix_dirent64 *lastdirent;
struct irix_dirent64_callback buf;
int error;
@@ -2088,30 +2162,37 @@ asmlinkage int irix_ngetdents64(int fd, void *dirent, int cnt, int *eob)
printk("[%s:%d] ngetdents64(%d, %p, %d) ", current->comm,
current->pid, fd, dirent, cnt);
#endif
- if (fd >= NR_OPEN || !(file = current->files->fd[fd])) {
- error = -EBADF;
+ error = -EBADF;
+ if (fd >= NR_OPEN || !(file = current->files->fd[fd]))
goto out;
- }
- if (!file->f_op || !file->f_op->readdir) {
- error = -ENOTDIR;
+
+ dentry = file->f_dentry;
+ if (!dentry)
goto out;
- }
- if(verify_area(VERIFY_WRITE, dirent, cnt) ||
- verify_area(VERIFY_WRITE, eob, sizeof(*eob))) {
- error = -EFAULT;
+
+ inode = dentry->d_inode;
+ if (!inode)
goto out;
- }
- if(cnt < (sizeof(struct irix_dirent64) + 255)) {
- error = -EINVAL;
+
+ error = -ENOTDIR;
+ if (!file->f_op || !file->f_op->readdir)
+ goto out;
+
+ error = -EFAULT;
+ if(!access_ok(VERIFY_WRITE, dirent, cnt) ||
+ !access_ok(VERIFY_WRITE, eob, sizeof(*eob)))
+ goto out;
+
+ error = -EINVAL;
+ if(cnt < (sizeof(struct irix_dirent64) + 255))
goto out;
- }
*eob = 0;
buf.curr = (struct irix_dirent64 *) dirent;
buf.previous = NULL;
buf.count = cnt;
buf.error = 0;
- error = file->f_op->readdir(file->f_inode, file, &buf, irix_filldir64);
+ error = file->f_op->readdir(inode, file, &buf, irix_filldir64);
if (error < 0)
goto out;
lastdirent = buf.previous;
diff --git a/arch/mips/kernel/sysmips.c b/arch/mips/kernel/sysmips.c
index ae99466e4..e73598345 100644
--- a/arch/mips/kernel/sysmips.c
+++ b/arch/mips/kernel/sysmips.c
@@ -7,7 +7,7 @@
*
* Copyright (C) 1995, 1996, 1997 by Ralf Baechle
*
- * $Id: sysmips.c,v 1.2 1997/06/28 23:26:25 ralf Exp $
+ * $Id: sysmips.c,v 1.2 1997/07/01 08:59:08 ralf Exp $
*/
#include <linux/errno.h>
#include <linux/linkage.h>
@@ -57,18 +57,21 @@ sys_sysmips(int cmd, int arg1, int arg2, int arg3)
switch(cmd)
{
case SETNAME:
- if (!suser()) {
- retval = -EPERM;
+ retval = -EPERM;
+ if (!suser())
goto out;
- }
+
name = (char *) arg1;
len = strlen_user(name);
+
+ retval = len;
if (len < 0)
- retval = len;
goto out;
+
+ retval = -EINVAL;
if (len == 0 || len > __NEW_UTS_LEN)
- retval = -EINVAL;
goto out;
+
copy_from_user(system_utsname.nodename, name, len);
system_utsname.nodename[len] = '\0';
retval = 0;