diff options
author | Ralf Baechle <ralf@linux-mips.org> | 1999-09-28 22:25:29 +0000 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 1999-09-28 22:25:29 +0000 |
commit | 0ae8dceaebe3659ee0c3352c08125f403e77ebca (patch) | |
tree | 5085c389f09da78182b899d19fe1068b619a69dd /fs/open.c | |
parent | 273767781288c35c9d679e908672b9996cda4c34 (diff) |
Merge with 2.3.10.
Diffstat (limited to 'fs/open.c')
-rw-r--r-- | fs/open.c | 74 |
1 files changed, 39 insertions, 35 deletions
@@ -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(¤t->files->file_lock); FD_CLR(fd, ¤t->files->open_fds); + write_unlock(¤t->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; } |