aboutsummaryrefslogtreecommitdiffstats
path: root/fs/open.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/open.c')
-rw-r--r--fs/open.c47
1 files changed, 33 insertions, 14 deletions
diff --git a/fs/open.c b/fs/open.c
index d54301219d0..9daa1cea52f 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