tmpfs_vfsops.c (269164) | tmpfs_vfsops.c (269175) |
---|---|
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 --- 27 unchanged lines hidden (view full) --- 36 * tmpfs is a file system that uses NetBSD's virtual memory sub-system 37 * (the well-known UVM) to store file data and metadata in an efficient 38 * way. This means that it does not follow the structure of an on-disk 39 * file system because it simply does not need to. Instead, it uses 40 * memory-specific data structures and algorithms to automatically 41 * allocate and release resources. 42 */ 43#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 --- 27 unchanged lines hidden (view full) --- 36 * tmpfs is a file system that uses NetBSD's virtual memory sub-system 37 * (the well-known UVM) to store file data and metadata in an efficient 38 * way. This means that it does not follow the structure of an on-disk 39 * file system because it simply does not need to. Instead, it uses 40 * memory-specific data structures and algorithms to automatically 41 * allocate and release resources. 42 */ 43#include <sys/cdefs.h> |
44__FBSDID("$FreeBSD: stable/10/sys/fs/tmpfs/tmpfs_vfsops.c 269164 2014-07-28 00:43:42Z kib $"); | 44__FBSDID("$FreeBSD: stable/10/sys/fs/tmpfs/tmpfs_vfsops.c 269175 2014-07-28 01:23:59Z kib $"); |
45 46#include <sys/param.h> 47#include <sys/limits.h> 48#include <sys/lock.h> 49#include <sys/mutex.h> 50#include <sys/proc.h> 51#include <sys/jail.h> 52#include <sys/kernel.h> --- 180 unchanged lines hidden (view full) --- 233 tmp->tm_node_pool = uma_zcreate("TMPFS node", 234 sizeof(struct tmpfs_node), 235 tmpfs_node_ctor, tmpfs_node_dtor, 236 tmpfs_node_init, tmpfs_node_fini, 237 UMA_ALIGN_PTR, 0); 238 tmp->tm_ronly = (mp->mnt_flag & MNT_RDONLY) != 0; 239 240 /* Allocate the root node. */ | 45 46#include <sys/param.h> 47#include <sys/limits.h> 48#include <sys/lock.h> 49#include <sys/mutex.h> 50#include <sys/proc.h> 51#include <sys/jail.h> 52#include <sys/kernel.h> --- 180 unchanged lines hidden (view full) --- 233 tmp->tm_node_pool = uma_zcreate("TMPFS node", 234 sizeof(struct tmpfs_node), 235 tmpfs_node_ctor, tmpfs_node_dtor, 236 tmpfs_node_init, tmpfs_node_fini, 237 UMA_ALIGN_PTR, 0); 238 tmp->tm_ronly = (mp->mnt_flag & MNT_RDONLY) != 0; 239 240 /* Allocate the root node. */ |
241 error = tmpfs_alloc_node(tmp, VDIR, root_uid, | 241 error = tmpfs_alloc_node(mp, tmp, VDIR, root_uid, |
242 root_gid, root_mode & ALLPERMS, NULL, NULL, 243 VNOVAL, &root); 244 245 if (error != 0 || root == NULL) { 246 uma_zdestroy(tmp->tm_node_pool); 247 uma_zdestroy(tmp->tm_dirent_pool); 248 delete_unrhdr(tmp->tm_ino_unr); 249 free(tmp, M_TMPFSMNT); --- 14 unchanged lines hidden (view full) --- 264 265 return 0; 266} 267 268/* ARGSUSED2 */ 269static int 270tmpfs_unmount(struct mount *mp, int mntflags) 271{ | 242 root_gid, root_mode & ALLPERMS, NULL, NULL, 243 VNOVAL, &root); 244 245 if (error != 0 || root == NULL) { 246 uma_zdestroy(tmp->tm_node_pool); 247 uma_zdestroy(tmp->tm_dirent_pool); 248 delete_unrhdr(tmp->tm_ino_unr); 249 free(tmp, M_TMPFSMNT); --- 14 unchanged lines hidden (view full) --- 264 265 return 0; 266} 267 268/* ARGSUSED2 */ 269static int 270tmpfs_unmount(struct mount *mp, int mntflags) 271{ |
272 int error; 273 int flags = 0; | |
274 struct tmpfs_mount *tmp; 275 struct tmpfs_node *node; | 272 struct tmpfs_mount *tmp; 273 struct tmpfs_node *node; |
274 int error, flags; |
|
276 | 275 |
277 /* Handle forced unmounts. */ 278 if (mntflags & MNT_FORCE) 279 flags |= FORCECLOSE; | 276 flags = (mntflags & MNT_FORCE) != 0 ? FORCECLOSE : 0; 277 tmp = VFS_TO_TMPFS(mp); |
280 | 278 |
281 /* Finalize all pending I/O. */ 282 error = vflush(mp, 0, flags, curthread); | 279 /* Stop writers */ 280 error = vfs_write_suspend_umnt(mp); |
283 if (error != 0) | 281 if (error != 0) |
284 return error; | 282 return (error); 283 /* 284 * At this point, nodes cannot be destroyed by any other 285 * thread because write suspension is started. 286 */ |
285 | 287 |
286 tmp = VFS_TO_TMPFS(mp); | 288 for (;;) { 289 error = vflush(mp, 0, flags, curthread); 290 if (error != 0) { 291 vfs_write_resume(mp, VR_START_WRITE); 292 return (error); 293 } 294 MNT_ILOCK(mp); 295 if (mp->mnt_nvnodelistsize == 0) { 296 MNT_IUNLOCK(mp); 297 break; 298 } 299 MNT_IUNLOCK(mp); 300 if ((mntflags & MNT_FORCE) == 0) { 301 vfs_write_resume(mp, VR_START_WRITE); 302 return (EBUSY); 303 } 304 } |
287 | 305 |
288 /* Free all associated data. The loop iterates over the linked list 289 * we have containing all used nodes. For each of them that is 290 * a directory, we free all its directory entries. Note that after 291 * freeing a node, it will automatically go to the available list, 292 * so we will later have to iterate over it to release its items. */ 293 node = LIST_FIRST(&tmp->tm_nodes_used); 294 while (node != NULL) { 295 struct tmpfs_node *next; 296 | 306 TMPFS_LOCK(tmp); 307 while ((node = LIST_FIRST(&tmp->tm_nodes_used)) != NULL) { 308 TMPFS_UNLOCK(tmp); |
297 if (node->tn_type == VDIR) 298 tmpfs_dir_destroy(tmp, node); | 309 if (node->tn_type == VDIR) 310 tmpfs_dir_destroy(tmp, node); |
299 300 next = LIST_NEXT(node, tn_entries); | |
301 tmpfs_free_node(tmp, node); | 311 tmpfs_free_node(tmp, node); |
302 node = next; | 312 TMPFS_LOCK(tmp); |
303 } | 313 } |
314 TMPFS_UNLOCK(tmp); |
|
304 305 uma_zdestroy(tmp->tm_dirent_pool); 306 uma_zdestroy(tmp->tm_node_pool); 307 delete_unrhdr(tmp->tm_ino_unr); 308 309 mtx_destroy(&tmp->allnode_lock); 310 MPASS(tmp->tm_pages_used == 0); 311 MPASS(tmp->tm_nodes_inuse == 0); 312 313 /* Throw away the tmpfs_mount structure. */ 314 free(mp->mnt_data, M_TMPFSMNT); 315 mp->mnt_data = NULL; | 315 316 uma_zdestroy(tmp->tm_dirent_pool); 317 uma_zdestroy(tmp->tm_node_pool); 318 delete_unrhdr(tmp->tm_ino_unr); 319 320 mtx_destroy(&tmp->allnode_lock); 321 MPASS(tmp->tm_pages_used == 0); 322 MPASS(tmp->tm_nodes_inuse == 0); 323 324 /* Throw away the tmpfs_mount structure. */ 325 free(mp->mnt_data, M_TMPFSMNT); 326 mp->mnt_data = NULL; |
327 vfs_write_resume(mp, VR_START_WRITE); |
|
316 317 MNT_ILOCK(mp); 318 mp->mnt_flag &= ~MNT_LOCAL; 319 MNT_IUNLOCK(mp); | 328 329 MNT_ILOCK(mp); 330 mp->mnt_flag &= ~MNT_LOCAL; 331 MNT_IUNLOCK(mp); |
320 return 0; | 332 333 return (0); |
321} 322 323static int 324tmpfs_root(struct mount *mp, int flags, struct vnode **vpp) 325{ 326 int error; 327 error = tmpfs_alloc_vp(mp, VFS_TO_TMPFS(mp)->tm_root, flags, vpp); 328 --- 67 unchanged lines hidden (view full) --- 396 sbp->f_ffree = 0; 397 else 398 sbp->f_ffree = sbp->f_files - used; 399 /* sbp->f_owner = tmp->tn_uid; */ 400 401 return 0; 402} 403 | 334} 335 336static int 337tmpfs_root(struct mount *mp, int flags, struct vnode **vpp) 338{ 339 int error; 340 error = tmpfs_alloc_vp(mp, VFS_TO_TMPFS(mp)->tm_root, flags, vpp); 341 --- 67 unchanged lines hidden (view full) --- 409 sbp->f_ffree = 0; 410 else 411 sbp->f_ffree = sbp->f_files - used; 412 /* sbp->f_owner = tmp->tn_uid; */ 413 414 return 0; 415} 416 |
417static int 418tmpfs_sync(struct mount *mp, int waitfor) 419{ 420 421 if (waitfor == MNT_SUSPEND) { 422 MNT_ILOCK(mp); 423 mp->mnt_kern_flag |= MNTK_SUSPEND2 | MNTK_SUSPENDED; 424 MNT_IUNLOCK(mp); 425 } 426 return (0); 427} 428 |
|
404/* 405 * tmpfs vfs operations. 406 */ 407 408struct vfsops tmpfs_vfsops = { 409 .vfs_mount = tmpfs_mount, 410 .vfs_unmount = tmpfs_unmount, 411 .vfs_root = tmpfs_root, 412 .vfs_statfs = tmpfs_statfs, 413 .vfs_fhtovp = tmpfs_fhtovp, | 429/* 430 * tmpfs vfs operations. 431 */ 432 433struct vfsops tmpfs_vfsops = { 434 .vfs_mount = tmpfs_mount, 435 .vfs_unmount = tmpfs_unmount, 436 .vfs_root = tmpfs_root, 437 .vfs_statfs = tmpfs_statfs, 438 .vfs_fhtovp = tmpfs_fhtovp, |
439 .vfs_sync = tmpfs_sync, |
|
414}; 415VFS_SET(tmpfs_vfsops, tmpfs, VFCF_JAIL); | 440}; 441VFS_SET(tmpfs_vfsops, tmpfs, VFCF_JAIL); |