summaryrefslogtreecommitdiffstats
path: root/fs/open.c
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>1999-09-28 22:25:29 +0000
committerRalf Baechle <ralf@linux-mips.org>1999-09-28 22:25:29 +0000
commit0ae8dceaebe3659ee0c3352c08125f403e77ebca (patch)
tree5085c389f09da78182b899d19fe1068b619a69dd /fs/open.c
parent273767781288c35c9d679e908672b9996cda4c34 (diff)
Merge with 2.3.10.
Diffstat (limited to 'fs/open.c')
-rw-r--r--fs/open.c74
1 files changed, 39 insertions, 35 deletions
diff --git a/fs/open.c b/fs/open.c
index deb898f76..c0f806f69 100644
--- a/fs/open.c
+++ b/fs/open.c
@@ -37,29 +37,21 @@ asmlinkage int sys_statfs(const char * path, struct statfs * buf)
asmlinkage int sys_fstatfs(unsigned int fd, struct statfs * buf)
{
struct file * file;
- struct inode * inode;
- struct dentry * dentry;
struct super_block * sb;
int error;
- lock_kernel();
error = -EBADF;
file = fget(fd);
if (!file)
goto out;
- error = -ENOENT;
- if (!(dentry = file->f_dentry))
- goto out_putf;
- if (!(inode = dentry->d_inode))
- goto out_putf;
error = -ENODEV;
- sb = inode->i_sb;
+ sb = file->f_dentry->d_inode->i_sb;
+ lock_kernel();
if (sb && sb->s_op && sb->s_op->statfs)
error = sb->s_op->statfs(sb, buf, sizeof(struct statfs));
-out_putf:
+ unlock_kernel();
fput(file);
out:
- unlock_kernel();
return error;
}
@@ -143,7 +135,6 @@ asmlinkage int sys_ftruncate(unsigned int fd, unsigned long length)
struct file * file;
int error;
- lock_kernel();
error = -EBADF;
file = fget(fd);
if (!file)
@@ -162,12 +153,13 @@ asmlinkage int sys_ftruncate(unsigned int fd, unsigned long length)
error = locks_verify_area(FLOCK_VERIFY_WRITE, inode, file,
length<inode->i_size ? length : inode->i_size,
abs(inode->i_size - length));
+ lock_kernel();
if (!error)
error = do_truncate(dentry, length);
+ unlock_kernel();
out_putf:
fput(file);
out:
- unlock_kernel();
return error;
}
@@ -361,8 +353,6 @@ asmlinkage int sys_fchdir(unsigned int fd)
struct inode *inode;
int error;
- lock_kernel();
-
error = -EBADF;
file = fget(fd);
if (!file)
@@ -378,16 +368,17 @@ asmlinkage int sys_fchdir(unsigned int fd)
if (!S_ISDIR(inode->i_mode))
goto out_putf;
+ lock_kernel();
error = permission(inode, MAY_EXEC);
if (!error) {
struct dentry *tmp = current->fs->pwd;
current->fs->pwd = dget(dentry);
dput(tmp);
}
+ unlock_kernel();
out_putf:
fput(file);
out:
- unlock_kernel();
return error;
}
@@ -439,7 +430,6 @@ asmlinkage int sys_fchmod(unsigned int fd, mode_t mode)
int err = -EBADF;
struct iattr newattrs;
- lock_kernel();
file = fget(fd);
if (!file)
goto out;
@@ -460,12 +450,13 @@ asmlinkage int sys_fchmod(unsigned int fd, mode_t mode)
mode = inode->i_mode;
newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO);
newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
+ lock_kernel();
err = notify_change(dentry, &newattrs);
+ unlock_kernel();
out_putf:
fput(file);
out:
- unlock_kernel();
return err;
}
@@ -601,17 +592,17 @@ asmlinkage int sys_fchown(unsigned int fd, uid_t user, gid_t group)
struct file * file;
int error = -EBADF;
- lock_kernel();
file = fget(fd);
if (!file)
goto out;
error = -ENOENT;
+ lock_kernel();
if ((dentry = file->f_dentry) != NULL)
error = chown_common(dentry, user, group);
+ unlock_kernel();
fput(file);
out:
- unlock_kernel();
return error;
}
@@ -663,6 +654,8 @@ struct file *filp_open(const char * filename, int flags, int mode)
f->f_op = NULL;
if (inode->i_op)
f->f_op = inode->i_op->default_file_ops;
+ if (inode->i_sb)
+ file_move(f, &inode->i_sb->s_files);
if (f->f_op && f->f_op->open) {
error = f->f_op->open(inode,f);
if (error)
@@ -693,6 +686,8 @@ int get_unused_fd(void)
int fd, error;
error = -EMFILE;
+
+ write_lock(&files->file_lock);
fd = find_first_zero_bit(&files->open_fds, NR_OPEN);
/*
* N.B. For clone tasks sharing a files structure, this test
@@ -715,12 +710,15 @@ int get_unused_fd(void)
error = fd;
out:
+ write_unlock(&files->file_lock);
return error;
}
inline void put_unused_fd(unsigned int fd)
{
+ write_lock(&current->files->file_lock);
FD_CLR(fd, &current->files->open_fds);
+ write_unlock(&current->files->file_lock);
}
asmlinkage int sys_open(const char * filename, int flags, int mode)
@@ -731,17 +729,18 @@ asmlinkage int sys_open(const char * filename, int flags, int mode)
tmp = getname(filename);
fd = PTR_ERR(tmp);
if (!IS_ERR(tmp)) {
- lock_kernel();
fd = get_unused_fd();
if (fd >= 0) {
- struct file * f = filp_open(tmp, flags, mode);
+ struct file * f;
+ lock_kernel();
+ f = filp_open(tmp, flags, mode);
+ unlock_kernel();
error = PTR_ERR(f);
if (IS_ERR(f))
goto out_error;
fd_install(fd, f);
}
out:
- unlock_kernel();
putname(tmp);
}
return fd;
@@ -790,7 +789,7 @@ int filp_close(struct file *filp, fl_owner_t id)
int retval;
struct dentry *dentry = filp->f_dentry;
- if (!atomic_read(&filp->f_count)) {
+ if (!file_count(filp)) {
printk("VFS: Close: file count is 0\n");
return 0;
}
@@ -812,19 +811,24 @@ asmlinkage int sys_close(unsigned int fd)
{
int error;
struct file * filp;
+ struct files_struct * files = current->files;
- lock_kernel();
error = -EBADF;
- filp = fcheck(fd);
- if (filp) {
- struct files_struct * files = current->files;
- files->fd[fd] = NULL;
- put_unused_fd(fd);
- FD_CLR(fd, &files->close_on_exec);
- error = filp_close(filp, files);
- }
+ write_lock(&files->file_lock);
+ filp = frip(fd);
+ if (!filp)
+ goto out_unlock;
+ FD_CLR(fd, &files->close_on_exec);
+ write_unlock(&files->file_lock);
+ put_unused_fd(fd);
+ lock_kernel();
+ error = filp_close(filp, files);
unlock_kernel();
+out:
return error;
+out_unlock:
+ write_unlock(&files->file_lock);
+ goto out;
}
/*
@@ -835,14 +839,14 @@ asmlinkage int sys_vhangup(void)
{
int ret = -EPERM;
- lock_kernel();
if (!capable(CAP_SYS_TTY_CONFIG))
goto out;
/* If there is a controlling tty, hang it up */
+ lock_kernel();
if (current->tty)
tty_vhangup(current->tty);
+ unlock_kernel();
ret = 0;
out:
- unlock_kernel();
return ret;
}