]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/fs/nandfs/nandfs.h
MFV r336851:
[FreeBSD/FreeBSD.git] / sys / fs / nandfs / nandfs.h
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
50 MALLOC_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
81 extern 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
98 int nandfs_init(struct vfsconf *);
99 int nandfs_uninit(struct vfsconf *);
100
101 extern struct vop_vector nandfs_vnodeops;
102 extern struct vop_vector nandfs_system_vnodeops;
103
104 struct nandfs_node;
105
106 /* Structure and derivatives */
107 struct 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
115 struct 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
136 struct 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
145 struct nandfs_fsarea {
146         int     offset;
147         int     flags;
148         int     last_used;
149 };
150
151 extern int nandfs_cleaner_enable;
152 extern int nandfs_cleaner_interval;
153 extern int nandfs_cleaner_segments;
154
155 struct 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
226 extern 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
238 static __inline int
239 nandfs_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
249 static __inline void
250 nandfs_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 */
266 struct 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
278 struct 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_ */