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