1/*- 2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD 3 * 4 * Copyright (c) 2010-2012 Semihalf 5 * Copyright (c) 2008, 2009 Reinoud Zandijk 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 * 28 * From: NetBSD: nilfs.h,v 1.1 2009/07/18 16:31:42 reinoud 29 * 30 * $FreeBSD$ 31 */ 32 33#ifndef _FS_NANDFS_NANDFS_H_ 34#define _FS_NANDFS_NANDFS_H_ 35 36#include <sys/param.h> 37#include <sys/proc.h> 38#include <sys/condvar.h> 39#include <sys/lock.h> 40#include <sys/mutex.h> 41 42#include <sys/queue.h> 43#include <sys/uio.h> 44#include <sys/mutex.h> 45 46#include <sys/disk.h> 47#include <sys/kthread.h> 48#include "nandfs_fs.h" 49 50MALLOC_DECLARE(M_NANDFSTEMP); 51 52/* Debug categories */ 53#define NANDFS_DEBUG_VOLUMES 0x000001 54#define NANDFS_DEBUG_BLOCK 0x000004 55#define NANDFS_DEBUG_LOCKING 0x000008 56#define NANDFS_DEBUG_NODE 0x000010 57#define NANDFS_DEBUG_LOOKUP 0x000020 58#define NANDFS_DEBUG_READDIR 0x000040 59#define NANDFS_DEBUG_TRANSLATE 0x000080 60#define NANDFS_DEBUG_STRATEGY 0x000100 61#define NANDFS_DEBUG_READ 0x000200 62#define NANDFS_DEBUG_WRITE 0x000400 63#define NANDFS_DEBUG_IFILE 0x000800 64#define NANDFS_DEBUG_ATTR 0x001000 65#define NANDFS_DEBUG_EXTATTR 0x002000 66#define NANDFS_DEBUG_ALLOC 0x004000 67#define NANDFS_DEBUG_CPFILE 0x008000 68#define NANDFS_DEBUG_DIRHASH 0x010000 69#define NANDFS_DEBUG_NOTIMPL 0x020000 70#define NANDFS_DEBUG_SHEDULE 0x040000 71#define NANDFS_DEBUG_SEG 0x080000 72#define NANDFS_DEBUG_SYNC 0x100000 73#define NANDFS_DEBUG_PARANOIA 0x200000 74#define NANDFS_DEBUG_VNCALL 0x400000 75#define NANDFS_DEBUG_BUF 0x1000000 76#define NANDFS_DEBUG_BMAP 0x2000000 77#define NANDFS_DEBUG_DAT 0x4000000 78#define NANDFS_DEBUG_GENERIC 0x8000000 79#define NANDFS_DEBUG_CLEAN 0x10000000 80 81extern int nandfs_verbose; 82 83#define DPRINTF(name, arg) { \ 84 if (nandfs_verbose & NANDFS_DEBUG_##name) {\ 85 printf arg;\ 86 };\ 87 } 88#define DPRINTFIF(name, cond, arg) { \ 89 if (nandfs_verbose & NANDFS_DEBUG_##name) { \ 90 if (cond) printf arg;\ 91 };\ 92 } 93 94#define VFSTONANDFS(mp) ((struct nandfsmount *)((mp)->mnt_data)) 95#define VTON(vp) ((struct nandfs_node *)(vp)->v_data) 96#define NTOV(xp) ((xp)->nn_vnode) 97 98int nandfs_init(struct vfsconf *); 99int nandfs_uninit(struct vfsconf *); 100 101extern struct vop_vector nandfs_vnodeops; 102extern struct vop_vector nandfs_system_vnodeops; 103 104struct nandfs_node; 105 106/* Structure and derivatives */ 107struct nandfs_mdt { 108 uint32_t entries_per_block; 109 uint32_t entries_per_group; 110 uint32_t blocks_per_group; 111 uint32_t groups_per_desc_block; /* desc is super group */ 112 uint32_t blocks_per_desc_block; /* desc is super group */ 113}; 114 115struct nandfs_segment { 116 LIST_ENTRY(nandfs_segment) seg_link; 117 118 struct nandfs_device *fsdev; 119 120 TAILQ_HEAD(, buf) segsum; 121 TAILQ_HEAD(, buf) data; 122 123 uint64_t seg_num; 124 uint64_t seg_next; 125 uint64_t start_block; 126 uint32_t num_blocks; 127 128 uint32_t nblocks; 129 uint32_t nbinfos; 130 uint32_t segsum_blocks; 131 uint32_t segsum_bytes; 132 uint32_t bytes_left; 133 char *current_off; 134}; 135 136struct nandfs_seginfo { 137 LIST_HEAD( ,nandfs_segment) seg_list; 138 struct nandfs_segment *curseg; 139 struct nandfs_device *fsdev; 140 uint32_t blocks; 141 uint8_t reiterate; 142}; 143 144#define NANDFS_FSSTOR_FAILED 1 145struct nandfs_fsarea { 146 int offset; 147 int flags; 148 int last_used; 149}; 150 151extern int nandfs_cleaner_enable; 152extern int nandfs_cleaner_interval; 153extern int nandfs_cleaner_segments; 154 155struct nandfs_device { 156 struct vnode *nd_devvp; 157 struct g_consumer *nd_gconsumer; 158 159 struct thread *nd_syncer; 160 struct thread *nd_cleaner; 161 int nd_syncer_exit; 162 int nd_cleaner_exit; 163 164 struct nandfs_fsarea nd_fsarea[NANDFS_NFSAREAS]; 165 int nd_last_fsarea; 166 167 STAILQ_HEAD(nandfs_mnts, nandfsmount) nd_mounts; 168 SLIST_ENTRY(nandfs_device) nd_next_device; 169 170 /* FS structures */ 171 struct nandfs_fsdata nd_fsdata; 172 struct nandfs_super_block nd_super; 173 struct nandfs_segment_summary nd_last_segsum; 174 struct nandfs_super_root nd_super_root; 175 struct nandfs_node *nd_dat_node; 176 struct nandfs_node *nd_cp_node; 177 struct nandfs_node *nd_su_node; 178 struct nandfs_node *nd_gc_node; 179 180 struct nandfs_mdt nd_dat_mdt; 181 struct nandfs_mdt nd_ifile_mdt; 182 183 struct timespec nd_ts; 184 185 /* Synchronization */ 186 struct mtx nd_mutex; 187 struct mtx nd_sync_mtx; 188 struct cv nd_sync_cv; 189 struct mtx nd_clean_mtx; 190 struct cv nd_clean_cv; 191 struct lock nd_seg_const; 192 193 struct nandfs_seginfo *nd_seginfo; 194 195 /* FS geometry */ 196 uint64_t nd_devsize; 197 uint64_t nd_maxfilesize; 198 uint32_t nd_blocksize; 199 uint32_t nd_erasesize; 200 201 uint32_t nd_devblocksize; 202 203 uint32_t nd_segs_reserved; 204 205 /* Segment usage */ 206 uint64_t nd_clean_segs; 207 uint64_t *nd_free_base; 208 uint64_t nd_free_count; 209 uint64_t nd_dirty_bufs; 210 211 /* Running values */ 212 uint64_t nd_seg_sequence; 213 uint64_t nd_seg_num; 214 uint64_t nd_next_seg_num; 215 uint64_t nd_last_pseg; 216 uint64_t nd_last_cno; 217 uint64_t nd_last_ino; 218 uint64_t nd_fakevblk; 219 220 int nd_mount_state; 221 int nd_refcnt; 222 int nd_syncing; 223 int nd_cleaning; 224}; 225 226extern SLIST_HEAD(_nandfs_devices, nandfs_device) nandfs_devices; 227 228#define NANDFS_FORCE_SYNCER 0x1 229#define NANDFS_UMOUNT 0x2 230 231#define SYNCER_UMOUNT 0x0 232#define SYNCER_VFS_SYNC 0x1 233#define SYNCER_BDFLUSH 0x2 234#define SYNCER_FFORCE 0x3 235#define SYNCER_FSYNC 0x4 236#define SYNCER_ROUPD 0x5 237 238static __inline int 239nandfs_writelockflags(struct nandfs_device *fsdev, int flags) 240{ 241 int error = 0; 242 243 if (lockstatus(&fsdev->nd_seg_const) != LK_EXCLUSIVE) 244 error = lockmgr(&fsdev->nd_seg_const, flags | LK_SHARED, NULL); 245 246 return (error); 247} 248 249static __inline void 250nandfs_writeunlock(struct nandfs_device *fsdev) 251{ 252 253 if (lockstatus(&fsdev->nd_seg_const) != LK_EXCLUSIVE) 254 lockmgr(&(fsdev)->nd_seg_const, LK_RELEASE, NULL); 255} 256 257#define NANDFS_WRITELOCKFLAGS(fsdev, flags) nandfs_writelockflags(fsdev, flags) 258 259#define NANDFS_WRITELOCK(fsdev) NANDFS_WRITELOCKFLAGS(fsdev, 0) 260 261#define NANDFS_WRITEUNLOCK(fsdev) nandfs_writeunlock(fsdev) 262 263#define NANDFS_WRITEASSERT(fsdev) lockmgr_assert(&(fsdev)->nd_seg_const, KA_LOCKED) 264 265/* Specific mountpoint; head or a checkpoint/snapshot */ 266struct nandfsmount { 267 STAILQ_ENTRY(nandfsmount) nm_next_mount; 268 269 struct mount *nm_vfs_mountp; 270 struct nandfs_device *nm_nandfsdev; 271 struct nandfs_args nm_mount_args; 272 struct nandfs_node *nm_ifile_node; 273 274 uint8_t nm_flags; 275 int8_t nm_ronly; 276}; 277 278struct nandfs_node { 279 struct vnode *nn_vnode; 280 struct nandfsmount *nn_nmp; 281 struct nandfs_device *nn_nandfsdev; 282 struct lockf *nn_lockf; 283 284 uint64_t nn_ino; 285 struct nandfs_inode nn_inode; 286 287 uint64_t nn_diroff; 288 uint32_t nn_flags; 289}; 290 291#define IN_ACCESS 0x0001 /* Inode access time update request */ 292#define IN_CHANGE 0x0002 /* Inode change time update request */ 293#define IN_UPDATE 0x0004 /* Inode was written to; update mtime*/ 294#define IN_MODIFIED 0x0008 /* node has been modified */ 295#define IN_RENAME 0x0010 /* node is being renamed. */ 296 297/* File permissions. */ 298#define IEXEC 0000100 /* Executable. */ 299#define IWRITE 0000200 /* Writeable. */ 300#define IREAD 0000400 /* Readable. */ 301#define ISVTX 0001000 /* Sticky bit. */ 302#define ISGID 0002000 /* Set-gid. */ 303#define ISUID 0004000 /* Set-uid. */ 304 305#define PRINT_NODE_FLAGS \ 306 "\10\1IN_ACCESS\2IN_CHANGE\3IN_UPDATE\4IN_MODIFIED\5IN_RENAME" 307 308#define NANDFS_GATHER(x) ((x)->b_flags |= B_FS_FLAG1) 309#define NANDFS_UNGATHER(x) ((x)->b_flags &= ~B_FS_FLAG1) 310#define NANDFS_ISGATHERED(x) ((x)->b_flags & B_FS_FLAG1) 311 312#endif /* !_FS_NANDFS_NANDFS_H_ */ 313