aboutsummaryrefslogtreecommitdiffstats
path: root/fs
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 /fs
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>
Diffstat (limited to 'fs')
-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
5 files changed, 38 insertions, 33 deletions
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: