diff options
author | gber <gber@FreeBSD.org> | 2012-05-17 10:11:18 +0000 |
---|---|---|
committer | gber <gber@FreeBSD.org> | 2012-05-17 10:11:18 +0000 |
commit | 6f7c7353004e2ff9709b326a4008ce8ea63d9270 (patch) | |
tree | a325137a898341311de8641f7212e28b7d87950e /sys/fs/nandfs/nandfs.h | |
parent | 661b9d94414ea6d11d5b7960aef1f172975ce52b (diff) | |
download | FreeBSD-src-6f7c7353004e2ff9709b326a4008ce8ea63d9270.zip FreeBSD-src-6f7c7353004e2ff9709b326a4008ce8ea63d9270.tar.gz |
Import work done under project/nand (@235533) into head.
The NAND Flash environment consists of several distinct components:
- NAND framework (drivers harness for NAND controllers and NAND chips)
- NAND simulator (NANDsim)
- NAND file system (NAND FS)
- Companion tools and utilities
- Documentation (manual pages)
This work is still experimental. Please use with caution.
Obtained from: Semihalf
Supported by: FreeBSD Foundation, Juniper Networks
Diffstat (limited to 'sys/fs/nandfs/nandfs.h')
-rw-r--r-- | sys/fs/nandfs/nandfs.h | 310 |
1 files changed, 310 insertions, 0 deletions
diff --git a/sys/fs/nandfs/nandfs.h b/sys/fs/nandfs/nandfs.h new file mode 100644 index 0000000..beb4e16 --- /dev/null +++ b/sys/fs/nandfs/nandfs.h @@ -0,0 +1,310 @@ +/*- + * Copyright (c) 2010-2012 Semihalf + * Copyright (c) 2008, 2009 Reinoud Zandijk + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * From: NetBSD: nilfs.h,v 1.1 2009/07/18 16:31:42 reinoud + * + * $FreeBSD$ + */ + +#ifndef _FS_NANDFS_NANDFS_H_ +#define _FS_NANDFS_NANDFS_H_ + +#include <sys/param.h> +#include <sys/proc.h> +#include <sys/condvar.h> +#include <sys/lock.h> +#include <sys/mutex.h> + +#include <sys/queue.h> +#include <sys/uio.h> +#include <sys/mutex.h> + +#include <sys/disk.h> +#include <sys/kthread.h> +#include "nandfs_fs.h" + +MALLOC_DECLARE(M_NANDFSTEMP); + +/* Debug categories */ +#define NANDFS_DEBUG_VOLUMES 0x000001 +#define NANDFS_DEBUG_BLOCK 0x000004 +#define NANDFS_DEBUG_LOCKING 0x000008 +#define NANDFS_DEBUG_NODE 0x000010 +#define NANDFS_DEBUG_LOOKUP 0x000020 +#define NANDFS_DEBUG_READDIR 0x000040 +#define NANDFS_DEBUG_TRANSLATE 0x000080 +#define NANDFS_DEBUG_STRATEGY 0x000100 +#define NANDFS_DEBUG_READ 0x000200 +#define NANDFS_DEBUG_WRITE 0x000400 +#define NANDFS_DEBUG_IFILE 0x000800 +#define NANDFS_DEBUG_ATTR 0x001000 +#define NANDFS_DEBUG_EXTATTR 0x002000 +#define NANDFS_DEBUG_ALLOC 0x004000 +#define NANDFS_DEBUG_CPFILE 0x008000 +#define NANDFS_DEBUG_DIRHASH 0x010000 +#define NANDFS_DEBUG_NOTIMPL 0x020000 +#define NANDFS_DEBUG_SHEDULE 0x040000 +#define NANDFS_DEBUG_SEG 0x080000 +#define NANDFS_DEBUG_SYNC 0x100000 +#define NANDFS_DEBUG_PARANOIA 0x200000 +#define NANDFS_DEBUG_VNCALL 0x400000 +#define NANDFS_DEBUG_BUF 0x1000000 +#define NANDFS_DEBUG_BMAP 0x2000000 +#define NANDFS_DEBUG_DAT 0x4000000 +#define NANDFS_DEBUG_GENERIC 0x8000000 +#define NANDFS_DEBUG_CLEAN 0x10000000 + +extern int nandfs_verbose; + +#define DPRINTF(name, arg) { \ + if (nandfs_verbose & NANDFS_DEBUG_##name) {\ + printf arg;\ + };\ + } +#define DPRINTFIF(name, cond, arg) { \ + if (nandfs_verbose & NANDFS_DEBUG_##name) { \ + if (cond) printf arg;\ + };\ + } + +#define VFSTONANDFS(mp) ((struct nandfsmount *)((mp)->mnt_data)) +#define VTON(vp) ((struct nandfs_node *)(vp)->v_data) +#define NTOV(xp) ((xp)->nn_vnode) + +int nandfs_init(struct vfsconf *); +int nandfs_uninit(struct vfsconf *); + +extern struct vop_vector nandfs_vnodeops; +extern struct vop_vector nandfs_system_vnodeops; + +struct nandfs_node; + +/* Structure and derivatives */ +struct nandfs_mdt { + uint32_t entries_per_block; + uint32_t entries_per_group; + uint32_t blocks_per_group; + uint32_t groups_per_desc_block; /* desc is super group */ + uint32_t blocks_per_desc_block; /* desc is super group */ +}; + +struct nandfs_segment { + LIST_ENTRY(nandfs_segment) seg_link; + + struct nandfs_device *fsdev; + + TAILQ_HEAD(, buf) segsum; + TAILQ_HEAD(, buf) data; + + uint64_t seg_num; + uint64_t seg_next; + uint64_t start_block; + uint32_t num_blocks; + + uint32_t nblocks; + uint32_t nbinfos; + uint32_t segsum_blocks; + uint32_t segsum_bytes; + uint32_t bytes_left; + char *current_off; +}; + +struct nandfs_seginfo { + LIST_HEAD( ,nandfs_segment) seg_list; + struct nandfs_segment *curseg; + struct nandfs_device *fsdev; + uint32_t blocks; + uint8_t reiterate; +}; + +#define NANDFS_FSSTOR_FAILED 1 +struct nandfs_fsarea { + int offset; + int flags; + int last_used; +}; + +extern int nandfs_cleaner_enable; +extern int nandfs_cleaner_interval; +extern int nandfs_cleaner_segments; + +struct nandfs_device { + struct vnode *nd_devvp; + struct g_consumer *nd_gconsumer; + + struct thread *nd_syncer; + struct thread *nd_cleaner; + int nd_syncer_exit; + int nd_cleaner_exit; + + int nd_is_nand; + + struct nandfs_fsarea nd_fsarea[NANDFS_NFSAREAS]; + int nd_last_fsarea; + + STAILQ_HEAD(nandfs_mnts, nandfsmount) nd_mounts; + SLIST_ENTRY(nandfs_device) nd_next_device; + + /* FS structures */ + struct nandfs_fsdata nd_fsdata; + struct nandfs_super_block nd_super; + struct nandfs_segment_summary nd_last_segsum; + struct nandfs_super_root nd_super_root; + struct nandfs_node *nd_dat_node; + struct nandfs_node *nd_cp_node; + struct nandfs_node *nd_su_node; + struct nandfs_node *nd_gc_node; + + struct nandfs_mdt nd_dat_mdt; + struct nandfs_mdt nd_ifile_mdt; + + struct timespec nd_ts; + + /* Synchronization */ + struct mtx nd_mutex; + struct mtx nd_sync_mtx; + struct cv nd_sync_cv; + struct mtx nd_clean_mtx; + struct cv nd_clean_cv; + struct lock nd_seg_const; + + struct nandfs_seginfo *nd_seginfo; + + /* FS geometry */ + uint64_t nd_devsize; + uint64_t nd_maxfilesize; + uint32_t nd_blocksize; + uint32_t nd_erasesize; + + uint32_t nd_devblocksize; + + /* Segment usage */ + uint64_t nd_clean_segs; + uint64_t *nd_free_base; + uint64_t nd_free_count; + uint64_t nd_dirty_bufs; + + /* Running values */ + uint64_t nd_seg_sequence; + uint64_t nd_seg_num; + uint64_t nd_next_seg_num; + uint64_t nd_last_pseg; + uint64_t nd_last_cno; + uint64_t nd_last_ino; + uint64_t nd_fakevblk; + + int nd_mount_state; + int nd_refcnt; + int nd_syncing; + int nd_cleaning; +}; + +extern SLIST_HEAD(_nandfs_devices, nandfs_device) nandfs_devices; + +#define NANDFS_FORCE_SYNCER 0x1 +#define NANDFS_UMOUNT 0x2 + +#define SYNCER_UMOUNT 0x0 +#define SYNCER_VFS_SYNC 0x1 +#define SYNCER_BDFLUSH 0x2 +#define SYNCER_FFORCE 0x3 +#define SYNCER_FSYNC 0x4 +#define SYNCER_ROUPD 0x5 + +static __inline int +nandfs_writelockflags(struct nandfs_device *fsdev, int flags) +{ + int error = 0; + + if (lockstatus(&fsdev->nd_seg_const) != LK_EXCLUSIVE) + error = lockmgr(&fsdev->nd_seg_const, flags | LK_SHARED, NULL); + + return (error); +} + +static __inline void +nandfs_writeunlock(struct nandfs_device *fsdev) +{ + + if (lockstatus(&fsdev->nd_seg_const) != LK_EXCLUSIVE) + lockmgr(&(fsdev)->nd_seg_const, LK_RELEASE, NULL); +} + +#define NANDFS_WRITELOCKFLAGS(fsdev, flags) nandfs_writelockflags(fsdev, flags) + +#define NANDFS_WRITELOCK(fsdev) NANDFS_WRITELOCKFLAGS(fsdev, 0) + +#define NANDFS_WRITEUNLOCK(fsdev) nandfs_writeunlock(fsdev) + +#define NANDFS_WRITEASSERT(fsdev) lockmgr_assert(&(fsdev)->nd_seg_const, KA_LOCKED) + +/* Specific mountpoint; head or a checkpoint/snapshot */ +struct nandfsmount { + STAILQ_ENTRY(nandfsmount) nm_next_mount; + + struct mount *nm_vfs_mountp; + struct nandfs_device *nm_nandfsdev; + struct nandfs_args nm_mount_args; + struct nandfs_node *nm_ifile_node; + + uint8_t nm_flags; + int8_t nm_ronly; +}; + +struct nandfs_node { + struct vnode *nn_vnode; + struct nandfsmount *nn_nmp; + struct nandfs_device *nn_nandfsdev; + struct lockf *nn_lockf; + + uint64_t nn_ino; + struct nandfs_inode nn_inode; + + uint64_t nn_diroff; + uint32_t nn_flags; +}; + +#define IN_ACCESS 0x0001 /* Inode access time update request */ +#define IN_CHANGE 0x0002 /* Inode change time update request */ +#define IN_UPDATE 0x0004 /* Inode was written to; update mtime*/ +#define IN_MODIFIED 0x0008 /* node has been modified */ +#define IN_RENAME 0x0010 /* node is being renamed. */ + +/* File permissions. */ +#define IEXEC 0000100 /* Executable. */ +#define IWRITE 0000200 /* Writeable. */ +#define IREAD 0000400 /* Readable. */ +#define ISVTX 0001000 /* Sticky bit. */ +#define ISGID 0002000 /* Set-gid. */ +#define ISUID 0004000 /* Set-uid. */ + +#define PRINT_NODE_FLAGS \ + "\10\1IN_ACCESS\2IN_CHANGE\3IN_UPDATE\4IN_MODIFIED\5IN_RENAME" + +#define NANDFS_GATHER(x) ((x)->b_flags |= B_00800000) +#define NANDFS_UNGATHER(x) ((x)->b_flags &= ~B_00800000) +#define NANDFS_ISGATHERED(x) ((x)->b_flags & B_00800000) + +#endif /* !_FS_NANDFS_NANDFS_H_ */ |