diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2015-07-04 22:36:06 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2015-07-04 22:36:06 -0400 |
commit | 1dc51b8288007753ad7cd7d08bb8fa930fc8bb10 (patch) | |
tree | 0616c0ff7d877e64d9c248a6cdff074eae258840 /fs/open.c | |
parent | 9b284cbdb5de3b8871014f8290d1b540e5181c21 (diff) | |
parent | 0f1db7dee200127da4c07928189748918c312031 (diff) |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
Pull more vfs updates from Al Viro:
"Assorted VFS fixes and related cleanups (IMO the most interesting in
that part are f_path-related things and Eric's descriptor-related
stuff). UFS regression fixes (it got broken last cycle). 9P fixes.
fs-cache series, DAX patches, Jan's file_remove_suid() work"
[ I'd say this is much more than "fixes and related cleanups". The
file_table locking rule change by Eric Dumazet is a rather big and
fundamental update even if the patch isn't huge. - Linus ]
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs: (49 commits)
9p: cope with bogus responses from server in p9_client_{read,write}
p9_client_write(): avoid double p9_free_req()
9p: forgetting to cancel request on interrupted zero-copy RPC
dax: bdev_direct_access() may sleep
block: Add support for DAX reads/writes to block devices
dax: Use copy_from_iter_nocache
dax: Add block size note to documentation
fs/file.c: __fget() and dup2() atomicity rules
fs/file.c: don't acquire files->file_lock in fd_install()
fs:super:get_anon_bdev: fix race condition could cause dev exceed its upper limitation
vfs: avoid creation of inode number 0 in get_next_ino
namei: make set_root_rcu() return void
make simple_positive() public
ufs: use dir_pages instead of ufs_dir_pages()
pagemap.h: move dir_pages() over there
remove the pointless include of lglock.h
fs: cleanup slight list_entry abuse
xfs: Correctly lock inode when removing suid and file capabilities
fs: Call security_ops->inode_killpriv on truncate
fs: Provide function telling whether file_remove_privs() will do anything
...
Diffstat (limited to 'fs/open.c')
-rw-r--r-- | fs/open.c | 61 |
1 files changed, 36 insertions, 25 deletions
@@ -51,8 +51,10 @@ int do_truncate(struct dentry *dentry, loff_t length, unsigned int time_attrs, | |||
51 | newattrs.ia_valid |= ATTR_FILE; | 51 | newattrs.ia_valid |= ATTR_FILE; |
52 | } | 52 | } |
53 | 53 | ||
54 | /* Remove suid/sgid on truncate too */ | 54 | /* Remove suid, sgid, and file capabilities on truncate too */ |
55 | ret = should_remove_suid(dentry); | 55 | ret = dentry_needs_remove_privs(dentry); |
56 | if (ret < 0) | ||
57 | return ret; | ||
56 | if (ret) | 58 | if (ret) |
57 | newattrs.ia_valid |= ret | ATTR_FORCE; | 59 | newattrs.ia_valid |= ret | ATTR_FORCE; |
58 | 60 | ||
@@ -678,18 +680,18 @@ int open_check_o_direct(struct file *f) | |||
678 | } | 680 | } |
679 | 681 | ||
680 | static int do_dentry_open(struct file *f, | 682 | static int do_dentry_open(struct file *f, |
683 | struct inode *inode, | ||
681 | int (*open)(struct inode *, struct file *), | 684 | int (*open)(struct inode *, struct file *), |
682 | const struct cred *cred) | 685 | const struct cred *cred) |
683 | { | 686 | { |
684 | static const struct file_operations empty_fops = {}; | 687 | static const struct file_operations empty_fops = {}; |
685 | struct inode *inode; | ||
686 | int error; | 688 | int error; |
687 | 689 | ||
688 | f->f_mode = OPEN_FMODE(f->f_flags) | FMODE_LSEEK | | 690 | f->f_mode = OPEN_FMODE(f->f_flags) | FMODE_LSEEK | |
689 | FMODE_PREAD | FMODE_PWRITE; | 691 | FMODE_PREAD | FMODE_PWRITE; |
690 | 692 | ||
691 | path_get(&f->f_path); | 693 | path_get(&f->f_path); |
692 | inode = f->f_inode = f->f_path.dentry->d_inode; | 694 | f->f_inode = inode; |
693 | f->f_mapping = inode->i_mapping; | 695 | f->f_mapping = inode->i_mapping; |
694 | 696 | ||
695 | if (unlikely(f->f_flags & O_PATH)) { | 697 | if (unlikely(f->f_flags & O_PATH)) { |
@@ -793,7 +795,8 @@ int finish_open(struct file *file, struct dentry *dentry, | |||
793 | BUG_ON(*opened & FILE_OPENED); /* once it's opened, it's opened */ | 795 | BUG_ON(*opened & FILE_OPENED); /* once it's opened, it's opened */ |
794 | 796 | ||
795 | file->f_path.dentry = dentry; | 797 | file->f_path.dentry = dentry; |
796 | error = do_dentry_open(file, open, current_cred()); | 798 | error = do_dentry_open(file, d_backing_inode(dentry), open, |
799 | current_cred()); | ||
797 | if (!error) | 800 | if (!error) |
798 | *opened |= FILE_OPENED; | 801 | *opened |= FILE_OPENED; |
799 | 802 | ||
@@ -822,6 +825,34 @@ int finish_no_open(struct file *file, struct dentry *dentry) | |||
822 | } | 825 | } |
823 | EXPORT_SYMBOL(finish_no_open); | 826 | EXPORT_SYMBOL(finish_no_open); |
824 | 827 | ||
828 | char *file_path(struct file *filp, char *buf, int buflen) | ||
829 | { | ||
830 | return d_path(&filp->f_path, buf, buflen); | ||
831 | } | ||
832 | EXPORT_SYMBOL(file_path); | ||
833 | |||
834 | /** | ||
835 | * vfs_open - open the file at the given path | ||
836 | * @path: path to open | ||
837 | * @file: newly allocated file with f_flag initialized | ||
838 | * @cred: credentials to use | ||
839 | */ | ||
840 | int vfs_open(const struct path *path, struct file *file, | ||
841 | const struct cred *cred) | ||
842 | { | ||
843 | struct dentry *dentry = path->dentry; | ||
844 | struct inode *inode = dentry->d_inode; | ||
845 | |||
846 | file->f_path = *path; | ||
847 | if (dentry->d_flags & DCACHE_OP_SELECT_INODE) { | ||
848 | inode = dentry->d_op->d_select_inode(dentry, file->f_flags); | ||
849 | if (IS_ERR(inode)) | ||
850 | return PTR_ERR(inode); | ||
851 | } | ||
852 | |||
853 | return do_dentry_open(file, inode, NULL, cred); | ||
854 | } | ||
855 | |||
825 | struct file *dentry_open(const struct path *path, int flags, | 856 | struct file *dentry_open(const struct path *path, int flags, |
826 | const struct cred *cred) | 857 | const struct cred *cred) |
827 | { | 858 | { |
@@ -853,26 +884,6 @@ struct file *dentry_open(const struct path *path, int flags, | |||
853 | } | 884 | } |
854 | EXPORT_SYMBOL(dentry_open); | 885 | EXPORT_SYMBOL(dentry_open); |
855 | 886 | ||
856 | /** | ||
857 | * vfs_open - open the file at the given path | ||
858 | * @path: path to open | ||
859 | * @filp: newly allocated file with f_flag initialized | ||
860 | * @cred: credentials to use | ||
861 | */ | ||
862 | int vfs_open(const struct path *path, struct file *filp, | ||
863 | const struct cred *cred) | ||
864 | { | ||
865 | struct inode *inode = path->dentry->d_inode; | ||
866 | |||
867 | if (inode->i_op->dentry_open) | ||
868 | return inode->i_op->dentry_open(path->dentry, filp, cred); | ||
869 | else { | ||
870 | filp->f_path = *path; | ||
871 | return do_dentry_open(filp, NULL, cred); | ||
872 | } | ||
873 | } | ||
874 | EXPORT_SYMBOL(vfs_open); | ||
875 | |||
876 | static inline int build_open_flags(int flags, umode_t mode, struct open_flags *op) | 887 | static inline int build_open_flags(int flags, umode_t mode, struct open_flags *op) |
877 | { | 888 | { |
878 | int lookup_flags = 0; | 889 | int lookup_flags = 0; |