[Ocfs2-commits] jlbec commits r2303 - in branches/alloc_inode: . fs/ocfs2 fs/ocfs2/cluster fs/ocfs2/dlm

svn-commits at oss.oracle.com svn-commits at oss.oracle.com
Fri May 20 22:32:26 CDT 2005


Author: jlbec
Date: 2005-05-20 22:32:25 -0500 (Fri, 20 May 2005)
New Revision: 2303

Modified:
   branches/alloc_inode/README
   branches/alloc_inode/configure.in
   branches/alloc_inode/fs/ocfs2/Makefile
   branches/alloc_inode/fs/ocfs2/alloc.c
   branches/alloc_inode/fs/ocfs2/alloc.h
   branches/alloc_inode/fs/ocfs2/cluster/heartbeat.c
   branches/alloc_inode/fs/ocfs2/cluster/heartbeat.h
   branches/alloc_inode/fs/ocfs2/cluster/tcp.c
   branches/alloc_inode/fs/ocfs2/dcache.c
   branches/alloc_inode/fs/ocfs2/dlm/dlmapi.h
   branches/alloc_inode/fs/ocfs2/dlm/dlmdebug.c
   branches/alloc_inode/fs/ocfs2/dlm/dlmunlock.c
   branches/alloc_inode/fs/ocfs2/dlmglue.c
   branches/alloc_inode/fs/ocfs2/dlmglue.h
   branches/alloc_inode/fs/ocfs2/file.c
   branches/alloc_inode/fs/ocfs2/heartbeat.c
   branches/alloc_inode/fs/ocfs2/heartbeat.h
   branches/alloc_inode/fs/ocfs2/inode.c
   branches/alloc_inode/fs/ocfs2/journal.c
   branches/alloc_inode/fs/ocfs2/mmap.c
   branches/alloc_inode/fs/ocfs2/namei.c
   branches/alloc_inode/fs/ocfs2/ocfs.h
   branches/alloc_inode/fs/ocfs2/ocfs2_fs.h
   branches/alloc_inode/fs/ocfs2/super.c
Log:

Merged 2267:2302 from trunk:
	- [2268] Proper formats for loff_t.
	- [2271] Bump versions.
	- [2272] Update README.
	- [2274] Remove workaround for broken applications.
	- [2275] Turn #warnings into comments.
	- [2279] Factor out oracore workarounds.
	- [2280] Fix oops on failed mount.
	- [2281] Remove incorrect comment.
	- [2282] Fix root inode refcount.
	- [2283] Fail mount instead of BUG() when on-disk clustersize
		 is bad.
	- [2284] Barrier support.
	- [2285] Fix LVB alignment.
	- [2287] Whitespace.
	- [2288] Fix net handler comparisons.
	- [2289] Remove unused code.
	- [2290] Better DLM error output.
	- [2292] Subsecond timestamps.
	- [2293] dlm_lock leaks.
	- [2294] Bump versions.
	- [2295] Truncate log coalescing.
	- [2300] Remove bugs assert.
	- [2301] Pack ocfs2_dir_entry.
	- [2302] Automatic flushing of the truncate log.



Modified: branches/alloc_inode/README
===================================================================
--- branches/alloc_inode/README	2005-05-20 22:02:32 UTC (rev 2302)
+++ branches/alloc_inode/README	2005-05-21 03:32:25 UTC (rev 2303)
@@ -1,92 +1,31 @@
-        OCFS Version 2 BETA 10
+OCFS2 filesystem
+==================
+OCFS2 is a shared disk cluster file system with many similarities to
+ext3. You'll want to install the tools in order to at least get
+"mount.ocfs2".
 
-*** WARNING WARNING WARNING ***
-This is BETA software. It should absolutely NOT be run on production
-systems.  If you are looking to run OCFS on a production system, check
-out OCFS version 1.
+Project web page:    http://oss.oracle.com/projects/ocfs2
+Tools web page:      http://oss.oracle.com/projects/ocfs2-tools
+OCFS2 mailing lists: http://oss.oracle.com/projects/ocfs2/mailman/
 
-WHAT IS OCFS2?
- OCFS2 is the latest version of the Oracle Cluster File System
- software. Where OCFS1 was designed specifically "for Oracle Database
- files", OCFS2 supports a shared ORACLE_HOME installation. New features 
- include:
+All code copyright 2005 Oracle except when otherwise noted.
 
- * Shared ORACLE_HOME
- * Improved performance of meta data operations (space allocation, 
-   locking, etc).
- * Improved meta data caching.
- * Improved data caching (for files such as oracle binaries, libraries, etc)
- * Network based DLM is used by default.
- * Improved journaling / node recovery - we now use the Linux Kernel "JBD" 
-   subsystem
- * Keep the same performance for Oracle data files as OCFS1.
- * CDSL for node specific files
- * POSIX compliance
+CREDITS:
+Lots of code taken from ext3 and other projects.
 
-INSTALLING OCFS2
- Step 1: Download and install OCFS2 and OCFS2-Tools
+Authors in alphabetical order:
+Joel Becker   <joel.becker at oracle.com>
+Zach Brown    <zach.brown at oracle.com>
+Mark Fasheh   <mark.fasheh at oracle.com>
+Kurt Hackel   <kurt.hackel at oracle.com>
+Sunil Mushran <sunil.mushran at oracle.com>
+Manish Singh  <manish.singh at oracle.com>
 
- To install you need to download the OCFS2 Beta RPMS for your system
- from the following location:
+Mount options
+=============
 
-    http://oss.oracle.com/projects/ocfs2/files/
+OCFS2 supports the following mount options:
+(*) == default
 
- You will need the module RPM for your kernel version and the
- ocfs2-support rpm for your distribution.
-
- Also, download the latest OCFS2-Tools rpm (version 0.99.4) from the
- following location:
-
-    http://oss.oracle.com/projects/ocfs2-tools/files/
-
- Install the packages using your package manager. The OCFS2 packages
- are designed to co-exist with an existing OCFS1 installation.
-
- Step 2: Configure a cluster
-
- The easiest way to do this is to use the GUI cluster configuration
- utility in ocfs2console.
-
- If you wish to do this by hand, see the file README.O2CB in the
- ocfs2-tools distribution.
-
- Step 3: Create a file system
-
- The example below assumes you want an OCFS2 file system on
- "/dev/sdb1" and are mounting it at "/ocfs2". Replace those values with
- your own.
-
- Creating a new OCFS2 file system is as easy as running the
- "mkfs.ocfs2" program. As a default it picks a block size of 4K and a
- cluster size of 4K and a file system which can contain up to 4
- nodes. You can specify your own options to override the
- defaults (please see the man page). If you're planning to run Oracle
- in a shared home configuration, we recommend you use a cluster size
- between 4K and 16K.
-
-    $ mkfs.ocfs2 /dev/sdb1
-
- Step 4: Mount the file system
-
-    $ mount -t ocfs2 /dev/sdb1 /ocfs2
-
-REPORTING BUGS
- To report OCFS2 bugs, please use bugzilla:
-
-    http://oss.oracle.com/bugzilla/buglist.cgi?product=OCFS2
-
- Please try to be as verbose in bug reports as possible.
-
-KNOWN ISSUES
- People upgrading from previous versions should upgrade all nodes before
- remounting the file system as some incompatible dlm fixes have gone
- in.
-
- Please see bugzilla for an up to date list of issues.
-
-MAILING LISTS
- Please join the OCFS2 mailing lists at: 
-
-    http://oss.oracle.com/projects/ocfs2/mailman/
-
-
+barrier=1		This enables/disables barriers. barrier=0 disables it,
+			barrier=1 enables it.

Modified: branches/alloc_inode/configure.in
===================================================================
--- branches/alloc_inode/configure.in	2005-05-20 22:02:32 UTC (rev 2302)
+++ branches/alloc_inode/configure.in	2005-05-21 03:32:25 UTC (rev 2303)
@@ -9,14 +9,14 @@
 # Adjust these for the software version.
 MAJOR_VERSION=0
 MINOR_VERSION=99
-MICRO_VERSION=8
-EXTRA_VERSION=BETA12
+MICRO_VERSION=9
+EXTRA_VERSION=BETA13
 
 # Adjust this only to bump the RPM packaging version
 RPM_VERSION=1
 
 # Required version of ocfs-tools
-TOOLS_REQUIRED_VERSION=0.99.6
+TOOLS_REQUIRED_VERSION=0.99.8
 
 DIST_VERSION=$MAJOR_VERSION.$MINOR_VERSION.$MICRO_VERSION
 VERSION=$DIST_VERSION-$EXTRA_VERSION

Modified: branches/alloc_inode/fs/ocfs2/Makefile
===================================================================
--- branches/alloc_inode/fs/ocfs2/Makefile	2005-05-20 22:02:32 UTC (rev 2302)
+++ branches/alloc_inode/fs/ocfs2/Makefile	2005-05-21 03:32:25 UTC (rev 2303)
@@ -21,7 +21,7 @@
 EXTRA_CFLAGS += -DDEBUG
 endif
 
-EXTRA_CFLAGS += -DCATCH_BH_JBD_RACES
+EXTRA_CFLAGS += -DCATCH_BH_JBD_RACES -DOCFS2_ORACORE_WORKAROUNDS
 
 ifdef JOURNAL_ACCESS_WITH_CREDITS
 EXTRA_CFLAGS += -DJOURNAL_ACCESS_WITH_CREDITS

Modified: branches/alloc_inode/fs/ocfs2/alloc.c
===================================================================
--- branches/alloc_inode/fs/ocfs2/alloc.c	2005-05-20 22:02:32 UTC (rev 2302)
+++ branches/alloc_inode/fs/ocfs2/alloc.c	2005-05-21 03:32:25 UTC (rev 2303)
@@ -871,6 +871,22 @@
 	return le16_to_cpu(tl->tl_used) == le16_to_cpu(tl->tl_count);
 }
 
+static int ocfs2_truncate_log_can_coalesce(ocfs2_truncate_log *tl,
+					   unsigned int new_start)
+{
+	unsigned int index = le16_to_cpu(tl->tl_used);
+	unsigned int current_tail;
+
+	/* No records, nothing to coalesce */
+	if (!index)
+		return 0;
+
+	current_tail = le32_to_cpu(tl->tl_recs[index].t_start);
+	current_tail += le32_to_cpu(tl->tl_recs[index].t_clusters);
+
+	return current_tail == new_start;
+}
+
 static int ocfs2_truncate_log_append(ocfs_super *osb,
 				     ocfs_journal_handle *handle,
 				     u64 start_blk,
@@ -919,11 +935,17 @@
 	     "%"MLFu64" (index = %d)\n", num_clusters, start_cluster,
 	     OCFS2_I(tl_inode)->ip_blkno, index);
 
-	/* TODO: Do we bother searching the truncate records for a
-	 * contiguous one and coalesce? */
-	tl->tl_recs[index].t_start = cpu_to_le32(start_cluster);
+	if (ocfs2_truncate_log_can_coalesce(tl, start_cluster)) {
+		/* Coalesce with the most recent record if possible */
+		num_clusters += le32_to_cpu(tl->tl_recs[index].t_clusters);
+		mlog(0, "Coalesce with index %u (start = %u, clusters = %u)\n",
+		     index, le32_to_cpu(tl->tl_recs[index].t_start),
+		     num_clusters);
+	} else {
+		tl->tl_recs[index].t_start = cpu_to_le32(start_cluster);
+		tl->tl_used = cpu_to_le16(index + 1);
+	}
 	tl->tl_recs[index].t_clusters = cpu_to_le32(num_clusters);
-	tl->tl_used = cpu_to_le16(index + 1);
 
 	status = ocfs_journal_dirty(handle, tl_bh);
 	if (status < 0) {
@@ -989,17 +1011,20 @@
 						    le32_to_cpu(rec.t_start));
 		num_clusters = le32_to_cpu(rec.t_clusters);
 
-		mlog(0, "free record %d, start = %u, clusters = %u\n", i,
-		     le32_to_cpu(rec.t_start), num_clusters);
+		/* if start_blk is not set, we ignore the record as
+		 * invalid. */
+		if (start_blk) {
+			mlog(0, "free record %d, start = %u, clusters = %u\n",
+			     i, le32_to_cpu(rec.t_start), num_clusters);
 
-		status = ocfs_free_clusters(handle, data_alloc_inode,
-					    data_alloc_bh, start_blk,
-					    num_clusters);
-		if (status < 0) {
-			mlog_errno(status);
-			goto bail;
+			status = ocfs_free_clusters(handle, data_alloc_inode,
+						    data_alloc_bh, start_blk,
+						    num_clusters);
+			if (status < 0) {
+				mlog_errno(status);
+				goto bail;
+			}
 		}
-
 		i--;
 	}
 
@@ -1009,7 +1034,7 @@
 }
 
 /* Expects you to already be holding tl_inode->i_sem */
-static int ocfs2_flush_truncate_log(ocfs_super *osb)
+static int __ocfs2_flush_truncate_log(ocfs_super *osb)
 {
 	int status;
 	unsigned int num_to_flush;
@@ -1086,6 +1111,47 @@
 	return status;
 }
 
+int ocfs2_flush_truncate_log(ocfs_super *osb)
+{
+	int status;
+	struct inode *tl_inode = osb->osb_tl_inode;
+
+	down(&tl_inode->i_sem);
+	status = __ocfs2_flush_truncate_log(osb);
+	up(&tl_inode->i_sem);
+
+	return status;
+}
+
+static void ocfs2_truncate_log_worker(void *data)
+{
+	int status;
+	ocfs_super *osb = data;
+
+	mlog_entry();
+
+	status = ocfs2_flush_truncate_log(osb);
+	if (status < 0)
+		mlog_errno(status);
+
+	mlog_exit(status);
+}
+
+#define OCFS2_TRUNCATE_LOG_FLUSH_INTERVAL (2 * HZ)
+void ocfs2_schedule_truncate_log_flush(ocfs_super *osb,
+				       int cancel)
+{
+	if (osb->osb_tl_inode) {
+		/* We want to push off log flushes while truncates are
+		 * still running. */
+		if (cancel)
+			cancel_delayed_work(&osb->osb_truncate_log_wq);
+
+		schedule_delayed_work(&osb->osb_truncate_log_wq,
+				      OCFS2_TRUNCATE_LOG_FLUSH_INTERVAL);
+	}
+}
+
 static int ocfs2_get_truncate_log_info(ocfs_super *osb,
 				       int slot_num,
 				       struct inode **tl_inode,
@@ -1214,7 +1280,7 @@
 	down(&tl_inode->i_sem);
 	for(i = 0; i < num_recs; i++) {
 		if (ocfs2_truncate_log_needs_flush(osb)) {
-			status = ocfs2_flush_truncate_log(osb);
+			status = __ocfs2_flush_truncate_log(osb);
 			if (status < 0) {
 				mlog_errno(status);
 				goto bail_up;
@@ -1256,20 +1322,18 @@
 
 	mlog_entry();
 
-	if (!tl_inode)
-		return;
+	if (tl_inode) {
+		cancel_delayed_work(&osb->osb_truncate_log_wq);
+		flush_scheduled_work();
 
-	down(&tl_inode->i_sem);
+		status = ocfs2_flush_truncate_log(osb);
+		if (status < 0)
+			mlog_errno(status);
 
-	status = ocfs2_flush_truncate_log(osb);
-	if (status)
-		mlog_errno(status);
+		brelse(osb->osb_tl_bh);
+		iput(osb->osb_tl_inode);
+	}
 
-	up(&tl_inode->i_sem);
-
-	brelse(osb->osb_tl_bh);
-	iput(osb->osb_tl_inode);
-
 	mlog_exit_void();
 }
 
@@ -1291,8 +1355,9 @@
 	/* ocfs2_truncate_log_shutdown keys on the existence of
 	 * osb->osb_tl_inode so we don't set any of the osb variables
 	 * until we're sure all is well. */
+	INIT_WORK(&osb->osb_truncate_log_wq, ocfs2_truncate_log_worker, osb);
+	osb->osb_tl_bh    = tl_bh;
 	osb->osb_tl_inode = tl_inode;
-	osb->osb_tl_bh    = tl_bh;
 
 	mlog_exit(status);
 	return status;
@@ -1423,6 +1488,7 @@
 	spin_unlock(&OCFS2_I(inode)->ip_lock);
 	fe->i_clusters -= clusters_to_del;
 	fe->i_mtime = CURRENT_TIME.tv_sec;
+	fe->i_mtime_nsec = cpu_to_le32(CURRENT_TIME.tv_nsec);
 
 	i = el->l_next_free_rec - 1;
 
@@ -1671,7 +1737,7 @@
 	 * record is free for use. If there isn't any, we flush to get
 	 * an empty truncate log.  */
 	if (ocfs2_truncate_log_needs_flush(osb)) {
-		status = ocfs2_flush_truncate_log(osb);
+		status = __ocfs2_flush_truncate_log(osb);
 		if (status < 0) {
 			mlog_errno(status);
 			goto bail;
@@ -1719,6 +1785,8 @@
 bail:
 	up_write(&OCFS_I(inode)->ip_alloc_sem);
 
+	ocfs2_schedule_truncate_log_flush(osb, 1);
+
 	if (tl_sem)
 		up(&tl_inode->i_sem);
 

Modified: branches/alloc_inode/fs/ocfs2/alloc.h
===================================================================
--- branches/alloc_inode/fs/ocfs2/alloc.h	2005-05-20 22:02:32 UTC (rev 2302)
+++ branches/alloc_inode/fs/ocfs2/alloc.h	2005-05-21 03:32:25 UTC (rev 2303)
@@ -53,6 +53,9 @@
 
 int ocfs2_truncate_log_init(ocfs_super *osb);
 void ocfs2_truncate_log_shutdown(ocfs_super *osb);
+void ocfs2_schedule_truncate_log_flush(ocfs_super *osb,
+				       int cancel);
+int ocfs2_flush_truncate_log(ocfs_super *osb);
 int ocfs2_begin_truncate_log_recovery(ocfs_super *osb,
 				      int slot_num,
 				      ocfs2_dinode **tl_copy);

Modified: branches/alloc_inode/fs/ocfs2/cluster/heartbeat.c
===================================================================
--- branches/alloc_inode/fs/ocfs2/cluster/heartbeat.c	2005-05-20 22:02:32 UTC (rev 2302)
+++ branches/alloc_inode/fs/ocfs2/cluster/heartbeat.c	2005-05-21 03:32:25 UTC (rev 2303)
@@ -1266,6 +1266,7 @@
 	hc->hc_data = data;
 	hc->hc_priority = priority;
 	hc->hc_type = type;
+	hc->hc_magic = HB_CB_MAGIC;
 }
 EXPORT_SYMBOL(hb_setup_callback);
 
@@ -1275,6 +1276,7 @@
 	struct list_head *iter;
 	struct hb_callback *hbcall;
 
+	BUG_ON(hc->hc_magic != HB_CB_MAGIC);
 	BUG_ON(!list_empty(&hc->hc_item));
 
 	hbcall = hbcall_from_type(hc->hc_type);
@@ -1301,8 +1303,11 @@
 
 int hb_unregister_callback(struct hb_callback_func *hc)
 {
-	BUG_ON(list_empty(&hc->hc_item));
+	BUG_ON(hc->hc_magic != HB_CB_MAGIC);
 
+	if (list_empty(&hc->hc_item))
+		return 0;
+
 	down_write(&hb_callback_sem);
 
 	list_del_init(&hc->hc_item);

Modified: branches/alloc_inode/fs/ocfs2/cluster/heartbeat.h
===================================================================
--- branches/alloc_inode/fs/ocfs2/cluster/heartbeat.h	2005-05-20 22:02:32 UTC (rev 2302)
+++ branches/alloc_inode/fs/ocfs2/cluster/heartbeat.h	2005-05-21 03:32:25 UTC (rev 2303)
@@ -29,6 +29,8 @@
 
 #include "ocfs2_heartbeat.h"
 
+#define HB_CB_MAGIC		0x51d1e4ec
+
 /* callback stuff */
 enum hb_callback_type {
 	HB_NODE_DOWN_CB = 0,
@@ -40,6 +42,7 @@
 typedef void (hb_cb_func)(struct nm_node *, int, void *);
 
 struct hb_callback_func {
+	u32			hc_magic;
 	struct list_head	hc_item;
 	hb_cb_func		*hc_func;
 	void			*hc_data;

Modified: branches/alloc_inode/fs/ocfs2/cluster/tcp.c
===================================================================
--- branches/alloc_inode/fs/ocfs2/cluster/tcp.c	2005-05-20 22:02:32 UTC (rev 2302)
+++ branches/alloc_inode/fs/ocfs2/cluster/tcp.c	2005-05-21 03:32:25 UTC (rev 2303)
@@ -472,13 +472,14 @@
 	return 0;
 }
 
-static int net_handler_cmp(struct net_msg_handler *nmh,
-			   u32 msg_type, u32 key)
+static int net_handler_cmp(struct net_msg_handler *nmh, u32 msg_type, u32 key)
 {
-	if (nmh->nh_msg_type != msg_type)
-		return nmh->nh_msg_type - msg_type;
+	int ret = memcmp(&nmh->nh_key, &key, sizeof(key));
 
-	return nmh->nh_key - key;
+	if (ret == 0)
+		ret = memcmp(&nmh->nh_msg_type, &msg_type, sizeof(msg_type));
+
+	return ret;
 }
 
 static struct net_msg_handler *

Modified: branches/alloc_inode/fs/ocfs2/dcache.c
===================================================================
--- branches/alloc_inode/fs/ocfs2/dcache.c	2005-05-20 22:02:32 UTC (rev 2302)
+++ branches/alloc_inode/fs/ocfs2/dcache.c	2005-05-21 03:32:25 UTC (rev 2303)
@@ -69,7 +69,7 @@
 	}
 	spin_unlock(&OCFS2_I(inode)->ip_lock);
 
-#warning "should we do this for all files?"
+	/* XXX: Should we do this for all files? */
 	if (S_ISDIR(inode->i_mode) && (!inode->i_nlink)) {
 		mlog(0, "dir inode (%"MLFu64") orphaned, returning false\n",
 		     OCFS2_I(inode)->ip_blkno);

Modified: branches/alloc_inode/fs/ocfs2/dlm/dlmapi.h
===================================================================
--- branches/alloc_inode/fs/ocfs2/dlm/dlmapi.h	2005-05-20 22:02:32 UTC (rev 2302)
+++ branches/alloc_inode/fs/ocfs2/dlm/dlmapi.h	2005-05-21 03:32:25 UTC (rev 2303)
@@ -185,4 +185,6 @@
 
 void dlm_unregister_domain(dlm_ctxt *dlm);
 
+void dlm_print_one_lock(dlm_lock *lockid);
+
 #endif /* DLMAPI_H */

Modified: branches/alloc_inode/fs/ocfs2/dlm/dlmdebug.c
===================================================================
--- branches/alloc_inode/fs/ocfs2/dlm/dlmdebug.c	2005-05-20 22:02:32 UTC (rev 2302)
+++ branches/alloc_inode/fs/ocfs2/dlm/dlmdebug.c	2005-05-21 03:32:25 UTC (rev 2303)
@@ -124,11 +124,58 @@
 	spin_unlock(&dlm_domain_lock);
 }
 
+static void dlm_print_one_lock_resource(dlm_lock_resource *res)
+{
+	struct list_head *iter2;
+	dlm_lock *lock;
+
+	printk("lockres: %.*s, owner=%u, state=%u\n", 
+	       res->lockname.len, res->lockname.name, 
+	       res->owner, res->state);
+	spin_lock(&res->spinlock);
+	printk("  granted queue: \n");
+	list_for_each(iter2, &res->granted) {
+		lock = list_entry(iter2, dlm_lock, list);
+		spin_lock(&lock->spinlock);
+		printk("    type=%d, conv=%d, node=%u, " 
+		       "cookie=%"MLFu64"\n", lock->ml.type, 
+		       lock->ml.convert_type, lock->ml.node, 
+		       lock->ml.cookie);
+		spin_unlock(&lock->spinlock);
+	}
+	printk("  converting queue: \n");
+	list_for_each(iter2, &res->converting) {
+		lock = list_entry(iter2, dlm_lock, list);
+		spin_lock(&lock->spinlock);
+		printk("    type=%d, conv=%d, node=%u, " 
+		       "cookie=%"MLFu64"\n", lock->ml.type, 
+		       lock->ml.convert_type, lock->ml.node, 
+		       lock->ml.cookie);
+		spin_unlock(&lock->spinlock);
+	}
+	printk("  blocked queue: \n");
+	list_for_each(iter2, &res->blocked) {
+		lock = list_entry(iter2, dlm_lock, list);
+		spin_lock(&lock->spinlock);
+		printk("    type=%d, conv=%d, node=%u, " 
+		       "cookie=%"MLFu64"\n", lock->ml.type, 
+		       lock->ml.convert_type, lock->ml.node, 
+		       lock->ml.cookie);
+		spin_unlock(&lock->spinlock);
+	}
+	spin_unlock(&res->spinlock);
+}
+
+void dlm_print_one_lock(dlm_lock *lockid)
+{
+	dlm_print_one_lock_resource(lockid->lockres);
+}
+EXPORT_SYMBOL(dlm_print_one_lock);
+
 void dlm_dump_lock_resources(dlm_ctxt *dlm)
 {
 	dlm_lock_resource *res;
-	dlm_lock *lock;
-	struct list_head *iter, *iter2;
+	struct list_head *iter;
 	struct list_head *bucket;
 	int i;
 
@@ -145,41 +192,7 @@
 		bucket = &(dlm->resources[i]);
 		list_for_each(iter, bucket) {
 			res = list_entry(iter, dlm_lock_resource, list);
-			printk("lockres: %.*s, owner=%u, state=%u\n", 
-			       res->lockname.len, res->lockname.name, 
-			       res->owner, res->state);
-			spin_lock(&res->spinlock);
-			printk("  granted queue: \n");
-			list_for_each(iter2, &res->granted) {
-				lock = list_entry(iter2, dlm_lock, list);
-				spin_lock(&lock->spinlock);
-				printk("    type=%d, conv=%d, node=%u, " 
-				       "cookie=%"MLFu64"\n", lock->ml.type, 
-				       lock->ml.convert_type, lock->ml.node, 
-				       lock->ml.cookie);
-				spin_unlock(&lock->spinlock);
-			}
-			printk("  converting queue: \n");
-			list_for_each(iter2, &res->converting) {
-				lock = list_entry(iter2, dlm_lock, list);
-				spin_lock(&lock->spinlock);
-				printk("    type=%d, conv=%d, node=%u, " 
-				       "cookie=%"MLFu64"\n", lock->ml.type, 
-				       lock->ml.convert_type, lock->ml.node, 
-				       lock->ml.cookie);
-				spin_unlock(&lock->spinlock);
-			}
-			printk("  blocked queue: \n");
-			list_for_each(iter2, &res->blocked) {
-				lock = list_entry(iter2, dlm_lock, list);
-				spin_lock(&lock->spinlock);
-				printk("    type=%d, conv=%d, node=%u, " 
-				       "cookie=%"MLFu64"\n", lock->ml.type, 
-				       lock->ml.convert_type, lock->ml.node, 
-				       lock->ml.cookie);
-				spin_unlock(&lock->spinlock);
-			}
-			spin_unlock(&res->spinlock);
+			dlm_print_one_lock_resource(res);
 		}
 	}
 	spin_unlock(&dlm->spinlock);

Modified: branches/alloc_inode/fs/ocfs2/dlm/dlmunlock.c
===================================================================
--- branches/alloc_inode/fs/ocfs2/dlm/dlmunlock.c	2005-05-20 22:02:32 UTC (rev 2302)
+++ branches/alloc_inode/fs/ocfs2/dlm/dlmunlock.c	2005-05-21 03:32:25 UTC (rev 2303)
@@ -195,14 +195,13 @@
 	spin_unlock(&res->spinlock);
 	wake_up(&res->wq);
 
-	/* let the caller's final dlm_lock_put handle the actual kfree
-	 * NOTE: this silly block and the FREE_LOCK constant
-	 * can go once the lock refcounting stuff is tested */
+	/* let the caller's final dlm_lock_put handle the actual kfree */
 	if (actions & DLM_UNLOCK_FREE_LOCK) {
 		/* this should always be coupled with list removal */
 		DLM_ASSERT(actions & DLM_UNLOCK_REMOVE_LOCK);
 		mlog(0, "lock %"MLFu64" should be gone now! refs=%d\n",
-		     lock->ml.cookie, atomic_read(&lock->lock_refs.refcount));
+		     lock->ml.cookie, atomic_read(&lock->lock_refs.refcount)-1);
+		dlm_lock_put(lock);
 	}
 	if (actions & DLM_UNLOCK_CALL_AST)
 		*call_ast = 1;
@@ -448,8 +447,7 @@
 		/* cancel this outright */
 		lksb->status = DLM_NORMAL;
 		status = DLM_NORMAL;
-		*actions = (DLM_UNLOCK_FREE_LOCK |
-			    DLM_UNLOCK_CALL_AST |
+		*actions = (DLM_UNLOCK_CALL_AST |
 			    DLM_UNLOCK_REMOVE_LOCK);
 	} else if (dlm_lock_on_list(&res->converting, lock)) {
 		/* cancel the request, put back on granted */

Modified: branches/alloc_inode/fs/ocfs2/dlmglue.c
===================================================================
--- branches/alloc_inode/fs/ocfs2/dlmglue.c	2005-05-20 22:02:32 UTC (rev 2302)
+++ branches/alloc_inode/fs/ocfs2/dlmglue.c	2005-05-21 03:32:25 UTC (rev 2303)
@@ -828,7 +828,8 @@
 			 lockres,
 			 lockres->l_ops->bast);
 	if (status != DLM_NORMAL) {
-		mlog(ML_ERROR, "Dlm returns %d\n", status);
+		mlog(ML_ERROR, "Dlm returns %d for lock %s\n", status,
+		     lockres->l_name);
 		ret = -ENOENT;
 		ocfs2_recover_from_dlm_error(lockres, 1);
 	}
@@ -1013,7 +1014,9 @@
 			    (status == DLM_NOTQUEUED))
 				ret = -EAGAIN;
 			else {
-				mlog(ML_ERROR, "Dlm returns %d\n", status);
+				mlog(ML_ERROR,
+				     "Dlm returns %d for lock %s\n",
+				     status, lockres->l_name);
 				ret = -ENOENT;
 			}
 			ocfs2_recover_from_dlm_error(lockres, 1);
@@ -1196,6 +1199,22 @@
 	mlog_exit_void();
 }
 
+#define OCFS2_SEC_SHIFT  34
+#define OCFS2_NSEC_MASK  ((1ULL << (64 - OCFS2_SEC_SHIFT)) - 1)
+
+/* LVB only has room for 64 bits of time here so we pack it for
+ * now. */
+static u64 ocfs2_pack_timespec(struct timespec *spec)
+{
+	u64 res;
+	u64 sec = spec->tv_sec;
+	u32 nsec = spec->tv_nsec;
+
+	res = (sec << OCFS2_SEC_SHIFT) | (nsec & OCFS2_NSEC_MASK);
+
+	return res;
+}
+
 /* Call this with the lockres locked. I am reasonably sure we don't
  * need ip_lock in this function as anyone who would be changing those
  * values is supposed to be blocked in ocfs2_meta_lock right now.
@@ -1214,13 +1233,20 @@
 	lvb->lvb_isize     = cpu_to_be64(i_size_read(inode));
 	lvb->lvb_imode     = cpu_to_be16(inode->i_mode);
 	lvb->lvb_inlink    = cpu_to_be16(inode->i_nlink);
-	lvb->lvb_iatime    = cpu_to_be64(inode->i_atime.tv_sec);
-	lvb->lvb_ictime    = cpu_to_be64(inode->i_ctime.tv_sec);
-	lvb->lvb_imtime    = cpu_to_be64(inode->i_mtime.tv_sec);
+	lvb->lvb_iatime    = cpu_to_be64(ocfs2_pack_timespec(&inode->i_atime));
+	lvb->lvb_ictime    = cpu_to_be64(ocfs2_pack_timespec(&inode->i_ctime));
+	lvb->lvb_imtime    = cpu_to_be64(ocfs2_pack_timespec(&inode->i_mtime));
 
 	mlog_exit_void();
 }
 
+static void ocfs2_unpack_timespec(struct timespec *spec,
+				  u64 packed_time)
+{
+	spec->tv_sec = packed_time >> OCFS2_SEC_SHIFT;
+	spec->tv_nsec = packed_time & OCFS2_NSEC_MASK;
+}
+
 static void ocfs2_refresh_inode_from_lvb(struct inode *inode)
 {
 	ocfs2_lock_res *lockres = &OCFS2_I(inode)->ip_meta_lockres;
@@ -1252,9 +1278,9 @@
 		inode->i_blocks = 0;
 	else
 		inode->i_blocks  = ocfs2_align_bytes_to_sectors(i_size_read(inode));
-	inode->i_atime.tv_sec = be64_to_cpu(lvb->lvb_iatime);
-	inode->i_ctime.tv_sec = be64_to_cpu(lvb->lvb_ictime);
-	inode->i_mtime.tv_sec = be64_to_cpu(lvb->lvb_imtime);
+	ocfs2_unpack_timespec(&inode->i_atime, be64_to_cpu(lvb->lvb_iatime));
+	ocfs2_unpack_timespec(&inode->i_mtime, be64_to_cpu(lvb->lvb_imtime));
+	ocfs2_unpack_timespec(&inode->i_ctime, be64_to_cpu(lvb->lvb_ictime));
 	spin_unlock(&OCFS2_I(inode)->ip_lock);
 
 	mlog_exit_void();
@@ -1561,51 +1587,6 @@
 	return status;
 }
 
-#if 0
-/* grabs the meta lock synchronusly.  */
-int ocfs2_meta_lock_flags(struct inode *inode,
-			  ocfs_journal_handle *handle,
-			  struct buffer_head **ret_bh,
-			  int ex,
-			  int flags)
-{
-	int status;
-
-	mlog_entry_void();
-
-	BUG_ON(handle && !ex);
-
-	status = ocfs2_meta_lock_flags_async(inode, ret_bh, ex, flags,
-					     NULL, 0);
-	if (status)
-		goto bail;
-
-	if (ret_bh && !(*ret_bh)) {
-		/* caller wants a buffer head but we haven't read it yet. */
-		status = ocfs_read_block(OCFS2_SB(inode->i_sb),
-					 OCFS2_I(inode)->ip_blkno, ret_bh,
-					 OCFS_BH_CACHED, inode);
-		if (status < 0) {
-			mlog_errno(status);
-			goto bail;
-		}
-	}
-	if (handle) {
-		status = ocfs_handle_add_lock(handle, inode);
-		if (status < 0)
-			mlog_errno(status);
-	}
-bail:
-	if (status < 0 && ret_bh && (*ret_bh)) {
-		brelse(*ret_bh);
-		ret_bh = NULL;
-	}
-
-	mlog_exit(status);
-	return status;
-}
-#endif
-
 void ocfs2_meta_unlock(struct inode *inode,
 		       int ex)
 {
@@ -1619,6 +1600,7 @@
 	     ex ? "EXMODE" : "PRMODE");
 
 	ocfs2_cluster_unlock(OCFS2_SB(inode->i_sb), lockres, level);
+
 	mlog_exit_void();
 }
 
@@ -1719,6 +1701,7 @@
 void ocfs2_dlm_shutdown(ocfs_super *osb)
 {
 	mlog_entry_void();
+
 	ocfs2_drop_super_lock(osb);
 
 	if (osb->vote_task) {
@@ -1743,7 +1726,8 @@
 	     lockres->l_unlock_action);
 
 	if (status != DLM_NORMAL)
-		mlog(ML_ERROR, "Dlm returns status %d\n", status);
+		mlog(ML_ERROR, "Dlm returns status %d for lock %s\n",
+		     status, lockres->l_name);
 
 	spin_lock(&lockres->l_lock);
 	switch(lockres->l_unlock_action) {
@@ -1765,6 +1749,7 @@
 	mlog_exit_void();
 }
 
+
 /* BEWARE: called with lockres lock, and always drops it. Caller
  * should not be calling us with a busy lock... */
 static int __ocfs2_drop_lock(ocfs_super *osb,
@@ -1774,7 +1759,8 @@
 	dlm_status status;
 
 	if (lockres->l_flags & OCFS2_LOCK_BUSY)
-		mlog(0,"destroying busy lock: \"%s\"\n", lockres->l_name);
+		mlog(ML_ERROR, "destroying busy lock: \"%s\"\n",
+		     lockres->l_name);
 	if (lockres->l_flags & OCFS2_LOCK_BLOCKED)
 		mlog(0, "destroying blocked lock: \"%s\"\n", lockres->l_name);
 
@@ -1802,9 +1788,10 @@
 			   lockres->l_ops->unlock_ast,
 			   lockres);
 	if (status != DLM_NORMAL) {
-		mlog(ML_ERROR, "Dlm returns %d\n", status);
-		ret = -ENOENT;
-		goto bail;
+		mlog(ML_ERROR, "Dlm returns %d for lock %s\n", status,
+		     lockres->l_name);
+		dlm_print_one_lock(lockres->l_lksb.lockid);
+		BUG();
 	}
 	mlog(0, "lock %s, successfull return from dlmunlock\n",
 	     lockres->l_name);
@@ -1945,7 +1932,8 @@
 			 lockres,
 			 lockres->l_ops->bast);
 	if (status != DLM_NORMAL) {
-		mlog(ML_ERROR, "Dlm returns %d\n", status);
+		mlog(ML_ERROR, "Dlm returns %d for lock %s\n", status,
+		     lockres->l_name);
 		ret = -ENOENT;
 		ocfs2_recover_from_dlm_error(lockres, 1);
 		goto bail;
@@ -1993,7 +1981,8 @@
 			lockres->l_unlock_action = OCFS2_UNLOCK_INVALID;
 		spin_unlock(&lockres->l_lock);
 	} else if (status != DLM_NORMAL) {
-		mlog(ML_ERROR, "Dlm returns %d\n", status);
+		mlog(ML_ERROR, "Dlm returns %d for lock %s\n", status,
+		     lockres->l_name);
 		ret = -ENOENT;
 		ocfs2_recover_from_dlm_error(lockres, 0);
 	}
@@ -2122,7 +2111,6 @@
 	spin_lock(&lockres->l_lock);
 
 	OCFS_ASSERT(lockres->l_flags & OCFS2_LOCK_BLOCKED);
-	OCFS_ASSERT(!(lockres->l_flags & OCFS2_LOCK_BUSY));
 
 recheck:
 	if (lockres->l_flags & OCFS2_LOCK_BUSY) {

Modified: branches/alloc_inode/fs/ocfs2/dlmglue.h
===================================================================
--- branches/alloc_inode/fs/ocfs2/dlmglue.h	2005-05-20 22:02:32 UTC (rev 2302)
+++ branches/alloc_inode/fs/ocfs2/dlmglue.h	2005-05-21 03:32:25 UTC (rev 2303)
@@ -69,9 +69,9 @@
 	u32       lvb_iclusters;
 	u32       lvb_iuid;
 	u32       lvb_igid;
-	u64       lvb_isize;
 	u16       lvb_imode;
 	u16       lvb_inlink;
+	u64       lvb_isize;
 	u64       lvb_iatime;
 	u64       lvb_ictime;
 	u64       lvb_imtime;

Modified: branches/alloc_inode/fs/ocfs2/file.c
===================================================================
--- branches/alloc_inode/fs/ocfs2/file.c	2005-05-20 22:02:32 UTC (rev 2302)
+++ branches/alloc_inode/fs/ocfs2/file.c	2005-05-21 03:32:25 UTC (rev 2303)
@@ -171,8 +171,8 @@
 void ocfs2_file_finish_extension(struct inode *inode, loff_t newsize,
 				 unsigned should_zero)
 {
-	mlog(0, "inode %"MLFu64", newsize = %"MLFu64" should_zero = %u\n",
-	     OCFS2_I(inode)->ip_blkno, newsize, should_zero);
+	mlog(0, "inode %"MLFu64", newsize = %lld, should_zero = %u\n",
+	     OCFS2_I(inode)->ip_blkno, (long long)newsize, should_zero);
 
 	ocfs2_update_inode_size(inode, newsize);
 
@@ -196,22 +196,23 @@
 
 /*
  * ocfs_file_write()
- * Linux 2.6 TODO: Remove all O_DIRECT conditionals here, they are no longer
- * needed.
  */
-static ssize_t ocfs_file_write(struct file *filp, const char __user *buf,
-		size_t count, loff_t *ppos)
+static ssize_t ocfs_file_write(struct file *filp,
+			       const char __user *buf,
+			       size_t count,
+			       loff_t *ppos)
 {
 	struct iovec local_iov = { .iov_base = (void __user *)buf, 
 				   .iov_len = count };
-	unsigned int savedflags;
 	int ret = 0;
 	ocfs_super *osb = NULL;
 	struct dentry *dentry = filp->f_dentry;
 	struct inode *inode = dentry->d_inode;
-	int sector_size;
 	struct ocfs2_write_lock_info info = {0, };
 	DECLARE_BUFFER_LOCK_CTXT(ctxt);
+#ifdef OCFS2_ORACORE_WORKAROUNDS
+	unsigned int saved_flags;
+#endif
 
 	mlog_entry ("(0x%p, 0x%p, %u, '%.*s')\n", filp, buf,
 			(unsigned int)count,
@@ -231,7 +232,6 @@
 	}
 
 	osb = OCFS2_SB(inode->i_sb);
-	sector_size = 1 << osb->s_sectsize_bits;
 
 	ret = ocfs_write_lock_maybe_extend(filp, buf, count, ppos, &info,
 					   &ctxt);
@@ -240,14 +240,17 @@
 
 	down_read(&OCFS_I(inode)->ip_alloc_sem);
 
-	/* ick.  seems to be our only way of toggling directio */
-	savedflags = filp->f_flags;
+#ifdef OCFS2_ORACORE_WORKAROUNDS
+	saved_flags = filp->f_flags;
 	if (info.wl_do_direct_io) 
 		filp->f_flags |= O_DIRECT;
 	else
 		filp->f_flags &= ~O_DIRECT;
-	ret = generic_file_write_nolock (filp, &local_iov, 1, ppos);
-	filp->f_flags = savedflags;
+#endif
+	ret = generic_file_write_nolock(filp, &local_iov, 1, ppos);
+#ifdef OCFS2_ORACORE_WORKAROUNDS
+	filp->f_flags = saved_flags;
+#endif
 
 	up_read(&OCFS_I(inode)->ip_alloc_sem);
 
@@ -268,20 +271,17 @@
 
 /*
  * ocfs_file_read()
- * Linux 2.6 TODO: Remove all O_DIRECT conditionals here, they are no longer
- * needed.
  */
-static ssize_t ocfs_file_read(struct file *filp, char __user *buf,
-		size_t count, loff_t *ppos)
+static ssize_t ocfs_file_read(struct file *filp,
+			      char __user *buf,
+			      size_t count,
+			      loff_t *ppos)
 {
-	unsigned int savedflags;
 	int ret = 0;
 	ocfs_super *osb = NULL;
 	struct dentry *dentry = filp->f_dentry;
 	struct inode *inode = dentry->d_inode;
 	ocfs2_backing_inode *target_binode;
-	int do_direct_io = 0;
-	int sector_size;
 	DECLARE_BUFFER_LOCK_CTXT(ctxt);
 
 	mlog_entry ("(0x%p, 0x%p, %u, '%.*s')\n", filp, buf,
@@ -294,19 +294,19 @@
 	}
 
 	osb = OCFS2_SB(inode->i_sb);
-	sector_size = 1 << osb->s_sectsize_bits;
 
+#ifdef OCFS2_ORACORE_WORKAROUNDS
 	if (filp->f_flags & O_DIRECT) {
-		/* anything special for o_direct? */
-		mlog(0, "O_DIRECT\n");
-		if (((*ppos) & (sector_size - 1)) || (count & (sector_size - 1)) || 
-		    ((unsigned long)buf & (sector_size - 1)) || (i_size_read(inode) & (sector_size -1))) {
-			do_direct_io = 0;
+		int sector_size = 1 << osb->s_sectsize_bits;
+
+		if (((*ppos) & (sector_size - 1)) ||
+		    (count & (sector_size - 1)) || 
+		    ((unsigned long)buf & (sector_size - 1)) ||
+		    (i_size_read(inode) & (sector_size -1))) {
 			filp->f_flags &= ~O_DIRECT;
-		} else {
-			do_direct_io = 1;
 		}
 	}
+#endif
 
 	ret = ocfs2_setup_io_locks(inode->i_sb, inode, buf, count, &ctxt,
 				   &target_binode);
@@ -315,7 +315,7 @@
 		goto bail;
 	}
 
-	target_binode->ba_lock_data = do_direct_io ? 0 : 1;
+	target_binode->ba_lock_data = (filp->f_flags & O_DIRECT) ? 0 : 1;
 
 	ret = ocfs2_lock_buffer_inodes(&ctxt, NULL);
 	if (ret < 0) {
@@ -325,14 +325,7 @@
 
 	down_read(&OCFS_I(inode)->ip_alloc_sem);
 
-	/* ick.  seems to be our only way of toggling directio */
-	savedflags = filp->f_flags;
-	if (do_direct_io) 
-		filp->f_flags |= O_DIRECT;
-	else
-		filp->f_flags &= ~O_DIRECT;
 	ret = generic_file_read (filp, buf, count, ppos);
-	filp->f_flags = savedflags;
 
 	up_read(&OCFS_I(inode)->ip_alloc_sem);
 
@@ -850,6 +843,7 @@
 			fe->i_size = new_fe_size;
 
 			fe->i_mtime = CURRENT_TIME.tv_sec;
+			fe->i_mtime_nsec = cpu_to_le32(CURRENT_TIME.tv_nsec);
 
 			status = ocfs_journal_dirty(handle, bh);
 			if (status < 0) {
@@ -896,6 +890,7 @@
 	     OCFS2_I(inode)->ip_clusters, i_size_read(inode));
 
 	fe->i_ctime = fe->i_mtime = CURRENT_TIME.tv_sec;
+	fe->i_ctime_nsec = fe->i_mtime_nsec = cpu_to_le32(CURRENT_TIME.tv_nsec);
 
 	status = ocfs_journal_dirty(handle, bh);
 	if (status < 0) {

Modified: branches/alloc_inode/fs/ocfs2/heartbeat.c
===================================================================
--- branches/alloc_inode/fs/ocfs2/heartbeat.c	2005-05-20 22:02:32 UTC (rev 2302)
+++ branches/alloc_inode/fs/ocfs2/heartbeat.c	2005-05-21 03:32:25 UTC (rev 2303)
@@ -102,21 +102,26 @@
 	ocfs_node_map_clear_bit(osb, &osb->umount_map, node_num);
 }
 
+void ocfs2_setup_hb_callbacks(ocfs_super *osb)
+{
+	hb_setup_callback(&osb->osb_hb_down, HB_NODE_DOWN_CB,
+			  ocfs2_hb_node_down_cb, osb, OCFS2_HB_NODE_DOWN_PRI);
+
+	hb_setup_callback(&osb->osb_hb_up, HB_NODE_UP_CB, ocfs2_hb_node_up_cb,
+			  osb, OCFS2_HB_NODE_UP_PRI);
+}
+
 /* Most functions here are just stubs for now... */
 int ocfs2_register_hb_callbacks(ocfs_super *osb)
 {
 	int status;
 
-	hb_setup_callback(&osb->osb_hb_down, HB_NODE_DOWN_CB,
-			  ocfs2_hb_node_down_cb, osb, OCFS2_HB_NODE_DOWN_PRI);
 	status = hb_register_callback(&osb->osb_hb_down);
 	if (status < 0) {
 		mlog_errno(status);
 		goto bail;
 	}
 
-	hb_setup_callback(&osb->osb_hb_up, HB_NODE_UP_CB, ocfs2_hb_node_up_cb,
-			  osb, OCFS2_HB_NODE_UP_PRI);
 	status = hb_register_callback(&osb->osb_hb_up);
 	if (status < 0)
 		mlog_errno(status);

Modified: branches/alloc_inode/fs/ocfs2/heartbeat.h
===================================================================
--- branches/alloc_inode/fs/ocfs2/heartbeat.h	2005-05-20 22:02:32 UTC (rev 2302)
+++ branches/alloc_inode/fs/ocfs2/heartbeat.h	2005-05-21 03:32:25 UTC (rev 2303)
@@ -28,6 +28,7 @@
 
 void ocfs2_init_node_maps(ocfs_super *osb);
 
+void ocfs2_setup_hb_callbacks(ocfs_super *osb);
 int ocfs2_register_hb_callbacks(ocfs_super *osb);
 void ocfs2_clear_hb_callbacks(ocfs_super *osb);
 void ocfs2_stop_heartbeat(ocfs_super *osb);

Modified: branches/alloc_inode/fs/ocfs2/inode.c
===================================================================
--- branches/alloc_inode/fs/ocfs2/inode.c	2005-05-20 22:02:32 UTC (rev 2302)
+++ branches/alloc_inode/fs/ocfs2/inode.c	2005-05-21 03:32:25 UTC (rev 2303)
@@ -278,8 +278,11 @@
 	inode->i_mapping->a_ops = &ocfs_aops;
 	inode->i_flags |= S_NOATIME;
 	inode->i_atime.tv_sec = fe->i_atime;
+	inode->i_atime.tv_nsec = le32_to_cpu(fe->i_atime_nsec);
 	inode->i_mtime.tv_sec = fe->i_mtime;
+	inode->i_mtime.tv_nsec = le32_to_cpu(fe->i_mtime_nsec);
 	inode->i_ctime.tv_sec = fe->i_ctime;
+	inode->i_ctime.tv_nsec = le32_to_cpu(fe->i_ctime_nsec);
 
 	if (OCFS2_I(inode)->ip_blkno != fe->i_blkno)
 		mlog(ML_ERROR,
@@ -728,6 +731,9 @@
 	mlog(0, "Clearing inode: %"MLFu64", nlink = %u)\n",
 	     OCFS2_I(inode)->ip_blkno, inode->i_nlink);
 
+	mlog_bug_on_msg(OCFS2_SB(inode->i_sb) == NULL,
+			"Inode=%lu\n", inode->i_ino);
+
 	if (!inode->u.generic_ip) {
 		mlog(ML_ERROR, "inode %lu has no generic_ip!\n", inode->i_ino);
 		goto bail;
@@ -810,8 +816,9 @@
 	u64 p_blkno;
 	int readflags = OCFS_BH_CACHED;
 
-#warning only turn this on if we know we can deal with read_block returning nothing
 #if 0
+	/* only turn this on if we know we can deal with read_block
+	 * returning nothing */
 	if (reada)
 		readflags |= OCFS_BH_READAHEAD;
 #endif
@@ -924,10 +931,13 @@
 	fe->i_gid = inode->i_gid;
 	fe->i_mode = inode->i_mode;
 	fe->i_atime = inode->i_atime.tv_sec;
+	fe->i_atime_nsec = cpu_to_le32(inode->i_atime.tv_nsec);
 	fe->i_ctime = inode->i_ctime.tv_sec;
+	fe->i_ctime_nsec = cpu_to_le32(inode->i_ctime.tv_nsec);
 	fe->i_mtime = inode->i_mtime.tv_sec;
-#warning "do we want to update these here?"
-//	fe->i_dtime = inode->i_dtime.tv_sec;
+	fe->i_mtime_nsec = cpu_to_le32(inode->i_mtime.tv_nsec);
+	/* XXX: Do we want to update i_dtime here? */
+	/* fe->i_dtime = inode->i_dtime.tv_sec; */
 
 	status = ocfs_journal_dirty(handle, bh);
 	if (status < 0)
@@ -968,10 +978,11 @@
 	else
 		inode->i_blocks = ocfs2_align_bytes_to_sectors(i_size_read(inode));
 	inode->i_atime.tv_sec = fe->i_atime;
+	inode->i_atime.tv_nsec = le32_to_cpu(fe->i_atime_nsec);
 	inode->i_mtime.tv_sec = fe->i_mtime;
+	inode->i_mtime.tv_nsec = le32_to_cpu(fe->i_mtime_nsec);
 	inode->i_ctime.tv_sec = fe->i_ctime;
+	inode->i_ctime.tv_nsec = le32_to_cpu(fe->i_ctime_nsec);
 
 	spin_unlock(&OCFS2_I(inode)->ip_lock);
 }				/* ocfs_refresh_inode */
-
-

Modified: branches/alloc_inode/fs/ocfs2/journal.c
===================================================================
--- branches/alloc_inode/fs/ocfs2/journal.c	2005-05-20 22:02:32 UTC (rev 2302)
+++ branches/alloc_inode/fs/ocfs2/journal.c	2005-05-21 03:32:25 UTC (rev 2303)
@@ -56,7 +56,7 @@
 static int ocfs_recover_node(ocfs_super *osb,
 			     int node_num);
 static int __ocfs_recovery_thread(void *arg);
-static int ocfs_commit_cache (ocfs_super * osb);
+static int ocfs_commit_cache(ocfs_super *osb);
 static int ocfs_wait_on_mount(ocfs_super *osb);
 static void ocfs_handle_cleanup_locks(ocfs_journal *journal, 
 				      ocfs_journal_handle *handle,
@@ -78,7 +78,7 @@
 	int status = 0;
 	unsigned int flushed;
 	unsigned long old_id;
-	ocfs_journal * journal = NULL;
+	ocfs_journal *journal = NULL;
 
 	mlog_entry_void();
 
@@ -114,13 +114,13 @@
 	ocfs2_kick_vote_thread(osb);
 	wake_up(&journal->j_checkpointed);
 finally:
-	mlog_exit (status);
+	mlog_exit(status);
 	return status;
 }				/* ocfs_commit_cache */
 
-ocfs_journal_handle * ocfs_alloc_handle(ocfs_super *osb)
+ocfs_journal_handle *ocfs_alloc_handle(ocfs_super *osb)
 {
-	ocfs_journal_handle * retval = NULL;
+	ocfs_journal_handle *retval = NULL;
 
 	retval = kmalloc(sizeof(*retval), GFP_KERNEL);
 	if (!retval) {
@@ -134,8 +134,8 @@
 	retval->num_locks = 0;
 	retval->k_handle = NULL;
 
-	INIT_LIST_HEAD(&(retval->locks));
-	INIT_LIST_HEAD(&(retval->inode_list));
+	INIT_LIST_HEAD(&retval->locks);
+	INIT_LIST_HEAD(&retval->inode_list);
 	retval->journal = osb->journal;
 
 	return retval;
@@ -144,13 +144,13 @@
 /* pass it NULL and it will allocate a new handle object for you.  If
  * you pass it a handle however, it may still return NULL, in which
  * case it has free'd the passed handle for you. */
-ocfs_journal_handle * ocfs_start_trans(ocfs_super *osb, 
+ocfs_journal_handle *ocfs_start_trans(ocfs_super *osb, 
 				       ocfs_journal_handle *handle, 
 				       int max_buffs) 
 {
-	journal_t * journal = osb->journal->j_journal;
+	journal_t *journal = osb->journal->j_journal;
 
-	mlog_entry ("(max_buffs = %d)\n", max_buffs);
+	mlog_entry("(max_buffs = %d)\n", max_buffs);
 
 	if (!osb || !osb->journal->j_journal)
 		BUG();
@@ -261,7 +261,7 @@
 /*
  * ocfs_commit_trans
  */
-void ocfs_commit_trans(ocfs_journal_handle * handle) 
+void ocfs_commit_trans(ocfs_journal_handle *handle) 
 {
 	handle_t *jbd_handle;
 	int retval;
@@ -377,12 +377,12 @@
 	OCFS_ASSERT(bh);
 	OCFS_ASSERT((handle->flags & OCFS_HANDLE_STARTED));
 
-	mlog_entry("(bh->b_blocknr=%llu, type=%d (\"%s\"), "
-		       "bh->b_size = %hu)\n", 
-		       (unsigned long long)bh->b_blocknr, type, 
-		       (type == OCFS_JOURNAL_ACCESS_CREATE) ? 
-		       "OCFS_JOURNAL_ACCESS_CREATE" : 
-		       "OCFS_JOURNAL_ACCESS_WRITE", bh->b_size);
+	mlog_entry("(bh->b_blocknr=%llu, type=%d (\"%s\"), bh->b_size = %hu)\n",
+		   (unsigned long long)bh->b_blocknr, type, 
+		   (type == OCFS_JOURNAL_ACCESS_CREATE) ? 
+			"OCFS_JOURNAL_ACCESS_CREATE" : 
+			"OCFS_JOURNAL_ACCESS_WRITE",
+		   bh->b_size);
 
 	/* we can safely remove this assertion after testing. */
 	if (!buffer_uptodate(bh)) {
@@ -412,6 +412,7 @@
 	if (status < 0)
 		mlog(ML_ERROR, "Error %d getting %d access to buffer!\n",
 		     status, type);
+
 	mlog_exit(status);
 	return status;
 } /* ocfs_journal_access */
@@ -428,7 +429,7 @@
 	OCFS_ASSERT((handle->flags & OCFS_HANDLE_STARTED));
 
 	mlog_entry("(bh->b_blocknr=%llu)\n",
-			(unsigned long long)bh->b_blocknr);
+		   (unsigned long long)bh->b_blocknr);
 
 	status = journal_dirty_metadata(handle->k_handle, bh);
 	if (status < 0)
@@ -448,6 +449,7 @@
 	ocfs_journal_lock *lock;
 
 	OCFS_ASSERT(inode);
+
 	lock = kmem_cache_alloc(ocfs2_lock_cache, GFP_NOFS);
 	if (!lock) {
 		status = -ENOMEM;
@@ -486,8 +488,9 @@
 			ocfs_set_inode_lock_trans(journal, inode);
 		ocfs2_meta_unlock(inode, 1);
 		if (atomic_read(&inode->i_count) == 1)
-			mlog(ML_ERROR, "Inode %"MLFu64", I'm doing a last iput "
-			     "for!", OCFS2_I(inode)->ip_blkno);
+			mlog(ML_ERROR,
+			     "Inode %"MLFu64", I'm doing a last iput for!",
+			     OCFS2_I(inode)->ip_blkno);
 		iput(inode);
 		kmem_cache_free(ocfs2_lock_cache, lock);
 	}
@@ -502,7 +505,7 @@
 {
 	int status = -1;
 	struct inode *inode = NULL; /* the journal inode */
-	journal_t * j_journal = NULL;
+	journal_t *j_journal = NULL;
 	ocfs2_dinode *fe = NULL;
 	struct buffer_head *bh = NULL;
 	ocfs_super *osb;
@@ -521,9 +524,9 @@
 		mlog_errno(status);
 		goto done;
 	}
-	if (is_bad_inode (inode)) {
+	if (is_bad_inode(inode)) {
 		mlog(ML_ERROR, "access error (bad inode)\n");
-		iput (inode);
+		iput(inode);
 		inode = NULL;
 		status = -EACCES;
 		goto done;
@@ -537,7 +540,7 @@
 			mlog(ML_ERROR, "Could not get lock on journal!\n");
 		goto done;
 	}
-	fe = (ocfs2_dinode *) bh->b_data;
+	fe = (ocfs2_dinode *)bh->b_data;
 
 	if (fe->i_size <  OCFS2_MIN_JOURNAL_SIZE) {
 		mlog(ML_ERROR, "Journal file size (%"MLFu64") is too small!",
@@ -555,8 +558,8 @@
 		mlog(ML_ERROR, "inode and fe alloc sizes differ! (%u != %u",
 		     OCFS2_I(inode)->ip_clusters, fe->i_clusters);
 	if (inode->i_size != fe->i_size)
-		mlog(ML_ERROR, "inode and fe i_size's differ! "
-			       "(%lld != %"MLFu64")",
+		mlog(ML_ERROR,
+		     "inode and fe i_size's differ! (%lld != %"MLFu64")",
 		     inode->i_size, fe->i_size);
 
 	OCFS2_I(inode)->ip_open_count++;
@@ -573,6 +576,13 @@
 	mlog(0, "j_journal->j_maxlen = %u\n", j_journal->j_maxlen);
 	j_journal->j_commit_interval = OCFS_DEFAULT_COMMIT_INTERVAL;
 
+	spin_lock(&j_journal->j_state_lock);
+	if (osb->s_mount_opt & OCFS2_MOUNT_BARRIER)
+		j_journal->j_flags |= JFS_BARRIER;
+	else
+		j_journal->j_flags &= ~JFS_BARRIER;
+	spin_unlock(&j_journal->j_state_lock);
+
 	*dirty = (le32_to_cpu(fe->id1.journal1.ij_flags) &
 		  OCFS2_JOURNAL_DIRTY_FL);
 
@@ -603,13 +613,13 @@
 {
 	int status;
 	unsigned int flags;
-	ocfs_journal * journal = osb->journal;
+	ocfs_journal *journal = osb->journal;
 	struct buffer_head *bh = journal->j_bh;
 	ocfs2_dinode *fe;
 
 	mlog_entry_void();
 
-	fe = (ocfs2_dinode *) bh->b_data;
+	fe = (ocfs2_dinode *)bh->b_data;
 	OCFS2_BUG_ON_INVALID_DINODE(fe);
 
 	flags = le32_to_cpu(fe->id1.journal1.ij_flags);
@@ -632,9 +642,9 @@
 */
 void ocfs_journal_shutdown(ocfs_super *osb) 
 {
-	ocfs_journal * journal = NULL;
+	ocfs_journal *journal = NULL;
 	int status = 0;
-	struct inode * inode = NULL;
+	struct inode *inode = NULL;
 	int num_running_trans = 0;
 
 	mlog_entry_void();
@@ -657,8 +667,9 @@
 
 	num_running_trans = atomic_read(&(osb->journal->j_num_trans));
 	if (num_running_trans > 0)
-		mlog(0, "Shutting down journal: must wait on %d"
-		     " running transactions!\n", num_running_trans);
+		mlog(0, "Shutting down journal: must wait on %d "
+		     "running transactions!\n",
+		     num_running_trans);
 
 	/* Do a commit_cache here. It will flush our journal, *and*
 	 * release any locks that are still held.
@@ -690,7 +701,7 @@
 	/* unlock our journal */
 	ocfs2_meta_unlock(inode, 1);
 
-	brelse (journal->j_bh);
+	brelse(journal->j_bh);
 	journal->j_bh = NULL;
 
 	journal->j_state = OCFS_JOURNAL_FREE;
@@ -1007,9 +1018,10 @@
 
 		status = ocfs_recover_node(osb, node_num);
 		if (status < 0) {
-			mlog(ML_ERROR, "Error %d recovering node %d on device "
-			     "(%u,%u)!\n", status, node_num,
-			     MAJOR(osb->sb->s_dev),MINOR(osb->sb->s_dev));
+			mlog(ML_ERROR,
+			     "Error %d recovering node %d on device (%u,%u)!\n",
+			     status, node_num,
+			     MAJOR(osb->sb->s_dev), MINOR(osb->sb->s_dev));
 			mlog(ML_ERROR, "Volume requires unmount.\n");
 			continue;
 		}
@@ -1048,7 +1060,7 @@
 void ocfs_recovery_thread(ocfs_super *osb, int node_num)
 {
 	mlog_entry("(node_num=%d, osb->node_num = %d)\n",
-		       node_num, osb->node_num);
+		   node_num, osb->node_num);
 
 	down(&osb->recovery_lock);
 	if (osb->disable_recovery)
@@ -1097,9 +1109,9 @@
 		mlog_errno(status);
 		goto done;
 	}
-	if (is_bad_inode (inode)) {
+	if (is_bad_inode(inode)) {
 		status = -EACCES;
-		iput (inode);
+		iput(inode);
 		inode = NULL;
 		mlog_errno(status);
 		goto done;
@@ -1126,8 +1138,8 @@
 	}
 
 	mlog(ML_NOTICE, "Recovering node %d from slot %d on device (%u,%u)\n",
-	     node_num, slot_num, MAJOR(osb->sb->s_dev),
-	     MINOR(osb->sb->s_dev));
+	     node_num, slot_num,
+	     MAJOR(osb->sb->s_dev), MINOR(osb->sb->s_dev));
 
 	OCFS2_I(inode)->ip_clusters = fe->i_clusters;
 
@@ -1214,7 +1226,7 @@
 	ocfs2_dinode *tl_copy = NULL;
 
 	mlog_entry("(node_num=%d, osb->node_num = %d)\n",
-		       node_num, osb->node_num);
+		   node_num, osb->node_num);
 
 	mlog(0, "checking node %d\n", node_num);
 
@@ -1286,9 +1298,9 @@
 		status = -EACCES;
 		goto bail;
 	}
-	if (is_bad_inode (inode)) {
+	if (is_bad_inode(inode)) {
 		mlog(ML_ERROR, "access error (bad inode)\n");
-		iput (inode);
+		iput(inode);
 		inode = NULL;
 		status = -EACCES;
 		goto bail;
@@ -1415,7 +1427,7 @@
 				up(&orphan_dir_inode->i_sem);
 				status = -EINVAL;
 				mlog_errno(status);
-				brelse (bh);
+				brelse(bh);
 				goto bail;
 			}
 
@@ -1426,11 +1438,12 @@
 			if (!le64_to_cpu(de->inode))
 				continue;
 			if (de->file_type > OCFS2_FT_MAX) {
-				mlog(ML_ERROR, "block %llu contains invalid "
-				     "de: inode = %"MLFu64", rec_len = %u, "
+				mlog(ML_ERROR,
+				     "block %llu contains invalid de: "
+				     "inode = %"MLFu64", rec_len = %u, "
 				     "name_len = %u, file_type = %u, "
 				     "name='%.*s'\n", 
-				     (unsigned long long) bh->b_blocknr, 
+				     (unsigned long long)bh->b_blocknr, 
 				     le64_to_cpu(de->inode),
 				     le16_to_cpu(de->rec_len),
 				     de->name_len, 
@@ -1531,8 +1544,9 @@
 			mlog_errno(status);
 
 		if (kthread_should_stop() && atomic_read(&journal->j_num_trans)){
-			mlog(ML_KTHREAD, "commit_thread: %u transactions "
-			     "pending on shutdown\n",
+			mlog(ML_KTHREAD,
+			     "commit_thread: %u transactions pending on "
+			     "shutdown\n",
 			     atomic_read(&journal->j_num_trans));
 		}
 	}

Modified: branches/alloc_inode/fs/ocfs2/mmap.c
===================================================================
--- branches/alloc_inode/fs/ocfs2/mmap.c	2005-05-20 22:02:32 UTC (rev 2302)
+++ branches/alloc_inode/fs/ocfs2/mmap.c	2005-05-21 03:32:25 UTC (rev 2303)
@@ -447,13 +447,11 @@
 	struct dentry *dentry = filp->f_dentry;
 	struct inode *inode = dentry->d_inode;
 	int status;
-	int sector_size;
 	int level = filp->f_flags & O_APPEND;
 	loff_t saved_ppos;
 	u64 bytes_added = 0;
 
 	osb = OCFS2_SB(inode->i_sb);
-	sector_size = 1 << osb->s_sectsize_bits;
 
 	/* the target inode is different from the other inodes.  in o_direct it
 	 * doesn't get a data lock and when appending it gets a level 1 meta
@@ -513,16 +511,18 @@
 		saved_ppos = i_size_read(inode);
 		mlog(0, "O_APPEND: inode->i_size=%llu\n", saved_ppos);
 
+#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. */
-#warning this is wrong wrong wrong
 		filp->f_flags &= ~O_DIRECT;
+#endif
 	}
 
 	if (filp->f_flags & O_DIRECT) {
-		/* anything special for o_direct? */
-		mlog(0, "O_DIRECT\n");
+#ifdef OCFS2_ORACORE_WORKAROUNDS
+		int sector_size = 1 << osb->s_sectsize_bits;
+
 		if ((saved_ppos & (sector_size - 1)) || 
 		    (count & (sector_size - 1)) || 
 		    ((unsigned long)buf & (sector_size - 1))) {
@@ -531,7 +531,12 @@
 		} else {
 			info->wl_do_direct_io = 1;
 		}
+#else
+		info->wl_do_direct_io = 1;
+#endif
+		mlog(0, "O_DIRECT\n");
 	}
+
 	info->wl_target_binode->ba_lock_data = info->wl_do_direct_io ? 0 : 1;
 
 	info->wl_newsize = count + saved_ppos;

Modified: branches/alloc_inode/fs/ocfs2/namei.c
===================================================================
--- branches/alloc_inode/fs/ocfs2/namei.c	2005-05-20 22:02:32 UTC (rev 2302)
+++ branches/alloc_inode/fs/ocfs2/namei.c	2005-05-21 03:32:25 UTC (rev 2303)
@@ -577,6 +577,8 @@
 	strcpy (fe->i_signature, OCFS2_INODE_SIGNATURE);
 	fe->i_flags |= OCFS2_VALID_FL;
 	fe->i_atime = fe->i_ctime = fe->i_mtime = CURRENT_TIME.tv_sec;
+	fe->i_mtime_nsec = fe->i_ctime_nsec = fe->i_atime_nsec = 
+		cpu_to_le32(CURRENT_TIME.tv_nsec);
 	fe->i_dtime = 0;
 
 	fel = &fe->id2.i_list;
@@ -713,10 +715,11 @@
 		goto bail;
 	}
 
-	fe->i_links_count++;
-	fe->i_ctime = CURRENT_TIME.tv_sec;
-	inode->i_nlink = fe->i_links_count;
-	inode->i_ctime.tv_sec = fe->i_ctime;
+	inode->i_nlink++;
+	inode->i_ctime = CURRENT_TIME;
+	fe->i_links_count = inode->i_nlink;
+	fe->i_ctime = inode->i_ctime.tv_sec;
+	fe->i_ctime_nsec = cpu_to_le32(inode->i_ctime.tv_nsec);
 
 	err = ocfs_journal_dirty(handle, fe_bh);
 	if (err < 0) {
@@ -1916,7 +1919,7 @@
 				}
 				num++;
 		
-#warning questionable readahead stuff here	
+				/* XXX: questionable readahead stuff here */
 				bh = ocfs_bread(dir, b++, &err, 1);
 				bh_use[ra_max] = bh;
 #if 0		// ???

Modified: branches/alloc_inode/fs/ocfs2/ocfs.h
===================================================================
--- branches/alloc_inode/fs/ocfs2/ocfs.h	2005-05-20 22:02:32 UTC (rev 2302)
+++ branches/alloc_inode/fs/ocfs2/ocfs.h	2005-05-21 03:32:25 UTC (rev 2303)
@@ -238,6 +238,12 @@
 	OCFS2_LA_DISABLED
 };
 
+enum ocfs2_mount_options
+{
+	OCFS2_MOUNT_HB_OK   = 1 << 0,	/* Heartbeat started */
+	OCFS2_MOUNT_BARRIER = 1 << 1	/* Use block barriers */
+};
+
 struct _ocfs_journal;
 struct _ocfs2_slot_info;
 
@@ -280,6 +286,8 @@
 	spinlock_t s_next_gen_lock;
 	u32 s_next_generation;
 
+	unsigned long s_mount_opt;
+
 	u16 max_nodes;
 	u16 num_nodes;
 	s16 node_num;
@@ -349,6 +357,7 @@
 	/* Truncate log info */
 	struct inode			*osb_tl_inode;
 	struct buffer_head		*osb_tl_bh;
+	struct work_struct		osb_truncate_log_wq;
 };
 
 #define NAMEI_RA_CHUNKS  2

Modified: branches/alloc_inode/fs/ocfs2/ocfs2_fs.h
===================================================================
--- branches/alloc_inode/fs/ocfs2/ocfs2_fs.h	2005-05-20 22:02:32 UTC (rev 2302)
+++ branches/alloc_inode/fs/ocfs2/ocfs2_fs.h	2005-05-21 03:32:25 UTC (rev 2303)
@@ -402,8 +402,10 @@
 	__u64 i_last_eb_blk;		/* Pointer to last extent
 					   block */
 /*60*/	__u32 i_fs_generation;		/* Generation per fs-instance */
-	__u32 i_reserved1;		/* Generation per fs-instance */
-/*68*/	__u64 i_reserved2[10];
+	__u32 i_atime_nsec;
+	__u32 i_ctime_nsec;
+	__u32 i_mtime_nsec;
+/*70*/	__u64 i_reserved1[9];
 /*B8*/	union {
 		__u64 i_pad1;		/* Generic way to refer to this
 					   64bit union */
@@ -435,6 +437,8 @@
 
 /*
  * On-disk directory entry structure for OCFS2
+ *
+ * Packed as this structure could be accessed unaligned on 64-bit platforms
  */
 struct ocfs2_dir_entry {
 /*00*/	__u64   inode;                  /* Inode number */
@@ -443,7 +447,7 @@
 	__u8    file_type;
 /*0C*/	char    name[OCFS2_MAX_FILENAME_LEN];   /* File name */
 /* Actual on-disk length specified by rec_len */
-};
+} __attribute__ ((packed));
 
 /*
  * On disk allocator group structure for OCFS2

Modified: branches/alloc_inode/fs/ocfs2/super.c
===================================================================
--- branches/alloc_inode/fs/ocfs2/super.c	2005-05-20 22:02:32 UTC (rev 2302)
+++ branches/alloc_inode/fs/ocfs2/super.c	2005-05-21 03:32:25 UTC (rev 2303)
@@ -36,6 +36,7 @@
 #include <linux/blkdev.h>
 #include <linux/socket.h>
 #include <linux/inet.h>
+#include <linux/parser.h>
 
 #include <cluster/nodemanager.h>
 
@@ -79,27 +80,28 @@
 MODULE_AUTHOR("Oracle");
 MODULE_LICENSE("GPL");
 
+static int ocfs2_parse_options(char *options, unsigned long *mount_opt);
 static void ocfs_put_super(struct super_block *sb);
-static int ocfs_mount_volume(struct super_block *sb);
-static void ocfs_dismount_volume(struct super_block *sb);
+static int ocfs_mount_volume(struct super_block *sb, unsigned long mount_opt);
+static void ocfs_dismount_volume(struct super_block *sb, int mnt_err);
 static int ocfs_initialize_mem_caches(void);
 static void ocfs_free_mem_caches(void);
-static void ocfs_delete_osb(ocfs_super * osb);
+static void ocfs_delete_osb(ocfs_super *osb);
 
 static int ocfs_statfs(struct super_block *sb, struct kstatfs *buf);
 
-static int ocfs_sync_fs(struct super_block *sb, int wait);
+static int ocfs2_sync_fs(struct super_block *sb, int wait);
 
 static int ocfs_init_global_system_inodes(ocfs_super *osb);
 static int ocfs_init_local_system_inodes(ocfs_super *osb);
 static int ocfs_release_system_inodes(ocfs_super *osb);
 static int ocfs2_fill_local_node_info(ocfs_super *osb);
-static int ocfs_check_volume(ocfs_super * osb);
+static int ocfs_check_volume(ocfs_super *osb);
 static int ocfs_verify_volume(ocfs2_dinode *di, struct buffer_head *bh,
 			      u32 sectsize);
 static int ocfs_initialize_osb(ocfs_super *osb, struct buffer_head *bh);
 static int ocfs2_get_sector(struct super_block *sb, struct buffer_head **bh, int block, int sect_size);
-static void ocfs_write_super(struct super_block * sb);
+static void ocfs_write_super(struct super_block *sb);
 static struct inode *ocfs2_alloc_inode(struct super_block *sb);
 static void ocfs2_destroy_inode(struct inode *inode);
 
@@ -111,7 +113,7 @@
 	.destroy_inode	= ocfs2_destroy_inode,
 	.clear_inode	= ocfs2_clear_inode,
 	.delete_inode	= ocfs_delete_inode, 
-	.sync_fs	= ocfs_sync_fs,
+	.sync_fs	= ocfs2_sync_fs,
 	.write_super	= ocfs_write_super,
 	.put_super	= ocfs_put_super,
 };
@@ -121,21 +123,44 @@
 	.get_parent	= ocfs_get_parent,
 };
 
+enum {
+	Opt_hbok,
+	Opt_barrier,
+	Opt_err,
+};
+
+static match_table_t tokens = {
+	{Opt_hbok, OCFS2_HB_OK},
+	{Opt_barrier, "barrier=%u"},
+	{Opt_err, NULL}
+};
+
 /*
  * write_super and sync_fs ripped right out of ext3.
  */
-static void ocfs_write_super (struct super_block * sb)
+static void ocfs_write_super(struct super_block *sb)
 {
 	if (down_trylock(&sb->s_lock) == 0)
 		BUG();
 	sb->s_dirt = 0;
 }
 
-static int ocfs_sync_fs(struct super_block *sb, int wait)
+static int ocfs2_sync_fs(struct super_block *sb, int wait)
 {
+	int status = 0;
 	tid_t target;
+	ocfs_super *osb = OCFS2_SB(sb);
 
 	sb->s_dirt = 0;
+
+	if (wait) {
+		status = ocfs2_flush_truncate_log(osb);
+		if (status < 0)
+			mlog_errno(status);
+	} else {
+		ocfs2_schedule_truncate_log_flush(osb, 0);
+	}
+
 	if (journal_start_commit(OCFS2_SB(sb)->journal->j_journal, &target)) {
 		if (wait)
 			log_wait_commit(OCFS2_SB(sb)->journal->j_journal, 
@@ -208,7 +233,8 @@
 		if (!new) {
 			ocfs_release_system_inodes(osb);
 			status = -EINVAL;
-			mlog_errno(status);
+			mlog(ML_ERROR, "status=%d, sysfile=%d, slot=%d\n",
+			     status, i, osb->slot_num);
 			goto bail;
 		}
 		// the array now has one ref, so drop this one
@@ -244,6 +270,12 @@
 		osb->sys_root_inode = NULL;
 	}
 
+	inode = osb->root_inode;
+	if (inode) {
+		iput(inode);
+		osb->root_inode = NULL;
+	}
+
 	mlog_exit(status);
 	return status;
 } /* ocfs_release_system_inodes */
@@ -306,8 +338,9 @@
 	int status;
 	struct inode *inode = NULL;
 	ocfs_super *osb = NULL;
+	unsigned long mount_opt = 0;
 
-	mlog_entry ("%p, %p, %i", sb, data, silent);
+	mlog_entry("%p, %p, %i", sb, data, silent);
 
 	/* for now we only have one cluster/node, make sure we see it
 	 * in the heartbeat universe */
@@ -316,24 +349,30 @@
 		goto read_super_error;
 	}
 
-	/* Stopgap check to ensure that mount.ocfs2 mounted the volume */
-	if (!data || strcmp(data, OCFS2_HB_OK)) {
+	if (!ocfs2_parse_options(data, &mount_opt)) {
 		status = -EINVAL;
-		if (data)
-			mlog(ML_ERROR, "Invalid options: %s\n", (char *)data);
 		goto read_super_error;
 	}
 
+	/* Stopgap check to ensure that mount.ocfs2 mounted the volume */
+	if (!(mount_opt & OCFS2_MOUNT_HB_OK)) {
+		  mlog(ML_ERROR, "No heartbeat for device (%s)\n", sb->s_id);
+		  status = -EINVAL;
+		  goto read_super_error;
+	}
+
 	sb->s_magic = OCFS2_SUPER_MAGIC;
 	sb->s_op = &ocfs_sops;
 	sb->s_export_op = &ocfs_export_ops;
 	sb->s_flags |= MS_NOATIME;
 	sb->s_fs_info = NULL;
 
-	status = ocfs_mount_volume(sb);
+	status = ocfs_mount_volume(sb, mount_opt);
 	/* ocfs_mount_volume may set osb even on error so we want to
 	 * pull it off for proper cleanup. */
 	osb = OCFS2_SB(sb);
+	if (osb && osb->root_inode)
+		inode = igrab(osb->root_inode);
 
 	if (status < 0)
 		goto read_super_error;
@@ -346,19 +385,16 @@
 		goto read_super_error;
 	}
 
-	inode = osb->root_inode;
 	if (!inode) {
 		status = -EIO;
 		mlog_errno(status);
 		goto read_super_error;
 	}
 
-	root = d_alloc_root (inode);
+	root = d_alloc_root(inode);
 	if (!root) {
 		status = -ENOMEM;
 		mlog_errno(status);
-		iput (inode);
-		inode = NULL;
 		goto read_super_error;
 	}
 
@@ -377,15 +413,15 @@
 	return status;		
 
 read_super_error:
+	if (inode)
+		iput(inode);
+
 	if (osb) {
 		atomic_set(&osb->vol_state, VOLUME_DISABLED);
 		wake_up(&osb->osb_mount_event);
-		ocfs_dismount_volume (sb);
+		ocfs_dismount_volume(sb, 1);
 	}
 
-	if (inode)
-		iput (inode);
-
 	mlog_exit(status);
 	return status;
 }
@@ -407,11 +443,61 @@
 	.next           = NULL
 };
 
+static int ocfs2_parse_options(char *options, unsigned long *mount_opt)
+{
+	int status;
+	char *p;
+
+	mlog_entry("options: \"%s\"\n", options ? options : "(none)");
+
+	if (!options) {
+		status = 1;
+		goto bail;
+	}
+
+	while ((p = strsep(&options, ",")) != NULL) {
+		int token, option;
+		substring_t args[MAX_OPT_ARGS];
+
+		if (!*p)
+			continue;
+
+		token = match_token(p, tokens, args);
+		switch (token) {
+		case Opt_hbok:
+			*mount_opt |= OCFS2_MOUNT_HB_OK;
+			break;
+		case Opt_barrier:
+			if (match_int(&args[0], &option)) {
+				status = 0;
+				goto bail;
+			}
+			if (option)
+				*mount_opt |= OCFS2_MOUNT_BARRIER;
+			else
+				*mount_opt &= ~OCFS2_MOUNT_BARRIER;
+			break;
+		default:
+			mlog(ML_ERROR,
+			     "Unrecognized mount option \"%s\" "
+			     "or missing value\n", p);
+			status = 0;
+			goto bail;
+		}
+	}
+
+	status = 1;
+
+bail:
+	mlog_exit(status);
+	return status;
+}
+
 static int __init ocfs2_init(void)
 {
 	int status;
 
-	mlog_entry_void ();
+	mlog_entry_void();
 
 	ocfs2_print_version();
 
@@ -425,9 +511,9 @@
 		goto leave;
 	}
 	
-	spin_lock (&ocfs2_globals_lock);
+	spin_lock(&ocfs2_globals_lock);
 	osb_id = 0;
-	spin_unlock (&ocfs2_globals_lock);
+	spin_unlock(&ocfs2_globals_lock);
 
 	/* Initialize the proc interface */
 	ocfs_proc_init();
@@ -438,10 +524,10 @@
 		exit_ocfs2_extent_maps();
 	}
 
-	mlog_exit (status);
+	mlog_exit(status);
 
 	if (status >= 0) {
-		return register_filesystem (&ocfs_fs_type);
+		return register_filesystem(&ocfs_fs_type);
 	} else
 		return -1;
 }
@@ -449,18 +535,18 @@
 static void __exit ocfs2_exit(void)
 {
 
-	mlog_entry_void ();
+	mlog_entry_void();
 
 	ocfs_free_mem_caches();
 
 	/* Deinit the proc interface */
-	ocfs_proc_deinit ();
+	ocfs_proc_deinit();
 
-	unregister_filesystem (&ocfs_fs_type);
+	unregister_filesystem(&ocfs_fs_type);
 
 	exit_ocfs2_extent_maps();
 
-	mlog_exit_void ();
+	mlog_exit_void();
 }
 
 
@@ -468,14 +554,14 @@
  * ocfs_put_super()
  *
  */
-static void ocfs_put_super (struct super_block *sb)
+static void ocfs_put_super(struct super_block *sb)
 {
-	mlog_entry ("(0x%p)\n", sb);
+	mlog_entry("(0x%p)\n", sb);
 
 	ocfs_sync_blockdev(sb);
-	ocfs_dismount_volume (sb);
+	ocfs_dismount_volume(sb, 0);
 
-	mlog_exit_void ();
+	mlog_exit_void();
 }				/* ocfs_put_super */
 
 
@@ -493,7 +579,7 @@
 	struct buffer_head *bh = NULL;
 	struct inode *inode = NULL;
 
-	mlog_entry ("(%p, %p)\n", sb, buf);
+	mlog_entry("(%p, %p)\n", sb, buf);
 
 	osb = OCFS2_SB(sb);
 
@@ -534,9 +620,9 @@
 	status = 0;
 bail:
 	if (inode)
-		iput (inode);
+		iput(inode);
 
-	mlog_exit (status);
+	mlog_exit(status);
 
 	return status;
 }                               /* ocfs_statfs */
@@ -653,8 +739,8 @@
 		     hdr->major_version, hdr->minor_version);
 		status = -EINVAL;
 	}
-	if (memcmp (hdr->signature, OCFS1_VOLUME_SIGNATURE,
-		    strlen (OCFS1_VOLUME_SIGNATURE)) == 0) {
+	if (memcmp(hdr->signature, OCFS1_VOLUME_SIGNATURE,
+		   strlen(OCFS1_VOLUME_SIGNATURE)) == 0) {
 		mlog(ML_ERROR, "incompatible volume signature: %8s\n",
 		     hdr->signature);
 		status = -EINVAL;
@@ -742,14 +828,14 @@
  * ocfs_mount_volume()
  *
  */
-static int ocfs_mount_volume (struct super_block *sb)
+static int ocfs_mount_volume(struct super_block *sb, unsigned long mount_opt)
 {
 	int status, sector_size;
 	int unlock_super = 0;
 	ocfs_super *osb = NULL;
 	struct buffer_head *bh = NULL;
 
-	mlog_entry_void ();
+	mlog_entry_void();
 
 	/* probe for superblock */
 	status = ocfs2_sb_probe(sb, &bh, &sector_size);
@@ -768,6 +854,8 @@
 	sb->s_fs_info = osb;
 	osb->sb = sb;
 
+	osb->s_mount_opt = mount_opt;
+
 	/* Save off for ocfs_rw_direct */
 	osb->s_sectsize_bits = blksize_bits(sector_size);
 	if (!osb->s_sectsize_bits)
@@ -829,12 +917,12 @@
 	}
 
 	/* Add proc entry for this volume */
-	ocfs_proc_add_volume (osb);
+	ocfs_proc_add_volume(osb);
 
 	/* Read the publish sector for this node and cleanup dirent being */
 	/* modified when we crashed. */
 	mlog(0, "ocfs_check_volume...\n");
-	status = ocfs_check_volume (osb);
+	status = ocfs_check_volume(osb);
 	if (status < 0) {
 		mlog_errno(status);
 		goto leave;
@@ -861,7 +949,7 @@
 
 	if (bh != NULL)
 		brelse(bh);
-	mlog_exit (status);
+	mlog_exit(status);
 	return status;
 }				/* ocfs_mount_volume */
 
@@ -879,12 +967,12 @@
  * ocfs_dismount_volume()
  *
  */
-static void ocfs_dismount_volume (struct super_block *sb)
+static void ocfs_dismount_volume(struct super_block *sb, int mnt_err)
 {
 	int tmp;
 	ocfs_super *osb = NULL;
 
-	mlog_entry ("(0x%p)\n", sb);
+	mlog_entry("(0x%p)\n", sb);
 
 	OCFS_ASSERT(sb);
 	osb = OCFS2_SB(sb);
@@ -928,7 +1016,8 @@
 		if (tmp < 0)
 			mlog_errno(tmp);
 
-		ocfs2_put_slot(osb);
+		if (osb->slot_num != OCFS_INVALID_NODE_NUM)
+			ocfs2_put_slot(osb);
 	}
 
 	ocfs_release_system_inodes(osb);
@@ -941,7 +1030,8 @@
 
 	ocfs2_clear_hb_callbacks(osb);
 
-	ocfs2_stop_heartbeat(osb);
+	if (!mnt_err)
+		ocfs2_stop_heartbeat(osb);
 
 	atomic_set(&osb->vol_state, VOLUME_DISMOUNTED);
 
@@ -951,6 +1041,7 @@
 	ocfs_delete_osb(osb);
 	kfree(osb);
 	sb->s_dev = 0;
+	sb->s_fs_info = NULL;
 }				/* ocfs_dismount_volume */
 
 static int osb_setup_uuid(ocfs_super *osb, const unsigned char *uuid,
@@ -972,7 +1063,7 @@
 		ret = snprintf(ptr, 3, "%02X", uuid[i]);
 		if (ret != 2) /* drop super cleans up */
 			return -EINVAL;
-		/* then only advace past the last char */
+		/* then only advance past the last char */
 		ptr += 2;
 	}
 
@@ -992,7 +1083,7 @@
 	struct buffer_head *bitmap_bh = NULL;
 	ocfs_journal *journal;
 
-	mlog_entry_void ();
+	mlog_entry_void();
 
 	INIT_LIST_HEAD(&osb->osb_net_handlers);
 	init_waitqueue_head(&osb->recovery_event);
@@ -1023,14 +1114,14 @@
 	snprintf(osb->dev_str, sizeof(osb->dev_str), "%u,%u",
 		 MAJOR(osb->sb->s_dev), MINOR(osb->sb->s_dev));
 
-	init_MUTEX (&(osb->recovery_lock));
+	init_MUTEX(&osb->recovery_lock);
 
 	osb->disable_recovery = 0;
 	osb->recovery_thread_task = NULL;
 
-	init_waitqueue_head (&osb->checkpoint_event);
-	atomic_set (&osb->needs_checkpoint, 0);
-	atomic_set (&osb->clean_buffer_seq, 1);
+	init_waitqueue_head(&osb->checkpoint_event);
+	atomic_set(&osb->needs_checkpoint, 0);
+	atomic_set(&osb->clean_buffer_seq, 1);
 
 	osb->node_num = OCFS_INVALID_NODE_NUM;
 	osb->slot_num = OCFS_INVALID_NODE_NUM;
@@ -1038,14 +1129,17 @@
 	osb->local_alloc_state = OCFS2_LA_UNUSED;
 	osb->local_alloc_bh = NULL;
 
+	ocfs2_setup_hb_callbacks(osb);
+
 	init_waitqueue_head(&osb->osb_mount_event);
 	
-	osb->vol_label = kmalloc(64, GFP_KERNEL);
+	osb->vol_label = kmalloc(OCFS2_MAX_VOL_LABEL_LEN, GFP_KERNEL);
 	if (!osb->vol_label) {
 		mlog(ML_ERROR, "unable to alloc vol label\n");
 		status = -ENOMEM;
 		goto bail;
 	}
+
 	osb->uuid = kmalloc(OCFS2_VOL_UUID_LEN, GFP_KERNEL);
 	if (!osb->uuid) {
 		mlog(ML_ERROR, "unable to alloc uuid\n");
@@ -1124,11 +1218,19 @@
 	journal->j_state = OCFS_JOURNAL_FREE;
 
 	/* get some pseudo constants for clustersize bits */
-	osb->s_clustersize_bits = le32_to_cpu(di->id2.i_super.s_clustersize_bits);
+	osb->s_clustersize_bits =
+		le32_to_cpu(di->id2.i_super.s_clustersize_bits);
 	osb->s_clustersize = 1 << osb->s_clustersize_bits;
 	mlog(0, "clusterbits=%d\n", osb->s_clustersize_bits);
-	OCFS_ASSERT(osb->s_clustersize_bits);
 
+	if (osb->s_clustersize < OCFS2_MIN_CLUSTERSIZE ||
+	    osb->s_clustersize > OCFS2_MAX_CLUSTERSIZE) {
+		mlog(ML_ERROR, "Volume has invalid cluster size (%d)\n",
+		     osb->s_clustersize);
+		status = -EINVAL;
+		goto bail;
+	}
+
 	if (ocfs2_clusters_to_blocks(osb->sb, di->i_clusters - 1)
 	    > (u32)~0UL) {
 		mlog(ML_ERROR, "Volume might try to write to blocks beyond "
@@ -1148,14 +1250,15 @@
 	osb->vol_label[63] = '\0';
 	osb->root_blkno = le64_to_cpu(di->id2.i_super.s_root_blkno);
 	osb->system_dir_blkno = le64_to_cpu(di->id2.i_super.s_system_dir_blkno);
-	osb->first_cluster_group_blkno = le64_to_cpu(di->id2.i_super.s_first_cluster_group);
+	osb->first_cluster_group_blkno =
+		le64_to_cpu(di->id2.i_super.s_first_cluster_group);
 	osb->fs_generation = le32_to_cpu(di->i_fs_generation);
 	mlog(0, "vol_label: %s\n", osb->vol_label);
 	mlog(0, "uuid: %s\n", osb->uuid_str);
 	mlog(0, "root_blkno=%"MLFu64", system_dir_blkno=%"MLFu64"\n",
 	     osb->root_blkno, osb->system_dir_blkno);
 
-	atomic_set (&osb->vol_state, VOLUME_INIT);
+	atomic_set(&osb->vol_state, VOLUME_INIT);
 
 	/* load root, system_dir, and all global system inodes */
 	status = ocfs_init_global_system_inodes(osb);
@@ -1175,8 +1278,9 @@
 	}
 
 	if (inode->i_size >> osb->sb->s_blocksize_bits < OCFS2_MAX_NODES) {
-		mlog(ML_ERROR, "heartbeat area size incorrect: found=%llu, "
-		     "need=%u\n", inode->i_size,
+		mlog(ML_ERROR,
+		     "heartbeat area size incorrect: found=%llu, need=%u\n",
+		     inode->i_size,
 		     OCFS2_MAX_NODES << osb->sb->s_blocksize_bits);
 		status = -EINVAL;
 		goto bail;
@@ -1223,15 +1327,13 @@
 	if (osb_id < OCFS_MAX_OSB_ID)
 		osb_id++;
 	else {
-		spin_unlock (&ocfs2_globals_lock);
 		mlog(ML_ERROR, "Too many volumes mounted\n");
 		status = -ENOMEM;
-		goto bail;
 	}
-	spin_unlock (&ocfs2_globals_lock);
+	spin_unlock(&ocfs2_globals_lock);
 
 bail:
-	mlog_exit (status);
+	mlog_exit(status);
 	return status;
 }				/* ocfs_initialize_osb */
 
@@ -1246,7 +1348,7 @@
 {
 	int status = -EAGAIN;
 
-	mlog_entry_void ();
+	mlog_entry_void();
 
 	if (memcmp(di->i_signature, OCFS2_SUPER_BLOCK_SIGNATURE,
 		   strlen(OCFS2_SUPER_BLOCK_SIGNATURE)) == 0) {
@@ -1289,7 +1391,7 @@
 		}
 	}
 
-	mlog_exit (status);
+	mlog_exit(status);
 	return status;
 }				/* ocfs_verify_volume */
 
@@ -1297,7 +1399,7 @@
  * ocfs_check_volume()
  *
  */
-static int ocfs_check_volume (ocfs_super * osb)
+static int ocfs_check_volume(ocfs_super *osb)
 {
 	int status = 0;
 	int dirty;
@@ -1305,7 +1407,7 @@
 					   * recover
 					   * ourselves. */
 
-	mlog_entry_void ();
+	mlog_entry_void();
 
 	/* Init our journal object. */
 	status = ocfs_journal_init(osb->journal, &dirty);
@@ -1371,7 +1473,7 @@
 	if (local_alloc)
 		kfree(local_alloc);
 
-	mlog_exit (status);
+	mlog_exit(status);
 	return status;
 }				/* ocfs_check_volume */
 
@@ -1384,9 +1486,9 @@
  * It will remove the osb from the global list and also free up all the
  * initialized resources and fileobject.
  */
-static void ocfs_delete_osb (ocfs_super * osb)
+static void ocfs_delete_osb(ocfs_super *osb)
 {
-	mlog_entry_void ();
+	mlog_entry_void();
 
 	/* This function assumes that the caller has the main osb resource */
 
@@ -1402,9 +1504,9 @@
 	if (osb->local_alloc_copy)
 		kfree(osb->local_alloc_copy);
 	kfree(osb->uuid_str);
-	memset (osb, 0, sizeof (ocfs_super));
+	memset(osb, 0, sizeof(ocfs_super));
 
-	mlog_exit_void ();
+	mlog_exit_void();
 }				/* ocfs_delete_osb */
 
 



More information about the Ocfs2-commits mailing list