[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