darwin-xnu/bsd/vfs/vfs_journal.h
<<
>>
Prefs
   1
   2/*
   3 * Copyright (c) 2000-2002 Apple Computer, Inc. All rights reserved.
   4 *
   5 * @APPLE_LICENSE_HEADER_START@
   6 * 
   7 * The contents of this file constitute Original Code as defined in and
   8 * are subject to the Apple Public Source License Version 1.1 (the
   9 * "License").  You may not use this file except in compliance with the
  10 * License.  Please obtain a copy of the License at
  11 * http://www.apple.com/publicsource and read it before using this file.
  12 * 
  13 * This Original Code and all software distributed under the License are
  14 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
  15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
  16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
  17 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
  18 * License for the specific language governing rights and limitations
  19 * under the License.
  20 * 
  21 * @APPLE_LICENSE_HEADER_END@
  22 */
  23/*
  24 * This header contains the structures and function prototypes
  25 * for the vfs journaling code.  The data types are not meant
  26 * to be modified by user code.  Just use the functions and do
  27 * not mess around with the structs.
  28 */ 
  29#ifndef _SYS_VFS_JOURNAL_H_
  30#define _SYS_VFS_JOURNAL_H_
  31
  32#include <sys/appleapiopts.h>
  33#include <sys/cdefs.h>
  34
  35#ifdef __APPLE_API_UNSTABLE
  36
  37#include <sys/types.h>
  38#include <kern/locks.h>
  39
  40typedef struct block_info {
  41    off_t       bnum;                // block # on the file system device
  42    size_t      bsize;               // in bytes
  43    struct buf *bp;
  44} block_info;
  45
  46typedef struct block_list_header {
  47    u_int16_t   max_blocks;          // max number of blocks in this chunk
  48    u_int16_t   num_blocks;          // number of valid block numbers in block_nums
  49    int32_t     bytes_used;          // how many bytes of this tbuffer are used
  50    int32_t     checksum;            // on-disk: checksum of this header and binfo[0]
  51    int32_t     pad;                 // pad out to 16 bytes
  52    block_info  binfo[1];            // so we can reference them by name
  53} block_list_header;
  54
  55
  56struct journal;
  57
  58typedef struct transaction {
  59    int                 tbuffer_size;  // in bytes
  60    char               *tbuffer;       // memory copy of the transaction
  61    block_list_header  *blhdr;         // points to the first byte of tbuffer
  62    int                 num_blhdrs;    // how many buffers we've allocated
  63    int                 total_bytes;   // total # of bytes in transaction
  64    int                 num_flushed;   // how many bytes have been flushed
  65    int                 num_killed;    // how many bytes were "killed"
  66    off_t               journal_start; // where in the journal this transaction starts
  67    off_t               journal_end;   // where in the journal this transaction ends
  68    struct journal     *jnl;           // ptr back to the journal structure
  69    struct transaction *next;          // list of tr's (either completed or to be free'd)
  70} transaction;
  71
  72
  73/*
  74 * This is written to block zero of the journal and it
  75 * maintains overall state about the journal.
  76 */
  77typedef struct journal_header {
  78    int32_t        magic;
  79    int32_t        endian;
  80    volatile off_t start;         // zero-based byte offset of the start of the first transaction
  81    volatile off_t end;           // zero-based byte offset of where free space begins
  82    off_t          size;          // size in bytes of the entire journal
  83    int32_t        blhdr_size;    // size in bytes of each block_list_header in the journal
  84    int32_t        checksum;
  85    int32_t        jhdr_size;     // block size (in bytes) of the journal header
  86} journal_header;
  87
  88#define JOURNAL_HEADER_MAGIC  0x4a4e4c78   // 'JNLx'
  89#define ENDIAN_MAGIC          0x12345678
  90
  91#define OLD_JOURNAL_HEADER_MAGIC  0x4a484452   // 'JHDR'
  92
  93
  94/*
  95 * In memory structure about the journal.
  96 */
  97typedef struct journal {
  98    lck_mtx_t           jlock;             // protects the struct journal data
  99
 100    struct vnode       *jdev;              // vnode of the device where the journal lives
 101    off_t               jdev_offset;       // byte offset to the start of the journal
 102
 103    struct vnode       *fsdev;             // vnode of the file system device
 104    
 105    void              (*flush)(void *arg); // fs callback to flush meta data blocks
 106    void               *flush_arg;         // arg that's passed to flush()
 107
 108    int32_t             flags;
 109    int32_t             tbuffer_size;      // default transaction buffer size
 110
 111    char               *header_buf;        // in-memory copy of the journal header
 112    journal_header     *jhdr;              // points to the first byte of header_buf
 113
 114    transaction        *cur_tr;            // for group-commit
 115    transaction        *completed_trs;     // out-of-order transactions that completed
 116    transaction        *active_tr;         // for nested transactions
 117    int32_t             nested_count;      // for nested transactions
 118    void               *owner;             // a ptr that's unique to the calling process
 119
 120    transaction        *tr_freeme;         // transaction structs that need to be free'd
 121
 122    volatile off_t      active_start;      // the active start that we only keep in memory
 123    lck_mtx_t           old_start_lock;    // protects the old_start
 124    volatile off_t      old_start[16];     // this is how we do lazy start update
 125
 126    int                 last_flush_err;    // last error from flushing the cache
 127} journal;
 128
 129/* internal-only journal flags (top 16 bits) */
 130#define JOURNAL_CLOSE_PENDING     0x00010000
 131#define JOURNAL_INVALID           0x00020000
 132#define JOURNAL_FLUSHCACHE_ERR    0x00040000   // means we already printed this err
 133#define JOURNAL_NEED_SWAP         0x00080000   // swap any data read from disk
 134
 135/* journal_open/create options are always in the low-16 bits */
 136#define JOURNAL_OPTION_FLAGS_MASK 0x0000ffff
 137
 138__BEGIN_DECLS
 139/*
 140 * Prototypes.
 141 */
 142
 143/*
 144 * Call journal_init() to initialize the journaling code (sets up lock attributes)
 145 */
 146void      journal_init(void);
 147
 148/*
 149 * Call journal_create() to create a new journal.  You only
 150 * call this once, typically at file system creation time.
 151 *
 152 * The "jvp" argument is the vnode where the journal is written.
 153 * The journal starts at "offset" and is "journal_size" bytes long.
 154 *
 155 * The "fsvp" argument is the vnode of your file system.  It may be
 156 * the same as "jvp".
 157 *
 158 * The "min_fs_block_size" argument is the minimum block size
 159 * (in bytes) that the file system will ever write.  Typically
 160 * this is the block size of the file system (1k, 4k, etc) but
 161 * on HFS+ it is the minimum block size of the underlying device.
 162 *
 163 * The flags argument lets you disable group commit if you
 164 * want tighter guarantees on transactions (in exchange for
 165 * lower performance).
 166 *
 167 * The tbuffer_size is the size of the transaction buffer
 168 * used by the journal. If you specify zero, the journal code
 169 * will use a reasonable defaults.  The tbuffer_size should 
 170 * be an integer multiple of the min_fs_block_size.
 171 *
 172 * Returns a valid journal pointer or NULL if one could not
 173 * be created.
 174 */
 175journal *journal_create(struct vnode *jvp,
 176                                                off_t         offset,
 177                                                off_t         journal_size,
 178                                                struct vnode *fsvp,
 179                                                size_t        min_fs_block_size,
 180                                                int32_t       flags,
 181                                                int32_t       tbuffer_size,
 182                                                void        (*flush)(void *arg),
 183                                                void         *arg);
 184
 185/*
 186 * Call journal_open() when mounting an existing file system
 187 * that has a previously created journal.  It will take care
 188 * of validating the journal and replaying it if necessary.
 189 *
 190 * See journal_create() for a description of the arguments.
 191 *
 192 * Returns a valid journal pointer of NULL if it runs into
 193 * trouble reading/playing back the journal.
 194 */
 195journal  *journal_open(struct vnode *jvp,
 196                                           off_t         offset,
 197                                           off_t         journal_size,
 198                                           struct vnode *fsvp,
 199                                           size_t        min_fs_block_size,
 200                                           int32_t       flags,
 201                                           int32_t       tbuffer_size,
 202                                           void        (*flush)(void *arg),
 203                                           void         *arg);
 204
 205/*
 206 * Test whether the journal is clean or not.  This is intended
 207 * to be used when you're mounting read-only.  If the journal
 208 * is not clean for some reason then you should not mount the
 209 * volume as your data structures may be in an unknown state.
 210 */
 211int journal_is_clean(struct vnode *jvp,
 212                     off_t         offset,
 213                     off_t         journal_size,
 214                     struct vnode *fsvp,
 215                     size_t        min_fs_block_size);
 216
 217
 218/*
 219 * Call journal_close() just before your file system is unmounted.
 220 * It flushes any outstanding transactions and makes sure the
 221 * journal is in a consistent state.
 222 */
 223void      journal_close(journal *journalp);
 224
 225/*
 226 * flags for journal_create/open.  only can use 
 227 * the low 16 bits for flags because internal 
 228 * bits go in the high 16.
 229 */
 230#define JOURNAL_NO_GROUP_COMMIT   0x00000001
 231#define JOURNAL_RESET             0x00000002
 232
 233/*
 234 * Transaction related functions.
 235 *
 236 * Before you start modifying file system meta data, you
 237 * should call journal_start_transaction().  Then before
 238 * you modify each block, call journal_modify_block_start()
 239 * and when you're done, journal_modify_block_end().  When
 240 * you've modified the last block as part of a transaction,
 241 * call journal_end_transaction() to commit the changes.
 242 *
 243 * If you decide to abort the modifications to a block you
 244 * should call journal_modify_block_abort().
 245 *
 246 * If as part of a transaction you need want to throw out
 247 * any previous copies of a block (because it got deleted)
 248 * then call journal_kill_block().  This will mark it so
 249 * that the journal does not play it back (effectively
 250 * dropping it).
 251 */
 252int   journal_start_transaction(journal *jnl);
 253int   journal_modify_block_start(journal *jnl, struct buf *bp);
 254int   journal_modify_block_abort(journal *jnl, struct buf *bp);
 255int   journal_modify_block_end(journal *jnl, struct buf *bp);
 256int   journal_kill_block(journal *jnl, struct buf *bp);
 257int   journal_end_transaction(journal *jnl);
 258
 259int   journal_active(journal *jnl);
 260int   journal_flush(journal *jnl);
 261void *journal_owner(journal *jnl);    // compare against current_thread()
 262
 263__END_DECLS
 264
 265#endif /* __APPLE_API_UNSTABLE */
 266#endif /* !_SYS_VFS_JOURNAL_H_ */
 267
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.