patch-2.1.23 linux/fs/open.c
Next file: linux/fs/pipe.c
Previous file: linux/fs/nfs/rpcsock.c
Back to the patch index
Back to the overall index
- Lines: 598
- Date:
Sun Jan 26 12:07:44 1997
- Orig file:
v2.1.22/linux/fs/open.c
- Orig date:
Thu Jan 2 15:55:23 1997
diff -u --recursive --new-file v2.1.22/linux/fs/open.c linux/fs/open.c
@@ -18,6 +18,8 @@
#include <linux/time.h>
#include <linux/mm.h>
#include <linux/file.h>
+#include <linux/smp.h>
+#include <linux/smp_lock.h>
#include <asm/uaccess.h>
#include <asm/bitops.h>
@@ -27,19 +29,24 @@
struct inode * inode;
int error;
+ lock_kernel();
error = verify_area(VERIFY_WRITE, buf, sizeof(struct statfs));
if (error)
- return error;
+ goto out;
error = namei(path,&inode);
if (error)
- return error;
+ goto out;
+ error = -ENOSYS;
if (!inode->i_sb->s_op->statfs) {
iput(inode);
- return -ENOSYS;
+ goto out;
}
inode->i_sb->s_op->statfs(inode->i_sb, buf, sizeof(struct statfs));
iput(inode);
- return 0;
+ error = 0;
+out:
+ unlock_kernel();
+ return error;
}
asmlinkage int sys_fstatfs(unsigned int fd, struct statfs * buf)
@@ -48,19 +55,23 @@
struct file * file;
int error;
+ lock_kernel();
error = verify_area(VERIFY_WRITE, buf, sizeof(struct statfs));
if (error)
- return error;
+ goto out;
if (fd >= NR_OPEN || !(file = current->files->fd[fd]))
- return -EBADF;
- if (!(inode = file->f_inode))
- return -ENOENT;
- if (!inode->i_sb)
- return -ENODEV;
- if (!inode->i_sb->s_op->statfs)
- return -ENOSYS;
- inode->i_sb->s_op->statfs(inode->i_sb, buf, sizeof(struct statfs));
- return 0;
+ error = -EBADF;
+ else if (!(inode = file->f_inode))
+ error = -ENOENT;
+ else if (!inode->i_sb)
+ error = -ENODEV;
+ else if (!inode->i_sb->s_op->statfs)
+ error = -ENOSYS;
+ else
+ inode->i_sb->s_op->statfs(inode->i_sb, buf, sizeof(struct statfs));
+out:
+ unlock_kernel();
+ return error;
}
int do_truncate(struct inode *inode, unsigned long length)
@@ -87,29 +98,30 @@
struct inode * inode;
int error;
+ lock_kernel();
error = namei(path,&inode);
if (error)
- return error;
+ goto out;
error = -EACCES;
if (S_ISDIR(inode->i_mode))
- goto out;
+ goto iput_and_out;
error = permission(inode,MAY_WRITE);
if (error)
- goto out;
+ goto iput_and_out;
error = -EROFS;
if (IS_RDONLY(inode))
- goto out;
+ goto iput_and_out;
error = -EPERM;
if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
- goto out;
+ goto iput_and_out;
error = get_write_access(inode);
if (error)
- goto out;
+ goto iput_and_out;
error = locks_verify_area(FLOCK_VERIFY_WRITE, inode, NULL,
length < inode->i_size ? length : inode->i_size,
@@ -120,8 +132,10 @@
error = do_truncate(inode, length);
}
put_write_access(inode);
-out:
+iput_and_out:
iput(inode);
+out:
+ unlock_kernel();
return error;
}
@@ -131,19 +145,23 @@
struct file * file;
int error;
+ lock_kernel();
if (fd >= NR_OPEN || !(file = current->files->fd[fd]))
- return -EBADF;
- if (!(inode = file->f_inode))
- return -ENOENT;
- if (S_ISDIR(inode->i_mode) || !(file->f_mode & FMODE_WRITE))
- return -EACCES;
- if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
- return -EPERM;
- error = locks_verify_area(FLOCK_VERIFY_WRITE, inode, file,
- length < inode->i_size ? length : inode->i_size,
- abs(inode->i_size - length));
- if (!error)
- error = do_truncate(inode, length);
+ error = -EBADF;
+ else if (!(inode = file->f_inode))
+ error = -ENOENT;
+ else if (S_ISDIR(inode->i_mode) || !(file->f_mode & FMODE_WRITE))
+ error = -EACCES;
+ else if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
+ error = -EPERM;
+ else {
+ error = locks_verify_area(FLOCK_VERIFY_WRITE, inode, file,
+ length<inode->i_size ? length : inode->i_size,
+ abs(inode->i_size - length));
+ if (!error)
+ error = do_truncate(inode, length);
+ }
+ unlock_kernel();
return error;
}
@@ -166,12 +184,14 @@
struct inode * inode;
struct iattr newattrs;
+ lock_kernel();
error = namei(filename,&inode);
if (error)
- return error;
+ goto out;
+ error = -EROFS;
if (IS_RDONLY(inode)) {
iput(inode);
- return -EROFS;
+ goto out;
}
/* Don't worry, the checks are done in inode_change_ok() */
newattrs.ia_valid = ATTR_CTIME | ATTR_MTIME | ATTR_ATIME;
@@ -181,18 +201,20 @@
error = get_user(newattrs.ia_mtime, ×->modtime);
if (error) {
iput(inode);
- return error;
+ goto out;
}
newattrs.ia_valid |= ATTR_ATIME_SET | ATTR_MTIME_SET;
} else {
if (current->fsuid != inode->i_uid &&
(error = permission(inode,MAY_WRITE)) != 0) {
iput(inode);
- return error;
+ goto out;
}
}
error = notify_change(inode, &newattrs);
iput(inode);
+out:
+ unlock_kernel();
return error;
}
@@ -208,32 +230,32 @@
struct inode * inode;
struct iattr newattrs;
+ lock_kernel();
error = namei(filename,&inode);
if (error)
- return error;
- if (IS_RDONLY(inode)) {
- iput(inode);
- return -EROFS;
- }
+ goto out;
+ error = -EROFS;
+ if (IS_RDONLY(inode))
+ goto iput_and_out;
/* Don't worry, the checks are done in inode_change_ok() */
newattrs.ia_valid = ATTR_CTIME | ATTR_MTIME | ATTR_ATIME;
if (utimes) {
struct timeval times[2];
- if (copy_from_user(×, utimes, sizeof(times))) {
- iput(inode);
- return -EFAULT;
- }
+ error = -EFAULT;
+ if (copy_from_user(×, utimes, sizeof(times)))
+ goto iput_and_out;
newattrs.ia_atime = times[0].tv_sec;
newattrs.ia_mtime = times[1].tv_sec;
newattrs.ia_valid |= ATTR_ATIME_SET | ATTR_MTIME_SET;
} else {
- if ((error = permission(inode,MAY_WRITE)) != 0) {
- iput(inode);
- return error;
- }
+ if ((error = permission(inode,MAY_WRITE)) != 0)
+ goto iput_and_out;
}
error = notify_change(inode, &newattrs);
+iput_and_out:
iput(inode);
+out:
+ unlock_kernel();
return error;
}
@@ -245,10 +267,11 @@
{
struct inode * inode;
int old_fsuid, old_fsgid;
- int res;
+ int res = -EINVAL;
+ lock_kernel();
if (mode != (mode & S_IRWXO)) /* where's F_OK, X_OK, W_OK, R_OK? */
- return -EINVAL;
+ goto out;
old_fsuid = current->fsuid;
old_fsgid = current->fsgid;
current->fsuid = current->uid;
@@ -260,6 +283,8 @@
}
current->fsuid = old_fsuid;
current->fsgid = old_fsgid;
+out:
+ unlock_kernel();
return res;
}
@@ -268,40 +293,51 @@
struct inode * inode;
int error;
+ lock_kernel();
error = namei(filename,&inode);
if (error)
- return error;
+ goto out;
+ error = -ENOTDIR;
if (!S_ISDIR(inode->i_mode)) {
iput(inode);
- return -ENOTDIR;
+ goto out;
}
if ((error = permission(inode,MAY_EXEC)) != 0) {
iput(inode);
- return error;
+ goto out;
}
iput(current->fs->pwd);
current->fs->pwd = inode;
- return (0);
+ error = 0;
+out:
+ unlock_kernel();
+ return error;
}
asmlinkage int sys_fchdir(unsigned int fd)
{
struct inode * inode;
struct file * file;
- int error;
+ int error = -EBADF;
+ lock_kernel();
if (fd >= NR_OPEN || !(file = current->files->fd[fd]))
- return -EBADF;
+ goto out;
+ error = -ENOENT;
if (!(inode = file->f_inode))
- return -ENOENT;
+ goto out;
+ error = -ENOTDIR;
if (!S_ISDIR(inode->i_mode))
- return -ENOTDIR;
+ goto out;
if ((error = permission(inode,MAY_EXEC)) != 0)
- return error;
+ goto out;
iput(current->fs->pwd);
current->fs->pwd = inode;
inode->i_count++;
- return (0);
+ error = 0;
+out:
+ unlock_kernel();
+ return error;
}
asmlinkage int sys_chroot(const char * filename)
@@ -309,20 +345,26 @@
struct inode * inode;
int error;
+ lock_kernel();
error = namei(filename,&inode);
if (error)
- return error;
+ goto out;
+ error = -ENOTDIR;
if (!S_ISDIR(inode->i_mode)) {
iput(inode);
- return -ENOTDIR;
+ goto out;
}
+ error = -EPERM;
if (!fsuser()) {
iput(inode);
- return -EPERM;
+ goto out;
}
iput(current->fs->root);
current->fs->root = inode;
- return (0);
+ error = 0;
+out:
+ unlock_kernel();
+ return error;
}
asmlinkage int sys_fchmod(unsigned int fd, mode_t mode)
@@ -330,21 +372,29 @@
struct inode * inode;
struct file * file;
struct iattr newattrs;
+ int err = -EBADF;
+ lock_kernel();
if (fd >= NR_OPEN || !(file = current->files->fd[fd]))
- return -EBADF;
+ goto out;
+ err = -ENOENT;
if (!(inode = file->f_inode))
- return -ENOENT;
+ goto out;
+ err = -EROFS;
if (IS_RDONLY(inode))
- return -EROFS;
+ goto out;
+ err = -EPERM;
if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
- return -EPERM;
+ goto out;
if (mode == (mode_t) -1)
mode = inode->i_mode;
newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO);
newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
inode->i_dirt = 1;
- return notify_change(inode, &newattrs);
+ err = notify_change(inode, &newattrs);
+out:
+ unlock_kernel();
+ return err;
}
asmlinkage int sys_chmod(const char * filename, mode_t mode)
@@ -353,24 +403,26 @@
int error;
struct iattr newattrs;
+ lock_kernel();
error = namei(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;
- }
+ goto out;
+ error = -EROFS;
+ if (IS_RDONLY(inode))
+ goto iput_and_out;
+ error = -EPERM;
+ if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
+ goto iput_and_out;
if (mode == (mode_t) -1)
mode = inode->i_mode;
newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO);
newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
inode->i_dirt = 1;
error = notify_change(inode, &newattrs);
+iput_and_out:
iput(inode);
+out:
+ unlock_kernel();
return error;
}
@@ -379,16 +431,20 @@
struct inode * inode;
struct file * file;
struct iattr newattrs;
- int error;
+ int error = -EBADF;
+ lock_kernel();
if (fd >= NR_OPEN || !(file = current->files->fd[fd]))
- return -EBADF;
+ goto out;
+ error = -ENOENT;
if (!(inode = file->f_inode))
- return -ENOENT;
+ goto out;
+ error = -EROFS;
if (IS_RDONLY(inode))
- return -EROFS;
+ goto out;
+ error = -EPERM;
if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
- return -EPERM;
+ goto out;
if (user == (uid_t) -1)
user = inode->i_uid;
if (group == (gid_t) -1)
@@ -417,13 +473,16 @@
inode->i_dirt = 1;
if (inode->i_sb && 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 out;
error = notify_change(inode, &newattrs);
if (error)
inode->i_sb->dq_op->transfer(inode, &newattrs, 1);
} else
error = notify_change(inode, &newattrs);
+out:
+ unlock_kernel();
return error;
}
@@ -433,17 +492,16 @@
int error;
struct iattr newattrs;
+ lock_kernel();
error = lnamei(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;
- }
+ goto out;
+ error = -EROFS;
+ if (IS_RDONLY(inode))
+ goto iput_and_out;
+ error = -EPERM;
+ if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
+ goto iput_and_out;
if (user == (uid_t) -1)
user = inode->i_uid;
if (group == (gid_t) -1)
@@ -472,14 +530,18 @@
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 out;
error = notify_change(inode, &newattrs);
if (error)
inode->i_sb->dq_op->transfer(inode, &newattrs, 1);
} else
error = notify_change(inode, &newattrs);
+iput_and_out:
iput(inode);
+out:
+ unlock_kernel();
return(error);
}
@@ -574,17 +636,24 @@
char * tmp;
int fd, error;
+ lock_kernel();
fd = get_unused_fd();
- if (fd < 0)
- return fd;
+ if (fd < 0) {
+ error = fd;
+ goto out;
+ }
error = getname(filename, &tmp);
if (!error) {
error = do_open(tmp,flags,mode, fd);
putname(tmp);
- if (!error)
- return fd;
+ if (!error) {
+ error = fd;
+ goto out;
+ }
}
put_unused_fd(fd);
+out:
+ unlock_kernel();
return error;
}
@@ -596,7 +665,12 @@
*/
asmlinkage int sys_creat(const char * pathname, int mode)
{
- return sys_open(pathname, O_CREAT | O_WRONLY | O_TRUNC, mode);
+ int ret;
+
+ lock_kernel();
+ ret = sys_open(pathname, O_CREAT | O_WRONLY | O_TRUNC, mode);
+ unlock_kernel();
+ return ret;
}
#endif
@@ -632,6 +706,7 @@
struct file * filp;
struct files_struct * files;
+ lock_kernel();
files = current->files;
error = -EBADF;
if (fd < NR_OPEN && (filp = files->fd[fd]) != NULL) {
@@ -640,6 +715,7 @@
files->fd[fd] = NULL;
error = close_fp(filp);
}
+ unlock_kernel();
return error;
}
@@ -649,10 +725,16 @@
*/
asmlinkage int sys_vhangup(void)
{
+ int ret = -EPERM;
+
+ lock_kernel();
if (!suser())
- return -EPERM;
+ goto out;
/* If there is a controlling tty, hang it up */
if (current->tty)
tty_vhangup(current->tty);
- return 0;
+ ret = 0;
+out:
+ unlock_kernel();
+ return ret;
}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov