diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2012-06-26 13:58:53 -0400 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2012-07-22 16:01:29 -0400 |
commit | 765927b2d508712d320c8934db963bbe14c3fcec (patch) | |
tree | 97acdb14fae285764def396c4ed01d4d5c93e76a | |
parent | bf349a447059656ebe63fb4fd1ccb27ac1da22ad (diff) |
switch dentry_open() to struct path, make it grab references itself
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
-rw-r--r-- | arch/powerpc/platforms/cell/spufs/inode.c | 18 | ||||
-rw-r--r-- | fs/autofs4/dev-ioctl.c | 4 | ||||
-rw-r--r-- | fs/cachefiles/rdwr.c | 8 | ||||
-rw-r--r-- | fs/ecryptfs/kthread.c | 21 | ||||
-rw-r--r-- | fs/exportfs/expfs.c | 13 | ||||
-rw-r--r-- | fs/hppfs/hppfs.c | 20 | ||||
-rw-r--r-- | fs/nfsd/vfs.c | 10 | ||||
-rw-r--r-- | fs/notify/fanotify/fanotify_user.c | 8 | ||||
-rw-r--r-- | fs/open.c | 17 | ||||
-rw-r--r-- | fs/xfs/xfs_ioctl.c | 7 | ||||
-rw-r--r-- | include/linux/fs.h | 3 | ||||
-rw-r--r-- | ipc/mqueue.c | 117 | ||||
-rw-r--r-- | security/selinux/hooks.c | 3 | ||||
-rw-r--r-- | security/selinux/include/security.h | 2 | ||||
-rw-r--r-- | security/selinux/selinuxfs.c | 6 |
15 files changed, 106 insertions, 151 deletions
diff --git a/arch/powerpc/platforms/cell/spufs/inode.c b/arch/powerpc/platforms/cell/spufs/inode.c index 1c9cac0cf895..d544d7816df3 100644 --- a/arch/powerpc/platforms/cell/spufs/inode.c +++ b/arch/powerpc/platforms/cell/spufs/inode.c | |||
@@ -317,7 +317,7 @@ out: | |||
317 | return ret; | 317 | return ret; |
318 | } | 318 | } |
319 | 319 | ||
320 | static int spufs_context_open(struct dentry *dentry, struct vfsmount *mnt) | 320 | static int spufs_context_open(struct path *path) |
321 | { | 321 | { |
322 | int ret; | 322 | int ret; |
323 | struct file *filp; | 323 | struct file *filp; |
@@ -326,11 +326,7 @@ static int spufs_context_open(struct dentry *dentry, struct vfsmount *mnt) | |||
326 | if (ret < 0) | 326 | if (ret < 0) |
327 | return ret; | 327 | return ret; |
328 | 328 | ||
329 | /* | 329 | filp = dentry_open(path, O_RDONLY, current_cred()); |
330 | * get references for dget and mntget, will be released | ||
331 | * in error path of *_open(). | ||
332 | */ | ||
333 | filp = dentry_open(dget(dentry), mntget(mnt), O_RDONLY, current_cred()); | ||
334 | if (IS_ERR(filp)) { | 330 | if (IS_ERR(filp)) { |
335 | put_unused_fd(ret); | 331 | put_unused_fd(ret); |
336 | return PTR_ERR(filp); | 332 | return PTR_ERR(filp); |
@@ -452,6 +448,7 @@ spufs_create_context(struct inode *inode, struct dentry *dentry, | |||
452 | int affinity; | 448 | int affinity; |
453 | struct spu_gang *gang; | 449 | struct spu_gang *gang; |
454 | struct spu_context *neighbor; | 450 | struct spu_context *neighbor; |
451 | struct path path = {.mnt = mnt, .dentry = dentry}; | ||
455 | 452 | ||
456 | ret = -EPERM; | 453 | ret = -EPERM; |
457 | if ((flags & SPU_CREATE_NOSCHED) && | 454 | if ((flags & SPU_CREATE_NOSCHED) && |
@@ -494,7 +491,7 @@ spufs_create_context(struct inode *inode, struct dentry *dentry, | |||
494 | put_spu_context(neighbor); | 491 | put_spu_context(neighbor); |
495 | } | 492 | } |
496 | 493 | ||
497 | ret = spufs_context_open(dentry, mnt); | 494 | ret = spufs_context_open(&path); |
498 | if (ret < 0) { | 495 | if (ret < 0) { |
499 | WARN_ON(spufs_rmdir(inode, dentry)); | 496 | WARN_ON(spufs_rmdir(inode, dentry)); |
500 | if (affinity) | 497 | if (affinity) |
@@ -551,7 +548,7 @@ out: | |||
551 | return ret; | 548 | return ret; |
552 | } | 549 | } |
553 | 550 | ||
554 | static int spufs_gang_open(struct dentry *dentry, struct vfsmount *mnt) | 551 | static int spufs_gang_open(struct path *path) |
555 | { | 552 | { |
556 | int ret; | 553 | int ret; |
557 | struct file *filp; | 554 | struct file *filp; |
@@ -564,7 +561,7 @@ static int spufs_gang_open(struct dentry *dentry, struct vfsmount *mnt) | |||
564 | * get references for dget and mntget, will be released | 561 | * get references for dget and mntget, will be released |
565 | * in error path of *_open(). | 562 | * in error path of *_open(). |
566 | */ | 563 | */ |
567 | filp = dentry_open(dget(dentry), mntget(mnt), O_RDONLY, current_cred()); | 564 | filp = dentry_open(path, O_RDONLY, current_cred()); |
568 | if (IS_ERR(filp)) { | 565 | if (IS_ERR(filp)) { |
569 | put_unused_fd(ret); | 566 | put_unused_fd(ret); |
570 | return PTR_ERR(filp); | 567 | return PTR_ERR(filp); |
@@ -579,13 +576,14 @@ static int spufs_create_gang(struct inode *inode, | |||
579 | struct dentry *dentry, | 576 | struct dentry *dentry, |
580 | struct vfsmount *mnt, umode_t mode) | 577 | struct vfsmount *mnt, umode_t mode) |
581 | { | 578 | { |
579 | struct path path = {.mnt = mnt, .dentry = dentry}; | ||
582 | int ret; | 580 | int ret; |
583 | 581 | ||
584 | ret = spufs_mkgang(inode, dentry, mode & S_IRWXUGO); | 582 | ret = spufs_mkgang(inode, dentry, mode & S_IRWXUGO); |
585 | if (ret) | 583 | if (ret) |
586 | goto out; | 584 | goto out; |
587 | 585 | ||
588 | ret = spufs_gang_open(dentry, mnt); | 586 | ret = spufs_gang_open(&path); |
589 | if (ret < 0) { | 587 | if (ret < 0) { |
590 | int err = simple_rmdir(inode, dentry); | 588 | int err = simple_rmdir(inode, dentry); |
591 | WARN_ON(err); | 589 | WARN_ON(err); |
diff --git a/fs/autofs4/dev-ioctl.c b/fs/autofs4/dev-ioctl.c index aa9103f8f01b..abf645c1703b 100644 --- a/fs/autofs4/dev-ioctl.c +++ b/fs/autofs4/dev-ioctl.c | |||
@@ -257,8 +257,8 @@ static int autofs_dev_ioctl_open_mountpoint(const char *name, dev_t devid) | |||
257 | * corresponding to the autofs fs we want to open. | 257 | * corresponding to the autofs fs we want to open. |
258 | */ | 258 | */ |
259 | 259 | ||
260 | filp = dentry_open(path.dentry, path.mnt, O_RDONLY, | 260 | filp = dentry_open(&path, O_RDONLY, current_cred()); |
261 | current_cred()); | 261 | path_put(&path); |
262 | if (IS_ERR(filp)) { | 262 | if (IS_ERR(filp)) { |
263 | err = PTR_ERR(filp); | 263 | err = PTR_ERR(filp); |
264 | goto out; | 264 | goto out; |
diff --git a/fs/cachefiles/rdwr.c b/fs/cachefiles/rdwr.c index 0e3c0924cc3a..c0353dfac51f 100644 --- a/fs/cachefiles/rdwr.c +++ b/fs/cachefiles/rdwr.c | |||
@@ -891,6 +891,7 @@ int cachefiles_write_page(struct fscache_storage *op, struct page *page) | |||
891 | struct cachefiles_cache *cache; | 891 | struct cachefiles_cache *cache; |
892 | mm_segment_t old_fs; | 892 | mm_segment_t old_fs; |
893 | struct file *file; | 893 | struct file *file; |
894 | struct path path; | ||
894 | loff_t pos, eof; | 895 | loff_t pos, eof; |
895 | size_t len; | 896 | size_t len; |
896 | void *data; | 897 | void *data; |
@@ -916,10 +917,9 @@ int cachefiles_write_page(struct fscache_storage *op, struct page *page) | |||
916 | 917 | ||
917 | /* write the page to the backing filesystem and let it store it in its | 918 | /* write the page to the backing filesystem and let it store it in its |
918 | * own time */ | 919 | * own time */ |
919 | dget(object->backer); | 920 | path.mnt = cache->mnt; |
920 | mntget(cache->mnt); | 921 | path.dentry = object->backer; |
921 | file = dentry_open(object->backer, cache->mnt, O_RDWR, | 922 | file = dentry_open(&path, O_RDWR, cache->cache_cred); |
922 | cache->cache_cred); | ||
923 | if (IS_ERR(file)) { | 923 | if (IS_ERR(file)) { |
924 | ret = PTR_ERR(file); | 924 | ret = PTR_ERR(file); |
925 | } else { | 925 | } else { |
diff --git a/fs/ecryptfs/kthread.c b/fs/ecryptfs/kthread.c index c7d199dc7d24..809e67d05ca3 100644 --- a/fs/ecryptfs/kthread.c +++ b/fs/ecryptfs/kthread.c | |||
@@ -29,8 +29,7 @@ | |||
29 | 29 | ||
30 | struct ecryptfs_open_req { | 30 | struct ecryptfs_open_req { |
31 | struct file **lower_file; | 31 | struct file **lower_file; |
32 | struct dentry *lower_dentry; | 32 | struct path path; |
33 | struct vfsmount *lower_mnt; | ||
34 | struct completion done; | 33 | struct completion done; |
35 | struct list_head kthread_ctl_list; | 34 | struct list_head kthread_ctl_list; |
36 | }; | 35 | }; |
@@ -74,10 +73,7 @@ static int ecryptfs_threadfn(void *ignored) | |||
74 | struct ecryptfs_open_req, | 73 | struct ecryptfs_open_req, |
75 | kthread_ctl_list); | 74 | kthread_ctl_list); |
76 | list_del(&req->kthread_ctl_list); | 75 | list_del(&req->kthread_ctl_list); |
77 | dget(req->lower_dentry); | 76 | *req->lower_file = dentry_open(&req->path, |
78 | mntget(req->lower_mnt); | ||
79 | (*req->lower_file) = dentry_open( | ||
80 | req->lower_dentry, req->lower_mnt, | ||
81 | (O_RDWR | O_LARGEFILE), current_cred()); | 77 | (O_RDWR | O_LARGEFILE), current_cred()); |
82 | complete(&req->done); | 78 | complete(&req->done); |
83 | } | 79 | } |
@@ -140,23 +136,22 @@ int ecryptfs_privileged_open(struct file **lower_file, | |||
140 | int flags = O_LARGEFILE; | 136 | int flags = O_LARGEFILE; |
141 | int rc = 0; | 137 | int rc = 0; |
142 | 138 | ||
139 | init_completion(&req.done); | ||
140 | req.lower_file = lower_file; | ||
141 | req.path.dentry = lower_dentry; | ||
142 | req.path.mnt = lower_mnt; | ||
143 | |||
143 | /* Corresponding dput() and mntput() are done when the | 144 | /* Corresponding dput() and mntput() are done when the |
144 | * lower file is fput() when all eCryptfs files for the inode are | 145 | * lower file is fput() when all eCryptfs files for the inode are |
145 | * released. */ | 146 | * released. */ |
146 | dget(lower_dentry); | ||
147 | mntget(lower_mnt); | ||
148 | flags |= IS_RDONLY(lower_dentry->d_inode) ? O_RDONLY : O_RDWR; | 147 | flags |= IS_RDONLY(lower_dentry->d_inode) ? O_RDONLY : O_RDWR; |
149 | (*lower_file) = dentry_open(lower_dentry, lower_mnt, flags, cred); | 148 | (*lower_file) = dentry_open(&req.path, flags, cred); |
150 | if (!IS_ERR(*lower_file)) | 149 | if (!IS_ERR(*lower_file)) |
151 | goto out; | 150 | goto out; |
152 | if ((flags & O_ACCMODE) == O_RDONLY) { | 151 | if ((flags & O_ACCMODE) == O_RDONLY) { |
153 | rc = PTR_ERR((*lower_file)); | 152 | rc = PTR_ERR((*lower_file)); |
154 | goto out; | 153 | goto out; |
155 | } | 154 | } |
156 | init_completion(&req.done); | ||
157 | req.lower_file = lower_file; | ||
158 | req.lower_dentry = lower_dentry; | ||
159 | req.lower_mnt = lower_mnt; | ||
160 | mutex_lock(&ecryptfs_kthread_ctl.mux); | 155 | mutex_lock(&ecryptfs_kthread_ctl.mux); |
161 | if (ecryptfs_kthread_ctl.flags & ECRYPTFS_KTHREAD_ZOMBIE) { | 156 | if (ecryptfs_kthread_ctl.flags & ECRYPTFS_KTHREAD_ZOMBIE) { |
162 | rc = -EIO; | 157 | rc = -EIO; |
diff --git a/fs/exportfs/expfs.c b/fs/exportfs/expfs.c index b42063cf1b2d..29ab099e3e08 100644 --- a/fs/exportfs/expfs.c +++ b/fs/exportfs/expfs.c | |||
@@ -19,19 +19,19 @@ | |||
19 | #define dprintk(fmt, args...) do{}while(0) | 19 | #define dprintk(fmt, args...) do{}while(0) |
20 | 20 | ||
21 | 21 | ||
22 | static int get_name(struct vfsmount *mnt, struct dentry *dentry, char *name, | 22 | static int get_name(const struct path *path, char *name, struct dentry *child); |
23 | struct dentry *child); | ||
24 | 23 | ||
25 | 24 | ||
26 | static int exportfs_get_name(struct vfsmount *mnt, struct dentry *dir, | 25 | static int exportfs_get_name(struct vfsmount *mnt, struct dentry *dir, |
27 | char *name, struct dentry *child) | 26 | char *name, struct dentry *child) |
28 | { | 27 | { |
29 | const struct export_operations *nop = dir->d_sb->s_export_op; | 28 | const struct export_operations *nop = dir->d_sb->s_export_op; |
29 | struct path path = {.mnt = mnt, .dentry = dir}; | ||
30 | 30 | ||
31 | if (nop->get_name) | 31 | if (nop->get_name) |
32 | return nop->get_name(dir, name, child); | 32 | return nop->get_name(dir, name, child); |
33 | else | 33 | else |
34 | return get_name(mnt, dir, name, child); | 34 | return get_name(&path, name, child); |
35 | } | 35 | } |
36 | 36 | ||
37 | /* | 37 | /* |
@@ -249,11 +249,10 @@ static int filldir_one(void * __buf, const char * name, int len, | |||
249 | * calls readdir on the parent until it finds an entry with | 249 | * calls readdir on the parent until it finds an entry with |
250 | * the same inode number as the child, and returns that. | 250 | * the same inode number as the child, and returns that. |
251 | */ | 251 | */ |
252 | static int get_name(struct vfsmount *mnt, struct dentry *dentry, | 252 | static int get_name(const struct path *path, char *name, struct dentry *child) |
253 | char *name, struct dentry *child) | ||
254 | { | 253 | { |
255 | const struct cred *cred = current_cred(); | 254 | const struct cred *cred = current_cred(); |
256 | struct inode *dir = dentry->d_inode; | 255 | struct inode *dir = path->dentry->d_inode; |
257 | int error; | 256 | int error; |
258 | struct file *file; | 257 | struct file *file; |
259 | struct getdents_callback buffer; | 258 | struct getdents_callback buffer; |
@@ -267,7 +266,7 @@ static int get_name(struct vfsmount *mnt, struct dentry *dentry, | |||
267 | /* | 266 | /* |
268 | * Open the directory ... | 267 | * Open the directory ... |
269 | */ | 268 | */ |
270 | file = dentry_open(dget(dentry), mntget(mnt), O_RDONLY, cred); | 269 | file = dentry_open(path, O_RDONLY, cred); |
271 | error = PTR_ERR(file); | 270 | error = PTR_ERR(file); |
272 | if (IS_ERR(file)) | 271 | if (IS_ERR(file)) |
273 | goto out; | 272 | goto out; |
diff --git a/fs/hppfs/hppfs.c b/fs/hppfs/hppfs.c index e5c06531dcc4..c1dffe47fde2 100644 --- a/fs/hppfs/hppfs.c +++ b/fs/hppfs/hppfs.c | |||
@@ -420,8 +420,7 @@ static int hppfs_open(struct inode *inode, struct file *file) | |||
420 | { | 420 | { |
421 | const struct cred *cred = file->f_cred; | 421 | const struct cred *cred = file->f_cred; |
422 | struct hppfs_private *data; | 422 | struct hppfs_private *data; |
423 | struct vfsmount *proc_mnt; | 423 | struct path path; |
424 | struct dentry *proc_dentry; | ||
425 | char *host_file; | 424 | char *host_file; |
426 | int err, fd, type, filter; | 425 | int err, fd, type, filter; |
427 | 426 | ||
@@ -434,12 +433,11 @@ static int hppfs_open(struct inode *inode, struct file *file) | |||
434 | if (host_file == NULL) | 433 | if (host_file == NULL) |
435 | goto out_free2; | 434 | goto out_free2; |
436 | 435 | ||
437 | proc_dentry = HPPFS_I(inode)->proc_dentry; | 436 | path.mnt = inode->i_sb->s_fs_info; |
438 | proc_mnt = inode->i_sb->s_fs_info; | 437 | path.dentry = HPPFS_I(inode)->proc_dentry; |
439 | 438 | ||
440 | /* XXX This isn't closed anywhere */ | 439 | /* XXX This isn't closed anywhere */ |
441 | data->proc_file = dentry_open(dget(proc_dentry), mntget(proc_mnt), | 440 | data->proc_file = dentry_open(&path, file_mode(file->f_mode), cred); |
442 | file_mode(file->f_mode), cred); | ||
443 | err = PTR_ERR(data->proc_file); | 441 | err = PTR_ERR(data->proc_file); |
444 | if (IS_ERR(data->proc_file)) | 442 | if (IS_ERR(data->proc_file)) |
445 | goto out_free1; | 443 | goto out_free1; |
@@ -484,8 +482,7 @@ static int hppfs_dir_open(struct inode *inode, struct file *file) | |||
484 | { | 482 | { |
485 | const struct cred *cred = file->f_cred; | 483 | const struct cred *cred = file->f_cred; |
486 | struct hppfs_private *data; | 484 | struct hppfs_private *data; |
487 | struct vfsmount *proc_mnt; | 485 | struct path path; |
488 | struct dentry *proc_dentry; | ||
489 | int err; | 486 | int err; |
490 | 487 | ||
491 | err = -ENOMEM; | 488 | err = -ENOMEM; |
@@ -493,10 +490,9 @@ static int hppfs_dir_open(struct inode *inode, struct file *file) | |||
493 | if (data == NULL) | 490 | if (data == NULL) |
494 | goto out; | 491 | goto out; |
495 | 492 | ||
496 | proc_dentry = HPPFS_I(inode)->proc_dentry; | 493 | path.mnt = inode->i_sb->s_fs_info; |
497 | proc_mnt = inode->i_sb->s_fs_info; | 494 | path.dentry = HPPFS_I(inode)->proc_dentry; |
498 | data->proc_file = dentry_open(dget(proc_dentry), mntget(proc_mnt), | 495 | data->proc_file = dentry_open(&path, file_mode(file->f_mode), cred); |
499 | file_mode(file->f_mode), cred); | ||
500 | err = PTR_ERR(data->proc_file); | 496 | err = PTR_ERR(data->proc_file); |
501 | if (IS_ERR(data->proc_file)) | 497 | if (IS_ERR(data->proc_file)) |
502 | goto out_free; | 498 | goto out_free; |
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c index 05d9eee6be3a..4700a0a929d7 100644 --- a/fs/nfsd/vfs.c +++ b/fs/nfsd/vfs.c | |||
@@ -745,7 +745,7 @@ __be32 | |||
745 | nfsd_open(struct svc_rqst *rqstp, struct svc_fh *fhp, umode_t type, | 745 | nfsd_open(struct svc_rqst *rqstp, struct svc_fh *fhp, umode_t type, |
746 | int may_flags, struct file **filp) | 746 | int may_flags, struct file **filp) |
747 | { | 747 | { |
748 | struct dentry *dentry; | 748 | struct path path; |
749 | struct inode *inode; | 749 | struct inode *inode; |
750 | int flags = O_RDONLY|O_LARGEFILE; | 750 | int flags = O_RDONLY|O_LARGEFILE; |
751 | __be32 err; | 751 | __be32 err; |
@@ -762,8 +762,9 @@ nfsd_open(struct svc_rqst *rqstp, struct svc_fh *fhp, umode_t type, | |||
762 | if (err) | 762 | if (err) |
763 | goto out; | 763 | goto out; |
764 | 764 | ||
765 | dentry = fhp->fh_dentry; | 765 | path.mnt = fhp->fh_export->ex_path.mnt; |
766 | inode = dentry->d_inode; | 766 | path.dentry = fhp->fh_dentry; |
767 | inode = path.dentry->d_inode; | ||
767 | 768 | ||
768 | /* Disallow write access to files with the append-only bit set | 769 | /* Disallow write access to files with the append-only bit set |
769 | * or any access when mandatory locking enabled | 770 | * or any access when mandatory locking enabled |
@@ -792,8 +793,7 @@ nfsd_open(struct svc_rqst *rqstp, struct svc_fh *fhp, umode_t type, | |||
792 | else | 793 | else |
793 | flags = O_WRONLY|O_LARGEFILE; | 794 | flags = O_WRONLY|O_LARGEFILE; |
794 | } | 795 | } |
795 | *filp = dentry_open(dget(dentry), mntget(fhp->fh_export->ex_path.mnt), | 796 | *filp = dentry_open(&path, flags, current_cred()); |
796 | flags, current_cred()); | ||
797 | if (IS_ERR(*filp)) | 797 | if (IS_ERR(*filp)) |
798 | host_err = PTR_ERR(*filp); | 798 | host_err = PTR_ERR(*filp); |
799 | else { | 799 | else { |
diff --git a/fs/notify/fanotify/fanotify_user.c b/fs/notify/fanotify/fanotify_user.c index 3568c8a8b138..d43803669739 100644 --- a/fs/notify/fanotify/fanotify_user.c +++ b/fs/notify/fanotify/fanotify_user.c | |||
@@ -61,8 +61,6 @@ static struct fsnotify_event *get_one_event(struct fsnotify_group *group, | |||
61 | static int create_fd(struct fsnotify_group *group, struct fsnotify_event *event) | 61 | static int create_fd(struct fsnotify_group *group, struct fsnotify_event *event) |
62 | { | 62 | { |
63 | int client_fd; | 63 | int client_fd; |
64 | struct dentry *dentry; | ||
65 | struct vfsmount *mnt; | ||
66 | struct file *new_file; | 64 | struct file *new_file; |
67 | 65 | ||
68 | pr_debug("%s: group=%p event=%p\n", __func__, group, event); | 66 | pr_debug("%s: group=%p event=%p\n", __func__, group, event); |
@@ -81,12 +79,10 @@ static int create_fd(struct fsnotify_group *group, struct fsnotify_event *event) | |||
81 | * we need a new file handle for the userspace program so it can read even if it was | 79 | * we need a new file handle for the userspace program so it can read even if it was |
82 | * originally opened O_WRONLY. | 80 | * originally opened O_WRONLY. |
83 | */ | 81 | */ |
84 | dentry = dget(event->path.dentry); | ||
85 | mnt = mntget(event->path.mnt); | ||
86 | /* it's possible this event was an overflow event. in that case dentry and mnt | 82 | /* it's possible this event was an overflow event. in that case dentry and mnt |
87 | * are NULL; That's fine, just don't call dentry open */ | 83 | * are NULL; That's fine, just don't call dentry open */ |
88 | if (dentry && mnt) | 84 | if (event->path.dentry && event->path.mnt) |
89 | new_file = dentry_open(dentry, mnt, | 85 | new_file = dentry_open(&event->path, |
90 | group->fanotify_data.f_flags | FMODE_NONOTIFY, | 86 | group->fanotify_data.f_flags | FMODE_NONOTIFY, |
91 | current_cred()); | 87 | current_cred()); |
92 | else | 88 | else |
@@ -766,11 +766,7 @@ int finish_no_open(struct file *file, struct dentry *dentry) | |||
766 | } | 766 | } |
767 | EXPORT_SYMBOL(finish_no_open); | 767 | EXPORT_SYMBOL(finish_no_open); |
768 | 768 | ||
769 | /* | 769 | struct file *dentry_open(const struct path *path, int flags, |
770 | * dentry_open() will have done dput(dentry) and mntput(mnt) if it returns an | ||
771 | * error. | ||
772 | */ | ||
773 | struct file *dentry_open(struct dentry *dentry, struct vfsmount *mnt, int flags, | ||
774 | const struct cred *cred) | 770 | const struct cred *cred) |
775 | { | 771 | { |
776 | int error; | 772 | int error; |
@@ -779,19 +775,16 @@ struct file *dentry_open(struct dentry *dentry, struct vfsmount *mnt, int flags, | |||
779 | validate_creds(cred); | 775 | validate_creds(cred); |
780 | 776 | ||
781 | /* We must always pass in a valid mount pointer. */ | 777 | /* We must always pass in a valid mount pointer. */ |
782 | BUG_ON(!mnt); | 778 | BUG_ON(!path->mnt); |
783 | 779 | ||
784 | error = -ENFILE; | 780 | error = -ENFILE; |
785 | f = get_empty_filp(); | 781 | f = get_empty_filp(); |
786 | if (f == NULL) { | 782 | if (f == NULL) |
787 | dput(dentry); | ||
788 | mntput(mnt); | ||
789 | return ERR_PTR(error); | 783 | return ERR_PTR(error); |
790 | } | ||
791 | 784 | ||
792 | f->f_flags = flags; | 785 | f->f_flags = flags; |
793 | f->f_path.mnt = mnt; | 786 | f->f_path = *path; |
794 | f->f_path.dentry = dentry; | 787 | path_get(&f->f_path); |
795 | error = do_dentry_open(f, NULL, cred); | 788 | error = do_dentry_open(f, NULL, cred); |
796 | if (!error) { | 789 | if (!error) { |
797 | error = open_check_o_direct(f); | 790 | error = open_check_o_direct(f); |
diff --git a/fs/xfs/xfs_ioctl.c b/fs/xfs/xfs_ioctl.c index 3a05a41b5d76..1f1535d25a9b 100644 --- a/fs/xfs/xfs_ioctl.c +++ b/fs/xfs/xfs_ioctl.c | |||
@@ -208,6 +208,7 @@ xfs_open_by_handle( | |||
208 | struct inode *inode; | 208 | struct inode *inode; |
209 | struct dentry *dentry; | 209 | struct dentry *dentry; |
210 | fmode_t fmode; | 210 | fmode_t fmode; |
211 | struct path path; | ||
211 | 212 | ||
212 | if (!capable(CAP_SYS_ADMIN)) | 213 | if (!capable(CAP_SYS_ADMIN)) |
213 | return -XFS_ERROR(EPERM); | 214 | return -XFS_ERROR(EPERM); |
@@ -252,8 +253,10 @@ xfs_open_by_handle( | |||
252 | goto out_dput; | 253 | goto out_dput; |
253 | } | 254 | } |
254 | 255 | ||
255 | filp = dentry_open(dentry, mntget(parfilp->f_path.mnt), | 256 | path.mnt = parfilp->f_path.mnt; |
256 | hreq->oflags, cred); | 257 | path.dentry = dentry; |
258 | filp = dentry_open(&path, hreq->oflags, cred); | ||
259 | dput(dentry); | ||
257 | if (IS_ERR(filp)) { | 260 | if (IS_ERR(filp)) { |
258 | put_unused_fd(fd); | 261 | put_unused_fd(fd); |
259 | return PTR_ERR(filp); | 262 | return PTR_ERR(filp); |
diff --git a/include/linux/fs.h b/include/linux/fs.h index 34acf51273dd..8fabb037a48d 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h | |||
@@ -2060,8 +2060,7 @@ extern long do_sys_open(int dfd, const char __user *filename, int flags, | |||
2060 | extern struct file *filp_open(const char *, int, umode_t); | 2060 | extern struct file *filp_open(const char *, int, umode_t); |
2061 | extern struct file *file_open_root(struct dentry *, struct vfsmount *, | 2061 | extern struct file *file_open_root(struct dentry *, struct vfsmount *, |
2062 | const char *, int); | 2062 | const char *, int); |
2063 | extern struct file * dentry_open(struct dentry *, struct vfsmount *, int, | 2063 | extern struct file * dentry_open(const struct path *, int, const struct cred *); |
2064 | const struct cred *); | ||
2065 | extern int filp_close(struct file *, fl_owner_t id); | 2064 | extern int filp_close(struct file *, fl_owner_t id); |
2066 | extern char * getname(const char __user *); | 2065 | extern char * getname(const char __user *); |
2067 | enum { | 2066 | enum { |
diff --git a/ipc/mqueue.c b/ipc/mqueue.c index 2dee38d53c73..f8e54f5b9080 100644 --- a/ipc/mqueue.c +++ b/ipc/mqueue.c | |||
@@ -721,8 +721,8 @@ static int mq_attr_ok(struct ipc_namespace *ipc_ns, struct mq_attr *attr) | |||
721 | /* | 721 | /* |
722 | * Invoked when creating a new queue via sys_mq_open | 722 | * Invoked when creating a new queue via sys_mq_open |
723 | */ | 723 | */ |
724 | static struct file *do_create(struct ipc_namespace *ipc_ns, struct dentry *dir, | 724 | static struct file *do_create(struct ipc_namespace *ipc_ns, struct inode *dir, |
725 | struct dentry *dentry, int oflag, umode_t mode, | 725 | struct path *path, int oflag, umode_t mode, |
726 | struct mq_attr *attr) | 726 | struct mq_attr *attr) |
727 | { | 727 | { |
728 | const struct cred *cred = current_cred(); | 728 | const struct cred *cred = current_cred(); |
@@ -732,9 +732,9 @@ static struct file *do_create(struct ipc_namespace *ipc_ns, struct dentry *dir, | |||
732 | if (attr) { | 732 | if (attr) { |
733 | ret = mq_attr_ok(ipc_ns, attr); | 733 | ret = mq_attr_ok(ipc_ns, attr); |
734 | if (ret) | 734 | if (ret) |
735 | goto out; | 735 | return ERR_PTR(ret); |
736 | /* store for use during create */ | 736 | /* store for use during create */ |
737 | dentry->d_fsdata = attr; | 737 | path->dentry->d_fsdata = attr; |
738 | } else { | 738 | } else { |
739 | struct mq_attr def_attr; | 739 | struct mq_attr def_attr; |
740 | 740 | ||
@@ -744,71 +744,51 @@ static struct file *do_create(struct ipc_namespace *ipc_ns, struct dentry *dir, | |||
744 | ipc_ns->mq_msgsize_default); | 744 | ipc_ns->mq_msgsize_default); |
745 | ret = mq_attr_ok(ipc_ns, &def_attr); | 745 | ret = mq_attr_ok(ipc_ns, &def_attr); |
746 | if (ret) | 746 | if (ret) |
747 | goto out; | 747 | return ERR_PTR(ret); |
748 | } | 748 | } |
749 | 749 | ||
750 | mode &= ~current_umask(); | 750 | mode &= ~current_umask(); |
751 | ret = mnt_want_write(ipc_ns->mq_mnt); | 751 | ret = mnt_want_write(path->mnt); |
752 | if (ret) | 752 | if (ret) |
753 | goto out; | 753 | return ERR_PTR(ret); |
754 | ret = vfs_create(dir->d_inode, dentry, mode, true); | 754 | ret = vfs_create(dir, path->dentry, mode, true); |
755 | dentry->d_fsdata = NULL; | 755 | path->dentry->d_fsdata = NULL; |
756 | if (ret) | 756 | if (!ret) |
757 | goto out_drop_write; | 757 | result = dentry_open(path, oflag, cred); |
758 | 758 | else | |
759 | result = dentry_open(dentry, ipc_ns->mq_mnt, oflag, cred); | 759 | result = ERR_PTR(ret); |
760 | /* | 760 | /* |
761 | * dentry_open() took a persistent mnt_want_write(), | 761 | * dentry_open() took a persistent mnt_want_write(), |
762 | * so we can now drop this one. | 762 | * so we can now drop this one. |
763 | */ | 763 | */ |
764 | mnt_drop_write(ipc_ns->mq_mnt); | 764 | mnt_drop_write(path->mnt); |
765 | return result; | 765 | return result; |
766 | |||
767 | out_drop_write: | ||
768 | mnt_drop_write(ipc_ns->mq_mnt); | ||
769 | out: | ||
770 | dput(dentry); | ||
771 | mntput(ipc_ns->mq_mnt); | ||
772 | return ERR_PTR(ret); | ||
773 | } | 766 | } |
774 | 767 | ||
775 | /* Opens existing queue */ | 768 | /* Opens existing queue */ |
776 | static struct file *do_open(struct ipc_namespace *ipc_ns, | 769 | static struct file *do_open(struct path *path, int oflag) |
777 | struct dentry *dentry, int oflag) | ||
778 | { | 770 | { |
779 | int ret; | ||
780 | const struct cred *cred = current_cred(); | ||
781 | |||
782 | static const int oflag2acc[O_ACCMODE] = { MAY_READ, MAY_WRITE, | 771 | static const int oflag2acc[O_ACCMODE] = { MAY_READ, MAY_WRITE, |
783 | MAY_READ | MAY_WRITE }; | 772 | MAY_READ | MAY_WRITE }; |
784 | 773 | int acc; | |
785 | if ((oflag & O_ACCMODE) == (O_RDWR | O_WRONLY)) { | 774 | if ((oflag & O_ACCMODE) == (O_RDWR | O_WRONLY)) |
786 | ret = -EINVAL; | 775 | return ERR_PTR(-EINVAL); |
787 | goto err; | 776 | acc = oflag2acc[oflag & O_ACCMODE]; |
788 | } | 777 | if (inode_permission(path->dentry->d_inode, acc)) |
789 | 778 | return ERR_PTR(-EACCES); | |
790 | if (inode_permission(dentry->d_inode, oflag2acc[oflag & O_ACCMODE])) { | 779 | return dentry_open(path, oflag, current_cred()); |
791 | ret = -EACCES; | ||
792 | goto err; | ||
793 | } | ||
794 | |||
795 | return dentry_open(dentry, ipc_ns->mq_mnt, oflag, cred); | ||
796 | |||
797 | err: | ||
798 | dput(dentry); | ||
799 | mntput(ipc_ns->mq_mnt); | ||
800 | return ERR_PTR(ret); | ||
801 | } | 780 | } |
802 | 781 | ||
803 | SYSCALL_DEFINE4(mq_open, const char __user *, u_name, int, oflag, umode_t, mode, | 782 | SYSCALL_DEFINE4(mq_open, const char __user *, u_name, int, oflag, umode_t, mode, |
804 | struct mq_attr __user *, u_attr) | 783 | struct mq_attr __user *, u_attr) |
805 | { | 784 | { |
806 | struct dentry *dentry; | 785 | struct path path; |
807 | struct file *filp; | 786 | struct file *filp; |
808 | char *name; | 787 | char *name; |
809 | struct mq_attr attr; | 788 | struct mq_attr attr; |
810 | int fd, error; | 789 | int fd, error; |
811 | struct ipc_namespace *ipc_ns = current->nsproxy->ipc_ns; | 790 | struct ipc_namespace *ipc_ns = current->nsproxy->ipc_ns; |
791 | struct dentry *root = ipc_ns->mq_mnt->mnt_root; | ||
812 | 792 | ||
813 | if (u_attr && copy_from_user(&attr, u_attr, sizeof(struct mq_attr))) | 793 | if (u_attr && copy_from_user(&attr, u_attr, sizeof(struct mq_attr))) |
814 | return -EFAULT; | 794 | return -EFAULT; |
@@ -822,52 +802,49 @@ SYSCALL_DEFINE4(mq_open, const char __user *, u_name, int, oflag, umode_t, mode, | |||
822 | if (fd < 0) | 802 | if (fd < 0) |
823 | goto out_putname; | 803 | goto out_putname; |
824 | 804 | ||
825 | mutex_lock(&ipc_ns->mq_mnt->mnt_root->d_inode->i_mutex); | 805 | error = 0; |
826 | dentry = lookup_one_len(name, ipc_ns->mq_mnt->mnt_root, strlen(name)); | 806 | mutex_lock(&root->d_inode->i_mutex); |
827 | if (IS_ERR(dentry)) { | 807 | path.dentry = lookup_one_len(name, root, strlen(name)); |
828 | error = PTR_ERR(dentry); | 808 | if (IS_ERR(path.dentry)) { |
809 | error = PTR_ERR(path.dentry); | ||
829 | goto out_putfd; | 810 | goto out_putfd; |
830 | } | 811 | } |
831 | mntget(ipc_ns->mq_mnt); | 812 | path.mnt = mntget(ipc_ns->mq_mnt); |
832 | 813 | ||
833 | if (oflag & O_CREAT) { | 814 | if (oflag & O_CREAT) { |
834 | if (dentry->d_inode) { /* entry already exists */ | 815 | if (path.dentry->d_inode) { /* entry already exists */ |
835 | audit_inode(name, dentry); | 816 | audit_inode(name, path.dentry); |
836 | if (oflag & O_EXCL) { | 817 | if (oflag & O_EXCL) { |
837 | error = -EEXIST; | 818 | error = -EEXIST; |
838 | goto out; | 819 | goto out; |
839 | } | 820 | } |
840 | filp = do_open(ipc_ns, dentry, oflag); | 821 | filp = do_open(&path, oflag); |
841 | } else { | 822 | } else { |
842 | filp = do_create(ipc_ns, ipc_ns->mq_mnt->mnt_root, | 823 | filp = do_create(ipc_ns, root->d_inode, |
843 | dentry, oflag, mode, | 824 | &path, oflag, mode, |
844 | u_attr ? &attr : NULL); | 825 | u_attr ? &attr : NULL); |
845 | } | 826 | } |
846 | } else { | 827 | } else { |
847 | if (!dentry->d_inode) { | 828 | if (!path.dentry->d_inode) { |
848 | error = -ENOENT; | 829 | error = -ENOENT; |
849 | goto out; | 830 | goto out; |
850 | } | 831 | } |
851 | audit_inode(name, dentry); | 832 | audit_inode(name, path.dentry); |
852 | filp = do_open(ipc_ns, dentry, oflag); | 833 | filp = do_open(&path, oflag); |
853 | } | 834 | } |
854 | 835 | ||
855 | if (IS_ERR(filp)) { | 836 | if (!IS_ERR(filp)) |
837 | fd_install(fd, filp); | ||
838 | else | ||
856 | error = PTR_ERR(filp); | 839 | error = PTR_ERR(filp); |
857 | goto out_putfd; | ||
858 | } | ||
859 | |||
860 | fd_install(fd, filp); | ||
861 | goto out_upsem; | ||
862 | |||
863 | out: | 840 | out: |
864 | dput(dentry); | 841 | path_put(&path); |
865 | mntput(ipc_ns->mq_mnt); | ||
866 | out_putfd: | 842 | out_putfd: |
867 | put_unused_fd(fd); | 843 | if (error) { |
868 | fd = error; | 844 | put_unused_fd(fd); |
869 | out_upsem: | 845 | fd = error; |
870 | mutex_unlock(&ipc_ns->mq_mnt->mnt_root->d_inode->i_mutex); | 846 | } |
847 | mutex_unlock(&root->d_inode->i_mutex); | ||
871 | out_putname: | 848 | out_putname: |
872 | putname(name); | 849 | putname(name); |
873 | return fd; | 850 | return fd; |
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 372ec6502aa8..e423f5fe67fa 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c | |||
@@ -2157,8 +2157,7 @@ static inline void flush_unauthorized_files(const struct cred *cred, | |||
2157 | get_file(devnull); | 2157 | get_file(devnull); |
2158 | } else { | 2158 | } else { |
2159 | devnull = dentry_open( | 2159 | devnull = dentry_open( |
2160 | dget(selinux_null), | 2160 | &selinux_null, |
2161 | mntget(selinuxfs_mount), | ||
2162 | O_RDWR, cred); | 2161 | O_RDWR, cred); |
2163 | if (IS_ERR(devnull)) { | 2162 | if (IS_ERR(devnull)) { |
2164 | devnull = NULL; | 2163 | devnull = NULL; |
diff --git a/security/selinux/include/security.h b/security/selinux/include/security.h index dde2005407aa..6d3885165d14 100644 --- a/security/selinux/include/security.h +++ b/security/selinux/include/security.h | |||
@@ -221,7 +221,7 @@ extern void selinux_status_update_policyload(int seqno); | |||
221 | extern void selinux_complete_init(void); | 221 | extern void selinux_complete_init(void); |
222 | extern int selinux_disable(void); | 222 | extern int selinux_disable(void); |
223 | extern void exit_sel_fs(void); | 223 | extern void exit_sel_fs(void); |
224 | extern struct dentry *selinux_null; | 224 | extern struct path selinux_null; |
225 | extern struct vfsmount *selinuxfs_mount; | 225 | extern struct vfsmount *selinuxfs_mount; |
226 | extern void selnl_notify_setenforce(int val); | 226 | extern void selnl_notify_setenforce(int val); |
227 | extern void selnl_notify_policyload(u32 seqno); | 227 | extern void selnl_notify_policyload(u32 seqno); |
diff --git a/security/selinux/selinuxfs.c b/security/selinux/selinuxfs.c index 3ad290251288..298e695d6822 100644 --- a/security/selinux/selinuxfs.c +++ b/security/selinux/selinuxfs.c | |||
@@ -1297,7 +1297,7 @@ out: | |||
1297 | 1297 | ||
1298 | #define NULL_FILE_NAME "null" | 1298 | #define NULL_FILE_NAME "null" |
1299 | 1299 | ||
1300 | struct dentry *selinux_null; | 1300 | struct path selinux_null; |
1301 | 1301 | ||
1302 | static ssize_t sel_read_avc_cache_threshold(struct file *filp, char __user *buf, | 1302 | static ssize_t sel_read_avc_cache_threshold(struct file *filp, char __user *buf, |
1303 | size_t count, loff_t *ppos) | 1303 | size_t count, loff_t *ppos) |
@@ -1838,7 +1838,7 @@ static int sel_fill_super(struct super_block *sb, void *data, int silent) | |||
1838 | 1838 | ||
1839 | init_special_inode(inode, S_IFCHR | S_IRUGO | S_IWUGO, MKDEV(MEM_MAJOR, 3)); | 1839 | init_special_inode(inode, S_IFCHR | S_IRUGO | S_IWUGO, MKDEV(MEM_MAJOR, 3)); |
1840 | d_add(dentry, inode); | 1840 | d_add(dentry, inode); |
1841 | selinux_null = dentry; | 1841 | selinux_null.dentry = dentry; |
1842 | 1842 | ||
1843 | dentry = sel_make_dir(sb->s_root, "avc", &sel_last_ino); | 1843 | dentry = sel_make_dir(sb->s_root, "avc", &sel_last_ino); |
1844 | if (IS_ERR(dentry)) { | 1844 | if (IS_ERR(dentry)) { |
@@ -1912,7 +1912,7 @@ static int __init init_sel_fs(void) | |||
1912 | return err; | 1912 | return err; |
1913 | } | 1913 | } |
1914 | 1914 | ||
1915 | selinuxfs_mount = kern_mount(&sel_fs_type); | 1915 | selinux_null.mnt = selinuxfs_mount = kern_mount(&sel_fs_type); |
1916 | if (IS_ERR(selinuxfs_mount)) { | 1916 | if (IS_ERR(selinuxfs_mount)) { |
1917 | printk(KERN_ERR "selinuxfs: could not mount!\n"); | 1917 | printk(KERN_ERR "selinuxfs: could not mount!\n"); |
1918 | err = PTR_ERR(selinuxfs_mount); | 1918 | err = PTR_ERR(selinuxfs_mount); |