1235537Sgber/*- 2235537Sgber * Copyright (c) 2010-2012 Semihalf 3235537Sgber * Copyright (c) 2008, 2009 Reinoud Zandijk 4235537Sgber * All rights reserved. 5235537Sgber * 6235537Sgber * Redistribution and use in source and binary forms, with or without 7235537Sgber * modification, are permitted provided that the following conditions 8235537Sgber * are met: 9235537Sgber * 1. Redistributions of source code must retain the above copyright 10235537Sgber * notice, this list of conditions and the following disclaimer. 11235537Sgber * 2. Redistributions in binary form must reproduce the above copyright 12235537Sgber * notice, this list of conditions and the following disclaimer in the 13235537Sgber * documentation and/or other materials provided with the distribution. 14235537Sgber * 15235537Sgber * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 16235537Sgber * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 17235537Sgber * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 18235537Sgber * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 19235537Sgber * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 20235537Sgber * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 21235537Sgber * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 22235537Sgber * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23235537Sgber * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 24235537Sgber * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25235537Sgber * 26235537Sgber * From: NetBSD: nilfs.h,v 1.1 2009/07/18 16:31:42 reinoud 27235537Sgber * 28235537Sgber * $FreeBSD$ 29235537Sgber */ 30235537Sgber 31235537Sgber#ifndef _FS_NANDFS_NANDFS_H_ 32235537Sgber#define _FS_NANDFS_NANDFS_H_ 33235537Sgber 34235537Sgber#include <sys/param.h> 35235537Sgber#include <sys/proc.h> 36235537Sgber#include <sys/condvar.h> 37235537Sgber#include <sys/lock.h> 38235537Sgber#include <sys/mutex.h> 39235537Sgber 40235537Sgber#include <sys/queue.h> 41235537Sgber#include <sys/uio.h> 42235537Sgber#include <sys/mutex.h> 43235537Sgber 44235537Sgber#include <sys/disk.h> 45235537Sgber#include <sys/kthread.h> 46235537Sgber#include "nandfs_fs.h" 47235537Sgber 48235537SgberMALLOC_DECLARE(M_NANDFSTEMP); 49235537Sgber 50235537Sgber/* Debug categories */ 51235537Sgber#define NANDFS_DEBUG_VOLUMES 0x000001 52235537Sgber#define NANDFS_DEBUG_BLOCK 0x000004 53235537Sgber#define NANDFS_DEBUG_LOCKING 0x000008 54235537Sgber#define NANDFS_DEBUG_NODE 0x000010 55235537Sgber#define NANDFS_DEBUG_LOOKUP 0x000020 56235537Sgber#define NANDFS_DEBUG_READDIR 0x000040 57235537Sgber#define NANDFS_DEBUG_TRANSLATE 0x000080 58235537Sgber#define NANDFS_DEBUG_STRATEGY 0x000100 59235537Sgber#define NANDFS_DEBUG_READ 0x000200 60235537Sgber#define NANDFS_DEBUG_WRITE 0x000400 61235537Sgber#define NANDFS_DEBUG_IFILE 0x000800 62235537Sgber#define NANDFS_DEBUG_ATTR 0x001000 63235537Sgber#define NANDFS_DEBUG_EXTATTR 0x002000 64235537Sgber#define NANDFS_DEBUG_ALLOC 0x004000 65235537Sgber#define NANDFS_DEBUG_CPFILE 0x008000 66235537Sgber#define NANDFS_DEBUG_DIRHASH 0x010000 67235537Sgber#define NANDFS_DEBUG_NOTIMPL 0x020000 68235537Sgber#define NANDFS_DEBUG_SHEDULE 0x040000 69235537Sgber#define NANDFS_DEBUG_SEG 0x080000 70235537Sgber#define NANDFS_DEBUG_SYNC 0x100000 71235537Sgber#define NANDFS_DEBUG_PARANOIA 0x200000 72235537Sgber#define NANDFS_DEBUG_VNCALL 0x400000 73235537Sgber#define NANDFS_DEBUG_BUF 0x1000000 74235537Sgber#define NANDFS_DEBUG_BMAP 0x2000000 75235537Sgber#define NANDFS_DEBUG_DAT 0x4000000 76235537Sgber#define NANDFS_DEBUG_GENERIC 0x8000000 77235537Sgber#define NANDFS_DEBUG_CLEAN 0x10000000 78235537Sgber 79235537Sgberextern int nandfs_verbose; 80235537Sgber 81235537Sgber#define DPRINTF(name, arg) { \ 82235537Sgber if (nandfs_verbose & NANDFS_DEBUG_##name) {\ 83235537Sgber printf arg;\ 84235537Sgber };\ 85235537Sgber } 86235537Sgber#define DPRINTFIF(name, cond, arg) { \ 87235537Sgber if (nandfs_verbose & NANDFS_DEBUG_##name) { \ 88235537Sgber if (cond) printf arg;\ 89235537Sgber };\ 90235537Sgber } 91235537Sgber 92235537Sgber#define VFSTONANDFS(mp) ((struct nandfsmount *)((mp)->mnt_data)) 93235537Sgber#define VTON(vp) ((struct nandfs_node *)(vp)->v_data) 94235537Sgber#define NTOV(xp) ((xp)->nn_vnode) 95235537Sgber 96235537Sgberint nandfs_init(struct vfsconf *); 97235537Sgberint nandfs_uninit(struct vfsconf *); 98235537Sgber 99235537Sgberextern struct vop_vector nandfs_vnodeops; 100235537Sgberextern struct vop_vector nandfs_system_vnodeops; 101235537Sgber 102235537Sgberstruct nandfs_node; 103235537Sgber 104235537Sgber/* Structure and derivatives */ 105235537Sgberstruct nandfs_mdt { 106235537Sgber uint32_t entries_per_block; 107235537Sgber uint32_t entries_per_group; 108235537Sgber uint32_t blocks_per_group; 109235537Sgber uint32_t groups_per_desc_block; /* desc is super group */ 110235537Sgber uint32_t blocks_per_desc_block; /* desc is super group */ 111235537Sgber}; 112235537Sgber 113235537Sgberstruct nandfs_segment { 114235537Sgber LIST_ENTRY(nandfs_segment) seg_link; 115235537Sgber 116235537Sgber struct nandfs_device *fsdev; 117235537Sgber 118235537Sgber TAILQ_HEAD(, buf) segsum; 119235537Sgber TAILQ_HEAD(, buf) data; 120235537Sgber 121235537Sgber uint64_t seg_num; 122235537Sgber uint64_t seg_next; 123235537Sgber uint64_t start_block; 124235537Sgber uint32_t num_blocks; 125235537Sgber 126235537Sgber uint32_t nblocks; 127235537Sgber uint32_t nbinfos; 128235537Sgber uint32_t segsum_blocks; 129235537Sgber uint32_t segsum_bytes; 130235537Sgber uint32_t bytes_left; 131235537Sgber char *current_off; 132235537Sgber}; 133235537Sgber 134235537Sgberstruct nandfs_seginfo { 135235537Sgber LIST_HEAD( ,nandfs_segment) seg_list; 136235537Sgber struct nandfs_segment *curseg; 137235537Sgber struct nandfs_device *fsdev; 138235537Sgber uint32_t blocks; 139235537Sgber uint8_t reiterate; 140235537Sgber}; 141235537Sgber 142235537Sgber#define NANDFS_FSSTOR_FAILED 1 143235537Sgberstruct nandfs_fsarea { 144235537Sgber int offset; 145235537Sgber int flags; 146235537Sgber int last_used; 147235537Sgber}; 148235537Sgber 149235537Sgberextern int nandfs_cleaner_enable; 150235537Sgberextern int nandfs_cleaner_interval; 151235537Sgberextern int nandfs_cleaner_segments; 152235537Sgber 153235537Sgberstruct nandfs_device { 154235537Sgber struct vnode *nd_devvp; 155235537Sgber struct g_consumer *nd_gconsumer; 156235537Sgber 157235537Sgber struct thread *nd_syncer; 158235537Sgber struct thread *nd_cleaner; 159235537Sgber int nd_syncer_exit; 160235537Sgber int nd_cleaner_exit; 161235537Sgber 162235537Sgber int nd_is_nand; 163235537Sgber 164235537Sgber struct nandfs_fsarea nd_fsarea[NANDFS_NFSAREAS]; 165235537Sgber int nd_last_fsarea; 166235537Sgber 167235537Sgber STAILQ_HEAD(nandfs_mnts, nandfsmount) nd_mounts; 168235537Sgber SLIST_ENTRY(nandfs_device) nd_next_device; 169235537Sgber 170235537Sgber /* FS structures */ 171235537Sgber struct nandfs_fsdata nd_fsdata; 172235537Sgber struct nandfs_super_block nd_super; 173235537Sgber struct nandfs_segment_summary nd_last_segsum; 174235537Sgber struct nandfs_super_root nd_super_root; 175235537Sgber struct nandfs_node *nd_dat_node; 176235537Sgber struct nandfs_node *nd_cp_node; 177235537Sgber struct nandfs_node *nd_su_node; 178235537Sgber struct nandfs_node *nd_gc_node; 179235537Sgber 180235537Sgber struct nandfs_mdt nd_dat_mdt; 181235537Sgber struct nandfs_mdt nd_ifile_mdt; 182235537Sgber 183235537Sgber struct timespec nd_ts; 184235537Sgber 185235537Sgber /* Synchronization */ 186235537Sgber struct mtx nd_mutex; 187235537Sgber struct mtx nd_sync_mtx; 188235537Sgber struct cv nd_sync_cv; 189235537Sgber struct mtx nd_clean_mtx; 190235537Sgber struct cv nd_clean_cv; 191235537Sgber struct lock nd_seg_const; 192235537Sgber 193235537Sgber struct nandfs_seginfo *nd_seginfo; 194235537Sgber 195235537Sgber /* FS geometry */ 196235537Sgber uint64_t nd_devsize; 197235537Sgber uint64_t nd_maxfilesize; 198235537Sgber uint32_t nd_blocksize; 199235537Sgber uint32_t nd_erasesize; 200235537Sgber 201235537Sgber uint32_t nd_devblocksize; 202235537Sgber 203235537Sgber /* Segment usage */ 204235537Sgber uint64_t nd_clean_segs; 205235537Sgber uint64_t *nd_free_base; 206235537Sgber uint64_t nd_free_count; 207235537Sgber uint64_t nd_dirty_bufs; 208235537Sgber 209235537Sgber /* Running values */ 210235537Sgber uint64_t nd_seg_sequence; 211235537Sgber uint64_t nd_seg_num; 212235537Sgber uint64_t nd_next_seg_num; 213235537Sgber uint64_t nd_last_pseg; 214235537Sgber uint64_t nd_last_cno; 215235537Sgber uint64_t nd_last_ino; 216235537Sgber uint64_t nd_fakevblk; 217235537Sgber 218235537Sgber int nd_mount_state; 219235537Sgber int nd_refcnt; 220235537Sgber int nd_syncing; 221235537Sgber int nd_cleaning; 222235537Sgber}; 223235537Sgber 224235537Sgberextern SLIST_HEAD(_nandfs_devices, nandfs_device) nandfs_devices; 225235537Sgber 226235537Sgber#define NANDFS_FORCE_SYNCER 0x1 227235537Sgber#define NANDFS_UMOUNT 0x2 228235537Sgber 229235537Sgber#define SYNCER_UMOUNT 0x0 230235537Sgber#define SYNCER_VFS_SYNC 0x1 231235537Sgber#define SYNCER_BDFLUSH 0x2 232235537Sgber#define SYNCER_FFORCE 0x3 233235537Sgber#define SYNCER_FSYNC 0x4 234235537Sgber#define SYNCER_ROUPD 0x5 235235537Sgber 236235537Sgberstatic __inline int 237235537Sgbernandfs_writelockflags(struct nandfs_device *fsdev, int flags) 238235537Sgber{ 239235537Sgber int error = 0; 240235537Sgber 241235537Sgber if (lockstatus(&fsdev->nd_seg_const) != LK_EXCLUSIVE) 242235537Sgber error = lockmgr(&fsdev->nd_seg_const, flags | LK_SHARED, NULL); 243235537Sgber 244235537Sgber return (error); 245235537Sgber} 246235537Sgber 247235537Sgberstatic __inline void 248235537Sgbernandfs_writeunlock(struct nandfs_device *fsdev) 249235537Sgber{ 250235537Sgber 251235537Sgber if (lockstatus(&fsdev->nd_seg_const) != LK_EXCLUSIVE) 252235537Sgber lockmgr(&(fsdev)->nd_seg_const, LK_RELEASE, NULL); 253235537Sgber} 254235537Sgber 255235537Sgber#define NANDFS_WRITELOCKFLAGS(fsdev, flags) nandfs_writelockflags(fsdev, flags) 256235537Sgber 257235537Sgber#define NANDFS_WRITELOCK(fsdev) NANDFS_WRITELOCKFLAGS(fsdev, 0) 258235537Sgber 259235537Sgber#define NANDFS_WRITEUNLOCK(fsdev) nandfs_writeunlock(fsdev) 260235537Sgber 261235537Sgber#define NANDFS_WRITEASSERT(fsdev) lockmgr_assert(&(fsdev)->nd_seg_const, KA_LOCKED) 262235537Sgber 263235537Sgber/* Specific mountpoint; head or a checkpoint/snapshot */ 264235537Sgberstruct nandfsmount { 265235537Sgber STAILQ_ENTRY(nandfsmount) nm_next_mount; 266235537Sgber 267235537Sgber struct mount *nm_vfs_mountp; 268235537Sgber struct nandfs_device *nm_nandfsdev; 269235537Sgber struct nandfs_args nm_mount_args; 270235537Sgber struct nandfs_node *nm_ifile_node; 271235537Sgber 272235537Sgber uint8_t nm_flags; 273235537Sgber int8_t nm_ronly; 274235537Sgber}; 275235537Sgber 276235537Sgberstruct nandfs_node { 277235537Sgber struct vnode *nn_vnode; 278235537Sgber struct nandfsmount *nn_nmp; 279235537Sgber struct nandfs_device *nn_nandfsdev; 280235537Sgber struct lockf *nn_lockf; 281235537Sgber 282235537Sgber uint64_t nn_ino; 283235537Sgber struct nandfs_inode nn_inode; 284235537Sgber 285235537Sgber uint64_t nn_diroff; 286235537Sgber uint32_t nn_flags; 287235537Sgber}; 288235537Sgber 289235537Sgber#define IN_ACCESS 0x0001 /* Inode access time update request */ 290235537Sgber#define IN_CHANGE 0x0002 /* Inode change time update request */ 291235537Sgber#define IN_UPDATE 0x0004 /* Inode was written to; update mtime*/ 292235537Sgber#define IN_MODIFIED 0x0008 /* node has been modified */ 293235537Sgber#define IN_RENAME 0x0010 /* node is being renamed. */ 294235537Sgber 295235537Sgber/* File permissions. */ 296235537Sgber#define IEXEC 0000100 /* Executable. */ 297235537Sgber#define IWRITE 0000200 /* Writeable. */ 298235537Sgber#define IREAD 0000400 /* Readable. */ 299235537Sgber#define ISVTX 0001000 /* Sticky bit. */ 300235537Sgber#define ISGID 0002000 /* Set-gid. */ 301235537Sgber#define ISUID 0004000 /* Set-uid. */ 302235537Sgber 303235537Sgber#define PRINT_NODE_FLAGS \ 304235537Sgber "\10\1IN_ACCESS\2IN_CHANGE\3IN_UPDATE\4IN_MODIFIED\5IN_RENAME" 305235537Sgber 306235537Sgber#define NANDFS_GATHER(x) ((x)->b_flags |= B_00800000) 307235537Sgber#define NANDFS_UNGATHER(x) ((x)->b_flags &= ~B_00800000) 308235537Sgber#define NANDFS_ISGATHERED(x) ((x)->b_flags & B_00800000) 309235537Sgber 310235537Sgber#endif /* !_FS_NANDFS_NANDFS_H_ */ 311