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 --- |