diff options
author | Miklos Szeredi <mszeredi@suse.cz> | 2012-05-21 11:30:15 -0400 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2012-06-01 12:12:00 -0400 |
commit | 90ad1a8ecb9bfd5ff4503ac42cd049a97643ee51 (patch) | |
tree | 0e41482d5706e153045c0635c53bb2d9d8c3e704 /fs/open.c | |
parent | 5f5daac12a4cef568d1269be0215fec0667193c1 (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/open.c')
-rw-r--r-- | fs/open.c | 47 |
1 files changed, 33 insertions, 14 deletions
@@ -654,10 +654,23 @@ static inline int __get_file_write_access(struct inode *inode, | |||
654 | return error; | 654 | return error; |
655 | } | 655 | } |
656 | 656 | ||
657 | static struct file *__dentry_open(struct dentry *dentry, struct vfsmount *mnt, | 657 | int 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 | |||
670 | static 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 | ||
728 | cleanup_all: | 731 | cleanup_all: |
@@ -750,6 +753,22 @@ cleanup_file: | |||
750 | return ERR_PTR(error); | 753 | return ERR_PTR(error); |
751 | } | 754 | } |
752 | 755 | ||
756 | static 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 |