From 241f224fb249243af20037d2145a1a0fe0f81581 Mon Sep 17 00:00:00 2001 From: Theodore Ts'o Date: Thu, 26 Oct 2000 20:42:07 +0000 Subject: [PATCH] .del-jfs.h~fa6593e8, ChangeLog, jfs_compat.h, journal.c: jfs.h, jfs_compat.h, journal.c: Updated to include the definition of the new journal superblock format; still only supports V1 superblocks for now. (From sct) --- e2fsck/ChangeLog | 6 ++ e2fsck/jfs.h | 173 ++++++++++++++++++++++++++++++++-------------------- e2fsck/jfs_compat.h | 20 ++++++ e2fsck/journal.c | 8 +-- 4 files changed, 138 insertions(+), 69 deletions(-) diff --git a/e2fsck/ChangeLog b/e2fsck/ChangeLog index 07fa523..ae9a577 100644 --- a/e2fsck/ChangeLog +++ b/e2fsck/ChangeLog @@ -1,3 +1,9 @@ +2000-10-26 + + * jfs.h, jfs_compat.h, journal.c: Updated to include the + definition of the new journal superblock format; still + only supports V1 superblocks for now. (From sct) + 2000-10-24 * super.c (release_inode_block, release_inode_blocks, diff --git a/e2fsck/jfs.h b/e2fsck/jfs.h index 2d08977..ba67b62 100644 --- a/e2fsck/jfs.h +++ b/e2fsck/jfs.h @@ -27,11 +27,11 @@ /* #define JFS_DEBUG */ #ifdef JFS_DEBUG -extern int jfs_enable_debug; +extern int journal_enable_debug; #define jfs_debug(n, f, a...) \ do { \ - if ((n) <= jfs_enable_debug) { \ + if ((n) <= journal_enable_debug) { \ printk (KERN_DEBUG "JFS DEBUG: (%s, %d): %s: ", \ __FILE__, __LINE__, __FUNCTION__); \ printk (f, ## a); \ @@ -60,7 +60,8 @@ extern int jfs_enable_debug; #define JFS_DESCRIPTOR_BLOCK 1 #define JFS_COMMIT_BLOCK 2 -#define JFS_SUPERBLOCK 3 +#define JFS_SUPERBLOCK_V1 3 +#define JFS_SUPERBLOCK_V2 4 /* * Standard header for all descriptor blocks: @@ -90,26 +91,67 @@ typedef struct journal_block_tag_s /* - * The journal superblock + * The journal superblock. All fields are in big-endian byte order. */ typedef struct journal_superblock_s { +/* 0x0000 */ journal_header_t s_header; +/* 0x000C */ /* Static information describing the journal */ - __u32 s_blocksize; /* journal device blocksize */ - __u32 s_maxlen; /* total blocks in journal file */ - __u32 s_first; /* first block of log information */ + __u32 s_blocksize; /* journal device blocksize */ + __u32 s_maxlen; /* total blocks in journal file */ + __u32 s_first; /* first block of log information */ +/* 0x0018 */ /* Dynamic information describing the current state of the log */ - __u32 s_sequence; /* first commit ID expected in log */ - __u32 s_start; /* blocknr of start of log */ + __u32 s_sequence; /* first commit ID expected in log */ + __u32 s_start; /* blocknr of start of log */ + +/* 0x0020 */ + /* Error value, as set by journal_abort(). */ + __s32 s_errno; + +/* 0x0024 */ + /* Remaining fields are only valid in a version-2 superblock */ + __u32 s_feature_compat; /* compatible feature set */ + __u32 s_feature_incompat; /* incompatible feature set */ + __u32 s_feature_ro_compat; /* readonly-compatible feature set */ +/* 0x0030 */ + __u8 s_uuid[16]; /* 128-bit uuid for journal */ + +/* 0x0040 */ + __u32 s_nr_users; /* Nr of filesystems sharing log */ + __u32 s_dynsuper; /* Blocknr of dynamic superblock copy*/ + +/* 0x0048 */ + __u32 s_max_transaction; /* Limit of journal blocks per trans.*/ + __u32 s_max_trans_data; /* Limit of data blocks per trans. */ + +/* 0x0050 */ + __u32 s_padding[44]; + +/* 0x0100 */ + __u8 s_users[16*48]; /* ids of all fs'es sharing the log */ +/* 0x0400 */ } journal_superblock_t; +#define JFS_HAS_COMPAT_FEATURE(j,mask) \ + ((j)->j_format_version >= 2 && \ + ((j)->j_superblock->s_feature_compat & cpu_to_be32((mask)))) +#define JFS_HAS_RO_COMPAT_FEATURE(j,mask) \ + ((j)->j_format_version >= 2 && \ + ((j)->j_superblock->s_feature_ro_compat & cpu_to_be32((mask)))) +#define JFS_HAS_INCOMPAT_FEATURE(j,mask) \ + ((j)->j_format_version >= 2 && \ + ((j)->j_superblock->s_feature_incompat & cpu_to_be32((mask)))) + +#define JFS_FEATURE_INCOMPAT_REVOKE 0x00000001 + #ifdef __KERNEL__ -#include #include @@ -150,6 +192,7 @@ struct handle_s /* Flags */ unsigned int h_sync : 1; /* sync-on-close */ + unsigned int h_jdata : 1; /* force data journaling */ }; @@ -250,7 +293,6 @@ struct transaction_s * jiffies ? */ unsigned long t_expires; }; -#endif /* __KERNEL__ */ /* The journal_t maintains all of the journaling state information for a @@ -264,12 +306,18 @@ struct journal_s { /* General journaling state flags */ unsigned long j_flags; + + /* Is there an outstanding uncleared error on the journal (from + * a prior abort)? */ + int j_errno; /* The superblock buffer */ struct buffer_head * j_sb_buffer; journal_superblock_t * j_superblock; + + /* Version of the superblock format */ + int j_format_version; -#ifdef __KERNEL__ /* Transactions: The current running transaction... */ transaction_t * j_running_transaction; @@ -306,14 +354,6 @@ struct journal_s /* The lock flag is *NEVER* touched from interrupts. */ unsigned int j_locked : 1; - /* Pointer to the current commit thread for this journal */ - struct task_struct * j_task; - - /* The timer used to wakeup the commit thread: */ - struct timer_list * j_commit_timer; - int j_commit_timer_active; -#endif - /* Journal head: identifies the first unused block in the journal. */ unsigned long j_head; @@ -359,6 +399,9 @@ struct journal_s __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; @@ -367,15 +410,18 @@ struct journal_s * commit? */ unsigned long j_commit_interval; + /* The timer used to wakeup the commit thread: */ + struct timer_list * j_commit_timer; + int j_commit_timer_active; }; -#ifdef __KERNEL__ - /* * Journal flag definitions */ #define JFS_UNMOUNT 1 /* Journal thread is being destroyed */ #define JFS_SYNC 2 /* Perform synchronous transaction commits */ +#define JFS_ABORT 4 /* Journaling has been aborted for errors. */ +#define JFS_ACK_ERR 8 /* The errno in the sb has been acked */ /* * Journaling internal variables/parameters @@ -421,28 +467,16 @@ extern void put_transaction (transaction_t *); extern int set_transaction_state (transaction_t *, int); -/* - * Transaction 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. - */ - -static inline void __wait_on_journal (journal_t * journal) -{ - while (journal->j_locked) - sleep_on (&journal->j_wait_lock); -} - +/* Transaction locking */ +extern void __wait_on_journal (journal_t *); /* Journal locking. In 2.2, we assume that the kernel lock is already * held. */ static inline void lock_journal (journal_t * journal) { +#ifdef __SMP__ + J_ASSERT(current->lock_depth >= 0); +#endif if (journal->j_locked) __wait_on_journal(journal); journal->j_locked = 1; @@ -475,30 +509,6 @@ static inline int journal_is_buffer_shared(struct buffer_head *bh) return (count > 1); } -/* Debugging code only: */ - -#define jfs_ENOSYS() \ -do { \ - printk (KERN_ERR "JFS unimplemented function " __FUNCTION__); \ - current->state = TASK_UNINTERRUPTIBLE; \ - schedule(); \ -} while (1) - -/* 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 void 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 *); - - /* The journaling code user interface: * * Create and destroy handles @@ -518,14 +528,47 @@ extern void journal_forget (handle_t *, struct buffer_head *); extern void journal_sync_buffer (struct buffer_head *); extern int journal_stop (handle_t *); extern int journal_flush (journal_t *); +extern int journal_revoke (handle_t *, int); extern journal_t * journal_init_dev (kdev_t, 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_features (journal_t *, unsigned long, unsigned long, unsigned long); extern int journal_create (journal_t *); extern int journal_load (journal_t *); extern void journal_release (journal_t *); -extern void journal_update_superblock (journal_t *, int); -#endif /* __KERNEL__ */ extern int journal_recover (journal_t *); +extern void journal_update_superblock (journal_t *, int); +extern void __journal_abort (journal_t *); +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 *); + +/* 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 void 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 *); + + +/* Debugging code only: */ + +#define jfs_ENOSYS() \ +do { \ + printk (KERN_ERR "JFS unimplemented function " __FUNCTION__); \ + current->state = TASK_UNINTERRUPTIBLE; \ + schedule(); \ +} while (1) + +#endif /* __KERNEL__ */ #endif /* _LINUX_JFS_H */ diff --git a/e2fsck/jfs_compat.h b/e2fsck/jfs_compat.h index d0e1da5..6d35e55 100644 --- a/e2fsck/jfs_compat.h +++ b/e2fsck/jfs_compat.h @@ -33,6 +33,26 @@ struct inode { struct ext2_inode i_ext2; }; +struct journal_s +{ + unsigned long j_flags; + int j_errno; + struct buffer_head * j_sb_buffer; + struct journal_superblock_s *j_superblock; + unsigned long j_head; + unsigned long j_tail; + unsigned long j_free; + unsigned long j_first, j_last; + kdev_t j_dev; + int j_blocksize; + unsigned int j_blk_offset; + unsigned int j_maxlen; + struct inode * j_inode; + tid_t j_tail_sequence; + tid_t j_transaction_sequence; + __u8 j_uuid[16]; +}; + int bmap(struct inode *inode, int block); struct buffer_head *getblk(e2fsck_t ctx, blk_t blocknr, int blocksize); void ll_rw_block(int rw, int dummy, struct buffer_head *bh); diff --git a/e2fsck/journal.c b/e2fsck/journal.c index 8e318b0..9ff204c 100644 --- a/e2fsck/journal.c +++ b/e2fsck/journal.c @@ -26,7 +26,7 @@ #ifdef JFS_DEBUG static int bh_count = 0; -int jfs_enable_debug = 2; +int journal_enable_debug = 2; #endif int bmap(struct inode *inode, int block) @@ -318,14 +318,14 @@ static int e2fsck_journal_load(journal_t *journal) if (jsb->s_header.h_magic != htonl(JFS_MAGIC_NUMBER)) return e2fsck_journal_fix_bad_inode(ctx, &pctx); - if (jsb->s_header.h_blocktype != htonl(JFS_SUPERBLOCK) || + if (jsb->s_header.h_blocktype != htonl(JFS_SUPERBLOCK_V1) || jsb->s_blocksize != htonl(journal->j_blocksize)) { com_err(ctx->device_name, EXT2_ET_CORRUPT_SUPERBLOCK, _("%s: no valid journal superblock found\n")); return EXT2_ET_CORRUPT_SUPERBLOCK; } - if (jsb->s_header.h_blocktype != htonl(JFS_SUPERBLOCK)) { + if (jsb->s_header.h_blocktype != htonl(JFS_SUPERBLOCK_V1)) { pctx.num = ntohl(jsb->s_header.h_blocktype); return e2fsck_journal_fix_unsupported_super(ctx, &pctx); } @@ -351,7 +351,7 @@ void e2fsck_journal_reset_super(e2fsck_t ctx, journal_superblock_t *jsb, blk_t size) { jsb->s_header.h_magic = htonl(JFS_MAGIC_NUMBER); - jsb->s_header.h_blocktype = htonl(JFS_SUPERBLOCK); + jsb->s_header.h_blocktype = htonl(JFS_SUPERBLOCK_V1); jsb->s_blocksize = htonl(ctx->fs->blocksize); jsb->s_maxlen = htonl(size); jsb->s_first = 1; -- 1.8.3.1