[Ocfs2-commits] mfasheh commits r1286 - trunk/src
svn-commits at oss.oracle.com
svn-commits at oss.oracle.com
Tue Jul 20 00:47:32 CDT 2004
Author: mfasheh
Date: 2004-07-19 23:47:30 -0500 (Mon, 19 Jul 2004)
New Revision: 1286
Modified:
trunk/src/file.c
Log:
* Pre zero on extend. We need this because we don't support holes.
Things can be made more performant -- that's for a later patch to
use the page cache for this stuff instead.
Modified: trunk/src/file.c
===================================================================
--- trunk/src/file.c 2004-07-20 04:03:30 UTC (rev 1285)
+++ trunk/src/file.c 2004-07-20 04:47:30 UTC (rev 1286)
@@ -1202,61 +1202,75 @@
fe = NULL;
- if (system_file) {
+#define OCFS_MAX_ZERO_BLOCKS (4096)
+
+ down(&OCFS_I(inode)->ip_sem);
+ if (!(OCFS_I(inode)->ip_open_flags & OCFS_OIN_OPEN_FOR_DIRECTIO)) {
struct buffer_head **bhs = NULL;
int i;
+ sector_t block;
+ u64 this_last;
- bhs = kmalloc(num_blocks * sizeof(struct buffer_head *),
+ up(&OCFS_I(inode)->ip_sem);
+
+ LOG_TRACE_ARGS("zeroing %llu blocks from offset %llu\n",
+ num_blocks, block_off);
+ bhs = kmalloc(OCFS_MAX_ZERO_BLOCKS * sizeof(struct buffer_head *),
GFP_KERNEL);
if (!bhs) {
status = -ENOMEM;
LOG_ERROR_STATUS(status);
goto leave;
}
- memset(bhs, 0, num_blocks *
+ memset(bhs, 0, OCFS_MAX_ZERO_BLOCKS *
sizeof(struct buffer_head *));
- status = ocfs_read_bhs(osb,
- block_off << osb->sb->s_blocksize_bits,
- (u64)num_blocks << osb->sb->s_blocksize_bits,
- bhs, 0,
- inode);
- if (status < 0) {
- kfree(bhs);
- LOG_ERROR_STATUS(status);
- goto leave;
+ block = block_off;
+ while (block < (block_off + num_blocks)) {
+ this_last = block + OCFS_MAX_ZERO_BLOCKS;
+ if (this_last > (block_off + num_blocks))
+ this_last = block_off + num_blocks;
+
+ //LOG_TRACE_ARGS("block = %llu, this_last = %llu\n",
+ // (unsigned long long) block, this_last);
+ i = 0;
+ while (block < this_last) {
+ bhs[i] = sb_getblk(osb->sb, block);
+ if (!bhs[i]) {
+ status = -ENOMEM;
+ LOG_ERROR_STATUS(status);
+ break;
+ }
+ memset(bhs[i]->b_data, 0,
+ osb->sb->s_blocksize);
+ set_buffer_uptodate(bhs[i]);
+ i++;
+ block++;
+ }
+ if (status)
+ break;
+
+ //LOG_TRACE_ARGS("writing %d blocks\n", i);
+ status = ocfs_write_bhs(osb, bhs, i, 0,
+ system_file ? inode : NULL);
+ if (status) {
+ LOG_ERROR_STATUS(status);
+ break;
+ }
+ for (i = 0; i < OCFS_MAX_ZERO_BLOCKS; i++)
+ if (bhs[i])
+ brelse(bhs[i]);
+ memset(bhs, 0, OCFS_MAX_ZERO_BLOCKS *
+ sizeof(struct buffer_head *));
}
- for (i = 0; i < num_blocks; i++)
- memset(bhs[i]->b_data, 0, osb->sb->s_blocksize);
-
- status = ocfs_write_bhs(osb, bhs, num_blocks, 0, inode);
- for (i = 0; i < num_blocks; i++)
- brelse(bhs[i]);
+ for (i = 0; i < OCFS_MAX_ZERO_BLOCKS; i++)
+ if (bhs[i])
+ brelse(bhs[i]);
kfree(bhs);
- if (status < 0) {
- LOG_ERROR_STATUS(status);
- goto leave;
- }
- } else {
- struct buffer_head *alloc_bh;
- sector_t block;
- struct super_block *sb = osb->sb;
+ } else
+ up(&OCFS_I(inode)->ip_sem);
- for (block = block_off;
- block < (block_off + num_blocks);
- block++) {
- alloc_bh = sb_getblk(sb, block);
- if (!alloc_bh) {
- LOG_ERROR_STATUS(status=-EIO);
- goto leave;
- }
- LOG_TRACE_ARGS("setting block %llu as new!\n",
- (unsigned long long)block);
- alloc_bh->b_state |= (1UL << BH_New);
- brelse(alloc_bh);
- }
- }
ext_alloc_inode = ocfs_get_system_file_inode(osb, EXTENT_ALLOC_BITMAP_SYSTEM_INODE, osb->node_num);
if (!ext_alloc_inode) {
status = -EFAIL;
More information about the Ocfs2-commits
mailing list