[Ocfs2-commits] jlbec commits r958 - in trunk/src: . inc
svn-commits at oss.oracle.com
svn-commits at oss.oracle.com
Fri May 28 20:02:27 CDT 2004
Author: jlbec
Date: 2004-05-28 19:02:26 -0500 (Fri, 28 May 2004)
New Revision: 958
Removed:
trunk/src/osb.c
Modified:
trunk/src/Makefile
trunk/src/file.c
trunk/src/inc/io.h
trunk/src/inc/journal.h
trunk/src/inc/ocfs.h
trunk/src/inc/proto.h
trunk/src/io.c
trunk/src/journal.c
trunk/src/nm.c
trunk/src/super.c
trunk/src/util.c
Log:
o Some header reordering.
o osb.c is folded into super.c
o osb->journal is now allocated. It's done in initialize_osb() and not
journal_init() because the OCFS mount/unmount code is just way screwey
Modified: trunk/src/Makefile
===================================================================
--- trunk/src/Makefile 2004-05-28 00:55:33 UTC (rev 957)
+++ trunk/src/Makefile 2004-05-29 00:02:26 UTC (rev 958)
@@ -141,7 +141,6 @@
lockres.c \
namei.c \
nm.c \
- osb.c \
proc.c \
super.c \
symlink.c \
Modified: trunk/src/file.c
===================================================================
--- trunk/src/file.c 2004-05-28 00:55:33 UTC (rev 957)
+++ trunk/src/file.c 2004-05-29 00:02:26 UTC (rev 958)
@@ -570,7 +570,7 @@
if (err)
goto bail;
- journal = osb->journal.k_journal;
+ journal = osb->journal->k_journal;
err = journal_force_commit(journal);
bail:
Modified: trunk/src/inc/io.h
===================================================================
--- trunk/src/inc/io.h 2004-05-28 00:55:33 UTC (rev 957)
+++ trunk/src/inc/io.h 2004-05-29 00:02:26 UTC (rev 958)
@@ -54,8 +54,6 @@
int flags,
struct inode *inode);
-void ocfs_end_buffer_io_sync (struct buffer_head *bh,
- int uptodate);
#define OCFS_BH_CACHED 1
#define OCFS_BH_COND_CACHED 2
Modified: trunk/src/inc/journal.h
===================================================================
--- trunk/src/inc/journal.h 2004-05-28 00:55:33 UTC (rev 957)
+++ trunk/src/inc/journal.h 2004-05-29 00:02:26 UTC (rev 958)
@@ -205,15 +205,6 @@
rv; \
})
-/*
- * Journal Configuration Management:
- * These are normally called at mount and unmount time.
- *
- * ocfs_journal_set_mounted - set the mounted flag for the current node.
- * ocfs_journal_set_unmounted - unset the mounted flag for the current node.
- */
-int ocfs_journal_set_mounted(struct _ocfs_super *osb, int node_num);
-int ocfs_journal_set_unmounted(struct _ocfs_super *osb, int node_num);
/*
* Journal Control:
Modified: trunk/src/inc/ocfs.h
===================================================================
--- trunk/src/inc/ocfs.h 2004-05-28 00:55:33 UTC (rev 957)
+++ trunk/src/inc/ocfs.h 2004-05-29 00:02:26 UTC (rev 958)
@@ -1690,7 +1690,7 @@
struct list_head needs_flush_head;
wait_queue_head_t flush_event;
atomic_t flush_event_woken;
- struct _ocfs_journal journal;
+ struct _ocfs_journal *journal;
atomic_t clean_buffer_seq;
spinlock_t clean_buffer_lock;
struct list_head lock_recovery_lists[OCFS_MAXIMUM_NODES];
@@ -2456,6 +2456,22 @@
#define ocfs_trace(p) do { printk("Trace in %s line %d called from [<%lx>]\n", __FILE__, __LINE__, __builtin_return_address(0) ); ocfs_show_trace(NULL); } while (0)
+
+/*
+ * Trans Lock:
+ * Right now OCFS2 only supports a single transaction at a
+ * time. Transactions are locked out by using trans_lock.
+ */
+static inline void ocfs_take_trans_lock(ocfs_super *osb)
+{
+ down(&osb->trans_lock);
+}
+
+static inline void ocfs_release_trans_lock(ocfs_super *osb)
+{
+ up(&osb->trans_lock);
+}
+
#include "proto.h"
#endif /* !OCFS_H */
Modified: trunk/src/inc/proto.h
===================================================================
--- trunk/src/inc/proto.h 2004-05-28 00:55:33 UTC (rev 957)
+++ trunk/src/inc/proto.h 2004-05-29 00:02:26 UTC (rev 958)
@@ -301,14 +301,6 @@
void ocfs_recover_oin_locks(ocfs_super *osb, __u32 node_num);
int ocfs_volume_thread(void *arg);
-/* osb.c */
-/* FIXME: should fold osb.c into super.c */
-int ocfs_check_volume(ocfs_super *osb);
-void ocfs_delete_osb(ocfs_super *osb);
-int ocfs_initialize_osb(ocfs_super *osb, ocfs_vol_disk_hdr *vdh,
- ocfs_vol_label *vol_label, __u32 sect_size);
-int ocfs_verify_volume(ocfs_vol_disk_hdr *vdh);
-
/* proc.c */
void ocfs_proc_add_volume(ocfs_super *osb);
void ocfs_proc_deinit(void);
@@ -316,8 +308,11 @@
void ocfs_proc_remove_volume(ocfs_super *osb);
/* super.c */
+void ocfs_delete_osb(ocfs_super *osb);
int ocfs_dismount_volume(struct super_block *sb);
+int ocfs_publish_get_mount_state(ocfs_super *osb, int node_num);
+
/* symlink.c */
int ocfs_follow_link(struct dentry *dentry, struct nameidata *nd);
@@ -339,7 +334,6 @@
void ocfs_daemonize(char *name, int len);
void *ocfs_dbg_slab_alloc(kmem_cache_t *slab, char *file, int line);
void ocfs_dbg_slab_free(kmem_cache_t *slab, void *m);
-void ocfs_end_buffer_io_sync(struct buffer_head *bh, int uptodate);
void ocfs_init_timeout(ocfs_timeout *to);
void *ocfs_linux_dbg_alloc(int Size, char *file, int line);
void ocfs_linux_dbg_free(const void *Buffer);
@@ -364,6 +358,8 @@
ocfs_vote_obj_lookup_data *data);
int ocfs_lookup_obj_by_lockid(ocfs_vote_obj *obj,
ocfs_vote_obj_lookup_data *data);
+int ocfs_lookup_vote_request_obj(ocfs_super *osb,
+ ocfs_vote_obj_lookup_data *data);
void ocfs_process_one_vote_reply(ocfs_super *osb,
ocfs_vote_reply_ctxt *ctxt,
__u32 node_num);
Modified: trunk/src/io.c
===================================================================
--- trunk/src/io.c 2004-05-28 00:55:33 UTC (rev 957)
+++ trunk/src/io.c 2004-05-29 00:02:26 UTC (rev 958)
@@ -28,7 +28,26 @@
#define OCFS_DEBUG_CONTEXT OCFS_DEBUG_CONTEXT_IO
+static void ocfs_end_buffer_io_sync(struct buffer_head *bh,
+ int uptodate)
+{
+// LOG_ENTRY_ARGS("(bh->b_blocknr = %u, uptodate = %d)\n", bh->b_blocknr,
+// uptodate);
+ if (!uptodate)
+ LOG_ERROR_STATUS(-EIO);
+
+ if (uptodate)
+ set_buffer_uptodate(bh);
+ else
+ clear_buffer_uptodate(bh);
+ unlock_buffer(bh);
+
+// LOG_EXIT();
+ return;
+}
+
+
int ocfs_write_bhs (ocfs_super * osb, struct buffer_head *bhs[],
int nr, int flags, struct inode *inode)
{
@@ -312,3 +331,6 @@
LOG_EXIT_STATUS(status);
return status;
}
+
+
+
Modified: trunk/src/journal.c
===================================================================
--- trunk/src/journal.c 2004-05-28 00:55:33 UTC (rev 957)
+++ trunk/src/journal.c 2004-05-29 00:02:26 UTC (rev 958)
@@ -51,8 +51,6 @@
static int ocfs_checkpoint_handle(ocfs_journal_handle *handle);
static int ocfs_revoke_handle(ocfs_journal_handle *handle);
-static int ocfs_journal_toggle_mounted(ocfs_super *osb, int node_num, int value);
-static int ocfs_journal_get_mount_state(ocfs_super *osb, int node_num);
static int ocfs_reset_publish (ocfs_super * osb, __u64 node_num);
static int ocfs_journal_release_locks(ocfs_journal_handle *handle, release_locks_action action);
static int ocfs_force_read_journal(ocfs_super *osb, __u64 size,
@@ -65,11 +63,11 @@
ocfs_journal_handle * ocfs_start_trans(ocfs_super *osb, int max_buffs)
{
ocfs_journal_handle * retval = NULL;
- journal_t * journal = osb->journal.k_journal;
+ journal_t * journal = osb->journal->k_journal;
LOG_ENTRY_ARGS ("(max_buffs = %d)\n", max_buffs);
- if (!osb || !osb->journal.k_journal)
+ if (!osb || !osb->journal->k_journal)
BUG();
/* for now, we only do one transaction at a time. Eventually
@@ -106,7 +104,7 @@
retval->num_locks = 0;
retval->num_co = 0;
- retval->journal = &osb->journal;
+ retval->journal = osb->journal;
retval->osb = osb;
retval->commit_bits = NULL;
@@ -119,11 +117,11 @@
goto done_free;
}
- atomic_inc(&(osb->journal.num_trans));
+ atomic_inc(&(osb->journal->num_trans));
- down(&osb->journal.commit_sem);
- osb->journal.curr = retval;
- up(&osb->journal.commit_sem);
+ down(&osb->journal->commit_sem);
+ osb->journal->curr = retval;
+ up(&osb->journal->commit_sem);
/* default handle flags! */
ocfs_handle_set_sync(retval, 1);
@@ -293,7 +291,7 @@
osb = handle->osb;
- if (osb->journal.curr == handle)
+ if (osb->journal->curr == handle)
BUG();
LOG_TRACE_ARGS("num_locks = %d\n", handle->num_locks);
@@ -358,7 +356,7 @@
/* this can be called early in the first mount */
if (osb->vol_layout.root_start_off != 0 &&
lockid >= osb->vol_layout.root_start_off) {
- journal = &osb->journal;
+ journal = osb->journal;
down(&journal->commit_sem);
list_for_each(p1, &(journal->commited)) {
handle = list_entry(p1, ocfs_journal_handle, h_list);
@@ -411,7 +409,7 @@
osb = handle->osb;
kern_handle = handle->k_handle;
kern_trans = kern_handle->h_transaction;
- journal = &osb->journal;
+ journal = osb->journal;
checkpoint = handle->flags & OCFS_HANDLE_CHECKPOINT;
/* if you want to checkpoint, you MUST also sync. */
if (checkpoint)
@@ -476,7 +474,7 @@
if (checkpoint) {
up(&journal->commit_sem);
- atomic_dec(&(osb->journal.num_trans));
+ atomic_dec(&(osb->journal->num_trans));
/* Release locks associated with this handle. */
retval = ocfs_journal_release_locks(handle, TRANS_COMMIT);
@@ -545,7 +543,7 @@
LOG_ENTRY();
osb = handle->osb;
- journal = &osb->journal;
+ journal = osb->journal;
if (handle->num_co < handle->num_buffs)
BUG();
@@ -632,13 +630,13 @@
handle->k_handle = NULL;
- atomic_dec(&(osb->journal.num_trans));
+ atomic_dec(&(osb->journal->num_trans));
/* done: */
- down(&osb->journal.commit_sem);
- osb->journal.curr = NULL;
- up(&osb->journal.commit_sem);
+ down(&osb->journal->commit_sem);
+ osb->journal->curr = NULL;
+ up(&osb->journal->commit_sem);
if (handle->num_buffs) {
/* Ok, we now want to fill our buffers with the older (but
@@ -910,12 +908,9 @@
if (!osb)
BUG();
- /* initialize our journal structure */
- memset(&osb->journal, 0, sizeof(ocfs_journal));
+ INIT_LIST_HEAD(&(osb->journal->commited));
+ init_MUTEX(&(osb->journal->commit_sem));
- INIT_LIST_HEAD(&(osb->journal.commited));
- init_MUTEX(&(osb->journal.commit_sem));
-
lock_id = ((OCFS_JOURNAL_FILE + osb->node_num) * osb->sect_size) +
osb->vol_layout.root_int_off;
@@ -998,16 +993,16 @@
k_journal->j_commit_interval = OCFS_DEFAULT_COMMIT_INTERVAL;
/* yay, pass the proper info back to our journal structure. */
- osb->journal.osb = osb;
+ osb->journal->osb = osb;
/* eventually this will be a value passed into us */
- osb->journal.node_num = osb->node_num;
- osb->journal.k_journal = k_journal;
- osb->journal.k_inode = inode;
- osb->journal.version = OCFS_JOURNAL_CURRENT_VERSION;
- osb->journal.lockbh = bh;
- osb->journal.lock_id = lock_id;
- atomic_set(&(osb->journal.num_trans), 0);
- osb->journal.state = OCFS_JOURNAL_LOADED;
+ osb->journal->node_num = osb->node_num;
+ osb->journal->k_journal = k_journal;
+ osb->journal->k_inode = inode;
+ osb->journal->version = OCFS_JOURNAL_CURRENT_VERSION;
+ osb->journal->lockbh = bh;
+ osb->journal->lock_id = lock_id;
+ atomic_set(&(osb->journal->num_trans), 0);
+ osb->journal->state = OCFS_JOURNAL_LOADED;
status = 0;
done:
if (status < 0) {
@@ -1019,6 +1014,7 @@
if (inode)
OCFS_I(inode)->open_hndl_cnt--;
}
+
LOG_EXIT_STATUS(status);
return(status);
}
@@ -1038,7 +1034,7 @@
if (!osb)
BUG();
- journal = &osb->journal;
+ journal = osb->journal;
inode = journal->k_inode;
if (journal->state != OCFS_JOURNAL_LOADED) {
@@ -1050,7 +1046,7 @@
if (ocfs_inc_icount(inode) < 0)
BUG();
- num_running_trans = atomic_read(&(osb->journal.num_trans));
+ num_running_trans = atomic_read(&(osb->journal->num_trans));
if (num_running_trans > 0)
LOG_TRACE_ARGS("Shutting down journal: must wait on %d"
" running transactions!\n", num_running_trans);
@@ -1136,124 +1132,7 @@
return(status);
}
-/* true if mounted, false otherwise */
-static int ocfs_journal_get_mount_state(ocfs_super *osb, int node_num)
-{
- int status = 0;
- ocfs_publish *publish = NULL;
- struct buffer_head *publish_bh = NULL;
- __u64 offset = 0;
- int retval = 0;
- int flags = 0;
- LOG_ENTRY();
-
- /* read it in */
- offset = osb->vol_layout.publ_sect_off +
- (node_num * osb->sect_size);
- /* we may be called during mount in which case our publish
- * sector might be dirty. */
- if (node_num == osb->node_num)
- flags = OCFS_BH_CACHED;
- status = ocfs_read_bh(osb, offset, &publish_bh, flags, NULL);
- if (status < 0) {
- brelse(publish_bh);
- LOG_ERROR_STR("Could not read publish sector, mounted value"
- " may be incorrect!");
- LOG_ERROR_STATUS (status);
- goto done;
- }
- publish = (ocfs_publish *) OCFS_BH_GET_DATA_READ(publish_bh); /* read */
-
- retval = publish->mounted;
-
- OCFS_BH_PUT_DATA(publish_bh);
- brelse(publish_bh);
-done:
- LOG_EXIT_STATUS(retval);
- return(retval);
-}
-
-static int ocfs_journal_toggle_mounted(ocfs_super *osb, int node_num, int value)
-{
- int status = 0;
- ocfs_publish *publish = NULL;
- struct buffer_head * publish_bh = NULL;
- __u64 offset = 0;
-
- LOG_ENTRY_ARGS("(node_num=%d, value=%d)\n", node_num, value);
-
- /* read it in */
- offset = osb->vol_layout.publ_sect_off +
- (node_num * osb->sect_size);
- status = ocfs_read_bh(osb, offset, &publish_bh, 0, NULL);
- if (status < 0) {
- LOG_ERROR_STATUS (status);
- goto done;
- }
- publish = (ocfs_publish *) OCFS_BH_GET_DATA_WRITE(publish_bh); /* write */
-
- /* change it */
- publish->mounted = value;
- OCFS_BH_PUT_DATA(publish_bh);
-
- /* write it back out */
- status = ocfs_write_bh(osb, publish_bh, 0, NULL);
- if (status < 0) {
- LOG_ERROR_STATUS (status);
- goto done;
- }
-
-done:
- if (publish_bh)
- brelse(publish_bh);
-
- LOG_EXIT_STATUS(status);
-
- return(status);
-}
-
-/* set the 'mounted' bit in the publish sector */
-int ocfs_journal_set_mounted(ocfs_super *osb, int node_num)
-{
- int retval;
-
- LOG_ENTRY_ARGS("(node_num=%d)\n", node_num);
-
- down (&(osb->publish_lock));
-
- retval = ocfs_journal_toggle_mounted(osb, node_num, 1);
- if (osb->node_num == node_num)
- osb->check_mounted = 1;
-
- up (&(osb->publish_lock));
-
- LOG_EXIT_STATUS(retval);
-
- return(retval);
-}
-
-/* unset the 'mounted' bit in the publish sector */
-int ocfs_journal_set_unmounted(ocfs_super *osb, int node_num)
-{
- int retval;
-
- LOG_ENTRY_ARGS("(node_num=%d)\n", node_num);
-
- down (&(osb->publish_lock));
-
- if (osb->node_num == node_num)
- osb->check_mounted = 0;
-
- retval = ocfs_journal_toggle_mounted(osb, node_num, 0);
-
- up (&(osb->publish_lock));
-
- LOG_EXIT_STATUS(retval);
-
- return(retval);
-}
-
/* 'full' flag tells us whether we clear out all blocks or if we just
* mark the journal clean */
int ocfs_journal_wipe(ocfs_journal *journal, int full)
@@ -1457,7 +1336,7 @@
goto done;
}
- journal = &osb->journal;
+ journal = osb->journal;
/* Grab the local recovery resource to ensure no other thread
* comes in from this node for recovery */
@@ -1509,7 +1388,7 @@
/* check if that nodes publish sector has been reset (mounted
* is set false) if so, we can unlock and quit. otherwise we
* should recover. */
- if (!ocfs_journal_get_mount_state(osb, node_num)) {
+ if (!ocfs_publish_get_mount_state(osb, node_num)) {
LOG_TRACE_ARGS("No recovery required for node %d\n", node_num);
status = 0;
goto clear_node;
@@ -1679,7 +1558,7 @@
ocfs_super *osb = (ocfs_super *)arg;
ocfs_commit_task *commit = osb->commit;
char name[16];
- ocfs_journal * journal = &osb->journal;
+ ocfs_journal *journal = osb->journal;
siginfo_t info;
sprintf (name, "ocfs2cmt-%d", osb->osb_id);
@@ -1748,7 +1627,7 @@
misses = 0;
}
- status = ocfs_commit_cache (osb, 0);
+ status = ocfs_commit_cache(osb, 0);
if (status < 0)
LOG_ERROR_STATUS(status);
@@ -1778,7 +1657,7 @@
*
* In any case, it will release the trans lock for you.
*/
-static int ocfs_commit_cache (ocfs_super * osb, int data_flush)
+static int ocfs_commit_cache(ocfs_super *osb, int data_flush)
{
int status = 0, tmpstat;
ocfs_journal * journal = NULL;
@@ -1791,7 +1670,7 @@
if (down_trylock(&osb->trans_lock) == 0)
BUG();
- journal = &osb->journal;
+ journal = osb->journal;
if (atomic_read(&journal->num_trans) == 0) {
up(&osb->trans_lock);
Modified: trunk/src/nm.c
===================================================================
--- trunk/src/nm.c 2004-05-28 00:55:33 UTC (rev 957)
+++ trunk/src/nm.c 2004-05-29 00:02:26 UTC (rev 958)
@@ -514,7 +514,7 @@
data.func = ocfs_lookup_obj_by_lockid;
data.u.s.lock_id = lockid;
data.ret = NULL;
- if (ocfs_lookup_vote_request_obj (osb, &data) == 0)
+ if (ocfs_lookup_vote_request_obj(osb, &data) == 0)
my_node_wins = (node_num < osb->node_num);
}
@@ -581,7 +581,7 @@
LOG_ENTRY();
- journal = &osb->journal;
+ journal = osb->journal;
list_for_each(handle_p, &journal->commited) {
handle = list_entry(handle_p, ocfs_journal_handle, h_list);
@@ -909,6 +909,7 @@
case RELEASE_CACHE:
case CHANGE_MASTER:
+#warning nm thread could get this too early
if (vote_type == RELEASE_CACHE)
LOG_TRACE_STR("RELEASE_CACHE");
else
@@ -920,13 +921,13 @@
if (lockres->lock_holders > 0) {
LOG_TRACE_ARGS("Lock id (%llu) has %u holders\n",
GET_INODE_FEOFF(inode), lockres->lock_holders);
- down(&(osb->journal.commit_sem));
+ down(&(osb->journal->commit_sem));
if (ocfs_search_commited(osb, inode)) {
// kick the commit thread
- atomic_set (&osb->flush_event_woken, 1);
- wake_up (&osb->flush_event);
+ atomic_set(&osb->flush_event_woken, 1);
+ wake_up(&osb->flush_event);
}
- up(&(osb->journal.commit_sem));
+ up(&(osb->journal->commit_sem));
vote_response = FLAG_VOTE_UPDATE_RETRY;
status = 0;
break;
Deleted: trunk/src/osb.c
===================================================================
--- trunk/src/osb.c 2004-05-28 00:55:33 UTC (rev 957)
+++ trunk/src/osb.c 2004-05-29 00:02:26 UTC (rev 958)
@@ -1,450 +0,0 @@
-/*
- * osb.c
- *
- * Initialize, verify osb
- *
- * Copyright (C) 2002, 2004 Oracle. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public
- * License along with this program; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 021110-1307, USA.
- *
- * Authors: Kurt Hackel, Mark Fasheh, Sunil Mushran, Wim Coekaerts,
- * Manish Singh, Neeraj Goyal, Suchit Kaura
- */
-
-#include "inc/ocfs.h"
-
-#define OCFS_DEBUG_CONTEXT OCFS_DEBUG_CONTEXT_OSB
-
-extern spinlock_t osb_id_lock;
-extern __u32 osb_id;
-
-/*
- * ocfs_initialize_osb()
- *
- */
-int ocfs_initialize_osb (ocfs_super * osb, ocfs_vol_disk_hdr * vdh, ocfs_vol_label * vol_label, __u32 sect_size)
-{
- int status = 0;
- ocfs_publish *publish = NULL;
- __u32 bitmap_bits, length;
- __u64 offset;
- ocfs_vol_layout *vol_layout;
- struct buffer_head *publish_bh = NULL; /* our own publish sector */
- struct buffer_head *publish_bhs[OCFS_MAXIMUM_NODES]; /* all the publish sectors */
- int i;
-
- LOG_ENTRY ();
-
- memset(publish_bhs, 0, OCFS_MAXIMUM_NODES * sizeof (struct buffer_head *));
- if (osb == NULL) {
- LOG_ERROR_STATUS(status = -EFAIL);
- goto finally;
- }
-
- OCFS_CLEAR_FLAG (osb->osb_flags, OCFS_OSB_FLAGS_SHUTDOWN);
-
- vol_layout = &(osb->vol_layout);
-
- vol_layout->cluster_size = (__u32) (vdh->cluster_size);
- osb->obj_id.type = OCFS_TYPE_OSB;
- osb->obj_id.size = sizeof (ocfs_super);
- INIT_LIST_HEAD (&(osb->osb_next));
-
- snprintf(osb->dev_str, sizeof(osb->dev_str), "%u,%u",
- MAJOR(osb->sb->s_dev), MINOR(osb->sb->s_dev));
-
- init_MUTEX (&(osb->osb_res));
- init_MUTEX (&(osb->recovery_lock));
- init_MUTEX (&(osb->comm_lock));
- init_MUTEX (&(osb->trans_lock));
- init_MUTEX (&(osb->extend_sem));
- init_MUTEX (&(osb->cfg_lock));
- init_MUTEX (&(osb->vote_sem));
- init_MUTEX (&(osb->local_alloc_sem));
-
- spin_lock_init(&osb->recovery_map_lock);
- osb->recovery_map = 0;
-
- osb->needs_flush = 0;
- osb->disable_recovery = 0;
-
- init_MUTEX (&(osb->publish_lock));
- atomic_set (&osb->node_req_vote, 0);
-
- atomic_set (&osb->num_recovery_threads, 0);
-
- init_waitqueue_head (&osb->nm_init_event);
- atomic_set (&osb->nm_init, 0);
-
- osb->publish_dirty = 0;
- init_waitqueue_head (&osb->flush_event);
- atomic_set (&osb->flush_event_woken, 0);
- atomic_set (&osb->clean_buffer_seq, 1);
- spin_lock_init (&osb->clean_buffer_lock);
- spin_lock_init (&osb->vote_obj_queue_lock);
-
- INIT_LIST_HEAD (&(osb->vote_obj_queue));
- INIT_LIST_HEAD (&(osb->cache_lock_list));
- INIT_LIST_HEAD (&(osb->needs_flush_head));
- for (i=0; i<32; i++) {
- INIT_LIST_HEAD(&(osb->lock_recovery_lists[i]));
- }
- osb->sect_size = sect_size;
-
- osb->node_num = OCFS_INVALID_NODE_NUM;
-
- memcpy (vol_layout->mount_point, vdh->mount_point, strlen (vdh->mount_point));
- vol_layout->serial_num = vdh->serial_num;
- vol_layout->size = (__u64) (vdh->device_size);
- vol_layout->start_off = vdh->start_off;
- vol_layout->bitmap_off = (__u64) vdh->bitmap_off;
- vol_layout->publ_sect_off = vdh->publ_off;
- vol_layout->vote_sect_off = vdh->vote_off;
- vol_layout->root_bitmap_off = vdh->root_bitmap_off;
- vol_layout->root_start_off = vdh->root_off;
- vol_layout->root_int_off = vdh->internal_off;
- vol_layout->root_size = vdh->root_size;
- vol_layout->cluster_size = (__u32) vdh->cluster_size;
- vol_layout->num_nodes = (__u32) vdh->num_nodes;
- vol_layout->data_start_off = vdh->data_start_off;
- vol_layout->root_bitmap_size = vdh->root_bitmap_size;
- vol_layout->num_clusters = vdh->num_clusters;
- vol_layout->dir_node_size = vdh->dir_node_size;
- vol_layout->file_node_size = vdh->file_node_size;
- vol_layout->node_cfg_off = vdh->node_cfg_off;
- vol_layout->node_cfg_size = vdh->node_cfg_size;
- vol_layout->new_cfg_off = vdh->new_cfg_off;
- vol_layout->prot_bits = vdh->prot_bits;
- vol_layout->uid = vdh->uid;
- vol_layout->gid = vdh->gid;
-
-
-
- memcpy (vol_layout->vol_id, vol_label->vol_id, MAX_VOL_ID_LENGTH);
-
- if (vol_layout->dir_node_size == 0)
- vol_layout->dir_node_size = OCFS_DEFAULT_DIR_NODE_SIZE;
-
- if (vol_layout->file_node_size == 0)
- vol_layout->file_node_size = OCFS_DEFAULT_FILE_NODE_SIZE;
-
- osb->inode_size = OCFS_DEFAULT_INODE_SIZE;
-
- /* get some pseudo constants for >> bits */
- osb->sect_size_bits = ocfs_get_right_shift_bits(sect_size);
- osb->cluster_size_bits = ocfs_get_right_shift_bits(vol_layout->cluster_size);
- osb->dir_alloc_bits = ocfs_get_right_shift_bits(vol_layout->dir_node_size);
- osb->file_alloc_bits = ocfs_get_right_shift_bits(vol_layout->file_node_size);
- osb->inode_alloc_bits = ocfs_get_right_shift_bits(osb->inode_size);
- printk("sectbits=%d, clusterbits=%d, dirbits=%d, filebits=%d, inodebits=%d\n",
- osb->sect_size_bits, osb->cluster_size_bits,
- osb->dir_alloc_bits, osb->file_alloc_bits, osb->inode_alloc_bits);
-
- OCFS_ASSERT(osb->sect_size_bits);
- OCFS_ASSERT(osb->cluster_size_bits);
- OCFS_ASSERT(osb->dir_alloc_bits);
- OCFS_ASSERT(osb->file_alloc_bits);
- OCFS_ASSERT(osb->inode_alloc_bits);
-
-
- osb->max_dir_node_ent = (__u32) (vol_layout->dir_node_size >> osb->sect_size_bits) - 2;
- bitmap_bits = (__u32) vol_layout->num_clusters;
-
- ocfs_initialize_bitmap (&osb->cluster_bitmap, bitmap_bits, ONE_MEGA_BYTE * 8);
- /* read the whole cluster bitmap off disk, even though we only
- * need the beginning of it. */
- status = ocfs_read_bhs(osb, vol_layout->bitmap_off, ONE_MEGA_BYTE, osb->cluster_bitmap.chunk, 0, NULL);
- if (status < 0) {
- LOG_ERROR_STATUS (status);
- goto bail;
- }
-
- osb->prealloc_lock = 0;
-
- osb->cfg_numblocks = OCFS_MAXIMUM_NODES + OCFS_VOLCFG_NEWCFG_SECTORS;
- osb->cfg_len = osb->cfg_numblocks * osb->sect_size;
- osb->cfg_bhs = ocfs_malloc (osb->cfg_numblocks
- * sizeof(struct buffer_head *));
- if (!osb->cfg_bhs) {
- LOG_ERROR_STATUS (status = -ENOMEM);
- goto bail;
- }
- memset(osb->cfg_bhs, 0,
- osb->cfg_numblocks * sizeof(struct buffer_head *));
-
- status = ocfs_get_config (osb);
- if (status < 0) {
- LOG_ERROR_STATUS (status);
- goto finally;
- }
-
- /* Read the Publish Sector of local Node */
- offset = vol_layout->publ_sect_off + (osb->node_num * osb->sect_size);
- status = ocfs_read_bh(osb, offset, &publish_bh, 0, NULL);
- if (status < 0) {
- LOG_ERROR_STATUS (status);
- goto finally;
- }
- publish = (ocfs_publish *) OCFS_BH_GET_DATA_WRITE(publish_bh); /* write */
-
- publish->time = ocfs_get_publish_time();
-
- OCFS_BH_PUT_DATA(publish_bh);
- publish = NULL;
-
- status = ocfs_write_bh (osb, publish_bh, 0, NULL);
- if (status < 0) {
- LOG_ERROR_STATUS (status);
- goto finally;
- }
- brelse(publish_bh);
-
- /* Read disk for all Publish Sectors */
- length = OCFS_MAXIMUM_NODES * osb->sect_size;
- status = ocfs_read_bhs(osb, vol_layout->publ_sect_off, length,
- publish_bhs, 0, NULL);
- if (status < 0) {
- LOG_ERROR_STATUS (status);
- goto finally;
- }
-
- ocfs_update_publish_map (osb, publish_bhs, 1);
-
- for(i = 0; i < OCFS_MAXIMUM_NODES; i++)
- osb->last_publ_seq_num[i] = (__u64) (-1);
-
- /* We might need to add a variable in Global List of osb to */
- /* delay any creation, if any other node is already creating a file */
-
- /* Link this osb onto the global linked list of all osb structures. */
- /* The Global Link List is mainted for the whole driver . */
- down (&(OcfsGlobalCtxt.global_res));
- list_add_tail (&(osb->osb_next), &(OcfsGlobalCtxt.osb_next));
- up (&(OcfsGlobalCtxt.global_res));
-
- /* Mark the fact that this osb structure is initialized. */
- OCFS_SET_FLAG (osb->osb_flags, OCFS_OSB_FLAGS_OSB_INITIALIZED);
-
- spin_lock (&osb_id_lock);
- osb->osb_id = osb_id;
- if (osb_id < OCFS_MAX_OSB_ID)
- osb_id++;
- else {
- spin_unlock (&osb_id_lock);
- LOG_ERROR_STR ("Too many volumes mounted");
- status = -ENOMEM;
- goto bail;
- }
- spin_unlock (&osb_id_lock);
-
-
- /* skip the frees which happen on error only */
- goto finally;
-
-bail:
- ocfs_safefree (osb->cfg_bhs);
-
-finally:
- if (publish) {
- if (publish_bh) {
- OCFS_BH_PUT_DATA(publish_bh);
- brelse(publish_bh);
- }
- }
- if (publish_bhs[0]) {
- int i;
- for(i = 0; i < OCFS_MAXIMUM_NODES; i++)
- if (publish_bhs[i])
- brelse(publish_bhs[i]);
- }
-
- LOG_EXIT_STATUS (status);
- return status;
-} /* ocfs_initialize_osb */
-
-/*
- * ocfs_verify_volume()
- *
- */
-int ocfs_verify_volume (ocfs_vol_disk_hdr * vdh)
-{
- int status = 0;
-
- LOG_ENTRY ();
-
- if (vdh == NULL) {
- LOG_ERROR_STATUS (status = -EFAIL);
- goto bail;
- }
-
- /* Compare the Signature with the one we read from disk */
- if (memcmp (vdh->signature, OCFS_VOLUME_SIGNATURE,
- strlen (OCFS_VOLUME_SIGNATURE)) != 0) {
- LOG_ERROR_STR ("Invalid volume signature");
- status = -EINVAL;
- goto bail;
- }
-
- /* Check the Volume Length and the ClusterSize. */
- if (vdh->device_size == 0) {
- LOG_ERROR_STR ("Device size cannot be zero");
- status = -EINVAL;
- goto bail;
- }
-
- if (vdh->cluster_size == 0) {
- LOG_ERROR_STR ("Cluster size cannot be zero");
- status = -EINVAL;
- goto bail;
- }
-
- if (vdh->major_version != OCFS_MAJOR_VERSION) {
- LOG_ERROR_ARGS ("Version number not compatible: %u.%u",
- vdh->major_version, vdh->minor_version);
- status = -EINVAL;
- goto bail;
- }
-
- if (vdh->root_off == 0) {
- LOG_ERROR_STR("No OCFS version 2 root directory found");
- status = -EINVAL;
- goto bail;
- }
-bail:
- LOG_EXIT_STATUS (status);
- return status;
-} /* ocfs_verify_volume */
-
-/*
- * ocfs_check_volume()
- *
- */
-int ocfs_check_volume (ocfs_super * osb)
-{
- int status = 0;
- __u64 offset = 0;
- ocfs_publish *publish = NULL;
- int node_num = osb->node_num;
- struct buffer_head * publish_bh = NULL;
- int mounted;
-
- LOG_ENTRY ();
-
- /* Read the node's publish sector */
- offset = osb->vol_layout.publ_sect_off +
- (osb->node_num * osb->sect_size);
- status = ocfs_read_bh(osb, offset, &publish_bh, 0, NULL);
- if (status < 0) {
- LOG_ERROR_STATUS (status);
- goto finally;
- }
-
- publish = (ocfs_publish *) OCFS_BH_GET_DATA_READ(publish_bh); /* read */
- /* we copy this out of the publish sector and then unlock
- * the bh as other functions will need to modify it. */
- mounted = publish->mounted;
- OCFS_BH_PUT_DATA(publish_bh);
- publish = NULL;
-
- /* Init our journal object. */
- status = ocfs_journal_init(osb);
- if (status < 0) {
- LOG_ERROR_STR("Could not initialize journal!");
- goto finally;
- }
-
- /* If the journal was unmounted cleanly then we don't want to
- * recover anything. Otherwise, journal_load will do that
- * dirty work for us :) */
- if (!mounted) {
- status = ocfs_journal_wipe(&osb->journal, 0);
- if (status < 0) {
- LOG_ERROR_STATUS(status);
- goto finally;
- }
- } else {
- printk(KERN_NOTICE "ocfs2: File system was not unmounted "
- "cleanly, recovering volume.\n");
- }
-
- /* will play back anything left in the journal. */
- ocfs_journal_load(&osb->journal);
-
- if (mounted) {
- /* recover my local alloc if we didn't unmount cleanly. */
- status = ocfs_recover_local_alloc(osb, node_num);
- if (status < 0) {
- LOG_ERROR_STATUS(status);
- goto finally;
- }
- }
-
- /* 'mounted' flag in publish sector should not be set until
- * after we successfully load the journal. */
- status = ocfs_journal_set_mounted(osb, osb->node_num);
- if (status < 0)
- LOG_ERROR_STR("Could not set mounted flag!");
- LOG_TRACE_STR("Journal loaded.");
-
- status = ocfs_load_local_alloc(osb);
- if (status < 0)
- LOG_ERROR_STATUS(status);
-
-finally:
- if (publish_bh) {
- if (publish)
- OCFS_BH_PUT_DATA(publish_bh);
- brelse(publish_bh);
- }
- LOG_EXIT_STATUS (status);
- return status;
-} /* ocfs_check_volume */
-
-
-/*
- * ocfs_delete_osb()
- *
- * The routine gets called from dismount or close whenever a dismount on
- * volume is requested and the osb open count becomes 1.
- * It will remove the osb from the global list and also free up all the
- * initialized resources and fileobject.
- */
-void ocfs_delete_osb (ocfs_super * osb)
-{
- int i;
- LOG_ENTRY ();
-
- /* This function assumes that the caller has the main osb resource */
-
- /* Remove the osb from the global linked list of all osb structures. */
- /* The Global Link List is mainted for the whole driver */
- down (&(OcfsGlobalCtxt.global_res));
- if (!list_empty(&(osb->osb_next)))
- list_del (&(osb->osb_next));
- up (&(OcfsGlobalCtxt.global_res));
-
- for (i=0; i<32; i++)
- ocfs_recover_oin_locks(osb, i);
-
- for(i = 0; i < osb->cfg_numblocks; i++)
- if (osb->cfg_bhs[i])
- brelse(osb->cfg_bhs[i]);
- ocfs_safefree(osb->cfg_bhs);
- memset (osb, 0, sizeof (ocfs_super));
-
- LOG_EXIT ();
- return;
-} /* ocfs_delete_osb */
Modified: trunk/src/super.c
===================================================================
--- trunk/src/super.c 2004-05-28 00:55:33 UTC (rev 957)
+++ trunk/src/super.c 2004-05-29 00:02:26 UTC (rev 958)
@@ -75,7 +75,7 @@
};
static ctl_table ocfs_kern_table[] = {
- {KERN_OCFS, "ocfs2", NULL, 0, 0555, ocfs_dbg_table},
+ {KERN_OCFS, "ocfs2", NULL, 0, 0555, ocfs_dbg_table},
{0}
};
static ctl_table ocfs_root_table[] = {
@@ -143,6 +143,15 @@
static int ocfs_init_system_inodes(ocfs_super *osb);
static int ocfs_release_system_inodes(ocfs_super *osb);
+static int ocfs_publish_set_unmounted(ocfs_super *osb, int node_num);
+static int ocfs_publish_set_mounted(ocfs_super *osb, int node_num);
+static int ocfs_publish_toggle_mounted(ocfs_super *osb, int node_num,
+ int value);
+static int ocfs_check_volume(ocfs_super * osb);
+static int ocfs_verify_volume(ocfs_vol_disk_hdr *vdh);
+static int ocfs_initialize_osb(ocfs_super *osb, ocfs_vol_disk_hdr *vdh,
+ ocfs_vol_label *vol_label,
+ __u32 sect_size);
static struct super_operations ocfs_sops = {
.statfs = ocfs_statfs,
@@ -893,8 +902,8 @@
/* FIXME: here it should use the actual blocksize */
sect_size = OCFS_SECTOR_SIZE;
- status = ocfs_initialize_osb (osb, vol_header, vol_label,
- sect_size);
+ status = ocfs_initialize_osb(osb, vol_header, vol_label,
+ sect_size);
if (status < 0) {
LOG_ERROR_STATUS (status);
goto leave;
@@ -929,28 +938,6 @@
init_completion (&osb->dlm_complete);
}
- /* Launch the commit thread */
- osb->commit = (ocfs_commit_task *)ocfs_malloc(sizeof(ocfs_commit_task));
- if (osb->commit == NULL) {
- LOG_ERROR_STATUS(status = -ENOMEM);
- up (&(osb->osb_res));
- goto leave;
- }
- memset(osb->commit, 0, sizeof(ocfs_commit_task));
- init_MUTEX(&osb->commit->c_lock);
- INIT_LIST_HEAD(&osb->commit->c_list);
- child_pid = kernel_thread (ocfs_commit_thread, osb,
- CLONE_FS | CLONE_FILES | CLONE_SIGHAND);
- if (child_pid < 0) {
- LOG_ERROR_ARGS ("unable to launch ocfs2commit thread, error=%d",
- child_pid);
- up (&(osb->osb_res));
- status = -EFAIL;
- goto leave;
- } else {
- init_completion (&osb->commit->c_complete);
- }
-
up (&(osb->osb_res));
/* Add proc entry for this volume */
@@ -1022,12 +1009,36 @@
LOG_TRACE_STR ("ocfs_check_volume...");
down(&(osb->osb_res));
status = ocfs_check_volume (osb);
- up (&(osb->osb_res));
if (status < 0) {
+ up(&(osb->osb_res));
LOG_ERROR_STATUS (status);
goto leave;
}
+ /* Launch the commit thread */
+ osb->commit = (ocfs_commit_task *)ocfs_malloc(sizeof(ocfs_commit_task));
+ if (osb->commit == NULL) {
+ LOG_ERROR_STATUS(status = -ENOMEM);
+ up (&(osb->osb_res));
+ goto leave;
+ }
+ memset(osb->commit, 0, sizeof(ocfs_commit_task));
+ init_MUTEX(&osb->commit->c_lock);
+ INIT_LIST_HEAD(&osb->commit->c_list);
+ child_pid = kernel_thread (ocfs_commit_thread, osb,
+ CLONE_FS | CLONE_FILES | CLONE_SIGHAND);
+ if (child_pid < 0) {
+ LOG_ERROR_ARGS ("unable to launch ocfs2commit thread, error=%d",
+ child_pid);
+ up (&(osb->osb_res));
+ status = -EFAIL;
+ goto leave;
+ } else {
+ init_completion (&osb->commit->c_complete);
+ }
+ up (&(osb->osb_res));
+
+
osb->vol_state = VOLUME_MOUNTED;
leave:
@@ -1104,7 +1115,7 @@
/* unset the mounted flag -- we're done with the journal and
* the local alloc bitmap */
- status = ocfs_journal_set_unmounted(osb, osb->node_num);
+ status = ocfs_publish_set_unmounted(osb, osb->node_num);
if (status < 0)
LOG_ERROR_STR("Could not set mounted flag!");
@@ -1199,5 +1210,570 @@
} /* ocfs_dismount_volume */
+/* true if mounted, false otherwise */
+int ocfs_publish_get_mount_state(ocfs_super *osb, int node_num)
+{
+ int status = 0;
+ ocfs_publish *publish = NULL;
+ struct buffer_head *publish_bh = NULL;
+ __u64 offset = 0;
+ int retval = 0;
+ int flags = 0;
+
+ LOG_ENTRY();
+
+ /* read it in */
+ offset = osb->vol_layout.publ_sect_off +
+ (node_num * osb->sect_size);
+ /* we may be called during mount in which case our publish
+ * sector might be dirty. */
+ if (node_num == osb->node_num)
+ flags = OCFS_BH_CACHED;
+ status = ocfs_read_bh(osb, offset, &publish_bh, flags, NULL);
+ if (status < 0) {
+ brelse(publish_bh);
+ LOG_ERROR_STR("Could not read publish sector, mounted value"
+ " may be incorrect!");
+ LOG_ERROR_STATUS (status);
+ goto done;
+ }
+ publish = (ocfs_publish *) OCFS_BH_GET_DATA_READ(publish_bh); /* read */
+
+ retval = publish->mounted;
+
+ OCFS_BH_PUT_DATA(publish_bh);
+ brelse(publish_bh);
+done:
+ LOG_EXIT_STATUS(retval);
+ return(retval);
+}
+
+static int ocfs_publish_toggle_mounted(ocfs_super *osb, int node_num, int value)
+{
+ int status = 0;
+ ocfs_publish *publish = NULL;
+ struct buffer_head * publish_bh = NULL;
+ __u64 offset = 0;
+
+ LOG_ENTRY_ARGS("(node_num=%d, value=%d)\n", node_num, value);
+
+ /* read it in */
+ offset = osb->vol_layout.publ_sect_off +
+ (node_num * osb->sect_size);
+ status = ocfs_read_bh(osb, offset, &publish_bh, 0, NULL);
+ if (status < 0) {
+ LOG_ERROR_STATUS (status);
+ goto done;
+ }
+ publish = (ocfs_publish *) OCFS_BH_GET_DATA_WRITE(publish_bh); /* write */
+
+ /* change it */
+ publish->mounted = value;
+ OCFS_BH_PUT_DATA(publish_bh);
+
+ /* write it back out */
+ status = ocfs_write_bh(osb, publish_bh, 0, NULL);
+ if (status < 0) {
+ LOG_ERROR_STATUS (status);
+ goto done;
+ }
+
+done:
+ if (publish_bh)
+ brelse(publish_bh);
+
+ LOG_EXIT_STATUS(status);
+
+ return(status);
+}
+
+/* set the 'mounted' bit in the publish sector */
+static int ocfs_publish_set_mounted(ocfs_super *osb, int node_num)
+{
+ int retval;
+
+ LOG_ENTRY_ARGS("(node_num=%d)\n", node_num);
+
+ down (&(osb->publish_lock));
+
+ retval = ocfs_publish_toggle_mounted(osb, node_num, 1);
+ if (osb->node_num == node_num)
+ osb->check_mounted = 1;
+
+ up (&(osb->publish_lock));
+
+ LOG_EXIT_STATUS(retval);
+
+ return(retval);
+}
+
+/* unset the 'mounted' bit in the publish sector */
+static int ocfs_publish_set_unmounted(ocfs_super *osb, int node_num)
+{
+ int retval;
+
+ LOG_ENTRY_ARGS("(node_num=%d)\n", node_num);
+
+ down (&(osb->publish_lock));
+
+ if (osb->node_num == node_num)
+ osb->check_mounted = 0;
+
+ retval = ocfs_publish_toggle_mounted(osb, node_num, 0);
+
+ up (&(osb->publish_lock));
+
+ LOG_EXIT_STATUS(retval);
+
+ return(retval);
+}
+
+
+/*
+ * ocfs_initialize_osb()
+ *
+ */
+static int ocfs_initialize_osb(ocfs_super *osb, ocfs_vol_disk_hdr *vdh,
+ ocfs_vol_label *vol_label,
+ __u32 sect_size)
+{
+ int status = 0;
+ ocfs_publish *publish = NULL;
+ __u32 bitmap_bits, length;
+ __u64 offset;
+ ocfs_vol_layout *vol_layout;
+ struct buffer_head *publish_bh = NULL; /* our own publish sector */
+ struct buffer_head *publish_bhs[OCFS_MAXIMUM_NODES]; /* all the publish sectors */
+ int i;
+
+ LOG_ENTRY ();
+
+ /* FIXME
+ * This should be done in ocfs_journal_init(), but unknown
+ * ordering issues will cause the filesystem to crash.
+ * If anyone wants to figure out what part of the code
+ * refers to osb->journal before ocfs_journal_init() is run,
+ * be my guest.
+ */
+ /* initialize our journal structure */
+ osb->journal = kmalloc(sizeof(ocfs_journal), GFP_KERNEL);
+ if (!osb->journal) {
+ LOG_ERROR_STR("unable to alloc journal");
+ status = -ENOMEM;
+ goto done_nojournal;
+ }
+ memset(osb->journal, 0, sizeof(ocfs_journal));
+
+ memset(publish_bhs, 0, OCFS_MAXIMUM_NODES * sizeof (struct buffer_head *));
+ if (osb == NULL) {
+ LOG_ERROR_STATUS(status = -EFAIL);
+ goto finally;
+ }
+
+ OCFS_CLEAR_FLAG (osb->osb_flags, OCFS_OSB_FLAGS_SHUTDOWN);
+
+ vol_layout = &(osb->vol_layout);
+
+ vol_layout->cluster_size = (__u32) (vdh->cluster_size);
+ osb->obj_id.type = OCFS_TYPE_OSB;
+ osb->obj_id.size = sizeof (ocfs_super);
+ INIT_LIST_HEAD (&(osb->osb_next));
+
+ snprintf(osb->dev_str, sizeof(osb->dev_str), "%u,%u",
+ MAJOR(osb->sb->s_dev), MINOR(osb->sb->s_dev));
+
+ init_MUTEX (&(osb->osb_res));
+ init_MUTEX (&(osb->recovery_lock));
+ init_MUTEX (&(osb->comm_lock));
+ init_MUTEX (&(osb->trans_lock));
+ init_MUTEX (&(osb->extend_sem));
+ init_MUTEX (&(osb->cfg_lock));
+ init_MUTEX (&(osb->vote_sem));
+ init_MUTEX (&(osb->local_alloc_sem));
+
+ spin_lock_init(&osb->recovery_map_lock);
+ osb->recovery_map = 0;
+
+ osb->needs_flush = 0;
+ osb->disable_recovery = 0;
+
+ init_MUTEX (&(osb->publish_lock));
+ atomic_set (&osb->node_req_vote, 0);
+
+ atomic_set (&osb->num_recovery_threads, 0);
+
+ init_waitqueue_head (&osb->nm_init_event);
+ atomic_set (&osb->nm_init, 0);
+
+ osb->publish_dirty = 0;
+ init_waitqueue_head (&osb->flush_event);
+ atomic_set (&osb->flush_event_woken, 0);
+ atomic_set (&osb->clean_buffer_seq, 1);
+ spin_lock_init (&osb->clean_buffer_lock);
+ spin_lock_init (&osb->vote_obj_queue_lock);
+
+ INIT_LIST_HEAD (&(osb->vote_obj_queue));
+ INIT_LIST_HEAD (&(osb->cache_lock_list));
+ INIT_LIST_HEAD (&(osb->needs_flush_head));
+ for (i=0; i<32; i++) {
+ INIT_LIST_HEAD(&(osb->lock_recovery_lists[i]));
+ }
+ osb->sect_size = sect_size;
+
+ osb->node_num = OCFS_INVALID_NODE_NUM;
+
+ memcpy (vol_layout->mount_point, vdh->mount_point, strlen (vdh->mount_point));
+ vol_layout->serial_num = vdh->serial_num;
+ vol_layout->size = (__u64) (vdh->device_size);
+ vol_layout->start_off = vdh->start_off;
+ vol_layout->bitmap_off = (__u64) vdh->bitmap_off;
+ vol_layout->publ_sect_off = vdh->publ_off;
+ vol_layout->vote_sect_off = vdh->vote_off;
+ vol_layout->root_bitmap_off = vdh->root_bitmap_off;
+ vol_layout->root_start_off = vdh->root_off;
+ vol_layout->root_int_off = vdh->internal_off;
+ vol_layout->root_size = vdh->root_size;
+ vol_layout->cluster_size = (__u32) vdh->cluster_size;
+ vol_layout->num_nodes = (__u32) vdh->num_nodes;
+ vol_layout->data_start_off = vdh->data_start_off;
+ vol_layout->root_bitmap_size = vdh->root_bitmap_size;
+ vol_layout->num_clusters = vdh->num_clusters;
+ vol_layout->dir_node_size = vdh->dir_node_size;
+ vol_layout->file_node_size = vdh->file_node_size;
+ vol_layout->node_cfg_off = vdh->node_cfg_off;
+ vol_layout->node_cfg_size = vdh->node_cfg_size;
+ vol_layout->new_cfg_off = vdh->new_cfg_off;
+ vol_layout->prot_bits = vdh->prot_bits;
+ vol_layout->uid = vdh->uid;
+ vol_layout->gid = vdh->gid;
+
+
+
+ memcpy (vol_layout->vol_id, vol_label->vol_id, MAX_VOL_ID_LENGTH);
+
+ if (vol_layout->dir_node_size == 0)
+ vol_layout->dir_node_size = OCFS_DEFAULT_DIR_NODE_SIZE;
+
+ if (vol_layout->file_node_size == 0)
+ vol_layout->file_node_size = OCFS_DEFAULT_FILE_NODE_SIZE;
+
+ osb->inode_size = OCFS_DEFAULT_INODE_SIZE;
+
+ /* get some pseudo constants for >> bits */
+ osb->sect_size_bits = ocfs_get_right_shift_bits(sect_size);
+ osb->cluster_size_bits = ocfs_get_right_shift_bits(vol_layout->cluster_size);
+ osb->dir_alloc_bits = ocfs_get_right_shift_bits(vol_layout->dir_node_size);
+ osb->file_alloc_bits = ocfs_get_right_shift_bits(vol_layout->file_node_size);
+ osb->inode_alloc_bits = ocfs_get_right_shift_bits(osb->inode_size);
+ printk("sectbits=%d, clusterbits=%d, dirbits=%d, filebits=%d, inodebits=%d\n",
+ osb->sect_size_bits, osb->cluster_size_bits,
+ osb->dir_alloc_bits, osb->file_alloc_bits, osb->inode_alloc_bits);
+
+ OCFS_ASSERT(osb->sect_size_bits);
+ OCFS_ASSERT(osb->cluster_size_bits);
+ OCFS_ASSERT(osb->dir_alloc_bits);
+ OCFS_ASSERT(osb->file_alloc_bits);
+ OCFS_ASSERT(osb->inode_alloc_bits);
+
+
+ osb->max_dir_node_ent = (__u32) (vol_layout->dir_node_size >> osb->sect_size_bits) - 2;
+ bitmap_bits = (__u32) vol_layout->num_clusters;
+
+ ocfs_initialize_bitmap (&osb->cluster_bitmap, bitmap_bits, ONE_MEGA_BYTE * 8);
+ /* read the whole cluster bitmap off disk, even though we only
+ * need the beginning of it. */
+ status = ocfs_read_bhs(osb, vol_layout->bitmap_off, ONE_MEGA_BYTE, osb->cluster_bitmap.chunk, 0, NULL);
+ if (status < 0) {
+ LOG_ERROR_STATUS (status);
+ goto bail;
+ }
+
+ osb->prealloc_lock = 0;
+
+ osb->cfg_numblocks = OCFS_MAXIMUM_NODES + OCFS_VOLCFG_NEWCFG_SECTORS;
+ osb->cfg_len = osb->cfg_numblocks * osb->sect_size;
+ osb->cfg_bhs = ocfs_malloc (osb->cfg_numblocks
+ * sizeof(struct buffer_head *));
+ if (!osb->cfg_bhs) {
+ LOG_ERROR_STATUS (status = -ENOMEM);
+ goto bail;
+ }
+ memset(osb->cfg_bhs, 0,
+ osb->cfg_numblocks * sizeof(struct buffer_head *));
+
+ status = ocfs_get_config (osb);
+ if (status < 0) {
+ LOG_ERROR_STATUS (status);
+ goto finally;
+ }
+
+ /* Read the Publish Sector of local Node */
+ offset = vol_layout->publ_sect_off + (osb->node_num * osb->sect_size);
+ status = ocfs_read_bh(osb, offset, &publish_bh, 0, NULL);
+ if (status < 0) {
+ LOG_ERROR_STATUS (status);
+ goto finally;
+ }
+ publish = (ocfs_publish *) OCFS_BH_GET_DATA_WRITE(publish_bh); /* write */
+
+ publish->time = ocfs_get_publish_time();
+
+ OCFS_BH_PUT_DATA(publish_bh);
+ publish = NULL;
+
+ status = ocfs_write_bh (osb, publish_bh, 0, NULL);
+ if (status < 0) {
+ LOG_ERROR_STATUS (status);
+ goto finally;
+ }
+ brelse(publish_bh);
+
+ /* Read disk for all Publish Sectors */
+ length = OCFS_MAXIMUM_NODES * osb->sect_size;
+ status = ocfs_read_bhs(osb, vol_layout->publ_sect_off, length,
+ publish_bhs, 0, NULL);
+ if (status < 0) {
+ LOG_ERROR_STATUS (status);
+ goto finally;
+ }
+
+ ocfs_update_publish_map (osb, publish_bhs, 1);
+
+ for(i = 0; i < OCFS_MAXIMUM_NODES; i++)
+ osb->last_publ_seq_num[i] = (__u64) (-1);
+
+ /* We might need to add a variable in Global List of osb to */
+ /* delay any creation, if any other node is already creating a file */
+
+ /* Link this osb onto the global linked list of all osb structures. */
+ /* The Global Link List is mainted for the whole driver . */
+ down (&(OcfsGlobalCtxt.global_res));
+ list_add_tail (&(osb->osb_next), &(OcfsGlobalCtxt.osb_next));
+ up (&(OcfsGlobalCtxt.global_res));
+
+ /* Mark the fact that this osb structure is initialized. */
+ OCFS_SET_FLAG (osb->osb_flags, OCFS_OSB_FLAGS_OSB_INITIALIZED);
+
+ spin_lock (&osb_id_lock);
+ osb->osb_id = osb_id;
+ if (osb_id < OCFS_MAX_OSB_ID)
+ osb_id++;
+ else {
+ spin_unlock (&osb_id_lock);
+ LOG_ERROR_STR ("Too many volumes mounted");
+ status = -ENOMEM;
+ goto bail;
+ }
+ spin_unlock (&osb_id_lock);
+
+
+ /* skip the frees which happen on error only */
+ goto finally;
+
+bail:
+ ocfs_safefree (osb->cfg_bhs);
+
+finally:
+ if (publish) {
+ if (publish_bh) {
+ OCFS_BH_PUT_DATA(publish_bh);
+ brelse(publish_bh);
+ }
+ }
+ if (publish_bhs[0]) {
+ int i;
+ for(i = 0; i < OCFS_MAXIMUM_NODES; i++)
+ if (publish_bhs[i])
+ brelse(publish_bhs[i]);
+ }
+
+done_nojournal:
+ LOG_EXIT_STATUS (status);
+ return status;
+} /* ocfs_initialize_osb */
+
+/*
+ * ocfs_verify_volume()
+ *
+ */
+static int ocfs_verify_volume(ocfs_vol_disk_hdr *vdh)
+{
+ int status = 0;
+
+ LOG_ENTRY ();
+
+ if (vdh == NULL) {
+ LOG_ERROR_STATUS (status = -EFAIL);
+ goto bail;
+ }
+
+ /* Compare the Signature with the one we read from disk */
+ if (memcmp (vdh->signature, OCFS_VOLUME_SIGNATURE,
+ strlen (OCFS_VOLUME_SIGNATURE)) != 0) {
+ LOG_ERROR_STR ("Invalid volume signature");
+ status = -EINVAL;
+ goto bail;
+ }
+
+ /* Check the Volume Length and the ClusterSize. */
+ if (vdh->device_size == 0) {
+ LOG_ERROR_STR ("Device size cannot be zero");
+ status = -EINVAL;
+ goto bail;
+ }
+
+ if (vdh->cluster_size == 0) {
+ LOG_ERROR_STR ("Cluster size cannot be zero");
+ status = -EINVAL;
+ goto bail;
+ }
+
+ if (vdh->major_version != OCFS_MAJOR_VERSION) {
+ LOG_ERROR_ARGS ("Version number not compatible: %u.%u",
+ vdh->major_version, vdh->minor_version);
+ status = -EINVAL;
+ goto bail;
+ }
+
+ if (vdh->root_off == 0) {
+ LOG_ERROR_STR("No OCFS version 2 root directory found");
+ status = -EINVAL;
+ goto bail;
+ }
+bail:
+ LOG_EXIT_STATUS (status);
+ return status;
+} /* ocfs_verify_volume */
+
+/*
+ * ocfs_check_volume()
+ *
+ */
+static int ocfs_check_volume (ocfs_super * osb)
+{
+ int status = 0;
+ __u64 offset = 0;
+ ocfs_publish *publish = NULL;
+ int node_num = osb->node_num;
+ struct buffer_head * publish_bh = NULL;
+ int mounted;
+
+ LOG_ENTRY ();
+
+ /* Read the node's publish sector */
+ offset = osb->vol_layout.publ_sect_off +
+ (osb->node_num * osb->sect_size);
+ status = ocfs_read_bh(osb, offset, &publish_bh, 0, NULL);
+ if (status < 0) {
+ LOG_ERROR_STATUS (status);
+ goto finally;
+ }
+
+ publish = (ocfs_publish *) OCFS_BH_GET_DATA_READ(publish_bh); /* read */
+ /* we copy this out of the publish sector and then unlock
+ * the bh as other functions will need to modify it. */
+ mounted = publish->mounted;
+ OCFS_BH_PUT_DATA(publish_bh);
+ publish = NULL;
+
+ /* Init our journal object. */
+ status = ocfs_journal_init(osb);
+ if (status < 0) {
+ LOG_ERROR_STR("Could not initialize journal!");
+ goto finally;
+ }
+
+ /* If the journal was unmounted cleanly then we don't want to
+ * recover anything. Otherwise, journal_load will do that
+ * dirty work for us :) */
+ if (!mounted) {
+ status = ocfs_journal_wipe(osb->journal, 0);
+ if (status < 0) {
+ LOG_ERROR_STATUS(status);
+ goto finally;
+ }
+ } else {
+ printk(KERN_NOTICE "ocfs2: File system was not unmounted "
+ "cleanly, recovering volume.\n");
+ }
+
+ /* will play back anything left in the journal. */
+ ocfs_journal_load(osb->journal);
+
+ if (mounted) {
+ /* recover my local alloc if we didn't unmount cleanly. */
+ status = ocfs_recover_local_alloc(osb, node_num);
+ if (status < 0) {
+ LOG_ERROR_STATUS(status);
+ goto finally;
+ }
+ }
+
+ /* 'mounted' flag in publish sector should not be set until
+ * after we successfully load the journal. */
+ status = ocfs_publish_set_mounted(osb, osb->node_num);
+ if (status < 0)
+ LOG_ERROR_STR("Could not set mounted flag!");
+ LOG_TRACE_STR("Journal loaded.");
+
+ status = ocfs_load_local_alloc(osb);
+ if (status < 0)
+ LOG_ERROR_STATUS(status);
+
+finally:
+ if (publish_bh) {
+ if (publish)
+ OCFS_BH_PUT_DATA(publish_bh);
+ brelse(publish_bh);
+ }
+ LOG_EXIT_STATUS (status);
+ return status;
+} /* ocfs_check_volume */
+
+
+/*
+ * ocfs_delete_osb()
+ *
+ * The routine gets called from dismount or close whenever a dismount on
+ * volume is requested and the osb open count becomes 1.
+ * It will remove the osb from the global list and also free up all the
+ * initialized resources and fileobject.
+ */
+void ocfs_delete_osb (ocfs_super * osb)
+{
+ int i;
+ LOG_ENTRY ();
+
+ /* This function assumes that the caller has the main osb resource */
+
+ /* Remove the osb from the global linked list of all osb structures. */
+ /* The Global Link List is mainted for the whole driver */
+ down (&(OcfsGlobalCtxt.global_res));
+ if (!list_empty(&(osb->osb_next)))
+ list_del (&(osb->osb_next));
+ up (&(OcfsGlobalCtxt.global_res));
+
+ for (i=0; i<32; i++)
+ ocfs_recover_oin_locks(osb, i);
+
+ for(i = 0; i < osb->cfg_numblocks; i++)
+ if (osb->cfg_bhs[i])
+ brelse(osb->cfg_bhs[i]);
+ ocfs_safefree(osb->cfg_bhs);
+
+ /* FIXME
+ * This belongs in journal shutdown, but because we have to
+ * allocate osb->journal at the start of ocfs_initalize_osb(),
+ * we free it here.
+ */
+ kfree(osb->journal);
+
+ memset (osb, 0, sizeof (ocfs_super));
+
+ LOG_EXIT ();
+ return;
+} /* ocfs_delete_osb */
+
+
module_init (ocfs_driver_entry);
module_exit (ocfs_driver_exit);
Modified: trunk/src/util.c
===================================================================
--- trunk/src/util.c 2004-05-28 00:55:33 UTC (rev 957)
+++ trunk/src/util.c 2004-05-29 00:02:26 UTC (rev 958)
@@ -331,26 +331,7 @@
truncate_inode_pages(&inode->i_data, off);
} /* ocfs_truncate_inode_pages */
-void ocfs_end_buffer_io_sync(struct buffer_head *bh, int uptodate)
-{
-// LOG_ENTRY_ARGS("(bh->b_blocknr = %u, uptodate = %d)\n", bh->b_blocknr,
-// uptodate);
- if (!uptodate)
- LOG_ERROR_STATUS(-EIO);
-
- if (uptodate)
- set_buffer_uptodate(bh);
- else
- clear_buffer_uptodate(bh);
- unlock_buffer(bh);
-
-// LOG_EXIT();
- return;
-}
-
-
-
/*
To print the ocfs call stack use: ocfs_show_stack( NULL);
More information about the Ocfs2-commits
mailing list