[Ocfs2-commits] rev 17 - trunk/src

svn-commits at oss.oracle.com svn-commits at oss.oracle.com
Thu Jan 29 01:40:47 CST 2004


Author: manish
Date: 2004-01-29 01:40:45 -0600 (Thu, 29 Jan 2004)
New Revision: 17

Added:
   trunk/src/io.c
Log:
Sync


Added: trunk/src/io.c
===================================================================
--- trunk/src/io.c	2004-01-27 18:24:19 UTC (rev 16)
+++ trunk/src/io.c	2004-01-29 07:40:45 UTC (rev 17)
@@ -0,0 +1,715 @@
+/*
+ * io.c
+ *
+ * Defines functions of I/O api
+ *
+ * Copyright (C) 2003 Oracle Corporation.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ * 
+ * You should have recieved a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 021110-1307, USA.
+ *
+ * Authors: Kurt Hackel, Sunil Mushran, Manish Singh, Wim Coekaerts,
+ *          Mark Fasheh, Joel Becker
+ */
+
+#include <ocfs.h>
+
+#define OCFS_DEBUG_CONTEXT    OCFS_DEBUG_CONTEXT_DISKIO
+
+static int ocfs_read_bhs_iarr (ocfs_super * osb, __u64 off, __u64 len, 
+				 struct buffer_head *bhs[], int flags, 
+				 struct inode *inodes[]);
+static int ocfs_write_bhs_iarr (ocfs_super * osb, struct buffer_head *bhs[], 
+				  int nr, int flags, struct inode *inodes[]);
+
+
+int ocfs_write_dirnode(ocfs_super * osb, struct buffer_head *bhs[],
+		      int flags, struct inode *hdr_inode)
+{
+	int status, i;
+	struct inode **arr = NULL;
+	struct inode *inode;
+	__u64 tmpoff;
+	unsigned long ino = 0;
+	ocfs_find_inode_args args;
+
+	arr = (struct inode **) ocfs_malloc (256 * sizeof(struct inode *));
+	if (arr == NULL) {
+		LOG_ERROR_STATUS(status = -ENOMEM);
+		goto bail;
+	}
+
+	arr[0] = hdr_inode;
+	for (i=1, tmpoff = (bhs[i]->b_blocknr << 9); i< 256; i++, tmpoff += 512ULL) {
+		inode = NULL;
+		ino = ocfs_inode_hash_lookup(&osb->inode_hash, tmpoff, NULL);
+		if (ino) {
+			args.offset = tmpoff;
+			args.fe_bh = bhs[i];
+			args.file_lookup_only = true;
+			inode = iget4(osb->sb, ino, (find_inode_t) ocfs_find_inode, &args);
+			if (!inode || is_bad_inode (inode)) {
+				LOG_ERROR_STATUS(-EINVAL);
+				if (inode) {
+					iput(inode);
+					inode = NULL;
+				}
+			}
+		}
+		arr[i] = inode;
+	}
+
+	status = ocfs_write_bhs_iarr (osb, bhs, 256, flags, arr);
+	
+	for (i=1; i< 256; i++) {
+		inode = arr[i];
+		if (inode)
+			iput(inode);
+	}
+
+bail:
+	ocfs_safefree(arr);
+	return status;
+}
+
+
+
+int ocfs_read_dirnode(ocfs_super * osb, __u64 off, struct buffer_head *bhs[],
+		      int flags, struct inode *hdr_inode)
+{
+	int status, i;
+	struct inode **arr = NULL;
+	struct inode *inode;
+	__u64 tmpoff;
+	unsigned long ino = 0;
+	ocfs_find_inode_args args;
+
+	arr = (struct inode **) ocfs_malloc (256 * sizeof(struct inode *));
+	if (arr == NULL) {
+		LOG_ERROR_STATUS(status = -ENOMEM);
+		goto bail;
+	}
+
+	arr[0] = hdr_inode;
+	for (i=1, tmpoff=off+512ULL; i< 256; i++, tmpoff += 512ULL) {
+		inode = NULL;
+		ino = ocfs_inode_hash_lookup(&osb->inode_hash, tmpoff, NULL);
+		if (ino) {
+			args.offset = tmpoff;
+			args.fe_bh = bhs[i];
+			args.file_lookup_only = true;
+			inode = iget4(osb->sb, ino, (find_inode_t) ocfs_find_inode, &args);
+			if (!inode || is_bad_inode (inode)) {
+				LOG_ERROR_STATUS(-EINVAL);
+				if (inode) {
+					iput(inode);
+					inode = NULL;
+				}
+			}
+		}
+		arr[i] = inode;
+	}
+
+	status = ocfs_read_bhs_iarr (osb, off, osb->vol_layout.dir_node_size,
+				 bhs, flags, arr);
+	
+	for (i=1; i< 256; i++) {
+		inode = arr[i];
+		if (inode)
+			iput(inode);
+	}
+
+bail:
+	ocfs_safefree(arr);
+	return status;
+}
+
+
+
+
+
+
+static int ocfs_write_bhs_iarr (ocfs_super * osb, struct buffer_head *bhs[], 
+				  int nr, int flags, struct inode *inodes[])
+{
+	int status = 0;
+	int i;
+	struct super_block *sb;
+	ocfs_blockdev dev;
+	struct buffer_head *bh;
+
+#ifdef OCFS_DBG_TIMING
+	my_timing_t begin, end; 
+#endif
+	
+	LOG_ENTRY_ARGS("(bh[0]->b_blocknr = %u, nr=%d, flags=%u, inodes=%p)\n", 
+		       bhs[0]->b_blocknr, nr, flags, inodes);
+#ifdef OCFS_DBG_TIMING
+	rdtsc (begin.lohi[0], begin.lohi[1]);
+#endif
+
+	if (osb == NULL || osb->sb == NULL || bhs == NULL) {
+		LOG_TRACE_STR("osb == NULL || osb->sb == NULL || bhs == "
+		       "NULL");
+		status = -EINVAL;
+		LOG_ERROR_STATUS(status);
+		goto bail;
+	}
+
+	if (nr > 256)
+		LOG_TRACE_ARGS ("Getting write for %d blocks\n", nr);
+
+	sb = osb->sb;
+	dev = OCFS_GET_BLOCKDEV(sb);
+
+	/* we don't ever want cached writes -- those should go to the
+	 * journal so we can control when they actually hit disk and
+	 * so we can make sure they never get overwritten by a
+	 * subsequent read. */
+	if ((flags & OCFS_BH_CACHED) || (flags & OCFS_BH_COND_CACHED)) {
+		LOG_TRACE_STR("asking for a cached write!");
+		status = -EINVAL;
+		LOG_ERROR_STATUS(status);
+		goto bail;
+	}
+
+	for (i = 0 ; i < nr ; i++) {
+		bh = bhs[i];
+		if (bh == NULL) {
+			LOG_TRACE_STR("bh == NULL");
+			status = -EIO;
+			LOG_ERROR_STATUS(status);
+			goto bail;
+		}
+
+		check_rootdir_overwrite(bh);
+
+		if (check_block_zero_write(bh) < 0) {
+			status = -EIO;	
+			LOG_ERROR_STATUS(status);
+			goto bail;
+		}
+
+		if (flags & OCFS_BH_CONCURRENT_WRITE)
+			goto skip_modified_check;
+
+		/* Make sure the buffer is locked for modify, and
+		 * we're the ones with the write lock on this
+		 * buffer. */
+		if (!buffer_modified(bh)) {
+			printk("ocfs2: modified bit is NOT set on buffer "
+			       "(bh->b_blocknr = %lu)!\n", bh->b_blocknr);
+			BUG();
+		}
+		if (ocfs_bh_sem_lock_modify(bh) == OCFS_BH_SEM_WAIT_ON_MODIFY){
+			printk("ocfs2: someone else owns this buffer"
+			       "(bh->b_blocknr = %lu)!\n", bh->b_blocknr);
+			BUG();
+		}
+		ocfs_bh_sem_unlock(bh);
+
+skip_modified_check:
+		if (!(flags & OCFS_BH_IGNORE_JBD) && buffer_jbd(bh)) {
+#ifdef VERBOSE_BH_JBD_TRACE
+			LOG_TRACE_ARGS("trying to write a jbd managed bh "
+				       "(blocknr = %u), nr=%d\n", 
+				       bh->b_blocknr, nr);
+#endif
+			continue;
+		}
+
+		LOCK_BUFFER_STR(bh);
+		VERBOSE_LOCK_BUFFER_STR(bh);
+		lock_buffer(bh);
+
+#ifdef LINUX_2_5
+		set_buffer_uptodate(bh);
+#else
+		mark_buffer_uptodate(bh, true);
+#endif
+		/* remove from dirty list before I/O. */
+		mark_buffer_clean(bh);
+
+		bh->b_end_io = ocfs_end_buffer_io_sync;
+		submit_bh(WRITE, bh);
+	}
+
+	for (i = (nr-1) ; i >= 0; i--) {
+		bh = bhs[i];
+
+		wait_on_buffer(bh);
+
+		if (inodes[i])
+			SET_BH_SEQNUM(inodes[i], bh);
+		else
+			CLEAR_BH_SEQNUM(bh);
+
+		if (!(flags & OCFS_BH_CONCURRENT_WRITE))
+			ocfs_clear_buffer_modified(bh);
+	}
+	
+bail:
+
+#ifdef OCFS_DBG_TIMING
+	IO_FUNC_TIMING_PRINT("ocfs_write_bhs_iarr", status);
+#endif
+
+	LOG_EXIT_STATUS(status);
+	return status;
+}
+
+/*
+ * ocfs_read_bhs_iarr()
+ *
+ */
+static int ocfs_read_bhs_iarr (ocfs_super * osb, __u64 off, __u64 len, 
+				 struct buffer_head *bhs[], int flags, 
+				 struct inode *inodes[])
+{
+	int status = 0;
+	struct super_block *sb;
+	int nr, i, ignore_cache = 0;
+	__u64 blocknum;
+	ocfs_blockdev dev;
+	struct buffer_head *bh;
+
+#ifdef OCFS_DBG_TIMING
+	my_timing_t begin, end; 
+#endif
+	LOG_ENTRY_ARGS("(off=(%u.%u), len=(%u.%u), flags=%d, inodes=%p)\n", HILO(off), 
+		       HILO(len), flags, inodes);
+#ifdef OCFS_DBG_TIMING
+	rdtsc (begin.lohi[0], begin.lohi[1]);
+#endif
+
+	if (len % 512) {
+		LOG_TRACE_ARGS("len %% 512 (len=%u)\n", len);
+		status = -EINVAL;
+		LOG_ERROR_STATUS(status);
+		goto bail;
+	}
+
+	if (osb == NULL || osb->sb == NULL || bhs == NULL) {
+		LOG_TRACE_STR("osb == NULL || osb->sb == NULL || bhs == NULL "
+			      "|| num == NULL");
+		status = -EINVAL;
+		LOG_ERROR_STATUS(status);
+		goto bail;
+	}
+
+	if ((flags & OCFS_BH_COND_CACHED) && 
+	    (off >= osb->vol_layout.bitmap_off))
+			flags |= OCFS_BH_CACHED;
+
+	if (OCFS_NONCACHED(osb, off)) {
+		if (flags & OCFS_BH_CACHED)
+			LOG_TRACE_STR("hey bozo you are trying to write "
+				      "a system thingy cached!");
+		flags &= ~OCFS_BH_CACHED;
+	}
+
+	sb = osb->sb;
+	dev = OCFS_GET_BLOCKDEV(sb);
+	blocknum = off >> sb->s_blocksize_bits;
+
+	nr = (len + 511) >> 9;
+	if (nr == 0) {
+		LOG_TRACE_STR("No buffers will be read!!!");
+		LOG_TRACE_ARGS("Len=%u Off=%u.%u numbuffers=%u "
+			       "blocknum=%u.%u\n", len, HI (off), LO (off), 
+			       nr, HI (blocknum), LO (blocknum));
+		status = 0;
+		goto bail;
+	}
+
+	for (i = 0 ; i < nr ; i++) {
+		if (bhs[i] == NULL) {
+			bhs[i] = getblk (dev, blocknum++, sb->s_blocksize);
+			if (bhs[i] == NULL) {
+				LOG_TRACE_STR("bh == NULL");
+				status = -EIO;
+				LOG_ERROR_STATUS(status);
+				goto bail;
+			}
+		}
+		bh = bhs[i];
+		ignore_cache = 0;
+
+		/* Lock everyone else out of this bh */
+		OCFS_BH_GET_DATA_READ(bh);
+	
+		if (!inodes[i]) {
+			ignore_cache = 1;
+		} else if (flags & OCFS_BH_CACHED && !TEST_BH_SEQNUM(inodes[i], bh)) {
+#ifdef VERBOSE_BH_SEQNUM_TRACE
+			LOG_TRACE_ARGS("(read) bh (%u) seqnum (%u) does not "
+			       	"match inode (%u)\n", bh->b_blocknr, 
+			       	(bh->b_state & STATE_BIT_MASK) >> 19,
+			       	atomic_read(GET_INODE_CLEAN_SEQ(inodes[i])));
+#endif
+			ignore_cache = 1;
+		}
+
+		if ((flags & OCFS_BH_CACHED) && (!buffer_uptodate(bh)))
+			ignore_cache = 1;
+
+		/* explicitly do not reread from disk */
+		if (flags & OCFS_BH_CACHE_LOCK)
+			ignore_cache = 0;
+
+		if (buffer_jbd(bh)) {
+#ifdef VERBOSE_BH_JBD_TRACE
+			if (!(flags & OCFS_BH_CACHED) || ignore_cache)
+				LOG_TRACE_ARGS("trying to sync read a jbd "
+					       "managed bh (blocknr = %u)\n",
+					       bh->b_blocknr);
+#endif
+			continue;
+		}
+
+		if (!(flags & OCFS_BH_CACHED) || ignore_cache) {
+			if (buffer_dirty(bh)) {
+				/* This should probably be a BUG, or
+				 * at least return an error. */
+				LOG_TRACE_ARGS("asking me to sync read a "
+					      "dirty buffer! (blocknr = %u)\n",
+					      bh->b_blocknr);
+				continue;
+			}
+
+			LOCK_BUFFER_STR(bh);
+			VERBOSE_LOCK_BUFFER_STR(bh);
+			lock_buffer(bh);
+#ifdef LINUX_2_5
+			clear_buffer_uptodate(bh);
+#else
+			mark_buffer_uptodate(bh, false);
+#endif
+			bh->b_end_io = ocfs_end_buffer_io_sync;
+			submit_bh(READ, bh);
+			continue;
+		}
+	}
+
+	status = 0;
+
+	for (i = (nr-1); i >= 0; i--) {
+		bh = bhs[i];
+
+		wait_on_buffer(bh);
+
+		if (inodes[i])
+			SET_BH_SEQNUM(inodes[i], bh);
+		else
+			CLEAR_BH_SEQNUM(bh);
+
+		OCFS_BH_PUT_DATA(bh);
+	}
+	LOG_TRACE_ARGS("off=(%u.%u), len=(%u.%u), cached=%s\n", HILO(off), HILO(len), 
+		       (!(flags & OCFS_BH_CACHED) || ignore_cache) ? "no" : "yes");
+
+bail:
+
+#ifdef OCFS_DBG_TIMING
+	IO_FUNC_TIMING_PRINT("ocfs_read_bhs_iarr", status);
+#endif
+
+	LOG_EXIT_STATUS(status);
+	return status;
+}
+
+int ocfs_write_bhs (ocfs_super * osb, struct buffer_head *bhs[], 
+				  int nr, int flags, struct inode *inode)
+{
+	int status = 0;
+	int i;
+	struct super_block *sb;
+	ocfs_blockdev dev;
+	struct buffer_head *bh;
+
+#ifdef OCFS_DBG_TIMING
+	my_timing_t begin, end; 
+#endif
+	
+	LOG_ENTRY_ARGS("(bh[0]->b_blocknr = %u, nr=%d, flags=%u, inode=%p)\n", 
+		       bhs[0]->b_blocknr, nr, flags, inode);
+#ifdef OCFS_DBG_TIMING
+	rdtsc (begin.lohi[0], begin.lohi[1]);
+#endif
+
+	if (osb == NULL || osb->sb == NULL || bhs == NULL) {
+		LOG_TRACE_STR("osb == NULL || osb->sb == NULL || bhs == "
+		       "NULL");
+		status = -EINVAL;
+		LOG_ERROR_STATUS(status);
+		goto bail;
+	}
+
+	if (nr > 256)
+		LOG_TRACE_ARGS ("Getting write for %d blocks\n", nr);
+
+	sb = osb->sb;
+	dev = OCFS_GET_BLOCKDEV(sb);
+
+	/* we don't ever want cached writes -- those should go to the
+	 * journal so we can control when they actually hit disk and
+	 * so we can make sure they never get overwritten by a
+	 * subsequent read. */
+	if ((flags & OCFS_BH_CACHED) || (flags & OCFS_BH_COND_CACHED)) {
+		LOG_TRACE_STR("asking for a cached write!");
+		status = -EINVAL;
+		LOG_ERROR_STATUS(status);
+		goto bail;
+	}
+
+	for (i = 0 ; i < nr ; i++) {
+		bh = bhs[i];
+		if (bh == NULL) {
+			LOG_TRACE_STR("bh == NULL");
+			status = -EIO;
+			LOG_ERROR_STATUS(status);
+			goto bail;
+		}
+
+		check_rootdir_overwrite(bh);
+
+		if (check_block_zero_write(bh) < 0) {
+			status = -EIO;	
+			LOG_ERROR_STATUS(status);
+			goto bail;
+		}
+
+		if (flags & OCFS_BH_CONCURRENT_WRITE)
+			goto skip_modified_check;
+
+		/* Make sure the buffer is locked for modify, and
+		 * we're the ones with the write lock on this
+		 * buffer. */
+		if (!buffer_modified(bh)) {
+			printk("ocfs2: modified bit is NOT set on buffer "
+			       "(bh->b_blocknr = %lu)!\n", bh->b_blocknr);
+			BUG();
+		}
+		if (ocfs_bh_sem_lock_modify(bh) == OCFS_BH_SEM_WAIT_ON_MODIFY){
+			printk("ocfs2: someone else owns this buffer"
+			       "(bh->b_blocknr = %lu)!\n", bh->b_blocknr);
+			BUG();
+		}
+		ocfs_bh_sem_unlock(bh);
+
+skip_modified_check:
+		if (!(flags & OCFS_BH_IGNORE_JBD) && buffer_jbd(bh)) {
+#ifdef VERBOSE_BH_JBD_TRACE
+			LOG_TRACE_ARGS("trying to write a jbd managed bh "
+				       "(blocknr = %u), nr=%d\n", 
+				       bh->b_blocknr, nr);
+#endif
+			continue;
+		}
+
+		LOCK_BUFFER_STR(bh);
+		VERBOSE_LOCK_BUFFER_STR(bh);
+		lock_buffer(bh);
+
+#ifdef LINUX_2_5
+		set_buffer_uptodate(bh);
+#else
+		mark_buffer_uptodate(bh, true);
+#endif
+		/* remove from dirty list before I/O. */
+		mark_buffer_clean(bh);
+
+		bh->b_end_io = ocfs_end_buffer_io_sync;
+		submit_bh(WRITE, bh);
+	}
+
+	for (i = (nr-1) ; i >= 0; i--) {
+		bh = bhs[i];
+
+		wait_on_buffer(bh);
+
+		if (inode)
+			SET_BH_SEQNUM(inode, bh);
+		else
+			CLEAR_BH_SEQNUM(bh);
+
+		if (!(flags & OCFS_BH_CONCURRENT_WRITE))
+			ocfs_clear_buffer_modified(bh);
+	}
+	
+bail:
+
+#ifdef OCFS_DBG_TIMING
+	IO_FUNC_TIMING_PRINT("ocfs_write_bhs", status);
+#endif
+
+	LOG_EXIT_STATUS(status);
+	return status;
+}
+
+/*
+ * ocfs_read_bhs()
+ *
+ */
+int ocfs_read_bhs (ocfs_super * osb, __u64 off, __u64 len, 
+				 struct buffer_head *bhs[], int flags, 
+				 struct inode *inode)
+{
+	int status = 0;
+	struct super_block *sb;
+	int nr, i, ignore_cache = 0;
+	__u64 blocknum;
+	ocfs_blockdev dev;
+	struct buffer_head *bh;
+
+#ifdef OCFS_DBG_TIMING
+	my_timing_t begin, end; 
+#endif
+	LOG_ENTRY_ARGS("(off=(%u.%u), len=(%u.%u), flags=%d, inode=%p)\n", HILO(off), 
+		       HILO(len), flags, inode);
+#ifdef OCFS_DBG_TIMING
+	rdtsc (begin.lohi[0], begin.lohi[1]);
+#endif
+
+	if (len % 512) {
+		LOG_TRACE_ARGS("len %% 512 (len=%u)\n", len);
+		status = -EINVAL;
+		LOG_ERROR_STATUS(status);
+		goto bail;
+	}
+
+	if (osb == NULL || osb->sb == NULL || bhs == NULL) {
+		LOG_TRACE_STR("osb == NULL || osb->sb == NULL || bhs == NULL "
+			      "|| num == NULL");
+		status = -EINVAL;
+		LOG_ERROR_STATUS(status);
+		goto bail;
+	}
+
+	if ((flags & OCFS_BH_COND_CACHED) && 
+	    (off >= osb->vol_layout.bitmap_off))
+			flags |= OCFS_BH_CACHED;
+
+	if (OCFS_NONCACHED(osb, off)) {
+		if (flags & OCFS_BH_CACHED)
+			LOG_TRACE_STR("hey bozo you are trying to write "
+				      "a system thingy cached!");
+		flags &= ~OCFS_BH_CACHED;
+	}
+
+	sb = osb->sb;
+	dev = OCFS_GET_BLOCKDEV(sb);
+	blocknum = off >> sb->s_blocksize_bits;
+
+	nr = (len + 511) >> 9;
+	if (nr == 0) {
+		LOG_TRACE_STR("No buffers will be read!!!");
+		LOG_TRACE_ARGS("Len=%u Off=%u.%u numbuffers=%u "
+			       "blocknum=%u.%u\n", len, HI (off), LO (off), 
+			       nr, HI (blocknum), LO (blocknum));
+		status = 0;
+		goto bail;
+	}
+
+	for (i = 0 ; i < nr ; i++) {
+		if (bhs[i] == NULL) {
+			bhs[i] = getblk (dev, blocknum++, sb->s_blocksize);
+			if (bhs[i] == NULL) {
+				LOG_TRACE_STR("bh == NULL");
+				status = -EIO;
+				LOG_ERROR_STATUS(status);
+				goto bail;
+			}
+		}
+		bh = bhs[i];
+		ignore_cache = 0;
+
+		/* Lock everyone else out of this bh */
+		OCFS_BH_GET_DATA_READ(bh);
+
+		if (flags & OCFS_BH_CACHED && inode && 
+		    !TEST_BH_SEQNUM(inode, bh)) {
+#ifdef VERBOSE_BH_SEQNUM_TRACE
+			LOG_TRACE_ARGS("(read) bh (%u) seqnum (%u) does not "
+				       "match inode (%u)\n", bh->b_blocknr, 
+				       (bh->b_state & STATE_BIT_MASK) >> 19,
+				       atomic_read(GET_INODE_CLEAN_SEQ(inode)));
+#endif
+			ignore_cache = 1;
+		}
+
+		if ((flags & OCFS_BH_CACHED) && (!buffer_uptodate(bh)))
+			ignore_cache = 1;
+
+		if (buffer_jbd(bh)) {
+#ifdef VERBOSE_BH_JBD_TRACE
+			if (!(flags & OCFS_BH_CACHED) || ignore_cache)
+				LOG_TRACE_ARGS("trying to sync read a jbd "
+					       "managed bh (blocknr = %u)\n",
+					       bh->b_blocknr);
+#endif
+			continue;
+		}
+
+		if (!(flags & OCFS_BH_CACHED) || ignore_cache) {
+			if (buffer_dirty(bh)) {
+				/* This should probably be a BUG, or
+				 * at least return an error. */
+				LOG_TRACE_ARGS("asking me to sync read a "
+					      "dirty buffer! (blocknr = %u)\n",
+					      bh->b_blocknr);
+				continue;
+			}
+
+			LOCK_BUFFER_STR(bh);
+			VERBOSE_LOCK_BUFFER_STR(bh);
+			lock_buffer(bh);
+#ifdef LINUX_2_5
+			clear_buffer_uptodate(bh);
+#else
+			mark_buffer_uptodate(bh, false);
+#endif
+			bh->b_end_io = ocfs_end_buffer_io_sync;
+			submit_bh(READ, bh);
+			continue;
+		}
+	}
+
+	status = 0;
+
+	for (i = (nr-1); i >= 0; i--) {
+		bh = bhs[i];
+
+		wait_on_buffer(bh);
+
+		if (inode)
+			SET_BH_SEQNUM(inode, bh);
+		else
+			CLEAR_BH_SEQNUM(bh);
+
+		OCFS_BH_PUT_DATA(bh);
+	}
+	LOG_TRACE_ARGS("off=(%u.%u), len=(%u.%u), cached=%s\n", HILO(off), HILO(len), 
+		       (!(flags & OCFS_BH_CACHED) || ignore_cache) ? "no" : "yes");
+
+bail:
+
+#ifdef OCFS_DBG_TIMING
+	IO_FUNC_TIMING_PRINT("ocfs_read_bhs", status);
+#endif
+
+	LOG_EXIT_STATUS(status);
+	return status;
+}



More information about the Ocfs2-commits mailing list