patch-2.1.45 linux/fs/ext2/truncate.c
Next file: linux/fs/fat/cache.c
Previous file: linux/fs/ext2/symlink.c
Back to the patch index
Back to the overall index
- Lines: 326
- Date:
Fri Jul 11 21:56:02 1997
- Orig file:
v2.1.44/linux/fs/ext2/truncate.c
- Orig date:
Thu Nov 14 00:27:38 1996
diff -u --recursive --new-file v2.1.44/linux/fs/ext2/truncate.c linux/fs/ext2/truncate.c
@@ -91,7 +91,7 @@
}
*p = 0;
inode->i_blocks -= blocks;
- inode->i_dirt = 1;
+ mark_inode_dirty(inode);
bforget(bh);
if (free_count == 0) {
block_to_free = tmp;
@@ -110,7 +110,8 @@
return retry;
}
-static int trunc_indirect (struct inode * inode, int offset, u32 * p)
+static int trunc_indirect (struct inode * inode, int offset, u32 * p,
+ int in_inode)
{
int i, tmp;
struct buffer_head * bh;
@@ -124,103 +125,16 @@
#define INDIRECT_BLOCK ((int)DIRECT_BLOCK - offset)
int indirect_block = INDIRECT_BLOCK;
- tmp = *p;
+ tmp = in_inode ? *p : le32_to_cpu(*p);
if (!tmp)
return 0;
ind_bh = bread (inode->i_dev, tmp, inode->i_sb->s_blocksize);
- if (tmp != *p) {
- brelse (ind_bh);
- return 1;
- }
- if (!ind_bh) {
- *p = 0;
- return 0;
- }
-repeat:
- for (i = indirect_block ; i < addr_per_block ; i++) {
- if (i < 0)
- i = 0;
- if (i < indirect_block)
- goto repeat;
- ind = i + (u32 *) ind_bh->b_data;
- tmp = le32_to_cpu(*ind);
- if (!tmp)
- continue;
- bh = get_hash_table (inode->i_dev, tmp,
- inode->i_sb->s_blocksize);
- if (i < indirect_block) {
- brelse (bh);
- goto repeat;
- }
- if ((bh && bh->b_count != 1) || tmp != le32_to_cpu(*ind)) {
- retry = 1;
- brelse (bh);
- continue;
- }
- *ind = cpu_to_le32(0);
- mark_buffer_dirty(ind_bh, 1);
- bforget(bh);
- if (free_count == 0) {
- block_to_free = tmp;
- free_count++;
- } else if (free_count > 0 && block_to_free == tmp - free_count)
- free_count++;
- else {
- ext2_free_blocks (inode, block_to_free, free_count);
- block_to_free = tmp;
- free_count = 1;
- }
-/* ext2_free_blocks (inode, tmp, 1); */
- inode->i_blocks -= blocks;
- inode->i_dirt = 1;
- }
- if (free_count > 0)
- ext2_free_blocks (inode, block_to_free, free_count);
- ind = (u32 *) ind_bh->b_data;
- for (i = 0; i < addr_per_block; i++)
- if (le32_to_cpu(*(ind++)))
- break;
- if (i >= addr_per_block)
- if (ind_bh->b_count != 1)
- retry = 1;
- else {
- tmp = *p;
- *p = 0;
- inode->i_blocks -= blocks;
- inode->i_dirt = 1;
- ext2_free_blocks (inode, tmp, 1);
- }
- if (IS_SYNC(inode) && buffer_dirty(ind_bh)) {
- ll_rw_block (WRITE, 1, &ind_bh);
- wait_on_buffer (ind_bh);
- }
- brelse (ind_bh);
- return retry;
-}
-
-static int trunc_indirect_swab32 (struct inode * inode, int offset, u32 * p)
-{
- int i, tmp;
- struct buffer_head * bh;
- struct buffer_head * ind_bh;
- u32 * ind;
- unsigned long block_to_free = 0;
- unsigned long free_count = 0;
- int retry = 0;
- int addr_per_block = EXT2_ADDR_PER_BLOCK(inode->i_sb);
- int blocks = inode->i_sb->s_blocksize / 512;
- int indirect_block = INDIRECT_BLOCK;
-
- tmp = le32_to_cpu(*p);
- if (!tmp)
- return 0;
- ind_bh = bread (inode->i_dev, tmp, inode->i_sb->s_blocksize);
- if (tmp != le32_to_cpu(*p)) {
+ if (tmp != (in_inode ? *p : le32_to_cpu(*p))) {
brelse (ind_bh);
return 1;
}
if (!ind_bh) {
- *p = cpu_to_le32(0);
+ *p = in_inode ? 0 : cpu_to_le32(0);
return 0;
}
repeat:
@@ -259,7 +173,7 @@
}
/* ext2_free_blocks (inode, tmp, 1); */
inode->i_blocks -= blocks;
- inode->i_dirt = 1;
+ mark_inode_dirty(inode);
}
if (free_count > 0)
ext2_free_blocks (inode, block_to_free, free_count);
@@ -271,13 +185,15 @@
if (ind_bh->b_count != 1)
retry = 1;
else {
- tmp = le32_to_cpu(*p);
- *p = cpu_to_le32(0);
+ tmp = in_inode ? *p : le32_to_cpu(*p);
+ *p = in_inode ? 0 : cpu_to_le32(0);
inode->i_blocks -= blocks;
- inode->i_dirt = 1;
+ mark_inode_dirty(inode);
ext2_free_blocks (inode, tmp, 1);
+ bforget(ind_bh);
+ ind_bh = NULL;
}
- if (IS_SYNC(inode) && buffer_dirty(ind_bh)) {
+ if (IS_SYNC(inode) && ind_bh && buffer_dirty(ind_bh)) {
ll_rw_block (WRITE, 1, &ind_bh);
wait_on_buffer (ind_bh);
}
@@ -286,7 +202,7 @@
}
static int trunc_dindirect (struct inode * inode, int offset,
- u32 * p)
+ u32 * p, int in_inode)
{
int i, tmp;
struct buffer_head * dind_bh;
@@ -297,75 +213,16 @@
#define DINDIRECT_BLOCK (((int)DIRECT_BLOCK - offset) / addr_per_block)
int dindirect_block = DINDIRECT_BLOCK;
- tmp = *p;
- if (!tmp)
- return 0;
- dind_bh = bread (inode->i_dev, tmp, inode->i_sb->s_blocksize);
- if (tmp != *p) {
- brelse (dind_bh);
- return 1;
- }
- if (!dind_bh) {
- *p = 0;
- return 0;
- }
-repeat:
- for (i = dindirect_block ; i < addr_per_block ; i++) {
- if (i < 0)
- i = 0;
- if (i < dindirect_block)
- goto repeat;
- dind = i + (u32 *) dind_bh->b_data;
- tmp = le32_to_cpu(*dind);
- if (!tmp)
- continue;
- retry |= trunc_indirect_swab32 (inode, offset + (i * addr_per_block),
- dind);
- mark_buffer_dirty(dind_bh, 1);
- }
- dind = (u32 *) dind_bh->b_data;
- for (i = 0; i < addr_per_block; i++)
- if (le32_to_cpu(*(dind++)))
- break;
- if (i >= addr_per_block)
- if (dind_bh->b_count != 1)
- retry = 1;
- else {
- tmp = *p;
- *p = 0;
- inode->i_blocks -= blocks;
- inode->i_dirt = 1;
- ext2_free_blocks (inode, tmp, 1);
- }
- if (IS_SYNC(inode) && buffer_dirty(dind_bh)) {
- ll_rw_block (WRITE, 1, &dind_bh);
- wait_on_buffer (dind_bh);
- }
- brelse (dind_bh);
- return retry;
-}
-
-static int trunc_dindirect_swab32 (struct inode * inode, int offset,
- u32 * p)
-{
- int i, tmp;
- struct buffer_head * dind_bh;
- u32 * dind;
- int retry = 0;
- int addr_per_block = EXT2_ADDR_PER_BLOCK(inode->i_sb);
- int blocks = inode->i_sb->s_blocksize / 512;
- int dindirect_block = DINDIRECT_BLOCK;
-
- tmp = le32_to_cpu(*p);
+ tmp = in_inode ? *p : le32_to_cpu(*p);
if (!tmp)
return 0;
dind_bh = bread (inode->i_dev, tmp, inode->i_sb->s_blocksize);
- if (tmp != le32_to_cpu(*p)) {
+ if (tmp != (in_inode ? *p : le32_to_cpu(*p))) {
brelse (dind_bh);
return 1;
}
if (!dind_bh) {
- *p = cpu_to_le32(0);
+ *p = in_inode ? 0 : cpu_to_le32(0);
return 0;
}
repeat:
@@ -378,8 +235,8 @@
tmp = le32_to_cpu(*dind);
if (!tmp)
continue;
- retry |= trunc_indirect_swab32 (inode, offset + (i * addr_per_block),
- dind);
+ retry |= trunc_indirect(inode, offset + (i * addr_per_block),
+ dind, 0);
mark_buffer_dirty(dind_bh, 1);
}
dind = (u32 *) dind_bh->b_data;
@@ -390,13 +247,15 @@
if (dind_bh->b_count != 1)
retry = 1;
else {
- tmp = le32_to_cpu(*p);
- *p = cpu_to_le32(0);
+ tmp = in_inode ? *p : le32_to_cpu(*p);
+ *p = in_inode ? 0 : cpu_to_le32(0);
inode->i_blocks -= blocks;
- inode->i_dirt = 1;
+ mark_inode_dirty(inode);
ext2_free_blocks (inode, tmp, 1);
+ bforget(dind_bh);
+ dind_bh = 0;
}
- if (IS_SYNC(inode) && buffer_dirty(dind_bh)) {
+ if (IS_SYNC(inode) && dind_bh && buffer_dirty(dind_bh)) {
ll_rw_block (WRITE, 1, &dind_bh);
wait_on_buffer (dind_bh);
}
@@ -436,9 +295,9 @@
if (i < tindirect_block)
goto repeat;
tind = i + (u32 *) tind_bh->b_data;
- retry |= trunc_dindirect_swab32(inode, EXT2_NDIR_BLOCKS +
+ retry |= trunc_dindirect(inode, EXT2_NDIR_BLOCKS +
addr_per_block + (i + 1) * addr_per_block * addr_per_block,
- tind);
+ tind, 0);
mark_buffer_dirty(tind_bh, 1);
}
tind = (u32 *) tind_bh->b_data;
@@ -452,10 +311,12 @@
tmp = *p;
*p = 0;
inode->i_blocks -= blocks;
- inode->i_dirt = 1;
+ mark_inode_dirty(inode);
ext2_free_blocks (inode, tmp, 1);
+ bforget(tind_bh);
+ tind_bh = 0;
}
- if (IS_SYNC(inode) && buffer_dirty(tind_bh)) {
+ if (IS_SYNC(inode) && tind_bh && buffer_dirty(tind_bh)) {
ll_rw_block (WRITE, 1, &tind_bh);
wait_on_buffer (tind_bh);
}
@@ -479,14 +340,14 @@
while (1) {
retry = trunc_direct(inode);
retry |= trunc_indirect (inode, EXT2_IND_BLOCK,
- (u32 *) &inode->u.ext2_i.i_data[EXT2_IND_BLOCK]);
+ (u32 *) &inode->u.ext2_i.i_data[EXT2_IND_BLOCK], 1);
retry |= trunc_dindirect (inode, EXT2_IND_BLOCK +
EXT2_ADDR_PER_BLOCK(inode->i_sb),
- (u32 *) &inode->u.ext2_i.i_data[EXT2_DIND_BLOCK]);
+ (u32 *) &inode->u.ext2_i.i_data[EXT2_DIND_BLOCK], 1);
retry |= trunc_tindirect (inode);
if (!retry)
break;
- if (IS_SYNC(inode) && inode->i_dirt)
+ if (IS_SYNC(inode) && test_bit(I_DIRTY, &inode->i_state))
ext2_sync_inode (inode);
current->counter = 0;
schedule ();
@@ -510,5 +371,5 @@
}
}
inode->i_mtime = inode->i_ctime = CURRENT_TIME;
- inode->i_dirt = 1;
+ mark_inode_dirty(inode);
}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov