[Ocfs2-commits] zab commits r2631 - in branches/locking-changes: . Documentation Documentation/filesystems fs/ocfs2

svn-commits at oss.oracle.com svn-commits at oss.oracle.com
Mon Oct 3 19:21:13 CDT 2005


Author: zab
Date: 2005-10-03 19:21:10 -0500 (Mon, 03 Oct 2005)
New Revision: 2631

Added:
   branches/locking-changes/Documentation/
   branches/locking-changes/Documentation/filesystems/
   branches/locking-changes/Documentation/filesystems/ocfs2.txt
Modified:
   branches/locking-changes/fs/ocfs2/aops.c
   branches/locking-changes/fs/ocfs2/aops.h
   branches/locking-changes/fs/ocfs2/file.c
   branches/locking-changes/fs/ocfs2/mmap.c
Log:
Move locking around to avoid file io -> nopage -> readpage deadlocking

o push locking into readpage and take it out of file read and nopage
o push locking into prepare_write and take it out of file write
o take a new file read/write serializing lock
o release rw lock in dio->end_io so pending o_direct is safe wrt truncate
o sendfile relies on readpage locking, just use generic method
o add a little (incomplete) doc that describes lock ordering



Added: branches/locking-changes/Documentation/filesystems/ocfs2.txt
===================================================================
--- branches/locking-changes/Documentation/filesystems/ocfs2.txt	2005-10-03 23:13:24 UTC (rev 2630)
+++ branches/locking-changes/Documentation/filesystems/ocfs2.txt	2005-10-04 00:21:10 UTC (rev 2631)
@@ -0,0 +1,121 @@
+
+For now this just documents locking ordering.  The intent is to have a 
+dense enough markup that one can visualize an entire path in a reasonably
+sized terminal.  So:
+
+ (  - lock
+ )  - unlock
+ () - lock and unlock without anything interesting in between
+ +  - descending into another function
+
+worst case buffered file write (extending, buf from mmaped ocfs2)
++ ocfs2_file_aio_write
+  ( i_sem
+  ( rw_lock
+  ( meta_lock
+  + ocfs2_extend_allocation
+    () ip_alloc_sem
+  ) meta_lock
+  + generic_file_aio_write_nolock
+    + ocfs2_prepare_write
+      ( meta_lock
+      ( ip_alloc_sem
+      ) ip_alloc_sem
+      ) meta_lock
+    + ocfs2_nopage
+      + filemap_nopage
+        + ocfs2_readpage
+          ( meta_lock
+          ( ip_alloc_sem
+          ( data_lock
+          ) data_lock
+          ) ip_alloc_sem
+          ) meta_lock
+    + ocfs2_commit_write
+      ( meta_lock
+      ( data_lock
+      ) data_lock
+      ) meta_lock
+  ) rw_lock
+  ) i_sem
+
+O_DIRECT file write:
++ ocfs2_file_aio_write
+  ( i_sem
+  ( rw_lock
+  () meta_lock
+  + __blkdev_direct_IO
+    ( i_alloc_sem
+    + ocfs2_direct_io_get_blocks
+      ( meta_lock
+      ( ip_alloc_sem
+      ) ip_alloc_sem
+      ) meta_lock
+  ) i_sem
++ dio_complete
+    ) i_alloc_sem
+  + ocfs2_dio_end_io
+    ) rw_lock
+
+buffered file read (nopage when buf is mmaped):
++ ocfs2_file_aio_read
+  + generic_file_aio_read
+    + ocfs2_readpage
+      ( meta_lock
+      ( ip_alloc_sem
+      ( data_lock
+      ) data_lock
+      ) ip_alloc_sem
+      ) meta_lock
+    + ocfs2_nopage
+      + filemap_nopage
+        + ocfs2_readpage
+          ( meta_lock
+          ( ip_alloc_sem
+          ( data_lock
+          ) data_lock
+          ) ip_alloc_sem
+          ) meta_lock
+
+O_DIRECT file read:
++ ocfs2_file_aio_read
+  + __blkdev_direct_IO
+    () i_sem
+    ( i_alloc_sem
+    + ocfs2_direct_io_get_blocks
+      ( meta_lock
+      ( ip_alloc_sem
+      ) ip_alloc_sem
+      ) meta_lock
++ dio_complete
+    ) i_alloc_sem
+  + ocfs2_dio_end_io
+    ) rw_lock
+
+truncate:
++ do_truncate
+  ( i_sem
+  + notify_change
+    ( i_alloc_sem
+    + ocfs2_setattr
+      ( meta_lock
+      + ocfs2_truncate_file
+        () data_lock
+      ) meta_lock
+    ) i_alloc_sem
+  ) i_sem
+
+readpage: (via sendfile, sys_readahead, fault->nopage)
++ ocfs2_readpage
+      ( meta_lock
+      ( ip_alloc_sem
+      ( data_lock
+      ) data_lock
+      ) ip_alloc_sem
+      ) meta_lock
+
+.. make this prettier ..
+
+-- Locks and what they cover --
+
+

Modified: branches/locking-changes/fs/ocfs2/aops.c
===================================================================
--- branches/locking-changes/fs/ocfs2/aops.c	2005-10-03 23:13:24 UTC (rev 2630)
+++ branches/locking-changes/fs/ocfs2/aops.c	2005-10-04 00:21:10 UTC (rev 2631)
@@ -31,11 +31,13 @@
 #include "ocfs2.h"
 
 #include "alloc.h"
+#include "aops.h"
 #include "dlmglue.h"
 #include "extent_map.h"
 #include "file.h"
 #include "inode.h"
 #include "journal.h"
+#include "super.h"
 #include "symlink.h"
 
 #include "buffer_head_io.h"
@@ -190,14 +192,56 @@
 
 static int ocfs2_readpage(struct file *file, struct page *page)
 {
+	struct inode *inode = page->mapping->host;
+	loff_t start = (loff_t)page->index << PAGE_CACHE_SHIFT;
 	int ret;
 
 	mlog_entry("(0x%p, %lu)\n", file, (page ? page->index : 0));
 
+	ret = ocfs2_meta_lock(inode, NULL, NULL, 0);
+	if (ret < 0) {
+		mlog_errno(ret);
+		goto out;
+	}
+
+	down_read(&OCFS2_I(inode)->ip_alloc_sem);
+
+	/*
+	 * i_size might have just been updated as we grabed the meta lock.  We
+	 * might now be discovering a truncate that hit on another node.
+	 * block_read_full_page->get_block freaks out if it is asked to read
+	 * beyond the end of a file, so we check here.  Callers
+	 * (generic_file_read, fault->nopage) are clever enough to check i_size
+	 * and notice that the page they just read isn't needed.
+	 *
+	 * XXX sys_readahead() seems to get that wrong?
+	 */
+	if (i_size_read(inode) >= start) {
+		char *addr = kmap(page);
+		memset(addr, 0, PAGE_SIZE);
+		flush_dcache_page(page);
+		kunmap(page);
+		SetPageUptodate(page);
+		unlock_page(page);
+		ret = 0;
+		goto out_alloc;
+	}
+
+	ret = ocfs2_data_lock(inode, 0);
+	if (ret < 0) {
+		mlog_errno(ret);
+		goto out_alloc;
+	}
+
 	ret = block_read_full_page(page, ocfs2_get_block);
 
+
+	ocfs2_data_unlock(inode, 0);
+out_alloc:
+	up_read(&OCFS2_I(inode)->ip_alloc_sem);
+	ocfs2_meta_unlock(inode, 0);
+out:
 	mlog_exit(ret);
-
 	return ret;
 }
 
@@ -218,17 +262,34 @@
 	return ret;
 }
 
+/*
+ * ocfs2_prepare_write() can be an outer-most ocfs2 call when it is called
+ * from loopback.  It must be able to perform its own locking around
+ * ocfs2_get_block().
+ */
 int ocfs2_prepare_write(struct file *file, struct page *page,
 			unsigned from, unsigned to)
 {
+	struct inode *inode = page->mapping->host;
 	int ret;
 
 	mlog_entry("(0x%p, 0x%p, %u, %u)\n", file, page, from, to);
 
+	ret = ocfs2_meta_lock(inode, NULL, NULL, 0);
+	if (ret < 0) {
+		mlog_errno(ret);
+		goto out;
+	}
+
+	down_read(&OCFS2_I(inode)->ip_alloc_sem);
+
 	ret = block_prepare_write(page, from, to, ocfs2_get_block);
 
+	up_read(&OCFS2_I(inode)->ip_alloc_sem);
+
+	ocfs2_meta_unlock(inode, 0);
+out:
 	mlog_exit(ret);
-
 	return ret;
 }
 
@@ -518,6 +579,25 @@
 	return ret;
 }
 
+/* 
+ * ocfs2_dio_end_io is called by the dio core when a dio is finished.  We're
+ * particularly interested in the aio/dio case.  Like the core uses
+ * i_alloc_sem, we use the rw_lock DLM lock to protect io on one node from
+ * truncation on another.
+ */
+static void ocfs2_dio_end_io(struct kiocb *iocb,
+			     loff_t offset,
+			     ssize_t bytes,
+			     void *private)
+{
+	struct inode *inode = iocb->ki_filp->f_dentry->d_inode;
+
+	/* this io's submitter should not have unlocked this before we could */
+	BUG_ON(!ocfs2_iocb_is_rw_locked(iocb));
+	ocfs2_iocb_clear_rw_locked(iocb);
+	ocfs2_rw_unlock(inode, 0);
+}
+
 static ssize_t ocfs2_direct_IO(int rw,
 			       struct kiocb *iocb,
 			       const struct iovec *iov,
@@ -531,7 +611,7 @@
 	mlog_entry_void();
 	ret = blockdev_direct_IO(rw, iocb, inode, inode->i_sb->s_bdev, iov,
 				 offset, nr_segs, ocfs2_direct_IO_get_blocks,
-				 NULL);
+				 ocfs2_dio_end_io);
 	mlog_exit(ret);
 	return ret;
 }

Modified: branches/locking-changes/fs/ocfs2/aops.h
===================================================================
--- branches/locking-changes/fs/ocfs2/aops.h	2005-10-03 23:13:24 UTC (rev 2630)
+++ branches/locking-changes/fs/ocfs2/aops.h	2005-10-04 00:21:10 UTC (rev 2631)
@@ -30,4 +30,12 @@
 						  unsigned from,
 						  unsigned to);
 
+/* all ocfs2_dio_end_io()'s fault */
+#define ocfs2_iocb_is_rw_locked(iocb) \
+	test_bit(0, (unsigned long *)&iocb->private)
+#define ocfs2_iocb_set_rw_locked(iocb) \
+	set_bit(0, (unsigned long *)&iocb->private)
+#define ocfs2_iocb_clear_rw_locked(iocb) \
+	clear_bit(0, (unsigned long *)&iocb->private)
+
 #endif /* OCFS2_FILE_H */

Modified: branches/locking-changes/fs/ocfs2/file.c
===================================================================
--- branches/locking-changes/fs/ocfs2/file.c	2005-10-03 23:13:24 UTC (rev 2630)
+++ branches/locking-changes/fs/ocfs2/file.c	2005-10-04 00:21:10 UTC (rev 2631)
@@ -875,13 +875,14 @@
 {
 	struct iovec local_iov = { .iov_base = (void __user *)buf,
 				   .iov_len = count };
-	int ret, level;
+	int ret, rw_level = -1, meta_level = -1;
 	u32 clusters;
-	ocfs2_super *osb = NULL;
 	struct file *filp = iocb->ki_filp;
 	struct inode *inode = filp->f_dentry->d_inode;
-	int do_direct = 0;
 	loff_t newsize, saved_pos;
+#ifdef OCFS2_ORACORE_WORKAROUNDS
+	ocfs2_super *osb = OCFS2_SB(inode->i_sb);
+#endif
 
 	mlog_entry("(0x%p, 0x%p, %u, '%.*s')\n", filp, buf,
 		   (unsigned int)count,
@@ -889,29 +890,46 @@
 		   filp->f_dentry->d_name.name);
 
 	/* happy write of zero bytes */
-	if (count == 0) {
-		ret = 0;
-		goto out;
-	}
+	if (count == 0)
+		return 0;
 
 	if (!inode) {
 		mlog(0, "bad inode\n");
-		ret = -EIO;
-		goto out;
+		return -EIO;
 	}
 
-	osb = OCFS2_SB(inode->i_sb);
+#ifdef OCFS2_ORACORE_WORKAROUNDS
+	/* ugh, work around some applications which open everything O_DIRECT +
+	 * O_APPEND and really don't mean to use O_DIRECT. */
+	if (osb->s_mount_opt & OCFS2_MOUNT_COMPAT_OCFS &&
+	    (filp->f_flags & O_APPEND) && (filp->f_flags & O_DIRECT)) 
+		filp->f_flags &= ~O_DIRECT;
+#endif
 
+
 	down(&inode->i_sem);
 
-	/* this ginormous block is in here because it has so many inputs
-	 * and outputs from this function.. */
-	level = !!(filp->f_flags & O_APPEND);
+	/* concurrent O_DIRECT writes are allowed */
+	rw_level = (filp->f_flags & O_DIRECT) ? 0 : 1;
+	ret = ocfs2_rw_lock(inode, rw_level);
+	if (ret < 0) {
+		rw_level = -1;
+		mlog_errno(ret);
+		goto out;
+	}
+
+	/* 
+	 * We sample i_size under a read level meta lock to see if our write
+	 * is extending the file, if it is we back off and get a write level
+	 * meta lock.
+	 */
+	meta_level = (filp->f_flags & O_APPEND) ? 1 : 0;
 	for(;;) {
-		ret = ocfs2_meta_lock(inode, NULL, NULL, level);
+		ret = ocfs2_meta_lock(inode, NULL, NULL, meta_level);
 		if (ret < 0) {
+			meta_level = -1;
 			mlog_errno(ret);
-			goto out_i_sem;
+			goto out;
 		}
 
 		/* work on a copy of ppos until we're sure that we won't have
@@ -919,14 +937,6 @@
 		if (filp->f_flags & O_APPEND) {
 			saved_pos = i_size_read(inode);
 			mlog(0, "O_APPEND: inode->i_size=%llu\n", saved_pos);
-#ifdef OCFS2_ORACORE_WORKAROUNDS
-			if (osb->s_mount_opt & OCFS2_MOUNT_COMPAT_OCFS) {
-				/* ugh, work around some applications which
-				 * open everything O_DIRECT + O_APPEND and
-				 * really don't mean to use O_DIRECT. */
-				filp->f_flags &= ~O_DIRECT;
-			}
-#endif
 		} else {
 			saved_pos = iocb->ki_pos;
 		}
@@ -940,9 +950,9 @@
 		if (newsize <= i_size_read(inode))
 			break;
 
-		if (level == 0) {
-			ocfs2_meta_unlock(inode, level);
-			level = 1;
+		if (meta_level == 0) {
+			ocfs2_meta_unlock(inode, meta_level);
+			meta_level = 1;
 			continue;
 		}
 
@@ -965,7 +975,7 @@
 		if (ret < 0) {
 			if (ret != -ENOSPC)
 				mlog_errno(ret);
-			goto out_meta_unlock;
+			goto out;
 		}
 
 		/* Fill any holes which would've been created by this
@@ -974,53 +984,31 @@
 		ret = ocfs2_zero_extend(inode, (u64) newsize - count);
 		if (ret < 0) {
 			mlog_errno(ret);
-			goto out_meta_unlock;
+			goto out;
 		}
 		break;
 	}
 
-	/* we've got whatever cluster lock is appropriate now, so we
-	 * can stuff *ppos back. */
+	/* ok, we're done with i_size and alloc work */
 	iocb->ki_pos = saved_pos;
+	ocfs2_meta_unlock(inode, meta_level);
+	meta_level = -1;
 
-	if (filp->f_flags & O_DIRECT) {
-#ifdef OCFS2_ORACORE_WORKAROUNDS
-		if (osb->s_mount_opt & OCFS2_MOUNT_COMPAT_OCFS) {
-			int sector_size = 1 << osb->s_sectsize_bits;
+	/* communicate with ocfs2_dio_end_io */
+	ocfs2_iocb_set_rw_locked(iocb);
 
-			if ((saved_pos & (sector_size - 1)) ||
-			    (count & (sector_size - 1)) ||
-			    ((unsigned long)buf & (sector_size - 1))) {
-				do_direct = 0;
-				filp->f_flags |= O_SYNC;
-			} else {
-				do_direct = 1;
-			}
-		} else
-#endif
-			do_direct = 1;
-
-		mlog(0, "O_DIRECT\n");
-	}
-
-	if (!do_direct) {
-		ret = ocfs2_data_lock(inode, 1);
-		if (ret < 0) {
-			mlog_errno(ret);
-			goto out_meta_unlock;
-		}
-	}
-
-	down_read(&OCFS2_I(inode)->ip_alloc_sem);
-
 #ifdef OCFS2_ORACORE_WORKAROUNDS
-	if (osb->s_mount_opt & OCFS2_MOUNT_COMPAT_OCFS) {
+	if (osb->s_mount_opt & OCFS2_MOUNT_COMPAT_OCFS &&
+	    filp->f_flags & O_DIRECT) {
 		unsigned int saved_flags = filp->f_flags;
+		int sector_size = 1 << osb->s_sectsize_bits;
 
-		if (do_direct)
-			filp->f_flags |= O_DIRECT;
-		else
+		if ((saved_pos & (sector_size - 1)) ||
+		    (count & (sector_size - 1)) ||
+		    ((unsigned long)buf & (sector_size - 1))) {
+			filp->f_flags |= O_SYNC;
 			filp->f_flags &= ~O_DIRECT;
+		}
 
 		ret = generic_file_aio_write_nolock(iocb, &local_iov, 1,
 						    &iocb->ki_pos);
@@ -1031,17 +1019,29 @@
 		ret = generic_file_aio_write_nolock(iocb, &local_iov, 1,
 						    &iocb->ki_pos);
 
-	up_read(&OCFS2_I(inode)->ip_alloc_sem);
+	/* buffered aio wouldn't have proper lock coverage today */
+	BUG_ON(ret == -EIOCBQUEUED && !(filp->f_flags & O_DIRECT));
 
-	if (!do_direct)
-		ocfs2_data_unlock(inode, 1);
+	/* 
+	 * deep in g_f_a_w_n()->ocfs2_direct_IO we pass in a ocfs2_dio_end_io
+	 * function pointer which is called when o_direct io completes so that
+	 * it can unlock our rw lock.  (it's the clustered equivalent of
+	 * i_alloc_sem; protects truncate from racing with pending ios).
+	 * Unfortunately there are error cases which call end_io and others
+	 * that don't.  so we don't have to unlock the rw_lock if either an
+	 * async dio is going to do it in the future or an end_io after an
+	 * error has already done it.
+	 */
+	if (ret == -EIOCBQUEUED || !ocfs2_iocb_is_rw_locked(iocb))
+		rw_level = -1;
 
-out_meta_unlock:
-	ocfs2_meta_unlock(inode, level);
-out_i_sem:
+out:
+	if (meta_level != -1)
+		ocfs2_meta_unlock(inode, meta_level);
+	if (rw_level != -1) 
+		ocfs2_rw_unlock(inode, rw_level);
 	up(&inode->i_sem);
 
-out:
 	mlog_exit(ret);
 	return ret;
 }
@@ -1051,10 +1051,12 @@
 				   size_t count,
 				   loff_t pos)
 {
-	int ret = 0;
-	ocfs2_super *osb = NULL;
+	int ret = 0, rw_level = -1;
 	struct file *filp = iocb->ki_filp;
 	struct inode *inode = filp->f_dentry->d_inode;
+#ifdef OCFS2_ORACORE_WORKAROUNDS
+	ocfs2_super *osb = OCFS2_SB(inode->i_sb);
+#endif
 
 	mlog_entry("(0x%p, 0x%p, %u, '%.*s')\n", filp, buf,
 		   (unsigned int)count,
@@ -1067,8 +1069,6 @@
 		goto bail;
 	}
 
-	osb = OCFS2_SB(inode->i_sb);
-
 #ifdef OCFS2_ORACORE_WORKAROUNDS
 	if (osb->s_mount_opt & OCFS2_MOUNT_COMPAT_OCFS) {
 		if (filp->f_flags & O_DIRECT) {
@@ -1084,86 +1084,40 @@
 	}
 #endif
 
-	ret = ocfs2_meta_lock(inode, NULL, NULL, 0);
-	if (ret < 0) {
-		mlog_errno(ret);
-		goto bail;
-	}
-
-	if (!(filp->f_flags & O_DIRECT)) {
-		ret = ocfs2_data_lock(inode, 0);
+	/* 
+	 * buffered reads protect themselves in ->readpage().  O_DIRECT reads
+	 * need locks to protect pending reads from racing with truncate.
+	 */
+	if (filp->f_flags & O_DIRECT) {
+		ret = ocfs2_rw_lock(inode, 0);
 		if (ret < 0) {
 			mlog_errno(ret);
-			goto bail_unlock_meta;
+			goto bail;
 		}
+		rw_level = 0;
+		/* communicate with ocfs2_dio_end_io */
+		ocfs2_iocb_set_rw_locked(iocb);
 	}
 
-	down_read(&OCFS2_I(inode)->ip_alloc_sem);
-
 	ret = generic_file_aio_read(iocb, buf, count, iocb->ki_pos);
-
-	up_read(&OCFS2_I(inode)->ip_alloc_sem);
-
 	if (ret == -EINVAL)
 		mlog(ML_ERROR, "generic_file_aio_read returned -EINVAL\n");
 
-	if (!(filp->f_flags & O_DIRECT))
-		ocfs2_data_unlock(inode, 0);
-bail_unlock_meta:
-	ocfs2_meta_unlock(inode, 0);
+	/* buffered aio wouldn't have proper lock coverage today */
+	BUG_ON(ret == -EIOCBQUEUED && !(filp->f_flags & O_DIRECT));
 
+	/* see ocfs2_file_aio_write */
+	if (ret == -EIOCBQUEUED || !ocfs2_iocb_is_rw_locked(iocb))
+		rw_level = -1;
+
 bail:
+	if (rw_level != -1) 
+		ocfs2_rw_unlock(inode, rw_level);
 	mlog_exit(ret);
 
 	return ret;
 }
 
-static ssize_t ocfs2_file_sendfile(struct file *in_file,
-				   loff_t *ppos,
-				   size_t count,
-				   read_actor_t actor,
-				   void *target)
-{
-	int ret;
-	struct inode *inode = in_file->f_mapping->host;
-
-	mlog_entry("inode %"MLFu64", ppos %lld, count = %u\n",
-		   OCFS2_I(inode)->ip_blkno, (long long) *ppos,
-		   (unsigned int) count);
-
-	/* Obviously, there is no user buffer to worry about here --
-	 * this simplifies locking, so no need to walk vmas a la
-	 * read/write. We take a simple set of cluster locks against
-	 * the inode and call generic_file_sendfile. */
-	ret = ocfs2_meta_lock(inode, NULL, NULL, 0);
-	if (ret < 0) {
-		mlog_errno(ret);
-		goto bail;
-	}
-
-	ret = ocfs2_data_lock(inode, 0);
-	if (ret < 0) {
-		mlog_errno(ret);
-		goto bail_unlock_meta;
-	}
-
-	down_read(&OCFS2_I(inode)->ip_alloc_sem);
-
-	ret = generic_file_sendfile(in_file, ppos, count, actor, target);
-	if (ret < 0)
-		mlog_errno(ret);
-
-	up_read(&OCFS2_I(inode)->ip_alloc_sem);
-
-	ocfs2_data_unlock(inode, 0);
-bail_unlock_meta:
-	ocfs2_meta_unlock(inode, 0);
-
-bail:
-	mlog_exit(ret);
-	return ret;
-}
-
 struct inode_operations ocfs2_file_iops = {
 	.setattr	= ocfs2_setattr,
 	.getattr	= ocfs2_getattr,
@@ -1177,7 +1131,7 @@
 struct file_operations ocfs2_fops = {
 	.read		= do_sync_read,
 	.write		= do_sync_write,
-	.sendfile	= ocfs2_file_sendfile,
+	.sendfile	= generic_file_sendfile,
 	.mmap		= ocfs2_mmap,
 	.fsync		= ocfs2_sync_file,
 	.release	= ocfs2_file_release,

Modified: branches/locking-changes/fs/ocfs2/mmap.c
===================================================================
--- branches/locking-changes/fs/ocfs2/mmap.c	2005-10-03 23:13:24 UTC (rev 2630)
+++ branches/locking-changes/fs/ocfs2/mmap.c	2005-10-04 00:21:10 UTC (rev 2631)
@@ -47,16 +47,12 @@
 				 int *type)
 {
 	struct inode *inode = area->vm_file->f_dentry->d_inode;
-	struct page *page;
+	struct page *page = NOPAGE_SIGBUS;
 	sigset_t blocked, oldset;
 	int ret;
 
 	mlog_entry("(inode %lu, address %lu)\n", inode->i_ino, address);
 
-	/* For lack of a better error... Unfortunately returns
-	 * from nopage aren't very expressive right now. */
-	page = NOPAGE_SIGBUS;
-
 	/* The best way to deal with signals in this path is
 	 * to block them upfront, rather than allowing the
 	 * locking paths to return -ERESTARTSYS. */
@@ -67,41 +63,15 @@
 	ret = sigprocmask(SIG_BLOCK, &blocked, &oldset);
 	if (ret < 0) {
 		mlog_errno(ret);
-		goto bail;
+		goto out;
 	}
 
-	/* Since we don't allow shared writable, we need only
-	 * worry about read locking here. */
-	ret = ocfs2_meta_lock(inode, NULL, NULL, 0);
-	if (ret < 0) {
-		mlog_errno(ret);
-
-		if (ret == -ENOMEM)
-			page = NOPAGE_OOM;
-		goto bail_setmask;
-	}
-
-	ret = ocfs2_data_lock(inode, 0);
-	if (ret < 0) {
-		mlog_errno(ret);
-
-		if (ret == -ENOMEM)
-			page = NOPAGE_OOM;
-		goto bail_unlock;
-	}
-
 	page = filemap_nopage(area, address, type);
 
-	ocfs2_data_unlock(inode, 0);
-
-bail_unlock:
-	ocfs2_meta_unlock(inode, 0);
-
-bail_setmask:
 	ret = sigprocmask(SIG_SETMASK, &oldset, NULL);
 	if (ret < 0)
 		mlog_errno(ret);
-bail:
+out:
 	mlog_exit_ptr(page);
 	return page;
 }



More information about the Ocfs2-commits mailing list