Deleted Added
full compact
tmpfs_vfsops.c (171087) tmpfs_vfsops.c (171308)
1/* $NetBSD: tmpfs_vfsops.c,v 1.10 2005/12/11 12:24:29 christos Exp $ */
2
3/*
4 * Copyright (c) 2005 The NetBSD Foundation, Inc.
5 * All rights reserved.
6 *
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Julio M. Merino Vidal, developed as part of Google's Summer of Code

--- 34 unchanged lines hidden (view full) ---

43 * tmpfs is a file system that uses NetBSD's virtual memory sub-system
44 * (the well-known UVM) to store file data and metadata in an efficient
45 * way. This means that it does not follow the structure of an on-disk
46 * file system because it simply does not need to. Instead, it uses
47 * memory-specific data structures and algorithms to automatically
48 * allocate and release resources.
49 */
50#include <sys/cdefs.h>
1/* $NetBSD: tmpfs_vfsops.c,v 1.10 2005/12/11 12:24:29 christos Exp $ */
2
3/*
4 * Copyright (c) 2005 The NetBSD Foundation, Inc.
5 * All rights reserved.
6 *
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Julio M. Merino Vidal, developed as part of Google's Summer of Code

--- 34 unchanged lines hidden (view full) ---

43 * tmpfs is a file system that uses NetBSD's virtual memory sub-system
44 * (the well-known UVM) to store file data and metadata in an efficient
45 * way. This means that it does not follow the structure of an on-disk
46 * file system because it simply does not need to. Instead, it uses
47 * memory-specific data structures and algorithms to automatically
48 * allocate and release resources.
49 */
50#include <sys/cdefs.h>
51__FBSDID("$FreeBSD: head/sys/fs/tmpfs/tmpfs_vfsops.c 171087 2007-06-29 05:23:15Z delphij $");
51__FBSDID("$FreeBSD: head/sys/fs/tmpfs/tmpfs_vfsops.c 171308 2007-07-08 15:56:12Z delphij $");
52
53#include <sys/param.h>
52
53#include <sys/param.h>
54#include <sys/limits.h>
54#include <sys/lock.h>
55#include <sys/mutex.h>
56#include <sys/kernel.h>
57#include <sys/stat.h>
58#include <sys/systm.h>
59#include <sys/sysctl.h>
60
61#include <vm/vm.h>

--- 84 unchanged lines hidden (view full) ---

146 struct tmpfs_node *node = (struct tmpfs_node *)mem;
147
148 if (node->tn_id == 0) {
149 /* if this node structure first time used */
150 struct tmpfs_mount *tmp = (struct tmpfs_mount *)arg;
151 TMPFS_LOCK(tmp);
152 node->tn_id = tmp->tm_nodes_last++;
153 TMPFS_UNLOCK(tmp);
55#include <sys/lock.h>
56#include <sys/mutex.h>
57#include <sys/kernel.h>
58#include <sys/stat.h>
59#include <sys/systm.h>
60#include <sys/sysctl.h>
61
62#include <vm/vm.h>

--- 84 unchanged lines hidden (view full) ---

147 struct tmpfs_node *node = (struct tmpfs_node *)mem;
148
149 if (node->tn_id == 0) {
150 /* if this node structure first time used */
151 struct tmpfs_mount *tmp = (struct tmpfs_mount *)arg;
152 TMPFS_LOCK(tmp);
153 node->tn_id = tmp->tm_nodes_last++;
154 TMPFS_UNLOCK(tmp);
155 if (node->tn_id == INT_MAX)
156 panic("all avariable id is used.");
154 node->tn_gen = arc4random();
155 } else {
156 node->tn_gen++;
157 }
158
159 node->tn_size = 0;
160 node->tn_status = 0;
161 node->tn_flags = 0;

--- 28 unchanged lines hidden (view full) ---

190tmpfs_node_fini(void *mem, int size)
191{
192 struct tmpfs_node *node = (struct tmpfs_node *)mem;
193
194 mtx_destroy(&node->tn_interlock);
195}
196
197static int
157 node->tn_gen = arc4random();
158 } else {
159 node->tn_gen++;
160 }
161
162 node->tn_size = 0;
163 node->tn_status = 0;
164 node->tn_flags = 0;

--- 28 unchanged lines hidden (view full) ---

193tmpfs_node_fini(void *mem, int size)
194{
195 struct tmpfs_node *node = (struct tmpfs_node *)mem;
196
197 mtx_destroy(&node->tn_interlock);
198}
199
200static int
198tmpfs_mount(struct mount *mp, struct thread *l)
201tmpfs_mount(struct mount *mp, struct thread *td)
199{
202{
200 struct tmpfs_args args;
201 struct tmpfs_mount *tmp;
202 struct tmpfs_node *root;
203 size_t pages, mem_size;
204 ino_t nodes;
205 int error;
203 struct tmpfs_mount *tmp;
204 struct tmpfs_node *root;
205 size_t pages, mem_size;
206 ino_t nodes;
207 int error;
208 /* Size counters. */
209 ino_t nodes_max;
210 off_t size_max;
206
211
212 /* Root node attributes. */
213 uid_t root_uid;
214 gid_t root_gid;
215 mode_t root_mode;
216
217 struct vattr va;
218
207 if (vfs_filteropt(mp->mnt_optnew, tmpfs_opts))
208 return (EINVAL);
209
210 if (mp->mnt_flag & MNT_UPDATE) {
211 /* XXX: There is no support yet to update file system
212 * settings. Should be added. */
213
214 return EOPNOTSUPP;
215 }
216
219 if (vfs_filteropt(mp->mnt_optnew, tmpfs_opts))
220 return (EINVAL);
221
222 if (mp->mnt_flag & MNT_UPDATE) {
223 /* XXX: There is no support yet to update file system
224 * settings. Should be added. */
225
226 return EOPNOTSUPP;
227 }
228
217 if (vfs_scanopt(mp->mnt_optnew, "gid", "%d", &args.ta_root_gid) != 1)
218 args.ta_root_gid = 0;
219 if (vfs_scanopt(mp->mnt_optnew, "uid", "%d", &args.ta_root_uid) != 1)
220 args.ta_root_uid = 0;
221 if (vfs_scanopt(mp->mnt_optnew, "mode", "%o", &args.ta_root_mode) != 1)
222 args.ta_root_mode = TMPFS_DEFAULT_ROOT_MODE;
223 if(vfs_scanopt(mp->mnt_optnew, "inodes", "%d", &args.ta_nodes_max) != 1)
224 args.ta_nodes_max = 0;
229 vn_lock(mp->mnt_vnodecovered, LK_SHARED | LK_RETRY, td);
230 error = VOP_GETATTR(mp->mnt_vnodecovered, &va, mp->mnt_cred, td);
231 VOP_UNLOCK(mp->mnt_vnodecovered, 0, td);
232 if (error)
233 return (error);
225
234
235 if (mp->mnt_cred->cr_ruid != 0 ||
236 vfs_scanopt(mp->mnt_optnew, "gid", "%d", &root_gid) != 1)
237 root_gid = va.va_gid;
238 if (mp->mnt_cred->cr_ruid != 0 ||
239 vfs_scanopt(mp->mnt_optnew, "uid", "%d", &root_uid) != 1)
240 root_uid = va.va_uid;
241 if (mp->mnt_cred->cr_ruid != 0 ||
242 vfs_scanopt(mp->mnt_optnew, "mode", "%o", &root_mode) != 1)
243 root_mode = va.va_mode;
244 if(vfs_scanopt(mp->mnt_optnew, "inodes", "%d", &nodes_max) != 1)
245 nodes_max = 0;
246
226 if(vfs_scanopt(mp->mnt_optnew,
227 "size",
247 if(vfs_scanopt(mp->mnt_optnew,
248 "size",
228 "%qu", &args.ta_size_max) != 1)
229 args.ta_size_max = 0;
249 "%qu", &size_max) != 1)
250 size_max = 0;
230
231 /* Do not allow mounts if we do not have enough memory to preserve
232 * the minimum reserved pages. */
233 mem_size = cnt.v_free_count + cnt.v_inactive_count + get_swpgtotal();
234 mem_size -= mem_size > cnt.v_wire_count ? cnt.v_wire_count : mem_size;
235 if (mem_size < TMPFS_PAGES_RESERVED)
236 return ENOSPC;
237
238 /* Get the maximum number of memory pages this file system is
239 * allowed to use, based on the maximum size the user passed in
240 * the mount structure. A value of zero is treated as if the
241 * maximum available space was requested. */
251
252 /* Do not allow mounts if we do not have enough memory to preserve
253 * the minimum reserved pages. */
254 mem_size = cnt.v_free_count + cnt.v_inactive_count + get_swpgtotal();
255 mem_size -= mem_size > cnt.v_wire_count ? cnt.v_wire_count : mem_size;
256 if (mem_size < TMPFS_PAGES_RESERVED)
257 return ENOSPC;
258
259 /* Get the maximum number of memory pages this file system is
260 * allowed to use, based on the maximum size the user passed in
261 * the mount structure. A value of zero is treated as if the
262 * maximum available space was requested. */
242 if (args.ta_size_max < PAGE_SIZE || args.ta_size_max >= SIZE_MAX)
263 if (size_max < PAGE_SIZE || size_max >= SIZE_MAX)
243 pages = SIZE_MAX;
244 else
264 pages = SIZE_MAX;
265 else
245 pages = args.ta_size_max / PAGE_SIZE +
246 (args.ta_size_max % PAGE_SIZE == 0 ? 0 : 1);
266 pages = howmany(size_max, PAGE_SIZE);
247 MPASS(pages > 0);
248
267 MPASS(pages > 0);
268
249 if (args.ta_nodes_max <= 3)
269 if (nodes_max <= 3)
250 nodes = 3 + pages * PAGE_SIZE / 1024;
251 else
270 nodes = 3 + pages * PAGE_SIZE / 1024;
271 else
252 nodes = args.ta_nodes_max;
272 nodes = nodes_max;
253 MPASS(nodes >= 3);
254
255 /* Allocate the tmpfs mount structure and fill it. */
256 tmp = (struct tmpfs_mount *)malloc(sizeof(struct tmpfs_mount),
257 M_TMPFSMNT, M_WAITOK | M_ZERO);
258
259 mtx_init(&tmp->allnode_lock, "tmpfs allnode lock", NULL, MTX_DEF);
260 tmp->tm_nodes_max = nodes;

--- 11 unchanged lines hidden (view full) ---

272 UMA_ALIGN_PTR,
273 0);
274 tmp->tm_node_pool = uma_zcreate(
275 "TMPFS node",
276 sizeof(struct tmpfs_node),
277 tmpfs_node_ctor, tmpfs_node_dtor,
278 tmpfs_node_init, tmpfs_node_fini,
279 UMA_ALIGN_PTR,
273 MPASS(nodes >= 3);
274
275 /* Allocate the tmpfs mount structure and fill it. */
276 tmp = (struct tmpfs_mount *)malloc(sizeof(struct tmpfs_mount),
277 M_TMPFSMNT, M_WAITOK | M_ZERO);
278
279 mtx_init(&tmp->allnode_lock, "tmpfs allnode lock", NULL, MTX_DEF);
280 tmp->tm_nodes_max = nodes;

--- 11 unchanged lines hidden (view full) ---

292 UMA_ALIGN_PTR,
293 0);
294 tmp->tm_node_pool = uma_zcreate(
295 "TMPFS node",
296 sizeof(struct tmpfs_node),
297 tmpfs_node_ctor, tmpfs_node_dtor,
298 tmpfs_node_init, tmpfs_node_fini,
299 UMA_ALIGN_PTR,
280 UMA_ZONE_NOFREE);
300 0);
281
282 /* Allocate the root node. */
301
302 /* Allocate the root node. */
283 error = tmpfs_alloc_node(tmp, VDIR, args.ta_root_uid,
284 args.ta_root_gid, args.ta_root_mode & ALLPERMS, NULL, NULL,
285 VNOVAL, l, &root);
303 error = tmpfs_alloc_node(tmp, VDIR, root_uid,
304 root_gid, root_mode & ALLPERMS, NULL, NULL,
305 VNOVAL, td, &root);
286
287 if (error != 0 || root == NULL) {
288 uma_zdestroy(tmp->tm_node_pool);
289 uma_zdestroy(tmp->tm_dirent_pool);
290 free(tmp, M_TMPFSMNT);
291 return error;
292 }
293 tmp->tm_root = root;

--- 61 unchanged lines hidden (view full) ---

355 node = next;
356 }
357
358 uma_zdestroy(tmp->tm_dirent_pool);
359 uma_zdestroy(tmp->tm_node_pool);
360
361 mtx_destroy(&tmp->allnode_lock);
362 MPASS(tmp->tm_pages_used == 0);
306
307 if (error != 0 || root == NULL) {
308 uma_zdestroy(tmp->tm_node_pool);
309 uma_zdestroy(tmp->tm_dirent_pool);
310 free(tmp, M_TMPFSMNT);
311 return error;
312 }
313 tmp->tm_root = root;

--- 61 unchanged lines hidden (view full) ---

375 node = next;
376 }
377
378 uma_zdestroy(tmp->tm_dirent_pool);
379 uma_zdestroy(tmp->tm_node_pool);
380
381 mtx_destroy(&tmp->allnode_lock);
382 MPASS(tmp->tm_pages_used == 0);
383 MPASS(tmp->tm_nodes_inuse == 0);
363
364 /* Throw away the tmpfs_mount structure. */
365 free(mp->mnt_data, M_TMPFSMNT);
366 mp->mnt_data = NULL;
367
368 MNT_ILOCK(mp);
369 mp->mnt_flag &= ~MNT_LOCAL;
370 MNT_IUNLOCK(mp);

--- 92 unchanged lines hidden ---
384
385 /* Throw away the tmpfs_mount structure. */
386 free(mp->mnt_data, M_TMPFSMNT);
387 mp->mnt_data = NULL;
388
389 MNT_ILOCK(mp);
390 mp->mnt_flag &= ~MNT_LOCAL;
391 MNT_IUNLOCK(mp);

--- 92 unchanged lines hidden ---