aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/configfs/dir.c5
-rw-r--r--fs/file_table.c60
-rw-r--r--fs/hugetlbfs/inode.c22
-rw-r--r--include/linux/file.h9
-rw-r--r--ipc/shm.c13
-rw-r--r--mm/shmem.c7
-rw-r--r--mm/tiny-shmem.c19
-rw-r--r--net/socket.c18
8 files changed, 104 insertions, 49 deletions
diff --git a/fs/configfs/dir.c b/fs/configfs/dir.c
index 2f436d4f1d6d..50ed691098bc 100644
--- a/fs/configfs/dir.c
+++ b/fs/configfs/dir.c
@@ -142,7 +142,7 @@ static int init_dir(struct inode * inode)
142 return 0; 142 return 0;
143} 143}
144 144
145static int init_file(struct inode * inode) 145static int configfs_init_file(struct inode * inode)
146{ 146{
147 inode->i_size = PAGE_SIZE; 147 inode->i_size = PAGE_SIZE;
148 inode->i_fop = &configfs_file_operations; 148 inode->i_fop = &configfs_file_operations;
@@ -283,7 +283,8 @@ static int configfs_attach_attr(struct configfs_dirent * sd, struct dentry * den
283 283
284 dentry->d_fsdata = configfs_get(sd); 284 dentry->d_fsdata = configfs_get(sd);
285 sd->s_dentry = dentry; 285 sd->s_dentry = dentry;
286 error = configfs_create(dentry, (attr->ca_mode & S_IALLUGO) | S_IFREG, init_file); 286 error = configfs_create(dentry, (attr->ca_mode & S_IALLUGO) | S_IFREG,
287 configfs_init_file);
287 if (error) { 288 if (error) {
288 configfs_put(sd); 289 configfs_put(sd);
289 return error; 290 return error;
diff --git a/fs/file_table.c b/fs/file_table.c
index ce3f39a4798a..3176fefc92e1 100644
--- a/fs/file_table.c
+++ b/fs/file_table.c
@@ -137,6 +137,66 @@ fail:
137 137
138EXPORT_SYMBOL(get_empty_filp); 138EXPORT_SYMBOL(get_empty_filp);
139 139
140/**
141 * alloc_file - allocate and initialize a 'struct file'
142 * @mnt: the vfsmount on which the file will reside
143 * @dentry: the dentry representing the new file
144 * @mode: the mode with which the new file will be opened
145 * @fop: the 'struct file_operations' for the new file
146 *
147 * Use this instead of get_empty_filp() to get a new
148 * 'struct file'. Do so because of the same initialization
149 * pitfalls reasons listed for init_file(). This is a
150 * preferred interface to using init_file().
151 *
152 * If all the callers of init_file() are eliminated, its
153 * code should be moved into this function.
154 */
155struct file *alloc_file(struct vfsmount *mnt, struct dentry *dentry,
156 mode_t mode, const struct file_operations *fop)
157{
158 struct file *file;
159 struct path;
160
161 file = get_empty_filp();
162 if (!file)
163 return NULL;
164
165 init_file(file, mnt, dentry, mode, fop);
166 return file;
167}
168EXPORT_SYMBOL(alloc_file);
169
170/**
171 * init_file - initialize a 'struct file'
172 * @file: the already allocated 'struct file' to initialized
173 * @mnt: the vfsmount on which the file resides
174 * @dentry: the dentry representing this file
175 * @mode: the mode the file is opened with
176 * @fop: the 'struct file_operations' for this file
177 *
178 * Use this instead of setting the members directly. Doing so
179 * avoids making mistakes like forgetting the mntget() or
180 * forgetting to take a write on the mnt.
181 *
182 * Note: This is a crappy interface. It is here to make
183 * merging with the existing users of get_empty_filp()
184 * who have complex failure logic easier. All users
185 * of this should be moving to alloc_file().
186 */
187int init_file(struct file *file, struct vfsmount *mnt, struct dentry *dentry,
188 mode_t mode, const struct file_operations *fop)
189{
190 int error = 0;
191 file->f_path.dentry = dentry;
192 file->f_path.mnt = mntget(mnt);
193 file->f_mapping = dentry->d_inode->i_mapping;
194 file->f_mode = mode;
195 file->f_op = fop;
196 return error;
197}
198EXPORT_SYMBOL(init_file);
199
140void fastcall fput(struct file *file) 200void fastcall fput(struct file *file)
141{ 201{
142 if (atomic_dec_and_test(&file->f_count)) 202 if (atomic_dec_and_test(&file->f_count))
diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c
index 0f5df73dbb73..12aca8ed605f 100644
--- a/fs/hugetlbfs/inode.c
+++ b/fs/hugetlbfs/inode.c
@@ -933,16 +933,11 @@ struct file *hugetlb_file_setup(const char *name, size_t size)
933 if (!dentry) 933 if (!dentry)
934 goto out_shm_unlock; 934 goto out_shm_unlock;
935 935
936 error = -ENFILE;
937 file = get_empty_filp();
938 if (!file)
939 goto out_dentry;
940
941 error = -ENOSPC; 936 error = -ENOSPC;
942 inode = hugetlbfs_get_inode(root->d_sb, current->fsuid, 937 inode = hugetlbfs_get_inode(root->d_sb, current->fsuid,
943 current->fsgid, S_IFREG | S_IRWXUGO, 0); 938 current->fsgid, S_IFREG | S_IRWXUGO, 0);
944 if (!inode) 939 if (!inode)
945 goto out_file; 940 goto out_dentry;
946 941
947 error = -ENOMEM; 942 error = -ENOMEM;
948 if (hugetlb_reserve_pages(inode, 0, size >> HPAGE_SHIFT)) 943 if (hugetlb_reserve_pages(inode, 0, size >> HPAGE_SHIFT))
@@ -951,17 +946,18 @@ struct file *hugetlb_file_setup(const char *name, size_t size)
951 d_instantiate(dentry, inode); 946 d_instantiate(dentry, inode);
952 inode->i_size = size; 947 inode->i_size = size;
953 inode->i_nlink = 0; 948 inode->i_nlink = 0;
954 file->f_path.mnt = mntget(hugetlbfs_vfsmount); 949
955 file->f_path.dentry = dentry; 950 error = -ENFILE;
956 file->f_mapping = inode->i_mapping; 951 file = alloc_file(hugetlbfs_vfsmount, dentry,
957 file->f_op = &hugetlbfs_file_operations; 952 FMODE_WRITE | FMODE_READ,
958 file->f_mode = FMODE_WRITE | FMODE_READ; 953 &hugetlbfs_file_operations);
954 if (!file)
955 goto out_inode;
956
959 return file; 957 return file;
960 958
961out_inode: 959out_inode:
962 iput(inode); 960 iput(inode);
963out_file:
964 put_filp(file);
965out_dentry: 961out_dentry:
966 dput(dentry); 962 dput(dentry);
967out_shm_unlock: 963out_shm_unlock:
diff --git a/include/linux/file.h b/include/linux/file.h
index 0114fbc78061..56023c74e9fd 100644
--- a/include/linux/file.h
+++ b/include/linux/file.h
@@ -62,6 +62,15 @@ extern struct kmem_cache *filp_cachep;
62extern void FASTCALL(__fput(struct file *)); 62extern void FASTCALL(__fput(struct file *));
63extern void FASTCALL(fput(struct file *)); 63extern void FASTCALL(fput(struct file *));
64 64
65struct file_operations;
66struct vfsmount;
67struct dentry;
68extern int init_file(struct file *, struct vfsmount *mnt,
69 struct dentry *dentry, mode_t mode,
70 const struct file_operations *fop);
71extern struct file *alloc_file(struct vfsmount *, struct dentry *dentry,
72 mode_t mode, const struct file_operations *fop);
73
65static inline void fput_light(struct file *file, int fput_needed) 74static inline void fput_light(struct file *file, int fput_needed)
66{ 75{
67 if (unlikely(fput_needed)) 76 if (unlikely(fput_needed))
diff --git a/ipc/shm.c b/ipc/shm.c
index b8884c288ecc..5fc5cf50cf1b 100644
--- a/ipc/shm.c
+++ b/ipc/shm.c
@@ -907,7 +907,7 @@ long do_shmat(int shmid, char __user *shmaddr, int shmflg, ulong *raddr)
907 goto out_unlock; 907 goto out_unlock;
908 908
909 path.dentry = dget(shp->shm_file->f_path.dentry); 909 path.dentry = dget(shp->shm_file->f_path.dentry);
910 path.mnt = mntget(shp->shm_file->f_path.mnt); 910 path.mnt = shp->shm_file->f_path.mnt;
911 shp->shm_nattch++; 911 shp->shm_nattch++;
912 size = i_size_read(path.dentry->d_inode); 912 size = i_size_read(path.dentry->d_inode);
913 shm_unlock(shp); 913 shm_unlock(shp);
@@ -915,18 +915,16 @@ long do_shmat(int shmid, char __user *shmaddr, int shmflg, ulong *raddr)
915 err = -ENOMEM; 915 err = -ENOMEM;
916 sfd = kzalloc(sizeof(*sfd), GFP_KERNEL); 916 sfd = kzalloc(sizeof(*sfd), GFP_KERNEL);
917 if (!sfd) 917 if (!sfd)
918 goto out_put_path; 918 goto out_put_dentry;
919 919
920 err = -ENOMEM; 920 err = -ENOMEM;
921 file = get_empty_filp(); 921
922 file = alloc_file(path.mnt, path.dentry, f_mode, &shm_file_operations);
922 if (!file) 923 if (!file)
923 goto out_free; 924 goto out_free;
924 925
925 file->f_op = &shm_file_operations;
926 file->private_data = sfd; 926 file->private_data = sfd;
927 file->f_path = path;
928 file->f_mapping = shp->shm_file->f_mapping; 927 file->f_mapping = shp->shm_file->f_mapping;
929 file->f_mode = f_mode;
930 sfd->id = shp->id; 928 sfd->id = shp->id;
931 sfd->ns = get_ipc_ns(ns); 929 sfd->ns = get_ipc_ns(ns);
932 sfd->file = shp->shm_file; 930 sfd->file = shp->shm_file;
@@ -977,9 +975,8 @@ out_unlock:
977 975
978out_free: 976out_free:
979 kfree(sfd); 977 kfree(sfd);
980out_put_path: 978out_put_dentry:
981 dput(path.dentry); 979 dput(path.dentry);
982 mntput(path.mnt);
983 goto out_nattch; 980 goto out_nattch;
984} 981}
985 982
diff --git a/mm/shmem.c b/mm/shmem.c
index 6fa20a84daa0..289dbb0a6fd6 100644
--- a/mm/shmem.c
+++ b/mm/shmem.c
@@ -2543,11 +2543,8 @@ struct file *shmem_file_setup(char *name, loff_t size, unsigned long flags)
2543 d_instantiate(dentry, inode); 2543 d_instantiate(dentry, inode);
2544 inode->i_size = size; 2544 inode->i_size = size;
2545 inode->i_nlink = 0; /* It is unlinked */ 2545 inode->i_nlink = 0; /* It is unlinked */
2546 file->f_path.mnt = mntget(shm_mnt); 2546 init_file(file, shm_mnt, dentry, FMODE_WRITE | FMODE_READ,
2547 file->f_path.dentry = dentry; 2547 &shmem_file_operations);
2548 file->f_mapping = inode->i_mapping;
2549 file->f_op = &shmem_file_operations;
2550 file->f_mode = FMODE_WRITE | FMODE_READ;
2551 return file; 2548 return file;
2552 2549
2553close_file: 2550close_file:
diff --git a/mm/tiny-shmem.c b/mm/tiny-shmem.c
index 8803471593fd..d436a9c82db7 100644
--- a/mm/tiny-shmem.c
+++ b/mm/tiny-shmem.c
@@ -66,24 +66,19 @@ struct file *shmem_file_setup(char *name, loff_t size, unsigned long flags)
66 if (!dentry) 66 if (!dentry)
67 goto put_memory; 67 goto put_memory;
68 68
69 error = -ENFILE;
70 file = get_empty_filp();
71 if (!file)
72 goto put_dentry;
73
74 error = -ENOSPC; 69 error = -ENOSPC;
75 inode = ramfs_get_inode(root->d_sb, S_IFREG | S_IRWXUGO, 0); 70 inode = ramfs_get_inode(root->d_sb, S_IFREG | S_IRWXUGO, 0);
76 if (!inode) 71 if (!inode)
77 goto close_file; 72 goto put_dentry;
78 73
79 d_instantiate(dentry, inode); 74 d_instantiate(dentry, inode);
80 inode->i_nlink = 0; /* It is unlinked */ 75 error = -ENFILE;
76 file = alloc_file(shm_mnt, dentry, FMODE_WRITE | FMODE_READ,
77 &ramfs_file_operations);
78 if (!file)
79 goto put_dentry;
81 80
82 file->f_path.mnt = mntget(shm_mnt); 81 inode->i_nlink = 0; /* It is unlinked */
83 file->f_path.dentry = dentry;
84 file->f_mapping = inode->i_mapping;
85 file->f_op = &ramfs_file_operations;
86 file->f_mode = FMODE_WRITE | FMODE_READ;
87 82
88 /* notify everyone as to the change of file size */ 83 /* notify everyone as to the change of file size */
89 error = do_truncate(dentry, size, 0, file); 84 error = do_truncate(dentry, size, 0, file);
diff --git a/net/socket.c b/net/socket.c
index 3cd96fe8191d..540013ea8620 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -364,26 +364,26 @@ static int sock_alloc_fd(struct file **filep)
364 364
365static int sock_attach_fd(struct socket *sock, struct file *file) 365static int sock_attach_fd(struct socket *sock, struct file *file)
366{ 366{
367 struct dentry *dentry;
367 struct qstr name = { .name = "" }; 368 struct qstr name = { .name = "" };
368 369
369 file->f_path.dentry = d_alloc(sock_mnt->mnt_sb->s_root, &name); 370 dentry = d_alloc(sock_mnt->mnt_sb->s_root, &name);
370 if (unlikely(!file->f_path.dentry)) 371 if (unlikely(!dentry))
371 return -ENOMEM; 372 return -ENOMEM;
372 373
373 file->f_path.dentry->d_op = &sockfs_dentry_operations; 374 dentry->d_op = &sockfs_dentry_operations;
374 /* 375 /*
375 * We dont want to push this dentry into global dentry hash table. 376 * We dont want to push this dentry into global dentry hash table.
376 * We pretend dentry is already hashed, by unsetting DCACHE_UNHASHED 377 * We pretend dentry is already hashed, by unsetting DCACHE_UNHASHED
377 * This permits a working /proc/$pid/fd/XXX on sockets 378 * This permits a working /proc/$pid/fd/XXX on sockets
378 */ 379 */
379 file->f_path.dentry->d_flags &= ~DCACHE_UNHASHED; 380 dentry->d_flags &= ~DCACHE_UNHASHED;
380 d_instantiate(file->f_path.dentry, SOCK_INODE(sock)); 381 d_instantiate(dentry, SOCK_INODE(sock));
381 file->f_path.mnt = mntget(sock_mnt);
382 file->f_mapping = file->f_path.dentry->d_inode->i_mapping;
383 382
384 sock->file = file; 383 sock->file = file;
385 file->f_op = SOCK_INODE(sock)->i_fop = &socket_file_ops; 384 init_file(file, sock_mnt, dentry, FMODE_READ | FMODE_WRITE,
386 file->f_mode = FMODE_READ | FMODE_WRITE; 385 &socket_file_ops);
386 SOCK_INODE(sock)->i_fop = &socket_file_ops;
387 file->f_flags = O_RDWR; 387 file->f_flags = O_RDWR;
388 file->f_pos = 0; 388 file->f_pos = 0;
389 file->private_data = sock; 389 file->private_data = sock;