patch-2.1.45 linux/fs/open.c

Next file: linux/fs/pipe.c
Previous file: linux/fs/nfsd/vfs.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.1.44/linux/fs/open.c linux/fs/open.c
@@ -4,7 +4,6 @@
  *  Copyright (C) 1991, 1992  Linus Torvalds
  */
 
-#include <linux/config.h>
 #include <linux/vfs.h>
 #include <linux/types.h>
 #include <linux/utime.h>
@@ -21,32 +20,27 @@
 #include <linux/file.h>
 #include <linux/smp.h>
 #include <linux/smp_lock.h>
-#include <linux/omirr.h>
 
 #include <asm/uaccess.h>
 #include <asm/bitops.h>
 
 asmlinkage int sys_statfs(const char * path, struct statfs * buf)
 {
-	struct inode * inode;
+	struct dentry * dentry;
 	int error;
 
 	lock_kernel();
-	error = verify_area(VERIFY_WRITE, buf, sizeof(struct statfs));
-	if (error)
-		goto out;
-	error = namei(path, &inode);
-	if (error)
-		goto out;
-	error = -ENOSYS;
-	if (!inode->i_sb->s_op->statfs) {
-		iput(inode);
-		goto out;
+	dentry = namei(path);
+	error = PTR_ERR(dentry);
+	if (!IS_ERR(dentry)) {
+		struct inode * inode = dentry->d_inode;
+
+		error = -ENOSYS;
+		if (inode->i_sb->s_op->statfs)
+			error = inode->i_sb->s_op->statfs(inode->i_sb, buf, sizeof(struct statfs));
+
+		dput(dentry);
 	}
-	inode->i_sb->s_op->statfs(inode->i_sb, buf, sizeof(struct statfs));
-	iput(inode);
-	error = 0;
-out:
 	unlock_kernel();
 	return error;
 }
@@ -54,6 +48,7 @@
 asmlinkage int sys_fstatfs(unsigned int fd, struct statfs * buf)
 {
 	struct inode * inode;
+	struct dentry * dentry;
 	struct file * file;
 	int error;
 
@@ -63,7 +58,9 @@
 		goto out;
 	if (fd >= NR_OPEN || !(file = current->files->fd[fd]))
 		error = -EBADF;
-	else if (!(inode = file->f_inode))
+	else if (!(dentry = file->f_dentry))
+		error = -ENOENT;
+	else if (!(inode = dentry->d_inode))
 		error = -ENOENT;
 	else if (!inode->i_sb)
 		error = -ENODEV;
@@ -90,7 +87,6 @@
 		vmtruncate(inode, length);
 		if (inode->i_op && inode->i_op->truncate)
 			inode->i_op->truncate(inode);
-		inode->i_status |= ST_MODIFIED;
 	}
 	up(&inode->i_sem);
 	return error;
@@ -98,33 +94,37 @@
 
 asmlinkage int sys_truncate(const char * path, unsigned long length)
 {
+	struct dentry * dentry;
 	struct inode * inode;
 	int error;
 
 	lock_kernel();
-	error = namei(path, &inode);
-	if (error)
+	dentry = namei(path);
+
+	error = PTR_ERR(dentry);
+	if (IS_ERR(dentry))
 		goto out;
+	inode = dentry->d_inode;
 
 	error = -EACCES;
 	if (S_ISDIR(inode->i_mode))
-		goto iput_and_out;
+		goto dput_and_out;
 
 	error = permission(inode,MAY_WRITE);
 	if (error)
-		goto iput_and_out;
+		goto dput_and_out;
 
 	error = -EROFS;
 	if (IS_RDONLY(inode))
-		goto iput_and_out;
+		goto dput_and_out;
 
 	error = -EPERM;
 	if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
-		goto iput_and_out;
+		goto dput_and_out;
 
 	error = get_write_access(inode);
 	if (error)
-		goto iput_and_out;
+		goto dput_and_out;
 
 	error = locks_verify_area(FLOCK_VERIFY_WRITE, inode, NULL,
 				  length < inode->i_size ? length : inode->i_size,
@@ -135,8 +135,8 @@
 		error = do_truncate(inode, length);
 	}
 	put_write_access(inode);
-iput_and_out:
-	iput(inode);
+dput_and_out:
+	dput(dentry);
 out:
 	unlock_kernel();
 	return error;
@@ -145,13 +145,16 @@
 asmlinkage int sys_ftruncate(unsigned int fd, unsigned long length)
 {
 	struct inode * inode;
+	struct dentry *dentry;
 	struct file * file;
 	int error;
 
 	lock_kernel();
 	if (fd >= NR_OPEN || !(file = current->files->fd[fd]))
 		error = -EBADF;
-	else if (!(inode = file->f_inode))
+	else if (!(dentry = file->f_dentry))
+		error = -ENOENT;
+	else if (!(inode = dentry->d_inode))
 		error = -ENOENT;
 	else if (S_ISDIR(inode->i_mode) || !(file->f_mode & FMODE_WRITE))
 		error = -EACCES;
@@ -184,17 +187,21 @@
 asmlinkage int sys_utime(char * filename, struct utimbuf * times)
 {
 	int error;
+	struct dentry * dentry;
 	struct inode * inode;
 	struct iattr newattrs;
 
 	lock_kernel();
-	/* Hmm, should I always follow symlinks or not ? */
-	error = namei(filename, &inode);
-	if (error)
+	dentry = namei(filename);
+
+	error = PTR_ERR(dentry);
+	if (IS_ERR(dentry))
 		goto out;
+	inode = dentry->d_inode;
+
 	error = -EROFS;
 	if (IS_RDONLY(inode))
-		goto iput_and_out;
+		goto dput_and_out;
 
 	/* Don't worry, the checks are done in inode_change_ok() */
 	newattrs.ia_valid = ATTR_CTIME | ATTR_MTIME | ATTR_ATIME;
@@ -203,22 +210,17 @@
 		if (!error) 
 			error = get_user(newattrs.ia_mtime, &times->modtime);
 		if (error)
-			goto iput_and_out;
+			goto dput_and_out;
 
 		newattrs.ia_valid |= ATTR_ATIME_SET | ATTR_MTIME_SET;
 	} else {
 		if (current->fsuid != inode->i_uid &&
 		    (error = permission(inode,MAY_WRITE)) != 0)
-			goto iput_and_out;
+			goto dput_and_out;
 	}
 	error = notify_change(inode, &newattrs);
-#ifdef CONFIG_OMIRR
-	if(!error)
-		omirr_printall(inode, " U %ld %ld %ld ", CURRENT_TIME,
-				newattrs.ia_atime, newattrs.ia_mtime);
-#endif
-iput_and_out:
-	iput(inode);
+dput_and_out:
+	dput(dentry);
 out:
 	unlock_kernel();
 	return error;
@@ -233,38 +235,39 @@
 asmlinkage int sys_utimes(char * filename, struct timeval * utimes)
 {
 	int error;
+	struct dentry * dentry;
 	struct inode * inode;
 	struct iattr newattrs;
 
 	lock_kernel();
-	error = namei(filename, &inode);
-	if (error)
+	dentry = namei(filename);
+
+	error = PTR_ERR(dentry);
+	if (IS_ERR(dentry))
 		goto out;
+	inode = dentry->d_inode;
+
 	error = -EROFS;
 	if (IS_RDONLY(inode))
-		goto iput_and_out;
+		goto dput_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];
 		error = -EFAULT;
 		if (copy_from_user(&times, utimes, sizeof(times)))
-			goto iput_and_out;
+			goto dput_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)
-			goto iput_and_out;
+			goto dput_and_out;
 	}
 	error = notify_change(inode, &newattrs);
-#ifdef CONFIG_OMIRR
-	if(!error)
-		omirr_printall(inode, " U %ld %ld %ld ", CURRENT_TIME,
-				newattrs.ia_atime, newattrs.ia_mtime);
-#endif
-iput_and_out:
-	iput(inode);
+dput_and_out:
+	dput(dentry);
 out:
 	unlock_kernel();
 	return error;
@@ -276,7 +279,7 @@
  */
 asmlinkage int sys_access(const char * filename, int mode)
 {
-	struct inode * inode;
+	struct dentry * dentry;
 	int old_fsuid, old_fsgid;
 	int res = -EINVAL;
 
@@ -287,11 +290,14 @@
 	old_fsgid = current->fsgid;
 	current->fsuid = current->uid;
 	current->fsgid = current->gid;
-	res = namei(filename, &inode);
-	if (!res) {
-		res = permission(inode, mode);
-		iput(inode);
+
+	dentry = namei(filename);
+	res = PTR_ERR(dentry);
+	if (!IS_ERR(dentry)) {
+		res = permission(dentry->d_inode, mode);
+		dput(dentry);
 	}
+
 	current->fsuid = old_fsuid;
 	current->fsgid = old_fsgid;
 out:
@@ -307,17 +313,14 @@
 
 	lock_kernel();
 	
-	dentry = lookup_dentry(filename, NULL, 1);
+	dentry = namei(filename);
 	error = PTR_ERR(dentry);
 	if (IS_ERR(dentry))
 		goto out;
 
-	error = -ENOENT;
-	if (dentry->d_flag & D_NEGATIVE)
-		goto dput_and_out;
+	inode = dentry->d_inode;
 
 	error = -ENOTDIR;
-	inode = dentry->d_inode;
 	if (!S_ISDIR(inode->i_mode))
 		goto dput_and_out;
 
@@ -340,8 +343,8 @@
 asmlinkage int sys_fchdir(unsigned int fd)
 {
 	struct file *file;
+	struct dentry *dentry;
 	struct inode *inode;
-	struct dentry *dentry, *tmp;
 	int error;
 
 	lock_kernel();
@@ -351,7 +354,9 @@
 		goto out;
 
 	error = -ENOENT;
-	if (!(inode = file->f_inode))
+	if (!(dentry = file->f_dentry))
+		goto out;
+	if (!(inode = dentry->d_inode))
 		goto out;
 
 	error = -ENOTDIR;
@@ -362,10 +367,13 @@
 	if (error)
 		goto out;
 
-	dentry = dget(inode->i_dentry);
-	tmp = current->fs->pwd;
-	current->fs->pwd = dentry;
-	dput(tmp);
+	{
+		struct dentry *tmp;
+	
+		tmp = current->fs->pwd;
+		current->fs->pwd = dget(dentry);
+		dput(tmp);
+	}
 out:
 	unlock_kernel();
 	return error;
@@ -379,17 +387,14 @@
 
 	lock_kernel();
 	
-	dentry = lookup_dentry(filename, NULL, 1);
+	dentry = namei(filename);
 	error = PTR_ERR(dentry);
 	if (IS_ERR(dentry))
 		goto out;
 
-	error = -ENOENT;
-	if (dentry->d_flag & D_NEGATIVE)
-		goto dput_and_out;
+	inode = dentry->d_inode;
 
 	error = -ENOTDIR;
-	inode = dentry->d_inode;
 	if (!S_ISDIR(inode->i_mode))
 		goto dput_and_out;
 
@@ -405,6 +410,7 @@
 	tmp = current->fs->root;
 	current->fs->root = dentry;
 	dentry = tmp;
+	error = 0;
 
 dput_and_out:
 	dput(dentry);
@@ -416,6 +422,7 @@
 asmlinkage int sys_fchmod(unsigned int fd, mode_t mode)
 {
 	struct inode * inode;
+	struct dentry * dentry;
 	struct file * file;
 	struct iattr newattrs;
 	int err = -EBADF;
@@ -424,7 +431,9 @@
 	if (fd >= NR_OPEN || !(file = current->files->fd[fd]))
 		goto out;
 	err = -ENOENT;
-	if (!(inode = file->f_inode))
+	if (!(dentry = file->f_dentry))
+		goto out;
+	if (!(inode = dentry->d_inode))
 		goto out;
 	err = -EROFS;
 	if (IS_RDONLY(inode))
@@ -436,12 +445,7 @@
 		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;
 	err = notify_change(inode, &newattrs);
-#ifdef CONFIG_OMIRR
-	if(!err)
-		omirr_printall(inode, " M %ld %ld ", CURRENT_TIME, newattrs.ia_mode);
-#endif
 out:
 	unlock_kernel();
 	return err;
@@ -449,36 +453,35 @@
 
 asmlinkage int sys_chmod(const char * filename, mode_t mode)
 {
+	struct dentry * dentry;
 	struct inode * inode;
 	int error;
 	struct iattr newattrs;
 
 	lock_kernel();
-	/* I'm not sure whether to use NAM_FOLLOW_TRAILSLASH instead,
-	 * because permissions on symlinks now can never be changed,
-	 * but on the other hand they are never needed.
-	 */
-	error = namei(filename, &inode);
-	if (error)
+	dentry = namei(filename);
+
+	error = PTR_ERR(dentry);
+	if (IS_ERR(dentry))
 		goto out;
+	inode = dentry->d_inode;
+
 	error = -EROFS;
 	if (IS_RDONLY(inode))
-		goto iput_and_out;
+		goto dput_and_out;
+
 	error = -EPERM;
 	if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
-		goto iput_and_out;
+		goto dput_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);
-#ifdef CONFIG_OMIRR
-	if(!error)
-		omirr_printall(inode, " M %ld %ld ", CURRENT_TIME, newattrs.ia_mode);
-#endif
-iput_and_out:
-	iput(inode);
+
+dput_and_out:
+	dput(dentry);
 out:
 	unlock_kernel();
 	return error;
@@ -487,6 +490,7 @@
 asmlinkage int sys_fchown(unsigned int fd, uid_t user, gid_t group)
 {
 	struct inode * inode;
+	struct dentry * dentry;
 	struct file * file;
 	struct iattr newattrs;
 	int error = -EBADF;
@@ -495,7 +499,9 @@
 	if (fd >= NR_OPEN || !(file = current->files->fd[fd]))
 		goto out;
 	error = -ENOENT;
-	if (!(inode = file->f_inode))
+	if (!(dentry = file->f_dentry))
+		goto out;
+	if (!(inode = dentry->d_inode))
 		goto out;
 	error = -EROFS;
 	if (IS_RDONLY(inode))
@@ -528,7 +534,6 @@
 		newattrs.ia_mode &= ~S_ISGID;
 		newattrs.ia_valid |= ATTR_MODE;
 	}
-	inode->i_dirt = 1;
 	if (inode->i_sb && inode->i_sb->dq_op) {
 		inode->i_sb->dq_op->initialize(inode, -1);
 		error = -EDQUOT;
@@ -539,11 +544,6 @@
 			inode->i_sb->dq_op->transfer(inode, &newattrs, 1);
 	} else
 		error = notify_change(inode, &newattrs);
-#ifdef CONFIG_OMIRR
-	if(!error)
-		omirr_printall(inode, " O %d %d ", CURRENT_TIME,
-				newattrs.ia_uid, newattrs.ia_gid);
-#endif
 out:
 	unlock_kernel();
 	return error;
@@ -551,20 +551,27 @@
 
 asmlinkage int sys_chown(const char * filename, uid_t user, gid_t group)
 {
+	struct dentry * dentry;
 	struct inode * inode;
 	int error;
 	struct iattr newattrs;
 
 	lock_kernel();
-	error = namei(filename, &inode);
-	if (error)
+	dentry = namei(filename);
+
+	error = PTR_ERR(dentry);
+	if (IS_ERR(dentry))
 		goto out;
+	inode = dentry->d_inode;
+
 	error = -EROFS;
 	if (IS_RDONLY(inode))
-		goto iput_and_out;
+		goto dput_and_out;
+
 	error = -EPERM;
 	if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
-		goto iput_and_out;
+		goto dput_and_out;
+
 	if (user == (uid_t) -1)
 		user = inode->i_uid;
 	if (group == (gid_t) -1)
@@ -590,24 +597,18 @@
 		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))
-			goto iput_and_out;
+			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);
-#ifdef CONFIG_OMIRR
-	if(!error)
-		omirr_printall(inode, " O %d %d ", CURRENT_TIME,
-				newattrs.ia_uid, newattrs.ia_gid);
-#endif
-iput_and_out:
-	iput(inode);
+dput_and_out:
+	dput(dentry);
 out:
 	unlock_kernel();
 	return(error);
@@ -630,6 +631,7 @@
 static int do_open(const char * filename,int flags,int mode, int fd)
 {
 	struct inode * inode;
+	struct dentry * dentry;
 	struct file * f;
 	int flag,error;
 
@@ -642,16 +644,18 @@
 		flag++;
 	if (flag & O_TRUNC)
 		flag |= 2;
-	error = open_namei(filename,flag,mode,&inode,NULL);
-	if (error)
+	dentry = open_namei(filename,flag,mode);
+	error = PTR_ERR(dentry);
+	if (IS_ERR(dentry))
 		goto cleanup_file;
+	inode = dentry->d_inode;
 	if (f->f_mode & FMODE_WRITE) {
 		error = get_write_access(inode);
 		if (error)
-			goto cleanup_inode;
+			goto cleanup_dentry;
 	}
 
-	f->f_inode = inode;
+	f->f_dentry = dentry;
 	f->f_pos = 0;
 	f->f_reada = 0;
 	f->f_op = NULL;
@@ -670,8 +674,8 @@
 cleanup_all:
 	if (f->f_mode & FMODE_WRITE)
 		put_write_access(inode);
-cleanup_inode:
-	iput(inode);
+cleanup_dentry:
+	dput(dentry);
 cleanup_file:
 	put_filp(f);
 	return error;
@@ -705,14 +709,15 @@
 	int fd, error;
 
 	lock_kernel();
-	fd = get_unused_fd();
-	if (fd < 0) {
-		error = fd;
+	error = get_unused_fd();
+	if (error < 0)
 		goto out;
-	}
-	error = getname(filename, &tmp);
-	if (!error) {
-		error = do_open(tmp,flags,mode, fd);
+
+	fd = error;
+	tmp = getname(filename);
+	error = PTR_ERR(tmp);
+	if (!IS_ERR(tmp)) {
+		error = do_open(tmp,flags,mode,fd);
 		putname(tmp);
 		if (!error) {
 			error = fd;
@@ -743,31 +748,35 @@
 
 #endif
 
-int __fput(struct file *filp, struct inode *inode)
+int __fput(struct file *filp)
 {
 	int	error = 0;
+	struct dentry * dentry = filp->f_dentry;
+	struct inode * inode = dentry->d_inode;
 
 	if (filp->f_op && filp->f_op->release)
 		error = filp->f_op->release(inode,filp);
-	filp->f_inode = NULL;
+	filp->f_dentry = NULL;
 	if (filp->f_mode & FMODE_WRITE)
 		put_write_access(inode);
-	iput(inode);
+	dput(dentry);
 	return error;
 }
 
 int close_fp(struct file *filp)
 {
+	struct dentry *dentry;
 	struct inode *inode;
 
 	if (filp->f_count == 0) {
 		printk("VFS: Close: file count is 0\n");
 		return 0;
 	}
-	inode = filp->f_inode;
+	dentry = filp->f_dentry;
+	inode = dentry->d_inode;
 	if (inode)
 		locks_remove_locks(current, filp);
-	return fput(filp, inode);
+	return fput(filp);
 }
 
 asmlinkage int sys_close(unsigned int fd)

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov