patch-2.3.99-pre4 linux/fs/open.c
Next file: linux/fs/partitions/Config.in
Previous file: linux/fs/ntfs/fs.c
Back to the patch index
Back to the overall index
- Lines: 288
- Date:
Fri Apr 7 13:41:53 2000
- Orig file:
v2.3.99-pre3/linux/fs/open.c
- Orig date:
Mon Mar 27 08:08:30 2000
diff -u --recursive --new-file v2.3.99-pre3/linux/fs/open.c linux/fs/open.c
@@ -141,11 +141,8 @@
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;
+ dentry = file->f_dentry;
+ inode = dentry->d_inode;
error = -EACCES;
if (S_ISDIR(inode->i_mode) || !(file->f_mode & FMODE_WRITE))
goto out_putf;
@@ -330,35 +327,41 @@
return res;
}
+/* MOUNT_REWRITE: pass &mnt to lookup_dentry */
asmlinkage long sys_chdir(const char * filename)
{
int error;
- struct inode *inode;
struct dentry *dentry, *tmp;
+ struct vfsmount *mnt = NULL, *tmp_mnt;
+ char *name;
lock_kernel();
- dentry = namei(filename);
+ name = getname(filename);
+ error = PTR_ERR(name);
+ if (IS_ERR(name))
+ goto out;
+
+ dentry = lookup_dentry(name, LOOKUP_POSITIVE | LOOKUP_FOLLOW | LOOKUP_DIRECTORY);
+ putname(name);
error = PTR_ERR(dentry);
if (IS_ERR(dentry))
goto out;
- inode = dentry->d_inode;
-
- error = -ENOTDIR;
- if (!S_ISDIR(inode->i_mode))
- goto dput_and_out;
-
- error = permission(inode,MAY_EXEC);
+ error = permission(dentry->d_inode,MAY_EXEC);
if (error)
goto dput_and_out;
/* exchange dentries */
tmp = current->fs->pwd;
+ tmp_mnt = current->fs->pwdmnt;
current->fs->pwd = dentry;
+ current->fs->pwdmnt = mnt;
dentry = tmp;
+ mnt = tmp_mnt;
dput_and_out:
+ mntput(mnt);
dput(dentry);
out:
unlock_kernel();
@@ -370,6 +373,7 @@
struct file *file;
struct dentry *dentry;
struct inode *inode;
+ struct vfsmount *mnt;
int error;
error = -EBADF;
@@ -377,11 +381,9 @@
if (!file)
goto out;
- error = -ENOENT;
- if (!(dentry = file->f_dentry))
- goto out_putf;
- if (!(inode = dentry->d_inode))
- goto out_putf;
+ dentry = file->f_dentry;
+ mnt = file->f_vfsmnt;
+ inode = dentry->d_inode;
error = -ENOTDIR;
if (!S_ISDIR(inode->i_mode))
@@ -391,7 +393,10 @@
error = permission(inode, MAY_EXEC);
if (!error) {
struct dentry *tmp = current->fs->pwd;
+ struct vfsmount *tmp_mnt = current->fs->pwdmnt;
current->fs->pwd = dget(dentry);
+ current->fs->pwdmnt = mntget(mnt);
+ mntput(tmp_mnt);
dput(tmp);
}
unlock_kernel();
@@ -401,26 +406,28 @@
return error;
}
+/* MOUNT_REWRITE: pass &mnt to lookup_dentry */
asmlinkage long sys_chroot(const char * filename)
{
int error;
- struct inode *inode;
struct dentry *dentry, *tmp;
+ struct vfsmount *mnt = NULL, *tmp_mnt;
+ char *name;
lock_kernel();
- dentry = namei(filename);
+ name = getname(filename);
+ error = PTR_ERR(name);
+ if (IS_ERR(name))
+ goto out;
+
+ dentry = lookup_dentry(name, LOOKUP_POSITIVE | LOOKUP_FOLLOW | LOOKUP_DIRECTORY);
+ putname(name);
error = PTR_ERR(dentry);
if (IS_ERR(dentry))
goto out;
- inode = dentry->d_inode;
-
- error = -ENOTDIR;
- if (!S_ISDIR(inode->i_mode))
- goto dput_and_out;
-
- error = permission(inode,MAY_EXEC);
+ error = permission(dentry->d_inode,MAY_EXEC);
if (error)
goto dput_and_out;
@@ -430,11 +437,15 @@
/* exchange dentries */
tmp = current->fs->root;
+ tmp_mnt = current->fs->rootmnt;
current->fs->root = dentry;
+ current->fs->rootmnt = mnt;
dentry = tmp;
+ mnt = tmp_mnt;
error = 0;
dput_and_out:
+ mntput(mnt);
dput(dentry);
out:
unlock_kernel();
@@ -453,11 +464,8 @@
if (!file)
goto out;
- err = -ENOENT;
- if (!(dentry = file->f_dentry))
- goto out_putf;
- if (!(inode = dentry->d_inode))
- goto out_putf;
+ dentry = file->f_dentry;
+ inode = dentry->d_inode;
err = -EROFS;
if (IS_RDONLY(inode))
@@ -612,20 +620,16 @@
asmlinkage long sys_fchown(unsigned int fd, uid_t user, gid_t group)
{
- struct dentry * dentry;
struct file * file;
int error = -EBADF;
file = fget(fd);
if (!file)
goto out;
- error = -ENOENT;
lock_kernel();
- if ((dentry = file->f_dentry) != NULL)
- error = chown_common(dentry, user, group);
+ error = chown_common(file->f_dentry, user, group);
unlock_kernel();
fput(file);
-
out:
return error;
}
@@ -644,26 +648,25 @@
* for the internal routines (ie open_namei()/follow_link() etc). 00 is
* used by symlinks.
*/
-struct file *filp_open(const char * filename, int flags, int mode, struct dentry * base)
+struct file *filp_open(const char * filename, int flags, int mode)
{
- struct dentry * dentry;
- int flag,error;
+ int namei_flags, error;
+ struct nameidata nd;
- flag = flags;
- if ((flag+1) & O_ACCMODE)
- flag++;
- if (flag & O_TRUNC)
- flag |= 2;
+ namei_flags = flags;
+ if ((namei_flags+1) & O_ACCMODE)
+ namei_flags++;
+ if (namei_flags & O_TRUNC)
+ namei_flags |= 2;
- dentry = __open_namei(filename, flag, mode, base);
- error = PTR_ERR(dentry);
- if (!IS_ERR(dentry))
- return dentry_open(dentry, flags);
+ error = open_namei(filename, namei_flags, mode, &nd);
+ if (!error)
+ return dentry_open(nd.dentry, nd.mnt, flags);
return ERR_PTR(error);
}
-struct file *dentry_open(struct dentry *dentry, int flags)
+struct file *dentry_open(struct dentry *dentry, struct vfsmount *mnt, int flags)
{
struct file * f;
struct inode *inode;
@@ -679,15 +682,14 @@
if (f->f_mode & FMODE_WRITE) {
error = get_write_access(inode);
if (error)
- goto cleanup_dentry;
+ goto cleanup_file;
}
f->f_dentry = dentry;
+ f->f_vfsmnt = mnt;
f->f_pos = 0;
f->f_reada = 0;
- f->f_op = NULL;
- if (inode->i_op)
- f->f_op = inode->i_fop;
+ f->f_op = inode->i_fop;
if (inode->i_sb)
file_move(f, &inode->i_sb->s_files);
if (f->f_op && f->f_op->open) {
@@ -703,9 +705,12 @@
if (f->f_mode & FMODE_WRITE)
put_write_access(inode);
f->f_dentry = NULL;
+ f->f_vfsmnt = NULL;
+cleanup_file:
+ put_filp(f);
cleanup_dentry:
dput(dentry);
- put_filp(f);
+ mntput(mnt);
return ERR_PTR(error);
}
@@ -795,7 +800,7 @@
if (fd >= 0) {
struct file * f;
lock_kernel();
- f = filp_open(tmp, flags, mode, NULL);
+ f = filp_open(tmp, flags, mode);
unlock_kernel();
error = PTR_ERR(f);
if (IS_ERR(f))
@@ -833,7 +838,6 @@
int filp_close(struct file *filp, fl_owner_t id)
{
int retval;
- struct dentry *dentry = filp->f_dentry;
if (!file_count(filp)) {
printk("VFS: Close: file count is 0\n");
@@ -842,8 +846,7 @@
retval = 0;
if (filp->f_op && filp->f_op->flush)
retval = filp->f_op->flush(filp);
- if (dentry->d_inode)
- locks_remove_posix(filp, id);
+ locks_remove_posix(filp, id);
fput(filp);
return retval;
}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)