diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2018-08-13 22:58:36 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2018-08-13 22:58:36 -0400 |
commit | a66b4cd1e7163adb327838a3c81faaf6a9330d5a (patch) | |
tree | 2b123a010bb0f1566ff6f34e529f01ddf10ee308 | |
parent | b16528466786a540cb00148acb124e0149d62710 (diff) | |
parent | 5f336e722cc961be94d264d96b90c92888fffae1 (diff) |
Merge branch 'work.open3' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
Pull vfs open-related updates from Al Viro:
- "do we need fput() or put_filp()" rules are gone - it's always fput()
now. We keep track of that state where it belongs - in ->f_mode.
- int *opened mess killed - in finish_open(), in ->atomic_open()
instances and in fs/namei.c code around do_last()/lookup_open()/atomic_open().
- alloc_file() wrappers with saner calling conventions are introduced
(alloc_file_clone() and alloc_file_pseudo()); callers converted, with
much simplification.
- while we are at it, saner calling conventions for path_init() and
link_path_walk(), simplifying things inside fs/namei.c (both on
open-related paths and elsewhere).
* 'work.open3' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs: (40 commits)
few more cleanups of link_path_walk() callers
allow link_path_walk() to take ERR_PTR()
make path_init() unconditionally paired with terminate_walk()
document alloc_file() changes
make alloc_file() static
do_shmat(): grab shp->shm_file earlier, switch to alloc_file_clone()
new helper: alloc_file_clone()
create_pipe_files(): switch the first allocation to alloc_file_pseudo()
anon_inode_getfile(): switch to alloc_file_pseudo()
hugetlb_file_setup(): switch to alloc_file_pseudo()
ocxlflash_getfile(): switch to alloc_file_pseudo()
cxl_getfile(): switch to alloc_file_pseudo()
... and switch shmem_file_setup() to alloc_file_pseudo()
__shmem_file_setup(): reorder allocations
new wrapper: alloc_file_pseudo()
kill FILE_{CREATED,OPENED}
switch atomic_open() and lookup_open() to returning 0 in all success cases
document ->atomic_open() changes
->atomic_open(): return 0 in all success cases
get rid of 'opened' in path_openat() and the helpers downstream
...
45 files changed, 371 insertions, 576 deletions
diff --git a/Documentation/filesystems/Locking b/Documentation/filesystems/Locking index 37bf0a9de75c..7cca82ed2ed1 100644 --- a/Documentation/filesystems/Locking +++ b/Documentation/filesystems/Locking | |||
@@ -64,7 +64,7 @@ prototypes: | |||
64 | void (*update_time)(struct inode *, struct timespec *, int); | 64 | void (*update_time)(struct inode *, struct timespec *, int); |
65 | int (*atomic_open)(struct inode *, struct dentry *, | 65 | int (*atomic_open)(struct inode *, struct dentry *, |
66 | struct file *, unsigned open_flag, | 66 | struct file *, unsigned open_flag, |
67 | umode_t create_mode, int *opened); | 67 | umode_t create_mode); |
68 | int (*tmpfile) (struct inode *, struct dentry *, umode_t); | 68 | int (*tmpfile) (struct inode *, struct dentry *, umode_t); |
69 | 69 | ||
70 | locking rules: | 70 | locking rules: |
diff --git a/Documentation/filesystems/porting b/Documentation/filesystems/porting index 17bb4dc28fae..7b7b845c490a 100644 --- a/Documentation/filesystems/porting +++ b/Documentation/filesystems/porting | |||
@@ -602,3 +602,23 @@ in your dentry operations instead. | |||
602 | dentry separately, and it now has request_mask and query_flags arguments | 602 | dentry separately, and it now has request_mask and query_flags arguments |
603 | to specify the fields and sync type requested by statx. Filesystems not | 603 | to specify the fields and sync type requested by statx. Filesystems not |
604 | supporting any statx-specific features may ignore the new arguments. | 604 | supporting any statx-specific features may ignore the new arguments. |
605 | -- | ||
606 | [mandatory] | ||
607 | ->atomic_open() calling conventions have changed. Gone is int *opened, | ||
608 | along with FILE_OPENED/FILE_CREATED. In place of those we have | ||
609 | FMODE_OPENED/FMODE_CREATED, set in file->f_mode. Additionally, return | ||
610 | value for 'called finish_no_open(), open it yourself' case has become | ||
611 | 0, not 1. Since finish_no_open() itself is returning 0 now, that part | ||
612 | does not need any changes in ->atomic_open() instances. | ||
613 | -- | ||
614 | [mandatory] | ||
615 | alloc_file() has become static now; two wrappers are to be used instead. | ||
616 | alloc_file_pseudo(inode, vfsmount, name, flags, ops) is for the cases | ||
617 | when dentry needs to be created; that's the majority of old alloc_file() | ||
618 | users. Calling conventions: on success a reference to new struct file | ||
619 | is returned and callers reference to inode is subsumed by that. On | ||
620 | failure, ERR_PTR() is returned and no caller's references are affected, | ||
621 | so the caller needs to drop the inode reference it held. | ||
622 | alloc_file_clone(file, flags, ops) does not affect any caller's references. | ||
623 | On success you get a new struct file sharing the mount/dentry with the | ||
624 | original, on failure - ERR_PTR(). | ||
diff --git a/Documentation/filesystems/vfs.txt b/Documentation/filesystems/vfs.txt index f608180ad59d..85907d5b9c2c 100644 --- a/Documentation/filesystems/vfs.txt +++ b/Documentation/filesystems/vfs.txt | |||
@@ -386,7 +386,7 @@ struct inode_operations { | |||
386 | ssize_t (*listxattr) (struct dentry *, char *, size_t); | 386 | ssize_t (*listxattr) (struct dentry *, char *, size_t); |
387 | void (*update_time)(struct inode *, struct timespec *, int); | 387 | void (*update_time)(struct inode *, struct timespec *, int); |
388 | int (*atomic_open)(struct inode *, struct dentry *, struct file *, | 388 | int (*atomic_open)(struct inode *, struct dentry *, struct file *, |
389 | unsigned open_flag, umode_t create_mode, int *opened); | 389 | unsigned open_flag, umode_t create_mode); |
390 | int (*tmpfile) (struct inode *, struct dentry *, umode_t); | 390 | int (*tmpfile) (struct inode *, struct dentry *, umode_t); |
391 | }; | 391 | }; |
392 | 392 | ||
@@ -496,13 +496,15 @@ otherwise noted. | |||
496 | 496 | ||
497 | atomic_open: called on the last component of an open. Using this optional | 497 | atomic_open: called on the last component of an open. Using this optional |
498 | method the filesystem can look up, possibly create and open the file in | 498 | method the filesystem can look up, possibly create and open the file in |
499 | one atomic operation. If it cannot perform this (e.g. the file type | 499 | one atomic operation. If it wants to leave actual opening to the |
500 | turned out to be wrong) it may signal this by returning 1 instead of | 500 | caller (e.g. if the file turned out to be a symlink, device, or just |
501 | usual 0 or -ve . This method is only called if the last component is | 501 | something filesystem won't do atomic open for), it may signal this by |
502 | negative or needs lookup. Cached positive dentries are still handled by | 502 | returning finish_no_open(file, dentry). This method is only called if |
503 | f_op->open(). If the file was created, the FILE_CREATED flag should be | 503 | the last component is negative or needs lookup. Cached positive dentries |
504 | set in "opened". In case of O_EXCL the method must only succeed if the | 504 | are still handled by f_op->open(). If the file was created, |
505 | file didn't exist and hence FILE_CREATED shall always be set on success. | 505 | FMODE_CREATED flag should be set in file->f_mode. In case of O_EXCL |
506 | the method must only succeed if the file didn't exist and hence FMODE_CREATED | ||
507 | shall always be set on success. | ||
506 | 508 | ||
507 | tmpfile: called in the end of O_TMPFILE open(). Optional, equivalent to | 509 | tmpfile: called in the end of O_TMPFILE open(). Optional, equivalent to |
508 | atomically creating, opening and unlinking a file in given directory. | 510 | atomically creating, opening and unlinking a file in given directory. |
diff --git a/drivers/gpu/drm/drm_lease.c b/drivers/gpu/drm/drm_lease.c index d638c0fb3418..b54fb78a283c 100644 --- a/drivers/gpu/drm/drm_lease.c +++ b/drivers/gpu/drm/drm_lease.c | |||
@@ -553,7 +553,7 @@ int drm_mode_create_lease_ioctl(struct drm_device *dev, | |||
553 | 553 | ||
554 | /* Clone the lessor file to create a new file for us */ | 554 | /* Clone the lessor file to create a new file for us */ |
555 | DRM_DEBUG_LEASE("Allocating lease file\n"); | 555 | DRM_DEBUG_LEASE("Allocating lease file\n"); |
556 | lessee_file = filp_clone_open(lessor_file); | 556 | lessee_file = file_clone_open(lessor_file); |
557 | if (IS_ERR(lessee_file)) { | 557 | if (IS_ERR(lessee_file)) { |
558 | ret = PTR_ERR(lessee_file); | 558 | ret = PTR_ERR(lessee_file); |
559 | goto out_lessee; | 559 | goto out_lessee; |
diff --git a/drivers/misc/cxl/api.c b/drivers/misc/cxl/api.c index 6b16946f9b05..8fd5ec4d6042 100644 --- a/drivers/misc/cxl/api.c +++ b/drivers/misc/cxl/api.c | |||
@@ -67,10 +67,8 @@ static struct file *cxl_getfile(const char *name, | |||
67 | const struct file_operations *fops, | 67 | const struct file_operations *fops, |
68 | void *priv, int flags) | 68 | void *priv, int flags) |
69 | { | 69 | { |
70 | struct qstr this; | ||
71 | struct path path; | ||
72 | struct file *file; | 70 | struct file *file; |
73 | struct inode *inode = NULL; | 71 | struct inode *inode; |
74 | int rc; | 72 | int rc; |
75 | 73 | ||
76 | /* strongly inspired by anon_inode_getfile() */ | 74 | /* strongly inspired by anon_inode_getfile() */ |
@@ -91,23 +89,11 @@ static struct file *cxl_getfile(const char *name, | |||
91 | goto err_fs; | 89 | goto err_fs; |
92 | } | 90 | } |
93 | 91 | ||
94 | file = ERR_PTR(-ENOMEM); | 92 | file = alloc_file_pseudo(inode, cxl_vfs_mount, name, |
95 | this.name = name; | 93 | flags & (O_ACCMODE | O_NONBLOCK), fops); |
96 | this.len = strlen(name); | 94 | if (IS_ERR(file)) |
97 | this.hash = 0; | ||
98 | path.dentry = d_alloc_pseudo(cxl_vfs_mount->mnt_sb, &this); | ||
99 | if (!path.dentry) | ||
100 | goto err_inode; | 95 | goto err_inode; |
101 | 96 | ||
102 | path.mnt = mntget(cxl_vfs_mount); | ||
103 | d_instantiate(path.dentry, inode); | ||
104 | |||
105 | file = alloc_file(&path, OPEN_FMODE(flags), fops); | ||
106 | if (IS_ERR(file)) { | ||
107 | path_put(&path); | ||
108 | goto err_fs; | ||
109 | } | ||
110 | file->f_flags = flags & (O_ACCMODE | O_NONBLOCK); | ||
111 | file->private_data = priv; | 97 | file->private_data = priv; |
112 | 98 | ||
113 | return file; | 99 | return file; |
diff --git a/drivers/scsi/cxlflash/ocxl_hw.c b/drivers/scsi/cxlflash/ocxl_hw.c index 497a68389461..a43d44e7e7dd 100644 --- a/drivers/scsi/cxlflash/ocxl_hw.c +++ b/drivers/scsi/cxlflash/ocxl_hw.c | |||
@@ -88,10 +88,8 @@ static struct file *ocxlflash_getfile(struct device *dev, const char *name, | |||
88 | const struct file_operations *fops, | 88 | const struct file_operations *fops, |
89 | void *priv, int flags) | 89 | void *priv, int flags) |
90 | { | 90 | { |
91 | struct qstr this; | ||
92 | struct path path; | ||
93 | struct file *file; | 91 | struct file *file; |
94 | struct inode *inode = NULL; | 92 | struct inode *inode; |
95 | int rc; | 93 | int rc; |
96 | 94 | ||
97 | if (fops->owner && !try_module_get(fops->owner)) { | 95 | if (fops->owner && !try_module_get(fops->owner)) { |
@@ -116,29 +114,15 @@ static struct file *ocxlflash_getfile(struct device *dev, const char *name, | |||
116 | goto err3; | 114 | goto err3; |
117 | } | 115 | } |
118 | 116 | ||
119 | this.name = name; | 117 | file = alloc_file_pseudo(inode, ocxlflash_vfs_mount, name, |
120 | this.len = strlen(name); | 118 | flags & (O_ACCMODE | O_NONBLOCK), fops); |
121 | this.hash = 0; | ||
122 | path.dentry = d_alloc_pseudo(ocxlflash_vfs_mount->mnt_sb, &this); | ||
123 | if (!path.dentry) { | ||
124 | dev_err(dev, "%s: d_alloc_pseudo failed\n", __func__); | ||
125 | rc = -ENOMEM; | ||
126 | goto err4; | ||
127 | } | ||
128 | |||
129 | path.mnt = mntget(ocxlflash_vfs_mount); | ||
130 | d_instantiate(path.dentry, inode); | ||
131 | |||
132 | file = alloc_file(&path, OPEN_FMODE(flags), fops); | ||
133 | if (IS_ERR(file)) { | 119 | if (IS_ERR(file)) { |
134 | rc = PTR_ERR(file); | 120 | rc = PTR_ERR(file); |
135 | dev_err(dev, "%s: alloc_file failed rc=%d\n", | 121 | dev_err(dev, "%s: alloc_file failed rc=%d\n", |
136 | __func__, rc); | 122 | __func__, rc); |
137 | path_put(&path); | 123 | goto err4; |
138 | goto err3; | ||
139 | } | 124 | } |
140 | 125 | ||
141 | file->f_flags = flags & (O_ACCMODE | O_NONBLOCK); | ||
142 | file->private_data = priv; | 126 | file->private_data = priv; |
143 | out: | 127 | out: |
144 | return file; | 128 | return file; |
diff --git a/fs/9p/vfs_inode.c b/fs/9p/vfs_inode.c index 42e102e2e74a..85ff859d3af5 100644 --- a/fs/9p/vfs_inode.c +++ b/fs/9p/vfs_inode.c | |||
@@ -859,8 +859,7 @@ struct dentry *v9fs_vfs_lookup(struct inode *dir, struct dentry *dentry, | |||
859 | 859 | ||
860 | static int | 860 | static int |
861 | v9fs_vfs_atomic_open(struct inode *dir, struct dentry *dentry, | 861 | v9fs_vfs_atomic_open(struct inode *dir, struct dentry *dentry, |
862 | struct file *file, unsigned flags, umode_t mode, | 862 | struct file *file, unsigned flags, umode_t mode) |
863 | int *opened) | ||
864 | { | 863 | { |
865 | int err; | 864 | int err; |
866 | u32 perm; | 865 | u32 perm; |
@@ -917,7 +916,7 @@ v9fs_vfs_atomic_open(struct inode *dir, struct dentry *dentry, | |||
917 | v9inode->writeback_fid = (void *) inode_fid; | 916 | v9inode->writeback_fid = (void *) inode_fid; |
918 | } | 917 | } |
919 | mutex_unlock(&v9inode->v_mutex); | 918 | mutex_unlock(&v9inode->v_mutex); |
920 | err = finish_open(file, dentry, generic_file_open, opened); | 919 | err = finish_open(file, dentry, generic_file_open); |
921 | if (err) | 920 | if (err) |
922 | goto error; | 921 | goto error; |
923 | 922 | ||
@@ -925,7 +924,7 @@ v9fs_vfs_atomic_open(struct inode *dir, struct dentry *dentry, | |||
925 | if (v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE) | 924 | if (v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE) |
926 | v9fs_cache_inode_set_cookie(d_inode(dentry), file); | 925 | v9fs_cache_inode_set_cookie(d_inode(dentry), file); |
927 | 926 | ||
928 | *opened |= FILE_CREATED; | 927 | file->f_mode |= FMODE_CREATED; |
929 | out: | 928 | out: |
930 | dput(res); | 929 | dput(res); |
931 | return err; | 930 | return err; |
diff --git a/fs/9p/vfs_inode_dotl.c b/fs/9p/vfs_inode_dotl.c index 7f6ae21a27b3..4823e1c46999 100644 --- a/fs/9p/vfs_inode_dotl.c +++ b/fs/9p/vfs_inode_dotl.c | |||
@@ -241,8 +241,7 @@ v9fs_vfs_create_dotl(struct inode *dir, struct dentry *dentry, umode_t omode, | |||
241 | 241 | ||
242 | static int | 242 | static int |
243 | v9fs_vfs_atomic_open_dotl(struct inode *dir, struct dentry *dentry, | 243 | v9fs_vfs_atomic_open_dotl(struct inode *dir, struct dentry *dentry, |
244 | struct file *file, unsigned flags, umode_t omode, | 244 | struct file *file, unsigned flags, umode_t omode) |
245 | int *opened) | ||
246 | { | 245 | { |
247 | int err = 0; | 246 | int err = 0; |
248 | kgid_t gid; | 247 | kgid_t gid; |
@@ -352,13 +351,13 @@ v9fs_vfs_atomic_open_dotl(struct inode *dir, struct dentry *dentry, | |||
352 | } | 351 | } |
353 | mutex_unlock(&v9inode->v_mutex); | 352 | mutex_unlock(&v9inode->v_mutex); |
354 | /* Since we are opening a file, assign the open fid to the file */ | 353 | /* Since we are opening a file, assign the open fid to the file */ |
355 | err = finish_open(file, dentry, generic_file_open, opened); | 354 | err = finish_open(file, dentry, generic_file_open); |
356 | if (err) | 355 | if (err) |
357 | goto err_clunk_old_fid; | 356 | goto err_clunk_old_fid; |
358 | file->private_data = ofid; | 357 | file->private_data = ofid; |
359 | if (v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE) | 358 | if (v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE) |
360 | v9fs_cache_inode_set_cookie(inode, file); | 359 | v9fs_cache_inode_set_cookie(inode, file); |
361 | *opened |= FILE_CREATED; | 360 | file->f_mode |= FMODE_CREATED; |
362 | out: | 361 | out: |
363 | v9fs_put_acl(dacl, pacl); | 362 | v9fs_put_acl(dacl, pacl); |
364 | dput(res); | 363 | dput(res); |
@@ -202,9 +202,7 @@ static const struct address_space_operations aio_ctx_aops; | |||
202 | 202 | ||
203 | static struct file *aio_private_file(struct kioctx *ctx, loff_t nr_pages) | 203 | static struct file *aio_private_file(struct kioctx *ctx, loff_t nr_pages) |
204 | { | 204 | { |
205 | struct qstr this = QSTR_INIT("[aio]", 5); | ||
206 | struct file *file; | 205 | struct file *file; |
207 | struct path path; | ||
208 | struct inode *inode = alloc_anon_inode(aio_mnt->mnt_sb); | 206 | struct inode *inode = alloc_anon_inode(aio_mnt->mnt_sb); |
209 | if (IS_ERR(inode)) | 207 | if (IS_ERR(inode)) |
210 | return ERR_CAST(inode); | 208 | return ERR_CAST(inode); |
@@ -213,31 +211,17 @@ static struct file *aio_private_file(struct kioctx *ctx, loff_t nr_pages) | |||
213 | inode->i_mapping->private_data = ctx; | 211 | inode->i_mapping->private_data = ctx; |
214 | inode->i_size = PAGE_SIZE * nr_pages; | 212 | inode->i_size = PAGE_SIZE * nr_pages; |
215 | 213 | ||
216 | path.dentry = d_alloc_pseudo(aio_mnt->mnt_sb, &this); | 214 | file = alloc_file_pseudo(inode, aio_mnt, "[aio]", |
217 | if (!path.dentry) { | 215 | O_RDWR, &aio_ring_fops); |
216 | if (IS_ERR(file)) | ||
218 | iput(inode); | 217 | iput(inode); |
219 | return ERR_PTR(-ENOMEM); | ||
220 | } | ||
221 | path.mnt = mntget(aio_mnt); | ||
222 | |||
223 | d_instantiate(path.dentry, inode); | ||
224 | file = alloc_file(&path, FMODE_READ | FMODE_WRITE, &aio_ring_fops); | ||
225 | if (IS_ERR(file)) { | ||
226 | path_put(&path); | ||
227 | return file; | ||
228 | } | ||
229 | |||
230 | file->f_flags = O_RDWR; | ||
231 | return file; | 218 | return file; |
232 | } | 219 | } |
233 | 220 | ||
234 | static struct dentry *aio_mount(struct file_system_type *fs_type, | 221 | static struct dentry *aio_mount(struct file_system_type *fs_type, |
235 | int flags, const char *dev_name, void *data) | 222 | int flags, const char *dev_name, void *data) |
236 | { | 223 | { |
237 | static const struct dentry_operations ops = { | 224 | struct dentry *root = mount_pseudo(fs_type, "aio:", NULL, NULL, |
238 | .d_dname = simple_dname, | ||
239 | }; | ||
240 | struct dentry *root = mount_pseudo(fs_type, "aio:", NULL, &ops, | ||
241 | AIO_RING_MAGIC); | 225 | AIO_RING_MAGIC); |
242 | 226 | ||
243 | if (!IS_ERR(root)) | 227 | if (!IS_ERR(root)) |
diff --git a/fs/anon_inodes.c b/fs/anon_inodes.c index 3168ee4e77f4..91262c34b797 100644 --- a/fs/anon_inodes.c +++ b/fs/anon_inodes.c | |||
@@ -71,8 +71,6 @@ struct file *anon_inode_getfile(const char *name, | |||
71 | const struct file_operations *fops, | 71 | const struct file_operations *fops, |
72 | void *priv, int flags) | 72 | void *priv, int flags) |
73 | { | 73 | { |
74 | struct qstr this; | ||
75 | struct path path; | ||
76 | struct file *file; | 74 | struct file *file; |
77 | 75 | ||
78 | if (IS_ERR(anon_inode_inode)) | 76 | if (IS_ERR(anon_inode_inode)) |
@@ -82,39 +80,23 @@ struct file *anon_inode_getfile(const char *name, | |||
82 | return ERR_PTR(-ENOENT); | 80 | return ERR_PTR(-ENOENT); |
83 | 81 | ||
84 | /* | 82 | /* |
85 | * Link the inode to a directory entry by creating a unique name | ||
86 | * using the inode sequence number. | ||
87 | */ | ||
88 | file = ERR_PTR(-ENOMEM); | ||
89 | this.name = name; | ||
90 | this.len = strlen(name); | ||
91 | this.hash = 0; | ||
92 | path.dentry = d_alloc_pseudo(anon_inode_mnt->mnt_sb, &this); | ||
93 | if (!path.dentry) | ||
94 | goto err_module; | ||
95 | |||
96 | path.mnt = mntget(anon_inode_mnt); | ||
97 | /* | ||
98 | * We know the anon_inode inode count is always greater than zero, | 83 | * We know the anon_inode inode count is always greater than zero, |
99 | * so ihold() is safe. | 84 | * so ihold() is safe. |
100 | */ | 85 | */ |
101 | ihold(anon_inode_inode); | 86 | ihold(anon_inode_inode); |
102 | 87 | file = alloc_file_pseudo(anon_inode_inode, anon_inode_mnt, name, | |
103 | d_instantiate(path.dentry, anon_inode_inode); | 88 | flags & (O_ACCMODE | O_NONBLOCK), fops); |
104 | |||
105 | file = alloc_file(&path, OPEN_FMODE(flags), fops); | ||
106 | if (IS_ERR(file)) | 89 | if (IS_ERR(file)) |
107 | goto err_dput; | 90 | goto err; |
91 | |||
108 | file->f_mapping = anon_inode_inode->i_mapping; | 92 | file->f_mapping = anon_inode_inode->i_mapping; |
109 | 93 | ||
110 | file->f_flags = flags & (O_ACCMODE | O_NONBLOCK); | ||
111 | file->private_data = priv; | 94 | file->private_data = priv; |
112 | 95 | ||
113 | return file; | 96 | return file; |
114 | 97 | ||
115 | err_dput: | 98 | err: |
116 | path_put(&path); | 99 | iput(anon_inode_inode); |
117 | err_module: | ||
118 | module_put(fops->owner); | 100 | module_put(fops->owner); |
119 | return file; | 101 | return file; |
120 | } | 102 | } |
diff --git a/fs/bad_inode.c b/fs/bad_inode.c index 125e8bbd22a2..8035d2a44561 100644 --- a/fs/bad_inode.c +++ b/fs/bad_inode.c | |||
@@ -134,7 +134,7 @@ static int bad_inode_update_time(struct inode *inode, struct timespec64 *time, | |||
134 | 134 | ||
135 | static int bad_inode_atomic_open(struct inode *inode, struct dentry *dentry, | 135 | static int bad_inode_atomic_open(struct inode *inode, struct dentry *dentry, |
136 | struct file *file, unsigned int open_flag, | 136 | struct file *file, unsigned int open_flag, |
137 | umode_t create_mode, int *opened) | 137 | umode_t create_mode) |
138 | { | 138 | { |
139 | return -EIO; | 139 | return -EIO; |
140 | } | 140 | } |
diff --git a/fs/binfmt_misc.c b/fs/binfmt_misc.c index 4b5fff31ef27..aa4a7a23ff99 100644 --- a/fs/binfmt_misc.c +++ b/fs/binfmt_misc.c | |||
@@ -205,7 +205,7 @@ static int load_misc_binary(struct linux_binprm *bprm) | |||
205 | goto error; | 205 | goto error; |
206 | 206 | ||
207 | if (fmt->flags & MISC_FMT_OPEN_FILE) { | 207 | if (fmt->flags & MISC_FMT_OPEN_FILE) { |
208 | interp_file = filp_clone_open(fmt->interp_file); | 208 | interp_file = file_clone_open(fmt->interp_file); |
209 | if (!IS_ERR(interp_file)) | 209 | if (!IS_ERR(interp_file)) |
210 | deny_write_access(interp_file); | 210 | deny_write_access(interp_file); |
211 | } else { | 211 | } else { |
diff --git a/fs/ceph/file.c b/fs/ceph/file.c index ad0bed99b1d5..e2679e8a2535 100644 --- a/fs/ceph/file.c +++ b/fs/ceph/file.c | |||
@@ -429,8 +429,7 @@ out: | |||
429 | * file or symlink, return 1 so the VFS can retry. | 429 | * file or symlink, return 1 so the VFS can retry. |
430 | */ | 430 | */ |
431 | int ceph_atomic_open(struct inode *dir, struct dentry *dentry, | 431 | int ceph_atomic_open(struct inode *dir, struct dentry *dentry, |
432 | struct file *file, unsigned flags, umode_t mode, | 432 | struct file *file, unsigned flags, umode_t mode) |
433 | int *opened) | ||
434 | { | 433 | { |
435 | struct ceph_fs_client *fsc = ceph_sb_to_client(dir->i_sb); | 434 | struct ceph_fs_client *fsc = ceph_sb_to_client(dir->i_sb); |
436 | struct ceph_mds_client *mdsc = fsc->mdsc; | 435 | struct ceph_mds_client *mdsc = fsc->mdsc; |
@@ -507,9 +506,9 @@ int ceph_atomic_open(struct inode *dir, struct dentry *dentry, | |||
507 | dout("atomic_open finish_open on dn %p\n", dn); | 506 | dout("atomic_open finish_open on dn %p\n", dn); |
508 | if (req->r_op == CEPH_MDS_OP_CREATE && req->r_reply_info.has_create_ino) { | 507 | if (req->r_op == CEPH_MDS_OP_CREATE && req->r_reply_info.has_create_ino) { |
509 | ceph_init_inode_acls(d_inode(dentry), &acls); | 508 | ceph_init_inode_acls(d_inode(dentry), &acls); |
510 | *opened |= FILE_CREATED; | 509 | file->f_mode |= FMODE_CREATED; |
511 | } | 510 | } |
512 | err = finish_open(file, dentry, ceph_open, opened); | 511 | err = finish_open(file, dentry, ceph_open); |
513 | } | 512 | } |
514 | out_req: | 513 | out_req: |
515 | if (!req->r_err && req->r_target_inode) | 514 | if (!req->r_err && req->r_target_inode) |
diff --git a/fs/ceph/super.h b/fs/ceph/super.h index a7077a0c989f..971328b99ede 100644 --- a/fs/ceph/super.h +++ b/fs/ceph/super.h | |||
@@ -1025,8 +1025,7 @@ extern const struct file_operations ceph_file_fops; | |||
1025 | extern int ceph_renew_caps(struct inode *inode); | 1025 | extern int ceph_renew_caps(struct inode *inode); |
1026 | extern int ceph_open(struct inode *inode, struct file *file); | 1026 | extern int ceph_open(struct inode *inode, struct file *file); |
1027 | extern int ceph_atomic_open(struct inode *dir, struct dentry *dentry, | 1027 | extern int ceph_atomic_open(struct inode *dir, struct dentry *dentry, |
1028 | struct file *file, unsigned flags, umode_t mode, | 1028 | struct file *file, unsigned flags, umode_t mode); |
1029 | int *opened); | ||
1030 | extern int ceph_release(struct inode *inode, struct file *filp); | 1029 | extern int ceph_release(struct inode *inode, struct file *filp); |
1031 | extern void ceph_fill_inline_data(struct inode *inode, struct page *locked_page, | 1030 | extern void ceph_fill_inline_data(struct inode *inode, struct page *locked_page, |
1032 | char *data, size_t len); | 1031 | char *data, size_t len); |
diff --git a/fs/cifs/cifsfs.h b/fs/cifs/cifsfs.h index 5f0231803431..f3a78efc3109 100644 --- a/fs/cifs/cifsfs.h +++ b/fs/cifs/cifsfs.h | |||
@@ -65,8 +65,7 @@ extern struct inode *cifs_root_iget(struct super_block *); | |||
65 | extern int cifs_create(struct inode *, struct dentry *, umode_t, | 65 | extern int cifs_create(struct inode *, struct dentry *, umode_t, |
66 | bool excl); | 66 | bool excl); |
67 | extern int cifs_atomic_open(struct inode *, struct dentry *, | 67 | extern int cifs_atomic_open(struct inode *, struct dentry *, |
68 | struct file *, unsigned, umode_t, | 68 | struct file *, unsigned, umode_t); |
69 | int *); | ||
70 | extern struct dentry *cifs_lookup(struct inode *, struct dentry *, | 69 | extern struct dentry *cifs_lookup(struct inode *, struct dentry *, |
71 | unsigned int); | 70 | unsigned int); |
72 | extern int cifs_unlink(struct inode *dir, struct dentry *dentry); | 71 | extern int cifs_unlink(struct inode *dir, struct dentry *dentry); |
diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c index ddae52bd1993..3713d22b95a7 100644 --- a/fs/cifs/dir.c +++ b/fs/cifs/dir.c | |||
@@ -465,8 +465,7 @@ out_err: | |||
465 | 465 | ||
466 | int | 466 | int |
467 | cifs_atomic_open(struct inode *inode, struct dentry *direntry, | 467 | cifs_atomic_open(struct inode *inode, struct dentry *direntry, |
468 | struct file *file, unsigned oflags, umode_t mode, | 468 | struct file *file, unsigned oflags, umode_t mode) |
469 | int *opened) | ||
470 | { | 469 | { |
471 | int rc; | 470 | int rc; |
472 | unsigned int xid; | 471 | unsigned int xid; |
@@ -539,9 +538,9 @@ cifs_atomic_open(struct inode *inode, struct dentry *direntry, | |||
539 | } | 538 | } |
540 | 539 | ||
541 | if ((oflags & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL)) | 540 | if ((oflags & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL)) |
542 | *opened |= FILE_CREATED; | 541 | file->f_mode |= FMODE_CREATED; |
543 | 542 | ||
544 | rc = finish_open(file, direntry, generic_file_open, opened); | 543 | rc = finish_open(file, direntry, generic_file_open); |
545 | if (rc) { | 544 | if (rc) { |
546 | if (server->ops->close) | 545 | if (server->ops->close) |
547 | server->ops->close(xid, tcon, &fid); | 546 | server->ops->close(xid, tcon, &fid); |
diff --git a/fs/file_table.c b/fs/file_table.c index 7ec0b3e5f05d..d6eccd04d703 100644 --- a/fs/file_table.c +++ b/fs/file_table.c | |||
@@ -51,6 +51,7 @@ static void file_free_rcu(struct rcu_head *head) | |||
51 | 51 | ||
52 | static inline void file_free(struct file *f) | 52 | static inline void file_free(struct file *f) |
53 | { | 53 | { |
54 | security_file_free(f); | ||
54 | percpu_counter_dec(&nr_files); | 55 | percpu_counter_dec(&nr_files); |
55 | call_rcu(&f->f_u.fu_rcuhead, file_free_rcu); | 56 | call_rcu(&f->f_u.fu_rcuhead, file_free_rcu); |
56 | } | 57 | } |
@@ -100,9 +101,8 @@ int proc_nr_files(struct ctl_table *table, int write, | |||
100 | * done, you will imbalance int the mount's writer count | 101 | * done, you will imbalance int the mount's writer count |
101 | * and a warning at __fput() time. | 102 | * and a warning at __fput() time. |
102 | */ | 103 | */ |
103 | struct file *get_empty_filp(void) | 104 | struct file *alloc_empty_file(int flags, const struct cred *cred) |
104 | { | 105 | { |
105 | const struct cred *cred = current_cred(); | ||
106 | static long old_max; | 106 | static long old_max; |
107 | struct file *f; | 107 | struct file *f; |
108 | int error; | 108 | int error; |
@@ -123,11 +123,10 @@ struct file *get_empty_filp(void) | |||
123 | if (unlikely(!f)) | 123 | if (unlikely(!f)) |
124 | return ERR_PTR(-ENOMEM); | 124 | return ERR_PTR(-ENOMEM); |
125 | 125 | ||
126 | percpu_counter_inc(&nr_files); | ||
127 | f->f_cred = get_cred(cred); | 126 | f->f_cred = get_cred(cred); |
128 | error = security_file_alloc(f); | 127 | error = security_file_alloc(f); |
129 | if (unlikely(error)) { | 128 | if (unlikely(error)) { |
130 | file_free(f); | 129 | file_free_rcu(&f->f_u.fu_rcuhead); |
131 | return ERR_PTR(error); | 130 | return ERR_PTR(error); |
132 | } | 131 | } |
133 | 132 | ||
@@ -136,7 +135,10 @@ struct file *get_empty_filp(void) | |||
136 | spin_lock_init(&f->f_lock); | 135 | spin_lock_init(&f->f_lock); |
137 | mutex_init(&f->f_pos_lock); | 136 | mutex_init(&f->f_pos_lock); |
138 | eventpoll_init_file(f); | 137 | eventpoll_init_file(f); |
138 | f->f_flags = flags; | ||
139 | f->f_mode = OPEN_FMODE(flags); | ||
139 | /* f->f_version: 0 */ | 140 | /* f->f_version: 0 */ |
141 | percpu_counter_inc(&nr_files); | ||
140 | return f; | 142 | return f; |
141 | 143 | ||
142 | over: | 144 | over: |
@@ -152,15 +154,15 @@ over: | |||
152 | * alloc_file - allocate and initialize a 'struct file' | 154 | * alloc_file - allocate and initialize a 'struct file' |
153 | * | 155 | * |
154 | * @path: the (dentry, vfsmount) pair for the new file | 156 | * @path: the (dentry, vfsmount) pair for the new file |
155 | * @mode: the mode with which the new file will be opened | 157 | * @flags: O_... flags with which the new file will be opened |
156 | * @fop: the 'struct file_operations' for the new file | 158 | * @fop: the 'struct file_operations' for the new file |
157 | */ | 159 | */ |
158 | struct file *alloc_file(const struct path *path, fmode_t mode, | 160 | static struct file *alloc_file(const struct path *path, int flags, |
159 | const struct file_operations *fop) | 161 | const struct file_operations *fop) |
160 | { | 162 | { |
161 | struct file *file; | 163 | struct file *file; |
162 | 164 | ||
163 | file = get_empty_filp(); | 165 | file = alloc_empty_file(flags, current_cred()); |
164 | if (IS_ERR(file)) | 166 | if (IS_ERR(file)) |
165 | return file; | 167 | return file; |
166 | 168 | ||
@@ -168,19 +170,56 @@ struct file *alloc_file(const struct path *path, fmode_t mode, | |||
168 | file->f_inode = path->dentry->d_inode; | 170 | file->f_inode = path->dentry->d_inode; |
169 | file->f_mapping = path->dentry->d_inode->i_mapping; | 171 | file->f_mapping = path->dentry->d_inode->i_mapping; |
170 | file->f_wb_err = filemap_sample_wb_err(file->f_mapping); | 172 | file->f_wb_err = filemap_sample_wb_err(file->f_mapping); |
171 | if ((mode & FMODE_READ) && | 173 | if ((file->f_mode & FMODE_READ) && |
172 | likely(fop->read || fop->read_iter)) | 174 | likely(fop->read || fop->read_iter)) |
173 | mode |= FMODE_CAN_READ; | 175 | file->f_mode |= FMODE_CAN_READ; |
174 | if ((mode & FMODE_WRITE) && | 176 | if ((file->f_mode & FMODE_WRITE) && |
175 | likely(fop->write || fop->write_iter)) | 177 | likely(fop->write || fop->write_iter)) |
176 | mode |= FMODE_CAN_WRITE; | 178 | file->f_mode |= FMODE_CAN_WRITE; |
177 | file->f_mode = mode; | 179 | file->f_mode |= FMODE_OPENED; |
178 | file->f_op = fop; | 180 | file->f_op = fop; |
179 | if ((mode & (FMODE_READ | FMODE_WRITE)) == FMODE_READ) | 181 | if ((file->f_mode & (FMODE_READ | FMODE_WRITE)) == FMODE_READ) |
180 | i_readcount_inc(path->dentry->d_inode); | 182 | i_readcount_inc(path->dentry->d_inode); |
181 | return file; | 183 | return file; |
182 | } | 184 | } |
183 | EXPORT_SYMBOL(alloc_file); | 185 | |
186 | struct file *alloc_file_pseudo(struct inode *inode, struct vfsmount *mnt, | ||
187 | const char *name, int flags, | ||
188 | const struct file_operations *fops) | ||
189 | { | ||
190 | static const struct dentry_operations anon_ops = { | ||
191 | .d_dname = simple_dname | ||
192 | }; | ||
193 | struct qstr this = QSTR_INIT(name, strlen(name)); | ||
194 | struct path path; | ||
195 | struct file *file; | ||
196 | |||
197 | path.dentry = d_alloc_pseudo(mnt->mnt_sb, &this); | ||
198 | if (!path.dentry) | ||
199 | return ERR_PTR(-ENOMEM); | ||
200 | if (!mnt->mnt_sb->s_d_op) | ||
201 | d_set_d_op(path.dentry, &anon_ops); | ||
202 | path.mnt = mntget(mnt); | ||
203 | d_instantiate(path.dentry, inode); | ||
204 | file = alloc_file(&path, flags, fops); | ||
205 | if (IS_ERR(file)) { | ||
206 | ihold(inode); | ||
207 | path_put(&path); | ||
208 | } | ||
209 | return file; | ||
210 | } | ||
211 | EXPORT_SYMBOL(alloc_file_pseudo); | ||
212 | |||
213 | struct file *alloc_file_clone(struct file *base, int flags, | ||
214 | const struct file_operations *fops) | ||
215 | { | ||
216 | struct file *f = alloc_file(&base->f_path, flags, fops); | ||
217 | if (!IS_ERR(f)) { | ||
218 | path_get(&f->f_path); | ||
219 | f->f_mapping = base->f_mapping; | ||
220 | } | ||
221 | return f; | ||
222 | } | ||
184 | 223 | ||
185 | /* the real guts of fput() - releasing the last reference to file | 224 | /* the real guts of fput() - releasing the last reference to file |
186 | */ | 225 | */ |
@@ -190,6 +229,9 @@ static void __fput(struct file *file) | |||
190 | struct vfsmount *mnt = file->f_path.mnt; | 229 | struct vfsmount *mnt = file->f_path.mnt; |
191 | struct inode *inode = file->f_inode; | 230 | struct inode *inode = file->f_inode; |
192 | 231 | ||
232 | if (unlikely(!(file->f_mode & FMODE_OPENED))) | ||
233 | goto out; | ||
234 | |||
193 | might_sleep(); | 235 | might_sleep(); |
194 | 236 | ||
195 | fsnotify_close(file); | 237 | fsnotify_close(file); |
@@ -207,7 +249,6 @@ static void __fput(struct file *file) | |||
207 | } | 249 | } |
208 | if (file->f_op->release) | 250 | if (file->f_op->release) |
209 | file->f_op->release(inode, file); | 251 | file->f_op->release(inode, file); |
210 | security_file_free(file); | ||
211 | if (unlikely(S_ISCHR(inode->i_mode) && inode->i_cdev != NULL && | 252 | if (unlikely(S_ISCHR(inode->i_mode) && inode->i_cdev != NULL && |
212 | !(file->f_mode & FMODE_PATH))) { | 253 | !(file->f_mode & FMODE_PATH))) { |
213 | cdev_put(inode->i_cdev); | 254 | cdev_put(inode->i_cdev); |
@@ -220,12 +261,10 @@ static void __fput(struct file *file) | |||
220 | put_write_access(inode); | 261 | put_write_access(inode); |
221 | __mnt_drop_write(mnt); | 262 | __mnt_drop_write(mnt); |
222 | } | 263 | } |
223 | file->f_path.dentry = NULL; | ||
224 | file->f_path.mnt = NULL; | ||
225 | file->f_inode = NULL; | ||
226 | file_free(file); | ||
227 | dput(dentry); | 264 | dput(dentry); |
228 | mntput(mnt); | 265 | mntput(mnt); |
266 | out: | ||
267 | file_free(file); | ||
229 | } | 268 | } |
230 | 269 | ||
231 | static LLIST_HEAD(delayed_fput_list); | 270 | static LLIST_HEAD(delayed_fput_list); |
@@ -300,14 +339,6 @@ void __fput_sync(struct file *file) | |||
300 | 339 | ||
301 | EXPORT_SYMBOL(fput); | 340 | EXPORT_SYMBOL(fput); |
302 | 341 | ||
303 | void put_filp(struct file *file) | ||
304 | { | ||
305 | if (atomic_long_dec_and_test(&file->f_count)) { | ||
306 | security_file_free(file); | ||
307 | file_free(file); | ||
308 | } | ||
309 | } | ||
310 | |||
311 | void __init files_init(void) | 342 | void __init files_init(void) |
312 | { | 343 | { |
313 | filp_cachep = kmem_cache_create("filp", sizeof(struct file), 0, | 344 | filp_cachep = kmem_cache_create("filp", sizeof(struct file), 0, |
diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c index 56231b31f806..c979329311c8 100644 --- a/fs/fuse/dir.c +++ b/fs/fuse/dir.c | |||
@@ -399,7 +399,7 @@ static struct dentry *fuse_lookup(struct inode *dir, struct dentry *entry, | |||
399 | */ | 399 | */ |
400 | static int fuse_create_open(struct inode *dir, struct dentry *entry, | 400 | static int fuse_create_open(struct inode *dir, struct dentry *entry, |
401 | struct file *file, unsigned flags, | 401 | struct file *file, unsigned flags, |
402 | umode_t mode, int *opened) | 402 | umode_t mode) |
403 | { | 403 | { |
404 | int err; | 404 | int err; |
405 | struct inode *inode; | 405 | struct inode *inode; |
@@ -469,7 +469,7 @@ static int fuse_create_open(struct inode *dir, struct dentry *entry, | |||
469 | d_instantiate(entry, inode); | 469 | d_instantiate(entry, inode); |
470 | fuse_change_entry_timeout(entry, &outentry); | 470 | fuse_change_entry_timeout(entry, &outentry); |
471 | fuse_invalidate_attr(dir); | 471 | fuse_invalidate_attr(dir); |
472 | err = finish_open(file, entry, generic_file_open, opened); | 472 | err = finish_open(file, entry, generic_file_open); |
473 | if (err) { | 473 | if (err) { |
474 | fuse_sync_release(ff, flags); | 474 | fuse_sync_release(ff, flags); |
475 | } else { | 475 | } else { |
@@ -489,7 +489,7 @@ out_err: | |||
489 | static int fuse_mknod(struct inode *, struct dentry *, umode_t, dev_t); | 489 | static int fuse_mknod(struct inode *, struct dentry *, umode_t, dev_t); |
490 | static int fuse_atomic_open(struct inode *dir, struct dentry *entry, | 490 | static int fuse_atomic_open(struct inode *dir, struct dentry *entry, |
491 | struct file *file, unsigned flags, | 491 | struct file *file, unsigned flags, |
492 | umode_t mode, int *opened) | 492 | umode_t mode) |
493 | { | 493 | { |
494 | int err; | 494 | int err; |
495 | struct fuse_conn *fc = get_fuse_conn(dir); | 495 | struct fuse_conn *fc = get_fuse_conn(dir); |
@@ -508,12 +508,12 @@ static int fuse_atomic_open(struct inode *dir, struct dentry *entry, | |||
508 | goto no_open; | 508 | goto no_open; |
509 | 509 | ||
510 | /* Only creates */ | 510 | /* Only creates */ |
511 | *opened |= FILE_CREATED; | 511 | file->f_mode |= FMODE_CREATED; |
512 | 512 | ||
513 | if (fc->no_create) | 513 | if (fc->no_create) |
514 | goto mknod; | 514 | goto mknod; |
515 | 515 | ||
516 | err = fuse_create_open(dir, entry, file, flags, mode, opened); | 516 | err = fuse_create_open(dir, entry, file, flags, mode); |
517 | if (err == -ENOSYS) { | 517 | if (err == -ENOSYS) { |
518 | fc->no_create = 1; | 518 | fc->no_create = 1; |
519 | goto mknod; | 519 | goto mknod; |
diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c index feda55f67050..648f0ca1ad57 100644 --- a/fs/gfs2/inode.c +++ b/fs/gfs2/inode.c | |||
@@ -580,7 +580,7 @@ static int gfs2_initxattrs(struct inode *inode, const struct xattr *xattr_array, | |||
580 | static int gfs2_create_inode(struct inode *dir, struct dentry *dentry, | 580 | static int gfs2_create_inode(struct inode *dir, struct dentry *dentry, |
581 | struct file *file, | 581 | struct file *file, |
582 | umode_t mode, dev_t dev, const char *symname, | 582 | umode_t mode, dev_t dev, const char *symname, |
583 | unsigned int size, int excl, int *opened) | 583 | unsigned int size, int excl) |
584 | { | 584 | { |
585 | const struct qstr *name = &dentry->d_name; | 585 | const struct qstr *name = &dentry->d_name; |
586 | struct posix_acl *default_acl, *acl; | 586 | struct posix_acl *default_acl, *acl; |
@@ -626,7 +626,7 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry, | |||
626 | error = 0; | 626 | error = 0; |
627 | if (file) { | 627 | if (file) { |
628 | if (S_ISREG(inode->i_mode)) | 628 | if (S_ISREG(inode->i_mode)) |
629 | error = finish_open(file, dentry, gfs2_open_common, opened); | 629 | error = finish_open(file, dentry, gfs2_open_common); |
630 | else | 630 | else |
631 | error = finish_no_open(file, NULL); | 631 | error = finish_no_open(file, NULL); |
632 | } | 632 | } |
@@ -767,8 +767,8 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry, | |||
767 | mark_inode_dirty(inode); | 767 | mark_inode_dirty(inode); |
768 | d_instantiate(dentry, inode); | 768 | d_instantiate(dentry, inode); |
769 | if (file) { | 769 | if (file) { |
770 | *opened |= FILE_CREATED; | 770 | file->f_mode |= FMODE_CREATED; |
771 | error = finish_open(file, dentry, gfs2_open_common, opened); | 771 | error = finish_open(file, dentry, gfs2_open_common); |
772 | } | 772 | } |
773 | gfs2_glock_dq_uninit(ghs); | 773 | gfs2_glock_dq_uninit(ghs); |
774 | gfs2_glock_dq_uninit(ghs + 1); | 774 | gfs2_glock_dq_uninit(ghs + 1); |
@@ -822,7 +822,7 @@ fail: | |||
822 | static int gfs2_create(struct inode *dir, struct dentry *dentry, | 822 | static int gfs2_create(struct inode *dir, struct dentry *dentry, |
823 | umode_t mode, bool excl) | 823 | umode_t mode, bool excl) |
824 | { | 824 | { |
825 | return gfs2_create_inode(dir, dentry, NULL, S_IFREG | mode, 0, NULL, 0, excl, NULL); | 825 | return gfs2_create_inode(dir, dentry, NULL, S_IFREG | mode, 0, NULL, 0, excl); |
826 | } | 826 | } |
827 | 827 | ||
828 | /** | 828 | /** |
@@ -830,14 +830,13 @@ static int gfs2_create(struct inode *dir, struct dentry *dentry, | |||
830 | * @dir: The directory inode | 830 | * @dir: The directory inode |
831 | * @dentry: The dentry of the new inode | 831 | * @dentry: The dentry of the new inode |
832 | * @file: File to be opened | 832 | * @file: File to be opened |
833 | * @opened: atomic_open flags | ||
834 | * | 833 | * |
835 | * | 834 | * |
836 | * Returns: errno | 835 | * Returns: errno |
837 | */ | 836 | */ |
838 | 837 | ||
839 | static struct dentry *__gfs2_lookup(struct inode *dir, struct dentry *dentry, | 838 | static struct dentry *__gfs2_lookup(struct inode *dir, struct dentry *dentry, |
840 | struct file *file, int *opened) | 839 | struct file *file) |
841 | { | 840 | { |
842 | struct inode *inode; | 841 | struct inode *inode; |
843 | struct dentry *d; | 842 | struct dentry *d; |
@@ -866,7 +865,7 @@ static struct dentry *__gfs2_lookup(struct inode *dir, struct dentry *dentry, | |||
866 | return d; | 865 | return d; |
867 | } | 866 | } |
868 | if (file && S_ISREG(inode->i_mode)) | 867 | if (file && S_ISREG(inode->i_mode)) |
869 | error = finish_open(file, dentry, gfs2_open_common, opened); | 868 | error = finish_open(file, dentry, gfs2_open_common); |
870 | 869 | ||
871 | gfs2_glock_dq_uninit(&gh); | 870 | gfs2_glock_dq_uninit(&gh); |
872 | if (error) { | 871 | if (error) { |
@@ -879,7 +878,7 @@ static struct dentry *__gfs2_lookup(struct inode *dir, struct dentry *dentry, | |||
879 | static struct dentry *gfs2_lookup(struct inode *dir, struct dentry *dentry, | 878 | static struct dentry *gfs2_lookup(struct inode *dir, struct dentry *dentry, |
880 | unsigned flags) | 879 | unsigned flags) |
881 | { | 880 | { |
882 | return __gfs2_lookup(dir, dentry, NULL, NULL); | 881 | return __gfs2_lookup(dir, dentry, NULL); |
883 | } | 882 | } |
884 | 883 | ||
885 | /** | 884 | /** |
@@ -1189,7 +1188,7 @@ static int gfs2_symlink(struct inode *dir, struct dentry *dentry, | |||
1189 | if (size >= gfs2_max_stuffed_size(GFS2_I(dir))) | 1188 | if (size >= gfs2_max_stuffed_size(GFS2_I(dir))) |
1190 | return -ENAMETOOLONG; | 1189 | return -ENAMETOOLONG; |
1191 | 1190 | ||
1192 | return gfs2_create_inode(dir, dentry, NULL, S_IFLNK | S_IRWXUGO, 0, symname, size, 0, NULL); | 1191 | return gfs2_create_inode(dir, dentry, NULL, S_IFLNK | S_IRWXUGO, 0, symname, size, 0); |
1193 | } | 1192 | } |
1194 | 1193 | ||
1195 | /** | 1194 | /** |
@@ -1204,7 +1203,7 @@ static int gfs2_symlink(struct inode *dir, struct dentry *dentry, | |||
1204 | static int gfs2_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) | 1203 | static int gfs2_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) |
1205 | { | 1204 | { |
1206 | unsigned dsize = gfs2_max_stuffed_size(GFS2_I(dir)); | 1205 | unsigned dsize = gfs2_max_stuffed_size(GFS2_I(dir)); |
1207 | return gfs2_create_inode(dir, dentry, NULL, S_IFDIR | mode, 0, NULL, dsize, 0, NULL); | 1206 | return gfs2_create_inode(dir, dentry, NULL, S_IFDIR | mode, 0, NULL, dsize, 0); |
1208 | } | 1207 | } |
1209 | 1208 | ||
1210 | /** | 1209 | /** |
@@ -1219,7 +1218,7 @@ static int gfs2_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) | |||
1219 | static int gfs2_mknod(struct inode *dir, struct dentry *dentry, umode_t mode, | 1218 | static int gfs2_mknod(struct inode *dir, struct dentry *dentry, umode_t mode, |
1220 | dev_t dev) | 1219 | dev_t dev) |
1221 | { | 1220 | { |
1222 | return gfs2_create_inode(dir, dentry, NULL, mode, dev, NULL, 0, 0, NULL); | 1221 | return gfs2_create_inode(dir, dentry, NULL, mode, dev, NULL, 0, 0); |
1223 | } | 1222 | } |
1224 | 1223 | ||
1225 | /** | 1224 | /** |
@@ -1229,14 +1228,13 @@ static int gfs2_mknod(struct inode *dir, struct dentry *dentry, umode_t mode, | |||
1229 | * @file: The proposed new struct file | 1228 | * @file: The proposed new struct file |
1230 | * @flags: open flags | 1229 | * @flags: open flags |
1231 | * @mode: File mode | 1230 | * @mode: File mode |
1232 | * @opened: Flag to say whether the file has been opened or not | ||
1233 | * | 1231 | * |
1234 | * Returns: error code or 0 for success | 1232 | * Returns: error code or 0 for success |
1235 | */ | 1233 | */ |
1236 | 1234 | ||
1237 | static int gfs2_atomic_open(struct inode *dir, struct dentry *dentry, | 1235 | static int gfs2_atomic_open(struct inode *dir, struct dentry *dentry, |
1238 | struct file *file, unsigned flags, | 1236 | struct file *file, unsigned flags, |
1239 | umode_t mode, int *opened) | 1237 | umode_t mode) |
1240 | { | 1238 | { |
1241 | struct dentry *d; | 1239 | struct dentry *d; |
1242 | bool excl = !!(flags & O_EXCL); | 1240 | bool excl = !!(flags & O_EXCL); |
@@ -1244,13 +1242,13 @@ static int gfs2_atomic_open(struct inode *dir, struct dentry *dentry, | |||
1244 | if (!d_in_lookup(dentry)) | 1242 | if (!d_in_lookup(dentry)) |
1245 | goto skip_lookup; | 1243 | goto skip_lookup; |
1246 | 1244 | ||
1247 | d = __gfs2_lookup(dir, dentry, file, opened); | 1245 | d = __gfs2_lookup(dir, dentry, file); |
1248 | if (IS_ERR(d)) | 1246 | if (IS_ERR(d)) |
1249 | return PTR_ERR(d); | 1247 | return PTR_ERR(d); |
1250 | if (d != NULL) | 1248 | if (d != NULL) |
1251 | dentry = d; | 1249 | dentry = d; |
1252 | if (d_really_is_positive(dentry)) { | 1250 | if (d_really_is_positive(dentry)) { |
1253 | if (!(*opened & FILE_OPENED)) | 1251 | if (!(file->f_mode & FMODE_OPENED)) |
1254 | return finish_no_open(file, d); | 1252 | return finish_no_open(file, d); |
1255 | dput(d); | 1253 | dput(d); |
1256 | return 0; | 1254 | return 0; |
@@ -1262,7 +1260,7 @@ skip_lookup: | |||
1262 | if (!(flags & O_CREAT)) | 1260 | if (!(flags & O_CREAT)) |
1263 | return -ENOENT; | 1261 | return -ENOENT; |
1264 | 1262 | ||
1265 | return gfs2_create_inode(dir, dentry, file, S_IFREG | mode, 0, NULL, 0, excl, opened); | 1263 | return gfs2_create_inode(dir, dentry, file, S_IFREG | mode, 0, NULL, 0, excl); |
1266 | } | 1264 | } |
1267 | 1265 | ||
1268 | /* | 1266 | /* |
diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c index 40d4c66c7751..346a146c7617 100644 --- a/fs/hugetlbfs/inode.c +++ b/fs/hugetlbfs/inode.c | |||
@@ -1310,10 +1310,6 @@ static int get_hstate_idx(int page_size_log) | |||
1310 | return h - hstates; | 1310 | return h - hstates; |
1311 | } | 1311 | } |
1312 | 1312 | ||
1313 | static const struct dentry_operations anon_ops = { | ||
1314 | .d_dname = simple_dname | ||
1315 | }; | ||
1316 | |||
1317 | /* | 1313 | /* |
1318 | * Note that size should be aligned to proper hugepage size in caller side, | 1314 | * Note that size should be aligned to proper hugepage size in caller side, |
1319 | * otherwise hugetlb_reserve_pages reserves one less hugepages than intended. | 1315 | * otherwise hugetlb_reserve_pages reserves one less hugepages than intended. |
@@ -1322,19 +1318,18 @@ struct file *hugetlb_file_setup(const char *name, size_t size, | |||
1322 | vm_flags_t acctflag, struct user_struct **user, | 1318 | vm_flags_t acctflag, struct user_struct **user, |
1323 | int creat_flags, int page_size_log) | 1319 | int creat_flags, int page_size_log) |
1324 | { | 1320 | { |
1325 | struct file *file = ERR_PTR(-ENOMEM); | ||
1326 | struct inode *inode; | 1321 | struct inode *inode; |
1327 | struct path path; | 1322 | struct vfsmount *mnt; |
1328 | struct super_block *sb; | ||
1329 | struct qstr quick_string; | ||
1330 | int hstate_idx; | 1323 | int hstate_idx; |
1324 | struct file *file; | ||
1331 | 1325 | ||
1332 | hstate_idx = get_hstate_idx(page_size_log); | 1326 | hstate_idx = get_hstate_idx(page_size_log); |
1333 | if (hstate_idx < 0) | 1327 | if (hstate_idx < 0) |
1334 | return ERR_PTR(-ENODEV); | 1328 | return ERR_PTR(-ENODEV); |
1335 | 1329 | ||
1336 | *user = NULL; | 1330 | *user = NULL; |
1337 | if (!hugetlbfs_vfsmount[hstate_idx]) | 1331 | mnt = hugetlbfs_vfsmount[hstate_idx]; |
1332 | if (!mnt) | ||
1338 | return ERR_PTR(-ENOENT); | 1333 | return ERR_PTR(-ENOENT); |
1339 | 1334 | ||
1340 | if (creat_flags == HUGETLB_SHMFS_INODE && !can_do_hugetlb_shm()) { | 1335 | if (creat_flags == HUGETLB_SHMFS_INODE && !can_do_hugetlb_shm()) { |
@@ -1350,45 +1345,28 @@ struct file *hugetlb_file_setup(const char *name, size_t size, | |||
1350 | } | 1345 | } |
1351 | } | 1346 | } |
1352 | 1347 | ||
1353 | sb = hugetlbfs_vfsmount[hstate_idx]->mnt_sb; | ||
1354 | quick_string.name = name; | ||
1355 | quick_string.len = strlen(quick_string.name); | ||
1356 | quick_string.hash = 0; | ||
1357 | path.dentry = d_alloc_pseudo(sb, &quick_string); | ||
1358 | if (!path.dentry) | ||
1359 | goto out_shm_unlock; | ||
1360 | |||
1361 | d_set_d_op(path.dentry, &anon_ops); | ||
1362 | path.mnt = mntget(hugetlbfs_vfsmount[hstate_idx]); | ||
1363 | file = ERR_PTR(-ENOSPC); | 1348 | file = ERR_PTR(-ENOSPC); |
1364 | inode = hugetlbfs_get_inode(sb, NULL, S_IFREG | S_IRWXUGO, 0); | 1349 | inode = hugetlbfs_get_inode(mnt->mnt_sb, NULL, S_IFREG | S_IRWXUGO, 0); |
1365 | if (!inode) | 1350 | if (!inode) |
1366 | goto out_dentry; | 1351 | goto out; |
1367 | if (creat_flags == HUGETLB_SHMFS_INODE) | 1352 | if (creat_flags == HUGETLB_SHMFS_INODE) |
1368 | inode->i_flags |= S_PRIVATE; | 1353 | inode->i_flags |= S_PRIVATE; |
1369 | 1354 | ||
1370 | file = ERR_PTR(-ENOMEM); | ||
1371 | if (hugetlb_reserve_pages(inode, 0, | ||
1372 | size >> huge_page_shift(hstate_inode(inode)), NULL, | ||
1373 | acctflag)) | ||
1374 | goto out_inode; | ||
1375 | |||
1376 | d_instantiate(path.dentry, inode); | ||
1377 | inode->i_size = size; | 1355 | inode->i_size = size; |
1378 | clear_nlink(inode); | 1356 | clear_nlink(inode); |
1379 | 1357 | ||
1380 | file = alloc_file(&path, FMODE_WRITE | FMODE_READ, | 1358 | if (hugetlb_reserve_pages(inode, 0, |
1381 | &hugetlbfs_file_operations); | 1359 | size >> huge_page_shift(hstate_inode(inode)), NULL, |
1382 | if (IS_ERR(file)) | 1360 | acctflag)) |
1383 | goto out_dentry; /* inode is already attached */ | 1361 | file = ERR_PTR(-ENOMEM); |
1384 | 1362 | else | |
1385 | return file; | 1363 | file = alloc_file_pseudo(inode, mnt, name, O_RDWR, |
1364 | &hugetlbfs_file_operations); | ||
1365 | if (!IS_ERR(file)) | ||
1366 | return file; | ||
1386 | 1367 | ||
1387 | out_inode: | ||
1388 | iput(inode); | 1368 | iput(inode); |
1389 | out_dentry: | 1369 | out: |
1390 | path_put(&path); | ||
1391 | out_shm_unlock: | ||
1392 | if (*user) { | 1370 | if (*user) { |
1393 | user_shm_unlock(size, *user); | 1371 | user_shm_unlock(size, *user); |
1394 | *user = NULL; | 1372 | *user = NULL; |
diff --git a/fs/internal.h b/fs/internal.h index 5645b4ebf494..52a346903748 100644 --- a/fs/internal.h +++ b/fs/internal.h | |||
@@ -93,7 +93,7 @@ extern void chroot_fs_refs(const struct path *, const struct path *); | |||
93 | /* | 93 | /* |
94 | * file_table.c | 94 | * file_table.c |
95 | */ | 95 | */ |
96 | extern struct file *get_empty_filp(void); | 96 | extern struct file *alloc_empty_file(int, const struct cred *); |
97 | 97 | ||
98 | /* | 98 | /* |
99 | * super.c | 99 | * super.c |
@@ -125,8 +125,7 @@ int do_fchmodat(int dfd, const char __user *filename, umode_t mode); | |||
125 | int do_fchownat(int dfd, const char __user *filename, uid_t user, gid_t group, | 125 | int do_fchownat(int dfd, const char __user *filename, uid_t user, gid_t group, |
126 | int flag); | 126 | int flag); |
127 | 127 | ||
128 | extern int open_check_o_direct(struct file *f); | 128 | extern int vfs_open(const struct path *, struct file *); |
129 | extern int vfs_open(const struct path *, struct file *, const struct cred *); | ||
130 | 129 | ||
131 | /* | 130 | /* |
132 | * inode.c | 131 | * inode.c |
diff --git a/fs/namei.c b/fs/namei.c index 734cef54fdf8..278e494bcbd2 100644 --- a/fs/namei.c +++ b/fs/namei.c | |||
@@ -2028,6 +2028,8 @@ static int link_path_walk(const char *name, struct nameidata *nd) | |||
2028 | { | 2028 | { |
2029 | int err; | 2029 | int err; |
2030 | 2030 | ||
2031 | if (IS_ERR(name)) | ||
2032 | return PTR_ERR(name); | ||
2031 | while (*name=='/') | 2033 | while (*name=='/') |
2032 | name++; | 2034 | name++; |
2033 | if (!*name) | 2035 | if (!*name) |
@@ -2125,12 +2127,15 @@ OK: | |||
2125 | } | 2127 | } |
2126 | } | 2128 | } |
2127 | 2129 | ||
2130 | /* must be paired with terminate_walk() */ | ||
2128 | static const char *path_init(struct nameidata *nd, unsigned flags) | 2131 | static const char *path_init(struct nameidata *nd, unsigned flags) |
2129 | { | 2132 | { |
2130 | const char *s = nd->name->name; | 2133 | const char *s = nd->name->name; |
2131 | 2134 | ||
2132 | if (!*s) | 2135 | if (!*s) |
2133 | flags &= ~LOOKUP_RCU; | 2136 | flags &= ~LOOKUP_RCU; |
2137 | if (flags & LOOKUP_RCU) | ||
2138 | rcu_read_lock(); | ||
2134 | 2139 | ||
2135 | nd->last_type = LAST_ROOT; /* if there are only slashes... */ | 2140 | nd->last_type = LAST_ROOT; /* if there are only slashes... */ |
2136 | nd->flags = flags | LOOKUP_JUMPED | LOOKUP_PARENT; | 2141 | nd->flags = flags | LOOKUP_JUMPED | LOOKUP_PARENT; |
@@ -2143,7 +2148,6 @@ static const char *path_init(struct nameidata *nd, unsigned flags) | |||
2143 | nd->path = nd->root; | 2148 | nd->path = nd->root; |
2144 | nd->inode = inode; | 2149 | nd->inode = inode; |
2145 | if (flags & LOOKUP_RCU) { | 2150 | if (flags & LOOKUP_RCU) { |
2146 | rcu_read_lock(); | ||
2147 | nd->seq = __read_seqcount_begin(&nd->path.dentry->d_seq); | 2151 | nd->seq = __read_seqcount_begin(&nd->path.dentry->d_seq); |
2148 | nd->root_seq = nd->seq; | 2152 | nd->root_seq = nd->seq; |
2149 | nd->m_seq = read_seqbegin(&mount_lock); | 2153 | nd->m_seq = read_seqbegin(&mount_lock); |
@@ -2159,21 +2163,15 @@ static const char *path_init(struct nameidata *nd, unsigned flags) | |||
2159 | 2163 | ||
2160 | nd->m_seq = read_seqbegin(&mount_lock); | 2164 | nd->m_seq = read_seqbegin(&mount_lock); |
2161 | if (*s == '/') { | 2165 | if (*s == '/') { |
2162 | if (flags & LOOKUP_RCU) | ||
2163 | rcu_read_lock(); | ||
2164 | set_root(nd); | 2166 | set_root(nd); |
2165 | if (likely(!nd_jump_root(nd))) | 2167 | if (likely(!nd_jump_root(nd))) |
2166 | return s; | 2168 | return s; |
2167 | nd->root.mnt = NULL; | ||
2168 | rcu_read_unlock(); | ||
2169 | return ERR_PTR(-ECHILD); | 2169 | return ERR_PTR(-ECHILD); |
2170 | } else if (nd->dfd == AT_FDCWD) { | 2170 | } else if (nd->dfd == AT_FDCWD) { |
2171 | if (flags & LOOKUP_RCU) { | 2171 | if (flags & LOOKUP_RCU) { |
2172 | struct fs_struct *fs = current->fs; | 2172 | struct fs_struct *fs = current->fs; |
2173 | unsigned seq; | 2173 | unsigned seq; |
2174 | 2174 | ||
2175 | rcu_read_lock(); | ||
2176 | |||
2177 | do { | 2175 | do { |
2178 | seq = read_seqcount_begin(&fs->seq); | 2176 | seq = read_seqcount_begin(&fs->seq); |
2179 | nd->path = fs->pwd; | 2177 | nd->path = fs->pwd; |
@@ -2195,16 +2193,13 @@ static const char *path_init(struct nameidata *nd, unsigned flags) | |||
2195 | 2193 | ||
2196 | dentry = f.file->f_path.dentry; | 2194 | dentry = f.file->f_path.dentry; |
2197 | 2195 | ||
2198 | if (*s) { | 2196 | if (*s && unlikely(!d_can_lookup(dentry))) { |
2199 | if (!d_can_lookup(dentry)) { | 2197 | fdput(f); |
2200 | fdput(f); | 2198 | return ERR_PTR(-ENOTDIR); |
2201 | return ERR_PTR(-ENOTDIR); | ||
2202 | } | ||
2203 | } | 2199 | } |
2204 | 2200 | ||
2205 | nd->path = f.file->f_path; | 2201 | nd->path = f.file->f_path; |
2206 | if (flags & LOOKUP_RCU) { | 2202 | if (flags & LOOKUP_RCU) { |
2207 | rcu_read_lock(); | ||
2208 | nd->inode = nd->path.dentry->d_inode; | 2203 | nd->inode = nd->path.dentry->d_inode; |
2209 | nd->seq = read_seqcount_begin(&nd->path.dentry->d_seq); | 2204 | nd->seq = read_seqcount_begin(&nd->path.dentry->d_seq); |
2210 | } else { | 2205 | } else { |
@@ -2272,24 +2267,15 @@ static int path_lookupat(struct nameidata *nd, unsigned flags, struct path *path | |||
2272 | const char *s = path_init(nd, flags); | 2267 | const char *s = path_init(nd, flags); |
2273 | int err; | 2268 | int err; |
2274 | 2269 | ||
2275 | if (IS_ERR(s)) | 2270 | if (unlikely(flags & LOOKUP_DOWN) && !IS_ERR(s)) { |
2276 | return PTR_ERR(s); | ||
2277 | |||
2278 | if (unlikely(flags & LOOKUP_DOWN)) { | ||
2279 | err = handle_lookup_down(nd); | 2271 | err = handle_lookup_down(nd); |
2280 | if (unlikely(err < 0)) { | 2272 | if (unlikely(err < 0)) |
2281 | terminate_walk(nd); | 2273 | s = ERR_PTR(err); |
2282 | return err; | ||
2283 | } | ||
2284 | } | 2274 | } |
2285 | 2275 | ||
2286 | while (!(err = link_path_walk(s, nd)) | 2276 | while (!(err = link_path_walk(s, nd)) |
2287 | && ((err = lookup_last(nd)) > 0)) { | 2277 | && ((err = lookup_last(nd)) > 0)) { |
2288 | s = trailing_symlink(nd); | 2278 | s = trailing_symlink(nd); |
2289 | if (IS_ERR(s)) { | ||
2290 | err = PTR_ERR(s); | ||
2291 | break; | ||
2292 | } | ||
2293 | } | 2279 | } |
2294 | if (!err) | 2280 | if (!err) |
2295 | err = complete_walk(nd); | 2281 | err = complete_walk(nd); |
@@ -2336,10 +2322,7 @@ static int path_parentat(struct nameidata *nd, unsigned flags, | |||
2336 | struct path *parent) | 2322 | struct path *parent) |
2337 | { | 2323 | { |
2338 | const char *s = path_init(nd, flags); | 2324 | const char *s = path_init(nd, flags); |
2339 | int err; | 2325 | int err = link_path_walk(s, nd); |
2340 | if (IS_ERR(s)) | ||
2341 | return PTR_ERR(s); | ||
2342 | err = link_path_walk(s, nd); | ||
2343 | if (!err) | 2326 | if (!err) |
2344 | err = complete_walk(nd); | 2327 | err = complete_walk(nd); |
2345 | if (!err) { | 2328 | if (!err) { |
@@ -2666,15 +2649,10 @@ path_mountpoint(struct nameidata *nd, unsigned flags, struct path *path) | |||
2666 | { | 2649 | { |
2667 | const char *s = path_init(nd, flags); | 2650 | const char *s = path_init(nd, flags); |
2668 | int err; | 2651 | int err; |
2669 | if (IS_ERR(s)) | 2652 | |
2670 | return PTR_ERR(s); | ||
2671 | while (!(err = link_path_walk(s, nd)) && | 2653 | while (!(err = link_path_walk(s, nd)) && |
2672 | (err = mountpoint_last(nd)) > 0) { | 2654 | (err = mountpoint_last(nd)) > 0) { |
2673 | s = trailing_symlink(nd); | 2655 | s = trailing_symlink(nd); |
2674 | if (IS_ERR(s)) { | ||
2675 | err = PTR_ERR(s); | ||
2676 | break; | ||
2677 | } | ||
2678 | } | 2656 | } |
2679 | if (!err) { | 2657 | if (!err) { |
2680 | *path = nd->path; | 2658 | *path = nd->path; |
@@ -3027,17 +3005,16 @@ static int may_o_create(const struct path *dir, struct dentry *dentry, umode_t m | |||
3027 | * Returns 0 if successful. The file will have been created and attached to | 3005 | * Returns 0 if successful. The file will have been created and attached to |
3028 | * @file by the filesystem calling finish_open(). | 3006 | * @file by the filesystem calling finish_open(). |
3029 | * | 3007 | * |
3030 | * Returns 1 if the file was looked up only or didn't need creating. The | 3008 | * If the file was looked up only or didn't need creating, FMODE_OPENED won't |
3031 | * caller will need to perform the open themselves. @path will have been | 3009 | * be set. The caller will need to perform the open themselves. @path will |
3032 | * updated to point to the new dentry. This may be negative. | 3010 | * have been updated to point to the new dentry. This may be negative. |
3033 | * | 3011 | * |
3034 | * Returns an error code otherwise. | 3012 | * Returns an error code otherwise. |
3035 | */ | 3013 | */ |
3036 | static int atomic_open(struct nameidata *nd, struct dentry *dentry, | 3014 | static int atomic_open(struct nameidata *nd, struct dentry *dentry, |
3037 | struct path *path, struct file *file, | 3015 | struct path *path, struct file *file, |
3038 | const struct open_flags *op, | 3016 | const struct open_flags *op, |
3039 | int open_flag, umode_t mode, | 3017 | int open_flag, umode_t mode) |
3040 | int *opened) | ||
3041 | { | 3018 | { |
3042 | struct dentry *const DENTRY_NOT_SET = (void *) -1UL; | 3019 | struct dentry *const DENTRY_NOT_SET = (void *) -1UL; |
3043 | struct inode *dir = nd->path.dentry->d_inode; | 3020 | struct inode *dir = nd->path.dentry->d_inode; |
@@ -3052,39 +3029,38 @@ static int atomic_open(struct nameidata *nd, struct dentry *dentry, | |||
3052 | file->f_path.dentry = DENTRY_NOT_SET; | 3029 | file->f_path.dentry = DENTRY_NOT_SET; |
3053 | file->f_path.mnt = nd->path.mnt; | 3030 | file->f_path.mnt = nd->path.mnt; |
3054 | error = dir->i_op->atomic_open(dir, dentry, file, | 3031 | error = dir->i_op->atomic_open(dir, dentry, file, |
3055 | open_to_namei_flags(open_flag), | 3032 | open_to_namei_flags(open_flag), mode); |
3056 | mode, opened); | ||
3057 | d_lookup_done(dentry); | 3033 | d_lookup_done(dentry); |
3058 | if (!error) { | 3034 | if (!error) { |
3059 | /* | 3035 | if (file->f_mode & FMODE_OPENED) { |
3060 | * We didn't have the inode before the open, so check open | 3036 | /* |
3061 | * permission here. | 3037 | * We didn't have the inode before the open, so check open |
3062 | */ | 3038 | * permission here. |
3063 | int acc_mode = op->acc_mode; | 3039 | */ |
3064 | if (*opened & FILE_CREATED) { | 3040 | int acc_mode = op->acc_mode; |
3065 | WARN_ON(!(open_flag & O_CREAT)); | 3041 | if (file->f_mode & FMODE_CREATED) { |
3066 | fsnotify_create(dir, dentry); | 3042 | WARN_ON(!(open_flag & O_CREAT)); |
3067 | acc_mode = 0; | 3043 | fsnotify_create(dir, dentry); |
3068 | } | 3044 | acc_mode = 0; |
3069 | error = may_open(&file->f_path, acc_mode, open_flag); | 3045 | } |
3070 | if (WARN_ON(error > 0)) | 3046 | error = may_open(&file->f_path, acc_mode, open_flag); |
3071 | error = -EINVAL; | 3047 | if (WARN_ON(error > 0)) |
3072 | } else if (error > 0) { | 3048 | error = -EINVAL; |
3073 | if (WARN_ON(file->f_path.dentry == DENTRY_NOT_SET)) { | 3049 | } else if (WARN_ON(file->f_path.dentry == DENTRY_NOT_SET)) { |
3074 | error = -EIO; | 3050 | error = -EIO; |
3075 | } else { | 3051 | } else { |
3076 | if (file->f_path.dentry) { | 3052 | if (file->f_path.dentry) { |
3077 | dput(dentry); | 3053 | dput(dentry); |
3078 | dentry = file->f_path.dentry; | 3054 | dentry = file->f_path.dentry; |
3079 | } | 3055 | } |
3080 | if (*opened & FILE_CREATED) | 3056 | if (file->f_mode & FMODE_CREATED) |
3081 | fsnotify_create(dir, dentry); | 3057 | fsnotify_create(dir, dentry); |
3082 | if (unlikely(d_is_negative(dentry))) { | 3058 | if (unlikely(d_is_negative(dentry))) { |
3083 | error = -ENOENT; | 3059 | error = -ENOENT; |
3084 | } else { | 3060 | } else { |
3085 | path->dentry = dentry; | 3061 | path->dentry = dentry; |
3086 | path->mnt = nd->path.mnt; | 3062 | path->mnt = nd->path.mnt; |
3087 | return 1; | 3063 | return 0; |
3088 | } | 3064 | } |
3089 | } | 3065 | } |
3090 | } | 3066 | } |
@@ -3095,25 +3071,22 @@ static int atomic_open(struct nameidata *nd, struct dentry *dentry, | |||
3095 | /* | 3071 | /* |
3096 | * Look up and maybe create and open the last component. | 3072 | * Look up and maybe create and open the last component. |
3097 | * | 3073 | * |
3098 | * Must be called with i_mutex held on parent. | 3074 | * Must be called with parent locked (exclusive in O_CREAT case). |
3099 | * | ||
3100 | * Returns 0 if the file was successfully atomically created (if necessary) and | ||
3101 | * opened. In this case the file will be returned attached to @file. | ||
3102 | * | 3075 | * |
3103 | * Returns 1 if the file was not completely opened at this time, though lookups | 3076 | * Returns 0 on success, that is, if |
3104 | * and creations will have been performed and the dentry returned in @path will | 3077 | * the file was successfully atomically created (if necessary) and opened, or |
3105 | * be positive upon return if O_CREAT was specified. If O_CREAT wasn't | 3078 | * the file was not completely opened at this time, though lookups and |
3106 | * specified then a negative dentry may be returned. | 3079 | * creations were performed. |
3080 | * These case are distinguished by presence of FMODE_OPENED on file->f_mode. | ||
3081 | * In the latter case dentry returned in @path might be negative if O_CREAT | ||
3082 | * hadn't been specified. | ||
3107 | * | 3083 | * |
3108 | * An error code is returned otherwise. | 3084 | * An error code is returned on failure. |
3109 | * | ||
3110 | * FILE_CREATE will be set in @*opened if the dentry was created and will be | ||
3111 | * cleared otherwise prior to returning. | ||
3112 | */ | 3085 | */ |
3113 | static int lookup_open(struct nameidata *nd, struct path *path, | 3086 | static int lookup_open(struct nameidata *nd, struct path *path, |
3114 | struct file *file, | 3087 | struct file *file, |
3115 | const struct open_flags *op, | 3088 | const struct open_flags *op, |
3116 | bool got_write, int *opened) | 3089 | bool got_write) |
3117 | { | 3090 | { |
3118 | struct dentry *dir = nd->path.dentry; | 3091 | struct dentry *dir = nd->path.dentry; |
3119 | struct inode *dir_inode = dir->d_inode; | 3092 | struct inode *dir_inode = dir->d_inode; |
@@ -3126,7 +3099,7 @@ static int lookup_open(struct nameidata *nd, struct path *path, | |||
3126 | if (unlikely(IS_DEADDIR(dir_inode))) | 3099 | if (unlikely(IS_DEADDIR(dir_inode))) |
3127 | return -ENOENT; | 3100 | return -ENOENT; |
3128 | 3101 | ||
3129 | *opened &= ~FILE_CREATED; | 3102 | file->f_mode &= ~FMODE_CREATED; |
3130 | dentry = d_lookup(dir, &nd->last); | 3103 | dentry = d_lookup(dir, &nd->last); |
3131 | for (;;) { | 3104 | for (;;) { |
3132 | if (!dentry) { | 3105 | if (!dentry) { |
@@ -3188,7 +3161,7 @@ static int lookup_open(struct nameidata *nd, struct path *path, | |||
3188 | 3161 | ||
3189 | if (dir_inode->i_op->atomic_open) { | 3162 | if (dir_inode->i_op->atomic_open) { |
3190 | error = atomic_open(nd, dentry, path, file, op, open_flag, | 3163 | error = atomic_open(nd, dentry, path, file, op, open_flag, |
3191 | mode, opened); | 3164 | mode); |
3192 | if (unlikely(error == -ENOENT) && create_error) | 3165 | if (unlikely(error == -ENOENT) && create_error) |
3193 | error = create_error; | 3166 | error = create_error; |
3194 | return error; | 3167 | return error; |
@@ -3211,7 +3184,7 @@ no_open: | |||
3211 | 3184 | ||
3212 | /* Negative dentry, just create the file */ | 3185 | /* Negative dentry, just create the file */ |
3213 | if (!dentry->d_inode && (open_flag & O_CREAT)) { | 3186 | if (!dentry->d_inode && (open_flag & O_CREAT)) { |
3214 | *opened |= FILE_CREATED; | 3187 | file->f_mode |= FMODE_CREATED; |
3215 | audit_inode_child(dir_inode, dentry, AUDIT_TYPE_CHILD_CREATE); | 3188 | audit_inode_child(dir_inode, dentry, AUDIT_TYPE_CHILD_CREATE); |
3216 | if (!dir_inode->i_op->create) { | 3189 | if (!dir_inode->i_op->create) { |
3217 | error = -EACCES; | 3190 | error = -EACCES; |
@@ -3230,7 +3203,7 @@ no_open: | |||
3230 | out_no_open: | 3203 | out_no_open: |
3231 | path->dentry = dentry; | 3204 | path->dentry = dentry; |
3232 | path->mnt = nd->path.mnt; | 3205 | path->mnt = nd->path.mnt; |
3233 | return 1; | 3206 | return 0; |
3234 | 3207 | ||
3235 | out_dput: | 3208 | out_dput: |
3236 | dput(dentry); | 3209 | dput(dentry); |
@@ -3241,8 +3214,7 @@ out_dput: | |||
3241 | * Handle the last step of open() | 3214 | * Handle the last step of open() |
3242 | */ | 3215 | */ |
3243 | static int do_last(struct nameidata *nd, | 3216 | static int do_last(struct nameidata *nd, |
3244 | struct file *file, const struct open_flags *op, | 3217 | struct file *file, const struct open_flags *op) |
3245 | int *opened) | ||
3246 | { | 3218 | { |
3247 | struct dentry *dir = nd->path.dentry; | 3219 | struct dentry *dir = nd->path.dentry; |
3248 | int open_flag = op->open_flag; | 3220 | int open_flag = op->open_flag; |
@@ -3308,17 +3280,17 @@ static int do_last(struct nameidata *nd, | |||
3308 | inode_lock(dir->d_inode); | 3280 | inode_lock(dir->d_inode); |
3309 | else | 3281 | else |
3310 | inode_lock_shared(dir->d_inode); | 3282 | inode_lock_shared(dir->d_inode); |
3311 | error = lookup_open(nd, &path, file, op, got_write, opened); | 3283 | error = lookup_open(nd, &path, file, op, got_write); |
3312 | if (open_flag & O_CREAT) | 3284 | if (open_flag & O_CREAT) |
3313 | inode_unlock(dir->d_inode); | 3285 | inode_unlock(dir->d_inode); |
3314 | else | 3286 | else |
3315 | inode_unlock_shared(dir->d_inode); | 3287 | inode_unlock_shared(dir->d_inode); |
3316 | 3288 | ||
3317 | if (error <= 0) { | 3289 | if (error) |
3318 | if (error) | 3290 | goto out; |
3319 | goto out; | ||
3320 | 3291 | ||
3321 | if ((*opened & FILE_CREATED) || | 3292 | if (file->f_mode & FMODE_OPENED) { |
3293 | if ((file->f_mode & FMODE_CREATED) || | ||
3322 | !S_ISREG(file_inode(file)->i_mode)) | 3294 | !S_ISREG(file_inode(file)->i_mode)) |
3323 | will_truncate = false; | 3295 | will_truncate = false; |
3324 | 3296 | ||
@@ -3326,7 +3298,7 @@ static int do_last(struct nameidata *nd, | |||
3326 | goto opened; | 3298 | goto opened; |
3327 | } | 3299 | } |
3328 | 3300 | ||
3329 | if (*opened & FILE_CREATED) { | 3301 | if (file->f_mode & FMODE_CREATED) { |
3330 | /* Don't check for write permission, don't truncate */ | 3302 | /* Don't check for write permission, don't truncate */ |
3331 | open_flag &= ~O_TRUNC; | 3303 | open_flag &= ~O_TRUNC; |
3332 | will_truncate = false; | 3304 | will_truncate = false; |
@@ -3395,20 +3367,15 @@ finish_open_created: | |||
3395 | error = may_open(&nd->path, acc_mode, open_flag); | 3367 | error = may_open(&nd->path, acc_mode, open_flag); |
3396 | if (error) | 3368 | if (error) |
3397 | goto out; | 3369 | goto out; |
3398 | BUG_ON(*opened & FILE_OPENED); /* once it's opened, it's opened */ | 3370 | BUG_ON(file->f_mode & FMODE_OPENED); /* once it's opened, it's opened */ |
3399 | error = vfs_open(&nd->path, file, current_cred()); | 3371 | error = vfs_open(&nd->path, file); |
3400 | if (error) | 3372 | if (error) |
3401 | goto out; | 3373 | goto out; |
3402 | *opened |= FILE_OPENED; | ||
3403 | opened: | 3374 | opened: |
3404 | error = open_check_o_direct(file); | 3375 | error = ima_file_check(file, op->acc_mode); |
3405 | if (!error) | ||
3406 | error = ima_file_check(file, op->acc_mode, *opened); | ||
3407 | if (!error && will_truncate) | 3376 | if (!error && will_truncate) |
3408 | error = handle_truncate(file); | 3377 | error = handle_truncate(file); |
3409 | out: | 3378 | out: |
3410 | if (unlikely(error) && (*opened & FILE_OPENED)) | ||
3411 | fput(file); | ||
3412 | if (unlikely(error > 0)) { | 3379 | if (unlikely(error > 0)) { |
3413 | WARN_ON(1); | 3380 | WARN_ON(1); |
3414 | error = -EINVAL; | 3381 | error = -EINVAL; |
@@ -3458,7 +3425,7 @@ EXPORT_SYMBOL(vfs_tmpfile); | |||
3458 | 3425 | ||
3459 | static int do_tmpfile(struct nameidata *nd, unsigned flags, | 3426 | static int do_tmpfile(struct nameidata *nd, unsigned flags, |
3460 | const struct open_flags *op, | 3427 | const struct open_flags *op, |
3461 | struct file *file, int *opened) | 3428 | struct file *file) |
3462 | { | 3429 | { |
3463 | struct dentry *child; | 3430 | struct dentry *child; |
3464 | struct path path; | 3431 | struct path path; |
@@ -3480,12 +3447,7 @@ static int do_tmpfile(struct nameidata *nd, unsigned flags, | |||
3480 | if (error) | 3447 | if (error) |
3481 | goto out2; | 3448 | goto out2; |
3482 | file->f_path.mnt = path.mnt; | 3449 | file->f_path.mnt = path.mnt; |
3483 | error = finish_open(file, child, NULL, opened); | 3450 | error = finish_open(file, child, NULL); |
3484 | if (error) | ||
3485 | goto out2; | ||
3486 | error = open_check_o_direct(file); | ||
3487 | if (error) | ||
3488 | fput(file); | ||
3489 | out2: | 3451 | out2: |
3490 | mnt_drop_write(path.mnt); | 3452 | mnt_drop_write(path.mnt); |
3491 | out: | 3453 | out: |
@@ -3499,7 +3461,7 @@ static int do_o_path(struct nameidata *nd, unsigned flags, struct file *file) | |||
3499 | int error = path_lookupat(nd, flags, &path); | 3461 | int error = path_lookupat(nd, flags, &path); |
3500 | if (!error) { | 3462 | if (!error) { |
3501 | audit_inode(nd->name, path.dentry, 0); | 3463 | audit_inode(nd->name, path.dentry, 0); |
3502 | error = vfs_open(&path, file, current_cred()); | 3464 | error = vfs_open(&path, file); |
3503 | path_put(&path); | 3465 | path_put(&path); |
3504 | } | 3466 | } |
3505 | return error; | 3467 | return error; |
@@ -3508,59 +3470,40 @@ static int do_o_path(struct nameidata *nd, unsigned flags, struct file *file) | |||
3508 | static struct file *path_openat(struct nameidata *nd, | 3470 | static struct file *path_openat(struct nameidata *nd, |
3509 | const struct open_flags *op, unsigned flags) | 3471 | const struct open_flags *op, unsigned flags) |
3510 | { | 3472 | { |
3511 | const char *s; | ||
3512 | struct file *file; | 3473 | struct file *file; |
3513 | int opened = 0; | ||
3514 | int error; | 3474 | int error; |
3515 | 3475 | ||
3516 | file = get_empty_filp(); | 3476 | file = alloc_empty_file(op->open_flag, current_cred()); |
3517 | if (IS_ERR(file)) | 3477 | if (IS_ERR(file)) |
3518 | return file; | 3478 | return file; |
3519 | 3479 | ||
3520 | file->f_flags = op->open_flag; | ||
3521 | |||
3522 | if (unlikely(file->f_flags & __O_TMPFILE)) { | 3480 | if (unlikely(file->f_flags & __O_TMPFILE)) { |
3523 | error = do_tmpfile(nd, flags, op, file, &opened); | 3481 | error = do_tmpfile(nd, flags, op, file); |
3524 | goto out2; | 3482 | } else if (unlikely(file->f_flags & O_PATH)) { |
3525 | } | ||
3526 | |||
3527 | if (unlikely(file->f_flags & O_PATH)) { | ||
3528 | error = do_o_path(nd, flags, file); | 3483 | error = do_o_path(nd, flags, file); |
3529 | if (!error) | 3484 | } else { |
3530 | opened |= FILE_OPENED; | 3485 | const char *s = path_init(nd, flags); |
3531 | goto out2; | 3486 | while (!(error = link_path_walk(s, nd)) && |
3532 | } | 3487 | (error = do_last(nd, file, op)) > 0) { |
3533 | 3488 | nd->flags &= ~(LOOKUP_OPEN|LOOKUP_CREATE|LOOKUP_EXCL); | |
3534 | s = path_init(nd, flags); | 3489 | s = trailing_symlink(nd); |
3535 | if (IS_ERR(s)) { | ||
3536 | put_filp(file); | ||
3537 | return ERR_CAST(s); | ||
3538 | } | ||
3539 | while (!(error = link_path_walk(s, nd)) && | ||
3540 | (error = do_last(nd, file, op, &opened)) > 0) { | ||
3541 | nd->flags &= ~(LOOKUP_OPEN|LOOKUP_CREATE|LOOKUP_EXCL); | ||
3542 | s = trailing_symlink(nd); | ||
3543 | if (IS_ERR(s)) { | ||
3544 | error = PTR_ERR(s); | ||
3545 | break; | ||
3546 | } | 3490 | } |
3491 | terminate_walk(nd); | ||
3547 | } | 3492 | } |
3548 | terminate_walk(nd); | 3493 | if (likely(!error)) { |
3549 | out2: | 3494 | if (likely(file->f_mode & FMODE_OPENED)) |
3550 | if (!(opened & FILE_OPENED)) { | 3495 | return file; |
3551 | BUG_ON(!error); | 3496 | WARN_ON(1); |
3552 | put_filp(file); | 3497 | error = -EINVAL; |
3553 | } | 3498 | } |
3554 | if (unlikely(error)) { | 3499 | fput(file); |
3555 | if (error == -EOPENSTALE) { | 3500 | if (error == -EOPENSTALE) { |
3556 | if (flags & LOOKUP_RCU) | 3501 | if (flags & LOOKUP_RCU) |
3557 | error = -ECHILD; | 3502 | error = -ECHILD; |
3558 | else | 3503 | else |
3559 | error = -ESTALE; | 3504 | error = -ESTALE; |
3560 | } | ||
3561 | file = ERR_PTR(error); | ||
3562 | } | 3505 | } |
3563 | return file; | 3506 | return ERR_PTR(error); |
3564 | } | 3507 | } |
3565 | 3508 | ||
3566 | struct file *do_filp_open(int dfd, struct filename *pathname, | 3509 | struct file *do_filp_open(int dfd, struct filename *pathname, |
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c index 7a9c14426855..f447b1a24350 100644 --- a/fs/nfs/dir.c +++ b/fs/nfs/dir.c | |||
@@ -1434,12 +1434,11 @@ static int do_open(struct inode *inode, struct file *filp) | |||
1434 | 1434 | ||
1435 | static int nfs_finish_open(struct nfs_open_context *ctx, | 1435 | static int nfs_finish_open(struct nfs_open_context *ctx, |
1436 | struct dentry *dentry, | 1436 | struct dentry *dentry, |
1437 | struct file *file, unsigned open_flags, | 1437 | struct file *file, unsigned open_flags) |
1438 | int *opened) | ||
1439 | { | 1438 | { |
1440 | int err; | 1439 | int err; |
1441 | 1440 | ||
1442 | err = finish_open(file, dentry, do_open, opened); | 1441 | err = finish_open(file, dentry, do_open); |
1443 | if (err) | 1442 | if (err) |
1444 | goto out; | 1443 | goto out; |
1445 | if (S_ISREG(file->f_path.dentry->d_inode->i_mode)) | 1444 | if (S_ISREG(file->f_path.dentry->d_inode->i_mode)) |
@@ -1452,7 +1451,7 @@ out: | |||
1452 | 1451 | ||
1453 | int nfs_atomic_open(struct inode *dir, struct dentry *dentry, | 1452 | int nfs_atomic_open(struct inode *dir, struct dentry *dentry, |
1454 | struct file *file, unsigned open_flags, | 1453 | struct file *file, unsigned open_flags, |
1455 | umode_t mode, int *opened) | 1454 | umode_t mode) |
1456 | { | 1455 | { |
1457 | DECLARE_WAIT_QUEUE_HEAD_ONSTACK(wq); | 1456 | DECLARE_WAIT_QUEUE_HEAD_ONSTACK(wq); |
1458 | struct nfs_open_context *ctx; | 1457 | struct nfs_open_context *ctx; |
@@ -1461,6 +1460,7 @@ int nfs_atomic_open(struct inode *dir, struct dentry *dentry, | |||
1461 | struct inode *inode; | 1460 | struct inode *inode; |
1462 | unsigned int lookup_flags = 0; | 1461 | unsigned int lookup_flags = 0; |
1463 | bool switched = false; | 1462 | bool switched = false; |
1463 | int created = 0; | ||
1464 | int err; | 1464 | int err; |
1465 | 1465 | ||
1466 | /* Expect a negative dentry */ | 1466 | /* Expect a negative dentry */ |
@@ -1521,7 +1521,9 @@ int nfs_atomic_open(struct inode *dir, struct dentry *dentry, | |||
1521 | goto out; | 1521 | goto out; |
1522 | 1522 | ||
1523 | trace_nfs_atomic_open_enter(dir, ctx, open_flags); | 1523 | trace_nfs_atomic_open_enter(dir, ctx, open_flags); |
1524 | inode = NFS_PROTO(dir)->open_context(dir, ctx, open_flags, &attr, opened); | 1524 | inode = NFS_PROTO(dir)->open_context(dir, ctx, open_flags, &attr, &created); |
1525 | if (created) | ||
1526 | file->f_mode |= FMODE_CREATED; | ||
1525 | if (IS_ERR(inode)) { | 1527 | if (IS_ERR(inode)) { |
1526 | err = PTR_ERR(inode); | 1528 | err = PTR_ERR(inode); |
1527 | trace_nfs_atomic_open_exit(dir, ctx, open_flags, err); | 1529 | trace_nfs_atomic_open_exit(dir, ctx, open_flags, err); |
@@ -1546,7 +1548,7 @@ int nfs_atomic_open(struct inode *dir, struct dentry *dentry, | |||
1546 | goto out; | 1548 | goto out; |
1547 | } | 1549 | } |
1548 | 1550 | ||
1549 | err = nfs_finish_open(ctx, ctx->dentry, file, open_flags, opened); | 1551 | err = nfs_finish_open(ctx, ctx->dentry, file, open_flags); |
1550 | trace_nfs_atomic_open_exit(dir, ctx, open_flags, err); | 1552 | trace_nfs_atomic_open_exit(dir, ctx, open_flags, err); |
1551 | put_nfs_open_context(ctx); | 1553 | put_nfs_open_context(ctx); |
1552 | out: | 1554 | out: |
diff --git a/fs/nfs/nfs4_fs.h b/fs/nfs/nfs4_fs.h index 137e18abb7e7..51beb6e38c90 100644 --- a/fs/nfs/nfs4_fs.h +++ b/fs/nfs/nfs4_fs.h | |||
@@ -258,7 +258,7 @@ extern const struct dentry_operations nfs4_dentry_operations; | |||
258 | 258 | ||
259 | /* dir.c */ | 259 | /* dir.c */ |
260 | int nfs_atomic_open(struct inode *, struct dentry *, struct file *, | 260 | int nfs_atomic_open(struct inode *, struct dentry *, struct file *, |
261 | unsigned, umode_t, int *); | 261 | unsigned, umode_t); |
262 | 262 | ||
263 | /* super.c */ | 263 | /* super.c */ |
264 | extern struct file_system_type nfs4_fs_type; | 264 | extern struct file_system_type nfs4_fs_type; |
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index f6c4ccd693f4..b790976d3913 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c | |||
@@ -2951,7 +2951,7 @@ static int _nfs4_do_open(struct inode *dir, | |||
2951 | } | 2951 | } |
2952 | } | 2952 | } |
2953 | if (opened && opendata->file_created) | 2953 | if (opened && opendata->file_created) |
2954 | *opened |= FILE_CREATED; | 2954 | *opened = 1; |
2955 | 2955 | ||
2956 | if (pnfs_use_threshold(ctx_th, opendata->f_attr.mdsthreshold, server)) { | 2956 | if (pnfs_use_threshold(ctx_th, opendata->f_attr.mdsthreshold, server)) { |
2957 | *ctx_th = opendata->f_attr.mdsthreshold; | 2957 | *ctx_th = opendata->f_attr.mdsthreshold; |
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c index b0555d7d8200..55a099e47ba2 100644 --- a/fs/nfsd/vfs.c +++ b/fs/nfsd/vfs.c | |||
@@ -763,7 +763,7 @@ nfsd_open(struct svc_rqst *rqstp, struct svc_fh *fhp, umode_t type, | |||
763 | goto out_nfserr; | 763 | goto out_nfserr; |
764 | } | 764 | } |
765 | 765 | ||
766 | host_err = ima_file_check(file, may_flags, 0); | 766 | host_err = ima_file_check(file, may_flags); |
767 | if (host_err) { | 767 | if (host_err) { |
768 | fput(file); | 768 | fput(file); |
769 | goto out_nfserr; | 769 | goto out_nfserr; |
@@ -724,27 +724,13 @@ SYSCALL_DEFINE3(fchown, unsigned int, fd, uid_t, user, gid_t, group) | |||
724 | return ksys_fchown(fd, user, group); | 724 | return ksys_fchown(fd, user, group); |
725 | } | 725 | } |
726 | 726 | ||
727 | int open_check_o_direct(struct file *f) | ||
728 | { | ||
729 | /* NB: we're sure to have correct a_ops only after f_op->open */ | ||
730 | if (f->f_flags & O_DIRECT) { | ||
731 | if (!f->f_mapping->a_ops || !f->f_mapping->a_ops->direct_IO) | ||
732 | return -EINVAL; | ||
733 | } | ||
734 | return 0; | ||
735 | } | ||
736 | |||
737 | static int do_dentry_open(struct file *f, | 727 | static int do_dentry_open(struct file *f, |
738 | struct inode *inode, | 728 | struct inode *inode, |
739 | int (*open)(struct inode *, struct file *), | 729 | int (*open)(struct inode *, struct file *)) |
740 | const struct cred *cred) | ||
741 | { | 730 | { |
742 | static const struct file_operations empty_fops = {}; | 731 | static const struct file_operations empty_fops = {}; |
743 | int error; | 732 | int error; |
744 | 733 | ||
745 | f->f_mode = OPEN_FMODE(f->f_flags) | FMODE_LSEEK | | ||
746 | FMODE_PREAD | FMODE_PWRITE; | ||
747 | |||
748 | path_get(&f->f_path); | 734 | path_get(&f->f_path); |
749 | f->f_inode = inode; | 735 | f->f_inode = inode; |
750 | f->f_mapping = inode->i_mapping; | 736 | f->f_mapping = inode->i_mapping; |
@@ -753,7 +739,7 @@ static int do_dentry_open(struct file *f, | |||
753 | f->f_wb_err = filemap_sample_wb_err(f->f_mapping); | 739 | f->f_wb_err = filemap_sample_wb_err(f->f_mapping); |
754 | 740 | ||
755 | if (unlikely(f->f_flags & O_PATH)) { | 741 | if (unlikely(f->f_flags & O_PATH)) { |
756 | f->f_mode = FMODE_PATH; | 742 | f->f_mode = FMODE_PATH | FMODE_OPENED; |
757 | f->f_op = &empty_fops; | 743 | f->f_op = &empty_fops; |
758 | return 0; | 744 | return 0; |
759 | } | 745 | } |
@@ -780,7 +766,7 @@ static int do_dentry_open(struct file *f, | |||
780 | goto cleanup_all; | 766 | goto cleanup_all; |
781 | } | 767 | } |
782 | 768 | ||
783 | error = security_file_open(f, cred); | 769 | error = security_file_open(f); |
784 | if (error) | 770 | if (error) |
785 | goto cleanup_all; | 771 | goto cleanup_all; |
786 | 772 | ||
@@ -788,6 +774,8 @@ static int do_dentry_open(struct file *f, | |||
788 | if (error) | 774 | if (error) |
789 | goto cleanup_all; | 775 | goto cleanup_all; |
790 | 776 | ||
777 | /* normally all 3 are set; ->open() can clear them if needed */ | ||
778 | f->f_mode |= FMODE_LSEEK | FMODE_PREAD | FMODE_PWRITE; | ||
791 | if (!open) | 779 | if (!open) |
792 | open = f->f_op->open; | 780 | open = f->f_op->open; |
793 | if (open) { | 781 | if (open) { |
@@ -795,6 +783,7 @@ static int do_dentry_open(struct file *f, | |||
795 | if (error) | 783 | if (error) |
796 | goto cleanup_all; | 784 | goto cleanup_all; |
797 | } | 785 | } |
786 | f->f_mode |= FMODE_OPENED; | ||
798 | if ((f->f_mode & (FMODE_READ | FMODE_WRITE)) == FMODE_READ) | 787 | if ((f->f_mode & (FMODE_READ | FMODE_WRITE)) == FMODE_READ) |
799 | i_readcount_inc(inode); | 788 | i_readcount_inc(inode); |
800 | if ((f->f_mode & FMODE_READ) && | 789 | if ((f->f_mode & FMODE_READ) && |
@@ -809,9 +798,16 @@ static int do_dentry_open(struct file *f, | |||
809 | 798 | ||
810 | file_ra_state_init(&f->f_ra, f->f_mapping->host->i_mapping); | 799 | file_ra_state_init(&f->f_ra, f->f_mapping->host->i_mapping); |
811 | 800 | ||
801 | /* NB: we're sure to have correct a_ops only after f_op->open */ | ||
802 | if (f->f_flags & O_DIRECT) { | ||
803 | if (!f->f_mapping->a_ops || !f->f_mapping->a_ops->direct_IO) | ||
804 | return -EINVAL; | ||
805 | } | ||
812 | return 0; | 806 | return 0; |
813 | 807 | ||
814 | cleanup_all: | 808 | cleanup_all: |
809 | if (WARN_ON_ONCE(error > 0)) | ||
810 | error = -EINVAL; | ||
815 | fops_put(f->f_op); | 811 | fops_put(f->f_op); |
816 | if (f->f_mode & FMODE_WRITER) { | 812 | if (f->f_mode & FMODE_WRITER) { |
817 | put_write_access(inode); | 813 | put_write_access(inode); |
@@ -847,19 +843,12 @@ cleanup_file: | |||
847 | * Returns zero on success or -errno if the open failed. | 843 | * Returns zero on success or -errno if the open failed. |
848 | */ | 844 | */ |
849 | int finish_open(struct file *file, struct dentry *dentry, | 845 | int finish_open(struct file *file, struct dentry *dentry, |
850 | int (*open)(struct inode *, struct file *), | 846 | int (*open)(struct inode *, struct file *)) |
851 | int *opened) | ||
852 | { | 847 | { |
853 | int error; | 848 | BUG_ON(file->f_mode & FMODE_OPENED); /* once it's opened, it's opened */ |
854 | BUG_ON(*opened & FILE_OPENED); /* once it's opened, it's opened */ | ||
855 | 849 | ||
856 | file->f_path.dentry = dentry; | 850 | file->f_path.dentry = dentry; |
857 | error = do_dentry_open(file, d_backing_inode(dentry), open, | 851 | return do_dentry_open(file, d_backing_inode(dentry), open); |
858 | current_cred()); | ||
859 | if (!error) | ||
860 | *opened |= FILE_OPENED; | ||
861 | |||
862 | return error; | ||
863 | } | 852 | } |
864 | EXPORT_SYMBOL(finish_open); | 853 | EXPORT_SYMBOL(finish_open); |
865 | 854 | ||
@@ -874,13 +863,13 @@ EXPORT_SYMBOL(finish_open); | |||
874 | * NB: unlike finish_open() this function does consume the dentry reference and | 863 | * NB: unlike finish_open() this function does consume the dentry reference and |
875 | * the caller need not dput() it. | 864 | * the caller need not dput() it. |
876 | * | 865 | * |
877 | * Returns "1" which must be the return value of ->atomic_open() after having | 866 | * Returns "0" which must be the return value of ->atomic_open() after having |
878 | * called this function. | 867 | * called this function. |
879 | */ | 868 | */ |
880 | int finish_no_open(struct file *file, struct dentry *dentry) | 869 | int finish_no_open(struct file *file, struct dentry *dentry) |
881 | { | 870 | { |
882 | file->f_path.dentry = dentry; | 871 | file->f_path.dentry = dentry; |
883 | return 1; | 872 | return 0; |
884 | } | 873 | } |
885 | EXPORT_SYMBOL(finish_no_open); | 874 | EXPORT_SYMBOL(finish_no_open); |
886 | 875 | ||
@@ -896,8 +885,7 @@ EXPORT_SYMBOL(file_path); | |||
896 | * @file: newly allocated file with f_flag initialized | 885 | * @file: newly allocated file with f_flag initialized |
897 | * @cred: credentials to use | 886 | * @cred: credentials to use |
898 | */ | 887 | */ |
899 | int vfs_open(const struct path *path, struct file *file, | 888 | int vfs_open(const struct path *path, struct file *file) |
900 | const struct cred *cred) | ||
901 | { | 889 | { |
902 | struct dentry *dentry = d_real(path->dentry, NULL, file->f_flags, 0); | 890 | struct dentry *dentry = d_real(path->dentry, NULL, file->f_flags, 0); |
903 | 891 | ||
@@ -905,7 +893,7 @@ int vfs_open(const struct path *path, struct file *file, | |||
905 | return PTR_ERR(dentry); | 893 | return PTR_ERR(dentry); |
906 | 894 | ||
907 | file->f_path = *path; | 895 | file->f_path = *path; |
908 | return do_dentry_open(file, d_backing_inode(dentry), NULL, cred); | 896 | return do_dentry_open(file, d_backing_inode(dentry), NULL); |
909 | } | 897 | } |
910 | 898 | ||
911 | struct file *dentry_open(const struct path *path, int flags, | 899 | struct file *dentry_open(const struct path *path, int flags, |
@@ -919,19 +907,11 @@ struct file *dentry_open(const struct path *path, int flags, | |||
919 | /* We must always pass in a valid mount pointer. */ | 907 | /* We must always pass in a valid mount pointer. */ |
920 | BUG_ON(!path->mnt); | 908 | BUG_ON(!path->mnt); |
921 | 909 | ||
922 | f = get_empty_filp(); | 910 | f = alloc_empty_file(flags, cred); |
923 | if (!IS_ERR(f)) { | 911 | if (!IS_ERR(f)) { |
924 | f->f_flags = flags; | 912 | error = vfs_open(path, f); |
925 | error = vfs_open(path, f, cred); | 913 | if (error) { |
926 | if (!error) { | 914 | fput(f); |
927 | /* from now on we need fput() to dispose of f */ | ||
928 | error = open_check_o_direct(f); | ||
929 | if (error) { | ||
930 | fput(f); | ||
931 | f = ERR_PTR(error); | ||
932 | } | ||
933 | } else { | ||
934 | put_filp(f); | ||
935 | f = ERR_PTR(error); | 915 | f = ERR_PTR(error); |
936 | } | 916 | } |
937 | } | 917 | } |
@@ -1063,26 +1043,6 @@ struct file *file_open_root(struct dentry *dentry, struct vfsmount *mnt, | |||
1063 | } | 1043 | } |
1064 | EXPORT_SYMBOL(file_open_root); | 1044 | EXPORT_SYMBOL(file_open_root); |
1065 | 1045 | ||
1066 | struct file *filp_clone_open(struct file *oldfile) | ||
1067 | { | ||
1068 | struct file *file; | ||
1069 | int retval; | ||
1070 | |||
1071 | file = get_empty_filp(); | ||
1072 | if (IS_ERR(file)) | ||
1073 | return file; | ||
1074 | |||
1075 | file->f_flags = oldfile->f_flags; | ||
1076 | retval = vfs_open(&oldfile->f_path, file, oldfile->f_cred); | ||
1077 | if (retval) { | ||
1078 | put_filp(file); | ||
1079 | return ERR_PTR(retval); | ||
1080 | } | ||
1081 | |||
1082 | return file; | ||
1083 | } | ||
1084 | EXPORT_SYMBOL(filp_clone_open); | ||
1085 | |||
1086 | long do_sys_open(int dfd, const char __user *filename, int flags, umode_t mode) | 1046 | long do_sys_open(int dfd, const char __user *filename, int flags, umode_t mode) |
1087 | { | 1047 | { |
1088 | struct open_flags op; | 1048 | struct open_flags op; |
@@ -741,54 +741,33 @@ fail_inode: | |||
741 | 741 | ||
742 | int create_pipe_files(struct file **res, int flags) | 742 | int create_pipe_files(struct file **res, int flags) |
743 | { | 743 | { |
744 | int err; | ||
745 | struct inode *inode = get_pipe_inode(); | 744 | struct inode *inode = get_pipe_inode(); |
746 | struct file *f; | 745 | struct file *f; |
747 | struct path path; | ||
748 | 746 | ||
749 | if (!inode) | 747 | if (!inode) |
750 | return -ENFILE; | 748 | return -ENFILE; |
751 | 749 | ||
752 | err = -ENOMEM; | 750 | f = alloc_file_pseudo(inode, pipe_mnt, "", |
753 | path.dentry = d_alloc_pseudo(pipe_mnt->mnt_sb, &empty_name); | 751 | O_WRONLY | (flags & (O_NONBLOCK | O_DIRECT)), |
754 | if (!path.dentry) | 752 | &pipefifo_fops); |
755 | goto err_inode; | ||
756 | path.mnt = mntget(pipe_mnt); | ||
757 | |||
758 | d_instantiate(path.dentry, inode); | ||
759 | |||
760 | f = alloc_file(&path, FMODE_WRITE, &pipefifo_fops); | ||
761 | if (IS_ERR(f)) { | 753 | if (IS_ERR(f)) { |
762 | err = PTR_ERR(f); | 754 | free_pipe_info(inode->i_pipe); |
763 | goto err_dentry; | 755 | iput(inode); |
756 | return PTR_ERR(f); | ||
764 | } | 757 | } |
765 | 758 | ||
766 | f->f_flags = O_WRONLY | (flags & (O_NONBLOCK | O_DIRECT)); | ||
767 | f->private_data = inode->i_pipe; | 759 | f->private_data = inode->i_pipe; |
768 | 760 | ||
769 | res[0] = alloc_file(&path, FMODE_READ, &pipefifo_fops); | 761 | res[0] = alloc_file_clone(f, O_RDONLY | (flags & O_NONBLOCK), |
762 | &pipefifo_fops); | ||
770 | if (IS_ERR(res[0])) { | 763 | if (IS_ERR(res[0])) { |
771 | err = PTR_ERR(res[0]); | 764 | put_pipe_info(inode, inode->i_pipe); |
772 | goto err_file; | 765 | fput(f); |
766 | return PTR_ERR(res[0]); | ||
773 | } | 767 | } |
774 | |||
775 | path_get(&path); | ||
776 | res[0]->private_data = inode->i_pipe; | 768 | res[0]->private_data = inode->i_pipe; |
777 | res[0]->f_flags = O_RDONLY | (flags & O_NONBLOCK); | ||
778 | res[1] = f; | 769 | res[1] = f; |
779 | return 0; | 770 | return 0; |
780 | |||
781 | err_file: | ||
782 | put_filp(f); | ||
783 | err_dentry: | ||
784 | free_pipe_info(inode->i_pipe); | ||
785 | path_put(&path); | ||
786 | return err; | ||
787 | |||
788 | err_inode: | ||
789 | free_pipe_info(inode->i_pipe); | ||
790 | iput(inode); | ||
791 | return err; | ||
792 | } | 771 | } |
793 | 772 | ||
794 | static int __do_pipe_flags(int *fd, struct file **files, int flags) | 773 | static int __do_pipe_flags(int *fd, struct file **files, int flags) |
diff --git a/include/linux/file.h b/include/linux/file.h index 279720db984a..6b2fb032416c 100644 --- a/include/linux/file.h +++ b/include/linux/file.h | |||
@@ -17,9 +17,12 @@ extern void fput(struct file *); | |||
17 | struct file_operations; | 17 | struct file_operations; |
18 | struct vfsmount; | 18 | struct vfsmount; |
19 | struct dentry; | 19 | struct dentry; |
20 | struct inode; | ||
20 | struct path; | 21 | struct path; |
21 | extern struct file *alloc_file(const struct path *, fmode_t mode, | 22 | extern struct file *alloc_file_pseudo(struct inode *, struct vfsmount *, |
22 | const struct file_operations *fop); | 23 | const char *, int flags, const struct file_operations *); |
24 | extern struct file *alloc_file_clone(struct file *, int flags, | ||
25 | const struct file_operations *); | ||
23 | 26 | ||
24 | static inline void fput_light(struct file *file, int fput_needed) | 27 | static inline void fput_light(struct file *file, int fput_needed) |
25 | { | 28 | { |
@@ -78,7 +81,6 @@ extern int f_dupfd(unsigned int from, struct file *file, unsigned flags); | |||
78 | extern int replace_fd(unsigned fd, struct file *file, unsigned flags); | 81 | extern int replace_fd(unsigned fd, struct file *file, unsigned flags); |
79 | extern void set_close_on_exec(unsigned int fd, int flag); | 82 | extern void set_close_on_exec(unsigned int fd, int flag); |
80 | extern bool get_close_on_exec(unsigned int fd); | 83 | extern bool get_close_on_exec(unsigned int fd); |
81 | extern void put_filp(struct file *); | ||
82 | extern int get_unused_fd_flags(unsigned flags); | 84 | extern int get_unused_fd_flags(unsigned flags); |
83 | extern void put_unused_fd(unsigned int fd); | 85 | extern void put_unused_fd(unsigned int fd); |
84 | 86 | ||
diff --git a/include/linux/fs.h b/include/linux/fs.h index 805bf22898cf..7899737a9a3e 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h | |||
@@ -148,6 +148,9 @@ typedef int (dio_iodone_t)(struct kiocb *iocb, loff_t offset, | |||
148 | /* Has write method(s) */ | 148 | /* Has write method(s) */ |
149 | #define FMODE_CAN_WRITE ((__force fmode_t)0x40000) | 149 | #define FMODE_CAN_WRITE ((__force fmode_t)0x40000) |
150 | 150 | ||
151 | #define FMODE_OPENED ((__force fmode_t)0x80000) | ||
152 | #define FMODE_CREATED ((__force fmode_t)0x100000) | ||
153 | |||
151 | /* File was opened by fanotify and shouldn't generate fanotify events */ | 154 | /* File was opened by fanotify and shouldn't generate fanotify events */ |
152 | #define FMODE_NONOTIFY ((__force fmode_t)0x4000000) | 155 | #define FMODE_NONOTIFY ((__force fmode_t)0x4000000) |
153 | 156 | ||
@@ -1776,7 +1779,7 @@ struct inode_operations { | |||
1776 | int (*update_time)(struct inode *, struct timespec64 *, int); | 1779 | int (*update_time)(struct inode *, struct timespec64 *, int); |
1777 | int (*atomic_open)(struct inode *, struct dentry *, | 1780 | int (*atomic_open)(struct inode *, struct dentry *, |
1778 | struct file *, unsigned open_flag, | 1781 | struct file *, unsigned open_flag, |
1779 | umode_t create_mode, int *opened); | 1782 | umode_t create_mode); |
1780 | int (*tmpfile) (struct inode *, struct dentry *, umode_t); | 1783 | int (*tmpfile) (struct inode *, struct dentry *, umode_t); |
1781 | int (*set_acl)(struct inode *, struct posix_acl *, int); | 1784 | int (*set_acl)(struct inode *, struct posix_acl *, int); |
1782 | } ____cacheline_aligned; | 1785 | } ____cacheline_aligned; |
@@ -2420,7 +2423,10 @@ extern struct file *filp_open(const char *, int, umode_t); | |||
2420 | extern struct file *file_open_root(struct dentry *, struct vfsmount *, | 2423 | extern struct file *file_open_root(struct dentry *, struct vfsmount *, |
2421 | const char *, int, umode_t); | 2424 | const char *, int, umode_t); |
2422 | extern struct file * dentry_open(const struct path *, int, const struct cred *); | 2425 | extern struct file * dentry_open(const struct path *, int, const struct cred *); |
2423 | extern struct file *filp_clone_open(struct file *); | 2426 | static inline struct file *file_clone_open(struct file *file) |
2427 | { | ||
2428 | return dentry_open(&file->f_path, file->f_flags, file->f_cred); | ||
2429 | } | ||
2424 | extern int filp_close(struct file *, fl_owner_t id); | 2430 | extern int filp_close(struct file *, fl_owner_t id); |
2425 | 2431 | ||
2426 | extern struct filename *getname_flags(const char __user *, int, int *); | 2432 | extern struct filename *getname_flags(const char __user *, int, int *); |
@@ -2428,13 +2434,8 @@ extern struct filename *getname(const char __user *); | |||
2428 | extern struct filename *getname_kernel(const char *); | 2434 | extern struct filename *getname_kernel(const char *); |
2429 | extern void putname(struct filename *name); | 2435 | extern void putname(struct filename *name); |
2430 | 2436 | ||
2431 | enum { | ||
2432 | FILE_CREATED = 1, | ||
2433 | FILE_OPENED = 2 | ||
2434 | }; | ||
2435 | extern int finish_open(struct file *file, struct dentry *dentry, | 2437 | extern int finish_open(struct file *file, struct dentry *dentry, |
2436 | int (*open)(struct inode *, struct file *), | 2438 | int (*open)(struct inode *, struct file *)); |
2437 | int *opened); | ||
2438 | extern int finish_no_open(struct file *file, struct dentry *dentry); | 2439 | extern int finish_no_open(struct file *file, struct dentry *dentry); |
2439 | 2440 | ||
2440 | /* fs/ioctl.c */ | 2441 | /* fs/ioctl.c */ |
diff --git a/include/linux/ima.h b/include/linux/ima.h index 0e4647e0eb60..d9ba3fc363b7 100644 --- a/include/linux/ima.h +++ b/include/linux/ima.h | |||
@@ -16,7 +16,7 @@ struct linux_binprm; | |||
16 | 16 | ||
17 | #ifdef CONFIG_IMA | 17 | #ifdef CONFIG_IMA |
18 | extern int ima_bprm_check(struct linux_binprm *bprm); | 18 | extern int ima_bprm_check(struct linux_binprm *bprm); |
19 | extern int ima_file_check(struct file *file, int mask, int opened); | 19 | extern int ima_file_check(struct file *file, int mask); |
20 | extern void ima_file_free(struct file *file); | 20 | extern void ima_file_free(struct file *file); |
21 | extern int ima_file_mmap(struct file *file, unsigned long prot); | 21 | extern int ima_file_mmap(struct file *file, unsigned long prot); |
22 | extern int ima_read_file(struct file *file, enum kernel_read_file_id id); | 22 | extern int ima_read_file(struct file *file, enum kernel_read_file_id id); |
@@ -34,7 +34,7 @@ static inline int ima_bprm_check(struct linux_binprm *bprm) | |||
34 | return 0; | 34 | return 0; |
35 | } | 35 | } |
36 | 36 | ||
37 | static inline int ima_file_check(struct file *file, int mask, int opened) | 37 | static inline int ima_file_check(struct file *file, int mask) |
38 | { | 38 | { |
39 | return 0; | 39 | return 0; |
40 | } | 40 | } |
diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h index 8f1131c8dd54..a8ee106b865d 100644 --- a/include/linux/lsm_hooks.h +++ b/include/linux/lsm_hooks.h | |||
@@ -1569,7 +1569,7 @@ union security_list_options { | |||
1569 | int (*file_send_sigiotask)(struct task_struct *tsk, | 1569 | int (*file_send_sigiotask)(struct task_struct *tsk, |
1570 | struct fown_struct *fown, int sig); | 1570 | struct fown_struct *fown, int sig); |
1571 | int (*file_receive)(struct file *file); | 1571 | int (*file_receive)(struct file *file); |
1572 | int (*file_open)(struct file *file, const struct cred *cred); | 1572 | int (*file_open)(struct file *file); |
1573 | 1573 | ||
1574 | int (*task_alloc)(struct task_struct *task, unsigned long clone_flags); | 1574 | int (*task_alloc)(struct task_struct *task, unsigned long clone_flags); |
1575 | void (*task_free)(struct task_struct *task); | 1575 | void (*task_free)(struct task_struct *task); |
diff --git a/include/linux/security.h b/include/linux/security.h index 63030c85ee19..88d30fc975e7 100644 --- a/include/linux/security.h +++ b/include/linux/security.h | |||
@@ -309,7 +309,7 @@ void security_file_set_fowner(struct file *file); | |||
309 | int security_file_send_sigiotask(struct task_struct *tsk, | 309 | int security_file_send_sigiotask(struct task_struct *tsk, |
310 | struct fown_struct *fown, int sig); | 310 | struct fown_struct *fown, int sig); |
311 | int security_file_receive(struct file *file); | 311 | int security_file_receive(struct file *file); |
312 | int security_file_open(struct file *file, const struct cred *cred); | 312 | int security_file_open(struct file *file); |
313 | int security_task_alloc(struct task_struct *task, unsigned long clone_flags); | 313 | int security_task_alloc(struct task_struct *task, unsigned long clone_flags); |
314 | void security_task_free(struct task_struct *task); | 314 | void security_task_free(struct task_struct *task); |
315 | int security_cred_alloc_blank(struct cred *cred, gfp_t gfp); | 315 | int security_cred_alloc_blank(struct cred *cred, gfp_t gfp); |
@@ -858,8 +858,7 @@ static inline int security_file_receive(struct file *file) | |||
858 | return 0; | 858 | return 0; |
859 | } | 859 | } |
860 | 860 | ||
861 | static inline int security_file_open(struct file *file, | 861 | static inline int security_file_open(struct file *file) |
862 | const struct cred *cred) | ||
863 | { | 862 | { |
864 | return 0; | 863 | return 0; |
865 | } | 864 | } |
@@ -1366,15 +1366,14 @@ long do_shmat(int shmid, char __user *shmaddr, int shmflg, | |||
1366 | struct shmid_kernel *shp; | 1366 | struct shmid_kernel *shp; |
1367 | unsigned long addr = (unsigned long)shmaddr; | 1367 | unsigned long addr = (unsigned long)shmaddr; |
1368 | unsigned long size; | 1368 | unsigned long size; |
1369 | struct file *file; | 1369 | struct file *file, *base; |
1370 | int err; | 1370 | int err; |
1371 | unsigned long flags = MAP_SHARED; | 1371 | unsigned long flags = MAP_SHARED; |
1372 | unsigned long prot; | 1372 | unsigned long prot; |
1373 | int acc_mode; | 1373 | int acc_mode; |
1374 | struct ipc_namespace *ns; | 1374 | struct ipc_namespace *ns; |
1375 | struct shm_file_data *sfd; | 1375 | struct shm_file_data *sfd; |
1376 | struct path path; | 1376 | int f_flags; |
1377 | fmode_t f_mode; | ||
1378 | unsigned long populate = 0; | 1377 | unsigned long populate = 0; |
1379 | 1378 | ||
1380 | err = -EINVAL; | 1379 | err = -EINVAL; |
@@ -1407,11 +1406,11 @@ long do_shmat(int shmid, char __user *shmaddr, int shmflg, | |||
1407 | if (shmflg & SHM_RDONLY) { | 1406 | if (shmflg & SHM_RDONLY) { |
1408 | prot = PROT_READ; | 1407 | prot = PROT_READ; |
1409 | acc_mode = S_IRUGO; | 1408 | acc_mode = S_IRUGO; |
1410 | f_mode = FMODE_READ; | 1409 | f_flags = O_RDONLY; |
1411 | } else { | 1410 | } else { |
1412 | prot = PROT_READ | PROT_WRITE; | 1411 | prot = PROT_READ | PROT_WRITE; |
1413 | acc_mode = S_IRUGO | S_IWUGO; | 1412 | acc_mode = S_IRUGO | S_IWUGO; |
1414 | f_mode = FMODE_READ | FMODE_WRITE; | 1413 | f_flags = O_RDWR; |
1415 | } | 1414 | } |
1416 | if (shmflg & SHM_EXEC) { | 1415 | if (shmflg & SHM_EXEC) { |
1417 | prot |= PROT_EXEC; | 1416 | prot |= PROT_EXEC; |
@@ -1447,46 +1446,44 @@ long do_shmat(int shmid, char __user *shmaddr, int shmflg, | |||
1447 | goto out_unlock; | 1446 | goto out_unlock; |
1448 | } | 1447 | } |
1449 | 1448 | ||
1450 | path = shp->shm_file->f_path; | 1449 | /* |
1451 | path_get(&path); | 1450 | * We need to take a reference to the real shm file to prevent the |
1451 | * pointer from becoming stale in cases where the lifetime of the outer | ||
1452 | * file extends beyond that of the shm segment. It's not usually | ||
1453 | * possible, but it can happen during remap_file_pages() emulation as | ||
1454 | * that unmaps the memory, then does ->mmap() via file reference only. | ||
1455 | * We'll deny the ->mmap() if the shm segment was since removed, but to | ||
1456 | * detect shm ID reuse we need to compare the file pointers. | ||
1457 | */ | ||
1458 | base = get_file(shp->shm_file); | ||
1452 | shp->shm_nattch++; | 1459 | shp->shm_nattch++; |
1453 | size = i_size_read(d_inode(path.dentry)); | 1460 | size = i_size_read(file_inode(base)); |
1454 | ipc_unlock_object(&shp->shm_perm); | 1461 | ipc_unlock_object(&shp->shm_perm); |
1455 | rcu_read_unlock(); | 1462 | rcu_read_unlock(); |
1456 | 1463 | ||
1457 | err = -ENOMEM; | 1464 | err = -ENOMEM; |
1458 | sfd = kzalloc(sizeof(*sfd), GFP_KERNEL); | 1465 | sfd = kzalloc(sizeof(*sfd), GFP_KERNEL); |
1459 | if (!sfd) { | 1466 | if (!sfd) { |
1460 | path_put(&path); | 1467 | fput(base); |
1461 | goto out_nattch; | 1468 | goto out_nattch; |
1462 | } | 1469 | } |
1463 | 1470 | ||
1464 | file = alloc_file(&path, f_mode, | 1471 | file = alloc_file_clone(base, f_flags, |
1465 | is_file_hugepages(shp->shm_file) ? | 1472 | is_file_hugepages(base) ? |
1466 | &shm_file_operations_huge : | 1473 | &shm_file_operations_huge : |
1467 | &shm_file_operations); | 1474 | &shm_file_operations); |
1468 | err = PTR_ERR(file); | 1475 | err = PTR_ERR(file); |
1469 | if (IS_ERR(file)) { | 1476 | if (IS_ERR(file)) { |
1470 | kfree(sfd); | 1477 | kfree(sfd); |
1471 | path_put(&path); | 1478 | fput(base); |
1472 | goto out_nattch; | 1479 | goto out_nattch; |
1473 | } | 1480 | } |
1474 | 1481 | ||
1475 | file->private_data = sfd; | ||
1476 | file->f_mapping = shp->shm_file->f_mapping; | ||
1477 | sfd->id = shp->shm_perm.id; | 1482 | sfd->id = shp->shm_perm.id; |
1478 | sfd->ns = get_ipc_ns(ns); | 1483 | sfd->ns = get_ipc_ns(ns); |
1479 | /* | 1484 | sfd->file = base; |
1480 | * We need to take a reference to the real shm file to prevent the | ||
1481 | * pointer from becoming stale in cases where the lifetime of the outer | ||
1482 | * file extends beyond that of the shm segment. It's not usually | ||
1483 | * possible, but it can happen during remap_file_pages() emulation as | ||
1484 | * that unmaps the memory, then does ->mmap() via file reference only. | ||
1485 | * We'll deny the ->mmap() if the shm segment was since removed, but to | ||
1486 | * detect shm ID reuse we need to compare the file pointers. | ||
1487 | */ | ||
1488 | sfd->file = get_file(shp->shm_file); | ||
1489 | sfd->vm_ops = NULL; | 1485 | sfd->vm_ops = NULL; |
1486 | file->private_data = sfd; | ||
1490 | 1487 | ||
1491 | err = security_mmap_file(file, prot, flags); | 1488 | err = security_mmap_file(file, prot, flags); |
1492 | if (err) | 1489 | if (err) |
diff --git a/mm/memfd.c b/mm/memfd.c index 27069518e3c5..2bb5e257080e 100644 --- a/mm/memfd.c +++ b/mm/memfd.c | |||
@@ -326,7 +326,7 @@ SYSCALL_DEFINE2(memfd_create, | |||
326 | goto err_fd; | 326 | goto err_fd; |
327 | } | 327 | } |
328 | file->f_mode |= FMODE_LSEEK | FMODE_PREAD | FMODE_PWRITE; | 328 | file->f_mode |= FMODE_LSEEK | FMODE_PREAD | FMODE_PWRITE; |
329 | file->f_flags |= O_RDWR | O_LARGEFILE; | 329 | file->f_flags |= O_LARGEFILE; |
330 | 330 | ||
331 | if (flags & MFD_ALLOW_SEALING) { | 331 | if (flags & MFD_ALLOW_SEALING) { |
332 | file_seals = memfd_file_seals_ptr(file); | 332 | file_seals = memfd_file_seals_ptr(file); |
diff --git a/mm/shmem.c b/mm/shmem.c index 41b9bbf24e16..96bcc51fb9ec 100644 --- a/mm/shmem.c +++ b/mm/shmem.c | |||
@@ -3897,18 +3897,11 @@ EXPORT_SYMBOL_GPL(shmem_truncate_range); | |||
3897 | 3897 | ||
3898 | /* common code */ | 3898 | /* common code */ |
3899 | 3899 | ||
3900 | static const struct dentry_operations anon_ops = { | ||
3901 | .d_dname = simple_dname | ||
3902 | }; | ||
3903 | |||
3904 | static struct file *__shmem_file_setup(struct vfsmount *mnt, const char *name, loff_t size, | 3900 | static struct file *__shmem_file_setup(struct vfsmount *mnt, const char *name, loff_t size, |
3905 | unsigned long flags, unsigned int i_flags) | 3901 | unsigned long flags, unsigned int i_flags) |
3906 | { | 3902 | { |
3907 | struct file *res; | ||
3908 | struct inode *inode; | 3903 | struct inode *inode; |
3909 | struct path path; | 3904 | struct file *res; |
3910 | struct super_block *sb; | ||
3911 | struct qstr this; | ||
3912 | 3905 | ||
3913 | if (IS_ERR(mnt)) | 3906 | if (IS_ERR(mnt)) |
3914 | return ERR_CAST(mnt); | 3907 | return ERR_CAST(mnt); |
@@ -3919,41 +3912,21 @@ static struct file *__shmem_file_setup(struct vfsmount *mnt, const char *name, l | |||
3919 | if (shmem_acct_size(flags, size)) | 3912 | if (shmem_acct_size(flags, size)) |
3920 | return ERR_PTR(-ENOMEM); | 3913 | return ERR_PTR(-ENOMEM); |
3921 | 3914 | ||
3922 | res = ERR_PTR(-ENOMEM); | 3915 | inode = shmem_get_inode(mnt->mnt_sb, NULL, S_IFREG | S_IRWXUGO, 0, |
3923 | this.name = name; | 3916 | flags); |
3924 | this.len = strlen(name); | 3917 | if (unlikely(!inode)) { |
3925 | this.hash = 0; /* will go */ | 3918 | shmem_unacct_size(flags, size); |
3926 | sb = mnt->mnt_sb; | 3919 | return ERR_PTR(-ENOSPC); |
3927 | path.mnt = mntget(mnt); | 3920 | } |
3928 | path.dentry = d_alloc_pseudo(sb, &this); | ||
3929 | if (!path.dentry) | ||
3930 | goto put_memory; | ||
3931 | d_set_d_op(path.dentry, &anon_ops); | ||
3932 | |||
3933 | res = ERR_PTR(-ENOSPC); | ||
3934 | inode = shmem_get_inode(sb, NULL, S_IFREG | 0777, 0, flags); | ||
3935 | if (!inode) | ||
3936 | goto put_memory; | ||
3937 | |||
3938 | inode->i_flags |= i_flags; | 3921 | inode->i_flags |= i_flags; |
3939 | d_instantiate(path.dentry, inode); | ||
3940 | inode->i_size = size; | 3922 | inode->i_size = size; |
3941 | clear_nlink(inode); /* It is unlinked */ | 3923 | clear_nlink(inode); /* It is unlinked */ |
3942 | res = ERR_PTR(ramfs_nommu_expand_for_mapping(inode, size)); | 3924 | res = ERR_PTR(ramfs_nommu_expand_for_mapping(inode, size)); |
3925 | if (!IS_ERR(res)) | ||
3926 | res = alloc_file_pseudo(inode, mnt, name, O_RDWR, | ||
3927 | &shmem_file_operations); | ||
3943 | if (IS_ERR(res)) | 3928 | if (IS_ERR(res)) |
3944 | goto put_path; | 3929 | iput(inode); |
3945 | |||
3946 | res = alloc_file(&path, FMODE_WRITE | FMODE_READ, | ||
3947 | &shmem_file_operations); | ||
3948 | if (IS_ERR(res)) | ||
3949 | goto put_path; | ||
3950 | |||
3951 | return res; | ||
3952 | |||
3953 | put_memory: | ||
3954 | shmem_unacct_size(flags, size); | ||
3955 | put_path: | ||
3956 | path_put(&path); | ||
3957 | return res; | 3930 | return res; |
3958 | } | 3931 | } |
3959 | 3932 | ||
diff --git a/net/socket.c b/net/socket.c index 8c24d5dc4bc8..792f0313ea91 100644 --- a/net/socket.c +++ b/net/socket.c | |||
@@ -388,39 +388,20 @@ static struct file_system_type sock_fs_type = { | |||
388 | 388 | ||
389 | struct file *sock_alloc_file(struct socket *sock, int flags, const char *dname) | 389 | struct file *sock_alloc_file(struct socket *sock, int flags, const char *dname) |
390 | { | 390 | { |
391 | struct qstr name = { .name = "" }; | ||
392 | struct path path; | ||
393 | struct file *file; | 391 | struct file *file; |
394 | 392 | ||
395 | if (dname) { | 393 | if (!dname) |
396 | name.name = dname; | 394 | dname = sock->sk ? sock->sk->sk_prot_creator->name : ""; |
397 | name.len = strlen(name.name); | ||
398 | } else if (sock->sk) { | ||
399 | name.name = sock->sk->sk_prot_creator->name; | ||
400 | name.len = strlen(name.name); | ||
401 | } | ||
402 | path.dentry = d_alloc_pseudo(sock_mnt->mnt_sb, &name); | ||
403 | if (unlikely(!path.dentry)) { | ||
404 | sock_release(sock); | ||
405 | return ERR_PTR(-ENOMEM); | ||
406 | } | ||
407 | path.mnt = mntget(sock_mnt); | ||
408 | |||
409 | d_instantiate(path.dentry, SOCK_INODE(sock)); | ||
410 | 395 | ||
411 | file = alloc_file(&path, FMODE_READ | FMODE_WRITE, | 396 | file = alloc_file_pseudo(SOCK_INODE(sock), sock_mnt, dname, |
412 | &socket_file_ops); | 397 | O_RDWR | (flags & O_NONBLOCK), |
398 | &socket_file_ops); | ||
413 | if (IS_ERR(file)) { | 399 | if (IS_ERR(file)) { |
414 | /* drop dentry, keep inode for a bit */ | ||
415 | ihold(d_inode(path.dentry)); | ||
416 | path_put(&path); | ||
417 | /* ... and now kill it properly */ | ||
418 | sock_release(sock); | 400 | sock_release(sock); |
419 | return file; | 401 | return file; |
420 | } | 402 | } |
421 | 403 | ||
422 | sock->file = file; | 404 | sock->file = file; |
423 | file->f_flags = O_RDWR | (flags & O_NONBLOCK); | ||
424 | file->private_data = sock; | 405 | file->private_data = sock; |
425 | return file; | 406 | return file; |
426 | } | 407 | } |
diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c index 74f17376202b..8b8b70620bbe 100644 --- a/security/apparmor/lsm.c +++ b/security/apparmor/lsm.c | |||
@@ -395,7 +395,7 @@ static int apparmor_inode_getattr(const struct path *path) | |||
395 | return common_perm_cond(OP_GETATTR, path, AA_MAY_GETATTR); | 395 | return common_perm_cond(OP_GETATTR, path, AA_MAY_GETATTR); |
396 | } | 396 | } |
397 | 397 | ||
398 | static int apparmor_file_open(struct file *file, const struct cred *cred) | 398 | static int apparmor_file_open(struct file *file) |
399 | { | 399 | { |
400 | struct aa_file_ctx *fctx = file_ctx(file); | 400 | struct aa_file_ctx *fctx = file_ctx(file); |
401 | struct aa_label *label; | 401 | struct aa_label *label; |
@@ -414,7 +414,7 @@ static int apparmor_file_open(struct file *file, const struct cred *cred) | |||
414 | return 0; | 414 | return 0; |
415 | } | 415 | } |
416 | 416 | ||
417 | label = aa_get_newest_cred_label(cred); | 417 | label = aa_get_newest_cred_label(file->f_cred); |
418 | if (!unconfined(label)) { | 418 | if (!unconfined(label)) { |
419 | struct inode *inode = file_inode(file); | 419 | struct inode *inode = file_inode(file); |
420 | struct path_cond cond = { inode->i_uid, inode->i_mode }; | 420 | struct path_cond cond = { inode->i_uid, inode->i_mode }; |
diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h index 354bb5716ce3..e4c1a236976c 100644 --- a/security/integrity/ima/ima.h +++ b/security/integrity/ima/ima.h | |||
@@ -238,7 +238,7 @@ int ima_appraise_measurement(enum ima_hooks func, | |||
238 | struct integrity_iint_cache *iint, | 238 | struct integrity_iint_cache *iint, |
239 | struct file *file, const unsigned char *filename, | 239 | struct file *file, const unsigned char *filename, |
240 | struct evm_ima_xattr_data *xattr_value, | 240 | struct evm_ima_xattr_data *xattr_value, |
241 | int xattr_len, int opened); | 241 | int xattr_len); |
242 | int ima_must_appraise(struct inode *inode, int mask, enum ima_hooks func); | 242 | int ima_must_appraise(struct inode *inode, int mask, enum ima_hooks func); |
243 | void ima_update_xattr(struct integrity_iint_cache *iint, struct file *file); | 243 | void ima_update_xattr(struct integrity_iint_cache *iint, struct file *file); |
244 | enum integrity_status ima_get_cache_status(struct integrity_iint_cache *iint, | 244 | enum integrity_status ima_get_cache_status(struct integrity_iint_cache *iint, |
@@ -254,7 +254,7 @@ static inline int ima_appraise_measurement(enum ima_hooks func, | |||
254 | struct file *file, | 254 | struct file *file, |
255 | const unsigned char *filename, | 255 | const unsigned char *filename, |
256 | struct evm_ima_xattr_data *xattr_value, | 256 | struct evm_ima_xattr_data *xattr_value, |
257 | int xattr_len, int opened) | 257 | int xattr_len) |
258 | { | 258 | { |
259 | return INTEGRITY_UNKNOWN; | 259 | return INTEGRITY_UNKNOWN; |
260 | } | 260 | } |
diff --git a/security/integrity/ima/ima_appraise.c b/security/integrity/ima/ima_appraise.c index 8bd7a0733e51..deec1804a00a 100644 --- a/security/integrity/ima/ima_appraise.c +++ b/security/integrity/ima/ima_appraise.c | |||
@@ -212,7 +212,7 @@ int ima_appraise_measurement(enum ima_hooks func, | |||
212 | struct integrity_iint_cache *iint, | 212 | struct integrity_iint_cache *iint, |
213 | struct file *file, const unsigned char *filename, | 213 | struct file *file, const unsigned char *filename, |
214 | struct evm_ima_xattr_data *xattr_value, | 214 | struct evm_ima_xattr_data *xattr_value, |
215 | int xattr_len, int opened) | 215 | int xattr_len) |
216 | { | 216 | { |
217 | static const char op[] = "appraise_data"; | 217 | static const char op[] = "appraise_data"; |
218 | const char *cause = "unknown"; | 218 | const char *cause = "unknown"; |
@@ -231,7 +231,7 @@ int ima_appraise_measurement(enum ima_hooks func, | |||
231 | cause = iint->flags & IMA_DIGSIG_REQUIRED ? | 231 | cause = iint->flags & IMA_DIGSIG_REQUIRED ? |
232 | "IMA-signature-required" : "missing-hash"; | 232 | "IMA-signature-required" : "missing-hash"; |
233 | status = INTEGRITY_NOLABEL; | 233 | status = INTEGRITY_NOLABEL; |
234 | if (opened & FILE_CREATED) | 234 | if (file->f_mode & FMODE_CREATED) |
235 | iint->flags |= IMA_NEW_FILE; | 235 | iint->flags |= IMA_NEW_FILE; |
236 | if ((iint->flags & IMA_NEW_FILE) && | 236 | if ((iint->flags & IMA_NEW_FILE) && |
237 | (!(iint->flags & IMA_DIGSIG_REQUIRED) || | 237 | (!(iint->flags & IMA_DIGSIG_REQUIRED) || |
diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c index dca44cf7838e..b286f37712d5 100644 --- a/security/integrity/ima/ima_main.c +++ b/security/integrity/ima/ima_main.c | |||
@@ -168,7 +168,7 @@ void ima_file_free(struct file *file) | |||
168 | 168 | ||
169 | static int process_measurement(struct file *file, const struct cred *cred, | 169 | static int process_measurement(struct file *file, const struct cred *cred, |
170 | u32 secid, char *buf, loff_t size, int mask, | 170 | u32 secid, char *buf, loff_t size, int mask, |
171 | enum ima_hooks func, int opened) | 171 | enum ima_hooks func) |
172 | { | 172 | { |
173 | struct inode *inode = file_inode(file); | 173 | struct inode *inode = file_inode(file); |
174 | struct integrity_iint_cache *iint = NULL; | 174 | struct integrity_iint_cache *iint = NULL; |
@@ -294,7 +294,7 @@ static int process_measurement(struct file *file, const struct cred *cred, | |||
294 | if (rc == 0 && (action & IMA_APPRAISE_SUBMASK)) { | 294 | if (rc == 0 && (action & IMA_APPRAISE_SUBMASK)) { |
295 | inode_lock(inode); | 295 | inode_lock(inode); |
296 | rc = ima_appraise_measurement(func, iint, file, pathname, | 296 | rc = ima_appraise_measurement(func, iint, file, pathname, |
297 | xattr_value, xattr_len, opened); | 297 | xattr_value, xattr_len); |
298 | inode_unlock(inode); | 298 | inode_unlock(inode); |
299 | } | 299 | } |
300 | if (action & IMA_AUDIT) | 300 | if (action & IMA_AUDIT) |
@@ -338,7 +338,7 @@ int ima_file_mmap(struct file *file, unsigned long prot) | |||
338 | if (file && (prot & PROT_EXEC)) { | 338 | if (file && (prot & PROT_EXEC)) { |
339 | security_task_getsecid(current, &secid); | 339 | security_task_getsecid(current, &secid); |
340 | return process_measurement(file, current_cred(), secid, NULL, | 340 | return process_measurement(file, current_cred(), secid, NULL, |
341 | 0, MAY_EXEC, MMAP_CHECK, 0); | 341 | 0, MAY_EXEC, MMAP_CHECK); |
342 | } | 342 | } |
343 | 343 | ||
344 | return 0; | 344 | return 0; |
@@ -364,13 +364,13 @@ int ima_bprm_check(struct linux_binprm *bprm) | |||
364 | 364 | ||
365 | security_task_getsecid(current, &secid); | 365 | security_task_getsecid(current, &secid); |
366 | ret = process_measurement(bprm->file, current_cred(), secid, NULL, 0, | 366 | ret = process_measurement(bprm->file, current_cred(), secid, NULL, 0, |
367 | MAY_EXEC, BPRM_CHECK, 0); | 367 | MAY_EXEC, BPRM_CHECK); |
368 | if (ret) | 368 | if (ret) |
369 | return ret; | 369 | return ret; |
370 | 370 | ||
371 | security_cred_getsecid(bprm->cred, &secid); | 371 | security_cred_getsecid(bprm->cred, &secid); |
372 | return process_measurement(bprm->file, bprm->cred, secid, NULL, 0, | 372 | return process_measurement(bprm->file, bprm->cred, secid, NULL, 0, |
373 | MAY_EXEC, CREDS_CHECK, 0); | 373 | MAY_EXEC, CREDS_CHECK); |
374 | } | 374 | } |
375 | 375 | ||
376 | /** | 376 | /** |
@@ -383,14 +383,14 @@ int ima_bprm_check(struct linux_binprm *bprm) | |||
383 | * On success return 0. On integrity appraisal error, assuming the file | 383 | * On success return 0. On integrity appraisal error, assuming the file |
384 | * is in policy and IMA-appraisal is in enforcing mode, return -EACCES. | 384 | * is in policy and IMA-appraisal is in enforcing mode, return -EACCES. |
385 | */ | 385 | */ |
386 | int ima_file_check(struct file *file, int mask, int opened) | 386 | int ima_file_check(struct file *file, int mask) |
387 | { | 387 | { |
388 | u32 secid; | 388 | u32 secid; |
389 | 389 | ||
390 | security_task_getsecid(current, &secid); | 390 | security_task_getsecid(current, &secid); |
391 | return process_measurement(file, current_cred(), secid, NULL, 0, | 391 | return process_measurement(file, current_cred(), secid, NULL, 0, |
392 | mask & (MAY_READ | MAY_WRITE | MAY_EXEC | | 392 | mask & (MAY_READ | MAY_WRITE | MAY_EXEC | |
393 | MAY_APPEND), FILE_CHECK, opened); | 393 | MAY_APPEND), FILE_CHECK); |
394 | } | 394 | } |
395 | EXPORT_SYMBOL_GPL(ima_file_check); | 395 | EXPORT_SYMBOL_GPL(ima_file_check); |
396 | 396 | ||
@@ -493,7 +493,7 @@ int ima_post_read_file(struct file *file, void *buf, loff_t size, | |||
493 | func = read_idmap[read_id] ?: FILE_CHECK; | 493 | func = read_idmap[read_id] ?: FILE_CHECK; |
494 | security_task_getsecid(current, &secid); | 494 | security_task_getsecid(current, &secid); |
495 | return process_measurement(file, current_cred(), secid, buf, size, | 495 | return process_measurement(file, current_cred(), secid, buf, size, |
496 | MAY_READ, func, 0); | 496 | MAY_READ, func); |
497 | } | 497 | } |
498 | 498 | ||
499 | static int __init init_ima(void) | 499 | static int __init init_ima(void) |
diff --git a/security/security.c b/security/security.c index 68f46d849abe..5dce67070cdf 100644 --- a/security/security.c +++ b/security/security.c | |||
@@ -970,11 +970,11 @@ int security_file_receive(struct file *file) | |||
970 | return call_int_hook(file_receive, 0, file); | 970 | return call_int_hook(file_receive, 0, file); |
971 | } | 971 | } |
972 | 972 | ||
973 | int security_file_open(struct file *file, const struct cred *cred) | 973 | int security_file_open(struct file *file) |
974 | { | 974 | { |
975 | int ret; | 975 | int ret; |
976 | 976 | ||
977 | ret = call_int_hook(file_open, 0, file, cred); | 977 | ret = call_int_hook(file_open, 0, file); |
978 | if (ret) | 978 | if (ret) |
979 | return ret; | 979 | return ret; |
980 | 980 | ||
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 2b5ee5fbd652..18006be15713 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c | |||
@@ -3862,7 +3862,7 @@ static int selinux_file_receive(struct file *file) | |||
3862 | return file_has_perm(cred, file, file_to_av(file)); | 3862 | return file_has_perm(cred, file, file_to_av(file)); |
3863 | } | 3863 | } |
3864 | 3864 | ||
3865 | static int selinux_file_open(struct file *file, const struct cred *cred) | 3865 | static int selinux_file_open(struct file *file) |
3866 | { | 3866 | { |
3867 | struct file_security_struct *fsec; | 3867 | struct file_security_struct *fsec; |
3868 | struct inode_security_struct *isec; | 3868 | struct inode_security_struct *isec; |
@@ -3886,7 +3886,7 @@ static int selinux_file_open(struct file *file, const struct cred *cred) | |||
3886 | * new inode label or new policy. | 3886 | * new inode label or new policy. |
3887 | * This check is not redundant - do not remove. | 3887 | * This check is not redundant - do not remove. |
3888 | */ | 3888 | */ |
3889 | return file_path_has_perm(cred, file, open_file_to_av(file)); | 3889 | return file_path_has_perm(file->f_cred, file, open_file_to_av(file)); |
3890 | } | 3890 | } |
3891 | 3891 | ||
3892 | /* task security operations */ | 3892 | /* task security operations */ |
diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c index 19de675d4504..9ab8097dab7c 100644 --- a/security/smack/smack_lsm.c +++ b/security/smack/smack_lsm.c | |||
@@ -1927,9 +1927,9 @@ static int smack_file_receive(struct file *file) | |||
1927 | * | 1927 | * |
1928 | * Returns 0 | 1928 | * Returns 0 |
1929 | */ | 1929 | */ |
1930 | static int smack_file_open(struct file *file, const struct cred *cred) | 1930 | static int smack_file_open(struct file *file) |
1931 | { | 1931 | { |
1932 | struct task_smack *tsp = cred->security; | 1932 | struct task_smack *tsp = file->f_cred->security; |
1933 | struct inode *inode = file_inode(file); | 1933 | struct inode *inode = file_inode(file); |
1934 | struct smk_audit_info ad; | 1934 | struct smk_audit_info ad; |
1935 | int rc; | 1935 | int rc; |
@@ -1937,7 +1937,7 @@ static int smack_file_open(struct file *file, const struct cred *cred) | |||
1937 | smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH); | 1937 | smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH); |
1938 | smk_ad_setfield_u_fs_path(&ad, file->f_path); | 1938 | smk_ad_setfield_u_fs_path(&ad, file->f_path); |
1939 | rc = smk_tskacc(tsp, smk_of_inode(inode), MAY_READ, &ad); | 1939 | rc = smk_tskacc(tsp, smk_of_inode(inode), MAY_READ, &ad); |
1940 | rc = smk_bu_credfile(cred, file, MAY_READ, rc); | 1940 | rc = smk_bu_credfile(file->f_cred, file, MAY_READ, rc); |
1941 | 1941 | ||
1942 | return rc; | 1942 | return rc; |
1943 | } | 1943 | } |
diff --git a/security/tomoyo/tomoyo.c b/security/tomoyo/tomoyo.c index 213b8c593668..9f932e2d6852 100644 --- a/security/tomoyo/tomoyo.c +++ b/security/tomoyo/tomoyo.c | |||
@@ -320,7 +320,7 @@ static int tomoyo_file_fcntl(struct file *file, unsigned int cmd, | |||
320 | * | 320 | * |
321 | * Returns 0 on success, negative value otherwise. | 321 | * Returns 0 on success, negative value otherwise. |
322 | */ | 322 | */ |
323 | static int tomoyo_file_open(struct file *f, const struct cred *cred) | 323 | static int tomoyo_file_open(struct file *f) |
324 | { | 324 | { |
325 | int flags = f->f_flags; | 325 | int flags = f->f_flags; |
326 | /* Don't check read permission here if called from do_execve(). */ | 326 | /* Don't check read permission here if called from do_execve(). */ |