aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorMiklos Szeredi <mszeredi@suse.cz>2012-05-21 11:30:15 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2012-06-01 12:12:00 -0400
commit90ad1a8ecb9bfd5ff4503ac42cd049a97643ee51 (patch)
tree0e41482d5706e153045c0635c53bb2d9d8c3e704 /fs
parent5f5daac12a4cef568d1269be0215fec0667193c1 (diff)
vfs: split __dentry_open()
Split __dentry_open() into two functions: do_dentry_open() - does most of the actual work, doesn't put file on failure open_check_o_direct() - after a successful open, checks direct_IO method This will allow i_op->atomic_open to do just the file initialization and leave the direct_IO checking to the VFS. Signed-off-by: Miklos Szeredi <mszeredi@suse.cz> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs')
-rw-r--r--fs/internal.h1
-rw-r--r--fs/open.c47
2 files changed, 34 insertions, 14 deletions
diff --git a/fs/internal.h b/fs/internal.h
index 8040af489c78..18bc216ea09d 100644
--- a/fs/internal.h
+++ b/fs/internal.h
@@ -100,6 +100,7 @@ extern struct file *do_file_open_root(struct dentry *, struct vfsmount *,
100 100
101extern long do_handle_open(int mountdirfd, 101extern long do_handle_open(int mountdirfd,
102 struct file_handle __user *ufh, int open_flag); 102 struct file_handle __user *ufh, int open_flag);
103extern int open_check_o_direct(struct file *f);
103 104
104/* 105/*
105 * inode.c 106 * inode.c
diff --git a/fs/open.c b/fs/open.c
index d54301219d04..9daa1cea52fc 100644
--- a/fs/open.c
+++ b/fs/open.c
@@ -654,10 +654,23 @@ static inline int __get_file_write_access(struct inode *inode,
654 return error; 654 return error;
655} 655}
656 656
657static struct file *__dentry_open(struct dentry *dentry, struct vfsmount *mnt, 657int open_check_o_direct(struct file *f)
658 struct file *f, 658{
659 int (*open)(struct inode *, struct file *), 659 /* NB: we're sure to have correct a_ops only after f_op->open */
660 const struct cred *cred) 660 if (f->f_flags & O_DIRECT) {
661 if (!f->f_mapping->a_ops ||
662 ((!f->f_mapping->a_ops->direct_IO) &&
663 (!f->f_mapping->a_ops->get_xip_mem))) {
664 return -EINVAL;
665 }
666 }
667 return 0;
668}
669
670static struct file *do_dentry_open(struct dentry *dentry, struct vfsmount *mnt,
671 struct file *f,
672 int (*open)(struct inode *, struct file *),
673 const struct cred *cred)
661{ 674{
662 static const struct file_operations empty_fops = {}; 675 static const struct file_operations empty_fops = {};
663 struct inode *inode; 676 struct inode *inode;
@@ -713,16 +726,6 @@ static struct file *__dentry_open(struct dentry *dentry, struct vfsmount *mnt,
713 726
714 file_ra_state_init(&f->f_ra, f->f_mapping->host->i_mapping); 727 file_ra_state_init(&f->f_ra, f->f_mapping->host->i_mapping);
715 728
716 /* NB: we're sure to have correct a_ops only after f_op->open */
717 if (f->f_flags & O_DIRECT) {
718 if (!f->f_mapping->a_ops ||
719 ((!f->f_mapping->a_ops->direct_IO) &&
720 (!f->f_mapping->a_ops->get_xip_mem))) {
721 fput(f);
722 f = ERR_PTR(-EINVAL);
723 }
724 }
725
726 return f; 729 return f;
727 730
728cleanup_all: 731cleanup_all:
@@ -750,6 +753,22 @@ cleanup_file:
750 return ERR_PTR(error); 753 return ERR_PTR(error);
751} 754}
752 755
756static struct file *__dentry_open(struct dentry *dentry, struct vfsmount *mnt,
757 struct file *f,
758 int (*open)(struct inode *, struct file *),
759 const struct cred *cred)
760{
761 struct file *res = do_dentry_open(dentry, mnt, f, open, cred);
762 if (!IS_ERR(res)) {
763 int error = open_check_o_direct(f);
764 if (error) {
765 fput(res);
766 res = ERR_PTR(error);
767 }
768 }
769 return res;
770}
771
753/** 772/**
754 * lookup_instantiate_filp - instantiates the open intent filp 773 * lookup_instantiate_filp - instantiates the open intent filp
755 * @nd: pointer to nameidata 774 * @nd: pointer to nameidata