---- ./fs/ext3/balloc.c.orig Fri Apr 12 10:27:49 2002
-+++ ./fs/ext3/balloc.c Tue May 7 15:35:59 2002
+ fs/ext3/balloc.c | 134 +-
+ fs/ext3/dir.c | 2
+ fs/ext3/ialloc.c | 102 -
+ fs/ext3/inode.c | 202 +--
+ fs/ext3/ioctl.c | 13
+ fs/ext3/namei.c | 9
+ fs/ext3/super.c | 22
+ fs/ext3/symlink.c | 8
+ include/linux/ext3_fs.h | 64
+ include/linux/ext3_jbd.h | 2
+ 19 files changed, 5574 insertions(+), 290 deletions(-)
+
+--- linux-2.4.18-chaos/fs/ext3/balloc.c~ext3-2.4.18-ino_sb_macro-2 2003-07-28 17:52:04.000000000 +0400
++++ linux-2.4.18-chaos-alexey/fs/ext3/balloc.c 2003-09-16 23:34:40.000000000 +0400
@@ -46,18 +46,18 @@ struct ext3_group_desc * ext3_get_group_
unsigned long desc;
struct ext3_group_desc * gdp;
if (block < le32_to_cpu(es->s_first_data_block) ||
block + count < block ||
(block + count) > le32_to_cpu(es->s_blocks_count)) {
-@@ -304,7 +302,7 @@ do_more:
+@@ -305,7 +303,7 @@ do_more:
if (bitmap_nr < 0)
goto error_return;
if (err)
goto error_return;
-@@ -341,7 +339,7 @@
+@@ -339,7 +337,7 @@ do_more:
if (block == le32_to_cpu(gdp->bg_block_bitmap) ||
block == le32_to_cpu(gdp->bg_inode_bitmap) ||
in_range(block, le32_to_cpu(gdp->bg_inode_table),
ext3_error(sb, __FUNCTION__,
"Freeing block in system zone - block = %lu",
block);
-@@ -410,8 +407,8 @@ do_more:
+@@ -412,8 +410,8 @@ do_more:
if (!err) err = ret;
/* And the superblock */
if (!err) err = ret;
if (overflow && !err) {
-@@ -564,12 +560,12 @@ int ext3_new_block (handle_t *handle, st
+@@ -566,12 +564,12 @@ int ext3_new_block (handle_t *handle, st
}
lock_super (sb);
!capable(CAP_SYS_RESOURCE)))
goto out;
-@@ -598,7 +595,7 @@ int ext3_new_block (handle_t *handle, st
+@@ -601,7 +599,7 @@ repeat:
if (bitmap_nr < 0)
goto io_error;
ext3_debug ("goal is at %d:%d.\n", i, j);
-@@ -621,9 +618,9 @@ int ext3_new_block (handle_t *handle, st
+@@ -624,9 +622,9 @@ repeat:
* Now search the rest of the groups. We assume that
* i and gdp correctly point to the last group visited.
*/
i = 0;
gdp = ext3_get_group_desc (sb, i, &bh2);
if (!gdp) {
-@@ -635,7 +632,7 @@ int ext3_new_block (handle_t *handle, st
+@@ -638,7 +636,7 @@ repeat:
if (bitmap_nr < 0)
goto io_error;
j = find_next_usable_block(-1, bh,
EXT3_BLOCKS_PER_GROUP(sb));
if (j >= 0)
-@@ -674,8 +671,8 @@ got_block:
+@@ -676,8 +674,8 @@ got_block:
fatal = ext3_journal_get_write_access(handle, bh2);
if (fatal) goto out;
if (fatal) goto out;
tmp = j + i * EXT3_BLOCKS_PER_GROUP(sb)
-@@ -796,7 +804,7 @@ got_block:
+@@ -810,7 +808,7 @@ got_block:
if (!fatal) fatal = err;
BUFFER_TRACE(bh, "journal_dirty_metadata for superblock");
if (!fatal) fatal = err;
sb->s_dirt = 1;
-@@ -829,11 +837,11 @@ unsigned long ext3_count_free_blocks (st
+@@ -848,11 +846,11 @@ unsigned long ext3_count_free_blocks (st
int i;
lock_super (sb);
gdp = ext3_get_group_desc (sb, i, NULL);
if (!gdp)
continue;
-@@ -842,7 +850,7 @@ unsigned long ext3_count_free_blocks (st
+@@ -861,7 +859,7 @@ unsigned long ext3_count_free_blocks (st
if (bitmap_nr < 0)
continue;
sb->s_blocksize);
printk ("group %d: stored = %d, counted = %lu\n",
i, le16_to_cpu(gdp->bg_free_blocks_count), x);
-@@ -853,7 +861,7 @@ unsigned long ext3_count_free_blocks (st
+@@ -872,7 +870,7 @@ unsigned long ext3_count_free_blocks (st
unlock_super (sb);
return bitmap_count;
#else
#endif
}
-@@ -862,7 +870,7 @@ static inline int block_in_use (unsigned
+@@ -881,7 +879,7 @@ static inline int block_in_use (unsigned
unsigned char * map)
{
return ext3_test_bit ((block -
EXT3_BLOCKS_PER_GROUP(sb), map);
}
-@@ -930,11 +938,11 @@ void ext3_check_blocks_bitmap (struct su
+@@ -949,11 +947,11 @@ void ext3_check_blocks_bitmap (struct su
struct ext3_group_desc * gdp;
int i;
gdp = ext3_get_group_desc (sb, i, NULL);
if (!gdp)
continue;
-@@ -968,7 +976,7 @@ void ext3_check_blocks_bitmap (struct su
+@@ -987,7 +985,7 @@ void ext3_check_blocks_bitmap (struct su
"Inode bitmap for group %d is marked free",
i);
if (!block_in_use (le32_to_cpu(gdp->bg_inode_table) + j,
sb, bh->b_data))
ext3_error (sb, "ext3_check_blocks_bitmap",
---- ./fs/ext3/dir.c.orig Fri Apr 12 10:27:49 2002
-+++ ./fs/ext3/dir.c Tue May 7 14:54:13 2002
-@@ -52,7 +52,7 @@ int ext3_check_dir_entry (const char * f
+--- linux-2.4.18-chaos/fs/ext3/dir.c~ext3-2.4.18-ino_sb_macro-2 2003-09-16 23:34:14.000000000 +0400
++++ linux-2.4.18-chaos-alexey/fs/ext3/dir.c 2003-09-16 23:34:40.000000000 +0400
+@@ -67,7 +67,7 @@ int ext3_check_dir_entry (const char * f
else if (((char *) de - bh->b_data) + rlen > dir->i_sb->s_blocksize)
error_msg = "directory entry across blocks";
else if (le32_to_cpu(de->inode) >
error_msg = "inode out of bounds";
if (error_msg != NULL)
---- ./fs/ext3/ialloc.c.orig Fri Apr 12 10:27:49 2002
-+++ ./fs/ext3/ialloc.c Tue May 7 15:39:26 2002
-@@ -73,8 +73,8 @@ static int read_inode_bitmap (struct sup
+--- linux-2.4.18-chaos/fs/ext3/ialloc.c~ext3-2.4.18-ino_sb_macro-2 2003-09-16 23:34:33.000000000 +0400
++++ linux-2.4.18-chaos-alexey/fs/ext3/ialloc.c 2003-09-16 23:34:40.000000000 +0400
+@@ -74,8 +74,8 @@ static int read_inode_bitmap (struct sup
* this group. The IO will be retried next time.
*/
error_out:
return retval;
}
-@@ -225,7 +225,7 @@ void ext3_free_inode (handle_t *handle,
+@@ -227,7 +227,7 @@ void ext3_free_inode (handle_t *handle,
clear_inode (inode);
lock_super (sb);
if (ino < EXT3_FIRST_INO(sb) || ino > le32_to_cpu(es->s_inodes_count)) {
ext3_error (sb, "ext3_free_inode",
"reserved or nonexistent inode %lu", ino);
-@@ -237,7 +237,7 @@ void ext3_free_inode (handle_t *handle,
+@@ -239,7 +239,7 @@ void ext3_free_inode (handle_t *handle,
if (bitmap_nr < 0)
goto error_return;
BUFFER_TRACE(bh, "get_write_access");
fatal = ext3_journal_get_write_access(handle, bh);
-@@ -255,8 +255,8 @@ void ext3_free_inode (handle_t *handle,
+@@ -257,8 +257,8 @@ void ext3_free_inode (handle_t *handle,
fatal = ext3_journal_get_write_access(handle, bh2);
if (fatal) goto error_return;
if (fatal) goto error_return;
if (gdp) {
-@@ -271,9 +271,9 @@ void ext3_free_inode (handle_t *handle,
+@@ -273,9 +273,9 @@ void ext3_free_inode (handle_t *handle,
if (!fatal) fatal = err;
es->s_free_inodes_count =
cpu_to_le32(le32_to_cpu(es->s_free_inodes_count) + 1);
if (!fatal) fatal = err;
}
BUFFER_TRACE(bh, "call ext3_journal_dirty_metadata");
-@@ -305,6 +305,8 @@ struct inode * ext3_new_inode (handle_t
+@@ -307,6 +307,8 @@ struct inode * ext3_new_inode (handle_t
int i, j, avefreei;
struct inode * inode;
int bitmap_nr;
struct ext3_group_desc * gdp;
struct ext3_group_desc * tmp;
struct ext3_super_block * es;
-@@ -318,7 +320,9 @@ struct inode * ext3_new_inode (handle_t
+@@ -320,7 +322,9 @@ struct inode * ext3_new_inode (handle_t
inode = new_inode(sb);
if (!inode)
return ERR_PTR(-ENOMEM);
lock_super (sb);
es = sb->u.ext3_sb.s_es;
-@@ -328,9 +332,9 @@ struct inode * ext3_new_inode (handle_t
+@@ -330,9 +334,9 @@ repeat:
if (S_ISDIR(mode)) {
avefreei = le32_to_cpu(es->s_free_inodes_count) /
struct buffer_head *temp_buffer;
tmp = ext3_get_group_desc (sb, j, &temp_buffer);
if (tmp &&
-@@ -350,7 +354,7 @@ repeat:
+@@ -352,7 +356,7 @@ repeat:
/*
* Try to place the inode in its parent directory
*/
tmp = ext3_get_group_desc (sb, i, &bh2);
if (tmp && le16_to_cpu(tmp->bg_free_inodes_count))
gdp = tmp;
-@@ -360,10 +364,10 @@ repeat:
+@@ -362,10 +366,10 @@ repeat:
* Use a quadratic hash to find a group with a
* free inode
*/
tmp = ext3_get_group_desc (sb, i, &bh2);
if (tmp &&
le16_to_cpu(tmp->bg_free_inodes_count)) {
-@@ -376,9 +380,9 @@ repeat:
+@@ -378,9 +382,9 @@ repeat:
/*
* That failed: try linear search for a free inode
*/
i = 0;
tmp = ext3_get_group_desc (sb, i, &bh2);
if (tmp &&
-@@ -399,11 +403,11 @@ repeat:
+@@ -401,11 +405,11 @@ repeat:
if (bitmap_nr < 0)
goto fail;
BUFFER_TRACE(bh, "get_write_access");
err = ext3_journal_get_write_access(handle, bh);
if (err) goto fail;
-@@ -457,13 +461,13 @@ repeat:
+@@ -459,13 +463,13 @@ repeat:
err = ext3_journal_dirty_metadata(handle, bh2);
if (err) goto fail;
sb->s_dirt = 1;
if (err) goto fail;
-@@ -483,31 +487,31 @@ repeat:
+@@ -485,31 +489,31 @@ repeat:
inode->i_blksize = PAGE_SIZE;
inode->i_blocks = 0;
inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
err = ext3_mark_inode_dirty(handle, inode);
if (err) goto fail;
-@@ -585,19 +589,19 @@ struct inode *ext3_orphan_get (struct su
+@@ -588,19 +592,19 @@ struct inode *ext3_orphan_get(struct sup
unsigned long ext3_count_free_inodes (struct super_block * sb)
{
gdp = ext3_get_group_desc (sb, i, NULL);
if (!gdp)
continue;
-@@ -606,8 +610,8 @@ unsigned long ext3_count_free_inodes (st
+@@ -609,8 +613,8 @@ unsigned long ext3_count_free_inodes (st
if (bitmap_nr < 0)
continue;
printk ("group %d: stored = %d, counted = %lu\n",
i, le16_to_cpu(gdp->bg_free_inodes_count), x);
bitmap_count += x;
-@@ -617,7 +621,7 @@ unsigned long ext3_count_free_inodes (st
+@@ -620,7 +624,7 @@ unsigned long ext3_count_free_inodes (st
unlock_super (sb);
return desc_count;
#else
#endif
}
-@@ -626,16 +630,18 @@ unsigned long ext3_count_free_inodes (st
+@@ -629,16 +633,18 @@ unsigned long ext3_count_free_inodes (st
void ext3_check_inodes_bitmap (struct super_block * sb)
{
struct ext3_super_block * es;
gdp = ext3_get_group_desc (sb, i, NULL);
if (!gdp)
continue;
-@@ -644,7 +650,7 @@ void ext3_check_inodes_bitmap (struct su
+@@ -647,7 +653,7 @@ void ext3_check_inodes_bitmap (struct su
if (bitmap_nr < 0)
continue;
EXT3_INODES_PER_GROUP(sb) / 8);
if (le16_to_cpu(gdp->bg_free_inodes_count) != x)
ext3_error (sb, "ext3_check_inodes_bitmap",
---- ./fs/ext3/inode.c.orig Fri Apr 12 10:27:49 2002
-+++ ./fs/ext3/inode.c Tue May 7 15:41:23 2002
-@@ -196,7 +196,7 @@ void ext3_delete_inode (struct inode * i
+--- linux-2.4.18-chaos/fs/ext3/inode.c~ext3-2.4.18-ino_sb_macro-2 2003-09-16 23:34:16.000000000 +0400
++++ linux-2.4.18-chaos-alexey/fs/ext3/inode.c 2003-09-16 23:34:40.000000000 +0400
+@@ -206,7 +206,7 @@ void ext3_delete_inode (struct inode * i
* (Well, we could do this if we need to, but heck - it works)
*/
ext3_orphan_del(handle, inode);
/*
* One subtle ordering requirement: if anything has gone wrong
-@@ -220,13 +220,14 @@ no_delete:
+@@ -230,13 +230,14 @@ no_delete:
void ext3_discard_prealloc (struct inode * inode)
{
#ifdef EXT3_PREALLOCATE
/* Writer: end */
ext3_free_blocks (inode, block, total);
}
-@@ -243,13 +244,15 @@ static int ext3_alloc_block (handle_t *h
+@@ -253,13 +254,15 @@ static int ext3_alloc_block (handle_t *h
unsigned long result;
#ifdef EXT3_PREALLOCATE
/* Writer: end */
ext3_debug ("preallocation hit (%lu/%lu).\n",
++alloc_hits, ++alloc_attempts);
-@@ -259,8 +262,8 @@ static int ext3_alloc_block (handle_t *h
+@@ -269,8 +272,8 @@ static int ext3_alloc_block (handle_t *h
alloc_hits, ++alloc_attempts);
if (S_ISREG(inode->i_mode))
result = ext3_new_block (inode, goal,
else
result = ext3_new_block (inode, goal, 0, 0, err);
/*
-@@ -394,7 +397,7 @@ static Indirect *ext3_get_branch(struct
+@@ -404,7 +407,7 @@ static Indirect *ext3_get_branch(struct
*err = 0;
/* i_data is not going away, no lock needed */
if (!p->key)
goto no_block;
while (--depth) {
-@@ -437,7 +440,8 @@ no_block:
+@@ -448,7 +451,8 @@ no_block:
static inline unsigned long ext3_find_near(struct inode *inode, Indirect *ind)
{
u32 *p;
/* Try to find previous block */
-@@ -453,9 +456,8 @@ static inline unsigned long ext3_find_ne
+@@ -464,9 +468,8 @@ static inline unsigned long ext3_find_ne
* It is going to be refered from inode itself? OK, just put it into
* the same cylinder group then.
*/
}
/**
-@@ -474,14 +477,15 @@
+@@ -485,14 +488,15 @@ static inline unsigned long ext3_find_ne
static int ext3_find_goal(struct inode *inode, long block, Indirect chain[4],
Indirect *partial, unsigned long *goal)
{
#endif
/* Writer: end */
/* Reader: pointers, ->i_next_alloc* */
-@@ -490,8 +493,8 @@ static int ext3_find_goal(struct inode *
+@@ -501,8 +505,8 @@ static int ext3_find_goal(struct inode *
* try the heuristic for sequential allocation,
* failing that at least try to get decent locality.
*/
if (!*goal)
*goal = ext3_find_near(inode, partial);
#ifdef SEARCH_FROM_ZERO
-@@ -619,6 +621,7 @@
+@@ -628,6 +632,7 @@ static int ext3_splice_branch(handle_t *
{
int i;
int err = 0;
/*
* If we're splicing into a [td]indirect block (as opposed to the
-@@ -641,11 +644,11 @@ static int ext3_splice_branch(handle_t *
+@@ -650,11 +655,11 @@ static int ext3_splice_branch(handle_t *
/* That's it */
*where->p = where->key;
#endif
/* Writer: end */
-@@ -729,6 +732,7 @@
+@@ -738,6 +743,7 @@ static int ext3_get_block_handle(handle_
unsigned long goal;
int left;
int depth = ext3_block_to_path(inode, iblock, offsets);
loff_t new_size;
J_ASSERT(handle != NULL || create == 0);
-@@ -782,7 +785,7 @@ out:
+@@ -791,7 +797,7 @@ out:
/*
* Block out ext3_truncate while we alter the tree
*/
err = ext3_alloc_branch(handle, inode, left, goal,
offsets+(partial-chain), partial);
-@@ -794,7 +797,7 @@ out:
+@@ -803,7 +809,7 @@ out:
if (!err)
err = ext3_splice_branch(handle, inode, iblock, chain,
partial, left);
if (err == -EAGAIN)
goto changed;
if (err)
-@@ -807,8 +810,8 @@ out:
+@@ -816,8 +822,8 @@ out:
* truncate is in progress. It is racy between multiple parallel
* instances of get_block, but we have the BKL.
*/
bh_result->b_state |= (1UL << BH_New);
goto got_it;
-@@ -921,7 +924,7 @@ struct buffer_head *ext3_bread(handle_t
+@@ -932,7 +938,7 @@ struct buffer_head *ext3_bread(handle_t
struct buffer_head *tmp_bh;
for (i = 1;
i < EXT3_SB(inode->i_sb)->s_es->s_prealloc_dir_blocks;
i++) {
/*
-@@ -1131,8 +1134,8 @@ static int ext3_commit_write(struct file
+@@ -1152,8 +1158,8 @@ static int ext3_commit_write(struct file
kunmap(page);
}
}
ret2 = ext3_mark_inode_dirty(handle, inode);
if (!ret)
ret = ret2;
-@@ -1832,7 +1835,8 @@ static void ext3_free_branches(handle_t
+@@ -1873,7 +1879,8 @@ static void ext3_free_branches(handle_t
void ext3_truncate(struct inode * inode)
{
handle_t *handle;
int addr_per_block = EXT3_ADDR_PER_BLOCK(inode->i_sb);
int offsets[4];
Indirect chain[4];
-@@ -1884,13 +1887,13 @@ void ext3_truncate(struct inode * inode)
+@@ -1934,13 +1941,13 @@ void ext3_truncate(struct inode * inode)
* on-disk inode. We do this via i_disksize, which is the value which
* ext3 *really* writes onto the disk inode.
*/
if (n == 1) { /* direct blocks */
ext3_free_data(handle, inode, NULL, i_data+offsets[0],
-@@ -1954,7 +1957,7 @@ do_indirects:
+@@ -2004,7 +2011,7 @@ do_indirects:
case EXT3_TIND_BLOCK:
;
}
inode->i_mtime = inode->i_ctime = CURRENT_TIME;
ext3_mark_inode_dirty(handle, inode);
-@@ -1983,6 +1986,8 @@ out_stop:
+@@ -2041,6 +2048,8 @@ out_unlock:
int ext3_get_inode_loc (struct inode *inode, struct ext3_iloc *iloc)
{
struct buffer_head *bh = 0;
unsigned long block;
unsigned long block_group;
-@@ -1997,23 +2010,19 @@ int ext3_get_inode_loc (struct inode *in
+@@ -2051,25 +2060,21 @@ int ext3_get_inode_loc (struct inode *in
+
+ if ((inode->i_ino != EXT3_ROOT_INO &&
inode->i_ino != EXT3_JOURNAL_INO &&
- inode->i_ino < EXT3_FIRST_INO(inode->i_sb)) ||
- inode->i_ino > le32_to_cpu(
goto bad_inode;
}
-@@ -2021,17 +2022,17 @@ int ext3_get_inode_loc (struct inode *in
+@@ -2077,17 +2082,17 @@ int ext3_get_inode_loc (struct inode *in
/*
* Figure out the offset within the block group inode table
*/
iloc->bh = bh;
iloc->raw_inode = (struct ext3_inode *) (bh->b_data + offset);
-@@ -2047,6 +2048,7 @@ void ext3_read_inode(struct inode * inod
+@@ -2103,6 +2108,7 @@ void ext3_read_inode(struct inode * inod
{
struct ext3_iloc iloc;
struct ext3_inode *raw_inode;
struct buffer_head *bh;
int block;
-@@ -2054,7 +2056,7 @@ void ext3_read_inode(struct inode * inod
+@@ -2110,7 +2116,7 @@ void ext3_read_inode(struct inode * inod
goto bad_inode;
bh = iloc.bh;
raw_inode = iloc.raw_inode;
inode->i_mode = le16_to_cpu(raw_inode->i_mode);
inode->i_uid = (uid_t)le16_to_cpu(raw_inode->i_uid_low);
inode->i_gid = (gid_t)le16_to_cpu(raw_inode->i_gid_low);
-@@ -2067,7 +2069,7 @@ void ext3_read_inode(struct inode * inod
+@@ -2123,7 +2129,7 @@ void ext3_read_inode(struct inode * inod
inode->i_atime = le32_to_cpu(raw_inode->i_atime);
inode->i_ctime = le32_to_cpu(raw_inode->i_ctime);
inode->i_mtime = le32_to_cpu(raw_inode->i_mtime);
/* We now have enough fields to check if the inode was active or not.
* This is needed because nfsd might try to access dead inodes
* the test is that same one that e2fsck uses
-@@ -2075,7 +2077,7 @@ void ext3_read_inode(struct inode * inod
+@@ -2131,7 +2137,7 @@ void ext3_read_inode(struct inode * inod
*/
if (inode->i_nlink == 0) {
if (inode->i_mode == 0 ||
/* this inode is deleted */
brelse (bh);
goto bad_inode;
-@@ -2090,33 +2092,33 @@ void ext3_read_inode(struct inode * inod
+@@ -2146,33 +2152,33 @@ void ext3_read_inode(struct inode * inod
* size */
inode->i_blocks = le32_to_cpu(raw_inode->i_blocks);
inode->i_version = ++event;
brelse (iloc.bh);
-@@ -2143,17 +2145,17 @@ void ext3_read_inode(struct inode * inod
+@@ -2194,19 +2200,19 @@ void ext3_read_inode(struct inode * inod
+ 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) {
+ if (ei->i_flags & EXT3_SYNC_FL) {
/* inode->i_attr_flags |= ATTR_FLAG_NOATIME; unused */
inode->i_flags |= S_NOATIME;
}
-@@ -2175,6 +2177,7 @@ static int ext3_do_update_inode(handle_t
+@@ -2228,6 +2234,7 @@ static int ext3_do_update_inode(handle_t
struct ext3_iloc *iloc)
{
struct ext3_inode *raw_inode = iloc->raw_inode;
struct buffer_head *bh = iloc->bh;
int err = 0, rc, block;
-@@ -2192,7 +2195,7 @@ static int ext3_do_update_inode(handle_t
+@@ -2245,7 +2252,7 @@ static int ext3_do_update_inode(handle_t
* Fix up interoperability with old kernels. Otherwise, old inodes get
* re-used with the upper 16 bits of the uid/gid intact
*/
raw_inode->i_uid_high =
cpu_to_le16(high_16_bits(inode->i_uid));
raw_inode->i_gid_high =
-@@ -2210,34 +2213,33 @@ static int ext3_do_update_inode(handle_t
+@@ -2263,34 +2270,33 @@ static int ext3_do_update_inode(handle_t
raw_inode->i_gid_high = 0;
}
raw_inode->i_links_count = cpu_to_le16(inode->i_nlink);
struct super_block *sb = inode->i_sb;
if (!EXT3_HAS_RO_COMPAT_FEATURE(sb,
EXT3_FEATURE_RO_COMPAT_LARGE_FILE) ||
-@@ -2247,7 +2249,7 @@ static int ext3_do_update_inode(handle_t
+@@ -2300,7 +2306,7 @@ static int ext3_do_update_inode(handle_t
* created, add a flag to the superblock.
*/
err = ext3_journal_get_write_access(handle,
if (err)
goto out_brelse;
ext3_update_dynamic_rev(sb);
-@@ -2256,7 +2258,7 @@ static int ext3_do_update_inode(handle_t
+@@ -2309,7 +2315,7 @@ static int ext3_do_update_inode(handle_t
sb->s_dirt = 1;
handle->h_sync = 1;
err = ext3_journal_dirty_metadata(handle,
}
}
}
-@@ -2265,13 +2267,13 @@ static int ext3_do_update_inode(handle_t
+@@ -2318,13 +2324,13 @@ static int ext3_do_update_inode(handle_t
raw_inode->i_block[0] =
cpu_to_le32(kdev_t_to_nr(inode->i_rdev));
else for (block = 0; block < EXT3_N_BLOCKS; block++)
out_brelse:
brelse (bh);
-@@ -2379,7 +2381,7 @@ int ext3_setattr(struct dentry *dentry,
+@@ -2432,7 +2438,7 @@ int ext3_setattr(struct dentry *dentry,
}
error = ext3_orphan_add(handle, inode);
rc = ext3_mark_inode_dirty(handle, inode);
if (!error)
error = rc;
-@@ -2622,9 +2624,9 @@ int ext3_change_inode_journal_flag(struc
+@@ -2675,9 +2681,9 @@ int ext3_change_inode_journal_flag(struc
*/
if (val)
journal_unlock_updates(journal);
---- ./fs/ext3/ioctl.c.orig Fri Apr 12 10:27:49 2002
-+++ ./fs/ext3/ioctl.c Tue May 7 15:20:52 2002
+--- linux-2.4.18-chaos/fs/ext3/ioctl.c~ext3-2.4.18-ino_sb_macro-2 2001-11-10 01:25:04.000000000 +0300
++++ linux-2.4.18-chaos-alexey/fs/ext3/ioctl.c 2003-09-16 23:34:40.000000000 +0400
@@ -18,13 +18,14 @@
int ext3_ioctl (struct inode * inode, struct file * filp, unsigned int cmd,
unsigned long arg)
return put_user(flags, (int *) arg);
case EXT3_IOC_SETFLAGS: {
handle_t *handle = NULL;
-@@ -42,7 +42,7 @@ int ext3_ioctl (struct inode * inode, st
+@@ -42,7 +43,7 @@ int ext3_ioctl (struct inode * inode, st
if (get_user(flags, (int *) arg))
return -EFAULT;
/* The JOURNAL_DATA flag is modifiable only by root */
jflag = flags & EXT3_JOURNAL_DATA_FL;
-@@ -79,7 +79,7 @@ int ext3_ioctl (struct inode * inode, st
+@@ -79,7 +80,7 @@ int ext3_ioctl (struct inode * inode, st
flags = flags & EXT3_FL_USER_MODIFIABLE;
flags |= oldflags & ~EXT3_FL_USER_MODIFIABLE;
if (flags & EXT3_SYNC_FL)
inode->i_flags |= S_SYNC;
-@@ -155,12 +155,12 @@ flags_err:
+@@ -155,12 +156,12 @@ flags_err:
int ret = 0;
set_current_state(TASK_INTERRUPTIBLE);
return ret;
}
#endif
---- ./fs/ext3/namei.c.orig Fri Apr 12 10:27:49 2002
-+++ ./fs/ext3/namei.c Tue May 7 16:05:51 2002
-@@ -1430,8 +1430,8 @@ int ext3_orphan_add(handle_t *handle, st
+--- linux-2.4.18-chaos/fs/ext3/namei.c~ext3-2.4.18-ino_sb_macro-2 2003-09-16 23:34:33.000000000 +0400
++++ linux-2.4.18-chaos-alexey/fs/ext3/namei.c 2003-09-16 23:34:40.000000000 +0400
+@@ -1764,8 +1764,8 @@ int ext3_orphan_add(handle_t *handle, st
J_ASSERT ((S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) ||
S_ISLNK(inode->i_mode)) || inode->i_nlink == 0);
if (err)
goto out_unlock;
-@@ -1442,7 +1442,7 @@ int ext3_orphan_add(handle_t *handle, st
+@@ -1776,7 +1776,7 @@ int ext3_orphan_add(handle_t *handle, st
/* Insert this inode at the head of the on-disk orphan list... */
NEXT_ORPHAN(inode) = le32_to_cpu(EXT3_SB(sb)->s_es->s_last_orphan);
EXT3_SB(sb)->s_es->s_last_orphan = cpu_to_le32(inode->i_ino);
rc = ext3_mark_iloc_dirty(handle, inode, &iloc);
if (!err)
err = rc;
-@@ -1520,8 +1520,7 @@ int ext3_orphan_del(handle_t *handle, st
+@@ -1850,8 +1850,7 @@ int ext3_orphan_del(handle_t *handle, st
err = ext3_journal_dirty_metadata(handle, sbi->s_sbh);
} else {
struct ext3_iloc iloc2;
jbd_debug(4, "orphan inode %lu will point to %lu\n",
i_prev->i_ino, ino_next);
---- ./fs/ext3/super.c.orig Fri Apr 12 10:27:49 2002
-+++ ./fs/ext3/super.c Tue May 7 16:05:44 2002
-@@ -121,7 +121,7 @@ static int ext3_error_behaviour(struct s
+--- linux-2.4.18-chaos/fs/ext3/super.c~ext3-2.4.18-ino_sb_macro-2 2003-09-16 23:34:16.000000000 +0400
++++ linux-2.4.18-chaos-alexey/fs/ext3/super.c 2003-09-16 23:34:40.000000000 +0400
+@@ -124,7 +124,7 @@ static int ext3_error_behaviour(struct s
/* If no overrides were specified on the mount, then fall back
* to the default behaviour set in the filesystem's superblock
* on disk. */
case EXT3_ERRORS_PANIC:
return EXT3_ERRORS_PANIC;
case EXT3_ERRORS_RO:
-@@ -269,9 +269,9 @@ void ext3_abort (struct super_block * sb
+@@ -272,9 +272,9 @@ void ext3_abort (struct super_block * sb
return;
printk (KERN_CRIT "Remounting filesystem read-only\n");
journal_abort(EXT3_SB(sb)->s_journal, -EIO);
}
-@@ -377,8 +377,6 @@ static int ext3_blkdev_remove(struct ext3
+@@ -380,8 +380,6 @@ static int ext3_blkdev_remove(struct ext
return ret;
}
static void dump_orphan_list(struct super_block *sb, struct ext3_sb_info *sbi)
{
struct list_head *l;
-@@ -818,7 +818,7 @@ static void ext3_orphan_cleanup (struct
+@@ -825,7 +823,7 @@ static void ext3_orphan_cleanup (struct
sb->s_flags &= ~MS_RDONLY;
}
if (es->s_last_orphan)
jbd_debug(1, "Errors on filesystem, "
"clearing orphan list.\n");
-@@ -1463,12 +1463,14 @@ static void ext3_commit_super (struct su
+@@ -1474,12 +1472,14 @@ static void ext3_commit_super (struct su
struct ext3_super_block * es,
int sync)
{
}
}
-@@ -1519,7 +1521,7 @@ static void ext3_clear_journal_err(struc
+@@ -1530,7 +1530,7 @@ static void ext3_clear_journal_err(struc
ext3_warning(sb, __FUNCTION__, "Marking fs in need of "
"filesystem check.");
es->s_state |= cpu_to_le16(EXT3_ERROR_FS);
ext3_commit_super (sb, es, 1);
---- ./fs/ext3/symlink.c.orig Fri Apr 12 10:27:49 2002
-+++ ./fs/ext3/symlink.c Tue May 7 15:25:39 2002
-@@ -23,13 +23,13 @@
+--- linux-2.4.18-chaos/fs/ext3/symlink.c~ext3-2.4.18-ino_sb_macro-2 2001-11-10 01:25:04.000000000 +0300
++++ linux-2.4.18-chaos-alexey/fs/ext3/symlink.c 2003-09-16 23:34:40.000000000 +0400
+@@ -23,14 +23,14 @@
static int ext3_readlink(struct dentry *dentry, char *buffer, int buflen)
{
+ return vfs_follow_link(nd, (char*)ei->i_data);
}
---- ./include/linux/ext3_fs.h.orig Tue Apr 16 14:27:25 2002
-+++ ./include/linux/ext3_fs.h Tue May 7 16:47:36 2002
-@@ -84,22 +84,25 @@
+ struct inode_operations ext3_fast_symlink_inode_operations = {
+--- linux-2.4.18-chaos/include/linux/ext3_fs.h~ext3-2.4.18-ino_sb_macro-2 2003-09-16 23:34:33.000000000 +0400
++++ linux-2.4.18-chaos-alexey/include/linux/ext3_fs.h 2003-09-16 23:34:40.000000000 +0400
+@@ -87,22 +87,25 @@
#define EXT3_MIN_BLOCK_SIZE 1024
#define EXT3_MAX_BLOCK_SIZE 4096
#define EXT3_MIN_BLOCK_LOG_SIZE 10
#define EXT3_INODE_SIZE(s) (((s)->s_rev_level == EXT3_GOOD_OLD_REV) ? \
EXT3_GOOD_OLD_INODE_SIZE : \
(s)->s_inode_size)
-@@ -108,6 +110,7 @@
+@@ -110,6 +113,7 @@
EXT3_GOOD_OLD_FIRST_INO : \
(s)->s_first_ino)
#endif
/*
* Macro-instructions used to manage fragments
-@@ -116,8 +120,8 @@
+@@ -118,8 +122,8 @@
#define EXT3_MAX_FRAG_SIZE 4096
#define EXT3_MIN_FRAG_LOG_SIZE 10
#ifdef __KERNEL__
#else
# define EXT3_FRAG_SIZE(s) (EXT3_MIN_FRAG_SIZE << (s)->s_log_frag_size)
# define EXT3_FRAGS_PER_BLOCK(s) (EXT3_BLOCK_SIZE(s) / EXT3_FRAG_SIZE(s))
-@@ -163,15 +167,13 @@
+@@ -143,15 +147,13 @@ struct ext3_group_desc
/*
* Macro-instructions used to manage group descriptors
*/
#endif
/*
-@@ -344,7 +347,7 @@
+@@ -325,7 +327,7 @@ struct ext3_inode {
#ifndef _LINUX_EXT2_FS_H
#define clear_opt(o, opt) o &= ~EXT3_MOUNT_##opt
#define set_opt(o, opt) o |= EXT3_MOUNT_##opt
EXT3_MOUNT_##opt)
#else
#define EXT2_MOUNT_NOLOAD EXT3_MOUNT_NOLOAD
-@@ -441,17 +443,11 @@
- /*EC*/ __u32 s_reserved[197]; /* Padding to the end of the block */
+@@ -425,17 +427,11 @@ struct ext3_super_block {
+ __u32 s_reserved[192]; /* Padding to the end of the block */
};
-#ifdef __KERNEL__
/*
* Codes for operating systems
---- ./include/linux/ext3_jbd.h.orig Tue May 7 14:44:08 2002
-+++ ./include/linux/ext3_jbd.h Tue May 7 14:44:43 2002
-@@ -291,7 +291,7 @@
+--- linux-2.4.18-chaos/include/linux/ext3_jbd.h~ext3-2.4.18-ino_sb_macro-2 2003-09-16 23:34:16.000000000 +0400
++++ linux-2.4.18-chaos-alexey/include/linux/ext3_jbd.h 2003-09-16 23:34:40.000000000 +0400
+@@ -297,7 +297,7 @@ static inline int ext3_should_journal_da
return 1;
if (test_opt(inode->i_sb, DATA_FLAGS) == EXT3_MOUNT_JOURNAL_DATA)
return 1;
-
-Create a service thread to handle delete and truncate of inodes, to avoid
-long latency while truncating very large files.
-
-
- fs/ext3/inode.c | 116 ++++++++++++++++++++++
+ fs/ext3/file.c | 4
+ fs/ext3/inode.c | 112 +++++++++++++++++++++
fs/ext3/super.c | 231 +++++++++++++++++++++++++++++++++++++++++++++
include/linux/ext3_fs.h | 5
include/linux/ext3_fs_sb.h | 10 +
- 4 files changed, 362 insertions(+)
+ 5 files changed, 362 insertions(+)
---- linux-2.4.18-18.8.0-l15/fs/ext3/super.c~ext3-delete_thread-2.4.18 Tue Jun 3 17:26:21 2003
-+++ linux-2.4.18-18.8.0-l15-adilger/fs/ext3/super.c Wed Jul 2 23:49:40 2003
-@@ -396,6 +396,220 @@ static void dump_orphan_list(struct supe
+--- linux-2.4.18-chaos/fs/ext3/file.c~ext3-delete_thread-2.4.18-2 2003-09-16 23:34:07.000000000 +0400
++++ linux-2.4.18-chaos-alexey/fs/ext3/file.c 2003-09-16 23:42:34.000000000 +0400
+@@ -124,7 +124,11 @@ struct file_operations ext3_file_operati
+ };
+
+ struct inode_operations ext3_file_inode_operations = {
++#ifdef EXT3_DELETE_THREAD
++ truncate: ext3_truncate_thread, /* BKL held */
++#else
+ truncate: ext3_truncate, /* BKL held */
++#endif
+ setattr: ext3_setattr, /* BKL held */
+ };
+
+--- linux-2.4.18-chaos/fs/ext3/inode.c~ext3-delete_thread-2.4.18-2 2003-09-16 23:39:37.000000000 +0400
++++ linux-2.4.18-chaos-alexey/fs/ext3/inode.c 2003-09-16 23:42:34.000000000 +0400
+@@ -2041,6 +2041,118 @@ out_unlock:
+ return; /* AKPM: return what? */
+ }
+
++#ifdef EXT3_DELETE_THREAD
++/* Move blocks from to-be-truncated inode over to a new inode, and delete
++ * that one from the delete thread instead. This avoids a lot of latency
++ * when truncating large files.
++ *
++ * If we have any problem deferring the truncate, just truncate it right away.
++ * If we defer it, we also mark how many blocks it would free, so that we
++ * can keep the statfs data correct, and we know if we should sleep on the
++ * delete thread when we run out of space.
++ */
++void ext3_truncate_thread(struct inode *old_inode)
++{
++ struct ext3_sb_info *sbi = EXT3_SB(old_inode->i_sb);
++ struct ext3_inode_info *nei, *oei = EXT3_I(old_inode);
++ struct inode *new_inode;
++ handle_t *handle;
++ unsigned long blocks = old_inode->i_blocks >> (old_inode->i_blkbits-9);
++
++ if (!test_opt(old_inode->i_sb, ASYNCDEL) || !sbi->s_delete_list.next)
++ goto out_truncate;
++
++ /* XXX This is a temporary limitation for code simplicity.
++ * We could truncate to arbitrary sizes at some later time.
++ */
++ if (old_inode->i_size != 0)
++ goto out_truncate;
++
++ /* We may want to truncate the inode immediately and not defer it */
++ if (IS_SYNC(old_inode) || blocks <= EXT3_NDIR_BLOCKS ||
++ old_inode->i_size > oei->i_disksize)
++ goto out_truncate;
++
++ /* We can't use the delete thread as-is during real orphan recovery,
++ * as we add to the orphan list here, causing ext3_orphan_cleanup()
++ * to loop endlessly. It would be nice to do so, but needs work.
++ */
++ if (oei->i_state & EXT3_STATE_DELETE ||
++ sbi->s_mount_state & EXT3_ORPHAN_FS) {
++ ext3_debug("doing deferred inode %lu delete (%lu blocks)\n",
++ old_inode->i_ino, blocks);
++ goto out_truncate;
++ }
++
++ ext3_discard_prealloc(old_inode);
++
++ /* old_inode = 1
++ * new_inode = sb + GDT + ibitmap
++ * orphan list = 1 inode/superblock for add, 2 inodes for del
++ * quota files = 2 * EXT3_SINGLEDATA_TRANS_BLOCKS
++ */
++ handle = ext3_journal_start(old_inode, 7);
++ if (IS_ERR(handle))
++ goto out_truncate;
++
++ new_inode = ext3_new_inode(handle, old_inode, old_inode->i_mode);
++ if (IS_ERR(new_inode)) {
++ ext3_debug("truncate inode %lu directly (no new inodes)\n",
++ old_inode->i_ino);
++ goto out_journal;
++ }
++
++ nei = EXT3_I(new_inode);
++
++ down_write(&oei->truncate_sem);
++ new_inode->i_size = old_inode->i_size;
++ new_inode->i_blocks = old_inode->i_blocks;
++ new_inode->i_uid = old_inode->i_uid;
++ new_inode->i_gid = old_inode->i_gid;
++ new_inode->i_nlink = 0;
++
++ /* FIXME when we do arbitrary truncates */
++ old_inode->i_blocks = oei->i_file_acl ? old_inode->i_blksize / 512 : 0;
++ old_inode->i_mtime = old_inode->i_ctime = CURRENT_TIME;
++
++ memcpy(nei->i_data, oei->i_data, sizeof(nei->i_data));
++ memset(oei->i_data, 0, sizeof(oei->i_data));
++
++ nei->i_disksize = oei->i_disksize;
++ nei->i_state |= EXT3_STATE_DELETE;
++ up_write(&oei->truncate_sem);
++
++ if (ext3_orphan_add(handle, new_inode) < 0)
++ goto out_journal;
++
++ if (ext3_orphan_del(handle, old_inode) < 0) {
++ ext3_orphan_del(handle, new_inode);
++ iput(new_inode);
++ goto out_journal;
++ }
++
++ ext3_journal_stop(handle, old_inode);
++
++ spin_lock(&sbi->s_delete_lock);
++ J_ASSERT(list_empty(&new_inode->i_dentry));
++ list_add_tail(&new_inode->i_dentry, &sbi->s_delete_list);
++ sbi->s_delete_blocks += blocks;
++ sbi->s_delete_inodes++;
++ spin_unlock(&sbi->s_delete_lock);
++
++ ext3_debug("delete inode %lu (%lu blocks) by thread\n",
++ new_inode->i_ino, blocks);
++
++ wake_up(&sbi->s_delete_thread_queue);
++ return;
++
++out_journal:
++ ext3_journal_stop(handle, old_inode);
++out_truncate:
++ ext3_truncate(old_inode);
++}
++#endif /* EXT3_DELETE_THREAD */
++
+ /*
+ * ext3_get_inode_loc returns with an extra refcount against the
+ * inode's underlying buffer_head on success.
+--- linux-2.4.18-chaos/fs/ext3/super.c~ext3-delete_thread-2.4.18-2 2003-09-16 23:42:33.000000000 +0400
++++ linux-2.4.18-chaos-alexey/fs/ext3/super.c 2003-09-16 23:42:34.000000000 +0400
+@@ -398,6 +398,220 @@ static void dump_orphan_list(struct supe
}
}
void ext3_put_super (struct super_block * sb)
{
struct ext3_sb_info *sbi = EXT3_SB(sb);
-@@ -403,6 +617,7 @@ void ext3_put_super (struct super_block
+@@ -405,6 +619,7 @@ void ext3_put_super (struct super_block
kdev_t j_dev = sbi->s_journal->j_dev;
int i;
ext3_xattr_put_super(sb);
journal_destroy(sbi->s_journal);
if (!(sb->s_flags & MS_RDONLY)) {
-@@ -451,7 +666,11 @@ static struct super_operations ext3_sops
+@@ -453,7 +668,11 @@ static struct super_operations ext3_sops
write_inode: ext3_write_inode, /* BKL not held. Don't need */
dirty_inode: ext3_dirty_inode, /* BKL not held. We take it */
put_inode: ext3_put_inode, /* BKL not held. Don't need */
+#endif
put_super: ext3_put_super, /* BKL held */
write_super: ext3_write_super, /* BKL held */
- write_super_lockfs: ext3_write_super_lockfs, /* BKL not held. Take it */
-@@ -511,6 +730,14 @@ static int parse_options (char * options
+ sync_fs: ext3_sync_fs,
+@@ -514,6 +733,14 @@ static int parse_options (char * options
this_char = strtok (NULL, ",")) {
if ((value = strchr (this_char, '=')) != NULL)
*value++ = 0;
if (!strcmp (this_char, "bsddf"))
clear_opt (*mount_options, MINIX_DF);
else if (!strcmp (this_char, "nouid32")) {
-@@ -1206,6 +1433,7 @@ struct super_block * ext3_read_super (st
+@@ -1203,6 +1430,7 @@ struct super_block * ext3_read_super (st
}
ext3_setup_super (sb, es, sb->s_flags & MS_RDONLY);
/*
* akpm: core read_super() calls in here with the superblock locked.
* That deadlocks, because orphan cleanup needs to lock the superblock
-@@ -1648,6 +1876,9 @@ int ext3_remount (struct super_block * s
+@@ -1643,6 +1871,9 @@ int ext3_remount (struct super_block * s
if (!parse_options(data, &tmp, sbi, &tmp, 1))
return -EINVAL;
if (sbi->s_mount_opt & EXT3_MOUNT_ABORT)
ext3_abort(sb, __FUNCTION__, "Abort forced by user");
---- linux/fs/ext3/file.c.orig Fri Jan 17 10:57:31 2003
-+++ linux/fs/ext3/file.c Mon Jun 30 13:28:52 2003
-@@ -121,7 +121,11 @@ struct file_operations ext3_file_operati
- };
-
- struct inode_operations ext3_file_inode_operations = {
-+#ifdef EXT3_DELETE_THREAD
-+ truncate: ext3_truncate_thread, /* BKL held */
-+#else
- truncate: ext3_truncate, /* BKL held */
-+#endif
- setattr: ext3_setattr, /* BKL held */
- };
-
---- linux-2.4.18-18.8.0-l15/fs/ext3/inode.c~ext3-delete_thread-2.4.18 Wed Jul 2 23:13:58 2003
-+++ linux-2.4.18-18.8.0-l15-adilger/fs/ext3/inode.c Wed Jul 2 23:50:29 2003
-@@ -2004,6 +2004,118 @@ out_stop:
- ext3_journal_stop(handle, inode);
- }
-
-+#ifdef EXT3_DELETE_THREAD
-+/* Move blocks from to-be-truncated inode over to a new inode, and delete
-+ * that one from the delete thread instead. This avoids a lot of latency
-+ * when truncating large files.
-+ *
-+ * If we have any problem deferring the truncate, just truncate it right away.
-+ * If we defer it, we also mark how many blocks it would free, so that we
-+ * can keep the statfs data correct, and we know if we should sleep on the
-+ * delete thread when we run out of space.
-+ */
-+void ext3_truncate_thread(struct inode *old_inode)
-+{
-+ struct ext3_sb_info *sbi = EXT3_SB(old_inode->i_sb);
-+ struct ext3_inode_info *nei, *oei = EXT3_I(old_inode);
-+ struct inode *new_inode;
-+ handle_t *handle;
-+ unsigned long blocks = old_inode->i_blocks >> (old_inode->i_blkbits-9);
-+
-+ if (!test_opt(old_inode->i_sb, ASYNCDEL) || !sbi->s_delete_list.next)
-+ goto out_truncate;
-+
-+ /* XXX This is a temporary limitation for code simplicity.
-+ * We could truncate to arbitrary sizes at some later time.
-+ */
-+ if (old_inode->i_size != 0)
-+ goto out_truncate;
-+
-+ /* We may want to truncate the inode immediately and not defer it */
-+ if (IS_SYNC(old_inode) || blocks <= EXT3_NDIR_BLOCKS ||
-+ old_inode->i_size > oei->i_disksize)
-+ goto out_truncate;
-+
-+ /* We can't use the delete thread as-is during real orphan recovery,
-+ * as we add to the orphan list here, causing ext3_orphan_cleanup()
-+ * to loop endlessly. It would be nice to do so, but needs work.
-+ */
-+ if (oei->i_state & EXT3_STATE_DELETE ||
-+ sbi->s_mount_state & EXT3_ORPHAN_FS) {
-+ ext3_debug("doing deferred inode %lu delete (%lu blocks)\n",
-+ old_inode->i_ino, blocks);
-+ goto out_truncate;
-+ }
-+
-+ ext3_discard_prealloc(old_inode);
-+
-+ /* old_inode = 1
-+ * new_inode = sb + GDT + ibitmap
-+ * orphan list = 1 inode/superblock for add, 2 inodes for del
-+ * quota files = 2 * EXT3_SINGLEDATA_TRANS_BLOCKS
-+ */
-+ handle = ext3_journal_start(old_inode, 7);
-+ if (IS_ERR(handle))
-+ goto out_truncate;
-+
-+ new_inode = ext3_new_inode(handle, old_inode, old_inode->i_mode);
-+ if (IS_ERR(new_inode)) {
-+ ext3_debug("truncate inode %lu directly (no new inodes)\n",
-+ old_inode->i_ino);
-+ goto out_journal;
-+ }
-+
-+ nei = EXT3_I(new_inode);
-+
-+ down_write(&oei->truncate_sem);
-+ new_inode->i_size = old_inode->i_size;
-+ new_inode->i_blocks = old_inode->i_blocks;
-+ new_inode->i_uid = old_inode->i_uid;
-+ new_inode->i_gid = old_inode->i_gid;
-+ new_inode->i_nlink = 0;
-+
-+ /* FIXME when we do arbitrary truncates */
-+ old_inode->i_blocks = oei->i_file_acl ? old_inode->i_blksize / 512 : 0;
-+ old_inode->i_mtime = old_inode->i_ctime = CURRENT_TIME;
-+
-+ memcpy(nei->i_data, oei->i_data, sizeof(nei->i_data));
-+ memset(oei->i_data, 0, sizeof(oei->i_data));
-+
-+ nei->i_disksize = oei->i_disksize;
-+ nei->i_state |= EXT3_STATE_DELETE;
-+ up_write(&oei->truncate_sem);
-+
-+ if (ext3_orphan_add(handle, new_inode) < 0)
-+ goto out_journal;
-+
-+ if (ext3_orphan_del(handle, old_inode) < 0) {
-+ ext3_orphan_del(handle, new_inode);
-+ iput(new_inode);
-+ goto out_journal;
-+ }
-+
-+ ext3_journal_stop(handle, old_inode);
-+
-+ spin_lock(&sbi->s_delete_lock);
-+ J_ASSERT(list_empty(&new_inode->i_dentry));
-+ list_add_tail(&new_inode->i_dentry, &sbi->s_delete_list);
-+ sbi->s_delete_blocks += blocks;
-+ sbi->s_delete_inodes++;
-+ spin_unlock(&sbi->s_delete_lock);
-+
-+ ext3_debug("delete inode %lu (%lu blocks) by thread\n",
-+ new_inode->i_ino, blocks);
-+
-+ wake_up(&sbi->s_delete_thread_queue);
-+ return;
-+
-+out_journal:
-+ ext3_journal_stop(handle, old_inode);
-+out_truncate:
-+ ext3_truncate(old_inode);
-+}
-+#endif /* EXT3_DELETE_THREAD */
-+
- /*
- * ext3_get_inode_loc returns with an extra refcount against the
- * inode's underlying buffer_head on success.
---- linux-2.4.18-18.8.0-l15/include/linux/ext3_fs.h~ext3-delete_thread-2.4.18 Tue Jun 3 17:26:20 2003
-+++ linux-2.4.18-18.8.0-l15-adilger/include/linux/ext3_fs.h Wed Jul 2 23:19:09 2003
-@@ -190,6 +190,7 @@ struct ext3_group_desc
+--- linux-2.4.18-chaos/include/linux/ext3_fs.h~ext3-delete_thread-2.4.18-2 2003-09-16 23:39:37.000000000 +0400
++++ linux-2.4.18-chaos-alexey/include/linux/ext3_fs.h 2003-09-16 23:42:34.000000000 +0400
+@@ -195,6 +195,7 @@ struct ext3_group_desc
*/
#define EXT3_STATE_JDATA 0x00000001 /* journaled data exists */
#define EXT3_STATE_NEW 0x00000002 /* inode is newly created */
/*
* ioctl commands
-@@ -317,6 +318,7 @@ struct ext3_inode {
+@@ -322,6 +323,7 @@ struct ext3_inode {
#define EXT3_MOUNT_UPDATE_JOURNAL 0x1000 /* Update the journal format */
#define EXT3_MOUNT_NO_UID32 0x2000 /* Disable 32-bit UIDs */
#define EXT3_MOUNT_INDEX 0x4000 /* Enable directory index */
/* Compatibility, for having both ext2_fs.h and ext3_fs.h included at once */
#ifndef _LINUX_EXT2_FS_H
-@@ -651,6 +653,9 @@ extern void ext3_discard_prealloc (struc
+@@ -708,6 +710,9 @@ extern void ext3_discard_prealloc (struc
extern void ext3_dirty_inode(struct inode *);
extern int ext3_change_inode_journal_flag(struct inode *, int);
extern void ext3_truncate (struct inode *);
/* ioctl.c */
extern int ext3_ioctl (struct inode *, struct file *, unsigned int,
---- linux-2.4.18-18.8.0-l15/include/linux/ext3_fs_sb.h~ext3-delete_thread-2.4.18 Tue Jun 3 17:26:21 2003
-+++ linux-2.4.18-18.8.0-l15-adilger/include/linux/ext3_fs_sb.h Wed Jul 2 23:19:09 2003
+--- linux-2.4.18-chaos/include/linux/ext3_fs_sb.h~ext3-delete_thread-2.4.18-2 2003-09-16 23:42:33.000000000 +0400
++++ linux-2.4.18-chaos-alexey/include/linux/ext3_fs_sb.h 2003-09-16 23:42:34.000000000 +0400
@@ -29,6 +29,8 @@
#define EXT3_MAX_GROUP_LOADED 32
/*
* third extended-fs super-block data in memory
*/
-@@ -74,6 +76,14 @@ struct ext3_sb_info {
+@@ -76,6 +78,14 @@ struct ext3_sb_info {
struct timer_list turn_ro_timer; /* For turning read-only (crash simulation) */
wait_queue_head_t ro_wait_queue; /* For people waiting for the fs to go read-only */
#endif
fs/inode.c | 1
- fs/namei.c | 66 ++++++++++++++++++++++++++++++++++++++---------------
+ fs/namei.c | 65 +++++++++++++++++++++++++++++++++++++++--------------
include/linux/fs.h | 11 ++++----
- 3 files changed, 54 insertions(+), 24 deletions(-)
+ 3 files changed, 54 insertions(+), 23 deletions(-)
---- linux-2.4.18/fs/namei.c~vfs-pdirops-2.4.18-chaos 2003-09-01 14:58:03.000000000 +0400
-+++ linux-2.4.18-alexey/fs/namei.c 2003-09-01 17:56:10.000000000 +0400
+--- linux-2.4.18-chaos/fs/namei.c~vfs-pdirops-2.4.18-chaos 2003-09-16 23:33:47.000000000 +0400
++++ linux-2.4.18-chaos-alexey/fs/namei.c 2003-09-17 00:18:45.000000000 +0400
@@ -101,6 +101,36 @@ void intent_release(struct lookup_intent
}
/* In order to reduce some races, while at the same time doing additional
* checking and hopefully speeding things up, we copy filenames to the
* kernel data space before using them..
-@@ -302,10 +332,10 @@ static struct dentry *real_lookup(struct
- {
+@@ -303,10 +333,11 @@ static struct dentry *real_lookup(struct
struct dentry * result;
struct inode *dir = parent->d_inode;
-+ void *lock;
+ int counter = 0;
++ void *lock;
again:
--
++ lock = lock_dir(dir, name);
+ counter++;
- down(&dir->i_sem);
-+ lock = lock_dir(dir, name);
/*
* First re-do the cached lookup just in case it was created
* while we waited for the directory semaphore..
-@@ -329,7 +359,7 @@ again:
+@@ -330,7 +361,7 @@ again:
else
result = dentry;
}
return result;
}
-@@ -337,7 +367,7 @@ again:
+@@ -338,7 +369,7 @@ again:
* Uhhuh! Nasty case: the cache was re-populated while
* we waited on the semaphore. Need to revalidate.
*/
if (result->d_op && result->d_op->d_revalidate) {
if (!result->d_op->d_revalidate(result, flags) && !d_invalidate(result)) {
dput(result);
-@@ -1234,13 +1264,13 @@ struct file *filp_open(const char * path
+@@ -1240,13 +1271,13 @@ struct file *filp_open(const char * path
goto exit;
dir = nd.dentry;
goto exit;
}
-@@ -1249,7 +1279,7 @@ do_last:
+@@ -1255,7 +1286,7 @@ do_last:
if (!dentry->d_inode) {
error = vfs_create_it(dir->d_inode, dentry,
mode & ~current->fs->umask, &it);
dput(nd.dentry);
nd.dentry = dentry;
if (error)
-@@ -1264,7 +1294,7 @@ do_last:
+@@ -1270,7 +1301,7 @@ do_last:
/*
* It already exists.
*/
error = -EEXIST;
if (flag & O_EXCL)
-@@ -1344,7 +1374,7 @@ do_link:
+@@ -1350,7 +1381,7 @@ do_link:
goto exit;
}
dir = nd.dentry;
dentry = lookup_hash_it(&nd.last, nd.dentry, &it);
putname(nd.last.name);
goto do_last;
-@@ -1357,7 +1387,7 @@ static struct dentry *lookup_create(stru
+@@ -1363,7 +1394,7 @@ static struct dentry *lookup_create(stru
{
struct dentry *dentry;
dentry = ERR_PTR(-EEXIST);
if (nd->last_type != LAST_NORM)
goto fail;
-@@ -1446,7 +1476,7 @@ asmlinkage long sys_mknod(const char * f
+@@ -1452,7 +1483,7 @@ asmlinkage long sys_mknod(const char * f
}
dput(dentry);
}
out2:
path_release(&nd);
out:
-@@ -1509,7 +1539,7 @@ asmlinkage long sys_mkdir(const char * p
+@@ -1515,7 +1546,7 @@ asmlinkage long sys_mkdir(const char * p
mode & ~current->fs->umask);
dput(dentry);
}
out2:
path_release(&nd);
out:
-@@ -1619,14 +1649,14 @@ asmlinkage long sys_rmdir(const char * p
+@@ -1625,14 +1656,14 @@ asmlinkage long sys_rmdir(const char * p
if (error != -EOPNOTSUPP)
goto exit1;
}
exit1:
path_release(&nd);
exit:
-@@ -1685,7 +1715,7 @@ asmlinkage long sys_unlink(const char *
+@@ -1691,7 +1722,7 @@ asmlinkage long sys_unlink(const char *
if (error != -EOPNOTSUPP)
goto exit1;
}
dentry = lookup_hash_it(&nd.last, nd.dentry, NULL);
error = PTR_ERR(dentry);
if (!IS_ERR(dentry)) {
-@@ -1696,7 +1726,7 @@ asmlinkage long sys_unlink(const char *
+@@ -1702,7 +1733,7 @@ asmlinkage long sys_unlink(const char *
exit2:
dput(dentry);
}
exit1:
path_release(&nd);
exit:
-@@ -1766,7 +1796,7 @@ asmlinkage long sys_symlink(const char *
+@@ -1772,7 +1803,7 @@ asmlinkage long sys_symlink(const char *
error = vfs_symlink(nd.dentry->d_inode, dentry, from);
dput(dentry);
}
out2:
path_release(&nd);
out:
-@@ -1858,7 +1888,7 @@ asmlinkage long sys_link(const char * ol
+@@ -1864,7 +1895,7 @@ asmlinkage long sys_link(const char * ol
error = vfs_link(old_nd.dentry, nd.dentry->d_inode, new_dentry);
dput(new_dentry);
}
out_release:
path_release(&nd);
out:
---- linux-2.4.18/include/linux/fs.h~vfs-pdirops-2.4.18-chaos 2003-09-01 14:58:03.000000000 +0400
-+++ linux-2.4.18-alexey/include/linux/fs.h 2003-09-01 16:36:16.000000000 +0400
+--- linux-2.4.18-chaos/include/linux/fs.h~vfs-pdirops-2.4.18-chaos 2003-09-16 23:33:47.000000000 +0400
++++ linux-2.4.18-chaos-alexey/include/linux/fs.h 2003-09-17 00:16:08.000000000 +0400
@@ -21,6 +21,7 @@
#include <linux/cache.h>
#include <linux/stddef.h>
#define IS_DEADDIR(inode) ((inode)->i_flags & S_DEAD)
-@@ -490,6 +493,7 @@ struct inode {
+@@ -491,6 +494,7 @@ struct inode {
atomic_t i_writecount;
unsigned int i_attr_flags;
__u32 i_generation;
union {
struct minix_inode_info minix_i;
struct ext2_inode_info ext2_i;
-@@ -713,6 +717,7 @@ struct nameidata {
+@@ -714,6 +718,7 @@ struct nameidata {
unsigned int flags;
int last_type;
struct lookup_intent *intent;
};
#define DQUOT_USR_ENABLED 0x01 /* User diskquotas enabled */
-@@ -1610,12 +1615,6 @@ static inline struct dentry *get_parent(
+@@ -1611,12 +1616,6 @@ static inline struct dentry *get_parent(
return dget(dentry->d_parent);
}
/*
* Whee.. Deadlock country. Happily there are only two VFS
* operations that does this..
---- linux-2.4.18/fs/inode.c~vfs-pdirops-2.4.18-chaos 2003-09-01 14:58:03.000000000 +0400
-+++ linux-2.4.18-alexey/fs/inode.c 2003-09-01 16:36:16.000000000 +0400
+--- linux-2.4.18-chaos/fs/inode.c~vfs-pdirops-2.4.18-chaos 2003-09-16 23:33:48.000000000 +0400
++++ linux-2.4.18-chaos-alexey/fs/inode.c 2003-09-16 23:47:45.000000000 +0400
@@ -119,6 +119,7 @@ static struct inode *alloc_inode(struct
mapping->host = inode;
mapping->gfp_mask = GFP_HIGHUSER;