aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2009-08-08 16:52:35 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2009-12-16 12:16:42 -0500
commit2c48b9c45579a9b5e3e74694eebf3d2451f3dbd3 (patch)
treececbf786ae0650368a8136bdd90910e05d9b95c3
parenta95161aaa801c18c52b2e7cf3d6b4b141c00a20a (diff)
switch alloc_file() to passing struct path
... and have the caller grab both mnt and dentry; kill leak in infiniband, while we are at it. Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
-rw-r--r--arch/ia64/kernel/perfmon.c15
-rw-r--r--drivers/infiniband/core/uverbs_main.c9
-rw-r--r--fs/anon_inodes.c18
-rw-r--r--fs/file_table.c13
-rw-r--r--fs/hugetlbfs/inode.c15
-rw-r--r--fs/notify/inotify/inotify_user.c8
-rw-r--r--fs/pipe.c17
-rw-r--r--include/linux/file.h5
-rw-r--r--ipc/shm.c10
-rw-r--r--mm/shmem.c14
-rw-r--r--net/socket.c17
11 files changed, 78 insertions, 63 deletions
diff --git a/arch/ia64/kernel/perfmon.c b/arch/ia64/kernel/perfmon.c
index 599b233bef75..5246285a95fb 100644
--- a/arch/ia64/kernel/perfmon.c
+++ b/arch/ia64/kernel/perfmon.c
@@ -2200,7 +2200,7 @@ pfm_alloc_file(pfm_context_t *ctx)
2200{ 2200{
2201 struct file *file; 2201 struct file *file;
2202 struct inode *inode; 2202 struct inode *inode;
2203 struct dentry *dentry; 2203 struct path path;
2204 char name[32]; 2204 char name[32];
2205 struct qstr this; 2205 struct qstr this;
2206 2206
@@ -2225,18 +2225,19 @@ pfm_alloc_file(pfm_context_t *ctx)
2225 /* 2225 /*
2226 * allocate a new dcache entry 2226 * allocate a new dcache entry
2227 */ 2227 */
2228 dentry = d_alloc(pfmfs_mnt->mnt_sb->s_root, &this); 2228 path.dentry = d_alloc(pfmfs_mnt->mnt_sb->s_root, &this);
2229 if (!dentry) { 2229 if (!path.dentry) {
2230 iput(inode); 2230 iput(inode);
2231 return ERR_PTR(-ENOMEM); 2231 return ERR_PTR(-ENOMEM);
2232 } 2232 }
2233 path.mnt = mntget(pfmfs_mnt);
2233 2234
2234 dentry->d_op = &pfmfs_dentry_operations; 2235 path.dentry->d_op = &pfmfs_dentry_operations;
2235 d_add(dentry, inode); 2236 d_add(path.dentry, inode);
2236 2237
2237 file = alloc_file(pfmfs_mnt, dentry, FMODE_READ, &pfm_file_ops); 2238 file = alloc_file(&path, FMODE_READ, &pfm_file_ops);
2238 if (!file) { 2239 if (!file) {
2239 dput(dentry); 2240 path_put(&path);
2240 return ERR_PTR(-ENFILE); 2241 return ERR_PTR(-ENFILE);
2241 } 2242 }
2242 2243
diff --git a/drivers/infiniband/core/uverbs_main.c b/drivers/infiniband/core/uverbs_main.c
index aec0fbdfe7f0..5f284ffd430e 100644
--- a/drivers/infiniband/core/uverbs_main.c
+++ b/drivers/infiniband/core/uverbs_main.c
@@ -492,6 +492,7 @@ struct file *ib_uverbs_alloc_event_file(struct ib_uverbs_file *uverbs_file,
492 int is_async, int *fd) 492 int is_async, int *fd)
493{ 493{
494 struct ib_uverbs_event_file *ev_file; 494 struct ib_uverbs_event_file *ev_file;
495 struct path path;
495 struct file *filp; 496 struct file *filp;
496 int ret; 497 int ret;
497 498
@@ -519,8 +520,10 @@ struct file *ib_uverbs_alloc_event_file(struct ib_uverbs_file *uverbs_file,
519 * system call on a uverbs file, which will already have a 520 * system call on a uverbs file, which will already have a
520 * module reference. 521 * module reference.
521 */ 522 */
522 filp = alloc_file(uverbs_event_mnt, dget(uverbs_event_mnt->mnt_root), 523 path.mnt = uverbs_event_mnt;
523 FMODE_READ, fops_get(&uverbs_event_fops)); 524 path.dentry = uverbs_event_mnt->mnt_root;
525 path_get(&path);
526 filp = alloc_file(&path, FMODE_READ, fops_get(&uverbs_event_fops));
524 if (!filp) { 527 if (!filp) {
525 ret = -ENFILE; 528 ret = -ENFILE;
526 goto err_fd; 529 goto err_fd;
@@ -531,6 +534,8 @@ struct file *ib_uverbs_alloc_event_file(struct ib_uverbs_file *uverbs_file,
531 return filp; 534 return filp;
532 535
533err_fd: 536err_fd:
537 fops_put(&uverbs_event_fops);
538 path_put(&path);
534 put_unused_fd(*fd); 539 put_unused_fd(*fd);
535 540
536err: 541err:
diff --git a/fs/anon_inodes.c b/fs/anon_inodes.c
index 2ca7a7cafdbf..94f5110c4655 100644
--- a/fs/anon_inodes.c
+++ b/fs/anon_inodes.c
@@ -88,7 +88,7 @@ struct file *anon_inode_getfile(const char *name,
88 void *priv, int flags) 88 void *priv, int flags)
89{ 89{
90 struct qstr this; 90 struct qstr this;
91 struct dentry *dentry; 91 struct path path;
92 struct file *file; 92 struct file *file;
93 int error; 93 int error;
94 94
@@ -106,10 +106,11 @@ struct file *anon_inode_getfile(const char *name,
106 this.name = name; 106 this.name = name;
107 this.len = strlen(name); 107 this.len = strlen(name);
108 this.hash = 0; 108 this.hash = 0;
109 dentry = d_alloc(anon_inode_mnt->mnt_sb->s_root, &this); 109 path.dentry = d_alloc(anon_inode_mnt->mnt_sb->s_root, &this);
110 if (!dentry) 110 if (!path.dentry)
111 goto err_module; 111 goto err_module;
112 112
113 path.mnt = mntget(anon_inode_mnt);
113 /* 114 /*
114 * We know the anon_inode inode count is always greater than zero, 115 * We know the anon_inode inode count is always greater than zero,
115 * so we can avoid doing an igrab() and we can use an open-coded 116 * so we can avoid doing an igrab() and we can use an open-coded
@@ -117,14 +118,13 @@ struct file *anon_inode_getfile(const char *name,
117 */ 118 */
118 atomic_inc(&anon_inode_inode->i_count); 119 atomic_inc(&anon_inode_inode->i_count);
119 120
120 dentry->d_op = &anon_inodefs_dentry_operations; 121 path.dentry->d_op = &anon_inodefs_dentry_operations;
121 /* Do not publish this dentry inside the global dentry hash table */ 122 /* Do not publish this dentry inside the global dentry hash table */
122 dentry->d_flags &= ~DCACHE_UNHASHED; 123 path.dentry->d_flags &= ~DCACHE_UNHASHED;
123 d_instantiate(dentry, anon_inode_inode); 124 d_instantiate(path.dentry, anon_inode_inode);
124 125
125 error = -ENFILE; 126 error = -ENFILE;
126 file = alloc_file(anon_inode_mnt, dentry, 127 file = alloc_file(&path, FMODE_READ | FMODE_WRITE, fops);
127 FMODE_READ | FMODE_WRITE, fops);
128 if (!file) 128 if (!file)
129 goto err_dput; 129 goto err_dput;
130 file->f_mapping = anon_inode_inode->i_mapping; 130 file->f_mapping = anon_inode_inode->i_mapping;
@@ -137,7 +137,7 @@ struct file *anon_inode_getfile(const char *name,
137 return file; 137 return file;
138 138
139err_dput: 139err_dput:
140 dput(dentry); 140 path_put(&path);
141err_module: 141err_module:
142 module_put(fops->owner); 142 module_put(fops->owner);
143 return ERR_PTR(error); 143 return ERR_PTR(error);
diff --git a/fs/file_table.c b/fs/file_table.c
index 602a9ee3023a..163cd28314e0 100644
--- a/fs/file_table.c
+++ b/fs/file_table.c
@@ -162,8 +162,8 @@ fail:
162 * If all the callers of init_file() are eliminated, its 162 * If all the callers of init_file() are eliminated, its
163 * code should be moved into this function. 163 * code should be moved into this function.
164 */ 164 */
165struct file *alloc_file(struct vfsmount *mnt, struct dentry *dentry, 165struct file *alloc_file(struct path *path, fmode_t mode,
166 fmode_t mode, const struct file_operations *fop) 166 const struct file_operations *fop)
167{ 167{
168 struct file *file; 168 struct file *file;
169 169
@@ -171,9 +171,8 @@ struct file *alloc_file(struct vfsmount *mnt, struct dentry *dentry,
171 if (!file) 171 if (!file)
172 return NULL; 172 return NULL;
173 173
174 file->f_path.dentry = dentry; 174 file->f_path = *path;
175 file->f_path.mnt = mntget(mnt); 175 file->f_mapping = path->dentry->d_inode->i_mapping;
176 file->f_mapping = dentry->d_inode->i_mapping;
177 file->f_mode = mode; 176 file->f_mode = mode;
178 file->f_op = fop; 177 file->f_op = fop;
179 178
@@ -183,10 +182,10 @@ struct file *alloc_file(struct vfsmount *mnt, struct dentry *dentry,
183 * visible. We do this for consistency, and so 182 * visible. We do this for consistency, and so
184 * that we can do debugging checks at __fput() 183 * that we can do debugging checks at __fput()
185 */ 184 */
186 if ((mode & FMODE_WRITE) && !special_file(dentry->d_inode->i_mode)) { 185 if ((mode & FMODE_WRITE) && !special_file(path->dentry->d_inode->i_mode)) {
187 int error = 0; 186 int error = 0;
188 file_take_write(file); 187 file_take_write(file);
189 error = mnt_clone_write(mnt); 188 error = mnt_clone_write(path->mnt);
190 WARN_ON(error); 189 WARN_ON(error);
191 } 190 }
192 return file; 191 return file;
diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c
index 87a1258953b8..6bd41525cd71 100644
--- a/fs/hugetlbfs/inode.c
+++ b/fs/hugetlbfs/inode.c
@@ -922,7 +922,8 @@ struct file *hugetlb_file_setup(const char *name, size_t size, int acctflag,
922 int error = -ENOMEM; 922 int error = -ENOMEM;
923 struct file *file; 923 struct file *file;
924 struct inode *inode; 924 struct inode *inode;
925 struct dentry *dentry, *root; 925 struct path path;
926 struct dentry *root;
926 struct qstr quick_string; 927 struct qstr quick_string;
927 928
928 *user = NULL; 929 *user = NULL;
@@ -944,10 +945,11 @@ struct file *hugetlb_file_setup(const char *name, size_t size, int acctflag,
944 quick_string.name = name; 945 quick_string.name = name;
945 quick_string.len = strlen(quick_string.name); 946 quick_string.len = strlen(quick_string.name);
946 quick_string.hash = 0; 947 quick_string.hash = 0;
947 dentry = d_alloc(root, &quick_string); 948 path.dentry = d_alloc(root, &quick_string);
948 if (!dentry) 949 if (!path.dentry)
949 goto out_shm_unlock; 950 goto out_shm_unlock;
950 951
952 path.mnt = mntget(hugetlbfs_vfsmount);
951 error = -ENOSPC; 953 error = -ENOSPC;
952 inode = hugetlbfs_get_inode(root->d_sb, current_fsuid(), 954 inode = hugetlbfs_get_inode(root->d_sb, current_fsuid(),
953 current_fsgid(), S_IFREG | S_IRWXUGO, 0); 955 current_fsgid(), S_IFREG | S_IRWXUGO, 0);
@@ -960,13 +962,12 @@ struct file *hugetlb_file_setup(const char *name, size_t size, int acctflag,
960 acctflag)) 962 acctflag))
961 goto out_inode; 963 goto out_inode;
962 964
963 d_instantiate(dentry, inode); 965 d_instantiate(path.dentry, inode);
964 inode->i_size = size; 966 inode->i_size = size;
965 inode->i_nlink = 0; 967 inode->i_nlink = 0;
966 968
967 error = -ENFILE; 969 error = -ENFILE;
968 file = alloc_file(hugetlbfs_vfsmount, dentry, 970 file = alloc_file(&path, FMODE_WRITE | FMODE_READ,
969 FMODE_WRITE | FMODE_READ,
970 &hugetlbfs_file_operations); 971 &hugetlbfs_file_operations);
971 if (!file) 972 if (!file)
972 goto out_dentry; /* inode is already attached */ 973 goto out_dentry; /* inode is already attached */
@@ -977,7 +978,7 @@ struct file *hugetlb_file_setup(const char *name, size_t size, int acctflag,
977out_inode: 978out_inode:
978 iput(inode); 979 iput(inode);
979out_dentry: 980out_dentry:
980 dput(dentry); 981 path_put(&path);
981out_shm_unlock: 982out_shm_unlock:
982 if (*user) { 983 if (*user) {
983 user_shm_unlock(size, *user); 984 user_shm_unlock(size, *user);
diff --git a/fs/notify/inotify/inotify_user.c b/fs/notify/inotify/inotify_user.c
index 9e4f90042eaf..8271cf05c957 100644
--- a/fs/notify/inotify/inotify_user.c
+++ b/fs/notify/inotify/inotify_user.c
@@ -646,6 +646,7 @@ SYSCALL_DEFINE1(inotify_init1, int, flags)
646 struct fsnotify_group *group; 646 struct fsnotify_group *group;
647 struct user_struct *user; 647 struct user_struct *user;
648 struct file *filp; 648 struct file *filp;
649 struct path path;
649 int fd, ret; 650 int fd, ret;
650 651
651 /* Check the IN_* constants for consistency. */ 652 /* Check the IN_* constants for consistency. */
@@ -675,8 +676,10 @@ SYSCALL_DEFINE1(inotify_init1, int, flags)
675 676
676 atomic_inc(&user->inotify_devs); 677 atomic_inc(&user->inotify_devs);
677 678
678 filp = alloc_file(inotify_mnt, dget(inotify_mnt->mnt_root), 679 path.mnt = inotify_mnt;
679 FMODE_READ, &inotify_fops); 680 path.dentry = inotify_mnt->mnt_root;
681 path_get(&path);
682 filp = alloc_file(&path, FMODE_READ, &inotify_fops);
680 if (!filp) 683 if (!filp)
681 goto Enfile; 684 goto Enfile;
682 685
@@ -689,6 +692,7 @@ SYSCALL_DEFINE1(inotify_init1, int, flags)
689 692
690Enfile: 693Enfile:
691 ret = -ENFILE; 694 ret = -ENFILE;
695 path_put(&path);
692 atomic_dec(&user->inotify_devs); 696 atomic_dec(&user->inotify_devs);
693out_free_uid: 697out_free_uid:
694 free_uid(user); 698 free_uid(user);
diff --git a/fs/pipe.c b/fs/pipe.c
index ae17d026aaa3..81288bc2bcbb 100644
--- a/fs/pipe.c
+++ b/fs/pipe.c
@@ -974,7 +974,7 @@ struct file *create_write_pipe(int flags)
974 int err; 974 int err;
975 struct inode *inode; 975 struct inode *inode;
976 struct file *f; 976 struct file *f;
977 struct dentry *dentry; 977 struct path path;
978 struct qstr name = { .name = "" }; 978 struct qstr name = { .name = "" };
979 979
980 err = -ENFILE; 980 err = -ENFILE;
@@ -983,21 +983,22 @@ struct file *create_write_pipe(int flags)
983 goto err; 983 goto err;
984 984
985 err = -ENOMEM; 985 err = -ENOMEM;
986 dentry = d_alloc(pipe_mnt->mnt_sb->s_root, &name); 986 path.dentry = d_alloc(pipe_mnt->mnt_sb->s_root, &name);
987 if (!dentry) 987 if (!path.dentry)
988 goto err_inode; 988 goto err_inode;
989 path.mnt = mntget(pipe_mnt);
989 990
990 dentry->d_op = &pipefs_dentry_operations; 991 path.dentry->d_op = &pipefs_dentry_operations;
991 /* 992 /*
992 * We dont want to publish this dentry into global dentry hash table. 993 * We dont want to publish this dentry into global dentry hash table.
993 * We pretend dentry is already hashed, by unsetting DCACHE_UNHASHED 994 * We pretend dentry is already hashed, by unsetting DCACHE_UNHASHED
994 * This permits a working /proc/$pid/fd/XXX on pipes 995 * This permits a working /proc/$pid/fd/XXX on pipes
995 */ 996 */
996 dentry->d_flags &= ~DCACHE_UNHASHED; 997 path.dentry->d_flags &= ~DCACHE_UNHASHED;
997 d_instantiate(dentry, inode); 998 d_instantiate(path.dentry, inode);
998 999
999 err = -ENFILE; 1000 err = -ENFILE;
1000 f = alloc_file(pipe_mnt, dentry, FMODE_WRITE, &write_pipefifo_fops); 1001 f = alloc_file(&path, FMODE_WRITE, &write_pipefifo_fops);
1001 if (!f) 1002 if (!f)
1002 goto err_dentry; 1003 goto err_dentry;
1003 f->f_mapping = inode->i_mapping; 1004 f->f_mapping = inode->i_mapping;
@@ -1009,7 +1010,7 @@ struct file *create_write_pipe(int flags)
1009 1010
1010 err_dentry: 1011 err_dentry:
1011 free_pipe_info(inode); 1012 free_pipe_info(inode);
1012 dput(dentry); 1013 path_put(&path);
1013 return ERR_PTR(err); 1014 return ERR_PTR(err);
1014 1015
1015 err_inode: 1016 err_inode:
diff --git a/include/linux/file.h b/include/linux/file.h
index 6a8d3612eb2a..5555508fd517 100644
--- a/include/linux/file.h
+++ b/include/linux/file.h
@@ -18,8 +18,9 @@ extern void drop_file_write_access(struct file *file);
18struct file_operations; 18struct file_operations;
19struct vfsmount; 19struct vfsmount;
20struct dentry; 20struct dentry;
21extern struct file *alloc_file(struct vfsmount *, struct dentry *dentry, 21struct path;
22 fmode_t mode, const struct file_operations *fop); 22extern struct file *alloc_file(struct path *, fmode_t mode,
23 const struct file_operations *fop);
23 24
24static inline void fput_light(struct file *file, int fput_needed) 25static inline void fput_light(struct file *file, int fput_needed)
25{ 26{
diff --git a/ipc/shm.c b/ipc/shm.c
index 11bec626c228..16e39230aa0d 100644
--- a/ipc/shm.c
+++ b/ipc/shm.c
@@ -878,8 +878,8 @@ long do_shmat(int shmid, char __user *shmaddr, int shmflg, ulong *raddr)
878 if (err) 878 if (err)
879 goto out_unlock; 879 goto out_unlock;
880 880
881 path.dentry = dget(shp->shm_file->f_path.dentry); 881 path = shp->shm_file->f_path;
882 path.mnt = shp->shm_file->f_path.mnt; 882 path_get(&path);
883 shp->shm_nattch++; 883 shp->shm_nattch++;
884 size = i_size_read(path.dentry->d_inode); 884 size = i_size_read(path.dentry->d_inode);
885 shm_unlock(shp); 885 shm_unlock(shp);
@@ -889,8 +889,8 @@ long do_shmat(int shmid, char __user *shmaddr, int shmflg, ulong *raddr)
889 if (!sfd) 889 if (!sfd)
890 goto out_put_dentry; 890 goto out_put_dentry;
891 891
892 file = alloc_file(path.mnt, path.dentry, f_mode, 892 file = alloc_file(&path, f_mode,
893 is_file_hugepages(shp->shm_file) ? 893 is_file_hugepages(shp->shm_file) ?
894 &shm_file_operations_huge : 894 &shm_file_operations_huge :
895 &shm_file_operations); 895 &shm_file_operations);
896 if (!file) 896 if (!file)
@@ -950,7 +950,7 @@ out_unlock:
950out_free: 950out_free:
951 kfree(sfd); 951 kfree(sfd);
952out_put_dentry: 952out_put_dentry:
953 dput(path.dentry); 953 path_put(&path);
954 goto out_nattch; 954 goto out_nattch;
955} 955}
956 956
diff --git a/mm/shmem.c b/mm/shmem.c
index ef8f47473c5a..d2ec7f029ff4 100644
--- a/mm/shmem.c
+++ b/mm/shmem.c
@@ -2626,7 +2626,8 @@ struct file *shmem_file_setup(const char *name, loff_t size, unsigned long flags
2626 int error; 2626 int error;
2627 struct file *file; 2627 struct file *file;
2628 struct inode *inode; 2628 struct inode *inode;
2629 struct dentry *dentry, *root; 2629 struct path path;
2630 struct dentry *root;
2630 struct qstr this; 2631 struct qstr this;
2631 2632
2632 if (IS_ERR(shm_mnt)) 2633 if (IS_ERR(shm_mnt))
@@ -2643,16 +2644,17 @@ struct file *shmem_file_setup(const char *name, loff_t size, unsigned long flags
2643 this.len = strlen(name); 2644 this.len = strlen(name);
2644 this.hash = 0; /* will go */ 2645 this.hash = 0; /* will go */
2645 root = shm_mnt->mnt_root; 2646 root = shm_mnt->mnt_root;
2646 dentry = d_alloc(root, &this); 2647 path.dentry = d_alloc(root, &this);
2647 if (!dentry) 2648 if (!path.dentry)
2648 goto put_memory; 2649 goto put_memory;
2650 path.mnt = mntget(shm_mnt);
2649 2651
2650 error = -ENOSPC; 2652 error = -ENOSPC;
2651 inode = shmem_get_inode(root->d_sb, S_IFREG | S_IRWXUGO, 0, flags); 2653 inode = shmem_get_inode(root->d_sb, S_IFREG | S_IRWXUGO, 0, flags);
2652 if (!inode) 2654 if (!inode)
2653 goto put_dentry; 2655 goto put_dentry;
2654 2656
2655 d_instantiate(dentry, inode); 2657 d_instantiate(path.dentry, inode);
2656 inode->i_size = size; 2658 inode->i_size = size;
2657 inode->i_nlink = 0; /* It is unlinked */ 2659 inode->i_nlink = 0; /* It is unlinked */
2658#ifndef CONFIG_MMU 2660#ifndef CONFIG_MMU
@@ -2662,7 +2664,7 @@ struct file *shmem_file_setup(const char *name, loff_t size, unsigned long flags
2662#endif 2664#endif
2663 2665
2664 error = -ENFILE; 2666 error = -ENFILE;
2665 file = alloc_file(shm_mnt, dentry, FMODE_WRITE | FMODE_READ, 2667 file = alloc_file(&path, FMODE_WRITE | FMODE_READ,
2666 &shmem_file_operations); 2668 &shmem_file_operations);
2667 if (!file) 2669 if (!file)
2668 goto put_dentry; 2670 goto put_dentry;
@@ -2671,7 +2673,7 @@ struct file *shmem_file_setup(const char *name, loff_t size, unsigned long flags
2671 return file; 2673 return file;
2672 2674
2673put_dentry: 2675put_dentry:
2674 dput(dentry); 2676 path_put(&path);
2675put_memory: 2677put_memory:
2676 shmem_unacct_size(flags, size); 2678 shmem_unacct_size(flags, size);
2677 return ERR_PTR(error); 2679 return ERR_PTR(error);
diff --git a/net/socket.c b/net/socket.c
index eaaba3510e81..dbfdfa96d29b 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -358,7 +358,7 @@ static const struct dentry_operations sockfs_dentry_operations = {
358static int sock_alloc_file(struct socket *sock, struct file **f, int flags) 358static int sock_alloc_file(struct socket *sock, struct file **f, int flags)
359{ 359{
360 struct qstr name = { .name = "" }; 360 struct qstr name = { .name = "" };
361 struct dentry *dentry; 361 struct path path;
362 struct file *file; 362 struct file *file;
363 int fd; 363 int fd;
364 364
@@ -366,28 +366,29 @@ static int sock_alloc_file(struct socket *sock, struct file **f, int flags)
366 if (unlikely(fd < 0)) 366 if (unlikely(fd < 0))
367 return fd; 367 return fd;
368 368
369 dentry = d_alloc(sock_mnt->mnt_sb->s_root, &name); 369 path.dentry = d_alloc(sock_mnt->mnt_sb->s_root, &name);
370 if (unlikely(!dentry)) { 370 if (unlikely(!path.dentry)) {
371 put_unused_fd(fd); 371 put_unused_fd(fd);
372 return -ENOMEM; 372 return -ENOMEM;
373 } 373 }
374 path.mnt = mntget(sock_mnt);
374 375
375 dentry->d_op = &sockfs_dentry_operations; 376 path.dentry->d_op = &sockfs_dentry_operations;
376 /* 377 /*
377 * We dont want to push this dentry into global dentry hash table. 378 * We dont want to push this dentry into global dentry hash table.
378 * We pretend dentry is already hashed, by unsetting DCACHE_UNHASHED 379 * We pretend dentry is already hashed, by unsetting DCACHE_UNHASHED
379 * This permits a working /proc/$pid/fd/XXX on sockets 380 * This permits a working /proc/$pid/fd/XXX on sockets
380 */ 381 */
381 dentry->d_flags &= ~DCACHE_UNHASHED; 382 path.dentry->d_flags &= ~DCACHE_UNHASHED;
382 d_instantiate(dentry, SOCK_INODE(sock)); 383 d_instantiate(path.dentry, SOCK_INODE(sock));
383 SOCK_INODE(sock)->i_fop = &socket_file_ops; 384 SOCK_INODE(sock)->i_fop = &socket_file_ops;
384 385
385 file = alloc_file(sock_mnt, dentry, FMODE_READ | FMODE_WRITE, 386 file = alloc_file(&path, FMODE_READ | FMODE_WRITE,
386 &socket_file_ops); 387 &socket_file_ops);
387 if (unlikely(!file)) { 388 if (unlikely(!file)) {
388 /* drop dentry, keep inode */ 389 /* drop dentry, keep inode */
389 atomic_inc(&path.dentry->d_inode->i_count); 390 atomic_inc(&path.dentry->d_inode->i_count);
390 dput(dentry); 391 path_put(&path);
391 put_unused_fd(fd); 392 put_unused_fd(fd);
392 return -ENFILE; 393 return -ENFILE;
393 } 394 }