diff options
Diffstat (limited to 'e2fsck')
-rw-r--r-- | e2fsck/ChangeLog | 9 | ||||
-rw-r--r-- | e2fsck/Makefile.in | 6 | ||||
-rw-r--r-- | e2fsck/jfs_compat.h | 77 | ||||
-rw-r--r-- | e2fsck/jfs_user.h | 61 | ||||
-rw-r--r-- | e2fsck/journal.c | 120 | ||||
-rw-r--r-- | e2fsck/recovery.c | 145 | ||||
-rw-r--r-- | e2fsck/revoke.c | 262 |
7 files changed, 378 insertions, 302 deletions
diff --git a/e2fsck/ChangeLog b/e2fsck/ChangeLog index 466ab46e..d42ff8fc 100644 --- a/e2fsck/ChangeLog +++ b/e2fsck/ChangeLog @@ -1,8 +1,15 @@ +2001-12-16 Theodore Tso <tytso@valinux.com> + + * recovery.c, revoke.c: Update to versions from 2.4.17-pre8. + + * journal.c, jfs_user.h: Update support code for new version of + recover.c and revoke.c. Fix support for filesystems with + external journals. + 2001-11-30 Gabriel Paubert <paubert@iram.es> * journal.c (e2fsck_journal_load): Fix an endianness bug. - 2001-11-26 Theodore Tso <tytso@valinux.com> * super.c (check_super_block): Make sure that if the inode table diff --git a/e2fsck/Makefile.in b/e2fsck/Makefile.in index 55394dea..a4e894fe 100644 --- a/e2fsck/Makefile.in +++ b/e2fsck/Makefile.in @@ -218,7 +218,7 @@ journal.o: $(srcdir)/journal.c $(srcdir)/jfs_user.h $(srcdir)/e2fsck.h \ $(top_srcdir)/lib/ext2fs/ext2_fs.h $(top_builddir)/lib/ext2fs/ext2_types.h \ $(top_srcdir)/lib/ext2fs/ext2fs.h $(top_srcdir)/lib/et/com_err.h \ $(top_srcdir)/lib/ext2fs/ext2_io.h $(top_builddir)/lib/ext2fs/ext2_err.h \ - $(top_srcdir)/lib/ext2fs/bitops.h $(top_srcdir)/include/linux/jfs.h \ + $(top_srcdir)/lib/ext2fs/bitops.h $(top_srcdir)/include/linux/jbd.h \ $(top_srcdir)/include/linux/jfs_compat.h \ $(top_srcdir)/include/linux/linked_list.h $(srcdir)/problem.h \ $(top_srcdir)/lib/uuid/uuid.h @@ -226,14 +226,14 @@ recovery.o: $(srcdir)/recovery.c $(srcdir)/jfs_user.h $(srcdir)/e2fsck.h \ $(top_srcdir)/lib/ext2fs/ext2_fs.h $(top_builddir)/lib/ext2fs/ext2_types.h \ $(top_srcdir)/lib/ext2fs/ext2fs.h $(top_srcdir)/lib/et/com_err.h \ $(top_srcdir)/lib/ext2fs/ext2_io.h $(top_builddir)/lib/ext2fs/ext2_err.h \ - $(top_srcdir)/lib/ext2fs/bitops.h $(top_srcdir)/include/linux/jfs.h \ + $(top_srcdir)/lib/ext2fs/bitops.h $(top_srcdir)/include/linux/jbd.h \ $(top_srcdir)/include/linux/jfs_compat.h \ $(top_srcdir)/include/linux/linked_list.h revoke.o: $(srcdir)/revoke.c $(srcdir)/jfs_user.h $(srcdir)/e2fsck.h \ $(top_srcdir)/lib/ext2fs/ext2_fs.h $(top_builddir)/lib/ext2fs/ext2_types.h \ $(top_srcdir)/lib/ext2fs/ext2fs.h $(top_srcdir)/lib/et/com_err.h \ $(top_srcdir)/lib/ext2fs/ext2_io.h $(top_builddir)/lib/ext2fs/ext2_err.h \ - $(top_srcdir)/lib/ext2fs/bitops.h $(top_srcdir)/include/linux/jfs.h \ + $(top_srcdir)/lib/ext2fs/bitops.h $(top_srcdir)/include/linux/jbd.h \ $(top_srcdir)/include/linux/jfs_compat.h \ $(top_srcdir)/include/linux/linked_list.h badblocks.o: $(srcdir)/badblocks.c $(top_srcdir)/lib/et/com_err.h \ diff --git a/e2fsck/jfs_compat.h b/e2fsck/jfs_compat.h deleted file mode 100644 index 6d35e553..00000000 --- a/e2fsck/jfs_compat.h +++ /dev/null @@ -1,77 +0,0 @@ - -#ifndef _JFS_COMPAT_H -#define _JFS_COMPAT_H - -#include "e2fsck.h" -#include <errno.h> - -#define printk printf -#define KERN_ERR "" -#define KERN_DEBUG "" - -#define READ 0 -#define WRITE 1 - -typedef int tid_t; -typedef e2fsck_t kdev_t; -typedef struct journal_s journal_t; - -struct buffer_head { - char b_data[8192]; - e2fsck_t b_ctx; - io_channel b_io; - int b_size; - blk_t b_blocknr; - int b_dirty; - int b_uptodate; - int b_err; -}; - -struct inode { - e2fsck_t i_ctx; - ino_t i_ino; - 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); -void mark_buffer_dirty(struct buffer_head *bh, int dummy); -void brelse(struct buffer_head *bh); -int buffer_uptodate(struct buffer_head *bh); -void wait_on_buffer(struct buffer_head *bh); -#define fsync_dev(dev) do {} while(0) -#define buffer_req(bh) 1 -#define do_readahead(journal, start) do {} while(0) - -extern e2fsck_t e2fsck_global_ctx; /* Try your very best not to use this! */ - -#define J_ASSERT(assert) \ - do { if (!(assert)) { \ - printf ("Assertion failure in %s() at %s line %d: " \ - "\"%s\"\n", \ - __FUNCTION__, __FILE__, __LINE__, # assert); \ - fatal_error(e2fsck_global_ctx, 0); \ - } } while (0) - -#endif /* _JFS_COMPAT_H */ diff --git a/e2fsck/jfs_user.h b/e2fsck/jfs_user.h index 356a0ec0..f02923b1 100644 --- a/e2fsck/jfs_user.h +++ b/e2fsck/jfs_user.h @@ -15,14 +15,14 @@ #include "e2fsck.h" struct buffer_head { - char b_data[8192]; - e2fsck_t b_ctx; - io_channel b_io; - int b_size; - blk_t b_blocknr; - int b_dirty; - int b_uptodate; - int b_err; + char b_data[8192]; + e2fsck_t b_ctx; + io_channel b_io; + int b_size; + blk_t b_blocknr; + int b_dirty; + int b_uptodate; + int b_err; }; struct inode { @@ -31,20 +31,17 @@ struct inode { struct ext2_inode i_ext2; }; -typedef e2fsck_t kdev_t; +struct kdev_s { + e2fsck_t k_ctx; + int k_dev; +}; -/* - * Kernel compatibility functions are defined in journal.c - */ -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[]); -void mark_buffer_dirty(struct buffer_head *bh, int dummy); -void mark_buffer_uptodate(struct buffer_head *bh, int val); -void brelse(struct buffer_head *bh); -int buffer_uptodate(struct buffer_head *bh); -void wait_on_buffer(struct buffer_head *bh); -#define fsync_dev(dev) do {} while(0) +#define K_DEV_FS 1 +#define K_DEV_JOURNAL 2 + +typedef struct kdev_s *kdev_t; + +#define fsync_no_super(dev) do {} while(0) #define buffer_req(bh) 1 #define do_readahead(journal, start) do {} while(0) @@ -57,6 +54,7 @@ typedef struct { #define kmem_cache_alloc(cache,flags) malloc((cache)->object_length) #define kmem_cache_free(cache,obj) free(obj) #define kmem_cache_create(name,len,a,b,c,d) do_cache_create(len) +#define kmem_cache_destroy(cache) do_cache_destroy(cache) #define kmalloc(len,flags) malloc(len) #define kfree(p) free(p) @@ -65,6 +63,7 @@ typedef struct { * functions. */ extern kmem_cache_t * do_cache_create(int len); +extern void do_cache_destroy(kmem_cache_t *cache); #if (defined(E2FSCK_INCLUDE_INLINE_FUNCS) || !defined(NO_INLINE_FUNCS)) #ifdef E2FSCK_INCLUDE_INLINE_FUNCS @@ -86,10 +85,28 @@ _INLINE_ kmem_cache_t * do_cache_create(int len) return new_cache; } +_INLINE_ void do_cache_destroy(kmem_cache_t *cache) +{ + free(cache); +} #undef _INLINE_ #endif +#define __init + /* * Now pull in the real linux/jfs.h definitions. */ -#include <linux/jfs.h> +#include <linux/jbd.h> + +/* + * Kernel compatibility functions are defined in journal.c + */ +int journal_bmap(journal_t *journal, blk_t block, unsigned long *phys); +struct buffer_head *getblk(kdev_t ctx, blk_t blocknr, int blocksize); +void ll_rw_block(int rw, int dummy, struct buffer_head *bh[]); +void mark_buffer_dirty(struct buffer_head *bh); +void mark_buffer_uptodate(struct buffer_head *bh, int val); +void brelse(struct buffer_head *bh); +int buffer_uptodate(struct buffer_head *bh); +void wait_on_buffer(struct buffer_head *bh); diff --git a/e2fsck/journal.c b/e2fsck/journal.c index 89b73ff4..a07c7c1d 100644 --- a/e2fsck/journal.c +++ b/e2fsck/journal.c @@ -25,7 +25,7 @@ #include "problem.h" #include "uuid/uuid.h" -#ifdef JFS_DEBUG /* Enabled by configure --enable-jfs-debug */ +#ifdef CONFIG_JBD_DEBUG /* Enabled by configure --enable-jfs-debug */ static int bh_count = 0; int journal_enable_debug = 2; #endif @@ -34,34 +34,39 @@ int journal_enable_debug = 2; * to use the recovery.c file virtually unchanged from the kernel, so we * don't have to do much to keep kernel and user recovery in sync. */ -int bmap(struct inode *inode, int block) +int journal_bmap(journal_t *journal, blk_t block, unsigned long *phys) { - int retval; - blk_t phys; - - retval = ext2fs_bmap(inode->i_ctx->fs, inode->i_ino, &inode->i_ext2, - NULL, 0, block, &phys); + struct inode *inode = journal->j_inode; + errcode_t retval; + blk_t pblk; - if (retval) - com_err(inode->i_ctx->device_name, retval, - _("bmap journal inode %ld, block %d\n"), - inode->i_ino, block); + if (!inode) { + *phys = block; + return 0; + } - return phys; + retval= ext2fs_bmap(inode->i_ctx->fs, inode->i_ino, + &inode->i_ext2, NULL, 0, block, &pblk); + *phys = pblk; + return (retval); } -struct buffer_head *getblk(e2fsck_t ctx, blk_t blocknr, int blocksize) +struct buffer_head *getblk(kdev_t kdev, blk_t blocknr, int blocksize) { struct buffer_head *bh; - bh = e2fsck_allocate_memory(ctx, sizeof(*bh), "block buffer"); + bh = e2fsck_allocate_memory(kdev->k_ctx, sizeof(*bh), "block buffer"); if (!bh) return NULL; jfs_debug(4, "getblk for block %lu (%d bytes)(total %d)\n", (unsigned long) blocknr, blocksize, ++bh_count); - bh->b_ctx = ctx; + bh->b_ctx = kdev->k_ctx; + if (kdev->k_dev == K_DEV_FS) + bh->b_io = kdev->k_ctx->fs->io; + else + bh->b_io = kdev->k_ctx->journal_io; bh->b_size = blocksize; bh->b_blocknr = blocknr; @@ -78,7 +83,7 @@ void ll_rw_block(int rw, int nr, struct buffer_head *bhp[]) if (rw == READ && !bh->b_uptodate) { jfs_debug(3, "reading block %lu/%p\n", (unsigned long) bh->b_blocknr, (void *) bh); - retval = io_channel_read_blk(bh->b_ctx->journal_io, + retval = io_channel_read_blk(bh->b_io, bh->b_blocknr, 1, bh->b_data); if (retval) { @@ -92,7 +97,7 @@ void ll_rw_block(int rw, int nr, struct buffer_head *bhp[]) } else if (rw == WRITE && bh->b_dirty) { jfs_debug(3, "writing block %lu/%p\n", (unsigned long) bh->b_blocknr, (void *) bh); - retval = io_channel_write_blk(bh->b_ctx->journal_io, + retval = io_channel_write_blk(bh->b_io, bh->b_blocknr, 1, bh->b_data); if (retval) { @@ -111,9 +116,9 @@ void ll_rw_block(int rw, int nr, struct buffer_head *bhp[]) } } -void mark_buffer_dirty(struct buffer_head *bh, int dummy) +void mark_buffer_dirty(struct buffer_head *bh) { - bh->b_dirty = dummy | 1; /* use dummy to avoid unused variable */ + bh->b_dirty = 1; } static void mark_buffer_clean(struct buffer_head * bh) @@ -161,10 +166,11 @@ static errcode_t e2fsck_journal_init_inode(e2fsck_t ctx, struct ext2_super_block *s, journal_t **journal) { - struct inode *inode; + struct inode *inode = NULL; struct buffer_head *bh; - blk_t start; + unsigned long start; int retval; + struct kdev_s *dev_fs = NULL, *dev_journal; jfs_debug(1, "Using journal inode %u\n", s->s_journal_inum); *journal = e2fsck_allocate_memory(ctx, sizeof(journal_t), "journal"); @@ -172,19 +178,31 @@ static errcode_t e2fsck_journal_init_inode(e2fsck_t ctx, return EXT2_ET_NO_MEMORY; } + dev_fs = e2fsck_allocate_memory(ctx, 2*sizeof(struct kdev_s), "kdev"); + if (!dev_fs) { + retval = EXT2_ET_NO_MEMORY; + goto errout; + } + dev_journal = dev_fs+1; + inode = e2fsck_allocate_memory(ctx, sizeof(*inode), "journal inode"); if (!inode) { retval = EXT2_ET_NO_MEMORY; - goto exit_journal; + goto errout; } inode->i_ctx = ctx; inode->i_ino = s->s_journal_inum; retval = ext2fs_read_inode(ctx->fs, s->s_journal_inum, &inode->i_ext2); if (retval) - goto exit_inode; + goto errout; - (*journal)->j_dev = ctx; + dev_fs->k_ctx = dev_journal->k_ctx = ctx; + dev_fs->k_dev = K_DEV_FS; + dev_journal->k_dev = K_DEV_JOURNAL; + + (*journal)->j_dev = dev_journal; + (*journal)->j_fs_dev = dev_fs; (*journal)->j_inode = inode; (*journal)->j_blocksize = ctx->fs->blocksize; (*journal)->j_maxlen = inode->i_ext2.i_size / (*journal)->j_blocksize; @@ -193,26 +211,27 @@ static errcode_t e2fsck_journal_init_inode(e2fsck_t ctx, if (!inode->i_ext2.i_links_count || !LINUX_S_ISREG(inode->i_ext2.i_mode) || (*journal)->j_maxlen < JFS_MIN_JOURNAL_BLOCKS || - (start = bmap(inode, 0)) == 0) { - retval = EXT2_ET_BAD_INODE_NUM; - goto exit_inode; + (retval = journal_bmap(*journal, 0, &start)) != 0) { + goto errout; } - bh = getblk(ctx, start, (*journal)->j_blocksize); + bh = getblk(dev_journal, start, (*journal)->j_blocksize); if (!bh) { retval = EXT2_ET_NO_MEMORY; - goto exit_inode; + goto errout; } (*journal)->j_sb_buffer = bh; (*journal)->j_superblock = (journal_superblock_t *)bh->b_data; return 0; -exit_inode: - ext2fs_free_mem((void **)&inode); -exit_journal: - ext2fs_free_mem((void **)journal); - +errout: + if (dev_fs) + ext2fs_free_mem((void **)&dev_fs); + if (inode) + ext2fs_free_mem((void **)&inode); + if (journal) + ext2fs_free_mem((void **)journal); return retval; } @@ -228,7 +247,17 @@ static errcode_t e2fsck_journal_init_dev(e2fsck_t ctx, struct ext2_super_block jsuper; struct problem_context pctx; const char *journal_name; + struct kdev_s *dev_fs = NULL, *dev_journal; + dev_fs = e2fsck_allocate_memory(ctx, 2*sizeof(struct kdev_s), "kdev"); + if (!dev_fs) { + return EXT2_ET_NO_MEMORY; + } + dev_journal = dev_fs+1; + dev_fs->k_ctx = dev_journal->k_ctx = ctx; + dev_fs->k_dev = K_DEV_FS; + dev_journal->k_dev = K_DEV_JOURNAL; + clear_problem_context(&pctx); journal_name = ctx->journal_name; if (!journal_name) @@ -255,7 +284,7 @@ static errcode_t e2fsck_journal_init_dev(e2fsck_t ctx, io_channel_set_blksize(ctx->journal_io, blocksize); start = (blocksize == 1024) ? 1 : 0; - bh = getblk(ctx, start, blocksize); + bh = getblk(dev_journal, start, blocksize); if (!bh) return EXT2_ET_NO_MEMORY; ll_rw_block(READ, 1, &bh); @@ -285,12 +314,13 @@ static errcode_t e2fsck_journal_init_dev(e2fsck_t ctx, return EXT2_ET_NO_MEMORY; } - (*journal)->j_dev = ctx; + (*journal)->j_dev = dev_journal; + (*journal)->j_fs_dev = dev_fs; (*journal)->j_inode = NULL; (*journal)->j_blocksize = ctx->fs->blocksize; (*journal)->j_maxlen = jsuper.s_blocks_count; - bh = getblk(ctx, start+1, (*journal)->j_blocksize); + bh = getblk(dev_journal, start+1, (*journal)->j_blocksize); if (!bh) { retval = EXT2_ET_NO_MEMORY; goto errout; @@ -301,6 +331,7 @@ static errcode_t e2fsck_journal_init_dev(e2fsck_t ctx, return 0; errout: + ext2fs_free_mem((void **)&dev_fs); ext2fs_free_mem((void **)journal); return retval; } @@ -354,8 +385,7 @@ static errcode_t e2fsck_journal_fix_bad_inode(e2fsck_t ctx, #define V1_SB_SIZE 0x0024 static void clear_v2_journal_fields(journal_t *journal) { - e2fsck_t ctx = journal->j_dev; - struct buffer_head *jbh = journal->j_sb_buffer; + e2fsck_t ctx = journal->j_dev->k_ctx; struct problem_context pctx; clear_problem_context(&pctx); @@ -365,13 +395,13 @@ static void clear_v2_journal_fields(journal_t *journal) memset(((char *) journal->j_superblock) + V1_SB_SIZE, 0, ctx->fs->blocksize-V1_SB_SIZE); - mark_buffer_dirty(journal->j_sb_buffer, 1); + mark_buffer_dirty(journal->j_sb_buffer); } static errcode_t e2fsck_journal_load(journal_t *journal) { - e2fsck_t ctx = journal->j_dev; + e2fsck_t ctx = journal->j_dev->k_ctx; journal_superblock_t *jsb; struct buffer_head *jbh = journal->j_sb_buffer; struct problem_context pctx; @@ -501,7 +531,7 @@ static void e2fsck_journal_reset_super(e2fsck_t ctx, journal_superblock_t *jsb, new_seq ^= u.val[i]; jsb->s_sequence = htonl(new_seq); - mark_buffer_dirty(journal->j_sb_buffer, 1); + mark_buffer_dirty(journal->j_sb_buffer); ll_rw_block(WRITE, 1, &journal->j_sb_buffer); } @@ -542,7 +572,7 @@ static void e2fsck_journal_release(e2fsck_t ctx, journal_t *journal, jsb->s_sequence = htonl(journal->j_transaction_sequence); if (reset) jsb->s_start = 0; /* this marks the journal as empty */ - mark_buffer_dirty(journal->j_sb_buffer, 1); + mark_buffer_dirty(journal->j_sb_buffer); } brelse(journal->j_sb_buffer); @@ -665,6 +695,7 @@ static errcode_t recover_ext3_journal(e2fsck_t ctx) journal_t *journal; int retval; + journal_init_revoke_caches(); retval = e2fsck_get_journal(ctx, &journal); if (retval) return retval; @@ -685,10 +716,11 @@ static errcode_t recover_ext3_journal(e2fsck_t ctx) ctx->fs->super->s_state |= EXT2_ERROR_FS; ext2fs_mark_super_dirty(ctx->fs); journal->j_superblock->s_errno = 0; - mark_buffer_dirty(journal->j_sb_buffer, 1); + mark_buffer_dirty(journal->j_sb_buffer); } errout: + journal_destroy_revoke_caches(); e2fsck_journal_release(ctx, journal, 1, 0); return retval; } diff --git a/e2fsck/recovery.c b/e2fsck/recovery.c index cabf278f..e8e41630 100644 --- a/e2fsck/recovery.c +++ b/e2fsck/recovery.c @@ -18,11 +18,10 @@ #else #include <linux/sched.h> #include <linux/fs.h> -#include <linux/jfs.h> +#include <linux/jbd.h> #include <linux/errno.h> -#include <linux/malloc.h> +#include <linux/slab.h> #include <linux/locks.h> -#include <linux/buffer.h> #endif /* @@ -40,13 +39,15 @@ struct recovery_info }; enum passtype {PASS_SCAN, PASS_REVOKE, PASS_REPLAY}; -static int do_one_pass(journal_t *, struct recovery_info *, enum passtype); -static int scan_revoke_records(journal_t *, struct buffer_head *, tid_t, struct recovery_info *); +static int do_one_pass(journal_t *journal, + struct recovery_info *info, enum passtype pass); +static int scan_revoke_records(journal_t *, struct buffer_head *, + tid_t, struct recovery_info *); #ifdef __KERNEL__ /* Release readahead buffers after use */ -static void brelse_array(struct buffer_head *b[], int n) +void journal_brelse_array(struct buffer_head *b[], int n) { while (--n >= 0) brelse (b[n]); @@ -69,7 +70,8 @@ static void brelse_array(struct buffer_head *b[], int n) static int do_readahead(journal_t *journal, unsigned int start) { int err; - unsigned int max, nbufs, next, blocknr; + unsigned int max, nbufs, next; + unsigned long blocknr; struct buffer_head *bh; struct buffer_head * bufs[MAXBUF]; @@ -85,16 +87,14 @@ static int do_readahead(journal_t *journal, unsigned int start) nbufs = 0; for (next = start; next < max; next++) { - blocknr = next; - if (journal->j_inode) - blocknr = bmap(journal->j_inode, next); - if (!blocknr) { - printk (KERN_ERR "JFS: bad block at offset %u\n", + err = journal_bmap(journal, next, &blocknr); + + if (err) { + printk (KERN_ERR "JBD: bad block at offset %u\n", next); - err = -EIO; goto failed; } - + bh = getblk(journal->j_dev, blocknr, journal->j_blocksize); if (!bh) { err = -ENOMEM; @@ -105,7 +105,7 @@ static int do_readahead(journal_t *journal, unsigned int start) bufs[nbufs++] = bh; if (nbufs == MAXBUF) { ll_rw_block(READ, nbufs, bufs); - brelse_array(bufs, nbufs); + journal_brelse_array(bufs, nbufs); nbufs = 0; } } else @@ -115,10 +115,10 @@ static int do_readahead(journal_t *journal, unsigned int start) if (nbufs) ll_rw_block(READ, nbufs, bufs); err = 0; - + failed: if (nbufs) - brelse_array(bufs, nbufs); + journal_brelse_array(bufs, nbufs); return err; } @@ -132,27 +132,26 @@ failed: static int jread(struct buffer_head **bhp, journal_t *journal, unsigned int offset) { - unsigned int blocknr; + int err; + unsigned long blocknr; struct buffer_head *bh; *bhp = NULL; J_ASSERT (offset < journal->j_maxlen); - - blocknr = offset; - if (journal->j_inode) - blocknr = bmap(journal->j_inode, offset); - if (!blocknr) { - printk (KERN_ERR "JFS: bad block at offset %u\n", + err = journal_bmap(journal, offset, &blocknr); + + if (err) { + printk (KERN_ERR "JBD: bad block at offset %u\n", offset); - return -EIO; + return err; } - + bh = getblk(journal->j_dev, blocknr, journal->j_blocksize); if (!bh) return -ENOMEM; - + if (!buffer_uptodate(bh)) { /* If this is a brand new buffer, start readahead. Otherwise, we assume we are already reading it. */ @@ -160,14 +159,14 @@ static int jread(struct buffer_head **bhp, journal_t *journal, do_readahead(journal, offset); wait_on_buffer(bh); } - + if (!buffer_uptodate(bh)) { - printk (KERN_ERR "JFS: Failed to read block at offset %u\n", + printk (KERN_ERR "JBD: Failed to read block at offset %u\n", offset); brelse(bh); return -EIO; } - + *bhp = bh; return 0; } @@ -182,12 +181,12 @@ static int count_tags(struct buffer_head *bh, int size) char * tagp; journal_block_tag_t * tag; int nr = 0; - + tagp = &bh->b_data[sizeof(journal_header_t)]; - + while ((tagp - bh->b_data + sizeof(journal_block_tag_t)) <= size) { tag = (journal_block_tag_t *) tagp; - + nr++; tagp += sizeof(journal_block_tag_t); if (!(tag->t_flags & htonl(JFS_FLAG_SAME_UUID))) @@ -196,7 +195,7 @@ static int count_tags(struct buffer_head *bh, int size) if (tag->t_flags & htonl(JFS_FLAG_LAST_TAG)) break; } - + return nr; } @@ -237,7 +236,7 @@ int journal_recover(journal_t *journal) */ if (!sb->s_start) { - jfs_debug(1, "No recovery required, last transaction %d\n", + jbd_debug(1, "No recovery required, last transaction %d\n", ntohl(sb->s_sequence)); journal->j_transaction_sequence = ntohl(sb->s_sequence) + 1; return 0; @@ -250,10 +249,10 @@ int journal_recover(journal_t *journal) if (!err) err = do_one_pass(journal, &info, PASS_REPLAY); - jfs_debug(0, "JFS: recovery, exit status %d, " + jbd_debug(0, "JBD: recovery, exit status %d, " "recovered transactions %u to %u\n", err, info.start_transaction, info.end_transaction); - jfs_debug(0, "JFS: Replayed %d and revoked %d/%d blocks\n", + jbd_debug(0, "JBD: Replayed %d and revoked %d/%d blocks\n", info.nr_replays, info.nr_revoke_hits, info.nr_revokes); /* Restart the log at the next transaction ID, thus invalidating @@ -261,7 +260,7 @@ int journal_recover(journal_t *journal) journal->j_transaction_sequence = ++info.end_transaction; journal_clear_revoke(journal); - fsync_dev(journal->j_dev); + fsync_no_super(journal->j_fs_dev); return err; } @@ -284,19 +283,21 @@ int journal_skip_recovery(journal_t *journal) struct recovery_info info; - memset(&info, 0, sizeof(info)); + memset (&info, 0, sizeof(info)); sb = journal->j_superblock; err = do_one_pass(journal, &info, PASS_SCAN); if (err) { - printk(KERN_ERR "JFS: error %d scanning journal\n", err); + printk(KERN_ERR "JBD: error %d scanning journal\n", err); ++journal->j_transaction_sequence; } else { +#ifdef CONFIG_JBD_DEBUG int dropped = info.end_transaction - ntohl(sb->s_sequence); +#endif - jfs_debug(0, - "JFS: ignoring %d transaction%s from the journal.\n", + jbd_debug(0, + "JBD: ignoring %d transaction%s from the journal.\n", dropped, (dropped == 1) ? "" : "s"); journal->j_transaction_sequence = ++info.end_transaction; } @@ -306,8 +307,8 @@ int journal_skip_recovery(journal_t *journal) return err; } -static int do_one_pass(journal_t *journal, struct recovery_info *info, - enum passtype pass) +static int do_one_pass(journal_t *journal, + struct recovery_info *info, enum passtype pass) { unsigned int first_commit_ID, next_commit_ID; @@ -337,9 +338,9 @@ static int do_one_pass(journal_t *journal, struct recovery_info *info, first_commit_ID = next_commit_ID; if (pass == PASS_SCAN) info->start_transaction = first_commit_ID; - - jfs_debug(1, "Starting recovery pass %d\n", pass); - + + jbd_debug(1, "Starting recovery pass %d\n", pass); + /* * Now we walk through the log, transaction by transaction, * making sure that each transaction has a commit block in the @@ -361,19 +362,19 @@ static int do_one_pass(journal_t *journal, struct recovery_info *info, if (pass != PASS_SCAN) if (tid_geq(next_commit_ID, info->end_transaction)) break; - - jfs_debug(2, "Scanning for sequence ID %u at %lu/%lu\n", + + jbd_debug(2, "Scanning for sequence ID %u at %lu/%lu\n", next_commit_ID, next_log_block, journal->j_last); /* Skip over each chunk of the transaction looking * either the next descriptor block or the final commit * record. */ - jfs_debug(3, "JFS: checking block %ld\n", next_log_block); + jbd_debug(3, "JBD: checking block %ld\n", next_log_block); err = jread(&bh, journal, next_log_block); if (err) goto failed; - + next_log_block++; wrap(journal, next_log_block); @@ -383,16 +384,16 @@ static int do_one_pass(journal_t *journal, struct recovery_info *info, * expected sequence number. Otherwise, we're all done * here. */ - tmp = (journal_header_t *) bh->b_data; + tmp = (journal_header_t *)bh->b_data; if (tmp->h_magic != htonl(JFS_MAGIC_NUMBER)) { brelse(bh); break; } - + blocktype = ntohl(tmp->h_blocktype); sequence = ntohl(tmp->h_sequence); - jfs_debug(3, "Found magic %d, sequence %d\n", + jbd_debug(3, "Found magic %d, sequence %d\n", blocktype, sequence); if (sequence != next_commit_ID) { @@ -403,14 +404,15 @@ static int do_one_pass(journal_t *journal, struct recovery_info *info, /* OK, we have a valid descriptor block which matches * all of the sequence number checks. What are we going * to do with it? That depends on the pass... */ - + switch(blocktype) { case JFS_DESCRIPTOR_BLOCK: /* If it is a valid descriptor block, replay it * in pass REPLAY; otherwise, just skip over the * blocks it describes. */ if (pass != PASS_REPLAY) { - next_log_block += count_tags(bh, journal->j_blocksize); + next_log_block += + count_tags(bh, journal->j_blocksize); wrap(journal, next_log_block); brelse(bh); continue; @@ -424,7 +426,7 @@ static int do_one_pass(journal_t *journal, struct recovery_info *info, while ((tagp - bh->b_data +sizeof(journal_block_tag_t)) <= journal->j_blocksize) { unsigned long io_block; - + tag = (journal_block_tag_t *) tagp; flags = ntohl(tag->t_flags); @@ -436,7 +438,7 @@ static int do_one_pass(journal_t *journal, struct recovery_info *info, * report failure at the end. */ success = err; printk (KERN_ERR - "JFS: IO error %d recovering " + "JBD: IO error %d recovering " "block %ld in log\n", err, io_block); } else { @@ -458,11 +460,11 @@ static int do_one_pass(journal_t *journal, struct recovery_info *info, /* Find a buffer for the new * data being restored */ - nbh = getblk(journal->j_dev, blocknr, + nbh = getblk(journal->j_fs_dev, blocknr, journal->j_blocksize); if (nbh == NULL) { printk(KERN_ERR - "JFS: Out of memory " + "JBD: Out of memory " "during recovery.\n"); err = -ENOMEM; brelse(bh); @@ -470,13 +472,16 @@ static int do_one_pass(journal_t *journal, struct recovery_info *info, goto failed; } - memcpy(nbh->b_data, obh->b_data, - journal->j_blocksize); + memcpy(nbh->b_data, obh->b_data, + journal->j_blocksize); if (flags & JFS_FLAG_ESCAPE) { - * ((unsigned int *) bh->b_data) = htonl(JFS_MAGIC_NUMBER); + *((unsigned int *)bh->b_data) = + htonl(JFS_MAGIC_NUMBER); } - - mark_buffer_dirty(nbh, 1); + + BUFFER_TRACE(nbh, "marking dirty"); + mark_buffer_dirty(nbh); + BUFFER_TRACE(nbh, "marking uptodate"); mark_buffer_uptodate(nbh, 1); ++info->nr_replays; /* ll_rw_block(WRITE, 1, &nbh); */ @@ -495,7 +500,7 @@ static int do_one_pass(journal_t *journal, struct recovery_info *info, brelse(bh); continue; - + case JFS_COMMIT_BLOCK: /* Found an expected commit block: not much to * do other than move on to the next sequence @@ -512,7 +517,7 @@ static int do_one_pass(journal_t *journal, struct recovery_info *info, continue; } - err = scan_revoke_records(journal, bh, + err = scan_revoke_records(journal, bh, next_commit_ID, info); brelse(bh); if (err) @@ -520,7 +525,7 @@ static int do_one_pass(journal_t *journal, struct recovery_info *info, continue; default: - jfs_debug(3, "Unrecognised magic %d, end of scan.\n", + jbd_debug(3, "Unrecognised magic %d, end of scan.\n", blocktype); goto done; } @@ -540,7 +545,7 @@ static int do_one_pass(journal_t *journal, struct recovery_info *info, /* It's really bad news if different passes end up at * different places (but possible due to IO errors). */ if (info->end_transaction != next_commit_ID) { - printk (KERN_ERR "JFS: recovery pass %d ended at " + printk (KERN_ERR "JBD: recovery pass %d ended at " "transaction %u, expected %u\n", pass, next_commit_ID, info->end_transaction); if (!success) @@ -562,7 +567,7 @@ static int scan_revoke_records(journal_t *journal, struct buffer_head *bh, { journal_revoke_header_t *header; int offset, max; - + header = (journal_revoke_header_t *) bh->b_data; offset = sizeof(journal_revoke_header_t); max = ntohl(header->r_count); diff --git a/e2fsck/revoke.c b/e2fsck/revoke.c index cdcf8efb..9866935f 100644 --- a/e2fsck/revoke.c +++ b/e2fsck/revoke.c @@ -50,11 +50,11 @@ * Revoke information on buffers is a tri-state value: * * RevokeValid clear: no cached revoke status, need to look it up - * RevokeValid set, Revoke clear: + * RevokeValid set, Revoked clear: * buffer has not been revoked, and cancel_revoke * need do nothing. - * RevokeValid set, Revoke set: - * buffer has been revoked. + * RevokeValid set, Revoked set: + * buffer has been revoked. */ #ifndef __KERNEL__ @@ -62,12 +62,13 @@ #else #include <linux/sched.h> #include <linux/fs.h> -#include <linux/jfs.h> +#include <linux/jbd.h> #include <linux/errno.h> #include <linux/slab.h> #include <linux/locks.h> -#include <linux/buffer.h> #include <linux/list.h> +#include <linux/smp_lock.h> +#include <linux/init.h> #endif static kmem_cache_t *revoke_record_cache; @@ -77,7 +78,7 @@ static kmem_cache_t *revoke_table_cache; journal replay, this involves recording the transaction ID of the last transaction to revoke this block. */ -struct jfs_revoke_record_s +struct jbd_revoke_record_s { struct list_head hash; tid_t sequence; /* Used for recovery only */ @@ -86,7 +87,7 @@ struct jfs_revoke_record_s /* The revoke table is just a simple hash table of revoke records. */ -struct jfs_revoke_table_s +struct jbd_revoke_table_s { /* It is conceivable that we might want a larger hash table * for recovery. Must be a power of two. */ @@ -98,9 +99,9 @@ struct jfs_revoke_table_s #ifdef __KERNEL__ static void write_one_revoke_record(journal_t *, transaction_t *, - struct buffer_head **, int *, - struct jfs_revoke_record_s *); -static void flush_descriptor(journal_t *, struct buffer_head *, int); + struct journal_head **, int *, + struct jbd_revoke_record_s *); +static void flush_descriptor(journal_t *, struct journal_head *, int); #endif /* Utility functions to maintain the revoke table */ @@ -108,7 +109,7 @@ static void flush_descriptor(journal_t *, struct buffer_head *, int); /* Borrowed from buffer.c: this is a tried and tested block hash function */ static inline int hash(journal_t *journal, unsigned long block) { - struct jfs_revoke_table_s *table = journal->j_revoke; + struct jbd_revoke_table_s *table = journal->j_revoke; int hash_shift = table->hash_shift; return ((block << (hash_shift - 6)) ^ @@ -116,43 +117,80 @@ static inline int hash(journal_t *journal, unsigned long block) (block << (hash_shift - 12))) & (table->hash_size - 1); } -static int insert_revoke_hash(journal_t *journal, - unsigned long blocknr, tid_t seq) +int insert_revoke_hash(journal_t *journal, unsigned long blocknr, tid_t seq) { struct list_head *hash_list; - struct jfs_revoke_record_s *record; - - record = kmem_cache_alloc(revoke_record_cache, GFP_KERNEL); + struct jbd_revoke_record_s *record; + +repeat: + record = kmem_cache_alloc(revoke_record_cache, GFP_NOFS); if (!record) - return -ENOMEM; + goto oom; record->sequence = seq; record->blocknr = blocknr; hash_list = &journal->j_revoke->hash_table[hash(journal, blocknr)]; list_add(&record->hash, hash_list); return 0; + +oom: +#ifdef __KERNEL__ + if (!journal_oom_retry) + return -ENOMEM; + jbd_debug(1, "ENOMEM in " __FUNCTION__ ", retrying.\n"); + current->policy |= SCHED_YIELD; + schedule(); + goto repeat; +#else + return -ENOMEM; +#endif } /* Find a revoke record in the journal's hash table. */ -static struct jfs_revoke_record_s *find_revoke_record(journal_t *journal, +static struct jbd_revoke_record_s *find_revoke_record(journal_t *journal, unsigned long blocknr) { struct list_head *hash_list; - struct jfs_revoke_record_s *record; + struct jbd_revoke_record_s *record; hash_list = &journal->j_revoke->hash_table[hash(journal, blocknr)]; - record = (struct jfs_revoke_record_s *) hash_list->next; + record = (struct jbd_revoke_record_s *) hash_list->next; while (&(record->hash) != hash_list) { if (record->blocknr == blocknr) return record; - record = (struct jfs_revoke_record_s *) record->hash.next; + record = (struct jbd_revoke_record_s *) record->hash.next; } return NULL; } +int __init journal_init_revoke_caches(void) +{ + revoke_record_cache = kmem_cache_create("revoke_record", + sizeof(struct jbd_revoke_record_s), + 0, SLAB_HWCACHE_ALIGN, NULL, NULL); + if (revoke_record_cache == 0) + return -ENOMEM; + revoke_table_cache = kmem_cache_create("revoke_table", + sizeof(struct jbd_revoke_table_s), + 0, 0, NULL, NULL); + if (revoke_table_cache == 0) { + kmem_cache_destroy(revoke_record_cache); + revoke_record_cache = NULL; + return -ENOMEM; + } + return 0; +} + +void journal_destroy_revoke_caches(void) +{ + kmem_cache_destroy(revoke_record_cache); + revoke_record_cache = 0; + kmem_cache_destroy(revoke_table_cache); + revoke_table_cache = 0; +} /* Initialise the revoke table for a given journal to a given size. */ @@ -162,21 +200,6 @@ int journal_init_revoke(journal_t *journal, int hash_size) J_ASSERT (journal->j_revoke == NULL); - if (!revoke_record_cache) - revoke_record_cache = - kmem_cache_create ("revoke_record", - sizeof(struct jfs_revoke_record_s), - 0, SLAB_HWCACHE_ALIGN, NULL, NULL); - - if (!revoke_table_cache) - revoke_table_cache = - kmem_cache_create ("revoke_table", - sizeof(struct jfs_revoke_table_s), - 0, 0, NULL, NULL); - - if (!revoke_record_cache || !revoke_table_cache) - return -ENOMEM; - journal->j_revoke = kmem_cache_alloc(revoke_table_cache, GFP_KERNEL); if (!journal->j_revoke) return -ENOMEM; @@ -210,7 +233,7 @@ int journal_init_revoke(journal_t *journal, int hash_size) void journal_destroy_revoke(journal_t *journal) { - struct jfs_revoke_table_s *table; + struct jbd_revoke_table_s *table; struct list_head *hash_list; int i; @@ -248,51 +271,87 @@ void journal_destroy_revoke(journal_t *journal) * parameter, but does _not_ forget the buffer_head if the bh was only * found implicitly. * - * Revoke must observe the same synchronisation rules as bforget: it - * must not discard the buffer once it has blocked. + * bh_in may not be a journalled buffer - it may have come off + * the hash tables without an attached journal_head. + * + * If bh_in is non-zero, journal_revoke() will decrement its b_count + * by one. */ int journal_revoke(handle_t *handle, unsigned long blocknr, struct buffer_head *bh_in) { - struct buffer_head *bh; + struct buffer_head *bh = NULL; journal_t *journal; kdev_t dev; int err; + if (bh_in) + BUFFER_TRACE(bh_in, "enter"); + journal = handle->h_transaction->t_journal; if (!journal_set_features(journal, 0, 0, JFS_FEATURE_INCOMPAT_REVOKE)){ J_ASSERT (!"Cannot set revoke feature!"); return -EINVAL; } - - dev = journal->j_dev; + + dev = journal->j_fs_dev; bh = bh_in; - if (!bh) + if (!bh) { bh = get_hash_table(dev, blocknr, journal->j_blocksize); + if (bh) + BUFFER_TRACE(bh, "found on hash"); + } +#ifdef JBD_EXPENSIVE_CHECKING + else { + struct buffer_head *bh2; + + /* If there is a different buffer_head lying around in + * memory anywhere... */ + bh2 = get_hash_table(dev, blocknr, journal->j_blocksize); + if (bh2) { + /* ... and it has RevokeValid status... */ + if ((bh2 != bh) && + test_bit(BH_RevokeValid, &bh2->b_state)) + /* ...then it better be revoked too, + * since it's illegal to create a revoke + * record against a buffer_head which is + * not marked revoked --- that would + * risk missing a subsequent revoke + * cancel. */ + J_ASSERT_BH(bh2, test_bit(BH_Revoked, & + bh2->b_state)); + __brelse(bh2); + } + } +#endif /* We really ought not ever to revoke twice in a row without first having the revoke cancelled: it's illegal to free a block twice without allocating it in between! */ if (bh) { - J_ASSERT (!test_and_set_bit(BH_Revoked, &bh->b_state)); + J_ASSERT_BH(bh, !test_bit(BH_Revoked, &bh->b_state)); + set_bit(BH_Revoked, &bh->b_state); set_bit(BH_RevokeValid, &bh->b_state); - if (bh_in) + if (bh_in) { + BUFFER_TRACE(bh_in, "call journal_forget"); journal_forget(handle, bh_in); - else - brelse(bh); + } else { + BUFFER_TRACE(bh, "call brelse"); + __brelse(bh); + } } lock_journal(journal); - err = insert_revoke_hash(journal, blocknr, - handle->h_transaction->t_tid); + jbd_debug(2, "insert revoke for block %lu, bh_in=%p\n", blocknr, bh_in); + err = insert_revoke_hash(journal, blocknr, + handle->h_transaction->t_tid); unlock_journal(journal); - + BUFFER_TRACE(bh_in, "exit"); return err; } - /* * Cancel an outstanding revoke. For use only internally by the * journaling code (called from journal_get_write_access). @@ -309,16 +368,17 @@ int journal_revoke(handle_t *handle, unsigned long blocknr, * set. * * The caller must have the journal locked. - * */ - -void journal_cancel_revoke(handle_t *handle, struct buffer_head *bh) + */ +int journal_cancel_revoke(handle_t *handle, struct journal_head *jh) { - struct jfs_revoke_record_s *record; + struct jbd_revoke_record_s *record; journal_t *journal = handle->h_transaction->t_journal; int need_cancel; + int did_revoke = 0; /* akpm: debug */ + struct buffer_head *bh = jh2bh(jh); - J_ASSERT (journal->j_locked); - + jbd_debug(4, "journal_head %p, cancelling revoke\n", jh); + /* Is the existing Revoke bit valid? If so, we trust it, and * only perform the full cancel if the revoke bit is set. If * not, we can't trust the revoke bit, and we need to do the @@ -329,14 +389,38 @@ void journal_cancel_revoke(handle_t *handle, struct buffer_head *bh) need_cancel = 1; clear_bit(BH_Revoked, &bh->b_state); } - + if (need_cancel) { record = find_revoke_record(journal, bh->b_blocknr); if (record) { + jbd_debug(4, "cancelled existing revoke on " + "blocknr %lu\n", bh->b_blocknr); list_del(&record->hash); kmem_cache_free(revoke_record_cache, record); + did_revoke = 1; } } + +#ifdef JBD_EXPENSIVE_CHECKING + /* There better not be one left behind by now! */ + record = find_revoke_record(journal, bh->b_blocknr); + J_ASSERT_JH(jh, record == NULL); +#endif + + /* Finally, have we just cleared revoke on an unhashed + * buffer_head? If so, we'd better make sure we clear the + * revoked status on any hashed alias too, otherwise the revoke + * state machine will get very upset later on. */ + if (need_cancel && !bh->b_pprev) { + struct buffer_head *bh2; + bh2 = get_hash_table(bh->b_dev, bh->b_blocknr, bh->b_size); + if (bh2) { + clear_bit(BH_Revoked, &bh2->b_state); + __brelse(bh2); + } + } + + return did_revoke; } @@ -350,12 +434,12 @@ void journal_cancel_revoke(handle_t *handle, struct buffer_head *bh) void journal_write_revoke_records(journal_t *journal, transaction_t *transaction) { - struct buffer_head *descriptor; - struct jfs_revoke_record_s *record; - struct jfs_revoke_table_s *revoke; + struct journal_head *descriptor; + struct jbd_revoke_record_s *record; + struct jbd_revoke_table_s *revoke; struct list_head *hash_list; int i, offset, count; - + descriptor = NULL; offset = 0; count = 0; @@ -365,7 +449,7 @@ void journal_write_revoke_records(journal_t *journal, hash_list = &revoke->hash_table[i]; while (!list_empty(hash_list)) { - record = (struct jfs_revoke_record_s *) + record = (struct jbd_revoke_record_s *) hash_list->next; write_one_revoke_record(journal, transaction, &descriptor, &offset, @@ -377,7 +461,7 @@ void journal_write_revoke_records(journal_t *journal, } if (descriptor) flush_descriptor(journal, descriptor, offset); - jfs_debug(1, "Wrote %d revoke records\n", count); + jbd_debug(1, "Wrote %d revoke records\n", count); } /* @@ -387,24 +471,24 @@ void journal_write_revoke_records(journal_t *journal, static void write_one_revoke_record(journal_t *journal, transaction_t *transaction, - struct buffer_head **descriptorp, + struct journal_head **descriptorp, int *offsetp, - struct jfs_revoke_record_s *record) + struct jbd_revoke_record_s *record) { - struct buffer_head *descriptor; + struct journal_head *descriptor; int offset; journal_header_t *header; - + /* If we are already aborting, this all becomes a noop. We still need to go round the loop in journal_write_revoke_records in order to free all of the revoke records: only the IO to the journal is omitted. */ - if (is_journal_abort(journal)) + if (is_journal_aborted(journal)) return; descriptor = *descriptorp; offset = *offsetp; - + /* Make sure we have a descriptor with space left for the record */ if (descriptor) { if (offset == journal->j_blocksize) { @@ -415,19 +499,22 @@ static void write_one_revoke_record(journal_t *journal, if (!descriptor) { descriptor = journal_get_descriptor_buffer(journal); - header = (journal_header_t *) &descriptor->b_data[0]; + if (!descriptor) + return; + header = (journal_header_t *) &jh2bh(descriptor)->b_data[0]; header->h_magic = htonl(JFS_MAGIC_NUMBER); header->h_blocktype = htonl(JFS_REVOKE_BLOCK); header->h_sequence = htonl(transaction->t_tid); /* Record it so that we can wait for IO completion later */ + JBUFFER_TRACE(descriptor, "file as BJ_LogCtl"); journal_file_buffer(descriptor, transaction, BJ_LogCtl); - + offset = sizeof(journal_revoke_header_t); *descriptorp = descriptor; } - * ((unsigned int *)(&descriptor->b_data[offset])) = + * ((unsigned int *)(&jh2bh(descriptor)->b_data[offset])) = htonl(record->blocknr); offset += 4; *offsetp = offset; @@ -441,20 +528,25 @@ static void write_one_revoke_record(journal_t *journal, */ static void flush_descriptor(journal_t *journal, - struct buffer_head *descriptor, + struct journal_head *descriptor, int offset) { journal_revoke_header_t *header; - - if (is_journal_abort(journal)) { - brelse(descriptor); + + if (is_journal_aborted(journal)) { + JBUFFER_TRACE(descriptor, "brelse"); + __brelse(jh2bh(descriptor)); return; } - header = (journal_revoke_header_t *) descriptor->b_data; + header = (journal_revoke_header_t *) jh2bh(descriptor)->b_data; header->r_count = htonl(offset); - set_bit(BH_JWrite, &descriptor->b_state); - ll_rw_block (WRITE, 1, &descriptor); + set_bit(BH_JWrite, &jh2bh(descriptor)->b_state); + { + struct buffer_head *bh = jh2bh(descriptor); + BUFFER_TRACE(bh, "write"); + ll_rw_block (WRITE, 1, &bh); + } } #endif @@ -485,7 +577,7 @@ int journal_set_revoke(journal_t *journal, unsigned long blocknr, tid_t sequence) { - struct jfs_revoke_record_s *record; + struct jbd_revoke_record_s *record; record = find_revoke_record(journal, blocknr); if (record) { @@ -509,7 +601,7 @@ int journal_test_revoke(journal_t *journal, unsigned long blocknr, tid_t sequence) { - struct jfs_revoke_record_s *record; + struct jbd_revoke_record_s *record; record = find_revoke_record(journal, blocknr); if (!record) @@ -528,15 +620,15 @@ void journal_clear_revoke(journal_t *journal) { int i; struct list_head *hash_list; - struct jfs_revoke_record_s *record; - struct jfs_revoke_table_s *revoke; + struct jbd_revoke_record_s *record; + struct jbd_revoke_table_s *revoke; revoke = journal->j_revoke; for (i = 0; i < revoke->hash_size; i++) { hash_list = &revoke->hash_table[i]; while (!list_empty(hash_list)) { - record = (struct jfs_revoke_record_s*) hash_list->next; + record = (struct jbd_revoke_record_s*) hash_list->next; list_del(&record->hash); kmem_cache_free(revoke_record_cache, record); } |