From: Alexander Zarochentsev <zam@namesys.com>
To: sudo Yang <sudoyang@gmail.com>
Cc: reiserfs-list@namesys.com
Subject: Re: journal too big
Date: Tue, 2 Aug 2005 22:44:59 +0400 [thread overview]
Message-ID: <200508022245.00532.zam@namesys.com> (raw)
In-Reply-To: <4f52331f050802094839f9ad7@mail.gmail.com>
[-- Attachment #1: Type: text/plain, Size: 483 bytes --]
Hello.
On Tuesday 02 August 2005 20:48, sudo Yang wrote:
> Some of our systems are getting a kernel panic. This error is logged
> to /var/log/messages:
> Jul 23 09:52:13 csd01a-bld kernel: REISERFS: panic (device sdb1):
> journal-1413: journal_mark_dirty: j_len (1024) is too big
[ ... ]
>
> We'r eusing ReiserfsFS 3.x. What does this error mean? What can we
> do about it?
Would you please try the attached patch? it is for 2.6.9 but applies cleanly
to 2.6.8.
>
> Thanks
[-- Attachment #2: reiserfs-do_truncate-fix-3.diff --]
[-- Type: text/x-diff, Size: 9086 bytes --]
--- linux-2.6.9/fs/reiserfs/stree.c.orig 2004-11-08 11:44:05.000000000 +0300
+++ linux-2.6.9/fs/reiserfs/stree.c 2004-11-17 10:11:21.618449392 +0300
@@ -1016,6 +1016,7 @@ static inline int prepare_for_direntry_i
return M_CUT;
}
+#define JOURNAL_FOR_FREE_BLOCK_AND_UPDATE_SD (2 * JOURNAL_PER_BALANCE_CNT + 1)
/* If the path points to a directory or direct item, calculate mode and the size cut, for balance.
If the path points to an indirect item, remove some number of its unformatted nodes.
@@ -1055,137 +1056,80 @@ static char prepare_for_delete_or_cut(
if ( is_direct_le_ih (p_le_ih) )
return prepare_for_direct_item (p_s_path, p_le_ih, inode, n_new_file_length, p_n_cut_size);
-
/* Case of an indirect item. */
{
- int n_unfm_number, /* Number of the item unformatted nodes. */
- n_counter,
- n_blk_size;
- __u32 * p_n_unfm_pointer; /* Pointer to the unformatted node number. */
- __u32 tmp;
- struct item_head s_ih; /* Item header. */
- char c_mode; /* Returned mode of the balance. */
- int need_research;
-
-
- n_blk_size = p_s_sb->s_blocksize;
-
- /* Search for the needed object indirect item until there are no unformatted nodes to be removed. */
- do {
- need_research = 0;
- p_s_bh = PATH_PLAST_BUFFER(p_s_path);
- /* Copy indirect item header to a temp variable. */
+ int blk_size = p_s_sb->s_blocksize;
+ struct item_head s_ih;
+ int need_re_search;
+ int delete = 0;
+ int result = M_CUT;
+ int pos = 0;
+
+ if ( n_new_file_length == max_reiserfs_offset (inode) ) {
+ /* prepare_for_delete_or_cut() is called by
+ * reiserfs_delete_item() */
+ n_new_file_length = 0;
+ delete = 1;
+ }
+
+ do {
+ need_re_search = 0;
+ *p_n_cut_size = 0;
+ p_s_bh = PATH_PLAST_BUFFER(p_s_path);
copy_item_head(&s_ih, PATH_PITEM_HEAD(p_s_path));
- /* Calculate number of unformatted nodes in this item. */
- n_unfm_number = I_UNFM_NUM(&s_ih);
+ pos = I_UNFM_NUM(&s_ih);
- RFALSE( ! is_indirect_le_ih(&s_ih) || ! n_unfm_number ||
- pos_in_item (p_s_path) + 1 != n_unfm_number,
- "PAP-5240: invalid item %h "
- "n_unfm_number = %d *p_n_pos_in_item = %d",
- &s_ih, n_unfm_number, pos_in_item (p_s_path));
-
- /* Calculate balance mode and position in the item to remove unformatted nodes. */
- if ( n_new_file_length == max_reiserfs_offset (inode) ) {/* Case of delete. */
- pos_in_item (p_s_path) = 0;
- *p_n_cut_size = -(IH_SIZE + ih_item_len(&s_ih));
- c_mode = M_DELETE;
- }
- else { /* Case of truncate. */
- if ( n_new_file_length < le_ih_k_offset (&s_ih) ) {
- pos_in_item (p_s_path) = 0;
- *p_n_cut_size = -(IH_SIZE + ih_item_len(&s_ih));
- c_mode = M_DELETE; /* Delete this item. */
- }
- else {
- /* indirect item must be truncated starting from *p_n_pos_in_item-th position */
- pos_in_item (p_s_path) = (n_new_file_length + n_blk_size - le_ih_k_offset (&s_ih) ) >> p_s_sb->s_blocksize_bits;
-
- RFALSE( pos_in_item (p_s_path) > n_unfm_number,
- "PAP-5250: invalid position in the item");
-
- /* Either convert last unformatted node of indirect item to direct item or increase
- its free space. */
- if ( pos_in_item (p_s_path) == n_unfm_number ) {
- *p_n_cut_size = 0; /* Nothing to cut. */
- return M_CONVERT; /* Maybe convert last unformatted node to the direct item. */
- }
- /* Calculate size to cut. */
- *p_n_cut_size = -(ih_item_len(&s_ih) - pos_in_item(p_s_path) * UNFM_P_SIZE);
+ while (le_ih_k_offset (&s_ih) + (pos - 1) * blk_size > n_new_file_length) {
+ __u32 *unfm, block;
- c_mode = M_CUT; /* Cut from this indirect item. */
+ /* Each unformatted block deletion may involve one additional
+ * bitmap block into the transaction, thereby the initial
+ * journal space reservation might not be enough. */
+ if (!delete && (*p_n_cut_size) != 0 &&
+ reiserfs_transaction_free_space(th) < JOURNAL_FOR_FREE_BLOCK_AND_UPDATE_SD) {
+ break;
}
- }
-
- RFALSE( n_unfm_number <= pos_in_item (p_s_path),
- "PAP-5260: invalid position in the indirect item");
- /* pointers to be cut */
- n_unfm_number -= pos_in_item (p_s_path);
- /* Set pointer to the last unformatted node pointer that is to be cut. */
- p_n_unfm_pointer = (__u32 *)B_I_PITEM(p_s_bh, &s_ih) + I_UNFM_NUM(&s_ih) - 1 - *p_n_removed;
-
-
- /* We go through the unformatted nodes pointers of the indirect
- item and look for the unformatted nodes in the cache. If we
- found some of them we free it, zero corresponding indirect item
- entry and log buffer containing that indirect item. For this we
- need to prepare last path element for logging. If some
- unformatted node has b_count > 1 we must not free this
- unformatted node since it is in use. */
- reiserfs_prepare_for_journal(p_s_sb, p_s_bh, 1);
- // note: path could be changed, first line in for loop takes care
- // of it
+ unfm = (__u32 *)B_I_PITEM(p_s_bh, &s_ih) + pos - 1;
+ block = get_block_num(unfm, 0);
- for (n_counter = *p_n_removed;
- n_counter < n_unfm_number; n_counter++, p_n_unfm_pointer-- ) {
+ if (block != 0) {
+ reiserfs_prepare_for_journal(p_s_sb, p_s_bh, 1);
+ put_block_num(unfm, 0, 0);
+ journal_mark_dirty (th, p_s_sb, p_s_bh);
+ reiserfs_free_block(th, inode, block, 1);
+ }
cond_resched();
- if (item_moved (&s_ih, p_s_path)) {
- need_research = 1 ;
- break;
- }
- RFALSE( p_n_unfm_pointer < (__u32 *)B_I_PITEM(p_s_bh, &s_ih) ||
- p_n_unfm_pointer > (__u32 *)B_I_PITEM(p_s_bh, &s_ih) + I_UNFM_NUM(&s_ih) - 1,
- "vs-5265: pointer out of range");
-
- /* Hole, nothing to remove. */
- if ( ! get_block_num(p_n_unfm_pointer,0) ) {
- (*p_n_removed)++;
- continue;
+ if (item_moved (&s_ih, p_s_path)) {
+ need_re_search = 1;
+ break ;
}
- (*p_n_removed)++;
-
- tmp = get_block_num(p_n_unfm_pointer,0);
- put_block_num(p_n_unfm_pointer, 0, 0);
- journal_mark_dirty (th, p_s_sb, p_s_bh);
- reiserfs_free_block(th, inode, tmp, 1);
- if ( item_moved (&s_ih, p_s_path) ) {
- need_research = 1;
- break ;
+ pos --;
+ (*p_n_removed) ++;
+ (*p_n_cut_size) -= UNFM_P_SIZE;
+
+ if (pos == 0) {
+ (*p_n_cut_size) -= IH_SIZE;
+ result = M_DELETE;
+ break;
}
}
-
- /* a trick. If the buffer has been logged, this
- ** will do nothing. If we've broken the loop without
- ** logging it, it will restore the buffer
- **
- */
+ /* a trick. If the buffer has been logged, this will do nothing. If
+ ** we've broken the loop without logging it, it will restore the
+ ** buffer */
reiserfs_restore_prepared_buffer(p_s_sb, p_s_bh);
-
- /* This loop can be optimized. */
- } while ( (*p_n_removed < n_unfm_number || need_research) &&
- search_for_position_by_key(p_s_sb, p_s_item_key, p_s_path) == POSITION_FOUND );
-
- RFALSE( *p_n_removed < n_unfm_number,
- "PAP-5310: indirect item is not found");
- RFALSE( item_moved (&s_ih, p_s_path),
- "after while, comp failed, retry") ;
-
- if (c_mode == M_CUT)
- pos_in_item (p_s_path) *= UNFM_P_SIZE;
- return c_mode;
+ } while (need_re_search &&
+ search_for_position_by_key(p_s_sb, p_s_item_key, p_s_path) == POSITION_FOUND);
+ pos_in_item(p_s_path) = pos * UNFM_P_SIZE;
+
+ if (*p_n_cut_size == 0) {
+ /* Nothing were cut. maybe convert last unformatted node to the
+ * direct item? */
+ result = M_CONVERT;
+ }
+ return result;
}
}
@@ -1893,7 +1837,8 @@ void reiserfs_do_truncate (struct reiser
** sure the file is consistent before ending the current trans
** and starting a new one
*/
- if (journal_transaction_should_end(th, th->t_blocks_allocated)) {
+ if (journal_transaction_should_end(th, 0) ||
+ reiserfs_transaction_free_space(th) <= JOURNAL_FOR_FREE_BLOCK_AND_UPDATE_SD) {
int orig_len_alloc = th->t_blocks_allocated ;
decrement_counters_in_path(&s_search_path) ;
@@ -1903,7 +1848,8 @@ void reiserfs_do_truncate (struct reiser
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) ;
+ journal_begin(th, p_s_inode->i_sb,
+ JOURNAL_FOR_FREE_BLOCK_AND_UPDATE_SD + JOURNAL_PER_BALANCE_CNT * 4) ;
reiserfs_update_inode_transaction(p_s_inode) ;
}
} while ( n_file_size > ROUND_UP (n_new_file_size) &&
--- linux-2.6.9/include/linux/reiserfs_fs.h.orig 2004-11-08 18:00:24.000000000 +0300
+++ linux-2.6.9/include/linux/reiserfs_fs.h 2004-11-08 18:40:05.000000000 +0300
@@ -1769,6 +1769,11 @@ static inline int reiserfs_transaction_r
return 0 ;
}
+static inline int reiserfs_transaction_free_space(struct reiserfs_transaction_handle *th)
+{
+ return th->t_blocks_allocated - th->t_blocks_logged;
+}
+
int reiserfs_async_progress_wait(struct super_block *s);
struct reiserfs_transaction_handle *
next prev parent reply other threads:[~2005-08-02 18:44 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2005-08-02 16:48 journal too big sudo Yang
2005-08-02 18:44 ` Alexander Zarochentsev [this message]
[not found] ` <4f52331f05080212161577b5f3@mail.gmail.com>
2005-08-03 4:23 ` Alexander Zarochentsev
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=200508022245.00532.zam@namesys.com \
--to=zam@namesys.com \
--cc=reiserfs-list@namesys.com \
--cc=sudoyang@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.