📄 jbd.h
字号:
* for checkpointing. */ /* Protected by journal_datalist_lock */ transaction_t * j_checkpoint_transactions; /* Wait queue for waiting for a locked transaction to start committing, or for a barrier lock to be released */ wait_queue_head_t j_wait_transaction_locked; /* Wait queue for waiting for checkpointing to complete */ wait_queue_head_t j_wait_logspace; /* Wait queue for waiting for commit to complete */ wait_queue_head_t j_wait_done_commit; /* Wait queue to trigger checkpointing */ wait_queue_head_t j_wait_checkpoint; /* Wait queue to trigger commit */ wait_queue_head_t j_wait_commit; /* Wait queue to wait for updates to complete */ wait_queue_head_t j_wait_updates; /* Semaphore for locking against concurrent checkpoints */ struct semaphore j_checkpoint_sem; /* The main journal lock, used by lock_journal() */ struct semaphore j_sem; /* Journal head: identifies the first unused block in the journal. */ unsigned long j_head; /* Journal tail: identifies the oldest still-used block in the * journal. */ unsigned long j_tail; /* Journal free: how many free blocks are there in the journal? */ unsigned long j_free; /* Journal start and end: the block numbers of the first usable * block and one beyond the last usable block in the journal. */ unsigned long j_first, j_last; /* Device, blocksize and starting block offset for the location * where we store the journal. */ kdev_t j_dev; int j_blocksize; unsigned int j_blk_offset; /* Device which holds the client fs. For internal journal this * will be equal to j_dev. */ kdev_t j_fs_dev; /* Total maximum capacity of the journal region on disk. */ unsigned int j_maxlen; /* Optional inode where we store the journal. If present, all * journal block numbers are mapped into this inode via * bmap(). */ struct inode * j_inode; /* Sequence number of the oldest transaction in the log */ tid_t j_tail_sequence; /* Sequence number of the next transaction to grant */ tid_t j_transaction_sequence; /* Sequence number of the most recently committed transaction */ tid_t j_commit_sequence; /* Sequence number of the most recent transaction wanting commit */ tid_t j_commit_request; /* Journal uuid: identifies the object (filesystem, LVM volume * etc) backed by this journal. This will eventually be * replaced by an array of uuids, allowing us to index multiple * devices within a single journal and to perform atomic updates * across them. */ __u8 j_uuid[16]; /* Pointer to the current commit thread for this journal */ struct task_struct * j_task; /* Maximum number of metadata buffers to allow in a single * compound commit transaction */ int j_max_transaction_buffers; /* The timer used to wakeup the commit thread: */ struct timer_list * j_commit_timer; int j_commit_timer_active; /* Link all journals together - system-wide */ struct list_head j_all_journals; /* The revoke table: maintains the list of revoked blocks in the current transaction. */ struct jbd_revoke_table_s *j_revoke;};/* * Journal flag definitions */#define JFS_UNMOUNT 0x001 /* Journal thread is being destroyed */#define JFS_ABORT 0x002 /* Journaling has been aborted for errors. */#define JFS_ACK_ERR 0x004 /* The errno in the sb has been acked */#define JFS_FLUSHED 0x008 /* The journal superblock has been flushed */#define JFS_LOADED 0x010 /* The journal superblock has been loaded *//* * Function declarations for the journaling transaction and buffer * management *//* Filing buffers */extern void __journal_unfile_buffer(struct journal_head *);extern void journal_unfile_buffer(struct journal_head *);extern void __journal_refile_buffer(struct journal_head *);extern void journal_refile_buffer(struct journal_head *);extern void __journal_file_buffer(struct journal_head *, transaction_t *, int);extern void __journal_free_buffer(struct journal_head *bh);extern void journal_file_buffer(struct journal_head *, transaction_t *, int);extern void __journal_clean_data_list(transaction_t *transaction);/* Log buffer allocation */extern struct journal_head * journal_get_descriptor_buffer(journal_t *);int journal_next_log_block(journal_t *, unsigned long *);/* Commit management */void journal_end_buffer_io_sync(struct buffer_head *bh, int uptodate);extern void journal_commit_transaction(journal_t *);/* Checkpoint list management */int __journal_clean_checkpoint_list(journal_t *journal);extern void journal_remove_checkpoint(struct journal_head *);extern void __journal_remove_checkpoint(struct journal_head *);extern void journal_insert_checkpoint(struct journal_head *, transaction_t *);extern void __journal_insert_checkpoint(struct journal_head *,transaction_t *);/* Buffer IO */extern int journal_write_metadata_buffer(transaction_t *transaction, struct journal_head *jh_in, struct journal_head **jh_out, int blocknr);/* Transaction locking */extern void __wait_on_journal (journal_t *);/* * Journal locking. * * We need to lock the journal during transaction state changes so that * nobody ever tries to take a handle on the running transaction while * we are in the middle of moving it to the commit phase. * * Note that the locking is completely interrupt unsafe. We never touch * journal structures from interrupts. * * In 2.2, the BKL was required for lock_journal. This is no longer * the case. */static inline void lock_journal(journal_t *journal){ down(&journal->j_sem);}/* This returns zero if we acquired the semaphore */static inline int try_lock_journal(journal_t * journal){ return down_trylock(&journal->j_sem);}static inline void unlock_journal(journal_t * journal){ up(&journal->j_sem);}static inline handle_t *journal_current_handle(void){ return current->journal_info;}/* The journaling code user interface: * * Create and destroy handles * Register buffer modifications against the current transaction. */extern handle_t *journal_start(journal_t *, int nblocks);extern handle_t *journal_try_start(journal_t *, int nblocks);extern int journal_restart (handle_t *, int nblocks);extern int journal_extend (handle_t *, int nblocks);extern int journal_get_write_access (handle_t *, struct buffer_head *);extern int journal_get_create_access (handle_t *, struct buffer_head *);extern int journal_get_undo_access (handle_t *, struct buffer_head *);extern int journal_dirty_data (handle_t *, struct buffer_head *, int async);extern int journal_dirty_metadata (handle_t *, struct buffer_head *);extern void journal_release_buffer (handle_t *, struct buffer_head *);extern void journal_forget (handle_t *, struct buffer_head *);extern void journal_sync_buffer (struct buffer_head *);extern int journal_flushpage(journal_t *, struct page *, unsigned long);extern int journal_try_to_free_buffers(journal_t *, struct page *, int);extern int journal_stop(handle_t *);extern int journal_flush (journal_t *);extern void journal_lock_updates (journal_t *);extern void journal_unlock_updates (journal_t *);extern journal_t * journal_init_dev(kdev_t dev, kdev_t fs_dev, int start, int len, int bsize);extern journal_t * journal_init_inode (struct inode *);extern int journal_update_format (journal_t *);extern int journal_check_used_features (journal_t *, unsigned long, unsigned long, unsigned long);extern int journal_check_available_features (journal_t *, unsigned long, unsigned long, unsigned long);extern int journal_set_features (journal_t *, unsigned long, unsigned long, unsigned long);extern int journal_create (journal_t *);extern int journal_load (journal_t *journal);extern void journal_destroy (journal_t *);extern int journal_recover (journal_t *journal);extern int journal_wipe (journal_t *, int);extern int journal_skip_recovery (journal_t *);extern void journal_update_superblock (journal_t *, int);extern void __journal_abort_hard (journal_t *);extern void __journal_abort_soft (journal_t *, int);extern void journal_abort (journal_t *, int);extern int journal_errno (journal_t *);extern void journal_ack_err (journal_t *);extern int journal_clear_err (journal_t *);extern int journal_bmap(journal_t *, unsigned long, unsigned long *);extern int journal_force_commit(journal_t *);/* * journal_head management */extern struct journal_head *journal_add_journal_head(struct buffer_head *bh);extern void journal_remove_journal_head(struct buffer_head *bh);extern void __journal_remove_journal_head(struct buffer_head *bh);extern void journal_unlock_journal_head(struct journal_head *jh);/* Primary revoke support */#define JOURNAL_REVOKE_DEFAULT_HASH 256extern int journal_init_revoke(journal_t *, int);extern void journal_destroy_revoke_caches(void);extern int journal_init_revoke_caches(void);extern void journal_destroy_revoke(journal_t *);extern int journal_revoke (handle_t *, unsigned long, struct buffer_head *);extern int journal_cancel_revoke(handle_t *, struct journal_head *);extern void journal_write_revoke_records(journal_t *, transaction_t *);/* Recovery revoke support */extern int journal_set_revoke(journal_t *, unsigned long, tid_t);extern int journal_test_revoke(journal_t *, unsigned long, tid_t);extern void journal_clear_revoke(journal_t *);extern void journal_brelse_array(struct buffer_head *b[], int n);/* The log thread user interface: * * Request space in the current transaction, and force transaction commit * transitions on demand. */extern int log_space_left (journal_t *); /* Called with journal locked */extern tid_t log_start_commit (journal_t *, transaction_t *);extern void log_wait_commit (journal_t *, tid_t);extern int log_do_checkpoint (journal_t *, int);extern void log_wait_for_space(journal_t *, int nblocks);extern void __journal_drop_transaction(journal_t *, transaction_t *);extern int cleanup_journal_tail(journal_t *);/* Reduce journal memory usage by flushing */extern void shrink_journal_memory(void);/* Debugging code only: */#define jbd_ENOSYS() \do { \ printk (KERN_ERR "JBD unimplemented function " __FUNCTION__); \ current->state = TASK_UNINTERRUPTIBLE; \ schedule(); \} while (1)/* * is_journal_abort * * Simple test wrapper function to test the JFS_ABORT state flag. This * bit, when set, indicates that we have had a fatal error somewhere, * either inside the journaling layer or indicated to us by the client * (eg. ext3), and that we and should not commit any further * transactions. */static inline int is_journal_aborted(journal_t *journal){ return journal->j_flags & JFS_ABORT;}static inline int is_handle_aborted(handle_t *handle){ if (handle->h_aborted) return 1; return is_journal_aborted(handle->h_transaction->t_journal);}static inline void journal_abort_handle(handle_t *handle){ handle->h_aborted = 1;}/* Not all architectures define BUG() */#ifndef BUG #define BUG() do { \ printk("kernel BUG at %s:%d!\n", __FILE__, __LINE__); \ * ((char *) 0) = 0; \ } while (0)#endif /* BUG */#endif /* __KERNEL__ *//* Comparison functions for transaction IDs: perform comparisons using * modulo arithmetic so that they work over sequence number wraps. */static inline int tid_gt(tid_t x, tid_t y){ int difference = (x - y); return (difference > 0);}static inline int tid_geq(tid_t x, tid_t y){ int difference = (x - y); return (difference >= 0);}extern int journal_blocks_per_page(struct inode *inode);/* * Definitions which augment the buffer_head layer *//* journaling buffer types */#define BJ_None 0 /* Not journaled */#define BJ_SyncData 1 /* Normal data: flush before commit */#define BJ_AsyncData 2 /* writepage data: wait on it before commit */#define BJ_Metadata 3 /* Normal journaled metadata */#define BJ_Forget 4 /* Buffer superseded by this transaction */#define BJ_IO 5 /* Buffer is for temporary IO use */#define BJ_Shadow 6 /* Buffer contents being shadowed to the log */#define BJ_LogCtl 7 /* Buffer contains log descriptors */#define BJ_Reserved 8 /* Buffer is reserved for access by journal */#define BJ_Types 9 #ifdef __KERNEL__extern spinlock_t jh_splice_lock;/* * Once `expr1' has been found true, take jh_splice_lock * and then reevaluate everything. */#define SPLICE_LOCK(expr1, expr2) \ ({ \ int ret = (expr1); \ if (ret) { \ spin_lock(&jh_splice_lock); \ ret = (expr1) && (expr2); \ spin_unlock(&jh_splice_lock); \ } \ ret; \ })/* * A number of buffer state predicates. They test for * buffer_jbd() because they are used in core kernel code. * * These will be racy on SMP unless we're *sure* that the * buffer won't be detached from the journalling system * in parallel. *//* Return true if the buffer is on journal list `list' */static inline int buffer_jlist_eq(struct buffer_head *bh, int list){ return SPLICE_LOCK(buffer_jbd(bh), bh2jh(bh)->b_jlist == list);}/* Return true if this bufer is dirty wrt the journal */static inline int buffer_jdirty(struct buffer_head *bh){ return buffer_jbd(bh) && __buffer_state(bh, JBDDirty);}/* Return true if it's a data buffer which journalling is managing */static inline int buffer_jbd_data(struct buffer_head *bh){ return SPLICE_LOCK(buffer_jbd(bh), bh2jh(bh)->b_jlist == BJ_SyncData || bh2jh(bh)->b_jlist == BJ_AsyncData);}#ifdef CONFIG_SMP#define assert_spin_locked(lock) J_ASSERT(spin_is_locked(lock))#else#define assert_spin_locked(lock) do {} while(0)#endif#define buffer_trace_init(bh) do {} while (0)#define print_buffer_fields(bh) do {} while (0)#define print_buffer_trace(bh) do {} while (0)#define BUFFER_TRACE(bh, info) do {} while (0)#define BUFFER_TRACE2(bh, bh2, info) do {} while (0)#define JBUFFER_TRACE(jh, info) do {} while (0)#endif /* __KERNEL__ */#endif /* CONFIG_JBD || CONFIG_JBD_MODULE || !__KERNEL__ *//* * Compatibility no-ops which allow the kernel to compile without CONFIG_JBD * go here. */#if defined(__KERNEL__) && !(defined(CONFIG_JBD) || defined(CONFIG_JBD_MODULE))#define J_ASSERT(expr) do {} while (0)#define J_ASSERT_BH(bh, expr) do {} while (0)#define buffer_jbd(bh) 0#define buffer_jlist_eq(bh, val) 0#define journal_buffer_journal_lru(bh) 0#endif /* defined(__KERNEL__) && !defined(CONFIG_JBD) */#endif /* _LINUX_JBD_H */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -