[Ocfs2-commits] mfasheh commits r1263 - trunk/src

svn-commits at oss.oracle.com svn-commits at oss.oracle.com
Wed Jul 14 21:38:42 CDT 2004


Author: mfasheh
Date: 2004-07-14 20:38:40 -0500 (Wed, 14 Jul 2004)
New Revision: 1263

Modified:
   trunk/src/inode.c
   trunk/src/journal.c
   trunk/src/journal.h
   trunk/src/ocfs.h
   trunk/src/super.c
Log:
* we can recover inodes from the orphan dir now on another nodes
  crash, or when we come up and notice that we've crashed before.

* rename ocfs_recover_vol to ocfs_recover_node. yes, i like it better
  that way.



Modified: trunk/src/inode.c
===================================================================
--- trunk/src/inode.c	2004-07-15 00:07:54 UTC (rev 1262)
+++ trunk/src/inode.c	2004-07-15 01:38:40 UTC (rev 1263)
@@ -49,6 +49,7 @@
 #include "namei.h"
 #include "super.h"
 #include "symlink.h"
+#include "sysfile.h"
 #include "util.h"
 #include "vote.h"
 
@@ -341,6 +342,7 @@
 	INIT_LIST_HEAD(&i->ip_recovery_list);
 	INIT_LIST_HEAD(&i->ip_handle_list);
 	i->ip_handle = NULL;
+	i->ip_next_orphan = NULL;
 
 	init_rwsem(&i->ip_io_sem);
 

Modified: trunk/src/journal.c
===================================================================
--- trunk/src/journal.c	2004-07-15 00:07:54 UTC (rev 1262)
+++ trunk/src/journal.c	2004-07-15 01:38:40 UTC (rev 1263)
@@ -41,6 +41,7 @@
 #include "extmap.h"
 #include "inode.h"
 #include "journal.h"
+#include "namei.h"
 #include "nm.h"
 #include "super.h"
 #include "util.h"
@@ -62,7 +63,7 @@
 static int ocfs_handle_release_locks(ocfs_journal_handle *handle, release_locks_action action);
 static int ocfs_force_read_journal(ocfs_super *osb, __u64 size, 
 				   struct inode *inode);
-static int ocfs_recover_vol(struct _ocfs_super *osb, int node_num);
+static int ocfs_recover_node(struct _ocfs_super *osb, int node_num);
 static int __ocfs_recovery_thread(void *arg);
 static int ocfs_commit_cache (ocfs_super * osb, int data_flush);
 static int ocfs_wait_on_mount(ocfs_super *osb);
@@ -1377,7 +1378,7 @@
 	spin_unlock_irq(&current->sigmask_lock);
 #endif	
 
-	status = ocfs_recover_vol(osb, node_num);
+	status = ocfs_recover_node(osb, node_num);
 	if (status < 0)
 		LOG_ERROR_STATUS(status);
 
@@ -1417,16 +1418,17 @@
 	return;
 }
 
-static int ocfs_recover_vol(ocfs_super *osb, int node_num) 
+static int ocfs_recover_node(ocfs_super *osb, int node_num) 
 {
 	int status = -1;
+	int tmpstat;
 	__u64 lock_id = 0;
 	ocfs2_dinode *fe;
 	struct inode *inode = NULL;
 	journal_t *k_journal = NULL;
 	struct buffer_head *bh = NULL;
 	ocfs_journal * journal = NULL;
-	int recovery_lock = 0, got_lock = 0;
+	int recovery_lock = 0, got_lock = 0, clean_orphans = 0;
 	__u64 alloc_size;
 	ocfs_bitmap_free_head *bits_to_free = NULL;
 
@@ -1498,6 +1500,7 @@
 	}
 	printk("ocfs2: Recovering node %d from device (%u,%u)\n", node_num, 
 	       MAJOR(osb->sb->s_dev), MINOR(osb->sb->s_dev));
+	clean_orphans = 1;
 
 	fe = (ocfs2_dinode *) bh->b_data;
 	/* gonna need this later */
@@ -1580,17 +1583,26 @@
 	if (got_lock) {
 		down_write(&OCFS_I(inode)->ip_io_sem);
 
-		status = ocfs_release_lock(osb, OCFS_LKM_EXMODE, 
+		tmpstat = ocfs_release_lock(osb, OCFS_LKM_EXMODE, 
 					   FLAG_FILE_CREATE|FLAG_FILE_RECOVERY,
 					   bh, inode);
-		up_write(&OCFS_I(inode)->ip_io_sem);
+		up_write(&OCFS_I(inode)->ip_io_sem);	
+		if (tmpstat < 0)
+			LOG_ERROR_STATUS(tmpstat);
 	}
+
 	if (inode)
 		iput(inode);
 
 	if (bh)
 		brelse(bh);
 
+	if (clean_orphans && !status) {
+		tmpstat = ocfs_recover_orphans(osb);
+		if (tmpstat < 0)
+			LOG_ERROR_STATUS(tmpstat);
+	}
+
 	/* Free bits from the bitmaps only after the node has been
 	 * removed from the recovery map. */
 	if (bits_to_free) {
@@ -1606,6 +1618,149 @@
 	return(status);
 }
 
+int ocfs_recover_orphans(ocfs_super *osb)
+{
+	int status = 0;
+	int have_disk_lock = 0;
+	int tmpstat;
+	struct inode *inode = NULL;
+	struct inode *iter;
+	struct inode *orphan_dir_inode = NULL;
+	unsigned long offset, blk, local;
+	struct buffer_head *bh = NULL;
+	struct ocfs2_dir_entry *de;
+	struct super_block *sb = osb->sb;
+
+	down(&osb->orphan_recovery_lock);
+
+	orphan_dir_inode = ocfs_get_system_file_inode(osb, 
+						      ORPHAN_DIR_SYSTEM_INODE, 
+						      -1);
+	if  (!orphan_dir_inode) {
+		status = -EFAIL;
+		LOG_ERROR_STATUS(status);
+		goto bail;
+	}
+
+	down_write(&OCFS_I(orphan_dir_inode)->ip_io_sem);
+	status = ocfs_acquire_lock(osb, 
+				   OCFS_LKM_EXMODE,
+				   FLAG_DIR|FLAG_READDIR, 
+				   NULL, 
+				   orphan_dir_inode);
+	if (status < 0) {
+		LOG_ERROR_STATUS(status);
+		goto bail;
+	}
+	have_disk_lock = 1;
+
+	/* Could we possibly have i_size out of sync? */
+	status = ocfs_verify_update_inode(osb, orphan_dir_inode, 0);
+	if (status < 0) {
+		LOG_ERROR_STATUS(status);
+		goto bail;
+	}
+
+	offset = 0;
+	iter = NULL;
+	while(offset < orphan_dir_inode->i_size) {
+		blk = offset >> sb->s_blocksize_bits;
+
+		bh = ocfs_bread(NULL, orphan_dir_inode, blk, 0, &status, 0);
+		if (!bh)
+			status = -EINVAL;
+		if (status < 0) {
+			if (bh)
+				brelse(bh);
+			LOG_ERROR_STATUS(status);
+			goto bail;
+		}
+
+		local = 0;
+		while(offset < orphan_dir_inode->i_size
+		      && local < sb->s_blocksize) {
+			de = (struct ocfs2_dir_entry *) (bh->b_data + local);
+
+			if (!ocfs_check_dir_entry(orphan_dir_inode,
+						  de, bh, local)) {
+				status = -EINVAL;
+				LOG_ERROR_STATUS(status);
+				brelse (bh);
+				goto bail;
+			}
+
+			local += le16_to_cpu(de->rec_len);
+			offset += le16_to_cpu(de->rec_len);
+
+			/* I guess we silently fail on no inode? */
+			if (!le64_to_cpu(de->inode))
+				continue;
+			if (de->file_type > OCFS2_FT_MAX) {
+				LOG_ERROR_ARGS("block %llu contains invalid "
+					       "de: inode = %llu, rec_len = "
+					       "%u, name_len = %u, file_type "
+					       "= %u, name='%*s'\n", 
+					       (unsigned long long) bh->b_blocknr, 
+					       de->inode, 
+					       de->rec_len, 
+					       de->name_len, 
+					       de->file_type, 
+					       de->name_len, 
+					       de->name);
+				continue;
+			}
+			if (de->name_len == 1 && !strncmp(".", de->name, 1))
+				continue;
+			if (de->name_len == 2 && !strncmp("..", de->name, 2))
+				continue;
+
+			iter = ocfs_iget(osb, de->inode);
+			if (!iter) 
+				continue;
+
+			OCFS_I(iter)->ip_next_orphan = inode;
+			inode = iter;
+		}
+		brelse(bh);
+	}
+
+	status = ocfs_release_lock (osb, OCFS_LKM_EXMODE,
+				    FLAG_DIR|FLAG_READDIR, NULL, 
+				    orphan_dir_inode);
+	have_disk_lock = 0;
+	if (status < 0) {
+		LOG_ERROR_STATUS(status);
+		goto bail;
+	}
+
+	up_write(&OCFS_I(orphan_dir_inode)->ip_io_sem);
+	iput(orphan_dir_inode);
+	orphan_dir_inode = NULL;
+
+	while (inode) {
+		iter = OCFS_I(inode)->ip_next_orphan;
+		iput(inode);
+		inode = iter;
+	}
+
+bail:
+	up(&osb->orphan_recovery_lock);
+
+	if (have_disk_lock) {
+		tmpstat = ocfs_release_lock (osb, OCFS_LKM_EXMODE,
+					     FLAG_DIR|FLAG_READDIR, NULL, 
+					     orphan_dir_inode);
+		if (tmpstat < 0)
+			LOG_ERROR_STATUS(tmpstat);
+	}
+
+	if (orphan_dir_inode) {
+		up_write(&OCFS_I(orphan_dir_inode)->ip_io_sem);
+		iput(orphan_dir_inode);
+	}
+	return(status);
+}
+
 static int ocfs_wait_on_mount(ocfs_super *osb)
 {
 
@@ -1633,7 +1788,7 @@
  * ocfs_reset_publish()
  *
  *
- * called by: old_ocfs_recover_vol()
+ * called by: old_ocfs_recover_node()
  *
  * NOTE: This function is unused. I keep it here because it may be
  * useful in the future. --Mark (Sept. 22, 2003)

Modified: trunk/src/journal.h
===================================================================
--- trunk/src/journal.h	2004-07-15 00:07:54 UTC (rev 1262)
+++ trunk/src/journal.h	2004-07-15 01:38:40 UTC (rev 1263)
@@ -30,5 +30,6 @@
 #define OCFS2_JOURNAL_H
 
 int ocfs_commit_thread(void *arg);
+int ocfs_recover_orphans(ocfs_super *osb);
 
 #endif /* OCFS2_JOURNAL_H */

Modified: trunk/src/ocfs.h
===================================================================
--- trunk/src/ocfs.h	2004-07-15 00:07:54 UTC (rev 1262)
+++ trunk/src/ocfs.h	2004-07-15 01:38:40 UTC (rev 1263)
@@ -444,6 +444,9 @@
 		} ip_bitinfo;
 	} u;
 
+	/* protected by recovery_lock. */
+	struct inode      *ip_next_orphan;
+
 	ocfs_lock_res     ip_lockres;
 	__u32 		  ip_dir_start_lookup;
 } ocfs_inode_private;
@@ -595,6 +598,7 @@
 
 	ocfs_alloc_bm cluster_bitmap;
 	atomic_t vol_state;
+	struct semaphore orphan_recovery_lock;
 	struct semaphore recovery_lock;
 	spinlock_t recovery_map_lock;
 	ocfs_node_map recovery_map;

Modified: trunk/src/super.c
===================================================================
--- trunk/src/super.c	2004-07-15 00:07:54 UTC (rev 1262)
+++ trunk/src/super.c	2004-07-15 01:38:40 UTC (rev 1263)
@@ -1422,6 +1422,7 @@
 
 	init_MUTEX (&(osb->osb_res));
 	init_MUTEX (&(osb->recovery_lock));
+	init_MUTEX (&(osb->orphan_recovery_lock));
 	init_MUTEX (&(osb->comm_lock));
 	init_MUTEX (&(osb->extend_sem));
 	init_MUTEX (&(osb->cfg_lock));
@@ -1865,6 +1866,12 @@
 	if (status < 0)
 		LOG_ERROR_STATUS(status);
 
+	if (mounted) {
+		status = ocfs_recover_orphans(osb);
+		if (status < 0)
+			LOG_ERROR_STATUS(status);
+	}
+
 finally:
 	if (publish_bh)
 		brelse(publish_bh);



More information about the Ocfs2-commits mailing list