r2029 - trunk/kernel/source/kernel-source-2.6.8-2.6.8/debian/patches
Andres Salomon
dilinger-guest@haydn.debian.org
Thu, 23 Dec 2004 02:03:27 -0700
Author: dilinger-guest
Date: 2004-12-23 02:03:11 -0700 (Thu, 23 Dec 2004)
New Revision: 2029
Added:
trunk/kernel/source/kernel-source-2.6.8-2.6.8/debian/patches/reiserfs-sucks-2.dpatch
Removed:
trunk/kernel/source/kernel-source-2.6.8-2.6.8/debian/patches/reiserfs-sucks.dpatch
Log:
moving patches out of the way
Copied: trunk/kernel/source/kernel-source-2.6.8-2.6.8/debian/patches/reiserfs-sucks-2.dpatch (from rev 2021, trunk/kernel/source/kernel-source-2.6.8-2.6.8/debian/patches/reiserfs-sucks.dpatch)
Deleted: trunk/kernel/source/kernel-source-2.6.8-2.6.8/debian/patches/reiserfs-sucks.dpatch
===================================================================
--- trunk/kernel/source/kernel-source-2.6.8-2.6.8/debian/patches/reiserfs-sucks.dpatch 2004-12-23 09:02:28 UTC (rev 2028)
+++ trunk/kernel/source/kernel-source-2.6.8-2.6.8/debian/patches/reiserfs-sucks.dpatch 2004-12-23 09:03:11 UTC (rev 2029)
@@ -1,2997 +0,0 @@
-#! /bin/sh -e
-## <PATCHNAME>.dpatch by <PATCH_AUTHOR@EMAI>
-##
-## All lines beginning with `## DP:' are a description of the patch.
-## DP: Description: ReiserFS: Add I/O error handling to journal operations
-## DP: Patch author: Jeff Mahoney <jeffm@novell.com>
-## DP: Upstream status: backported
-
-. $(dirname $0)/DPATCH
-
-@DPATCH@
-# This is a BitKeeper generated diff -Nru style patch.
-#
-# ChangeSet
-# 2004/10/18 23:07:45-07:00 jeffm@novell.com
-# [PATCH] ReiserFS: Add I/O error handling to journal operations
-#
-# This patch allows ReiserFS to handle I/O errors in the journal (or journal
-# flush) where it would have previously panicked. The new behavior is to
-# mark the filesystem read-only, disallow new transactions to be started, and
-# to allow existing transactions to complete (though not to commit). The
-# resultant filesystem can be safely umounted, and checked via normal
-# mechanisms. As it is a journaling filesystem, the filesystem itself will
-# be in a similar state to the power being cut to the machine, once umounted.
-#
-# Signed-off-by: Jeff Mahoney <jeffm@novell.com>
-# Signed-off-by: Andrew Morton <akpm@osdl.org>
-# Signed-off-by: Linus Torvalds <torvalds@osdl.org>
-#
-# fs/reiserfs/bitmap.c
-# 2004/10/18 22:26:49-07:00 jeffm@novell.com +13 -0
-# ReiserFS: Add I/O error handling to journal operations
-#
-# fs/reiserfs/dir.c
-# 2004/10/18 22:26:49-07:00 jeffm@novell.com +5 -2
-# ReiserFS: Add I/O error handling to journal operations
-#
-# fs/reiserfs/file.c
-# 2004/10/18 22:26:49-07:00 jeffm@novell.com +103 -24
-# ReiserFS: Add I/O error handling to journal operations
-#
-# fs/reiserfs/inode.c
-# 2004/10/18 22:26:49-07:00 jeffm@novell.com +149 -47
-# ReiserFS: Add I/O error handling to journal operations
-#
-# fs/reiserfs/journal.c
-# 2004/10/18 22:26:49-07:00 jeffm@novell.com +260 -95
-# ReiserFS: Add I/O error handling to journal operations
-#
-# fs/reiserfs/namei.c
-# 2004/10/18 22:28:07-07:00 jeffm@novell.com +108 -47
-# ReiserFS: Add I/O error handling to journal operations
-#
-# fs/reiserfs/objectid.c
-# 2004/10/18 22:26:49-07:00 jeffm@novell.com +2 -0
-# ReiserFS: Add I/O error handling to journal operations
-#
-# fs/reiserfs/prints.c
-# 2004/10/18 22:26:49-07:00 jeffm@novell.com +43 -0
-# ReiserFS: Add I/O error handling to journal operations
-#
-# fs/reiserfs/resize.c
-# 2004/10/18 22:26:49-07:00 jeffm@novell.com +18 -8
-# ReiserFS: Add I/O error handling to journal operations
-#
-# fs/reiserfs/stree.c
-# 2004/10/18 22:26:49-07:00 jeffm@novell.com +46 -11
-# ReiserFS: Add I/O error handling to journal operations
-#
-# fs/reiserfs/super.c
-# 2004/10/18 22:26:49-07:00 jeffm@novell.com +99 -37
-# ReiserFS: Add I/O error handling to journal operations
-#
-# fs/reiserfs/tail_conversion.c
-# 2004/10/18 22:26:49-07:00 jeffm@novell.com +3 -0
-# ReiserFS: Add I/O error handling to journal operations
-#
-# include/linux/reiserfs_fs.h
-# 2004/10/18 22:26:49-07:00 jeffm@novell.com +9 -6
-# ReiserFS: Add I/O error handling to journal operations
-#
-# include/linux/reiserfs_fs_sb.h
-# 2004/10/18 22:26:49-07:00 jeffm@novell.com +26 -0
-# ReiserFS: Add I/O error handling to journal operations
-#
-diff -Nru a/fs/reiserfs/bitmap.c b/fs/reiserfs/bitmap.c
---- a/fs/reiserfs/bitmap.c 2004-12-22 22:53:54 -08:00
-+++ b/fs/reiserfs/bitmap.c 2004-12-22 22:53:54 -08:00
-@@ -137,6 +137,8 @@
- int end, next;
- int org = *beg;
-
-+ BUG_ON (!th->t_trans_id);
-+
- RFALSE(bmap_n >= SB_BMAP_NR (s), "Bitmap %d is out of range (0..%d)",bmap_n, SB_BMAP_NR (s) - 1);
- PROC_INFO_INC( s, scan_bitmap.bmap );
- /* this is unclear and lacks comments, explain how journal bitmaps
-@@ -290,6 +292,8 @@
- int end_bm, end_off;
- int off_max = s->s_blocksize << 3;
-
-+ BUG_ON (!th->t_trans_id);
-+
- PROC_INFO_INC( s, scan_bitmap.call );
- if ( SB_FREE_BLOCKS(s) <= 0)
- return 0; // No point in looking for more free blocks
-@@ -348,6 +352,8 @@
- struct reiserfs_bitmap_info *apbi;
- int nr, offset;
-
-+ BUG_ON (!th->t_trans_id);
-+
- PROC_INFO_INC( s, free_block );
-
- rs = SB_DISK_SUPER_BLOCK (s);
-@@ -389,6 +395,8 @@
- {
- struct super_block * s = th->t_super;
-
-+ BUG_ON (!th->t_trans_id);
-+
- RFALSE(!s, "vs-4061: trying to free block on nonexistent device");
- RFALSE(is_reusable (s, block, 1) == 0, "vs-4071: can not free such block");
- /* mark it before we clear it, just in case */
-@@ -401,6 +409,7 @@
- struct inode *inode, b_blocknr_t block) {
- RFALSE(!th->t_super, "vs-4060: trying to free block on nonexistent device");
- RFALSE(is_reusable (th->t_super, block, 1) == 0, "vs-4070: can not free such block");
-+ BUG_ON (!th->t_trans_id);
- _reiserfs_free_block(th, inode, block, 1) ;
- }
-
-@@ -410,6 +419,7 @@
- unsigned long save = ei->i_prealloc_block ;
- int dirty = 0;
- struct inode *inode = &ei->vfs_inode;
-+ BUG_ON (!th->t_trans_id);
- #ifdef CONFIG_REISERFS_CHECK
- if (ei->i_prealloc_count < 0)
- reiserfs_warning (th->t_super, "zam-4001:%s: inode has negative prealloc blocks count.", __FUNCTION__ );
-@@ -431,6 +441,7 @@
- struct inode *inode)
- {
- struct reiserfs_inode_info *ei = REISERFS_I(inode);
-+ BUG_ON (!th->t_trans_id);
- if (ei->i_prealloc_count)
- __discard_prealloc(th, ei);
- }
-@@ -438,6 +449,8 @@
- void reiserfs_discard_all_prealloc (struct reiserfs_transaction_handle *th)
- {
- struct list_head * plist = &SB_JOURNAL(th->t_super)->j_prealloc_list;
-+
-+ BUG_ON (!th->t_trans_id);
-
- while (!list_empty(plist)) {
- struct reiserfs_inode_info *ei;
-diff -Nru a/fs/reiserfs/dir.c b/fs/reiserfs/dir.c
---- a/fs/reiserfs/dir.c 2004-12-22 22:53:54 -08:00
-+++ b/fs/reiserfs/dir.c 2004-12-22 22:53:54 -08:00
-@@ -26,10 +26,13 @@
-
- int reiserfs_dir_fsync(struct file *filp, struct dentry *dentry, int datasync) {
- struct inode *inode = dentry->d_inode;
-+ int err;
- reiserfs_write_lock(inode->i_sb);
-- reiserfs_commit_for_inode(inode) ;
-+ err = reiserfs_commit_for_inode(inode) ;
- reiserfs_write_unlock(inode->i_sb) ;
-- return 0 ;
-+ if (err < 0)
-+ return err;
-+ return 0;
- }
-
-
-diff -Nru a/fs/reiserfs/file.c b/fs/reiserfs/file.c
---- a/fs/reiserfs/file.c 2004-12-22 22:53:54 -08:00
-+++ b/fs/reiserfs/file.c 2004-12-22 22:53:54 -08:00
-@@ -35,6 +35,8 @@
- {
-
- struct reiserfs_transaction_handle th ;
-+ int err;
-+ int jbegin_failure = 0;
-
- if (!S_ISREG (inode->i_mode))
- BUG ();
-@@ -49,26 +51,58 @@
-
- reiserfs_write_lock(inode->i_sb);
- down (&inode->i_sem);
-- journal_begin(&th, inode->i_sb, JOURNAL_PER_BALANCE_CNT * 3) ;
-+ /* freeing preallocation only involves relogging blocks that
-+ * are already in the current transaction. preallocation gets
-+ * freed at the end of each transaction, so it is impossible for
-+ * us to log any additional blocks
-+ */
-+ err = journal_begin(&th, inode->i_sb, 1);
-+ if (err) {
-+ /* uh oh, we can't allow the inode to go away while there
-+ * is still preallocation blocks pending. Try to join the
-+ * aborted transaction
-+ */
-+ jbegin_failure = err;
-+ err = journal_join_abort(&th, inode->i_sb, 1);
-+
-+ if (err) {
-+ /* hmpf, our choices here aren't good. We can pin the inode
-+ * which will disallow unmount from every happening, we can
-+ * do nothing, which will corrupt random memory on unmount,
-+ * or we can forcibly remove the file from the preallocation
-+ * list, which will leak blocks on disk. Lets pin the inode
-+ * and let the admin know what is going on.
-+ */
-+ igrab(inode);
-+ reiserfs_warning(inode->i_sb, "pinning inode %lu because the "
-+ "preallocation can't be freed");
-+ goto out;
-+ }
-+ }
- reiserfs_update_inode_transaction(inode) ;
-
- #ifdef REISERFS_PREALLOCATE
- reiserfs_discard_prealloc (&th, inode);
- #endif
-- journal_end(&th, inode->i_sb, JOURNAL_PER_BALANCE_CNT * 3) ;
-+ err = journal_end(&th, inode->i_sb, 1);
-
-- if (atomic_read(&inode->i_count) <= 1 &&
-+ /* copy back the error code from journal_begin */
-+ if (!err)
-+ err = jbegin_failure;
-+
-+ if (!err && atomic_read(&inode->i_count) <= 1 &&
- (REISERFS_I(inode)->i_flags & i_pack_on_close_mask) &&
- tail_has_to_be_packed (inode)) {
- /* if regular file is released by last holder and it has been
- appended (we append by unformatted node only) or its direct
- item(s) had to be converted, then it may have to be
- indirect2direct converted */
-- reiserfs_truncate_file(inode, 0) ;
-+ err = reiserfs_truncate_file(inode, 0) ;
- }
-+out:
- up (&inode->i_sem);
- reiserfs_write_unlock(inode->i_sb);
-- return 0;
-+ return err;
- }
-
- static void reiserfs_vfs_truncate_file(struct inode *inode) {
-@@ -99,6 +133,8 @@
- reiserfs_write_unlock(p_s_inode->i_sb);
- if (barrier_done != 1)
- blkdev_issue_flush(p_s_inode->i_sb->s_bdev, NULL);
-+ if (barrier_done < 0)
-+ return barrier_done;
- return ( n_err < 0 ) ? -EIO : 0;
- }
-
-@@ -146,7 +182,6 @@
- // of the fact that we already prepared
- // current block for journal
- int will_prealloc = 0;
--
- RFALSE(!blocks_to_allocate, "green-9004: tried to allocate zero blocks?");
-
- /* only preallocate if this is a small write */
-@@ -166,7 +201,9 @@
- /* If we came here, it means we absolutely need to open a transaction,
- since we need to allocate some blocks */
- reiserfs_write_lock(inode->i_sb); // Journaling stuff and we need that.
-- journal_begin(th, inode->i_sb, JOURNAL_PER_BALANCE_CNT * 3 + 1); // Wish I know if this number enough
-+ res = journal_begin(th, inode->i_sb, JOURNAL_PER_BALANCE_CNT * 3 + 1); // Wish I know if this number enough
-+ if (res)
-+ goto error_exit;
- reiserfs_update_inode_transaction(inode) ;
-
- /* Look for the in-tree position of our write, need path for block allocator */
-@@ -194,7 +231,9 @@
- /* We flush the transaction in case of no space. This way some
- blocks might become free */
- SB_JOURNAL(inode->i_sb)->j_must_wait = 1;
-- restart_transaction(th, inode, &path);
-+ res = restart_transaction(th, inode, &path);
-+ if (res)
-+ goto error_exit;
-
- /* We might have scheduled, so search again */
- res = search_for_position_by_key(inode->i_sb, &key, &path);
-@@ -322,8 +361,14 @@
- }
- /* Now we want to check if transaction is too full, and if it is
- we restart it. This will also free the path. */
-- if (journal_transaction_should_end(th, th->t_blocks_allocated))
-- restart_transaction(th, inode, &path);
-+ if (journal_transaction_should_end(th, th->t_blocks_allocated)) {
-+ res = restart_transaction(th, inode, &path);
-+ if (res) {
-+ pathrelse (&path);
-+ kfree(zeros);
-+ goto error_exit;
-+ }
-+ }
-
- /* Well, need to recalculate path and stuff */
- set_cpu_key_k_offset( &key, cpu_key_k_offset(&key) + (to_paste << inode->i_blkbits));
-@@ -349,6 +394,7 @@
- // we are going to overwrite, so there is nothing to scan through for holes.
- for ( curr_block = 0, itempos = path.pos_in_item ; curr_block < blocks_to_allocate && res == POSITION_FOUND ; ) {
- retry:
-+
- if ( itempos >= ih_item_len(ih)/UNFM_P_SIZE ) {
- /* We run out of data in this indirect item, let's look for another
- one. */
-@@ -526,8 +572,14 @@
- reiserfs_free_block(th, inode, le32_to_cpu(allocated_blocks[i]), 1);
-
- error_exit:
-- reiserfs_update_sd(th, inode); // update any changes we made to blk count
-- journal_end(th, inode->i_sb, JOURNAL_PER_BALANCE_CNT * 3 + 1);
-+ if (th->t_trans_id) {
-+ int err;
-+ // update any changes we made to blk count
-+ reiserfs_update_sd(th, inode);
-+ err = journal_end(th, inode->i_sb, JOURNAL_PER_BALANCE_CNT * 3 + 1);
-+ if (err)
-+ res = err;
-+ }
- reiserfs_write_unlock(inode->i_sb);
- kfree(allocated_blocks);
-
-@@ -602,13 +654,16 @@
- struct super_block *s = inode->i_sb;
- int bh_per_page = PAGE_CACHE_SIZE / s->s_blocksize;
- struct reiserfs_transaction_handle th;
-- th.t_trans_id = 0;
-+ int ret = 0;
-
-+ th.t_trans_id = 0;
- blocksize = 1 << inode->i_blkbits;
-
- if (logit) {
- reiserfs_write_lock(s);
-- journal_begin(&th, s, bh_per_page + 1);
-+ ret = journal_begin(&th, s, bh_per_page + 1);
-+ if (ret)
-+ goto drop_write_lock;
- reiserfs_update_inode_transaction(inode);
- }
- for(bh = head = page_buffers(page), block_start = 0;
-@@ -640,7 +695,8 @@
- }
- }
- if (logit) {
-- journal_end(&th, s, bh_per_page + 1);
-+ ret = journal_end(&th, s, bh_per_page + 1);
-+drop_write_lock:
- reiserfs_write_unlock(s);
- }
- /*
-@@ -651,7 +707,7 @@
- */
- if (!partial)
- SetPageUptodate(page);
-- return 0;
-+ return ret;
- }
-
-
-@@ -717,7 +773,9 @@
- reiserfs_write_lock(inode->i_sb);
- if (!sd_update)
- reiserfs_update_sd(th, inode);
-- journal_end(th, th->t_super, th->t_blocks_allocated);
-+ status = journal_end(th, th->t_super, th->t_blocks_allocated);
-+ if (status)
-+ retval = status;
- reiserfs_write_unlock(inode->i_sb);
- }
- th->t_trans_id = 0;
-@@ -1100,6 +1158,7 @@
- size_t already_written = 0; // Number of bytes already written to the file.
- loff_t pos; // Current position in the file.
- ssize_t res; // return value of various functions that we call.
-+ int err = 0;
- struct inode *inode = file->f_dentry->d_inode; // Inode of the file that we are writing to.
- /* To simplify coding at this time, we store
- locked pages in array for now */
-@@ -1114,24 +1173,40 @@
- If we will crash while doing direct io, finish_unfinished will
- cut the garbage from the file end. */
- reiserfs_write_lock(inode->i_sb);
-- journal_begin(&th, inode->i_sb, JOURNAL_PER_BALANCE_CNT );
-+ err = journal_begin(&th, inode->i_sb, JOURNAL_PER_BALANCE_CNT );
-+ if (err) {
-+ reiserfs_write_unlock (inode->i_sb);
-+ return err;
-+ }
- reiserfs_update_inode_transaction(inode);
- add_save_link (&th, inode, 1 /* Truncate */);
-- journal_end(&th, inode->i_sb, JOURNAL_PER_BALANCE_CNT );
-- reiserfs_write_unlock(inode->i_sb);
- after_file_end = 1;
-+ err = journal_end(&th, inode->i_sb, JOURNAL_PER_BALANCE_CNT );
-+ reiserfs_write_unlock(inode->i_sb);
-+ if (err)
-+ return err;
- }
- result = generic_file_write(file, buf, count, ppos);
-
- if ( after_file_end ) { /* Now update i_size and remove the savelink */
- struct reiserfs_transaction_handle th;
- reiserfs_write_lock(inode->i_sb);
-- journal_begin(&th, inode->i_sb, 1);
-+ err = journal_begin(&th, inode->i_sb, 1);
-+ if (err) {
-+ reiserfs_write_unlock (inode->i_sb);
-+ return err;
-+ }
- reiserfs_update_inode_transaction(inode);
- reiserfs_update_sd(&th, inode);
-- journal_end(&th, inode->i_sb, 1);
-- remove_save_link (inode, 1/* truncate */);
-+ err = journal_end(&th, inode->i_sb, 1);
-+ if (err) {
-+ reiserfs_write_unlock (inode->i_sb);
-+ return err;
-+ }
-+ err = remove_save_link (inode, 1/* truncate */);
- reiserfs_write_unlock(inode->i_sb);
-+ if (err)
-+ return err;
- }
-
- return result;
-@@ -1280,8 +1355,12 @@
- /* this is only true on error */
- if (th.t_trans_id) {
- reiserfs_write_lock(inode->i_sb);
-- journal_end(&th, th.t_super, th.t_blocks_allocated);
-+ err = journal_end(&th, th.t_super, th.t_blocks_allocated);
- reiserfs_write_unlock(inode->i_sb);
-+ if (err) {
-+ res = err;
-+ goto out;
-+ }
- }
-
- if ((file->f_flags & O_SYNC) || IS_SYNC(inode))
-diff -Nru a/fs/reiserfs/inode.c b/fs/reiserfs/inode.c
---- a/fs/reiserfs/inode.c 2004-12-22 22:53:54 -08:00
-+++ b/fs/reiserfs/inode.c 2004-12-22 22:53:54 -08:00
-@@ -47,21 +47,32 @@
-
- reiserfs_delete_xattrs (inode);
-
-- journal_begin(&th, inode->i_sb, jbegin_count) ;
-+ if (journal_begin(&th, inode->i_sb, jbegin_count)) {
-+ up (&inode->i_sem);
-+ goto out;
-+ }
- reiserfs_update_inode_transaction(inode) ;
-
-- reiserfs_delete_object (&th, inode);
-+ if (reiserfs_delete_object (&th, inode)) {
-+ up (&inode->i_sem);
-+ goto out;
-+ }
-
-- journal_end(&th, inode->i_sb, jbegin_count) ;
-+ if (journal_end(&th, inode->i_sb, jbegin_count)) {
-+ up (&inode->i_sem);
-+ goto out;
-+ }
-
- up (&inode->i_sem);
-
- /* all items of file are deleted, so we can remove "save" link */
-- remove_save_link (inode, 0/* not truncate */);
-+ remove_save_link (inode, 0/* not truncate */); /* we can't do anything
-+ * about an error here */
- } else {
- /* no object items are in the tree */
- ;
- }
-+out:
- clear_inode (inode); /* note this must go after the journal_end to prevent deadlock */
- inode->i_blocks = 0;
- reiserfs_write_unlock(inode->i_sb);
-@@ -201,20 +212,28 @@
- return 0;
- }
-
--/*static*/ void restart_transaction(struct reiserfs_transaction_handle *th,
-+/*static*/ int restart_transaction(struct reiserfs_transaction_handle *th,
- struct inode *inode, struct path *path) {
- struct super_block *s = th->t_super ;
- int len = th->t_blocks_allocated ;
-+ int err;
-+
-+ BUG_ON (!th->t_trans_id);
-+ BUG_ON (!th->t_refcount);
-
- /* we cannot restart while nested */
- if (th->t_refcount > 1) {
-- return ;
-+ return 0 ;
- }
- pathrelse(path) ;
- reiserfs_update_sd(th, inode) ;
-- journal_end(th, s, len) ;
-- journal_begin(th, s, JOURNAL_PER_BALANCE_CNT * 6) ;
-- reiserfs_update_inode_transaction(inode) ;
-+ err = journal_end(th, s, len) ;
-+ if (!err) {
-+ err = journal_begin(th, s, JOURNAL_PER_BALANCE_CNT * 6) ;
-+ if (!err)
-+ reiserfs_update_inode_transaction(inode) ;
-+ }
-+ return err;
- }
-
- // it is called by get_block when create == 0. Returns block number
-@@ -443,9 +462,11 @@
-
- ret = reiserfs_get_block(inode, iblock, bh_result,
- create | GET_BLOCK_NO_DANGLE) ;
-+ if (ret)
-+ goto out;
-
- /* don't allow direct io onto tail pages */
-- if (ret == 0 && buffer_mapped(bh_result) && bh_result->b_blocknr == 0) {
-+ if (buffer_mapped(bh_result) && bh_result->b_blocknr == 0) {
- /* make sure future calls to the direct io funcs for this offset
- ** in the file fail by unmapping the buffer
- */
-@@ -455,11 +476,15 @@
- /* Possible unpacked tail. Flush the data before pages have
- disappeared */
- if (REISERFS_I(inode)->i_flags & i_pack_on_close_mask) {
-+ int err;
- lock_kernel();
-- reiserfs_commit_for_inode(inode);
-+ err = reiserfs_commit_for_inode(inode);
- REISERFS_I(inode)->i_flags &= ~i_pack_on_close_mask;
- unlock_kernel();
-+ if (err < 0)
-+ ret = err;
- }
-+out:
- return ret ;
- }
-
-@@ -539,6 +564,7 @@
- b_blocknr_t *allocated_block_nr,
- struct path * path,
- int flags) {
-+ BUG_ON (!th->t_trans_id);
-
- #ifdef REISERFS_PREALLOCATE
- if (!(flags & GET_BLOCK_NO_ISEM)) {
-@@ -551,7 +577,7 @@
- int reiserfs_get_block (struct inode * inode, sector_t block,
- struct buffer_head * bh_result, int create)
- {
-- int repeat, retval;
-+ int repeat, retval = 0;
- b_blocknr_t allocated_block_nr = 0;// b_blocknr_t is (unsigned) 32 bit int
- INITIALIZE_PATH(path);
- int pos_in_item;
-@@ -655,7 +681,9 @@
- ** research if we succeed on the second try
- */
- SB_JOURNAL(inode->i_sb)->j_next_async_flush = 1;
-- restart_transaction(th, inode, &path) ;
-+ retval = restart_transaction(th, inode, &path) ;
-+ if (retval)
-+ goto failure;
- repeat = _allocate_block(th, block, inode, &allocated_block_nr, NULL, create);
-
- if (repeat != NO_DISK_SPACE && repeat != QUOTA_EXCEEDED) {
-@@ -696,8 +724,9 @@
- }
- set_block_dev_mapped(bh_result, unfm_ptr, inode);
- pathrelse (&path);
-+ retval = 0;
- if (!dangle && th)
-- reiserfs_end_persistent_transaction(th);
-+ retval = reiserfs_end_persistent_transaction(th);
-
- reiserfs_write_unlock(inode->i_sb);
-
-@@ -705,7 +734,7 @@
- ** there is no need to make sure the inode is updated with this
- ** transaction
- */
-- return 0;
-+ return retval;
- }
-
- if (!th) {
-@@ -766,9 +795,12 @@
- * ugly, but we can only end the transaction if
- * we aren't nested
- */
-+ BUG_ON (!th->t_refcount);
- if (th->t_refcount == 1) {
-- reiserfs_end_persistent_transaction(th);
-+ retval = reiserfs_end_persistent_transaction(th);
- th = NULL;
-+ if (retval)
-+ goto failure;
- }
-
- retval = convert_tail_for_hole(inode, bh_result, tail_offset) ;
-@@ -898,7 +930,9 @@
- ** ending their transaction will be able to continue.
- */
- if (journal_transaction_should_end(th, th->t_blocks_allocated)) {
-- restart_transaction(th, inode, &path) ;
-+ retval = restart_transaction(th, inode, &path) ;
-+ if (retval)
-+ goto failure;
- }
- /* inserting indirect pointers for a hole can take a
- ** long time. reschedule if needed
-@@ -929,10 +963,15 @@
- retval = 0;
-
- failure:
-- if (th && !dangle) {
-- reiserfs_update_sd(th, inode) ;
-- reiserfs_end_persistent_transaction(th);
-+ if (th && (!dangle || (retval && !th->t_trans_id))) {
-+ int err;
-+ if (th->t_trans_id)
-+ reiserfs_update_sd(th, inode);
-+ err = reiserfs_end_persistent_transaction(th);
-+ if (err)
-+ retval = err;
- }
-+
- reiserfs_write_unlock(inode->i_sb);
- reiserfs_check_path(&path) ;
- return retval;
-@@ -1215,6 +1254,8 @@
- struct item_head *ih, tmp_ih ;
- int retval;
-
-+ BUG_ON (!th->t_trans_id);
-+
- make_cpu_key (&key, inode, SD_OFFSET, TYPE_STAT_DATA, 3);//key type is unimportant
-
- for(;;) {
-@@ -1508,12 +1549,8 @@
- struct reiserfs_transaction_handle th ;
- int jbegin_count = 1 ;
-
-- if (inode->i_sb->s_flags & MS_RDONLY) {
-- reiserfs_warning (inode->i_sb,
-- "clm-6005: writing inode %lu on readonly FS",
-- inode->i_ino) ;
-+ if (inode->i_sb->s_flags & MS_RDONLY)
- return -EROFS;
-- }
- /* memory pressure can sometimes initiate write_inode calls with sync == 1,
- ** these cases are just when the system needs ram, not when the
- ** inode needs to reach disk for safety, and they can safely be
-@@ -1521,9 +1558,10 @@
- */
- if (do_sync && !(current->flags & PF_MEMALLOC)) {
- reiserfs_write_lock(inode->i_sb);
-- journal_begin(&th, inode->i_sb, jbegin_count) ;
-- reiserfs_update_sd (&th, inode);
-- journal_end_sync(&th, inode->i_sb, jbegin_count) ;
-+ if (!journal_begin(&th, inode->i_sb, jbegin_count)) {
-+ reiserfs_update_sd (&th, inode);
-+ journal_end_sync(&th, inode->i_sb, jbegin_count) ;
-+ }
- reiserfs_write_unlock(inode->i_sb);
- }
- return 0;
-@@ -1551,6 +1589,8 @@
- char * body = empty_dir;
- struct cpu_key key;
- int retval;
-+
-+ BUG_ON (!th->t_trans_id);
-
- _make_cpu_key (&key, KEY_FORMAT_3_5, le32_to_cpu (ih->ih_key.k_dir_id),
- le32_to_cpu (ih->ih_key.k_objectid), DOT_OFFSET, TYPE_DIRENTRY, 3/*key length*/);
-@@ -1602,6 +1642,8 @@
- struct cpu_key key;
- int retval;
-
-+ BUG_ON (!th->t_trans_id);
-+
- _make_cpu_key (&key, KEY_FORMAT_3_5,
- le32_to_cpu (ih->ih_key.k_dir_id),
- le32_to_cpu (ih->ih_key.k_objectid),
-@@ -1652,6 +1694,8 @@
- struct stat_data sd;
- int retval;
- int err;
-+
-+ BUG_ON (!th->t_trans_id);
-
- if (!dir || !dir->i_nlink) {
- err = -EPERM;
-@@ -1926,7 +1970,7 @@
- **
- ** some code taken from block_truncate_page
- */
--void reiserfs_truncate_file(struct inode *p_s_inode, int update_timestamps) {
-+int reiserfs_truncate_file(struct inode *p_s_inode, int update_timestamps) {
- struct reiserfs_transaction_handle th ;
- /* we want the offset for the first byte after the end of the file */
- unsigned long offset = p_s_inode->i_size & (PAGE_CACHE_SIZE - 1) ;
-@@ -1962,18 +2006,28 @@
- /* it is enough to reserve space in transaction for 2 balancings:
- one for "save" link adding and another for the first
- cut_from_item. 1 is for update_sd */
-- journal_begin(&th, p_s_inode->i_sb, JOURNAL_PER_BALANCE_CNT * 2 + 1 ) ;
-+ error = journal_begin (&th, p_s_inode->i_sb,
-+ JOURNAL_PER_BALANCE_CNT * 2 + 1);
-+ if (error)
-+ goto out;
- reiserfs_update_inode_transaction(p_s_inode) ;
- if (update_timestamps)
- /* we are doing real truncate: if the system crashes before the last
- transaction of truncating gets committed - on reboot the file
- either appears truncated properly or not truncated at all */
- add_save_link (&th, p_s_inode, 1);
-- reiserfs_do_truncate (&th, p_s_inode, page, update_timestamps) ;
-- journal_end(&th, p_s_inode->i_sb, JOURNAL_PER_BALANCE_CNT * 2 + 1 ) ;
-+ error = reiserfs_do_truncate (&th, p_s_inode, page, update_timestamps) ;
-+ if (error)
-+ goto out;
-+ error = journal_end (&th, p_s_inode->i_sb, JOURNAL_PER_BALANCE_CNT * 2 + 1);
-+ if (error)
-+ goto out;
-
-- if (update_timestamps)
-- remove_save_link (p_s_inode, 1/* truncate */);
-+ if (update_timestamps) {
-+ error = remove_save_link (p_s_inode, 1/* truncate */);
-+ if (error)
-+ goto out;
-+ }
-
- if (page) {
- length = offset & (blocksize - 1) ;
-@@ -1995,6 +2049,14 @@
- }
-
- reiserfs_write_unlock(p_s_inode->i_sb);
-+ return 0;
-+out:
-+ if (page) {
-+ unlock_page (page);
-+ page_cache_release (page);
-+ }
-+ reiserfs_write_unlock(p_s_inode->i_sb);
-+ return error;
- }
-
- static int map_block_for_writepage(struct inode *inode,
-@@ -2064,7 +2126,9 @@
-
- if (!trans_running) {
- /* vs-3050 is gone, no need to drop the path */
-- journal_begin(&th, inode->i_sb, jbegin_count) ;
-+ retval = journal_begin(&th, inode->i_sb, jbegin_count) ;
-+ if (retval)
-+ goto out;
- reiserfs_update_inode_transaction(inode) ;
- trans_running = 1;
- if (fs_changed(fs_gen, inode->i_sb) && item_moved(&tmp_ih, &path)) {
-@@ -2104,7 +2168,9 @@
- out:
- pathrelse(&path) ;
- if (trans_running) {
-- journal_end(&th, inode->i_sb, jbegin_count) ;
-+ int err = journal_end(&th, inode->i_sb, jbegin_count) ;
-+ if (err)
-+ retval = err;
- trans_running = 0;
- }
- reiserfs_write_unlock(inode->i_sb);
-@@ -2210,7 +2276,11 @@
- if (checked) {
- ClearPageChecked(page);
- reiserfs_write_lock(s);
-- journal_begin(&th, s, bh_per_page + 1);
-+ error = journal_begin(&th, s, bh_per_page + 1);
-+ if (error) {
-+ reiserfs_write_unlock(s);
-+ goto fail;
-+ }
- reiserfs_update_inode_transaction(inode);
- }
- /* now go through and lock any dirty buffers on the page */
-@@ -2245,8 +2315,10 @@
- } while((bh = bh->b_this_page) != head);
-
- if (checked) {
-- journal_end(&th, s, bh_per_page + 1);
-+ error = journal_end(&th, s, bh_per_page + 1);
- reiserfs_write_unlock(s);
-+ if (error)
-+ goto fail;
- }
- BUG_ON(PageWriteback(page));
- set_page_writeback(page);
-@@ -2352,7 +2424,9 @@
- fix_tail_page_for_writing(page) ;
- if (reiserfs_transaction_running(inode->i_sb)) {
- struct reiserfs_transaction_handle *th;
-- th = (struct reiserfs_transaction_handle *)current->journal_info;
-+ th = (struct reiserfs_transaction_handle *)current->journal_info;
-+ BUG_ON (!th->t_refcount);
-+ BUG_ON (!th->t_trans_id);
- old_ref = th->t_refcount;
- th->t_refcount++;
- }
-@@ -2374,9 +2448,12 @@
- if (old_ref)
- th->t_refcount--;
- else {
-+ int err;
- reiserfs_write_lock(inode->i_sb);
-- reiserfs_end_persistent_transaction(th);
-+ err = reiserfs_end_persistent_transaction(th);
- reiserfs_write_unlock(inode->i_sb);
-+ if (err)
-+ ret = err;
- }
- }
- }
-@@ -2417,20 +2494,28 @@
- (have_small_tails (inode->i_sb) && inode->i_size > i_block_size(inode)) )
- REISERFS_I(inode)->i_flags &= ~i_pack_on_close_mask ;
-
-- journal_begin(&myth, inode->i_sb, 1) ;
-+ ret = journal_begin(&myth, inode->i_sb, 1) ;
-+ if (ret) {
-+ reiserfs_write_unlock(inode->i_sb);
-+ goto journal_error;
-+ }
- reiserfs_update_inode_transaction(inode) ;
- inode->i_size = pos ;
- reiserfs_update_sd(&myth, inode) ;
- update_sd = 1;
-- journal_end(&myth, inode->i_sb, 1) ;
-+ ret = journal_end(&myth, inode->i_sb, 1) ;
- reiserfs_write_unlock(inode->i_sb);
-+ if (ret)
-+ goto journal_error;
- }
- if (th) {
- reiserfs_write_lock(inode->i_sb);
- if (!update_sd)
- reiserfs_update_sd(th, inode) ;
-- reiserfs_end_persistent_transaction(th);
-+ ret = reiserfs_end_persistent_transaction(th);
- reiserfs_write_unlock(inode->i_sb);
-+ if (ret)
-+ goto out;
- }
-
- /* we test for O_SYNC here so we can commit the transaction
-@@ -2438,10 +2523,22 @@
- */
- if (f && (f->f_flags & O_SYNC)) {
- reiserfs_write_lock(inode->i_sb);
-- reiserfs_commit_for_inode(inode) ;
-+ ret = reiserfs_commit_for_inode(inode) ;
- reiserfs_write_unlock(inode->i_sb);
- }
-+out:
- return ret ;
-+
-+journal_error:
-+ if (th) {
-+ reiserfs_write_lock(inode->i_sb);
-+ if (!update_sd)
-+ reiserfs_update_sd(th, inode) ;
-+ ret = reiserfs_end_persistent_transaction(th);
-+ reiserfs_write_unlock(inode->i_sb);
-+ }
-+
-+ return ret;
- }
-
- void sd_attrs_to_i_attrs( __u16 sd_attrs, struct inode *inode )
-@@ -2667,11 +2764,16 @@
- if (attr->ia_size > inode->i_size) {
- error = generic_cont_expand(inode, attr->ia_size) ;
- if (REISERFS_I(inode)->i_prealloc_count > 0) {
-+ int err;
- struct reiserfs_transaction_handle th ;
- /* we're changing at most 2 bitmaps, inode + super */
-- journal_begin(&th, inode->i_sb, 4) ;
-- reiserfs_discard_prealloc (&th, inode);
-- journal_end(&th, inode->i_sb, 4) ;
-+ err = journal_begin(&th, inode->i_sb, 4) ;
-+ if (!err) {
-+ reiserfs_discard_prealloc (&th, inode);
-+ err = journal_end(&th, inode->i_sb, 4) ;
-+ }
-+ if (err)
-+ error = err;
- }
- if (error)
- goto out;
-diff -Nru a/fs/reiserfs/journal.c b/fs/reiserfs/journal.c
---- a/fs/reiserfs/journal.c 2004-12-22 22:53:54 -08:00
-+++ b/fs/reiserfs/journal.c 2004-12-22 22:53:54 -08:00
-@@ -93,12 +93,6 @@
- #define COMMIT_NOW 2 /* end and commit this transaction */
- #define WAIT 4 /* wait for the log blocks to hit the disk*/
-
--/* state bits for the journal */
--#define WRITERS_BLOCKED 1 /* set when new writers not allowed */
--#define WRITERS_QUEUED 2 /* set when log is full due to too many
-- * writers
-- */
--
- static int do_journal_end(struct reiserfs_transaction_handle *,struct super_block *,unsigned long nblocks,int flags) ;
- static int flush_journal_list(struct super_block *s, struct reiserfs_journal_list *jl, int flushall) ;
- static int flush_commit_list(struct super_block *s, struct reiserfs_journal_list *jl, int flushall) ;
-@@ -109,6 +103,18 @@
- static int dirty_one_transaction(struct super_block *s,
- struct reiserfs_journal_list *jl);
- static void flush_async_commits(void *p);
-+static void queue_log_writer(struct super_block *s);
-+
-+/* values for join in do_journal_begin_r */
-+enum {
-+ JBEGIN_REG = 0, /* regular journal begin */
-+ JBEGIN_JOIN = 1, /* join the running transaction if at all possible */
-+ JBEGIN_ABORT = 2, /* called from cleanup code, ignores aborted flag */
-+};
-+
-+static int do_journal_begin_r(struct reiserfs_transaction_handle *th,
-+ struct super_block * p_s_sb,
-+ unsigned long nblocks,int join);
-
- static void init_journal_hash(struct super_block *p_s_sb) {
- struct reiserfs_journal *journal = SB_JOURNAL (p_s_sb);
-@@ -771,7 +777,7 @@
- {
- struct buffer_head *bh;
- struct reiserfs_jh *jh;
-- int ret = 0;
-+ int ret = j->j_errno;
- struct buffer_chunk chunk;
- struct list_head tmp;
- INIT_LIST_HEAD(&tmp);
-@@ -795,11 +801,11 @@
- cond_resched();
- spin_lock(lock);
- goto loop_next;
-- }
-+ }
- if (buffer_dirty(bh)) {
- list_del_init(&jh->list);
- list_add(&jh->list, &tmp);
-- add_to_chunk(&chunk, bh, lock, write_ordered_chunk);
-+ add_to_chunk(&chunk, bh, lock, write_ordered_chunk);
- } else {
- reiserfs_free_jh(bh);
- unlock_buffer(bh);
-@@ -824,8 +830,9 @@
- wait_on_buffer(bh);
- spin_lock(lock);
- }
-- if (!buffer_uptodate(bh))
-+ if (!buffer_uptodate(bh)) {
- ret = -EIO;
-+ }
- put_bh(bh);
- cond_resched_lock(lock);
- }
-@@ -917,6 +924,7 @@
- unsigned long trans_id = jl->j_trans_id;
- struct reiserfs_journal *journal = SB_JOURNAL (s);
- int barrier = 0;
-+ int retval = 0;
-
- reiserfs_check_lock_depth(s, "flush_commit_list") ;
-
-@@ -927,10 +935,8 @@
- /* before we can put our commit blocks on disk, we have to make sure everyone older than
- ** us is on disk too
- */
-- if (jl->j_len <= 0)
-- BUG();
-- if (trans_id == journal->j_trans_id)
-- BUG();
-+ BUG_ON (jl->j_len <= 0);
-+ BUG_ON (trans_id == journal->j_trans_id);
-
- get_journal_list(jl);
- if (flushall) {
-@@ -946,8 +952,7 @@
- up(&jl->j_commit_lock);
- goto put_jl;
- }
-- if (jl->j_trans_id == 0)
-- BUG();
-+ BUG_ON (jl->j_trans_id == 0);
-
- /* this commit is done, exit */
- if (atomic_read(&(jl->j_commit_left)) <= 0) {
-@@ -964,8 +969,7 @@
- journal, jl, &jl->j_bh_list);
- lock_kernel();
- }
-- if (!list_empty(&jl->j_bh_list))
-- BUG();
-+ BUG_ON (!list_empty(&jl->j_bh_list));
- /*
- * for the description block and all the log blocks, submit any buffers
- * that haven't already reached the disk
-@@ -975,7 +979,7 @@
- bn = SB_ONDISK_JOURNAL_1st_BLOCK(s) + (jl->j_start+i) %
- SB_ONDISK_JOURNAL_SIZE(s);
- tbh = journal_find_get_block(s, bn) ;
-- if (buffer_dirty(tbh))
-+ if (buffer_dirty(tbh)) /* redundant, ll_rw_block() checks */
- ll_rw_block(WRITE, 1, &tbh) ;
- put_bh(tbh) ;
- }
-@@ -1003,18 +1007,20 @@
- // since we're using ll_rw_blk above, it might have skipped over
- // a locked buffer. Double check here
- //
-- if (buffer_dirty(tbh))
-+ if (buffer_dirty(tbh)) /* redundant, sync_dirty_buffer() checks */
- sync_dirty_buffer(tbh);
-- if (!buffer_uptodate(tbh)) {
-- reiserfs_panic(s, "journal-601, buffer write failed\n") ;
-+ if (unlikely (!buffer_uptodate(tbh))) {
-+#ifdef CONFIG_REISERFS_CHECK
-+ reiserfs_warning(s, "journal-601, buffer write failed") ;
-+#endif
-+ retval = -EIO;
- }
- put_bh(tbh) ; /* once for journal_find_get_block */
- put_bh(tbh) ; /* once due to original getblk in do_journal_end */
- atomic_dec(&(jl->j_commit_left)) ;
- }
-
-- if (atomic_read(&(jl->j_commit_left)) != 1)
-- BUG();
-+ BUG_ON (atomic_read(&(jl->j_commit_left)) != 1);
-
- if (!barrier) {
- if (buffer_dirty(jl->j_commit_bh))
-@@ -1025,8 +1031,15 @@
- wait_on_buffer(jl->j_commit_bh);
-
- check_barrier_completion(s, jl->j_commit_bh);
-- if (!buffer_uptodate(jl->j_commit_bh)) {
-- reiserfs_panic(s, "journal-615: buffer write failed\n") ;
-+
-+ /* If there was a write error in the journal - we can't commit this
-+ * transaction - it will be invalid and, if successful, will just end
-+ * up propogating the write error out to the filesystem. */
-+ if (unlikely (!buffer_uptodate(jl->j_commit_bh))) {
-+#ifdef CONFIG_REISERFS_CHECK
-+ reiserfs_warning(s, "journal-615: buffer write failed") ;
-+#endif
-+ retval = -EIO;
- }
- bforget(jl->j_commit_bh) ;
- if (journal->j_last_commit_id != 0 &&
-@@ -1040,8 +1053,11 @@
- /* now, every commit block is on the disk. It is safe to allow blocks freed during this transaction to be reallocated */
- cleanup_freed_for_journal_list(s, jl) ;
-
-+ retval = retval ? retval : journal->j_errno;
-+
- /* mark the metadata dirty */
-- dirty_one_transaction(s, jl);
-+ if (!retval)
-+ dirty_one_transaction(s, jl);
- atomic_dec(&(jl->j_commit_left)) ;
-
- if (flushall) {
-@@ -1050,7 +1066,10 @@
- up(&jl->j_commit_lock);
- put_jl:
- put_journal_list(s, jl);
-- return 0 ;
-+
-+ if (retval)
-+ reiserfs_abort (s, retval, "Journal write error in %s", __FUNCTION__);
-+ return retval;
- }
-
- /*
-@@ -1113,11 +1132,18 @@
- static int _update_journal_header_block(struct super_block *p_s_sb, unsigned long offset, unsigned long trans_id) {
- struct reiserfs_journal_header *jh ;
- struct reiserfs_journal *journal = SB_JOURNAL (p_s_sb);
-+
-+ if (reiserfs_is_journal_aborted (journal))
-+ return -EIO;
-+
- if (trans_id >= journal->j_last_flush_trans_id) {
- if (buffer_locked((journal->j_header_bh))) {
- wait_on_buffer((journal->j_header_bh)) ;
-- if (!buffer_uptodate(journal->j_header_bh)) {
-- reiserfs_panic(p_s_sb, "journal-699: buffer write failed\n") ;
-+ if (unlikely (!buffer_uptodate(journal->j_header_bh))) {
-+#ifdef CONFIG_REISERFS_CHECK
-+ reiserfs_warning (p_s_sb, "journal-699: buffer write failed") ;
-+#endif
-+ return -EIO;
- }
- }
- journal->j_last_flush_trans_id = trans_id ;
-@@ -1154,10 +1180,7 @@
- static int update_journal_header_block(struct super_block *p_s_sb,
- unsigned long offset,
- unsigned long trans_id) {
-- if (_update_journal_header_block(p_s_sb, offset, trans_id)) {
-- reiserfs_panic(p_s_sb, "journal-712: buffer write failed\n") ;
-- }
-- return 0 ;
-+ return _update_journal_header_block(p_s_sb, offset, trans_id);
- }
- /*
- ** flush any and all journal lists older than you are
-@@ -1176,8 +1199,12 @@
- */
- restart:
- entry = journal->j_journal_list.next;
-+ /* Did we wrap? */
-+ if (entry == &journal->j_journal_list)
-+ return 0;
- other_jl = JOURNAL_LIST_ENTRY(entry);
- if (other_jl->j_trans_id < trans_id) {
-+ BUG_ON (other_jl->j_refcount <= 0);
- /* do not flush all */
- flush_journal_list(p_s_sb, other_jl, 0) ;
-
-@@ -1215,17 +1242,15 @@
- struct buffer_head *saved_bh ;
- unsigned long j_len_saved = jl->j_len ;
- struct reiserfs_journal *journal = SB_JOURNAL (s);
-+ int err = 0;
-
-- if (j_len_saved <= 0) {
-- BUG();
-- }
-+ BUG_ON (j_len_saved <= 0);
-
- if (atomic_read(&journal->j_wcount) != 0) {
- reiserfs_warning(s, "clm-2048: flush_journal_list called with wcount %d",
- atomic_read(&journal->j_wcount)) ;
- }
-- if (jl->j_trans_id == 0)
-- BUG();
-+ BUG_ON (jl->j_trans_id == 0);
-
- /* if flushall == 0, the lock is already held */
- if (flushall) {
-@@ -1251,7 +1276,7 @@
- */
- flush_commit_list(s, jl, 1) ;
-
-- if (!(jl->j_state & LIST_DIRTY))
-+ if (!(jl->j_state & LIST_DIRTY) && !reiserfs_is_journal_aborted (journal))
- BUG();
-
- /* are we done now? */
-@@ -1275,6 +1300,11 @@
- if (cn->blocknr == 0) {
- goto free_cnode ;
- }
-+
-+ /* This transaction failed commit. Don't write out to the disk */
-+ if (!(jl->j_state & LIST_DIRTY))
-+ goto free_cnode;
-+
- pjl = find_newer_jl_for_cn(cn) ;
- /* the order is important here. We check pjl to make sure we
- ** don't clear BH_JDirty_wait if we aren't the one writing this
-@@ -1289,8 +1319,7 @@
- get_bh(saved_bh) ;
-
- if (buffer_journal_dirty(saved_bh)) {
-- if (!can_dirty(cn))
-- BUG();
-+ BUG_ON (!can_dirty (cn));
- was_jwait = 1 ;
- was_dirty = 1 ;
- } else if (can_dirty(cn)) {
-@@ -1330,8 +1359,7 @@
- get_bh(saved_bh) ;
- set_bit(BLOCK_NEEDS_FLUSH, &cn->state) ;
- lock_buffer(saved_bh);
-- if (cn->blocknr != saved_bh->b_blocknr)
-- BUG();
-+ BUG_ON (cn->blocknr != saved_bh->b_blocknr);
- if (buffer_dirty(saved_bh))
- submit_logged_buffer(saved_bh) ;
- else
-@@ -1363,14 +1391,16 @@
- if (!cn->bh) {
- reiserfs_panic(s, "journal-1012: cn->bh is NULL\n") ;
- }
-- if (!buffer_uptodate(cn->bh)) {
-- reiserfs_panic(s, "journal-949: buffer write failed\n") ;
-- }
-+ if (unlikely (!buffer_uptodate(cn->bh))) {
-+#ifdef CONFIG_REISERFS_CHECK
-+ reiserfs_warning(s, "journal-949: buffer write failed\n") ;
-+#endif
-+ err = -EIO;
-+ }
- /* note, we must clear the JDirty_wait bit after the up to date
- ** check, otherwise we race against our flushpage routine
- */
-- if (!test_clear_buffer_journal_dirty (cn->bh))
-- BUG();
-+ BUG_ON (!test_clear_buffer_journal_dirty (cn->bh));
-
- /* undo the inc from journal_mark_dirty */
- put_bh(cn->bh) ;
-@@ -1380,7 +1410,11 @@
- }
- }
-
-+ if (err)
-+ reiserfs_abort (s, -EIO, "Write error while pushing transaction to disk in %s", __FUNCTION__);
- flush_older_and_return:
-+
-+
- /* before we can update the journal header block, we _must_ flush all
- ** real blocks from all older transactions to disk. This is because
- ** once the header block is updated, this transaction will not be
-@@ -1390,6 +1424,7 @@
- flush_older_journal_lists(s, jl);
- }
-
-+ err = journal->j_errno;
- /* before we can remove everything from the hash tables for this
- ** transaction, we must make sure it can never be replayed
- **
-@@ -1398,11 +1433,13 @@
- ** we only need to update the journal header block for the last list
- ** being flushed
- */
-- if (flushall) {
-- update_journal_header_block(s, (jl->j_start + jl->j_len + 2) % SB_ONDISK_JOURNAL_SIZE(s), jl->j_trans_id) ;
-+ if (!err && flushall) {
-+ err = update_journal_header_block(s, (jl->j_start + jl->j_len + 2) % SB_ONDISK_JOURNAL_SIZE(s), jl->j_trans_id) ;
-+ if (err)
-+ reiserfs_abort (s, -EIO, "Write error while updating journal header in %s", __FUNCTION__);
- }
- remove_all_from_journal_list(s, jl, 0) ;
-- list_del(&jl->j_list);
-+ list_del_init(&jl->j_list);
- journal->j_num_lists--;
- del_from_work_list(s, jl);
-
-@@ -1427,7 +1464,7 @@
- put_journal_list(s, jl);
- if (flushall)
- up(&journal->j_flush_sem);
-- return 0 ;
-+ return err ;
- }
-
- static int write_one_transaction(struct super_block *s,
-@@ -1497,8 +1534,7 @@
- pjl = find_newer_jl_for_cn(cn) ;
- if (!pjl && cn->blocknr && cn->bh && buffer_journal_dirty(cn->bh))
- {
-- if (!can_dirty(cn))
-- BUG();
-+ BUG_ON (!can_dirty(cn));
- /* if the buffer is prepared, it will either be logged
- * or restored. If restored, we need to make sure
- * it actually gets marked dirty
-@@ -1543,7 +1579,7 @@
- (!num_trans && written < num_blocks)) {
-
- if (jl->j_len == 0 || (jl->j_state & LIST_TOUCHED) ||
-- atomic_read(&jl->j_commit_left))
-+ atomic_read(&jl->j_commit_left) || !(jl->j_state & LIST_DIRTY))
- {
- del_from_work_list(s, jl);
- break;
-@@ -1693,18 +1729,33 @@
- */
- static int do_journal_release(struct reiserfs_transaction_handle *th, struct super_block *p_s_sb, int error) {
- struct reiserfs_transaction_handle myth ;
-+ int flushed = 0;
-+ struct reiserfs_journal *journal = SB_JOURNAL(p_s_sb);
-
- /* we only want to flush out transactions if we were called with error == 0
- */
- if (!error && !(p_s_sb->s_flags & MS_RDONLY)) {
- /* end the current trans */
-+ BUG_ON (!th->t_trans_id);
- do_journal_end(th, p_s_sb,10, FLUSH_ALL) ;
-
- /* make sure something gets logged to force our way into the flush code */
-- journal_join(&myth, p_s_sb, 1) ;
-- reiserfs_prepare_for_journal(p_s_sb, SB_BUFFER_WITH_SB(p_s_sb), 1) ;
-- journal_mark_dirty(&myth, p_s_sb, SB_BUFFER_WITH_SB(p_s_sb)) ;
-- do_journal_end(&myth, p_s_sb,1, FLUSH_ALL) ;
-+ if (!journal_join(&myth, p_s_sb, 1)) {
-+ reiserfs_prepare_for_journal(p_s_sb, SB_BUFFER_WITH_SB(p_s_sb), 1) ;
-+ journal_mark_dirty(&myth, p_s_sb, SB_BUFFER_WITH_SB(p_s_sb)) ;
-+ do_journal_end(&myth, p_s_sb,1, FLUSH_ALL) ;
-+ flushed = 1;
-+ }
-+ }
-+
-+ /* this also catches errors during the do_journal_end above */
-+ if (!error && reiserfs_is_journal_aborted(journal)) {
-+ memset(&myth, 0, sizeof(myth));
-+ if (!journal_join_abort(&myth, p_s_sb, 1)) {
-+ reiserfs_prepare_for_journal(p_s_sb, SB_BUFFER_WITH_SB(p_s_sb), 1) ;
-+ journal_mark_dirty(&myth, p_s_sb, SB_BUFFER_WITH_SB(p_s_sb)) ;
-+ do_journal_end(&myth, p_s_sb, 1, FLUSH_ALL) ;
-+ }
- }
-
- reiserfs_mounted_fs_count-- ;
-@@ -2314,6 +2365,7 @@
- INIT_LIST_HEAD (&journal->j_prealloc_list);
- INIT_LIST_HEAD(&journal->j_working_list);
- INIT_LIST_HEAD(&journal->j_journal_list);
-+ journal->j_persistent_trans = 0;
- if (reiserfs_allocate_list_bitmaps(p_s_sb,
- journal->j_list_bitmap,
- SB_BMAP_NR(p_s_sb)))
-@@ -2492,6 +2544,7 @@
- struct reiserfs_journal *journal = SB_JOURNAL (th->t_super);
- time_t now = get_seconds() ;
- /* cannot restart while nested */
-+ BUG_ON (!th->t_trans_id);
- if (th->t_refcount > 1)
- return 0 ;
- if ( journal->j_must_wait > 0 ||
-@@ -2509,8 +2562,9 @@
- */
- void reiserfs_block_writes(struct reiserfs_transaction_handle *th) {
- struct reiserfs_journal *journal = SB_JOURNAL (th->t_super);
-+ BUG_ON (!th->t_trans_id);
- journal->j_must_wait = 1 ;
-- set_bit(WRITERS_BLOCKED, &journal->j_state) ;
-+ set_bit(J_WRITERS_BLOCKED, &journal->j_state) ;
- return ;
- }
-
-@@ -2519,7 +2573,7 @@
- */
- void reiserfs_allow_writes(struct super_block *s) {
- struct reiserfs_journal *journal = SB_JOURNAL (s);
-- clear_bit(WRITERS_BLOCKED, &journal->j_state) ;
-+ clear_bit(J_WRITERS_BLOCKED, &journal->j_state) ;
- wake_up(&journal->j_join_wait) ;
- }
-
-@@ -2529,13 +2583,13 @@
- void reiserfs_wait_on_write_block(struct super_block *s) {
- struct reiserfs_journal *journal = SB_JOURNAL (s);
- wait_event(journal->j_join_wait,
-- !test_bit(WRITERS_BLOCKED, &journal->j_state)) ;
-+ !test_bit(J_WRITERS_BLOCKED, &journal->j_state)) ;
- }
-
- static void queue_log_writer(struct super_block *s) {
- wait_queue_t wait;
- struct reiserfs_journal *journal = SB_JOURNAL (s);
-- set_bit(WRITERS_QUEUED, &journal->j_state);
-+ set_bit(J_WRITERS_QUEUED, &journal->j_state);
-
- /*
- * we don't want to use wait_event here because
-@@ -2544,7 +2598,7 @@
- init_waitqueue_entry(&wait, current);
- add_wait_queue(&journal->j_join_wait, &wait);
- set_current_state(TASK_UNINTERRUPTIBLE);
-- if (test_bit(WRITERS_QUEUED, &journal->j_state))
-+ if (test_bit(J_WRITERS_QUEUED, &journal->j_state))
- schedule();
- current->state = TASK_RUNNING;
- remove_wait_queue(&journal->j_join_wait, &wait);
-@@ -2552,7 +2606,7 @@
-
- static void wake_queued_writers(struct super_block *s) {
- struct reiserfs_journal *journal = SB_JOURNAL (s);
-- if (test_and_clear_bit(WRITERS_QUEUED, &journal->j_state))
-+ if (test_and_clear_bit(J_WRITERS_QUEUED, &journal->j_state))
- wake_up(&journal->j_join_wait);
- }
-
-@@ -2590,10 +2644,9 @@
- struct reiserfs_journal *journal = SB_JOURNAL(p_s_sb);
- struct reiserfs_transaction_handle myth;
- int sched_count = 0;
-+ int retval;
-
- reiserfs_check_lock_depth(p_s_sb, "journal_begin") ;
-- RFALSE( p_s_sb->s_flags & MS_RDONLY,
-- "clm-2078: calling journal_begin on readonly FS") ;
-
- PROC_INFO_INC( p_s_sb, journal.journal_being );
- /* set here for journal_join */
-@@ -2602,9 +2655,14 @@
-
- relock:
- lock_journal(p_s_sb) ;
-+ if (join != JBEGIN_ABORT && reiserfs_is_journal_aborted (journal)) {
-+ unlock_journal (p_s_sb);
-+ retval = journal->j_errno;
-+ goto out_fail;
-+ }
- journal->j_bcount++;
-
-- if (test_bit(WRITERS_BLOCKED, &journal->j_state)) {
-+ if (test_bit(J_WRITERS_BLOCKED, &journal->j_state)) {
- unlock_journal(p_s_sb) ;
- reiserfs_wait_on_write_block(p_s_sb) ;
- PROC_INFO_INC( p_s_sb, journal.journal_relock_writers );
-@@ -2647,15 +2705,20 @@
- }
- goto relock;
- }
-- journal_join(&myth, p_s_sb, 1) ;
-+ retval = journal_join(&myth, p_s_sb, 1) ;
-+ if (retval)
-+ goto out_fail;
-
- /* someone might have ended the transaction while we joined */
- if (old_trans_id != journal->j_trans_id) {
-- do_journal_end(&myth, p_s_sb, 1, 0) ;
-+ retval = do_journal_end(&myth, p_s_sb, 1, 0) ;
- } else {
-- do_journal_end(&myth, p_s_sb, 1, COMMIT_NOW) ;
-+ retval = do_journal_end(&myth, p_s_sb, 1, COMMIT_NOW) ;
- }
-
-+ if (retval)
-+ goto out_fail;
-+
- PROC_INFO_INC( p_s_sb, journal.journal_relock_wcount );
- goto relock ;
- }
-@@ -2669,7 +2732,16 @@
- th->t_blocks_allocated = nblocks ;
- th->t_trans_id = journal->j_trans_id ;
- unlock_journal(p_s_sb) ;
-+ INIT_LIST_HEAD (&th->t_list);
- return 0 ;
-+
-+out_fail:
-+ memset (th, 0, sizeof (*th));
-+ /* Re-set th->t_super, so we can properly keep track of how many
-+ * persistent transactions there are. We need to do this so if this
-+ * call is part of a failed restart_transaction, we can free it later */
-+ th->t_super = p_s_sb;
-+ return retval;
- }
-
- struct reiserfs_transaction_handle *
-@@ -2696,16 +2768,23 @@
- reiserfs_kfree(th, sizeof(struct reiserfs_transaction_handle), s) ;
- return NULL;
- }
-+
-+ SB_JOURNAL(s)->j_persistent_trans++;
- return th ;
- }
-
- int
- reiserfs_end_persistent_transaction(struct reiserfs_transaction_handle *th) {
- struct super_block *s = th->t_super;
-- int ret;
-- ret = journal_end(th, th->t_super, th->t_blocks_allocated);
-- if (th->t_refcount == 0)
-+ int ret = 0;
-+ if (th->t_trans_id)
-+ ret = journal_end(th, th->t_super, th->t_blocks_allocated);
-+ else
-+ ret = -EIO;
-+ if (th->t_refcount == 0) {
-+ SB_JOURNAL(s)->j_persistent_trans--;
- reiserfs_kfree(th, sizeof(struct reiserfs_transaction_handle), s) ;
-+ }
- return ret;
- }
-
-@@ -2719,7 +2798,20 @@
- if (cur_th && cur_th->t_refcount > 1) {
- BUG() ;
- }
-- return do_journal_begin_r(th, p_s_sb, nblocks, 1) ;
-+ return do_journal_begin_r(th, p_s_sb, nblocks, JBEGIN_JOIN) ;
-+}
-+
-+int journal_join_abort(struct reiserfs_transaction_handle *th, struct super_block *p_s_sb, unsigned long nblocks) {
-+ struct reiserfs_transaction_handle *cur_th = current->journal_info;
-+
-+ /* this keeps do_journal_end from NULLing out the current->journal_info
-+ ** pointer
-+ */
-+ th->t_handle_save = cur_th ;
-+ if (cur_th && cur_th->t_refcount > 1) {
-+ BUG() ;
-+ }
-+ return do_journal_begin_r(th, p_s_sb, nblocks, JBEGIN_ABORT) ;
- }
-
- int journal_begin(struct reiserfs_transaction_handle *th, struct super_block * p_s_sb, unsigned long nblocks) {
-@@ -2730,6 +2822,7 @@
- if (cur_th) {
- /* we are nesting into the current transaction */
- if (cur_th->t_super == p_s_sb) {
-+ BUG_ON (!cur_th->t_refcount);
- cur_th->t_refcount++ ;
- memcpy(th, cur_th, sizeof(*th));
- if (th->t_refcount <= 1)
-@@ -2747,9 +2840,18 @@
- } else {
- current->journal_info = th;
- }
-- ret = do_journal_begin_r(th, p_s_sb, nblocks, 0) ;
-+ ret = do_journal_begin_r(th, p_s_sb, nblocks, JBEGIN_REG) ;
- if (current->journal_info != th)
- BUG() ;
-+
-+ /* I guess this boils down to being the reciprocal of clm-2100 above.
-+ * If do_journal_begin_r fails, we need to put it back, since journal_end
-+ * won't be called to do it. */
-+ if (ret)
-+ current->journal_info = th->t_handle_save;
-+ else
-+ BUG_ON (!th->t_refcount);
-+
- return ret ;
- }
-
-@@ -2767,12 +2869,14 @@
- struct reiserfs_journal_cnode *cn = NULL;
- int count_already_incd = 0 ;
- int prepared = 0 ;
-+ BUG_ON (!th->t_trans_id);
-
- PROC_INFO_INC( p_s_sb, journal.mark_dirty );
- if (th->t_trans_id != journal->j_trans_id) {
- reiserfs_panic(th->t_super, "journal-1577: handle trans id %ld != current trans id %ld\n",
- th->t_trans_id, journal->j_trans_id);
- }
-+
- p_s_sb->s_dirt = 1;
-
- prepared = test_clear_buffer_journal_prepared (bh);
-@@ -2860,6 +2964,11 @@
- reiserfs_warning (p_s_sb, "REISER-NESTING: th NULL, refcount %d",
- th->t_refcount);
-
-+ if (!th->t_trans_id) {
-+ WARN_ON (1);
-+ return -EIO;
-+ }
-+
- th->t_refcount--;
- if (th->t_refcount > 0) {
- struct reiserfs_transaction_handle *cur_th = current->journal_info ;
-@@ -2976,6 +3085,7 @@
- int journal_end_sync(struct reiserfs_transaction_handle *th, struct super_block *p_s_sb, unsigned long nblocks) {
- struct reiserfs_journal *journal = SB_JOURNAL (p_s_sb);
-
-+ BUG_ON (!th->t_trans_id);
- /* you can sync while nested, very, very bad */
- if (th->t_refcount > 1) {
- BUG() ;
-@@ -3008,7 +3118,7 @@
- * this is a little racey, but there's no harm in missing
- * the filemap_fdata_write
- */
-- if (!atomic_read(&journal->j_async_throttle)) {
-+ if (!atomic_read(&journal->j_async_throttle) && !reiserfs_is_journal_aborted (journal)) {
- atomic_inc(&journal->j_async_throttle);
- filemap_fdatawrite(p_s_sb->s_bdev->bd_inode->i_mapping);
- atomic_dec(&journal->j_async_throttle);
-@@ -3040,14 +3150,15 @@
- journal->j_len > 0 &&
- (now - journal->j_trans_start_time) > journal->j_max_trans_age)
- {
-- journal_join(&th, p_s_sb, 1) ;
-- reiserfs_prepare_for_journal(p_s_sb, SB_BUFFER_WITH_SB(p_s_sb), 1) ;
-- journal_mark_dirty(&th, p_s_sb, SB_BUFFER_WITH_SB(p_s_sb)) ;
--
-- /* we're only being called from kreiserfsd, it makes no sense to do
-- ** an async commit so that kreiserfsd can do it later
-- */
-- do_journal_end(&th, p_s_sb,1, COMMIT_NOW | WAIT) ;
-+ if (!journal_join(&th, p_s_sb, 1)) {
-+ reiserfs_prepare_for_journal(p_s_sb, SB_BUFFER_WITH_SB(p_s_sb), 1) ;
-+ journal_mark_dirty(&th, p_s_sb, SB_BUFFER_WITH_SB(p_s_sb)) ;
-+
-+ /* we're only being called from kreiserfsd, it makes no sense to do
-+ ** an async commit so that kreiserfsd can do it later
-+ */
-+ do_journal_end(&th, p_s_sb,1, COMMIT_NOW | WAIT) ;
-+ }
- }
- return p_s_sb->s_dirt;
- }
-@@ -3073,6 +3184,8 @@
- struct reiserfs_journal_list *jl;
- struct reiserfs_journal *journal = SB_JOURNAL (p_s_sb);
-
-+ BUG_ON (!th->t_trans_id);
-+
- if (th->t_trans_id != journal->j_trans_id) {
- reiserfs_panic(th->t_super, "journal-1577: handle trans id %ld != current trans id %ld\n",
- th->t_trans_id, journal->j_trans_id);
-@@ -3178,6 +3291,7 @@
- struct buffer_head *bh = NULL ;
- struct reiserfs_list_bitmap *jb = NULL ;
- int cleaned = 0 ;
-+ BUG_ON (!th->t_trans_id);
-
- cn = get_journal_hash_dev(p_s_sb, journal->j_hash_table, blocknr);
- if (cn && cn->bh) {
-@@ -3269,18 +3383,21 @@
- goto flush_commit_only;
- }
-
-- journal_begin(&th, sb, 1) ;
-+ ret = journal_begin(&th, sb, 1) ;
-+ if (ret)
-+ return ret;
-
- /* someone might have ended this transaction while we joined */
- if (journal->j_trans_id != id) {
- reiserfs_prepare_for_journal(sb, SB_BUFFER_WITH_SB(sb), 1) ;
- journal_mark_dirty(&th, sb, SB_BUFFER_WITH_SB(sb)) ;
-- journal_end(&th, sb, 1) ;
-+ ret = journal_end(&th, sb, 1) ;
- goto flush_commit_only;
- }
-
-- journal_end_sync(&th, sb, 1) ;
-- ret = 1;
-+ ret = journal_end_sync(&th, sb, 1) ;
-+ if (!ret)
-+ ret = 1;
-
- } else {
- /* this gets tricky, we have to make sure the journal list in
-@@ -3297,6 +3414,8 @@
- if (atomic_read(&jl->j_commit_left) > 1)
- ret = 1;
- flush_commit_list(sb, jl, 1) ;
-+ if (journal->j_errno)
-+ ret = journal->j_errno;
- }
- }
- /* otherwise the list is gone, and long since committed */
-@@ -3390,6 +3509,9 @@
- ** If no_async, won't return until all commit blocks are on disk.
- **
- ** keep reading, there are comments as you go along
-+**
-+** If the journal is aborted, we just clean up. Things like flushing
-+** journal lists, etc just won't happen.
- */
- static int do_journal_end(struct reiserfs_transaction_handle *th, struct super_block * p_s_sb, unsigned long nblocks,
- int flags) {
-@@ -3411,8 +3533,8 @@
- unsigned long commit_trans_id;
- int trans_half;
-
-- if (th->t_refcount > 1)
-- BUG() ;
-+ BUG_ON (th->t_refcount > 1);
-+ BUG_ON (!th->t_trans_id);
-
- current->journal_info = th->t_handle_save;
- reiserfs_check_lock_depth(p_s_sb, "journal end");
-@@ -3707,7 +3829,7 @@
- atomic_set(&(journal->j_jlock), 0) ;
- unlock_journal(p_s_sb) ;
- /* wake up any body waiting to join. */
-- clear_bit(WRITERS_QUEUED, &journal->j_state);
-+ clear_bit(J_WRITERS_QUEUED, &journal->j_state);
- wake_up(&(journal->j_join_wait)) ;
-
- if (!flush && wait_on_commit &&
-@@ -3716,6 +3838,49 @@
- }
- out:
- reiserfs_check_lock_depth(p_s_sb, "journal end2");
-- th->t_trans_id = 0;
-- return 0 ;
-+
-+ memset (th, 0, sizeof (*th));
-+ /* Re-set th->t_super, so we can properly keep track of how many
-+ * persistent transactions there are. We need to do this so if this
-+ * call is part of a failed restart_transaction, we can free it later */
-+ th->t_super = p_s_sb;
-+
-+ return journal->j_errno;
-+}
-+
-+void
-+__reiserfs_journal_abort_hard (struct super_block *sb)
-+{
-+ struct reiserfs_journal *journal = SB_JOURNAL (sb);
-+ if (test_bit (J_ABORTED, &journal->j_state))
-+ return;
-+
-+ printk (KERN_CRIT "REISERFS: Aborting journal for filesystem on %s\n",
-+ reiserfs_bdevname (sb));
-+
-+ sb->s_flags |= MS_RDONLY;
-+ set_bit (J_ABORTED, &journal->j_state);
-+
-+#ifdef CONFIG_REISERFS_CHECK
-+ dump_stack();
-+#endif
-+}
-+
-+void
-+__reiserfs_journal_abort_soft (struct super_block *sb, int errno)
-+{
-+ struct reiserfs_journal *journal = SB_JOURNAL (sb);
-+ if (test_bit (J_ABORTED, &journal->j_state))
-+ return;
-+
-+ if (!journal->j_errno)
-+ journal->j_errno = errno;
-+
-+ __reiserfs_journal_abort_hard (sb);
-+}
-+
-+void
-+reiserfs_journal_abort (struct super_block *sb, int errno)
-+{
-+ return __reiserfs_journal_abort_soft (sb, errno);
- }
-diff -Nru a/fs/reiserfs/namei.c b/fs/reiserfs/namei.c
---- a/fs/reiserfs/namei.c 2004-12-22 22:53:54 -08:00
-+++ b/fs/reiserfs/namei.c 2004-12-22 22:53:54 -08:00
-@@ -430,6 +430,7 @@
- int buflen, paste_size;
- int retval;
-
-+ BUG_ON (!th->t_trans_id);
-
- /* cannot allow items to be added into a busy deleted directory */
- if (!namelen)
-@@ -606,16 +607,21 @@
- if (locked)
- reiserfs_write_lock_xattrs (dir->i_sb);
-
-- journal_begin(&th, dir->i_sb, jbegin_count) ;
-- retval = reiserfs_new_inode (&th, dir, mode, NULL, 0/*i_size*/, dentry, inode);
--
-- if (locked)
-- reiserfs_write_unlock_xattrs (dir->i_sb);
--
-+ retval = journal_begin(&th, dir->i_sb, jbegin_count);
- if (retval) {
-+ drop_new_inode (inode);
- goto out_failed;
- }
-+
-+ retval = reiserfs_new_inode (&th, dir, mode, 0, 0/*i_size*/, dentry, inode);
-+ if (retval)
-+ goto out_failed;
-
-+ if (locked) {
-+ reiserfs_write_unlock_xattrs (dir->i_sb);
-+ locked = 0;
-+ }
-+
- inode->i_op = &reiserfs_file_inode_operations;
- inode->i_fop = &reiserfs_file_operations;
- inode->i_mapping->a_ops = &reiserfs_address_space_operations ;
-@@ -623,9 +629,12 @@
- retval = reiserfs_add_entry (&th, dir, dentry->d_name.name, dentry->d_name.len,
- inode, 1/*visible*/);
- if (retval) {
-+ int err;
- inode->i_nlink--;
- reiserfs_update_sd (&th, inode);
-- journal_end(&th, dir->i_sb, jbegin_count) ;
-+ err = journal_end(&th, dir->i_sb, jbegin_count) ;
-+ if (err)
-+ retval = err;
- iput (inode);
- goto out_failed;
- }
-@@ -633,9 +642,11 @@
- reiserfs_update_inode_transaction(dir) ;
-
- d_instantiate(dentry, inode);
-- journal_end(&th, dir->i_sb, jbegin_count) ;
-+ retval = journal_end(&th, dir->i_sb, jbegin_count) ;
-
- out_failed:
-+ if (locked)
-+ reiserfs_write_unlock_xattrs (dir->i_sb);
- reiserfs_write_unlock(dir->i_sb);
- return retval;
- }
-@@ -666,17 +677,23 @@
- if (locked)
- reiserfs_write_lock_xattrs (dir->i_sb);
-
-- journal_begin(&th, dir->i_sb, jbegin_count) ;
-+ retval = journal_begin(&th, dir->i_sb, jbegin_count) ;
-+ if (retval) {
-+ drop_new_inode (inode);
-+ goto out_failed;
-+ }
-
- retval = reiserfs_new_inode (&th, dir, mode, NULL, 0/*i_size*/, dentry, inode);
--
-- if (locked)
-- reiserfs_write_unlock_xattrs (dir->i_sb);
--
- if (retval) {
- goto out_failed;
- }
-
-+ if (locked) {
-+ reiserfs_write_unlock_xattrs (dir->i_sb);
-+ locked = 0;
-+ }
-+
-+
- inode->i_op = &reiserfs_special_inode_operations;
- init_special_inode(inode, inode->i_mode, rdev) ;
-
-@@ -689,17 +706,22 @@
- retval = reiserfs_add_entry (&th, dir, dentry->d_name.name, dentry->d_name.len,
- inode, 1/*visible*/);
- if (retval) {
-+ int err;
- inode->i_nlink--;
- reiserfs_update_sd (&th, inode);
-- journal_end(&th, dir->i_sb, jbegin_count) ;
-+ err = journal_end(&th, dir->i_sb, jbegin_count) ;
-+ if (err)
-+ retval = err;
- iput (inode);
- goto out_failed;
- }
-
- d_instantiate(dentry, inode);
-- journal_end(&th, dir->i_sb, jbegin_count) ;
-+ retval = journal_end(&th, dir->i_sb, jbegin_count) ;
-
- out_failed:
-+ if (locked)
-+ reiserfs_write_unlock_xattrs (dir->i_sb);
- reiserfs_write_unlock(dir->i_sb);
- return retval;
- }
-@@ -730,7 +752,13 @@
- reiserfs_write_lock(dir->i_sb);
- if (locked)
- reiserfs_write_lock_xattrs (dir->i_sb);
-- journal_begin(&th, dir->i_sb, jbegin_count) ;
-+
-+ retval = journal_begin(&th, dir->i_sb, jbegin_count) ;
-+ if (retval) {
-+ drop_new_inode (inode);
-+ goto out_failed;
-+ }
-+
-
- /* inc the link count now, so another writer doesn't overflow it while
- ** we sleep later on.
-@@ -741,13 +769,16 @@
- old_format_only (dir->i_sb) ?
- EMPTY_DIR_SIZE_V1 : EMPTY_DIR_SIZE,
- dentry, inode);
-- if (locked)
-- reiserfs_write_unlock_xattrs (dir->i_sb);
--
- if (retval) {
- dir->i_nlink-- ;
- goto out_failed;
- }
-+
-+ if (locked) {
-+ reiserfs_write_unlock_xattrs (dir->i_sb);
-+ locked = 0;
-+ }
-+
- reiserfs_update_inode_transaction(inode) ;
- reiserfs_update_inode_transaction(dir) ;
-
-@@ -758,10 +789,13 @@
- retval = reiserfs_add_entry (&th, dir, dentry->d_name.name, dentry->d_name.len,
- inode, 1/*visible*/);
- if (retval) {
-+ int err;
- inode->i_nlink = 0;
- DEC_DIR_INODE_NLINK(dir);
- reiserfs_update_sd (&th, inode);
-- journal_end(&th, dir->i_sb, jbegin_count) ;
-+ err = journal_end(&th, dir->i_sb, jbegin_count) ;
-+ if (err)
-+ retval = err;
- iput (inode);
- goto out_failed;
- }
-@@ -770,8 +804,10 @@
- reiserfs_update_sd (&th, dir);
-
- d_instantiate(dentry, inode);
-- journal_end(&th, dir->i_sb, jbegin_count) ;
-+ retval = journal_end(&th, dir->i_sb, jbegin_count) ;
- out_failed:
-+ if (locked)
-+ reiserfs_write_unlock_xattrs (dir->i_sb);
- reiserfs_write_unlock(dir->i_sb);
- return retval;
- }
-@@ -791,7 +827,7 @@
-
- static int reiserfs_rmdir (struct inode * dir, struct dentry *dentry)
- {
-- int retval;
-+ int retval, err;
- struct inode * inode;
- struct reiserfs_transaction_handle th ;
- int jbegin_count;
-@@ -803,7 +839,9 @@
- jbegin_count = JOURNAL_PER_BALANCE_CNT * 2 + 2;
-
- reiserfs_write_lock(dir->i_sb);
-- journal_begin(&th, dir->i_sb, jbegin_count) ;
-+ retval = journal_begin(&th, dir->i_sb, jbegin_count) ;
-+ if (retval)
-+ goto out_rmdir;
-
- de.de_gen_number_bit_string = NULL;
- if ( (retval = reiserfs_find_entry (dir, dentry->d_name.name, dentry->d_name.len, &path, &de)) == NAME_NOT_FOUND) {
-@@ -852,24 +890,25 @@
- /* prevent empty directory from getting lost */
- add_save_link (&th, inode, 0/* not truncate */);
-
-- journal_end(&th, dir->i_sb, jbegin_count) ;
-+ retval = journal_end(&th, dir->i_sb, jbegin_count) ;
- reiserfs_check_path(&path) ;
-+out_rmdir:
- reiserfs_write_unlock(dir->i_sb);
-- return 0;
-+ return retval;
-
- end_rmdir:
- /* we must release path, because we did not call
- reiserfs_cut_from_item, or reiserfs_cut_from_item does not
- release path if operation was not complete */
- pathrelse (&path);
-- journal_end(&th, dir->i_sb, jbegin_count) ;
-+ err = journal_end(&th, dir->i_sb, jbegin_count) ;
- reiserfs_write_unlock(dir->i_sb);
-- return retval;
-+ return err ? err : retval;
- }
-
- static int reiserfs_unlink (struct inode * dir, struct dentry *dentry)
- {
-- int retval;
-+ int retval, err;
- struct inode * inode;
- struct reiserfs_dir_entry de;
- INITIALIZE_PATH (path);
-@@ -884,7 +923,9 @@
- jbegin_count = JOURNAL_PER_BALANCE_CNT * 2 + 2;
-
- reiserfs_write_lock(dir->i_sb);
-- journal_begin(&th, dir->i_sb, jbegin_count) ;
-+ retval = journal_begin(&th, dir->i_sb, jbegin_count) ;
-+ if (retval)
-+ goto out_unlink;
-
- de.de_gen_number_bit_string = NULL;
- if ( (retval = reiserfs_find_entry (dir, dentry->d_name.name, dentry->d_name.len, &path, &de)) == NAME_NOT_FOUND) {
-@@ -938,15 +979,18 @@
- /* prevent file from getting lost */
- add_save_link (&th, inode, 0/* not truncate */);
-
-- journal_end(&th, dir->i_sb, jbegin_count) ;
-+ retval = journal_end(&th, dir->i_sb, jbegin_count) ;
- reiserfs_check_path(&path) ;
- reiserfs_write_unlock(dir->i_sb);
-- return 0;
-+ return retval;
-
- end_unlink:
- pathrelse (&path);
-- journal_end(&th, dir->i_sb, jbegin_count) ;
-+ err = journal_end(&th, dir->i_sb, jbegin_count) ;
- reiserfs_check_path(&path) ;
-+ if (err)
-+ retval = err;
-+out_unlink:
- reiserfs_write_unlock(dir->i_sb);
- return retval;
- }
-@@ -989,7 +1033,12 @@
-
- /* We would inherit the default ACL here, but symlinks don't get ACLs */
-
-- journal_begin(&th, parent_dir->i_sb, jbegin_count) ;
-+ retval = journal_begin(&th, parent_dir->i_sb, jbegin_count) ;
-+ if (retval) {
-+ drop_new_inode (inode);
-+ reiserfs_kfree (name, item_len, parent_dir->i_sb);
-+ goto out_failed;
-+ }
-
- retval = reiserfs_new_inode (&th, parent_dir, mode, name, strlen (symname),
- dentry, inode);
-@@ -1011,15 +1060,18 @@
- retval = reiserfs_add_entry (&th, parent_dir, dentry->d_name.name,
- dentry->d_name.len, inode, 1/*visible*/);
- if (retval) {
-+ int err;
- inode->i_nlink--;
- reiserfs_update_sd (&th, inode);
-- journal_end(&th, parent_dir->i_sb, jbegin_count) ;
-+ err = journal_end(&th, parent_dir->i_sb, jbegin_count) ;
-+ if (err)
-+ retval = err;
- iput (inode);
- goto out_failed;
- }
-
- d_instantiate(dentry, inode);
-- journal_end(&th, parent_dir->i_sb, jbegin_count) ;
-+ retval = journal_end(&th, parent_dir->i_sb, jbegin_count) ;
- out_failed:
- reiserfs_write_unlock(parent_dir->i_sb);
- return retval;
-@@ -1045,7 +1097,12 @@
- /* inc before scheduling so reiserfs_unlink knows we are here */
- inode->i_nlink++;
-
-- journal_begin(&th, dir->i_sb, jbegin_count) ;
-+ retval = journal_begin(&th, dir->i_sb, jbegin_count) ;
-+ if (retval) {
-+ inode->i_nlink--;
-+ reiserfs_write_unlock (dir->i_sb);
-+ return retval;
-+ }
-
- /* create new entry */
- retval = reiserfs_add_entry (&th, dir, dentry->d_name.name, dentry->d_name.len,
-@@ -1055,10 +1112,11 @@
- reiserfs_update_inode_transaction(dir) ;
-
- if (retval) {
-+ int err;
- inode->i_nlink--;
-- journal_end(&th, dir->i_sb, jbegin_count) ;
-+ err = journal_end(&th, dir->i_sb, jbegin_count) ;
- reiserfs_write_unlock(dir->i_sb);
-- return retval;
-+ return err ? err : retval;
- }
-
- inode->i_ctime = CURRENT_TIME;
-@@ -1066,9 +1124,9 @@
-
- atomic_inc(&inode->i_count) ;
- d_instantiate(dentry, inode);
-- journal_end(&th, dir->i_sb, jbegin_count) ;
-+ retval = journal_end(&th, dir->i_sb, jbegin_count) ;
- reiserfs_write_unlock(dir->i_sb);
-- return 0;
-+ return retval;
- }
-
-
-@@ -1195,7 +1253,12 @@
- }
- }
-
-- journal_begin(&th, old_dir->i_sb, jbegin_count) ;
-+ retval = journal_begin(&th, old_dir->i_sb, jbegin_count) ;
-+ if (retval) {
-+ reiserfs_write_unlock (old_dir->i_sb);
-+ return retval;
-+ }
-+
-
- /* add new entry (or find the existing one) */
- retval = reiserfs_add_entry (&th, new_dir, new_dentry->d_name.name, new_dentry->d_name.len,
-@@ -1206,9 +1269,9 @@
- "vs-7050: new entry is found, new inode == 0\n");
- }
- } else if (retval) {
-- journal_end(&th, old_dir->i_sb, jbegin_count) ;
-+ int err = journal_end(&th, old_dir->i_sb, jbegin_count) ;
- reiserfs_write_unlock(old_dir->i_sb);
-- return retval;
-+ return err ? err : retval;
- }
-
- reiserfs_update_inode_transaction(old_dir) ;
-@@ -1357,9 +1420,9 @@
- reiserfs_update_sd (&th, new_dentry_inode);
- }
-
-- journal_end(&th, old_dir->i_sb, jbegin_count) ;
-+ retval = journal_end(&th, old_dir->i_sb, jbegin_count) ;
- reiserfs_write_unlock(old_dir->i_sb);
-- return 0;
-+ return retval;
- }
-
- /*
-@@ -1414,5 +1477,3 @@
- .permission = reiserfs_permission,
-
- };
--
--
-diff -Nru a/fs/reiserfs/objectid.c b/fs/reiserfs/objectid.c
---- a/fs/reiserfs/objectid.c 2004-12-22 22:53:54 -08:00
-+++ b/fs/reiserfs/objectid.c 2004-12-22 22:53:54 -08:00
-@@ -55,6 +55,7 @@
- __u32 * map = objectid_map (s, rs);
- __u32 unused_objectid;
-
-+ BUG_ON (!th->t_trans_id);
-
- check_objectid_map (s, map);
-
-@@ -99,6 +100,7 @@
- __u32 * map = objectid_map (s, rs);
- int i = 0;
-
-+ BUG_ON (!th->t_trans_id);
- //return;
- check_objectid_map (s, map);
-
-diff -Nru a/fs/reiserfs/prints.c b/fs/reiserfs/prints.c
---- a/fs/reiserfs/prints.c 2004-12-22 22:53:54 -08:00
-+++ b/fs/reiserfs/prints.c 2004-12-22 22:53:54 -08:00
-@@ -366,6 +366,49 @@
- reiserfs_bdevname (sb), error_buf);
- }
-
-+static void
-+do_handle_error (struct super_block *sb, int errno)
-+{
-+ if (reiserfs_error_panic (sb)) {
-+ panic ("REISERFS: panic (device %s): Panic forced after error\n",
-+ reiserfs_bdevname (sb));
-+ }
-+
-+ if (reiserfs_error_ro (sb)) {
-+ printk (KERN_CRIT "REISERFS: error (device %s): Re-mounting fs "
-+ "readonly\n", reiserfs_bdevname (sb));
-+ reiserfs_journal_abort (sb, errno);
-+ }
-+}
-+
-+void
-+reiserfs_error (struct super_block * sb, int errno, const char *fmt, ...)
-+{
-+ do_reiserfs_warning (fmt);
-+ printk (KERN_CRIT "REISERFS: error (device %s): %s\n",
-+ reiserfs_bdevname (sb), error_buf);
-+ do_handle_error (sb, errno);
-+}
-+
-+void
-+reiserfs_abort (struct super_block *sb, int errno, const char *fmt, ...)
-+{
-+ do_reiserfs_warning (fmt);
-+
-+ if (reiserfs_error_panic (sb)) {
-+ panic (KERN_CRIT "REISERFS: panic (device %s): %s\n",
-+ reiserfs_bdevname (sb), error_buf);
-+ }
-+
-+ if (sb->s_flags & MS_RDONLY)
-+ return;
-+
-+ printk (KERN_CRIT "REISERFS: abort (device %s): %s\n",
-+ reiserfs_bdevname (sb), error_buf);
-+
-+ sb->s_flags |= MS_RDONLY;
-+ reiserfs_journal_abort (sb, errno);
-+}
-
- void print_virtual_node (struct virtual_node * vn)
- {
-diff -Nru a/fs/reiserfs/resize.c b/fs/reiserfs/resize.c
---- a/fs/reiserfs/resize.c 2004-12-22 22:53:54 -08:00
-+++ b/fs/reiserfs/resize.c 2004-12-22 22:53:54 -08:00
-@@ -19,8 +19,10 @@
-
- int reiserfs_resize (struct super_block * s, unsigned long block_count_new)
- {
-+ int err = 0;
- struct reiserfs_super_block * sb;
- struct reiserfs_bitmap_info *bitmap;
-+ struct reiserfs_bitmap_info *old_bitmap = SB_AP_BITMAP(s);
- struct buffer_head * bh;
- struct reiserfs_transaction_handle th;
- unsigned int bmap_nr_new, bmap_nr;
-@@ -107,12 +109,19 @@
- * block pointers */
- bitmap = vmalloc(sizeof(struct reiserfs_bitmap_info) * bmap_nr_new);
- if (!bitmap) {
-+ /* Journal bitmaps are still supersized, but the memory isn't
-+ * leaked, so I guess it's ok */
- printk("reiserfs_resize: unable to allocate memory.\n");
- return -ENOMEM;
- }
- memset (bitmap, 0, sizeof (struct reiserfs_bitmap_info) * SB_BMAP_NR(s));
- for (i = 0; i < bmap_nr; i++)
-- bitmap[i] = SB_AP_BITMAP(s)[i];
-+ bitmap[i] = old_bitmap[i];
-+
-+ /* This doesn't go through the journal, but it doesn't have to.
-+ * The changes are still atomic: We're synced up when the journal
-+ * transaction begins, and the new bitmaps don't matter if the
-+ * transaction fails. */
- for (i = bmap_nr; i < bmap_nr_new; i++) {
- bitmap[i].bh = sb_getblk(s, i * s->s_blocksize * 8);
- memset(bitmap[i].bh->b_data, 0, sb_blocksize(sb));
-@@ -126,12 +135,16 @@
- bitmap[i].free_count = sb_blocksize(sb) * 8 - 1;
- }
- /* free old bitmap blocks array */
-- vfree(SB_AP_BITMAP(s));
- SB_AP_BITMAP(s) = bitmap;
-+ vfree (old_bitmap);
- }
-
-- /* begin transaction */
-- journal_begin(&th, s, 10);
-+ /* begin transaction, if there was an error, it's fine. Yes, we have
-+ * incorrect bitmaps now, but none of it is ever going to touch the
-+ * disk anyway. */
-+ err = journal_begin(&th, s, 10);
-+ if (err)
-+ return err;
-
- /* correct last bitmap blocks in old and new disk layout */
- reiserfs_prepare_for_journal(s, SB_AP_BITMAP(s)[bmap_nr - 1].bh, 1);
-@@ -165,8 +178,5 @@
- journal_mark_dirty(&th, s, SB_BUFFER_WITH_SB(s));
-
- SB_JOURNAL(s)->j_must_wait = 1;
-- journal_end(&th, s, 10);
--
-- return 0;
-+ return journal_end(&th, s, 10);
- }
--
-diff -Nru a/fs/reiserfs/stree.c b/fs/reiserfs/stree.c
---- a/fs/reiserfs/stree.c 2004-12-22 22:53:54 -08:00
-+++ b/fs/reiserfs/stree.c 2004-12-22 22:53:54 -08:00
-@@ -1036,6 +1036,8 @@
- struct item_head * p_le_ih = PATH_PITEM_HEAD(p_s_path);
- struct buffer_head * p_s_bh = PATH_PLAST_BUFFER(p_s_path);
-
-+ BUG_ON (!th->t_trans_id);
-+
- /* Stat_data item. */
- if ( is_statdata_le_ih (p_le_ih) ) {
-
-@@ -1222,6 +1224,9 @@
- struct path * p_s_path,
- int n_size
- ) {
-+
-+ BUG_ON (!th->t_trans_id);
-+
- memset (p_s_tb,'\0',sizeof(struct tree_balance));
- p_s_tb->transaction_handle = th ;
- p_s_tb->tb_sb = p_s_sb;
-@@ -1290,6 +1295,8 @@
- int n_iter = 0;
- #endif
-
-+ BUG_ON (!th->t_trans_id);
-+
- init_tb_struct(th, &s_del_balance, p_s_sb, p_s_path, 0/*size is unknown*/);
-
- while ( 1 ) {
-@@ -1419,6 +1426,8 @@
- struct cpu_key cpu_key;
- int retval;
- int quota_cut_bytes = 0;
-+
-+ BUG_ON (!th->t_trans_id);
-
- le_key2cpu_key (&cpu_key, key);
-
-@@ -1474,12 +1483,16 @@
- }
-
-
--void reiserfs_delete_object (struct reiserfs_transaction_handle *th, struct inode * inode)
-+int reiserfs_delete_object (struct reiserfs_transaction_handle *th, struct inode * inode)
- {
-+ int err;
- inode->i_size = 0;
-+ BUG_ON (!th->t_trans_id);
-
- /* for directory this deletes item containing "." and ".." */
-- reiserfs_do_truncate (th, inode, NULL, 0/*no timestamp updates*/);
-+ err = reiserfs_do_truncate (th, inode, NULL, 0/*no timestamp updates*/);
-+ if (err)
-+ return err;
-
- #if defined( USE_INODE_GENERATION_COUNTER )
- if( !old_format_only ( th -> t_super ) )
-@@ -1493,6 +1506,8 @@
- /* USE_INODE_GENERATION_COUNTER */
- #endif
- reiserfs_delete_solid_item (th, inode, INODE_PKEY (inode));
-+
-+ return err;
- }
-
- static void
-@@ -1542,6 +1557,7 @@
- struct super_block * p_s_sb = p_s_inode->i_sb;
- int n_block_size = p_s_sb->s_blocksize;
- int cut_bytes;
-+ BUG_ON (!th->t_trans_id);
-
- if (n_new_file_size != p_s_inode->i_size)
- BUG ();
-@@ -1574,6 +1590,7 @@
- struct cpu_key tail_key;
- int tail_len;
- int removed;
-+ BUG_ON (!th->t_trans_id);
-
- make_cpu_key (&tail_key, inode, inode->i_size + 1, TYPE_DIRECT, 4);// !!!!
- tail_key.key_length = 4;
-@@ -1623,6 +1640,8 @@
- int retval2 = -1;
- int quota_cut_bytes;
- loff_t tail_pos = 0;
-+
-+ BUG_ON (!th->t_trans_id);
-
- init_tb_struct(th, &s_cut_balance, p_s_inode->i_sb, p_s_path, n_cut_size);
-
-@@ -1775,6 +1794,7 @@
-
- static void truncate_directory (struct reiserfs_transaction_handle *th, struct inode * inode)
- {
-+ BUG_ON (!th->t_trans_id);
- if (inode->i_nlink)
- reiserfs_warning (inode->i_sb,
- "vs-5655: truncate_directory: link count != 0");
-@@ -1792,7 +1812,7 @@
-
- /* Truncate file to the new size. Note, this must be called with a transaction
- already started */
--void reiserfs_do_truncate (struct reiserfs_transaction_handle *th,
-+int reiserfs_do_truncate (struct reiserfs_transaction_handle *th,
- struct inode * p_s_inode, /* ->i_size contains new
- size */
- struct page *page, /* up to date for last block */
-@@ -1808,14 +1828,16 @@
- n_new_file_size;/* New file size. */
- int n_deleted; /* Number of deleted or truncated bytes. */
- int retval;
-+ int err = 0;
-
-+ BUG_ON (!th->t_trans_id);
- if ( ! (S_ISREG(p_s_inode->i_mode) || S_ISDIR(p_s_inode->i_mode) || S_ISLNK(p_s_inode->i_mode)) )
-- return;
-+ return 0;
-
- if (S_ISDIR(p_s_inode->i_mode)) {
- // deletion of directory - no need to update timestamps
- truncate_directory (th, p_s_inode);
-- return;
-+ return 0;
- }
-
- /* Get new file size. */
-@@ -1828,13 +1850,15 @@
- if (retval == IO_ERROR) {
- reiserfs_warning (p_s_inode->i_sb, "vs-5657: reiserfs_do_truncate: "
- "i/o failure occurred trying to truncate %K", &s_item_key);
-- return;
-+ err = -EIO;
-+ goto out;
- }
- if (retval == POSITION_FOUND || retval == FILE_NOT_FOUND) {
-- pathrelse (&s_search_path);
- reiserfs_warning (p_s_inode->i_sb, "PAP-5660: reiserfs_do_truncate: "
- "wrong result %d of search for %K", retval, &s_item_key);
-- return;
-+
-+ err = -EIO;
-+ goto out;
- }
-
- s_search_path.pos_in_item --;
-@@ -1872,7 +1896,7 @@
- if (n_deleted < 0) {
- reiserfs_warning (p_s_inode->i_sb, "vs-5665: reiserfs_do_truncate: reiserfs_cut_from_item failed");
- reiserfs_check_path(&s_search_path) ;
-- return;
-+ return 0;
- }
-
- RFALSE( n_deleted > n_file_size,
-@@ -1902,8 +1926,13 @@
- }
- reiserfs_update_sd(th, p_s_inode) ;
-
-- journal_end(th, p_s_inode->i_sb, orig_len_alloc) ;
-- journal_begin(th, p_s_inode->i_sb, JOURNAL_PER_BALANCE_CNT * 6) ;
-+ err = journal_end(th, p_s_inode->i_sb, orig_len_alloc) ;
-+ if (err)
-+ goto out;
-+ err = journal_begin (th, p_s_inode->i_sb,
-+ JOURNAL_PER_BALANCE_CNT * 6);
-+ if (err)
-+ goto out;
- reiserfs_update_inode_transaction(p_s_inode) ;
- }
- } while ( n_file_size > ROUND_UP (n_new_file_size) &&
-@@ -1920,7 +1949,9 @@
- }
- reiserfs_update_sd (th, p_s_inode);
-
-+out:
- pathrelse(&s_search_path) ;
-+ return err;
- }
-
-
-@@ -1963,6 +1994,8 @@
- int retval;
- int fs_gen;
-
-+ BUG_ON (!th->t_trans_id);
-+
- fs_gen = get_generation(inode->i_sb) ;
-
- #ifdef REISERQUOTA_DEBUG
-@@ -2034,6 +2067,8 @@
- int retval;
- int fs_gen = 0 ;
- int quota_bytes = 0 ;
-+
-+ BUG_ON (!th->t_trans_id);
-
- if (inode) { /* Do we count quotas for item? */
- fs_gen = get_generation(inode->i_sb);
-diff -Nru a/fs/reiserfs/super.c b/fs/reiserfs/super.c
---- a/fs/reiserfs/super.c 2004-12-22 22:53:54 -08:00
-+++ b/fs/reiserfs/super.c 2004-12-22 22:53:54 -08:00
-@@ -24,6 +24,7 @@
- #include <linux/blkdev.h>
- #include <linux/buffer_head.h>
- #include <linux/vfs.h>
-+#include <linux/namespace.h>
-
- struct file_system_type reiserfs_fs_type;
-
-@@ -66,11 +67,14 @@
- if (!(s->s_flags & MS_RDONLY)) {
- struct reiserfs_transaction_handle th;
- reiserfs_write_lock(s);
-- journal_begin(&th, s, 1);
-- journal_end_sync(&th, s, 1);
-- reiserfs_flush_old_commits(s);
-- s->s_dirt = 0;
-+ if (!journal_begin(&th, s, 1))
-+ if (!journal_end_sync(&th, s, 1))
-+ reiserfs_flush_old_commits(s);
-+ s->s_dirt = 0; /* Even if it's not true.
-+ * We'll loop forever in sync_supers otherwise */
- reiserfs_write_unlock(s);
-+ } else {
-+ s->s_dirt = 0;
- }
- }
-
-@@ -84,11 +88,15 @@
- struct reiserfs_transaction_handle th ;
- reiserfs_write_lock(s);
- if (!(s->s_flags & MS_RDONLY)) {
-- journal_begin(&th, s, 1) ;
-- reiserfs_prepare_for_journal(s, SB_BUFFER_WITH_SB(s), 1);
-- journal_mark_dirty(&th, s, SB_BUFFER_WITH_SB (s));
-- reiserfs_block_writes(&th) ;
-- journal_end_sync(&th, s, 1) ;
-+ int err = journal_begin(&th, s, 1) ;
-+ if (err) {
-+ reiserfs_block_writes(&th) ;
-+ } else {
-+ reiserfs_prepare_for_journal(s, SB_BUFFER_WITH_SB(s), 1);
-+ journal_mark_dirty(&th, s, SB_BUFFER_WITH_SB (s));
-+ reiserfs_block_writes(&th) ;
-+ journal_end_sync(&th, s, 1) ;
-+ }
- }
- s->s_dirt = 0;
- reiserfs_write_unlock(s);
-@@ -108,29 +116,32 @@
- protecting unlink is bigger that a key lf "save link" which
- protects truncate), so there left no items to make truncate
- completion on */
--static void remove_save_link_only (struct super_block * s, struct key * key, int oid_free)
-+static int remove_save_link_only (struct super_block * s, struct key * key, int oid_free)
- {
- struct reiserfs_transaction_handle th;
-+ int err;
-
- /* we are going to do one balancing */
-- journal_begin (&th, s, JOURNAL_PER_BALANCE_CNT);
-+ err = journal_begin (&th, s, JOURNAL_PER_BALANCE_CNT);
-+ if (err)
-+ return err;
-
- reiserfs_delete_solid_item (&th, NULL, key);
- if (oid_free)
- /* removals are protected by direct items */
- reiserfs_release_objectid (&th, le32_to_cpu (key->k_objectid));
-
-- journal_end (&th, s, JOURNAL_PER_BALANCE_CNT);
-+ return journal_end (&th, s, JOURNAL_PER_BALANCE_CNT);
- }
-
-
- /* look for uncompleted unlinks and truncates and complete them */
--static void finish_unfinished (struct super_block * s)
-+static int finish_unfinished (struct super_block * s)
- {
- INITIALIZE_PATH (path);
- struct cpu_key max_cpu_key, obj_key;
- struct key save_link_key;
-- int retval;
-+ int retval = 0;
- struct item_head * ih;
- struct buffer_head * bh;
- int item_pos;
-@@ -147,7 +158,7 @@
-
- done = 0;
- REISERFS_SB(s)->s_is_unlinked_ok = 1;
-- while (1) {
-+ while (!retval) {
- retval = search_item (s, &max_cpu_key, &path);
- if (retval != ITEM_NOT_FOUND) {
- reiserfs_warning (s, "vs-2140: finish_unfinished: search_by_key returned %d",
-@@ -189,7 +200,7 @@
- "save" link and release objectid */
- reiserfs_warning (s, "vs-2180: finish_unfinished: iget failed for %K",
- &obj_key);
-- remove_save_link_only (s, &save_link_key, 1);
-+ retval = remove_save_link_only (s, &save_link_key, 1);
- continue;
- }
-
-@@ -197,7 +208,7 @@
- /* file is not unlinked */
- reiserfs_warning (s, "vs-2185: finish_unfinished: file %K is not unlinked",
- &obj_key);
-- remove_save_link_only (s, &save_link_key, 0);
-+ retval = remove_save_link_only (s, &save_link_key, 0);
- continue;
- }
-
-@@ -207,7 +218,7 @@
- then boot into old kernel, remove the file and create dir with
- the same key. */
- reiserfs_warning(s, "green-2101: impossible truncate on a directory %k. Please report", INODE_PKEY (inode));
-- remove_save_link_only (s, &save_link_key, 0);
-+ retval = remove_save_link_only (s, &save_link_key, 0);
- truncate = 0;
- iput (inode);
- continue;
-@@ -220,12 +231,13 @@
- reiserfs_info (s, "Truncating %k to %Ld ..",
- INODE_PKEY (inode), inode->i_size);
- reiserfs_truncate_file (inode, 0/*don't update modification time*/);
-- remove_save_link (inode, truncate);
-+ retval = remove_save_link (inode, truncate);
- } else {
- REISERFS_I(inode) -> i_flags |= i_link_saved_unlink_mask;
- /* not completed unlink (rmdir) found */
- reiserfs_info (s, "Removing %k..", INODE_PKEY (inode));
- /* removal gets completed in iput */
-+ retval = 0;
- }
-
- iput (inode);
-@@ -238,6 +250,7 @@
- if (done)
- reiserfs_info (s, "There were %d uncompleted unlinks/truncates. "
- "Completed\n", done);
-+ return retval;
- }
-
- /* to protect file being unlinked from getting lost we "safe" link files
-@@ -253,6 +266,8 @@
- struct item_head ih;
- __u32 link;
-
-+ BUG_ON (!th->t_trans_id);
-+
- /* file can only get one "save link" of each kind */
- RFALSE( truncate &&
- ( REISERFS_I(inode) -> i_flags & i_link_saved_truncate_mask ),
-@@ -317,14 +332,16 @@
-
-
- /* this opens transaction unlike add_save_link */
--void remove_save_link (struct inode * inode, int truncate)
-+int remove_save_link (struct inode * inode, int truncate)
- {
- struct reiserfs_transaction_handle th;
- struct key key;
--
-+ int err;
-
- /* we are going to do one balancing only */
-- journal_begin (&th, inode->i_sb, JOURNAL_PER_BALANCE_CNT);
-+ err = journal_begin (&th, inode->i_sb, JOURNAL_PER_BALANCE_CNT);
-+ if (err)
-+ return err;
-
- /* setup key of "save" link */
- key.k_dir_id = cpu_to_le32 (MAX_KEY_OBJECTID);
-@@ -352,7 +369,7 @@
- } else
- REISERFS_I(inode) -> i_flags &= ~i_link_saved_truncate_mask;
-
-- journal_end (&th, inode->i_sb, JOURNAL_PER_BALANCE_CNT);
-+ return journal_end (&th, inode->i_sb, JOURNAL_PER_BALANCE_CNT);
- }
-
-
-@@ -360,6 +377,7 @@
- {
- int i;
- struct reiserfs_transaction_handle th ;
-+ th.t_trans_id = 0;
-
- if (REISERFS_SB(s)->xattr_root) {
- d_invalidate (REISERFS_SB(s)->xattr_root);
-@@ -373,10 +391,11 @@
-
- /* change file system state to current state if it was mounted with read-write permissions */
- if (!(s->s_flags & MS_RDONLY)) {
-- journal_begin(&th, s, 10) ;
-- reiserfs_prepare_for_journal(s, SB_BUFFER_WITH_SB(s), 1) ;
-- set_sb_umount_state( SB_DISK_SUPER_BLOCK(s), REISERFS_SB(s)->s_mount_state );
-- journal_mark_dirty(&th, s, SB_BUFFER_WITH_SB (s));
-+ if (!journal_begin(&th, s, 10)) {
-+ reiserfs_prepare_for_journal(s, SB_BUFFER_WITH_SB(s), 1) ;
-+ set_sb_umount_state( SB_DISK_SUPER_BLOCK(s), REISERFS_SB(s)->s_mount_state );
-+ journal_mark_dirty(&th, s, SB_BUFFER_WITH_SB (s));
-+ }
- }
-
- /* note, journal_release checks for readonly mount, and can decide not
-@@ -461,6 +480,7 @@
- static void reiserfs_dirty_inode (struct inode * inode) {
- struct reiserfs_transaction_handle th ;
-
-+ int err = 0;
- if (inode->i_sb->s_flags & MS_RDONLY) {
- reiserfs_warning(inode->i_sb, "clm-6006: writing inode %lu on readonly FS",
- inode->i_ino) ;
-@@ -471,7 +491,11 @@
- /* this is really only used for atime updates, so they don't have
- ** to be included in O_SYNC or fsync
- */
-- journal_begin(&th, inode->i_sb, 1) ;
-+ err = journal_begin(&th, inode->i_sb, 1) ;
-+ if (err) {
-+ reiserfs_write_unlock (inode->i_sb);
-+ return;
-+ }
- reiserfs_update_sd (&th, inode);
- journal_end(&th, inode->i_sb, 1) ;
- reiserfs_write_unlock(inode->i_sb);
-@@ -575,6 +599,18 @@
- {NULL, 0, 0}
- };
-
-+static const arg_desc_t error_actions[] = {
-+ {"panic", 1 << REISERFS_ERROR_PANIC,
-+ (1 << REISERFS_ERROR_RO | 1 << REISERFS_ERROR_CONTINUE)},
-+ {"ro-remount", 1 << REISERFS_ERROR_RO,
-+ (1 << REISERFS_ERROR_PANIC | 1 << REISERFS_ERROR_CONTINUE)},
-+#ifdef REISERFS_JOURNAL_ERROR_ALLOWS_NO_LOG
-+ {"continue", 1 << REISERFS_ERROR_CONTINUE,
-+ (1 << REISERFS_ERROR_PANIC | 1 << REISERFS_ERROR_RO)},
-+#endif
-+ {NULL, 0, 0},
-+};
-+
- int reiserfs_default_io_size = 128 * 1024; /* Default recommended I/O size is 128k.
- There might be broken applications that are
- confused by this. Use nolargeio mount option
-@@ -725,6 +761,7 @@
- {"commit", .arg_required = 'c', .values = NULL},
- {"usrquota",},
- {"grpquota",},
-+ {"errors", .arg_required = 'e', .values = error_actions},
- {NULL,}
- };
-
-@@ -862,6 +899,7 @@
- unsigned long safe_mask = 0;
- unsigned int commit_max_age = (unsigned int)-1;
- struct reiserfs_journal *journal = SB_JOURNAL(s);
-+ int err;
-
- rs = SB_DISK_SUPER_BLOCK (s);
-
-@@ -882,6 +920,9 @@
- safe_mask |= 1 << REISERFS_POSIXACL;
- safe_mask |= 1 << REISERFS_BARRIER_FLUSH;
- safe_mask |= 1 << REISERFS_BARRIER_NONE;
-+ safe_mask |= 1 << REISERFS_ERROR_RO;
-+ safe_mask |= 1 << REISERFS_ERROR_CONTINUE;
-+ safe_mask |= 1 << REISERFS_ERROR_PANIC;
-
- /* Update the bitmask, taking care to keep
- * the bits we're not allowed to change here */
-@@ -915,7 +956,10 @@
- return 0;
- }
-
-- journal_begin(&th, s, 10) ;
-+ err = journal_begin(&th, s, 10) ;
-+ if (err)
-+ return err;
-+
- /* Mounting a rw partition read-only. */
- reiserfs_prepare_for_journal(s, SB_BUFFER_WITH_SB(s), 1) ;
- set_sb_umount_state( rs, REISERFS_SB(s)->s_mount_state );
-@@ -927,11 +971,16 @@
- return 0; /* We are read-write already */
- }
-
-+ if (reiserfs_is_journal_aborted (journal))
-+ return journal->j_errno;
-+
- handle_data_mode(s, mount_options);
- handle_barrier_mode(s, mount_options);
- REISERFS_SB(s)->s_mount_state = sb_umount_state(rs) ;
- s->s_flags &= ~MS_RDONLY ; /* now it is safe to call journal_begin */
-- journal_begin(&th, s, 10) ;
-+ err = journal_begin(&th, s, 10) ;
-+ if (err)
-+ return err;
-
- /* Mount a partition which is read-only, read-write */
- reiserfs_prepare_for_journal(s, SB_BUFFER_WITH_SB(s), 1) ;
-@@ -944,7 +993,9 @@
- }
- /* this will force a full flush of all journal lists */
- SB_JOURNAL(s)->j_must_wait = 1 ;
-- journal_end(&th, s, 10) ;
-+ err = journal_end(&th, s, 10) ;
-+ if (err)
-+ return err;
- s->s_dirt = 0;
-
- if (!( *mount_flags & MS_RDONLY ) ) {
-@@ -1372,8 +1423,9 @@
- }
- s->s_fs_info = sbi;
- memset (sbi, 0, sizeof (struct reiserfs_sb_info));
-- /* Set default values for options: non-aggressive tails */
-- REISERFS_SB(s)->s_mount_opt = ( 1 << REISERFS_SMALLTAIL );
-+ /* Set default values for options: non-aggressive tails, RO on errors */
-+ REISERFS_SB(s)->s_mount_opt |= (1 << REISERFS_SMALLTAIL);
-+ REISERFS_SB(s)->s_mount_opt |= (1 << REISERFS_ERROR_RO);
- /* no preallocation minimum, be smart in
- reiserfs_file_write instead */
- REISERFS_SB(s)->s_alloc_options.preallocmin = 0;
-@@ -1501,7 +1553,12 @@
-
- if (!(s->s_flags & MS_RDONLY)) {
-
-- journal_begin(&th, s, 1) ;
-+ errval = journal_begin(&th, s, 1) ;
-+ if (errval) {
-+ dput (s->s_root);
-+ s->s_root = NULL;
-+ goto error;
-+ }
- reiserfs_prepare_for_journal(s, SB_BUFFER_WITH_SB(s), 1) ;
-
- set_sb_umount_state( rs, REISERFS_ERROR_FS );
-@@ -1531,9 +1588,14 @@
- }
-
- journal_mark_dirty(&th, s, SB_BUFFER_WITH_SB (s));
-- journal_end(&th, s, 1) ;
-+ errval = journal_end(&th, s, 1) ;
-+ if (errval) {
-+ dput (s->s_root);
-+ s->s_root = NULL;
-+ goto error;
-+ }
-
-- if (reiserfs_xattr_init (s, s->s_flags)) {
-+ if ((errval = reiserfs_xattr_init (s, s->s_flags))) {
- dput (s->s_root);
- s->s_root = NULL;
- goto error;
-@@ -1546,7 +1608,7 @@
- reiserfs_info (s, "using 3.5.x disk format\n") ;
- }
-
-- if (reiserfs_xattr_init (s, s->s_flags)) {
-+ if ((errval = reiserfs_xattr_init (s, s->s_flags))) {
- dput (s->s_root);
- s->s_root = NULL;
- goto error;
-diff -Nru a/fs/reiserfs/tail_conversion.c b/fs/reiserfs/tail_conversion.c
---- a/fs/reiserfs/tail_conversion.c 2004-12-22 22:53:54 -08:00
-+++ b/fs/reiserfs/tail_conversion.c 2004-12-22 22:53:54 -08:00
-@@ -34,6 +34,7 @@
- that will be inserted in the
- tree. */
-
-+ BUG_ON (!th->t_trans_id);
-
- REISERFS_SB(sb)->s_direct2indirect ++;
-
-@@ -183,6 +184,8 @@
- int tail_len, round_tail_len;
- loff_t pos, pos1; /* position of first byte of the tail */
- struct cpu_key key;
-+
-+ BUG_ON (!th->t_trans_id);
-
- REISERFS_SB(p_s_sb)->s_indirect2direct ++;
-
-diff -Nru a/include/linux/reiserfs_fs.h b/include/linux/reiserfs_fs.h
---- a/include/linux/reiserfs_fs.h 2004-12-22 22:53:54 -08:00
-+++ b/include/linux/reiserfs_fs.h 2004-12-22 22:53:54 -08:00
-@@ -1751,6 +1751,7 @@
- void *t_handle_save ; /* save existing current->journal_info */
- unsigned displace_new_blocks:1; /* if new block allocation occurres, that block
- should be displaced from others */
-+ struct list_head t_list;
- } ;
-
- /* used to keep track of ordered and tail writes, attached to the buffer
-@@ -1810,12 +1811,14 @@
- int journal_transaction_should_end(struct reiserfs_transaction_handle *, int) ;
- int reiserfs_in_journal(struct super_block *p_s_sb, int bmap_nr, int bit_nr, int searchall, b_blocknr_t *next) ;
- int journal_begin(struct reiserfs_transaction_handle *, struct super_block *p_s_sb, unsigned long) ;
--
-+int journal_join_abort(struct reiserfs_transaction_handle *, struct super_block *p_s_sb, unsigned long) ;
-+void reiserfs_journal_abort (struct super_block *sb, int errno);
-+void reiserfs_abort (struct super_block *sb, int errno, const char *fmt, ...);
- int reiserfs_allocate_list_bitmaps(struct super_block *s, struct reiserfs_list_bitmap *, int) ;
-
- void add_save_link (struct reiserfs_transaction_handle * th,
- struct inode * inode, int truncate);
--void remove_save_link (struct inode * inode, int truncate);
-+int remove_save_link (struct inode * inode, int truncate);
-
- /* objectid.c */
- __u32 reiserfs_get_unused_objectid (struct reiserfs_transaction_handle *th);
-@@ -1911,8 +1914,8 @@
-
- void reiserfs_delete_solid_item (struct reiserfs_transaction_handle *th,
- struct inode *inode, struct key * key);
--void reiserfs_delete_object (struct reiserfs_transaction_handle *th, struct inode * p_s_inode);
--void reiserfs_do_truncate (struct reiserfs_transaction_handle *th,
-+int reiserfs_delete_object (struct reiserfs_transaction_handle *th, struct inode * p_s_inode);
-+int reiserfs_do_truncate (struct reiserfs_transaction_handle *th,
- struct inode * p_s_inode, struct page *,
- int update_timestamps);
-
-@@ -1926,7 +1929,7 @@
- void padd_item (char * item, int total_length, int length);
-
- /* inode.c */
--void restart_transaction(struct reiserfs_transaction_handle *th, struct inode *inode, struct path *path);
-+int restart_transaction(struct reiserfs_transaction_handle *th, struct inode *inode, struct path *path);
- void reiserfs_read_locked_inode(struct inode * inode, struct reiserfs_iget_args *args) ;
- int reiserfs_find_actor(struct inode * inode, void *p) ;
- int reiserfs_init_locked_inode(struct inode * inode, void *p) ;
-@@ -1941,7 +1944,7 @@
- int connectable );
-
- int reiserfs_prepare_write(struct file *, struct page *, unsigned, unsigned) ;
--void reiserfs_truncate_file(struct inode *, int update_timestamps) ;
-+int reiserfs_truncate_file(struct inode *, int update_timestamps) ;
- void make_cpu_key (struct cpu_key * cpu_key, struct inode * inode, loff_t offset,
- int type, int key_length);
- void make_le_item_head (struct item_head * ih, const struct cpu_key * key,
-diff -Nru a/include/linux/reiserfs_fs_sb.h b/include/linux/reiserfs_fs_sb.h
---- a/include/linux/reiserfs_fs_sb.h 2004-12-22 22:53:54 -08:00
-+++ b/include/linux/reiserfs_fs_sb.h 2004-12-22 22:53:54 -08:00
-@@ -242,14 +242,24 @@
- struct reiserfs_journal_cnode *j_list_hash_table[JOURNAL_HASH_SIZE] ; /* hash table for all the real buffer heads in all
- the transactions */
- struct list_head j_prealloc_list; /* list of inodes which have preallocated blocks */
-+ int j_persistent_trans;
- unsigned long j_max_trans_size ;
- unsigned long j_max_batch_size ;
-
-+ int j_errno;
-+
- /* when flushing ordered buffers, throttle new ordered writers */
- struct work_struct j_work;
- atomic_t j_async_throttle;
- };
-
-+enum journal_state_bits {
-+ J_WRITERS_BLOCKED = 1, /* set when new writers not allowed */
-+ J_WRITERS_QUEUED, /* set when log is full due to too many writers */
-+ J_ABORTED, /* set when log is aborted */
-+};
-+
-+
- #define JOURNAL_DESC_MAGIC "ReIsErLB" /* ick. magic string to find desc blocks in the journal */
-
- typedef __u32 (*hashf_t) (const signed char *, int);
-@@ -399,6 +409,7 @@
- struct dentry *xattr_root; /* root of /.reiserfs_priv/.xa */
- struct rw_semaphore xattr_dir_sem;
-
-+ int j_errno;
- };
-
- /* Definitions of reiserfs on-disk properties: */
-@@ -447,6 +458,11 @@
- REISERFS_BARRIER_NONE,
- REISERFS_BARRIER_FLUSH,
-
-+ /* Actions on error */
-+ REISERFS_ERROR_PANIC,
-+ REISERFS_ERROR_RO,
-+ REISERFS_ERROR_CONTINUE,
-+
- REISERFS_TEST1,
- REISERFS_TEST2,
- REISERFS_TEST3,
-@@ -478,6 +494,10 @@
- #define reiserfs_barrier_none(s) (REISERFS_SB(s)->s_mount_opt & (1 << REISERFS_BARRIER_NONE))
- #define reiserfs_barrier_flush(s) (REISERFS_SB(s)->s_mount_opt & (1 << REISERFS_BARRIER_FLUSH))
-
-+#define reiserfs_error_panic(s) (REISERFS_SB(s)->s_mount_opt & (1 << REISERFS_ERROR_PANIC))
-+#define reiserfs_error_ro(s) (REISERFS_SB(s)->s_mount_opt & (1 << REISERFS_ERROR_RO))
-+#define reiserfs_error_continue(s) (REISERFS_SB(s)->s_mount_opt & (1 << REISERFS_ERROR_CONTINUE))
-+
- void reiserfs_file_buffer (struct buffer_head * bh, int list);
- extern struct file_system_type reiserfs_fs_type;
- int reiserfs_resize(struct super_block *, unsigned long) ;
-@@ -500,6 +520,12 @@
- static inline char *reiserfs_bdevname(struct super_block *s)
- {
- return (s == NULL) ? "Null superblock" : s -> s_id;
-+}
-+
-+#define reiserfs_is_journal_aborted(journal) (unlikely (__reiserfs_is_journal_aborted (journal)))
-+static inline int __reiserfs_is_journal_aborted (struct reiserfs_journal *journal)
-+{
-+ return test_bit (J_ABORTED, &journal->j_state);
- }
-
- #endif /* _LINUX_REISER_FS_SB */