[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(¤t->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