patch-2.4.21 linux-2.4.21/fs/ext3/inode.c
Next file: linux-2.4.21/fs/ext3/ioctl.c
Previous file: linux-2.4.21/fs/ext3/ialloc.c
Back to the patch index
Back to the overall index
- Lines: 146
- Date:
2003-06-13 07:51:37.000000000 -0700
- Orig file:
linux-2.4.20/fs/ext3/inode.c
- Orig date:
2002-11-28 15:53:15.000000000 -0800
diff -urN linux-2.4.20/fs/ext3/inode.c linux-2.4.21/fs/ext3/inode.c
@@ -87,6 +87,34 @@
return err;
}
+/*
+ * Work out how many blocks we need to progress with the next chunk of a
+ * truncate transaction.
+ */
+
+static unsigned long blocks_for_truncate(struct inode *inode)
+{
+ unsigned long needed;
+
+ needed = inode->i_blocks >> (inode->i_sb->s_blocksize_bits - 9);
+
+ /* Give ourselves just enough room to cope with inodes in which
+ * i_blocks is corrupt: we've seen disk corruptions in the past
+ * which resulted in random data in an inode which looked enough
+ * like a regular file for ext3 to try to delete it. Things
+ * will go a bit crazy if that happens, but at least we should
+ * try not to panic the whole kernel. */
+ if (needed < 2)
+ needed = 2;
+
+ /* But we need to bound the transaction so we don't overflow the
+ * journal. */
+ if (needed > EXT3_MAX_TRANS_DATA)
+ needed = EXT3_MAX_TRANS_DATA;
+
+ return EXT3_DATA_TRANS_BLOCKS + needed;
+}
+
/*
* Truncate transactions can be complex and absolutely huge. So we need to
* be able to restart the transaction at a conventient checkpoint to make
@@ -100,14 +128,9 @@
static handle_t *start_transaction(struct inode *inode)
{
- long needed;
handle_t *result;
- needed = inode->i_blocks;
- if (needed > EXT3_MAX_TRANS_DATA)
- needed = EXT3_MAX_TRANS_DATA;
-
- result = ext3_journal_start(inode, EXT3_DATA_TRANS_BLOCKS + needed);
+ result = ext3_journal_start(inode, blocks_for_truncate(inode));
if (!IS_ERR(result))
return result;
@@ -123,14 +146,9 @@
*/
static int try_to_extend_transaction(handle_t *handle, struct inode *inode)
{
- long needed;
-
if (handle->h_buffer_credits > EXT3_RESERVE_TRANS_BLOCKS)
return 0;
- needed = inode->i_blocks;
- if (needed > EXT3_MAX_TRANS_DATA)
- needed = EXT3_MAX_TRANS_DATA;
- if (!ext3_journal_extend(handle, EXT3_RESERVE_TRANS_BLOCKS + needed))
+ if (!ext3_journal_extend(handle, blocks_for_truncate(inode)))
return 0;
return 1;
}
@@ -142,11 +160,8 @@
*/
static int ext3_journal_test_restart(handle_t *handle, struct inode *inode)
{
- long needed = inode->i_blocks;
- if (needed > EXT3_MAX_TRANS_DATA)
- needed = EXT3_MAX_TRANS_DATA;
jbd_debug(2, "restarting handle %p\n", handle);
- return ext3_journal_restart(handle, EXT3_DATA_TRANS_BLOCKS + needed);
+ return ext3_journal_restart(handle, blocks_for_truncate(inode));
}
/*
@@ -2053,6 +2068,22 @@
return -EIO;
}
+void ext3_set_inode_flags(struct inode *inode)
+{
+ unsigned int flags = inode->u.ext3_i.i_flags;
+
+ inode->i_flags &= ~(S_SYNC|S_APPEND|S_IMMUTABLE|S_NOATIME);
+ if (flags & EXT3_SYNC_FL)
+ inode->i_flags |= S_SYNC;
+ if (flags & EXT3_APPEND_FL)
+ inode->i_flags |= S_APPEND;
+ if (flags & EXT3_IMMUTABLE_FL)
+ inode->i_flags |= S_IMMUTABLE;
+ if (flags & EXT3_NOATIME_FL)
+ inode->i_flags |= S_NOATIME;
+}
+
+
void ext3_read_inode(struct inode * inode)
{
struct ext3_iloc iloc;
@@ -2150,23 +2181,7 @@
} else
init_special_inode(inode, inode->i_mode,
le32_to_cpu(iloc.raw_inode->i_block[0]));
- /* inode->i_attr_flags = 0; unused */
- if (inode->u.ext3_i.i_flags & EXT3_SYNC_FL) {
- /* inode->i_attr_flags |= ATTR_FLAG_SYNCRONOUS; unused */
- inode->i_flags |= S_SYNC;
- }
- if (inode->u.ext3_i.i_flags & EXT3_APPEND_FL) {
- /* inode->i_attr_flags |= ATTR_FLAG_APPEND; unused */
- inode->i_flags |= S_APPEND;
- }
- if (inode->u.ext3_i.i_flags & EXT3_IMMUTABLE_FL) {
- /* inode->i_attr_flags |= ATTR_FLAG_IMMUTABLE; unused */
- inode->i_flags |= S_IMMUTABLE;
- }
- if (inode->u.ext3_i.i_flags & EXT3_NOATIME_FL) {
- /* inode->i_attr_flags |= ATTR_FLAG_NOATIME; unused */
- inode->i_flags |= S_NOATIME;
- }
+ ext3_set_inode_flags(inode);
return;
bad_inode:
@@ -2270,7 +2285,7 @@
}
}
}
- raw_inode->i_generation = le32_to_cpu(inode->i_generation);
+ raw_inode->i_generation = cpu_to_le32(inode->i_generation);
if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode))
raw_inode->i_block[0] =
cpu_to_le32(kdev_t_to_nr(inode->i_rdev));
@@ -2553,7 +2568,7 @@
handle_t *handle;
lock_kernel();
- handle = ext3_journal_start(inode, 1);
+ handle = ext3_journal_start(inode, 2);
if (IS_ERR(handle))
goto out;
if (current_handle &&
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)