[Ocfs2-commits] mfasheh commits r847 - in trunk/src: . inc
svn-commits at oss.oracle.com
svn-commits at oss.oracle.com
Fri Apr 16 18:38:57 CDT 2004
Author: mfasheh
Date: 2004-04-16 17:38:55 -0500 (Fri, 16 Apr 2004)
New Revision: 847
Modified:
trunk/src/alloc.c
trunk/src/dcache.c
trunk/src/dlm.c
trunk/src/extmap.c
trunk/src/file.c
trunk/src/hash.c
trunk/src/inc/journal.h
trunk/src/inc/ocfs.h
trunk/src/inc/proto.h
trunk/src/inode.c
trunk/src/journal.c
trunk/src/namei.c
trunk/src/nm.c
trunk/src/oin.c
trunk/src/super.c
trunk/src/sysfile.c
Log:
* Merge my nooin branch from r831 to r846 back into trunk
Modified: trunk/src/alloc.c
===================================================================
--- trunk/src/alloc.c 2004-04-16 21:49:58 UTC (rev 846)
+++ trunk/src/alloc.c 2004-04-16 22:38:55 UTC (rev 847)
@@ -1159,7 +1159,7 @@
* ocfs_allocate_extent()
*
*/
-int ocfs_allocate_extent (ocfs_super * osb, ocfs_inode * oin, struct buffer_head *fe_bh, ocfs_journal_handle *handle, __u64 actualDiskOffset, __u64 actualLength, struct inode *inode)
+int ocfs_allocate_extent (ocfs_super * osb, struct buffer_head *fe_bh, ocfs_journal_handle *handle, __u64 actualDiskOffset, __u64 actualLength, struct inode *inode)
{
int status = 0;
bool IncreaseTreeDepth = false;
@@ -1169,9 +1169,13 @@
bool UpdateParent = false;
__u64 newExtentOff, up_ptr;
ocfs_file_entry * FileEntry = NULL;
+ ocfs_inode *oin = NULL;
LOG_ENTRY_ARGS("(actualDiskOffset=%u.%u, actualLength=%u.%u)\n", actualDiskOffset, actualLength);
+ if (inode)
+ oin = GET_INODE_OIN(inode);
+
FileEntry = (ocfs_file_entry *)OCFS_BH_GET_DATA_WRITE(fe_bh); /* write */
OCFS_ASSERT (FileEntry);
@@ -2459,7 +2463,7 @@
* decoded and updated in the extent map.
*
*/
-int ocfs_lookup_file_allocation (ocfs_super * osb, ocfs_inode * oin, __s64 Vbo, __s64 * Lbo, __u32 sectors, u32 *sector_count, struct inode *inode)
+int ocfs_lookup_file_allocation (ocfs_super * osb, __s64 Vbo, __s64 * Lbo, __u32 sectors, u32 *sector_count, struct inode *inode)
{
int status = -EFAIL;
ocfs_file_entry *fe = NULL;
@@ -2471,13 +2475,15 @@
__s64 localVbo;
__u64 cnt;
__u32 NumIndex;
+ ocfs_inode *oin = NULL;
LOG_ENTRY ();
OCFS_ASSERT (osb);
- OCFS_ASSERT (oin);
+ OCFS_ASSERT (inode);
+ oin = GET_INODE_OIN(inode);
- if (oin->journal_inode || Vbo < oin->alloc_size) {
+ if (INODE_JOURNAL(inode) || Vbo < oin->alloc_size) {
if (ocfs_lookup_extent_map_entry (osb, &(oin->map),
Vbo, Lbo, &cnt, &NumIndex) && cnt >= sectors) {
status = 0;
@@ -2485,8 +2491,6 @@
}
}
- OCFS_ASSERT (inode);
-
remainingLength = sectors;
localVbo = Vbo;
@@ -2507,7 +2511,7 @@
goto finally;
}
- if (!oin->journal_inode && Vbo >= (__s64) fe->alloc_size) {
+ if (!INODE_JOURNAL(inode) && Vbo >= (__s64) fe->alloc_size) {
LOG_ERROR_ARGS ("vbo=%u.%u, fe->alloc_sz=%u.%u oin->alloc_size=%u.%u",
HILO (Vbo), HILO (fe->alloc_size),
HILO (oin->alloc_size));
@@ -3115,7 +3119,7 @@
ocfs_journal_add_lock(handle, lockId,
OCFS_DLM_EXCLUSIVE_LOCK,
FLAG_FILE_CREATE,
- pLockResource, bh);
+ pLockResource, bh, NULL);
tmpstat = 0;
} else if (bLockAcquired) {
tmpstat =
Modified: trunk/src/dcache.c
===================================================================
--- trunk/src/dcache.c 2004-04-16 21:49:58 UTC (rev 846)
+++ trunk/src/dcache.c 2004-04-16 22:38:55 UTC (rev 847)
@@ -97,8 +97,8 @@
/* hit the disk */
/* TODO: optimize */
ocfs_down_sem (&(oin->main_res), true);
- oin->needs_verification = true;
- tmpstat = ocfs_verify_update_oin(osb, oin, &needs_trunc);
+ OCFS_I(inode)->needs_verification = true;
+ tmpstat = ocfs_verify_update_inode(osb, inode, &needs_trunc);
if (tmpstat < 0)
LOG_ERROR_STATUS (tmpstat);
ocfs_up_sem (&(oin->main_res));
Modified: trunk/src/dlm.c
===================================================================
--- trunk/src/dlm.c 2004-04-16 21:49:58 UTC (rev 846)
+++ trunk/src/dlm.c 2004-04-16 22:38:55 UTC (rev 847)
@@ -35,47 +35,26 @@
int new_lock_function(ocfs_super * osb, __u32 requested_lock, __u32 flags, ocfs_lock_res * lockres, struct buffer_head *bh, bool *disk_vote, struct inode *inode);
-static inline int ocfs_wait_for_readonly_drop(ocfs_super *osb, ocfs_lock_res *lockres);
+static inline int ocfs_wait_for_readonly_drop(ocfs_super *osb, ocfs_lock_res *lockres, struct inode *inode);
-static int ocfs_insert_cache_link (ocfs_super * osb, ocfs_lock_res * lockres);
-static int ocfs_send_dlm_request_msg (ocfs_super * osb, __u64 lock_id, __u32 lock_type, __u32 flags, ocfs_lock_res * lockres, __u64 vote_map);
+static int ocfs_send_dlm_request_msg (ocfs_super * osb, __u64 lock_id, __u32 lock_type, __u32 flags, ocfs_lock_res * lockres, __u64 vote_map, struct inode *inode);
static int ocfs_request_vote (ocfs_super * osb, __u64 lock_id, __u32 lock_type, __u32 flags, __u64 vote_map, __u64 * lock_seq_num, struct inode *inode);
static int ocfs_wait_for_vote (ocfs_super * osb, __u64 lock_id, __u32 lock_type, __u32 flags, __u64 vote_map, __u32 time_to_wait, __u64 lock_seq_num, ocfs_lock_res * lockres);
static int ocfs_reset_voting (ocfs_super * osb);
static int ocfs_wait_for_lock_release (ocfs_super * osb, __u64 offset, __u32 time_to_wait, ocfs_lock_res * lockres, __u32 lock_type, struct inode *inode);
static int ocfs_get_vote_on_disk (ocfs_super * osb, __u64 lock_id, __u32 lock_type, __u32 flags, __u64 * got_vote_map, __u64 vote_map, __u64 lock_seq_num, __u64 * oin_open_map);
static int ocfs_break_cache_lock (ocfs_super * osb, ocfs_lock_res * lockres, struct inode *inode);
-static int ocfs_disk_request_vote (ocfs_super * osb, __u64 lock_id, __u32 lock_type, __u32 flags, __u64 vote_map, __u64 * lock_seq_num);
-int ocfs_update_disk_lock (ocfs_super * osb, ocfs_lock_res * lockres, __u32 flags, struct buffer_head **bh, struct inode *inode);
-static int ocfs_update_master_on_open (ocfs_super * osb, ocfs_lock_res * lockres, struct inode *inode);
+static int ocfs_disk_request_vote (ocfs_super * osb, __u64 lock_id, __u32 lock_type, __u32 flags, __u64 vote_map, __u64 * lock_seq_num, __u64 feoff);
+int ocfs_update_disk_lock (ocfs_super * osb, ocfs_lock_res * lockres, __u32 flags, struct buffer_head **bh, struct inode *inode, ocfs_journal_handle *handle);
+static int ocfs_update_master_on_open (ocfs_super * osb, ocfs_lock_res * lockres, struct inode *inode, ocfs_journal_handle *handle);
int ocfs_disk_release_lock (ocfs_super * osb, __u64 lock_id, __u32 lock_type, __u32 flags, ocfs_lock_res * lockres, struct buffer_head *bh, struct inode *inode);
static int ocfs_zap_child_buffers_func(struct dentry *dentry, void *data);
/*
- * ocfs_insert_cache_link()
- *
- */
-static int ocfs_insert_cache_link (ocfs_super * osb, ocfs_lock_res * lockres)
-{
- int status = 0;
-
- LOG_ENTRY ();
-
- lockres->in_cache_list = true;
-
- list_add_tail (&(lockres->cache_list), &(osb->cache_lock_list));
-
- LOG_EXIT_STATUS (status);
- return status;
-} /* ocfs_insert_cache_link */
-
-
-
-/*
* ocfs_disk_request_vote()
*
*/
-static int ocfs_disk_request_vote (ocfs_super * osb, __u64 lock_id, __u32 lock_type, __u32 flags, __u64 vote_map, __u64 * lock_seq_num)
+static int ocfs_disk_request_vote (ocfs_super * osb, __u64 lock_id, __u32 lock_type, __u32 flags, __u64 vote_map, __u64 * lock_seq_num, __u64 feoff)
{
int status = 0;
__u64 offset = 0;
@@ -161,8 +140,13 @@
pubsect->vote_map = vote_map;
pubsect->vote_type = flags;
pubsect->dir_ent = lock_id;
+ pubsect->fe_off = feoff;
OCFS_BH_PUT_DATA(bhs[osb->node_num]);
+#ifdef VERBOSE_LOCKING_TRACE
+ printk("ocfs_disk_request_vote: lockid = %u.%u, "
+ "fe_off=%u.%u\n", HILO(lock_id), HILO(feoff));
+#endif
pub_off = osb->vol_layout.publ_sect_off + (osb->node_num * osb->sect_size);
status = ocfs_write_bh (osb, bhs[osb->node_num], 0, NULL);
@@ -695,7 +679,8 @@
LOG_ENTRY ();
status = ocfs_disk_request_vote (osb, lock_id, lock_type, flags,
- vote_map, lock_seq_num);
+ vote_map, lock_seq_num,
+ inode ? GET_INODE_FEOFF(inode) : 0);
LOG_EXIT_STATUS (status);
return status;
@@ -729,7 +714,7 @@
* ocfs_send_dlm_request_msg()
*
*/
-static int ocfs_send_dlm_request_msg (ocfs_super * osb, __u64 lock_id, __u32 lock_type, __u32 flags, ocfs_lock_res * lockres, __u64 vote_map)
+static int ocfs_send_dlm_request_msg (ocfs_super * osb, __u64 lock_id, __u32 lock_type, __u32 flags, ocfs_lock_res * lockres, __u64 vote_map, struct inode *inode)
{
int status = 0;
ocfs_dlm_msg *dlm_msg = NULL;
@@ -766,7 +751,15 @@
req->lock_id = lock_id;
req->flags = flags;
req->lock_seq_num = lockres->last_upd_seq_num;
+ if (inode)
+ req->fe_off = GET_INODE_FEOFF(inode);
+ else
+ req->fe_off = 0;
+#ifdef VERBOSE_LOCKING_TRACE
+ printk("ocfs_send_dlm_request_msg: inode=%p, lockid = %u.%u, "
+ "fe_off=%u.%u\n", inode, HILO(lock_id), HILO(req->fe_off));
+#endif
ocfs_send_bcast (osb, vote_map, dlm_msg);
status = ocfs_wait (lockres->voted_event,
atomic_read (&lockres->voted_event_woken),
@@ -798,6 +791,9 @@
unsigned long jif = 0;
int status = 0;
int cnt = 0;
+#ifdef VERBOSE_LOCKING_TRACE
+ bool printed = false;
+#endif
LOG_ENTRY_ARGS ("(0x%08x, %d)\n", lockres, timeout);
@@ -812,6 +808,12 @@
if (lockres->in_use) {
if (lockres->thread_id != mypid) {
spin_unlock (&lockres->lock_mutex);
+#ifdef VERBOSE_LOCKING_TRACE
+ if (!printed) {
+ printk("ocfs2: waiting on lockres %u.%u, mypid = %u, thread_id = %u\n", HILO(lockres->sector_num), ocfs_getpid(), lockres->thread_id);
+ printed = true;
+ }
+#endif
if (jif && jif < jiffies) {
LOG_TRACE_ARGS ("lockpid=%d, newpid=%d,"
" timedout\n",
@@ -876,7 +878,7 @@
* ocfs_update_disk_lock()
*
*/
-int ocfs_update_disk_lock (ocfs_super * osb, ocfs_lock_res * lockres, __u32 flags, struct buffer_head **bh, struct inode *inode)
+int ocfs_update_disk_lock (ocfs_super * osb, ocfs_lock_res * lockres, __u32 flags, struct buffer_head **bh, struct inode *inode, ocfs_journal_handle *handle)
{
int status = 0;
__u64 offset = 0;
@@ -891,6 +893,15 @@
LOG_ERROR_STATUS (status);
goto finally;
}
+
+ if (handle) {
+ status = ocfs_journal_access(handle, *bh, OCFS_JOURNAL_ACCESS_WRITE);
+ if (status < 0) {
+ LOG_ERROR_STATUS (status);
+ goto finally;
+ }
+ }
+
fe = (ocfs_file_entry *)OCFS_BH_GET_DATA_READ(*bh); /* read */
if (flags & DLOCK_FLAG_MASTER &&
@@ -936,7 +947,16 @@
OCFS_BH_PUT_DATA(*bh);
if (changed) {
- status = ocfs_write_bh (osb, *bh, 0, inode);
+ if (handle) {
+ status = ocfs_journal_dirty(handle, *bh);
+ lockres->lock_holders++;
+#warning I hope these lock flags are alright.
+ ocfs_get_lockres(lockres);
+ ocfs_journal_add_lock(handle, lockres->sector_num,
+ lockres->lock_type, 0, lockres,
+ *bh, inode);
+ } else
+ status = ocfs_write_bh (osb, *bh, 0, inode);
if (status < 0)
LOG_ERROR_STATUS (status);
}
@@ -950,7 +970,7 @@
* ocfs_update_master_on_open()
*
*/
-int ocfs_update_master_on_open (ocfs_super * osb, ocfs_lock_res * lockres, struct inode *inode)
+int ocfs_update_master_on_open (ocfs_super * osb, ocfs_lock_res * lockres, struct inode *inode, ocfs_journal_handle *handle)
{
int status = -EAGAIN;
bool disk_vote = false;
@@ -977,7 +997,8 @@
lockres->oin_openmap |= (1 << osb->node_num);
status = ocfs_update_disk_lock (osb, lockres,
- DLOCK_FLAG_OPEN_MAP, &bh, inode);
+ DLOCK_FLAG_OPEN_MAP, &bh,
+ inode, handle);
if (bh)
brelse(bh);
@@ -1031,7 +1052,6 @@
lockres->oin_openmap = 0;
lockres->sector_num = lock_id;
lockres->in_use = 0;
- lockres->oin = NULL;
lockres->lock_state = 0;
lockres->vote_state = 0;
lockres->in_cache_list = false;
@@ -1066,16 +1086,19 @@
* ocfs_create_update_lock()
*
*/
-int ocfs_create_update_lock (ocfs_super * osb, ocfs_inode * oin, __u64 lock_id, __u32 flags, bool new_file, struct inode *inode)
+int ocfs_create_update_lock (ocfs_super * osb, __u64 lock_id, __u32 flags, bool new_file, struct inode *inode, ocfs_journal_handle *handle)
{
int status = 0;
ocfs_lock_res *lockres = NULL;
ocfs_lock_res *tmp_lockres = NULL;
bool is_dir = false;
+ ocfs_inode *oin = NULL;
LOG_ENTRY_ARGS ("(0x%08x, 0x%08x, %u.%u, %u)\n", osb, oin,
HI (lock_id), LO (lock_id), flags);
+ oin = GET_INODE_OIN(inode);
+
is_dir = (flags & OCFS_OIN_DIRECTORY) ? true : false;
/* Check the lock state on the disk / in our resource map */
@@ -1087,17 +1110,6 @@
}
ocfs_acquire_lockres (lockres);
- if (lockres->oin) {
- if (lockres->oin->obj_id.type != OCFS_TYPE_OIN) {
- ocfs_release_lockres (lockres);
- LOG_ERROR_STATUS (status = -EFAIL);
- goto bail;
- } else {
- ocfs_put_lockres (lockres->oin->lock_res);
- lockres->oin->lock_res = NULL;
- }
- }
- lockres->oin = oin;
oin->oin_flags |= flags;
ocfs_get_lockres (lockres);
oin->lock_res = lockres;
@@ -1154,20 +1166,11 @@
}
goto bail;
}
- } else {
- if (flags & OCFS_OIN_CACHE_UPDATE) {
- status = ocfs_insert_cache_link (osb, lockres);
- if (status < 0) {
- LOG_ERROR_STR ("Lock up volume");
- goto bail;
- }
- }
}
}
ocfs_acquire_lockres (lockres);
- lockres->oin = oin;
oin->oin_flags |= flags;
if (oin->lock_res != lockres) {
ocfs_put_lockres (oin->lock_res);
@@ -1185,7 +1188,7 @@
/* Send a message to master so that he can send the oin update to */
/* this node also. If u are the master then update File_entry */
/* and set the bit that this node has a open */
- status = ocfs_update_master_on_open (osb, lockres, inode);
+ status = ocfs_update_master_on_open (osb, lockres, inode, handle);
if (status < 0) {
ocfs_release_lockres (lockres);
if (status != -EINTR)
@@ -1350,7 +1353,7 @@
if (lockres->readonly_node != osb->node_num)
lockres->readonly_node = OCFS_INVALID_NODE_NUM; // clear any owner
- status = ocfs_wait_for_readonly_drop(osb, lockres);
+ status = ocfs_wait_for_readonly_drop(osb, lockres, inode);
if (status < 0) {
if (status == -ETIMEDOUT)
goto again;
@@ -1528,7 +1531,7 @@
if (comm_voting && !disk_vote) {
LOG_TRACE_STR ("Network vote");
status = ocfs_send_dlm_request_msg (osb, lock_id, lock_type,
- flags, lockres, votemap);
+ flags, lockres, votemap, inode);
if (status >= 0) {
status = lockres->vote_status;
if (status >= 0) {
@@ -1748,7 +1751,7 @@
status = ocfs_send_dlm_request_msg (osb, lockres->sector_num,
lockres->lock_type,
FLAG_ACQUIRE_LOCK|FLAG_FILE_RELEASE_CACHE,
- lockres, votemap);
+ lockres, votemap, inode);
if (status >= 0) {
status = lockres->vote_status;
if (status >= 0) {
@@ -1872,7 +1875,7 @@
/* TODO: merge down into new lock function */
-int ocfs_send_readonly_drop_message(ocfs_super *osb, ocfs_lock_res *lockres, __u64 vote_map)
+int ocfs_send_readonly_drop_message(ocfs_super *osb, ocfs_lock_res *lockres, __u64 vote_map, struct inode *inode)
{
int status = 0, tmpstat;
__u64 lock_id = lockres->sector_num, lockseqnum = 0;
@@ -1882,7 +1885,7 @@
if (comm_voting) {
status = ocfs_send_dlm_request_msg (osb, lock_id, OCFS_DLM_ENABLE_CACHE_LOCK,
- FLAG_DROP_READONLY, lockres, vote_map);
+ FLAG_DROP_READONLY, lockres, vote_map, inode);
if (status >= 0) {
status = lockres->vote_status;
goto bail;
@@ -2009,7 +2012,7 @@
/* net voting */
if (comm_voting && !*disk_vote) {
LOG_TRACE_STR ("Network vote");
- status = ocfs_send_dlm_request_msg (osb, lock_id, lock_type, flags, lockres, vote_map);
+ status = ocfs_send_dlm_request_msg (osb, lock_id, lock_type, flags, lockres, vote_map, inode);
if (status >= 0) {
status = lockres->vote_status;
if (status >= 0)
@@ -2068,7 +2071,7 @@
/* update the disk lock */
if (need_lock_write) {
- status = ocfs_update_disk_lock (osb, lockres, lock_write_flags, &bh, inode);
+ status = ocfs_update_disk_lock (osb, lockres, lock_write_flags, &bh, inode, NULL);
if (status < 0)
LOG_ERROR_STATUS (status);
}
@@ -2095,17 +2098,17 @@
return status;
}
-static int _ocfs_wait_for_readonly_drop(ocfs_super *osb, ocfs_lock_res *lockres);
+static int _ocfs_wait_for_readonly_drop(ocfs_super *osb, ocfs_lock_res *lockres, struct inode *inode);
-static inline int ocfs_wait_for_readonly_drop(ocfs_super *osb, ocfs_lock_res *lockres)
+static inline int ocfs_wait_for_readonly_drop(ocfs_super *osb, ocfs_lock_res *lockres, struct inode *inode)
{
if (lockres->readonly_map == 0ULL)
return 0;
- return _ocfs_wait_for_readonly_drop(osb, lockres);
+ return _ocfs_wait_for_readonly_drop(osb, lockres, inode);
}
#define READONLY_DROP_TRIES 5
-static int _ocfs_wait_for_readonly_drop(ocfs_super *osb, ocfs_lock_res *lockres)
+static int _ocfs_wait_for_readonly_drop(ocfs_super *osb, ocfs_lock_res *lockres, struct inode *inode)
{
int tries = 0;
int status = 0;
@@ -2120,7 +2123,7 @@
OCFS_ASSERT(lockres->readonly_node == osb->node_num);
if (!lockres->readonly_dropping) {
ocfs_get_lockres(lockres);
- status = ocfs_drop_readonly_cache_lock(osb, lockres);
+ status = ocfs_drop_readonly_cache_lock(osb, lockres, inode);
if (status < 0) {
LOG_ERROR_STATUS (status);
ocfs_release_lockres (lockres);
Modified: trunk/src/extmap.c
===================================================================
--- trunk/src/extmap.c 2004-04-16 21:49:58 UTC (rev 846)
+++ trunk/src/extmap.c 2004-04-16 22:38:55 UTC (rev 847)
@@ -439,7 +439,7 @@
* ocfs_delete_all_extent_maps()
*
*/
-void ocfs_delete_all_extent_maps (ocfs_inode * oin)
+void ocfs_delete_all_extent_maps (ocfs_super *osb, ocfs_inode * oin)
{
__u32 RunsInExtentMap = 0, ExtentMapIndex, ByteCount = 0;
__s64 Vbo;
@@ -452,9 +452,9 @@
for (ExtentMapIndex = 0; ExtentMapIndex < RunsInExtentMap;
ExtentMapIndex++) {
if (ocfs_get_next_extent_map_entry
- (oin->osb, &oin->map, ExtentMapIndex, &Vbo, &Lbo,
+ (osb, &oin->map, ExtentMapIndex, &Vbo, &Lbo,
&ByteCount)) {
- ocfs_remove_extent_map_entry (oin->osb, &oin->map, Vbo,
+ ocfs_remove_extent_map_entry (osb, &oin->map, Vbo,
ByteCount);
}
}
Modified: trunk/src/file.c
===================================================================
--- trunk/src/file.c 2004-04-16 21:49:58 UTC (rev 846)
+++ trunk/src/file.c 2004-04-16 22:38:55 UTC (rev 847)
@@ -96,7 +96,6 @@
ocfs_inode *oin = NULL;
bool bAcquiredOIN = false;
bool bClearInUse = false;
- bool new_oin = false;
struct buffer_head *fe_bh = NULL;
__u64 parent_off;
ocfs_sem *oin_sem = NULL;
@@ -121,98 +120,60 @@
/* kch - for an open request we are already given the
* inode, and therefore we are given the oin too */
down(&inode->i_sem);
- oin = NULL;
- if (inode_data_is_oin (inode))
- oin = GET_INODE_OIN(inode);
- status = -EFAIL;
+ oin = GET_INODE_OIN(inode);
+ oin_sem = &(oin->main_res);
+ ocfs_down_sem (oin_sem, true);
+ bAcquiredOIN = true;
- if (oin != NULL) {
- if (!(oin->oin_flags & OCFS_OIN_IN_TEARDOWN) &&
- !(oin->oin_flags & OCFS_OIN_DELETE_ON_CLOSE)) {
- OCFS_SET_FLAG (oin->oin_flags, OCFS_OIN_IN_USE);
- status = 0;
- }
- if (status < 0) {
- if (oin->oin_flags & OCFS_OIN_IN_TEARDOWN)
- LOG_ERROR_ARGS ("oin (%p) in teardown", oin);
- else
- LOG_ERROR_ARGS ("oin (%p) deleted", oin);
- }
+ /* If the in use flag is set, forget about it. This will go
+ * eventually. */
+ if (!(oin->oin_flags & OCFS_OIN_IN_TEARDOWN) &&
+ !(oin->oin_flags & OCFS_OIN_DELETE_ON_CLOSE)) {
+ OCFS_SET_FLAG (oin->oin_flags, OCFS_OIN_IN_USE);
+ bClearInUse = true;
} else {
- /* now it IS possible to have an inode but no OIN attached yet
- * must be loaded now to open file */
- status = -ENOENT;
+ if (oin->oin_flags & OCFS_OIN_IN_TEARDOWN)
+ LOG_ERROR_ARGS ("oin (%p) in teardown", oin);
+ else
+ LOG_ERROR_ARGS ("oin (%p) deleted", oin);
+ up(&inode->i_sem);
+ goto leave;
}
- up(&inode->i_sem);
- if (status < 0) {
- if (status != -ENOENT && status != -EINTR) {
- LOG_ERROR_STATUS (status);
+ /* first open, we've gotta update the lock state. */
+ if (!OCFS_I(inode)->open_hndl_cnt) {
+ status = ocfs_read_bh(osb, GET_INODE_FEOFF(inode), &fe_bh,
+ OCFS_BH_CACHED, inode);
+ if (status < 0) {
+ up(&inode->i_sem);
+ LOG_ERROR_STATUS(status);
goto leave;
}
- /* Look on the disk now ... */
- down(&parent->i_sem);
- status = ocfs_find_files_on_disk (osb, parent_off, &(dentry->d_name),
- &fe_bh, NULL, parent, true);
- up(&parent->i_sem);
-
- if (status >= 0) {
- oin = NULL;
- ocfs_down_sem (&(osb->osb_res), true);
- status = ocfs_create_oin_from_entry (osb, fe_bh, &oin, parent_off, inode);
- if (status < 0)
- LOG_ERROR_STATUS(status);
- new_oin = true;
- ocfs_up_sem (&(osb->osb_res));
+ status = ocfs_inode_open(osb, fe_bh, NULL, inode);
+ if (status < 0) {
+ up(&inode->i_sem);
+ LOG_ERROR_STATUS(status);
+ if (status != -EINTR) {
+ LOG_ERROR_ARGS("Open request made for nonexistent "
+ "file! ('%*s')",
+ file->f_dentry->d_name.len,
+ file->f_dentry->d_name.name);
+ status = -ENOENT;
+ }
+ goto leave;
}
- }
+ bClearInUse = true;
- if (status < 0) { /* not found on disk or in mem */
- if (status != -EINTR) {
- LOG_ERROR_ARGS("Open request made for nonexistent "
- "file! ('%*s')",
- file->f_dentry->d_name.len,
- file->f_dentry->d_name.name);
- status = -ENOENT;
+ status = ocfs_inode_fill_ext_map (osb, fe_bh, inode);
+ if (status < 0) {
+ up(&inode->i_sem);
+ LOG_ERROR_STATUS(status);
+ goto leave;
}
- goto leave;
}
-
- bClearInUse = true;
-
- /* check if another process doing an open */
- /* concurrently has just set the oin */
- down(&inode->i_sem);
- if (new_oin) {
- if (inode_data_is_oin (inode)) {
- // delete the oin we just made
- if (oin->inode) {
- iput(oin->inode);
- oin->inode = NULL;
- }
- oin->lock_res = NULL;
- ocfs_release_oin(oin, true);
- // and use the correct one
- oin = GET_INODE_OIN(inode);
- } else {
- if (ocfs_inc_icount(inode) < 0)
- BUG();
- oin->inode = inode;
- SET_INODE_OIN (inode, oin);
- }
- }
-
- /* we should now have a single oin regardless */
- /* of how many concurrent openers at this point */
- /* so take the oin->main_res so we won't need the i_sem */
up(&inode->i_sem);
-
- oin_sem = &(oin->main_res);
- if (!bAcquiredOIN) {
- ocfs_down_sem (oin_sem, true);
- bAcquiredOIN = true;
- }
+ /* yes, hold onto main_res. */
if (oin->oin_flags & OCFS_OIN_DELETE_ON_CLOSE) {
LOG_TRACE_STR ("oin has DELETE_ON_CLOSE set, returning DELETE_PENDING");
@@ -220,9 +181,8 @@
goto leave;
}
- /* only call ocfs_verify_update_oin if there's a good inode */
- if (oin->inode == inode && OIN_NEEDS_VERIFICATION(oin)) {
- status = ocfs_verify_update_oin (osb, oin, &truncate_pages);
+ if (OCFS_I(inode)->needs_verification) {
+ status = ocfs_verify_update_inode (osb, inode, &truncate_pages);
if (status < 0) {
/* disable VOLUME TODO */
LOG_ERROR_STATUS (status);
@@ -230,12 +190,13 @@
}
}
- if (oin->open_hndl_cnt > 0) {
+ if (OCFS_I(inode)->open_hndl_cnt > 0) {
/* The OIN is currently in use by some thread. */
/* We must check whether the requested access/share access */
/* conflicts with the existing open operations. */
- LOG_TRACE_ARGS ("oin->open_hndl_cnt > 0! : %u\n", oin->open_hndl_cnt);
+ LOG_TRACE_ARGS ("oin->open_hndl_cnt > 0! : %u\n",
+ OCFS_I(inode)->open_hndl_cnt);
if (!(mode & O_DIRECT)) {
if ((oin->oin_flags & OCFS_OIN_OPEN_FOR_DIRECTIO) && !(mode & O_RDONLY)) {
status = -EACCES;
@@ -266,7 +227,7 @@
}
}
- oin->open_hndl_cnt++;
+ OCFS_I(inode)->open_hndl_cnt++;
/* We should clear the in use now as we are safe from the case */
/* where the voting thread can vote and we have an open in */
@@ -326,6 +287,9 @@
ret = 0;
}
+ if (ret < 0)
+ ocfs_bh_sem_hash_cleanup_pid(ocfs_getpid());
+
LOG_TRACE_ARGS
("exiting file_open: file=%p dentry=%p inode=%p oin=%p kiovec=%d\n",
file, file->f_dentry, file->f_dentry->d_inode,
@@ -375,68 +339,49 @@
ocfs_safefree (ofile->curr_dir_buf);
ofile->curr_dir_buf = NULL;
}
- ocfs_release_ofile (ofile);
+ ocfs_release_ofile (ofile);
}
goto bail;
}
- /* file */
- if (inode_data_is_oin(inode))
- oin = GET_INODE_OIN(inode);
+ oin = GET_INODE_OIN(inode);
- if (oin == NULL)
- goto bail;
-
- if (oin->obj_id.type != OCFS_TYPE_OIN ||
- oin->obj_id.size != sizeof (ocfs_inode) ||
- oin->main_res.magic != OCFS_SEM_MAGIC) {
- int i;
-
- LOG_ERROR_ARGS("oin appears to have been freed! oin=%p, inode->oin=%p\n",
- oin, GET_INODE_OIN(inode));
- for (i=0; i<sizeof (ocfs_inode); i++) {
- printk("%03x ", ((char *)oin)[i]);
- }
- printk("\n");
- goto bail;
- }
-
-
ocfs_down_sem (&(oin->main_res), true);
- oin->open_hndl_cnt--;
- if (!oin->open_hndl_cnt)
+ OCFS_I(inode)->open_hndl_cnt--;
+ if (!OCFS_I(inode)->open_hndl_cnt)
last_close = true;
if (oin->oin_flags & OCFS_OIN_ROOT_DIRECTORY) {
ocfs_up_sem (&(oin->main_res));
goto bail;
}
-
+
LOG_TRACE_ARGS ("openhandles: %d / osbfiles: %d / refcount: %d\n",
- oin->open_hndl_cnt, osb->file_open_cnt,
+ OCFS_I(inode)->open_hndl_cnt, osb->file_open_cnt,
atomic_read(&dentry->d_count));
-
- /* FIXME: in all the other places I run thru all the dentries */
- /* for the inode, but here I just check this one becuz I'm lz */
- /* no hard links yet so who cares */
- if (!atomic_read(&dentry->d_count)) {
- if (oin->oin_flags & OCFS_OIN_OPEN_FOR_DIRECTIO) {
+
+ if (last_close) {
+ ocfs_extent_map_destroy (&oin->map);
+ ocfs_extent_map_init (&oin->map);
+
+ if (oin->oin_flags & OCFS_OIN_OPEN_FOR_DIRECTIO)
OCFS_CLEAR_FLAG(oin->oin_flags, OCFS_OIN_OPEN_FOR_DIRECTIO);
+
+ if (oin->oin_flags & OCFS_OIN_NEEDS_DELETION ||
+ oin->oin_flags & OCFS_OIN_IN_USE) {
+ ocfs_up_sem (&(oin->main_res));
+ LOG_ERROR_STR("Not deleting lockrse on a last close! eek!");
+ goto bail;
}
- if (oin->oin_flags & OCFS_OIN_NEEDS_DELETION ||
- oin->oin_flags & OCFS_OIN_IN_USE) {
- ocfs_up_sem (&(oin->main_res));
- goto bail;
- }
-
- ocfs_up_sem (&(oin->main_res));
- ocfs_release_oin (oin, true);
- ocfs_sync_inode(inode);
- } else {
- ocfs_up_sem (&(oin->main_res));
- ocfs_release_cached_oin (osb, oin);
- ocfs_sync_inode(inode);
- }
+ if (!oin->lock_res)
+ LOG_ERROR_STR("My oin has no lockres!");
+ else {
+ ocfs_put_lockres(oin->lock_res);
+ oin->lock_res = NULL;
+ }
+ }
+ ocfs_up_sem (&(oin->main_res));
+ ocfs_sync_inode(inode);
if (last_close) {
if (inode->i_data.nrpages)
@@ -444,6 +389,8 @@
}
bail:
+// ocfs_bh_sem_hash_cleanup_pid(ocfs_getpid());
+
LOG_EXIT_LONG (0);
return 0;
} /* ocfs_file_release */
@@ -597,8 +544,9 @@
if (status < 0) {
ocfs_abort_trans(handle);
} else {
- ocfs_journal_add_lock(handle, lockId, locktype, lockFlags,
- pLockResource, bh);
+ ocfs_journal_add_lock(handle, lockId, locktype,
+ lockFlags, pLockResource, bh,
+ inode);
bAcquiredLock = false;
ocfs_commit_trans(handle);
@@ -656,7 +604,7 @@
goto bail;
}
oin = GET_INODE_OIN(inode);
- osb = (ocfs_super *) oin->osb;
+ osb = (ocfs_super *) OCFS_GENERIC_SB_P(inode->i_sb);
lockres = oin->lock_res;
if (lockres == NULL) {
@@ -666,13 +614,6 @@
ocfs_get_lockres (lockres);
- if ((lockres->master_node_num != osb->node_num) ||
- (lockres->lock_type != OCFS_DLM_ENABLE_CACHE_LOCK)) {
- oin->cache_enabled = false;
- } else {
- oin->cache_enabled = true;
- }
-
if (osb->osb_flags & OCFS_OSB_FLAGS_SHUTDOWN) {
LOG_TRACE_STR ("Volume has already started shutdown");
ret = -EIO;
@@ -696,8 +637,8 @@
if (!(filp->f_flags & O_DIRECT)) {
/* FIXME: is the down_sem supposed to be here?! */
LOG_TRACE_ARGS ("non O_DIRECT write, fileopencount=%d\n",
- oin->open_hndl_cnt);
- if (oin->open_hndl_cnt > 1) {
+ OCFS_I(inode)->open_hndl_cnt);
+ if (OCFS_I(inode)->open_hndl_cnt > 1) {
if (oin->oin_flags & OCFS_OIN_OPEN_FOR_WRITE) {
LOG_TRACE_STR
("uh oh! someone else is doing non O_DIRECT writes!\n");
@@ -712,15 +653,15 @@
}
}
- if (OIN_NEEDS_VERIFICATION (oin)) {
+ if (OCFS_I(inode)->needs_verification) {
LOG_TRACE_STR ("OIN_NEEDS_VERIFICATION");
ocfs_down_sem (&(oin->main_res), true);
- status = ocfs_verify_update_oin (osb, oin, &needs_trunc);
+ status = ocfs_verify_update_inode (osb, inode, &needs_trunc);
ocfs_up_sem (&(oin->main_res));
if (needs_trunc)
ocfs_truncate_inode_pages(inode, 0);
if (status < 0) {
- LOG_TRACE_STR ("ocfs_verify_update_oin failed");
+ LOG_TRACE_STR ("ocfs_verify_update_inode failed");
LOG_TRACE_STR ("TODO: disable volume");
ret = -EIO;
goto bail;
@@ -756,7 +697,7 @@
HI (oin->alloc_size), LO (oin->alloc_size), HI (newsize),
LO (newsize));
- status = ocfs_extend_file (osb, oin->parent_dirnode_off, oin, newsize, GET_INODE_FEOFF(inode), NULL, inode, NULL);
+ status = ocfs_extend_file (osb, newsize, GET_INODE_FEOFF(inode), NULL, inode, NULL);
if (status < 0) {
if (status != -EINTR && status != -ENOSPC) {
LOG_ERROR_STATUS (status);
@@ -796,17 +737,8 @@
OCFS_CLEAR_FLAG(oin->oin_flags, OCFS_OIN_OPEN_FOR_WRITE);
}
-#if 0
- if (inode && oin && !oin->cache_enabled && !(filp->f_flags & O_DIRECT)) {
- fsync_inode_buffers(inode);
-#if LINUX_VERSION_CODE >= LinuxVersionCode(2,4,18)
- fsync_inode_data_buffers(inode);
-#endif
- }
-#endif
-
ocfs_put_lockres (lockres);
-
+
if (ret < 0)
ocfs_bh_sem_hash_cleanup_pid(ocfs_getpid());
@@ -837,7 +769,7 @@
goto bail;
}
oin = GET_INODE_OIN(inode);
- osb = (ocfs_super *) oin->osb;
+ osb = (ocfs_super *) OCFS_GENERIC_SB_P(inode->i_sb);
if (filp->f_flags & O_DIRECT) {
/* anything special for o_direct? */
@@ -849,14 +781,14 @@
}
}
- if (OIN_NEEDS_VERIFICATION (oin)) {
+ if (OCFS_I(inode)->needs_verification) {
ocfs_down_sem (&(oin->main_res), true);
- status = ocfs_verify_update_oin (osb, oin, &needs_trunc);
+ status = ocfs_verify_update_inode (osb, inode, &needs_trunc);
ocfs_up_sem (&(oin->main_res));
if (needs_trunc)
ocfs_truncate_inode_pages(inode, 0);
if (status < 0) {
- LOG_TRACE_STR ("ocfs_verify_update_oin failed");
+ LOG_TRACE_STR ("ocfs_verify_update_inode failed");
LOG_TRACE_STR ("TODO: disable volume");
ret = -EIO;
goto bail;
@@ -1081,7 +1013,7 @@
/* ocfs_extend_file()
*
*/
-int ocfs_extend_file (ocfs_super * osb, __u64 parent_off, ocfs_inode * oin, __u64 file_size, __u64 file_off, ocfs_journal_handle *passed_handle, struct inode *inode, struct iattr *attr)
+int ocfs_extend_file (ocfs_super * osb, __u64 file_size, __u64 file_off, ocfs_journal_handle *passed_handle, struct inode *inode, struct iattr *attr)
{
int status = 0;
int tmpstat;
@@ -1102,9 +1034,15 @@
struct buffer_head *bh = NULL;
int flags = 0;
ocfs_journal_handle *handle = NULL;
+ ocfs_inode *oin = NULL;
LOG_ENTRY ();
+ if (!inode)
+ BUG();
+
+ oin = GET_INODE_OIN(inode);
+
if (file_size == 0)
goto leave;
@@ -1238,7 +1176,7 @@
/* note: ok if oin is null here, not used in
* ocfs_allocate_extent */
- status = ocfs_allocate_extent (osb, oin, bh, handle,
+ status = ocfs_allocate_extent (osb, bh, handle,
actualDiskOffset, actualLength, inode);
if (status < 0) {
OCFS_BH_PUT_DATA(bh);
@@ -1298,9 +1236,9 @@
if (bFileLockAcquired)
lockFlags |= FLAG_FILE_UPDATE_OIN;
- ocfs_journal_add_lock(handle, lockId, locktype,
+ ocfs_journal_add_lock(handle, lockId, locktype,
lockFlags, pLockResource,
- bh);
+ bh, inode);
bAcquiredLock = false;
ocfs_commit_trans(handle);
@@ -1397,30 +1335,28 @@
}
if (attr->ia_valid & ATTR_SIZE) {
- if (oin != NULL) {
- ocfs_down_sem (&(oin->main_res), true);
- if (OIN_NEEDS_VERIFICATION (oin)) {
- LOG_TRACE_STR ("OIN_NEEDS_VERIFICATION");
- status = ocfs_verify_update_oin (osb, oin, &needs_trunc);
- if (status < 0) {
- LOG_ERROR_STATUS (status);
- LOG_TRACE_STR ("TODO: disable volume");
- ocfs_up_sem (&(oin->main_res));
- error = -EIO;
- goto bail;
- }
+ ocfs_down_sem (&(oin->main_res), true);
+ if (OCFS_I(inode)->needs_verification) {
+ LOG_TRACE_STR ("OIN_NEEDS_VERIFICATION");
+ status = ocfs_verify_update_inode (osb, inode, &needs_trunc);
+ if (status < 0) {
+ LOG_ERROR_STATUS (status);
+ LOG_TRACE_STR ("TODO: disable volume");
+ ocfs_up_sem (&(oin->main_res));
+ error = -EIO;
+ goto bail;
}
- ocfs_up_sem (&(oin->main_res));
- if (needs_trunc)
- ocfs_truncate_inode_pages(inode, 0);
}
+ ocfs_up_sem (&(oin->main_res));
+ if (needs_trunc)
+ ocfs_truncate_inode_pages(inode, 0);
if (inode->i_size > newsize)
status = ocfs_truncate_file(osb, fileOff, newsize,
oin, inode);
else {
- status = ocfs_extend_file(osb, parentOff, oin, newsize,
- fileOff, NULL, inode, attr);
+ status = ocfs_extend_file(osb, newsize, fileOff, NULL,
+ inode, attr);
extended = true;
}
if (status < 0) {
@@ -1433,7 +1369,7 @@
if (oin != NULL) {
ocfs_down_sem (&(oin->main_res), true);
if (inode->i_size > newsize) {
- ocfs_delete_all_extent_maps(oin);
+ ocfs_delete_all_extent_maps(osb, oin);
}
inode->i_size = newsize;
inode->i_blocks = (newsize + sb->s_blocksize) >> sb->s_blocksize_bits;
@@ -1522,6 +1458,7 @@
struct inode *inode;
struct super_block *sb = dentry->d_inode->i_sb;
int status, needs_trunc = 0;
+ ocfs_super *osb;
LOG_ENTRY_ARGS ("(0x%08x, 0x%08x, '%*s')\n", dentry, attr,
dentry->d_name.len, dentry->d_name.name);
@@ -1529,19 +1466,20 @@
inode = dentry->d_inode;
if (inode == NULL || !inode_data_is_oin (inode))
goto bail;
+
+ osb = (ocfs_super *) OCFS_GENERIC_SB_P(inode->i_sb);
oin = GET_INODE_OIN(inode);
if (oin == ((ocfs_super *)(OCFS_GENERIC_SB_P(sb)))->oin_root_dir)
goto bail;
- if (oin != NULL) {
- ocfs_down_sem (&(oin->main_res), true);
- status = ocfs_verify_update_oin (oin->osb, oin, &needs_trunc);
- ocfs_up_sem (&(oin->main_res));
- if (needs_trunc)
- ocfs_truncate_inode_pages(inode, 0);
- if (status < 0)
- LOG_ERROR_STATUS (status);
- }
+ ocfs_down_sem (&(oin->main_res), true);
+ status = ocfs_verify_update_inode (osb, inode, &needs_trunc);
+ ocfs_up_sem (&(oin->main_res));
+ if (needs_trunc)
+ ocfs_truncate_inode_pages(inode, 0);
+ if (status < 0)
+ LOG_ERROR_STATUS (status);
+
bail:
LOG_EXIT_LONG (0);
return 0;
Modified: trunk/src/hash.c
===================================================================
--- trunk/src/hash.c 2004-04-16 21:49:58 UTC (rev 846)
+++ trunk/src/hash.c 2004-04-16 22:38:55 UTC (rev 847)
@@ -1526,7 +1526,7 @@
inum = __ocfs_inode_hash_lookup(h, voteoff);
if (!inum) {
- printk("ocfs2: lost inum, offset =%u.%u, inode->i_ino= %lu\n",
+ printk("ocfs2: lost inum, offset = %u.%u, inode->i_ino= %lu\n",
HILO(voteoff), inode->i_ino);
BUG();
@@ -1615,6 +1615,12 @@
spin_unlock(&h->lock);
+ if (!inum->i_inode)
+ LOG_ERROR_ARGS("deleting inum in unbound state! (state = %d, "
+ "voteoff = %u.%u, feoff = %u.%u, i_ino = %u\n",
+ inum->i_state, HILO(inum->i_voteoff),
+ HILO(inum->i_feoff), inum->i_ino);
+
if (inum->i_inode)
iput(inum->i_inode);
@@ -1708,45 +1714,27 @@
/*
* ocfs_get_inode_from_offset()
*
- * If you call this on an offset, you MUST make sure that it won't be
- * deleted out from underneath us.
+ * Not all fields are required, pick your poison:
+ * * fe_bh only -- voteoff and feoff should both be zero then.
+ * * voteoff and feoff -- fe_bh can be NULL (doesn't have to)
*/
struct inode *ocfs_get_inode_from_offset(ocfs_super *osb,
- __u64 offset,
+ __u64 voteoff, __u64 feoff,
struct buffer_head *fe_bh)
{
struct inode *inode = NULL;
struct super_block *sb = osb->sb;
- __u64 fe_off;
ocfs_file_entry *fe;
ocfs_find_inode_args args;
- LOG_ENTRY_ARGS("(offset = %u.%u)\n", HILO(offset));
+ LOG_ENTRY_ARGS("(voteoff = %u.%u, feoff = %u.%u, fe_bh = %p)\n",
+ HILO(voteoff), HILO(feoff), fe_bh);
- /* This is ugly, but...
- * There are several cases where we may not want an inode:
- * 1) any time during 1st mount (root_start_off will be 0)
- * 2) any system file, EXCEPT the journal as JBD requires one
- */
- if (osb->vol_layout.root_start_off == 0
- || offset < osb->vol_layout.root_start_off) {
- /* OHMYGODTHISISTHEUGLIESTIFEVER */
- if (offset < (JOURNAL_FILE_BASE_ID * osb->sect_size
- + osb->vol_layout.root_int_off)
- ||
- offset >= ((JOURNAL_FILE_BASE_ID + OCFS_MAXIMUM_NODES)
- * osb->sect_size
- + osb->vol_layout.root_int_off)) {
- printk("ocfs2: skipping inode create for %u.%u\n",
- HILO(offset));
- goto bail;
- }
- }
-
- /* if they ask for the root dirnode, just return it. */
- if (offset == osb->vol_layout.root_start_off) {
+ /* Shortcut: if they ask for the root dirnode, just return
+ * it. */
+ if (voteoff == osb->vol_layout.root_start_off) {
LOG_TRACE_ARGS("Asked for root dirnode (%u.%u)\n",
- HILO(offset));
+ HILO(feoff));
inode = osb->sb->s_root->d_inode;
@@ -1760,29 +1748,65 @@
goto bail;
}
- /* if it's a directory, we want the parent fe off so get it here. */
- fe = (ocfs_file_entry *) OCFS_BH_GET_DATA_READ(fe_bh);
- if (!IS_VALID_FILE_ENTRY(fe)) {
+ /* Ok, lets try to be smart here. We need a very specific set
+ * of arguments to get our inode. Figure these out from the
+ * available data. */
+ if (fe_bh) {
+ /* best case -- we can figure out what we need from
+ * the file entry! */
+ fe = (ocfs_file_entry *) OCFS_BH_GET_DATA_READ(fe_bh);
+ if (!IS_VALID_FILE_ENTRY(fe)) {
+ OCFS_BH_PUT_DATA(fe_bh);
+ LOG_ERROR_STATUS(-EINVAL);
+ goto bail;
+ }
+ feoff = fe->this_sector;
+ /* need voteoff too. */
+ if (fe->attribs & OCFS_ATTRIB_DIRECTORY)
+ voteoff = fe->extents[0].disk_off;
+ else
+ voteoff = fe->this_sector;
OCFS_BH_PUT_DATA(fe_bh);
- LOG_ERROR_STATUS(-EINVAL);
- goto bail;
+ } else {
+ if ((voteoff == 0) || (feoff == 0)) {
+ LOG_ERROR_STATUS(-EINVAL);
+ goto bail;
+ }
}
- fe_off = fe->this_sector;
- OCFS_BH_PUT_DATA(fe_bh);
- inode = ocfs_inode_hash_lookup(osb, offset, false);
+ /* This is ugly, but...
+ * There are several cases where we may not want an inode:
+ * 1) any time during 1st mount (root_start_off will be 0)
+ * 2) any system file, EXCEPT the journal as JBD requires one
+ */
+ if (osb->vol_layout.root_start_off == 0
+ || feoff < osb->vol_layout.root_start_off) {
+ /* OHMYGODTHISISTHEUGLIESTIFEVER */
+ if (feoff < (JOURNAL_FILE_BASE_ID * osb->sect_size
+ + osb->vol_layout.root_int_off)
+ ||
+ feoff >= ((JOURNAL_FILE_BASE_ID + OCFS_MAXIMUM_NODES)
+ * osb->sect_size
+ + osb->vol_layout.root_int_off)) {
+ printk("ocfs2: skipping inode create for %u.%u\n",
+ HILO(feoff));
+ goto bail;
+ }
+ }
+
+ inode = ocfs_inode_hash_lookup(osb, voteoff, false);
if (!inode) {
/* we should put this guy in the hash now... */
LOG_TRACE_STR("calling iget4");
- args.offset = fe_off;
+ args.offset = feoff;
args.fe_bh = fe_bh;
args.skip_bind = 0;
/* alright, allocate a new inode number for this guy
* and insert it into the hash. It's not bound yet --
* read_inode2 binds the actual inode to it. */
- args.ino = ocfs_inode_hash_insert(osb, offset, fe_off);
+ args.ino = ocfs_inode_hash_insert(osb, voteoff, feoff);
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
inode = ocfs_iget (sb, &args);
#else
@@ -1804,7 +1828,6 @@
}
}
-
bail:
if (inode)
LOG_TRACE_ARGS("returning inode with number %lu\n",
Modified: trunk/src/inc/journal.h
===================================================================
--- trunk/src/inc/journal.h 2004-04-16 21:49:58 UTC (rev 846)
+++ trunk/src/inc/journal.h 2004-04-16 22:38:55 UTC (rev 847)
@@ -99,6 +99,7 @@
__u32 flags;
struct _ocfs_lock_res * res;
struct buffer_head *bh;
+ struct inode *inode;
struct list_head lock_list;
};
@@ -330,7 +331,8 @@
void ocfs_journal_add_lock(ocfs_journal_handle *handle,
__u64 id, __u32 type, __u32 flags,
struct _ocfs_lock_res *res,
- struct buffer_head *bh);
+ struct buffer_head *bh,
+ struct inode *inode);
/*
* Trans Lock:
@@ -393,4 +395,8 @@
+ OCFS_MAX_FILE_ENTRY_EXTENTS \
+ OCFS_JOURNAL_FUZZ_CREDITS + \
OCFS_DEFAULT_DIR_NODE_SECTS)
+
+/* On very rare open operations (it's a first open and we're not in
+ * the open map), we have to change the file entry. */
+#define OCFS_OPEN_CREDITS 1
#endif /* _OCFSJOURNAL_H_ */
Modified: trunk/src/inc/ocfs.h
===================================================================
--- trunk/src/inc/ocfs.h 2004-04-16 21:49:58 UTC (rev 846)
+++ trunk/src/inc/ocfs.h 2004-04-16 22:38:55 UTC (rev 847)
@@ -229,62 +229,6 @@
#define ocfs_getpid() getpid()
#endif
-struct _ocfs_inode;
-
-/* OCFS2 Inode Private Data
- *
- * feoff/voteoff can change during rename. Luckily, rename takes a ton
- * of locks and does several checks, so you're safe reading these values
- * if any of the following is true:
- * 1) you have i_sem
- * 2) you have oin->main_res
- * 3) oin->open_hndl_cnt > 0
- */
-typedef struct _ocfs_inode_private
-{
- struct _ocfs_inode *oin;
- __u64 voteoff;
- __u64 feoff;
- atomic_t i_clean_buffer_seq;
- __u8 deleted; /* this can be a generic flags field later */
-} ocfs_inode_private;
-
-#define GET_INODE_CLEAN_SEQ(i) (atomic_t *)(&(OCFS_GENERIC_IP(i)->i_clean_buffer_seq))
-
-#define OCFS_GENERIC_IP(i) ((ocfs_inode_private *)(i->u.generic_ip))
-
-#define inode_data_is_oin(i) (OCFS_GENERIC_IP(i)->oin != NULL)
-
-#define INODE_DELETED(i) (OCFS_GENERIC_IP(i)->deleted)
-#define SET_INODE_DELETED(i) OCFS_GENERIC_IP(i)->deleted = 1
-#define CLEAR_INODE_DELETED(i) OCFS_GENERIC_IP(i)->deleted = 0
-
-#define SET_INODE_VOTEOFF(i,o) \
-do { \
- OCFS_GENERIC_IP(i)->voteoff = o; \
-} while (0)
-
-#define GET_INODE_VOTEOFF(i) OCFS_GENERIC_IP(i)->voteoff
-
-#define SET_INODE_FEOFF(i,o) \
-do { \
- OCFS_GENERIC_IP(i)->feoff = o; \
-} while (0)
-
-#define GET_INODE_FEOFF(i) OCFS_GENERIC_IP(i)->feoff
-
-#define CLEAR_INODE_OIN(i) \
-do { \
- GET_INODE_OIN(i)= (void *)NULL; \
-} while (0)
-
-#define SET_INODE_OIN(i,o) \
-do { \
- GET_INODE_OIN(i)= (void *)o; \
-} while (0)
-
-#define GET_INODE_OIN(i) ((OCFS_GENERIC_IP(i)->oin))
-
#define FIRST_FILE_ENTRY(dir) ((char *) ((char *)dir)+OCFS_SECTOR_SIZE)
#define FILEENT(dir,idx) (ocfs_file_entry *) ( ((char *)dir) + \
((dir->index[idx]+1) * OCFS_SECTOR_SIZE))
@@ -603,9 +547,6 @@
#ifndef _OCFSDEF_H_
#define _OCFSDEF_H_
-#define OIN_NEEDS_VERIFICATION(a) ((a)->needs_verification)
-#define OIN_UPDATED(a) ((a)->needs_verification = false)
-
#define IS_VALID_DIR_NODE(ptr) \
(!strncmp((ptr)->signature, OCFS_DIR_NODE_SIGNATURE, \
strlen(OCFS_DIR_NODE_SIGNATURE)))
@@ -998,6 +939,7 @@
} while (0)
#endif
+#if 0
/* oin macros - currently the release is handled separately */
#ifdef OCFS_MEM_DBG
#define ocfs_allocate_oin() ((ocfs_inode *)({ \
@@ -1020,8 +962,8 @@
} \
oin; }))
#endif
+#endif
-
#define hashsize(n) ((__u32)1<<(n))
#define hashmask(n) (hashsize(n)-1)
@@ -1801,7 +1743,6 @@
bool cache_lock_held;
__u32 lock_state;
__u32 vote_state; /* Is the lockres being voted on over ipcdlm */
- ocfs_inode *oin;
spinlock_t lock_mutex;
wait_queue_head_t voted_event;
atomic_t voted_event_woken;
@@ -1820,25 +1761,80 @@
struct _ocfs_inode
{
- ocfs_obj_id obj_id;
- struct inode *inode;
- struct _ocfs_super *osb; /* ocfs_inode belongs to this volume */
- struct list_head recovery_list;
ocfs_sem main_res;
struct semaphore extend_sem;
__u32 num_extends;
ocfs_lock_res *lock_res;
ocfs_extent_map map;
__s64 alloc_size;
- __u64 chng_seq_num;
- __u64 parent_dirnode_off; /* from the start of vol */
- __u32 open_hndl_cnt;
__u32 oin_flags;
- bool needs_verification;
- bool cache_enabled;
- bool journal_inode; /* is this the journal oin? */
};
+/* OCFS2 Inode Private Data
+ *
+ * feoff/voteoff can change during rename. Luckily, rename takes a ton
+ * of locks and does several checks, so you're safe reading these values
+ * if any of the following is true:
+ * 1) you have i_sem
+ * 2) you have oin->main_res
+ * 3) oin->open_hndl_cnt > 0
+ */
+typedef struct _ocfs_inode_private
+{
+ /* always valid, just a simple back pointer. */
+ struct inode *inode;
+
+ /* protected by main_res */
+ ocfs_inode oin;
+ __u32 open_hndl_cnt;
+ bool needs_verification;
+ struct list_head recovery_list;
+ __u64 chng_seq_num;
+
+ __u64 voteoff;
+ __u64 feoff;
+ atomic_t i_clean_buffer_seq;
+ __u32 flags; /* see below */
+} ocfs_inode_private;
+
+/* has this inode been deleted, either from this node or from another node. */
+#define OCFS_INODE_DELETED 0x00000001
+/* is this the journal inode? */
+#define OCFS_INODE_JOURNAL 0x00000002
+
+#define GET_INODE_CLEAN_SEQ(i) (atomic_t *)(&(OCFS_GENERIC_IP(i)->i_clean_buffer_seq))
+
+#define OCFS_GENERIC_IP(i) ((ocfs_inode_private *)(i->u.generic_ip))
+#define OCFS_I(i) OCFS_GENERIC_IP(i)
+
+#define INODE_DELETED(i) (OCFS_GENERIC_IP(i)->flags & OCFS_INODE_DELETED)
+#define SET_INODE_DELETED(i) (OCFS_GENERIC_IP(i)->flags |= OCFS_INODE_DELETED)
+#define CLEAR_INODE_DELETED(i) (OCFS_GENERIC_IP(i)->flags &= (~OCFS_INODE_DELETED))
+
+#define INODE_JOURNAL(i) (OCFS_GENERIC_IP(i)->flags & OCFS_INODE_JOURNAL)
+#define SET_INODE_JOURNAL(i) (OCFS_GENERIC_IP(i)->flags |= OCFS_INODE_JOURNAL)
+#define CLEAR_INODE_JOURNAL(i) (OCFS_GENERIC_IP(i)->flags &= (~OCFS_INODE_JOURNAL))
+
+#define SET_INODE_VOTEOFF(i,o) \
+do { \
+ OCFS_GENERIC_IP(i)->voteoff = o; \
+} while (0)
+
+#define GET_INODE_VOTEOFF(i) OCFS_GENERIC_IP(i)->voteoff
+
+#define SET_INODE_FEOFF(i,o) \
+do { \
+ OCFS_GENERIC_IP(i)->feoff = o; \
+} while (0)
+
+#define GET_INODE_FEOFF(i) OCFS_GENERIC_IP(i)->feoff
+
+/* callers of these next three functions should be fixed as we always
+ * have oin now. */
+#define inode_data_is_oin(i) (1)
+
+#define GET_INODE_OIN(i) (&(OCFS_GENERIC_IP(i)->oin))
+
typedef enum _ocfs_vol_state
{
VOLUME_DISABLED,
@@ -1964,6 +1960,7 @@
HASHTABLE root_sect_node; /* lockres->sector_num hash */
struct list_head cache_lock_list;
struct super_block *sb;
+ struct inode *root_inode;
ocfs_inode *oin_root_dir; /* ptr to the root dir ocfs_inode */
ocfs_vol_layout vol_layout;
ocfs_vol_node_map vol_node_map;
@@ -2143,6 +2140,7 @@
/* last seq num used in comm voting */
__u64 comm_seq_num; // NUMBER RANGE(0,ULONG_LONG_MAX)
bool mounted; /* used for journaling */
+ __u64 fe_off; /* needed to create inodes. */
}
OCFS_GCC_ATTR_PACKALGN
ocfs_publish; // END CLASS
@@ -2317,6 +2315,7 @@
__u32 flags;
__u64 lock_seq_num;
__u8 open_handle;
+ __u64 fe_off;
}
OCFS_GCC_ATTR_PACKALGN
ocfs_dlm_msg_hdr;
Modified: trunk/src/inc/proto.h
===================================================================
--- trunk/src/inc/proto.h 2004-04-16 21:49:58 UTC (rev 846)
+++ trunk/src/inc/proto.h 2004-04-16 22:38:55 UTC (rev 847)
@@ -27,10 +27,10 @@
#ifndef _PROTO_H_
#define _PROTO_H_
-int ocfs_allocate_extent (ocfs_super * osb, ocfs_inode * oin, struct buffer_head *fe_bh, ocfs_journal_handle *handle,__u64 actualDiskOffset, __u64 actualLength, struct inode *inode);
+int ocfs_allocate_extent (ocfs_super * osb, struct buffer_head *fe_bh, ocfs_journal_handle *handle,__u64 actualDiskOffset, __u64 actualLength, struct inode *inode);
int ocfs_kill_this_tree(ocfs_super *osb, struct buffer_head *extent_grp_bh, ocfs_journal_handle *handle, struct inode *inode);
int ocfs_free_extents_for_truncate (ocfs_super * osb, ocfs_file_entry * FileEntry, ocfs_journal_handle *handle, struct inode *inode);
-int ocfs_lookup_file_allocation (ocfs_super * osb, ocfs_inode * oin, __s64 Vbo, __s64 * Lbo, __u32 sectors, u32 *sector_count, struct inode *inode);
+int ocfs_lookup_file_allocation (ocfs_super * osb, __s64 Vbo, __s64 * Lbo, __u32 sectors, u32 *sector_count, struct inode *inode);
int ocfs_get_leaf_extent (ocfs_super * osb, ocfs_file_entry * FileEntry, __s64 Vbo, struct buffer_head **data_extent_bh, struct inode *inode);
int ocfs_find_contiguous_space_from_bitmap (ocfs_super * osb, __u64 file_size, __u64 * cluster_off, __u64 * cluster_count, bool sysfile, struct buffer_head *lock_bh);
int ocfs_alloc_node_block (ocfs_super * osb, __u64 FileSize, __u64 * DiskOffset, __u64 * file_off, __u32 NodeNum, __u32 Type, ocfs_journal_handle *handle);
@@ -44,20 +44,20 @@
int ocfs_acquire_lockres_ex (ocfs_lock_res * lockres, __u32 timeout);
void ocfs_release_lockres (ocfs_lock_res * lockres);
void ocfs_init_lockres (ocfs_super * osb, ocfs_lock_res * lockres, __u64 lock_id);
-int ocfs_create_update_lock (ocfs_super * osb, ocfs_inode * oin, __u64 lock_id, __u32 flags, bool new_file, struct inode *inode);
+int ocfs_create_update_lock (ocfs_super * osb, __u64 lock_id, __u32 flags, bool new_file, struct inode *inode, ocfs_journal_handle *handle);
int ocfs_acquire_lock (ocfs_super * osb, __u64 lock_id, __u32 lock_type,
__u32 flags, ocfs_lock_res ** lr, struct buffer_head **bh, struct inode *inode);
int ocfs_release_lock (ocfs_super * osb, __u64 lock_id, __u32 lock_type, __u32 flags, ocfs_lock_res * lockres, struct buffer_head *bh, struct inode *inode);
int ocfs_init_dlm (void);
void ocfs_process_one_vote_reply(ocfs_super *osb, ocfs_vote_reply_ctxt *ctxt, __u32 node_num);
int ocfs_break_cache_lock_zap_buffers(ocfs_super * osb, struct inode * inode);
-int ocfs_send_readonly_drop_message(ocfs_super *osb, ocfs_lock_res *lockres, __u64 vote_map);
+int ocfs_send_readonly_drop_message(ocfs_super *osb, ocfs_lock_res *lockres, __u64 vote_map, struct inode *inode);
int ocfs_extend_system_file (ocfs_super * osb, __u32 FileId, __u64 FileSize, struct buffer_head *fe_bh, ocfs_journal_handle *handle, bool zero);
void ocfs_extent_map_init (ocfs_extent_map * map);
void ocfs_extent_map_destroy (ocfs_extent_map * map);
-void ocfs_delete_all_extent_maps (ocfs_inode * oin);
+void ocfs_delete_all_extent_maps (ocfs_super * osb, ocfs_inode * oin);
void ocfs_remove_extent_map_entry (ocfs_super * osb, ocfs_extent_map * Map, __s64 Vbo, __u32 ByteCount);
bool ocfs_get_next_extent_map_entry (ocfs_super * osb, ocfs_extent_map * Map, __u32 RunIndex, __s64 * Vbo, __s64 * Lbo, __u32 * SectorCount);
bool ocfs_lookup_extent_map_entry (ocfs_super * osb, ocfs_extent_map * Map, __s64 Vbo, __s64 * Lbo, __u64 * SectorCount, __u32 * Index);
@@ -76,7 +76,7 @@
int ocfs_sync_file (struct file *file, struct dentry *dentry, int datasync);
ssize_t ocfs_file_write (struct file *filp, const char *buf, size_t count, loff_t * ppos);
ssize_t ocfs_file_read (struct file *filp, char *buf, size_t count, loff_t * ppos);
-int ocfs_extend_file (ocfs_super * osb, __u64 parent_off, ocfs_inode * oin, __u64 file_size, __u64 file_off, ocfs_journal_handle *passed_handle, struct inode *inode, struct iattr *attr);
+int ocfs_extend_file (ocfs_super * osb, __u64 file_size, __u64 file_off, ocfs_journal_handle *passed_handle, struct inode *inode, struct iattr *attr);
int ocfs_setattr (struct dentry *dentry, struct iattr *attr);
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
int ocfs_getattr (struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat);
@@ -85,6 +85,7 @@
#endif
int ocfs_find_inode (struct inode *inode, unsigned long ino, void *opaque);
+int ocfs_inode_init_private(struct inode *inode);
void ocfs_populate_inode (struct inode *inode, ocfs_file_entry *fe, umode_t mode, void *genptr, bool create_ino);
void ocfs_read_locked_inode (struct inode *inode, ocfs_find_inode_args *args);
void ocfs_read_inode2 (struct inode *inode, void *opaque);
@@ -172,15 +173,12 @@
void ocfs_linux_dbg_free (const void *Buffer);
-int ocfs_verify_update_oin (ocfs_super * osb, ocfs_inode * oin, int *needs_trunc);
-int ocfs_create_oin_from_entry (ocfs_super * osb, struct buffer_head * fe_bh, ocfs_inode ** new_oin, __u64 parent_dir_off, struct inode *inode);
-int ocfs_initialize_oin (ocfs_inode * oin, ocfs_super * osb, __u32 flags, __u64 file_off, __u64 lock_id, bool new_file, struct inode *inode);
-int ocfs_create_new_oin (ocfs_inode ** Returnedoin, __u64 alloc_size, ocfs_super * osb);
+int ocfs_verify_update_inode (ocfs_super * osb, struct inode * inode, int *needs_trunc);
+int ocfs_inode_fill_ext_map(ocfs_super * osb, struct buffer_head * fe_bh, struct inode *inode);
+int ocfs_inode_open(ocfs_super *osb, struct buffer_head *fe_bh,
+ ocfs_journal_handle *handle, struct inode *inode);
int ocfs_create_root_oin (ocfs_super * osb, struct inode *root);
-void ocfs_release_oin (ocfs_inode * oin, bool FreeMemory);
-void ocfs_release_cached_oin (ocfs_super * osb, ocfs_inode * oin);
-
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);
int ocfs_check_volume (ocfs_super * osb);
@@ -205,7 +203,7 @@
int ocfs_recv_udp_msg (ocfs_recv_ctxt * recv_ctxt);
int ocfs_send_dismount_msg (ocfs_super * osb, __u64 vote_map);
int ocfs_send_vote_reply (ocfs_super * osb, ocfs_dlm_msg * dlm_msg, __u32 vote_status, bool inode_open);
-int ocfs_drop_readonly_cache_lock(ocfs_super *osb, ocfs_lock_res *lockres);
+int ocfs_drop_readonly_cache_lock(ocfs_super *osb, ocfs_lock_res *lockres, struct inode *inode);
void ocfs_initialize_bitmap (ocfs_alloc_bm * bitmap, __u32 validbits, __u32 allocbits);
@@ -308,7 +306,8 @@
__u64 oldoff,
__u64 newoff,
__u64 new_fe_off);
-struct inode *ocfs_get_inode_from_offset(ocfs_super *osb, __u64 offset,
+struct inode *ocfs_get_inode_from_offset(ocfs_super *osb,
+ __u64 voteoff, __u64 feoff,
struct buffer_head *fe_bh);
struct inode *ocfs_inode_hash_lookup(ocfs_super *osb,
__u64 voteoff,
Modified: trunk/src/inode.c
===================================================================
--- trunk/src/inode.c 2004-04-16 21:49:58 UTC (rev 846)
+++ trunk/src/inode.c 2004-04-16 22:38:55 UTC (rev 847)
@@ -28,6 +28,7 @@
#define OCFS_DEBUG_CONTEXT OCFS_DEBUG_CONTEXT_INODE
+extern struct semaphore recovery_list_sem;
static int ocfs_readpage (struct file *file, struct page *page);
static int ocfs_prepare_write (struct file *file, struct page *page, unsigned from, unsigned to);
@@ -133,8 +134,6 @@
#if LINUX_VERSION_CODE < LinuxVersionCode(2,5,0)
-#define REPOPULATE_INODE 1
-
/*
* ocfs_find_inode()
*
@@ -143,81 +142,26 @@
int ocfs_find_inode (struct inode *inode, unsigned long ino, void *opaque)
{
ocfs_find_inode_args *args = NULL;
- ocfs_inode *oin;
int ret = 0;
- __u64 fileOff;
- mode_t mode;
ocfs_file_entry *fe = NULL;
LOG_ENTRY_ARGS ("(0x%08x, %u, 0x%08x)\n", inode, ino, opaque);
-
+
+ /* We have unique inode numbers so these are just sanity
+ * checks at this point. */
if (opaque == NULL || inode == NULL)
goto bail;
+
args = (ocfs_find_inode_args *) opaque;
- if (ino != inode->i_ino) {
+ if (ino != inode->i_ino)
goto bail;
- }
- if (!ocfs_linux_get_inode_offset (inode, &fileOff, NULL)) {
- LOG_TRACE_STR ("error getting inode offset");
+ if (GET_INODE_FEOFF(inode) != args->offset) {
+ LOG_ERROR_STATUS(-EINVAL);
goto bail;
}
- fe = (ocfs_file_entry *) OCFS_BH_GET_DATA_READ(args->fe_bh); /* read */
- if (S_ISDIR (inode->i_mode)) {
- LOG_TRACE_STR ("find_inode -> S_ISDIR");
- if (fe->extents[0].disk_off != fileOff) {
- LOG_TRACE_ARGS
- ("DIR : inode number same but full offset does not match: %u.%u != %u.%u\n",
- fe->extents[0].disk_off, fileOff);
- goto bail;
- }
- } else if (args->offset != fileOff) {
- LOG_TRACE_ARGS
- ("FILE : inode number same but full offset does not match: %u.%u != %u.%u\n",
- args->offset, fileOff);
- goto bail;
- }
-
-#ifdef REPOPULATE_INODE
- /* not sure if this is appropriate, but we have the most
- * current file entry so why not use it? */
- mode = fe->prot_bits;
-
- switch (fe->attribs) {
- case OCFS_ATTRIB_DIRECTORY:
- mode |= S_IFDIR;
- break;
- case OCFS_ATTRIB_CHAR:
- mode |= S_IFCHR;
- inode->i_rdev = MKDEV (fe->dev_major, fe->dev_minor);
- break;
- case OCFS_ATTRIB_BLOCK:
- mode |= S_IFBLK;
- inode->i_rdev = MKDEV (fe->dev_major, fe->dev_minor);
- break;
- case OCFS_ATTRIB_FIFO:
- mode |= S_IFIFO;
- break;
- case OCFS_ATTRIB_SYMLINK:
- mode |= S_IFLNK;
- break;
- case OCFS_ATTRIB_SOCKET:
- mode |= S_IFSOCK;
- break;
- case OCFS_ATTRIB_REG:
- default:
- mode |= S_IFREG;
- break;
- }
- oin = NULL; /* set it back to our current OIN if we have one */
- if (inode_data_is_oin (inode))
- oin = GET_INODE_OIN(inode);
-
- ocfs_populate_inode (inode, fe, mode, oin, false);
-#endif /* REPOPULATE_INODE */
-
ret = 1;
bail:
if (fe)
@@ -227,7 +171,50 @@
} /* ocfs_find_inode */
#endif /* LINUX_VERSION_CODE < LinuxVersionCode(2,5,0) */
+/*
+ * ocfs_inode_init_private()
+ *
+ */
+int ocfs_inode_init_private(struct inode *inode)
+{
+ ocfs_inode_private *i = NULL;
+ struct _ocfs_inode *oin;
+ if (!inode)
+ BUG();
+
+ inode->u.generic_ip = kmem_cache_alloc(OcfsGlobalCtxt.inode_cache,
+ GFP_NOFS);
+
+ if (!inode->u.generic_ip)
+ return -ENOMEM;
+
+ i = (ocfs_inode_private *) inode->u.generic_ip;
+ oin = &i->oin;
+
+ memset(i, 0, sizeof(ocfs_inode_private));
+
+ i->flags = 0;
+ atomic_set(&i->i_clean_buffer_seq, 0);
+
+ /* Init OIN (or old OIN) stuff. */
+// oin->obj_id.type = OCFS_TYPE_OIN;
+// oin->obj_id.size = sizeof (ocfs_inode);
+ ocfs_init_sem (&(oin->main_res));
+ init_MUTEX(&(oin->extend_sem));
+ OCFS_SET_FLAG (oin->oin_flags, OCFS_INITIALIZED_MAIN_RESOURCE);
+ i->open_hndl_cnt = 0;
+ ocfs_extent_map_init (&oin->map);
+ INIT_LIST_HEAD(&i->recovery_list);
+
+ /* These should be set in read_inode2. */
+ oin->alloc_size = 0ULL;
+ i->voteoff = 0ULL;
+ i->feoff = 0ULL;
+
+ return 0;
+} /* ocfs_inode_init_private */
+
/*
* ocfs_populate_inode()
*
@@ -238,6 +225,7 @@
ocfs_super *osb;
__u64 offset, fe_off;
unsigned long uniq_ino;
+ ocfs_inode *oin = NULL;
LOG_ENTRY_ARGS ("(0x%08x, %u, size:%u)\n", inode, mode, fe->file_size);
@@ -251,12 +239,10 @@
BUG();
}
- if (!inode->u.generic_ip)
- inode->u.generic_ip = kmem_cache_alloc(OcfsGlobalCtxt.inode_cache,
- GFP_NOFS);
- if (!inode->u.generic_ip) {
+ if (!inode->u.generic_ip && ocfs_inode_init_private(inode)) {
/* How can we recover gracefully? */
- LOG_ERROR_STR("unable to allocate private data for inode");
+ LOG_ERROR_STR("unable to allocate private data for "
+ "inode");
goto bail;
}
@@ -274,14 +260,17 @@
OCFS_SET_INODE_TIME(inode, i_atime, fe->modify_time);
OCFS_SET_INODE_TIME(inode, i_mtime, fe->modify_time);
OCFS_SET_INODE_TIME(inode, i_ctime, fe->create_time);
- if (genptr)
- SET_INODE_OIN(inode, genptr);
- else
- CLEAR_INODE_OIN(inode);
SET_INODE_VOTEOFF(inode, offset);
SET_INODE_FEOFF(inode, fe_off);
+ oin = GET_INODE_OIN(inode);
+ oin->alloc_size = fe->alloc_size;
+ OCFS_I(inode)->inode = inode;
+ OCFS_I(inode)->chng_seq_num = DISK_LOCK_SEQNUM (fe);
+ if (fe->attribs & OCFS_ATTRIB_DIRECTORY)
+ oin->oin_flags |= OCFS_OIN_DIRECTORY;
+
if (create_ino) {
uniq_ino = ocfs_inode_hash_insert(osb, offset, fe_off);
inode->i_ino = uniq_ino;
@@ -335,6 +324,8 @@
umode_t mode;
__u64 voteoff;
ocfs_file_entry *fe = NULL;
+ ocfs_inode *oin = NULL;
+ struct buffer_head *bh = NULL;
LOG_ENTRY_ARGS ("(%p, %p)\n", inode, args);
@@ -347,8 +338,7 @@
LOG_TRACE_ARGS("osb = %x\n", osb);
if (inode->i_ino == OCFS_ROOT_INODE_NUMBER) {
LOG_TRACE_ARGS("Populating root inode (i_ino = %lu)\n", inode->i_ino);
- inode->u.generic_ip = kmem_cache_alloc(OcfsGlobalCtxt.inode_cache, GFP_NOFS);
- if (!inode->u.generic_ip) {
+ if (!inode->u.generic_ip && ocfs_inode_init_private(inode)) {
/* How can we recover gracefully? */
LOG_ERROR_STR("unable to allocate private data for inode");
goto bail;
@@ -367,20 +357,41 @@
inode->i_fop = &ocfs_dops;
inode->i_uid = osb->vol_layout.uid;
inode->i_gid = osb->vol_layout.gid;
- SET_INODE_OIN (inode, osb->oin_root_dir);
SET_INODE_VOTEOFF(inode, osb->vol_layout.root_start_off);
SET_INODE_FEOFF(inode, 0);
+
+ oin = GET_INODE_OIN(inode);
+ oin->alloc_size = 0ULL;
+ OCFS_I(inode)->inode = inode;
+ OCFS_I(inode)->chng_seq_num = 0ULL;
+ oin->oin_flags |= OCFS_OIN_DIRECTORY | OCFS_OIN_ROOT_DIRECTORY;
+
ocfs_inode_hash_bind(osb, GET_INODE_VOTEOFF(inode), inode);
goto bail;
}
LOG_TRACE_ARGS("Populating non-root inode (i_ino = %lu)\n", inode->i_ino);
- if (args)
- fe = (ocfs_file_entry *) OCFS_BH_GET_DATA_READ(args->fe_bh);
- if (!fe) {
+
+ if (!args) {
make_bad_inode (inode);
goto bail;
}
+
+ /* Uhoh, they didn't give us a buffer. Read the FE off
+ * disk. This is safe because the kernel only does one
+ * read_inode2 for a new inode, and if it doesn't exist yet
+ * then nobody can be working on it! */
+ if (!args->fe_bh) {
+ status = ocfs_read_bh(osb, args->offset, &bh, 0, NULL);
+ if (status < 0) {
+ LOG_ERROR_STATUS(status);
+ make_bad_inode (inode);
+ goto bail;
+ }
+ } else
+ bh = args->fe_bh;
+
+ fe = (ocfs_file_entry *) OCFS_BH_GET_DATA_READ(bh);
newoin = NULL;
@@ -412,14 +423,18 @@
break;
}
ocfs_populate_inode (inode, fe, mode, newoin, false);
+
voteoff = S_ISDIR (mode) ? fe->extents[0].disk_off : fe->this_sector;
if (!args->skip_bind)
ocfs_inode_hash_bind(osb, voteoff, inode);
bail:
if (fe)
- OCFS_BH_PUT_DATA(args->fe_bh);
+ OCFS_BH_PUT_DATA(bh);
+ if (args && !args->fe_bh && bh)
+ brelse(bh);
+
LOG_EXIT ();
return;
} /* ocfs_read_locked_inode */
@@ -437,10 +452,12 @@
struct super_block *sb;
ocfs_find_inode_args *args = NULL;
ocfs_super *osb;
- ocfs_inode *newoin;
+ ocfs_inode *oin = NULL;
umode_t mode;
ocfs_file_entry *fe = NULL;
__u64 voteoff;
+ struct buffer_head *bh = NULL;
+ int status;
LOG_ENTRY_ARGS ("(0x%08x, 0x%08x)\n", inode, opaque);
@@ -451,8 +468,7 @@
sb = inode->i_sb;
osb = (ocfs_super *) OCFS_GENERIC_SB_P(sb);
if (inode->i_ino == OCFS_ROOT_INODE_NUMBER) {
- inode->u.generic_ip = kmem_cache_alloc(OcfsGlobalCtxt.inode_cache, GFP_NOFS);
- if (!inode->u.generic_ip) {
+ if (!inode->u.generic_ip && ocfs_inode_init_private(inode)) {
/* How can we recover gracefully? */
LOG_ERROR_STR("unable to allocate private data for inode");
goto bail;
@@ -474,9 +490,15 @@
inode->i_fop = &ocfs_dops;
inode->i_uid = osb->vol_layout.uid;
inode->i_gid = osb->vol_layout.gid;
- SET_INODE_OIN (inode, osb->oin_root_dir);
SET_INODE_VOTEOFF(inode, osb->vol_layout.root_start_off);
SET_INODE_FEOFF(inode, 0);
+
+ oin = GET_INODE_OIN(inode);
+ oin->alloc_size = 0ULL;
+ OCFS_I(inode)->inode = inode;
+ OCFS_I(inode)->chng_seq_num = 0ULL;
+ oin->oin_flags |= OCFS_OIN_DIRECTORY | OCFS_OIN_ROOT_DIRECTORY;
+
ocfs_inode_hash_bind(osb, GET_INODE_VOTEOFF(inode), inode);
goto bail;
}
@@ -487,12 +509,23 @@
}
args = (ocfs_find_inode_args *) opaque;
- newoin = NULL;
- if (args->fe_bh == NULL)
- BUG();
- fe = (ocfs_file_entry *) OCFS_BH_GET_DATA_READ(args->fe_bh); /* read */
+ /* Uhoh, they didn't give us a buffer. Read the FE off
+ * disk. This is safe because the kernel only does one
+ * read_inode2 for a new inode, and if it doesn't exist yet
+ * then nobody can be working on it! */
+ if (!args->fe_bh) {
+ status = ocfs_read_bh(osb, args->offset, &bh, 0, NULL);
+ if (status < 0) {
+ LOG_ERROR_STATUS(status);
+ make_bad_inode (inode);
+ goto bail;
+ }
+ } else
+ bh = args->fe_bh;
+ fe = (ocfs_file_entry *) OCFS_BH_GET_DATA_READ(bh); /* read */
+
mode = fe->prot_bits;
switch (fe->attribs) {
@@ -521,7 +554,7 @@
mode |= S_IFREG;
break;
}
- ocfs_populate_inode (inode, fe, mode, newoin, false);
+ ocfs_populate_inode (inode, fe, mode, NULL, false);
voteoff = S_ISDIR (mode) ? fe->extents[0].disk_off : fe->this_sector;
if (!args->skip_bind)
@@ -529,7 +562,11 @@
bail:
if (fe)
- OCFS_BH_PUT_DATA(args->fe_bh);
+ OCFS_BH_PUT_DATA(bh);
+
+ if (args && !args->fe_bh && bh)
+ brelse(bh);
+
LOG_EXIT ();
return;
} /* ocfs_read_inode2 */
@@ -576,27 +613,11 @@
goto bail;
args = (ocfs_find_inode_args *) opaque;
- if (!ocfs_linux_get_inode_offset (inode, &fileOff, NULL)) {
- LOG_TRACE_STR ("could not get inode offset");
+ if (GET_INODE_FEOFF(inode) != args->offset) {
+ LOG_ERROR_STATUS(-EINVAL);
goto bail;
}
- if (S_ISDIR (inode->i_mode)) {
- LOG_TRACE_STR ("find_actor -> S_ISDIR\n");
- fe = OCFS_BH_GET_DATA_READ(args->fe_bh); /* read */
- if (fe->extents[0].disk_off != fileOff) {
- LOG_TRACE_ARGS
- ("DIR : inode number same but full offset does not match: %u.%u != %u.%u\n",
- fe->extents[0].disk_off, fileOff);
- goto bail;
- }
- } else if (args->offset != fileOff) {
- LOG_TRACE_ARGS
- ("FILE : inode number same but full offset does not match: %u.%u != %u.%u\n",
- args->offset, fileOff);
- goto bail;
- }
-
ret = 1;
bail:
if (fe)
@@ -695,17 +716,6 @@
if (inode_data_is_oin(inode))
oin = GET_INODE_OIN(inode);
- /* can we destroy the oin? Uhm, shouldn't this be a test
- * against a count of '3'? */
- if (oin && (atomic_read (&inode->i_count) == 2) &&
- (inode->i_ino != OCFS_ROOT_INODE_NUMBER)) {
- ocfs_extent_map_destroy (&oin->map);
- ocfs_extent_map_init (&oin->map);
- ocfs_release_cached_oin (osb, oin);
- ocfs_release_oin (oin, true);
- oin = NULL;
- }
-
/* Ok, if after this iput we would be the last holder of the
* root inode, then we know we're unmounting so just dump it
* now. */
@@ -752,6 +762,12 @@
if (!inode)
goto bail;
+ LOG_TRACE_ARGS("Clearing inode %u (voteoff: %u.%u, "
+ "feoff: %u.%u)\n", inode->i_ino,
+ HILO(GET_INODE_VOTEOFF(inode)),
+ HILO(GET_INODE_FEOFF(inode)));
+
+ /* we should not really be using osb in this context. */
osb = (ocfs_super *) OCFS_GENERIC_SB_P(inode->i_sb);
if (!ocfs_linux_get_inode_offset(inode, &offset, NULL)) {
@@ -762,42 +778,63 @@
/* offset == 0 if this inode is newly created and hasn't been
* filled in yet. */
- if (offset == 0)
+ if (offset == 0) {
+ LOG_ERROR_STR("uhm, feoff = 0!");
goto bail;
+ }
- if (inode_data_is_oin (inode)) {
- LOG_TRACE_STR ("inode with oin : clear inode");
+ oin = GET_INODE_OIN(inode);
- oin = GET_INODE_OIN(inode);
- if (oin != osb->oin_root_dir)
- BUG();
-
+ if (inode->i_ino == OCFS_ROOT_INODE_NUMBER) {
LOG_TRACE_STR("this is the root inode, doing cleanup now!");
ocfs_sync_blockdev(inode->i_sb);
LOG_TRACE_STR ("syncing past root inode");
LOG_TRACE_STR ("calling dismount");
ocfs_dismount_volume (inode->i_sb);
+ goto bail;
+ }
+
+ OCFS_SET_FLAG (oin->oin_flags, OCFS_OIN_IN_TEARDOWN);
+
+ lockres = oin->lock_res;
+ if (lockres) {
+ ocfs_acquire_lockres (lockres);
+ ocfs_release_lockres (lockres);
+ oin->lock_res = NULL;
+ ocfs_put_lockres (lockres);
+ lockres = NULL;
+ }
+
+ ocfs_extent_map_destroy (&oin->map);
+ ocfs_extent_map_init (&oin->map);
+
+ down(&recovery_list_sem);
+ list_del(&OCFS_I(inode)->recovery_list);
+ up(&recovery_list_sem);
+
+ ocfs_del_sem (&(oin->main_res));
+ OCFS_CLEAR_FLAG (oin->oin_flags, OCFS_INITIALIZED_MAIN_RESOURCE);
+
+ /* clean out the oin ... why?! */
+ memset(oin, 0, sizeof(ocfs_inode));
+
+ if (!ocfs_lookup_sector_node (osb, offset, &lockres)) {
+ if (lockres) {
+ ocfs_remove_sector_node (osb, lockres);
+ ocfs_put_lockres(lockres);
+ } else
+ LOG_TRACE_STR ("lockres in hash is null");
} else {
- if (!ocfs_lookup_sector_node (osb, offset, &lockres)) {
- if (lockres) {
- if (lockres->oin) {
- ocfs_put_lockres (lockres->oin->lock_res);
- lockres->oin->lock_res = NULL;
- lockres->oin = NULL;
- }
- ocfs_remove_sector_node (osb, lockres);
- ocfs_put_lockres(lockres);
- } else
- LOG_TRACE_STR ("lockres in hash is null");
- } else {
- LOG_TRACE_STR("hashtable has already been destroyed.");
- }
+ LOG_TRACE_STR("hashtable has already been destroyed.");
}
- if (inode->u.generic_ip)
+bail:
+ if (inode && inode->u.generic_ip) {
kmem_cache_free(OcfsGlobalCtxt.inode_cache,
inode->u.generic_ip);
-bail:
+ inode->u.generic_ip = NULL;
+ }
+
LOG_EXIT ();
return;
} /* ocfs_clear_inode */
@@ -895,7 +932,9 @@
if (unlock)
ocfs_up_sem (&(oin->main_res));
- status = ocfs_extend_file (osb, oin->parent_dirnode_off, oin, newsize, GET_INODE_FEOFF(inode), NULL, inode, NULL);
+ status = ocfs_extend_file (osb, newsize,
+ GET_INODE_FEOFF(inode), NULL,
+ inode, NULL);
if (unlock)
ocfs_down_sem (&(oin->main_res), true);
@@ -1011,10 +1050,10 @@
goto bail;
}
- osb = (ocfs_super *) oin->osb;
+ osb = (ocfs_super *) OCFS_GENERIC_SB_P(inode->i_sb);
vbo = (__s64) iblock << inode->i_sb->s_blocksize_bits;
- if (!oin->journal_inode && vbo >= oin->alloc_size) {
+ if (!INODE_JOURNAL(inode) && vbo >= oin->alloc_size) {
LOG_TRACE_STR("Extending allocation");
err = ocfs_extend_allocation(osb, oin, vbo+512, false, inode);
if (err < 0) {
@@ -1030,8 +1069,7 @@
len = 1;
down(&oin->extend_sem);
- err = ocfs_lookup_file_allocation(osb, oin, vbo, &lbo, len, NULL,
- inode);
+ err = ocfs_lookup_file_allocation(osb, vbo, &lbo, len, NULL, inode);
up(&oin->extend_sem);
if (err < 0) {
LOG_ERROR_ARGS ("vbo=%u.%u lbo=%u.%u len=%u", HILO(vbo),
@@ -1088,7 +1126,7 @@
oin = GET_INODE_OIN(inode);
- if (!(oin->journal_inode)) {
+ if (!INODE_JOURNAL(inode)) {
LOG_ERROR_STR("bmap is only for journal inodes!");
err = -EINVAL;
LOG_ERROR_STATUS(err);
@@ -1111,8 +1149,7 @@
vbo = (__s64) block << inode->i_sb->s_blocksize_bits;
len = 1;
- err = ocfs_lookup_file_allocation(osb, oin, vbo, &lbo, len,
- NULL, inode);
+ err = ocfs_lookup_file_allocation(osb, vbo, &lbo, len, NULL, inode);
if (err < 0) {
LOG_ERROR_ARGS ("vbo=%u.%u lbo=%u.%u len=%u", HILO(vbo),
HILO(lbo), len);
@@ -1149,11 +1186,11 @@
}
oin = GET_INODE_OIN(inode);
- osb = (ocfs_super *) oin->osb;
+ osb = (ocfs_super *) OCFS_GENERIC_SB_P(inode->i_sb);
vbo = (__s64) iblock << inode->i_sb->s_blocksize_bits;
len = 1;
- err = ocfs_lookup_file_allocation (osb, oin, vbo, &lbo, len, NULL, inode);
+ err = ocfs_lookup_file_allocation (osb, vbo, &lbo, len, NULL, inode);
if (err < 0) {
LOG_ERROR_STATUS (err);
err = -1;
@@ -1270,13 +1307,13 @@
osb = (ocfs_super *) inode->i_sb->s_fs_info;
blocksize_bits = inode->i_sb->s_blocksize_bits;
/* make sure we're up to date... */
- if (OIN_NEEDS_VERIFICATION (oin)) {
+ if (OCFS_I(inode)->needs_verification) {
LOG_TRACE_STR ("ocfs_direct_IO_get_blocks: verify oin.");
- status = ocfs_verify_update_oin (osb, oin, &needs_trunc);
+ status = ocfs_verify_update_inode (osb, inode, &needs_trunc);
if (needs_trunc)
ocfs_truncate_inode_pages(inode, 0);
if (status < 0) {
- LOG_TRACE_STR ("ocfs_verify_update_oin failed");
+ LOG_TRACE_STR ("ocfs_verify_update_inode failed");
ret = -EIO;
goto bail;
}
@@ -1305,7 +1342,8 @@
/* This figure out the size of the next contiguous block, and
* our logical offset */
/* TODO: Try our damndest to give sizes in multiples of PAGE_SIZE */
- status = ocfs_lookup_file_allocation(osb, oin, vbo, &lbo, max_blocks, &new_size, inode);
+ status = ocfs_lookup_file_allocation(osb, vbo, &lbo, max_blocks,
+ &new_size, inode);
/* Do whatever we need to the buffer_head */
if (set_new) {
Modified: trunk/src/journal.c
===================================================================
--- trunk/src/journal.c 2004-04-16 21:49:58 UTC (rev 846)
+++ trunk/src/journal.c 2004-04-16 22:38:55 UTC (rev 847)
@@ -237,7 +237,8 @@
tmpstat = ocfs_release_lock(osb, lock->id, lock->type,
lock->flags, lock->res,
- (abort ? NULL : lock->bh), NULL);
+ (abort ? NULL : lock->bh),
+ lock->inode);
if (tmpstat < 0) {
LOG_ERROR_ARGS("Could not release lock %u.%u\n",
HILO(lock->id));
@@ -247,7 +248,8 @@
ocfs_put_lockres(lock->res);
if (lock->bh != NULL)
brelse(lock->bh);
-
+ if (lock->inode)
+ iput(lock->inode);
list_del(&(lock->lock_list));
handle->num_locks--;
ocfs_free(lock);
@@ -769,7 +771,7 @@
* other transactions anyway... */
void ocfs_journal_add_lock(ocfs_journal_handle *handle, __u64 id, __u32 type,
__u32 flags, struct _ocfs_lock_res *res,
- struct buffer_head *bh)
+ struct buffer_head *bh, struct inode *inode)
{
ocfs_journal_lock *lock;
@@ -789,9 +791,13 @@
lock->flags = flags;
lock->res = res;
lock->bh = bh;
+ lock->inode = inode;
if (bh)
get_bh(bh);
+
+ if (inode)
+ atomic_inc(&inode->i_count);
spin_lock(&handle->list_lock);
list_add_tail(&(lock->lock_list), &(handle->locks));
@@ -858,7 +864,6 @@
int status = -1;
struct inode *inode = NULL; /* the journal inode */
journal_t * k_journal = NULL;
- ocfs_find_inode_args args;
ocfs_file_entry *fe = NULL;
ocfs_lock_res *lock_res = NULL;
__u32 cleanup_file_id = 0;
@@ -878,14 +883,29 @@
INIT_LIST_HEAD(&(osb->journal.commited));
init_MUTEX(&(osb->journal.commit_sem));
- /* get the cleanup file fe and lock */
cleanup_file_id = (__u32) (JOURNAL_FILE_BASE_ID + osb->node_num);
lock_id = ((JOURNAL_FILE_BASE_ID + osb->node_num) * osb->sect_size) +
osb->vol_layout.root_int_off;
+ /* Ok, look up the inode for our journal */
+ inode = ocfs_get_inode_from_offset(osb, lock_id, lock_id, NULL);
+ if (inode == NULL) {
+ LOG_ERROR_STR("access error");
+ status = -EACCES;
+ goto done;
+ }
+ if (is_bad_inode (inode)) {
+ LOG_ERROR_STR("access error (bad inode)");
+ iput (inode);
+ inode = NULL;
+ status = -EACCES;
+ goto done;
+ }
+ SET_INODE_JOURNAL(inode);
+
/* TODO: Use another type of lock. */
status = ocfs_acquire_lock (osb, lock_id, OCFS_DLM_EXCLUSIVE_LOCK,
- FLAG_FILE_CREATE, &lock_res, &bh, NULL);
+ FLAG_FILE_CREATE, &lock_res, &bh, inode);
if (status < 0) {
if (status != -EINTR)
LOG_ERROR_STR("Could not get lock on journal!");
@@ -914,35 +934,22 @@
/* gonna need this later */
alloc_size = fe->alloc_size;
-
- /* Ok, look up the inode for our journal */
- args.offset = fe->this_sector;
- args.fe_bh = bh;
- args.skip_bind = 0;
LOG_TRACE_ARGS("fe->this_sector = %u.%u\n", HI(fe->this_sector),
LO(fe->this_sector));
+ inode->i_size = fe->file_size;
OCFS_BH_PUT_DATA(bh);
fe = NULL;
- inode = ocfs_get_inode_from_offset(osb, args.offset, bh);
- if (inode == NULL) {
- LOG_ERROR_STR("access error");
- status = -EACCES;
+
+ /* we just changed this but extend_system_file doesn't know
+ * about oins, so we update alloc_size ourselves. */
+ oin = GET_INODE_OIN(inode);
+ oin->alloc_size = alloc_size;
+ status = ocfs_create_update_lock(osb, lock_id, 0, false, inode, NULL);
+ if (status < 0) {
+ LOG_ERROR_STATUS(status);
goto done;
}
- if (is_bad_inode (inode)) {
- LOG_ERROR_STR("access error (bad inode)");
- iput (inode);
- inode = NULL;
- status = -EACCES;
- goto done;
- }
- LOG_TRACE_ARGS("inode->i_size = %u\n", inode->i_size);
-
- status = ocfs_create_new_oin(&oin, alloc_size, osb);
- status = ocfs_initialize_oin(oin, osb, 0, lock_id, lock_id, false, NULL);
- oin->journal_inode = true;
- oin->open_hndl_cnt++;
- SET_INODE_OIN(inode, oin);
+ OCFS_I(inode)->open_hndl_cnt++;
LOG_TRACE_ARGS("oin->alloc_size = %u.%u\n", HI(oin->alloc_size),
LO(oin->alloc_size));
@@ -979,8 +986,8 @@
OCFS_BH_PUT_DATA(bh);
brelse(bh);
}
- if (oin)
- oin->open_hndl_cnt--;
+ if (inode)
+ OCFS_I(inode)->open_hndl_cnt--;
}
LOG_EXIT_STATUS(status);
return(status);
@@ -1049,9 +1056,7 @@
/* release the oin here. Isn't this racy? */
if (inode_data_is_oin(inode)) {
oin = GET_INODE_OIN(inode);
- CLEAR_INODE_OIN(inode);
- oin->open_hndl_cnt--;
- ocfs_release_oin(oin, true);
+ OCFS_I(inode)->open_hndl_cnt--;
}
/* unlock our journal */
@@ -1333,7 +1338,7 @@
LOG_TRACE_ARGS("Force reading %u blocks\n", totalblks);
- status = ocfs_lookup_file_allocation(osb, oin, vbo, &lbo, size, NULL,
+ status = ocfs_lookup_file_allocation(osb, vbo, &lbo, size, NULL,
inode);
if (status < 0) {
LOG_ERROR_STATUS(status);
@@ -1467,7 +1472,6 @@
ocfs_inode *oin = NULL;
struct inode *inode = NULL;
journal_t *k_journal = NULL;
- ocfs_find_inode_args args;
struct buffer_head *bh = NULL;
ocfs_journal * journal = NULL;
bool recovery_lock = false;
@@ -1499,6 +1503,22 @@
lock_id = ((JOURNAL_FILE_BASE_ID + node_num) * osb->sect_size)
+ osb->vol_layout.root_int_off;
+ /* Ok, look up the inode for our journal */
+ inode = ocfs_get_inode_from_offset(osb, lock_id, lock_id, NULL);
+ if (inode == NULL) {
+ LOG_ERROR_STR("access error");
+ status = -EACCES;
+ goto done;
+ }
+ if (is_bad_inode (inode)) {
+ LOG_ERROR_STR("access error (bad inode)");
+ iput (inode);
+ inode = NULL;
+ status = -EACCES;
+ goto done;
+ }
+ SET_INODE_JOURNAL(inode);
+
/* Should not ever be called to recover ourselves -- in that
* case we should've called ocfs_journal_load instead. */
if (osb->node_num == node_num)
@@ -1507,7 +1527,7 @@
status = ocfs_acquire_lock (osb, lock_id,
OCFS_DLM_EXCLUSIVE_LOCK,
FLAG_FILE_CREATE|FLAG_FILE_RECOVERY,
- &lock_res, &bh, NULL);
+ &lock_res, &bh, inode);
if (status < 0) {
LOG_TRACE_ARGS("status returned from acquire_lock=%d\n",
status);
@@ -1548,40 +1568,19 @@
OCFS_BH_PUT_DATA(config_bh);
fe = (ocfs_file_entry *)OCFS_BH_GET_DATA_READ(bh); /* read */
-
/* gonna need this later */
alloc_size = fe->alloc_size;
-
- /* Ok, look up the inode for our journal */
- args.offset = fe->this_sector;
- args.fe_bh = bh;
- args.skip_bind = 0;
OCFS_BH_PUT_DATA(bh);
+
fe = NULL;
- inode = ocfs_get_inode_from_offset(osb, args.offset, bh);
- if (inode == NULL) {
- LOG_ERROR_STR("access error");
- status = -EACCES;
- goto done;
- }
- if (is_bad_inode (inode)) {
- LOG_ERROR_STR("access error (bad inode)");
- iput (inode);
- inode = NULL;
- status = -EACCES;
- goto done;
- }
- LOG_TRACE_ARGS("inode->i_size = %u\n", inode->i_size);
- status = ocfs_create_new_oin(&oin, alloc_size, osb);
+ oin = GET_INODE_OIN(inode);
+ oin->alloc_size = alloc_size;
+ status = ocfs_create_update_lock(osb, lock_id, 0, false, inode, NULL);
if (status < 0) {
LOG_ERROR_STATUS(status);
goto done;
}
- status = ocfs_initialize_oin(oin, osb, 0, lock_id, lock_id, false,
- NULL);
- oin->journal_inode = true;
- SET_INODE_OIN(inode, oin);
status = ocfs_force_read_journal(osb, inode->i_size, oin, inode);
if (status < 0) {
@@ -1639,14 +1638,7 @@
CLEAR_NODE_IN_RECOVERY(osb, node_num);
ocfs_recover_oin_locks(osb, node_num);
done:
- /* close the journal file */
if (inode)
- CLEAR_INODE_OIN(inode);
-
- if (oin)
- ocfs_release_oin(oin, true);
-
- if (inode)
iput(inode);
if (recovery_lock)
Modified: trunk/src/namei.c
===================================================================
--- trunk/src/namei.c 2004-04-16 21:49:58 UTC (rev 846)
+++ trunk/src/namei.c 2004-04-16 22:38:55 UTC (rev 847)
@@ -196,8 +196,7 @@
goto leave;
}
- inode->u.generic_ip = kmem_cache_alloc(OcfsGlobalCtxt.inode_cache, GFP_NOFS);
- if (!inode->u.generic_ip) {
+ if (ocfs_inode_init_private(inode)) {
LOG_ERROR_STATUS(status = -ENOMEM);
goto leave;
}
@@ -232,7 +231,8 @@
/* Ok, we got the lock -- we'd better add it to our transaction */
ocfs_journal_add_lock(handle, parent_off,
OCFS_DLM_ENABLE_CACHE_LOCK,
- FLAG_FILE_CREATE | FLAG_DIR, lock_res, lock_bh);
+ FLAG_FILE_CREATE | FLAG_DIR, lock_res, lock_bh,
+ dir);
/* do the real work now. */
status = ocfs_mknod_locked(osb, dir, dentry, mode, dev, lock_bh,
@@ -243,24 +243,12 @@
goto leave;
}
- status = ocfs_create_new_oin (&oin, 0ULL, osb);
- if (status < 0) {
- LOG_ERROR_STATUS (status);
- goto leave;
- }
-
fe = (ocfs_file_entry *) OCFS_BH_GET_DATA_READ(new_fe_bh); /* read */
file_off = fe->this_sector;
dirnode_off = fe->extents[0].disk_off;
- oinflags = OCFS_OIN_CACHE_UPDATE | (S_ISDIR (mode) ? OCFS_OIN_DIRECTORY : 0);
+ oinflags = (S_ISDIR (mode) ? OCFS_OIN_DIRECTORY : 0);
- OCFS_BH_PUT_DATA(new_fe_bh);
- fe = NULL;
-
- status = ocfs_initialize_oin (oin, osb, oinflags, file_off,
- S_ISDIR (mode) ? dirnode_off : file_off, true, inode);
-
if (!ocfs_linux_get_inode_offset (dir, &parent_off, &ParentOin)) {
LOG_ERROR_STATUS (status = -ENOENT);
goto leave;
@@ -269,8 +257,24 @@
if (ParentOin)
OCFS_CLEAR_FLAG (ParentOin->oin_flags, OCFS_OIN_IN_USE);
+ ocfs_populate_inode (inode, fe, mode, NULL, true);
+ insert_inode_hash (inode);
+ ocfs_inode_hash_bind(osb, GET_INODE_VOTEOFF(inode), inode);
+
+ handle->new_file_lockid = fe->this_sector;
+ OCFS_BH_PUT_DATA(new_fe_bh);
+ fe = NULL;
+
+ oin = GET_INODE_OIN(inode);
+ status = ocfs_create_update_lock(osb, GET_INODE_VOTEOFF(inode),
+ oinflags, true, inode, handle);
+ if (status < 0)
+ LOG_ERROR_STATUS(status);
+
fe = (ocfs_file_entry *) OCFS_BH_GET_DATA_READ(new_fe_bh); /* read */
+ /* Insert the OFile on the OIN list */
+ OCFS_I(inode)->chng_seq_num = DISK_LOCK_SEQNUM (fe);
if (oin->lock_res != NULL) {
ocfs_lock_res *lockres = oin->lock_res;
ocfs_acquire_lockres(lockres);
@@ -285,28 +289,15 @@
}
ocfs_release_lockres(lockres);
}
-
- /* Insert the OFile on the OIN list */
- oin->chng_seq_num = DISK_LOCK_SEQNUM (fe);
- oin->parent_dirnode_off = parent_off;
-
- LOG_TRACE_ARGS("ocfs_mknod: new_fe_bh: this_sector = %u.%u, "
- "extents[0].disk_off = %u.%u\n",
- HILO(fe->this_sector), HILO(fe->extents[0].disk_off));
-
- if (ocfs_inc_icount(inode) < 0)
- BUG();
- oin->inode = inode;
-
- ocfs_populate_inode (inode, fe, mode, oin, true);
- insert_inode_hash (inode);
- ocfs_inode_hash_bind(osb, GET_INODE_VOTEOFF(inode), inode);
- d_instantiate (dentry, inode);
-
- handle->new_file_lockid = fe->this_sector;
OCFS_BH_PUT_DATA(new_fe_bh);
fe = NULL;
+ LOG_TRACE_ARGS("ocfs2: Created inode %u (voteoff: %u.%u, "
+ "feoff: %u.%u)\n", inode->i_ino,
+ HILO(GET_INODE_VOTEOFF(inode)),
+ HILO(GET_INODE_FEOFF(inode)));
+
+ d_instantiate (dentry, inode);
ocfs_commit_trans(handle);
status = 0;
@@ -588,15 +579,6 @@
__u64 parentOff, fileOff;
bool do_release = false;
struct inode *parentInode = dentry->d_parent->d_inode;
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
- /*
- * On a 2.6 kernel sys_unlink will increment the inode
- * count before calling the filesystem unlink function
- */
- int max_cnt = 3; /* one for this process, inode hash, and sys_unlink */
-#else
- int max_cnt = 2; /* one for this process and one for inode hash */
-#endif
LOG_ENTRY_ARGS ("(0x%08x, 0x%08x, '%*s')\n", dir, dentry,
dentry->d_name.len, dentry->d_name.name);
@@ -614,15 +596,10 @@
status = -EBUSY;
- if (oin && oin->inode)
- max_cnt++;
-
- if (atomic_read (&inode->i_count) > max_cnt || atomic_read (&dentry->d_count) > 2) {
- LOG_TRACE_ARGS ("i_count > %d or d_count > 2\n", max_cnt);
- } else if (!ocfs_empty(dentry)) {
+ if (!ocfs_empty(dentry)) {
LOG_TRACE_STR ("dentry is not empty, cannot delete");
- } else if (oin && oin->open_hndl_cnt > 0) {
- LOG_TRACE_ARGS ("Cannot remove an open file (open_hndl_cnt = %u, fileOff = %u.%u, d_count=%u)\n", oin->open_hndl_cnt, HILO(fileOff), atomic_read(&dentry->d_count));
+ } else if (OCFS_I(inode)->open_hndl_cnt > 0) {
+ LOG_TRACE_ARGS ("Cannot remove an open file (open_hndl_cnt = %u, fileOff = %u.%u, d_count=%u)\n", OCFS_I(inode)->open_hndl_cnt, HILO(fileOff), atomic_read(&dentry->d_count));
} else if (oin && oin->oin_flags & OCFS_OIN_ROOT_DIRECTORY) {
LOG_TRACE_STR ("Cannot delete the root directory");
status = -EPERM;
@@ -637,7 +614,7 @@
if (oin) {
spin_lock(&oin_num_ext_lock);
if (oin->num_extends) {
- LOG_TRACE_ARGS ("Cannot remove a file with = "
+ LOG_ERROR_ARGS ("Cannot remove a file with = "
"%u, pending extends (fileOff "
"= %u.%u)\n", oin->num_extends,
HILO(fileOff));
@@ -669,17 +646,12 @@
}
goto bail;
}
-
- if (oin)
- ocfs_release_cached_oin (osb, oin);
}
if (do_release)
{
- if (oin)
- ocfs_release_oin (oin, true);
- else {
- if (fileOff != -1) {
+ if (!oin) {
+ if (fileOff != -1) {
tmpstat = ocfs_lookup_sector_node (osb, fileOff, &lockres);
if (tmpstat >= 0 && lockres) {
ocfs_remove_sector_node (osb, lockres);
@@ -798,8 +770,9 @@
} else if (handle) {
if (id2_locked)
ocfs_journal_add_lock(handle, id2, type2, flags2,
- *res2, *bh2);
- ocfs_journal_add_lock(handle, id1, type1, flags1, *res1, *bh1);
+ *res2, *bh2, inode2);
+ ocfs_journal_add_lock(handle, id1, type1, flags1, *res1, *bh1,
+ inode1);
}
LOG_EXIT_STATUS(status);
@@ -935,7 +908,6 @@
__u32 newfe_flags = 0;
__u32 newfe_lockid = 0;
int needs_trunc = 0;
- int max_cnt = 2;
LOG_ENTRY_ARGS ("(0x%08x, 0x%08x, 0x%08x, 0x%08x, from='%*s' to='%*s')\n",
old_dir, old_dentry, new_dir, new_dentry,
@@ -966,13 +938,7 @@
BUG();
}
- if (oldOIN && oldOIN->inode)
- max_cnt++;
-
- if (atomic_read (&old_inode->i_count) > max_cnt) {
- status = -EBUSY;
- goto bail;
- } else if (atomic_read (&old_dentry->d_count) > 2) {
+ if (atomic_read (&old_dentry->d_count) > 2) {
shrink_dcache_parent (old_dentry);
if (atomic_read (&old_dentry->d_count) > 2) {
status = -EBUSY;
@@ -988,7 +954,7 @@
}
if (oldOIN) {
- if (oldOIN->open_hndl_cnt != 0) {
+ if (OCFS_I(old_dentry->d_inode)->open_hndl_cnt != 0) {
status = -EBUSY;
goto bail;
}
@@ -1010,7 +976,7 @@
/* OIN exists and it's not marked for deletion! */
ocfs_down_sem (&(newOIN->main_res), true);
OCFS_SET_FLAG (newOIN->oin_flags, OCFS_OIN_IN_USE);
- status = ocfs_verify_update_oin (osb, newOIN, &needs_trunc);
+ status = ocfs_verify_update_inode (osb, new_dentry->d_inode, &needs_trunc);
ocfs_up_sem (&(newOIN->main_res));
delete_target_oin = true;
if (needs_trunc)
@@ -1258,18 +1224,8 @@
LOG_ERROR_STATUS(status);
}
- if (oldOIN) {
- ocfs_release_cached_oin (osb, oldOIN);
- ocfs_release_oin (oldOIN, true);
- if (new_dentry->d_inode)
+ if (oldOIN && new_dentry->d_inode)
fsync_inode_buffers(old_dentry->d_inode);
- }
-
- /* delete the targets oin here as we've just blown it away! */
- if (kill_newfe && newOIN && delete_target_oin) {
- ocfs_release_cached_oin (osb, newOIN);
- ocfs_release_oin (newOIN, true);
- }
}
old_inode->i_nlink++;
@@ -1366,8 +1322,7 @@
goto bail;
}
- inode->u.generic_ip = kmem_cache_alloc(OcfsGlobalCtxt.inode_cache, GFP_NOFS);
- if (!inode->u.generic_ip) {
+ if (ocfs_inode_init_private(inode)) {
LOG_ERROR_STATUS(status = -ENOMEM);
goto bail;
}
@@ -1421,7 +1376,7 @@
OCFS_BH_PUT_DATA(new_fe_bh);
fe = NULL;
- status = ocfs_extend_file (osb, parent_off, NULL, newsize, file_off, handle, inode, NULL);
+ status = ocfs_extend_file (osb, newsize, file_off, handle, inode, NULL);
if (status < 0) {
if (status != -ENOSPC && status != -EINTR) {
LOG_ERROR_ARGS ("Failed to extend file to %u.%u", HILO (newsize));
@@ -1430,20 +1385,8 @@
}
goto abort_trans;
}
-
- status = ocfs_create_oin_from_entry(osb, new_fe_bh, &oin,
- parent_off, NULL);
- if (status < 0) {
- LOG_ERROR_STATUS(status);
- goto abort_trans;
- }
-
inode->i_rdev = OCFS_NODEV;
- if (ocfs_inc_icount(inode) < 0)
- BUG();
- oin->inode = inode;
-
fe = (ocfs_file_entry *) OCFS_BH_GET_DATA_READ(new_fe_bh); /* read */
ocfs_populate_inode (inode, fe, S_IFLNK | S_IRWXUGO, oin, true);
OCFS_BH_PUT_DATA(new_fe_bh);
@@ -1451,6 +1394,19 @@
inode->i_size = newsize;
inode->i_blocks = (newsize + sb->s_blocksize) >> sb->s_blocksize_bits;
+
+ status = ocfs_inode_open(osb, new_fe_bh, handle, inode);
+ if (status < 0) {
+ LOG_ERROR_STATUS(status);
+ goto abort_trans;
+ }
+
+ status = ocfs_inode_fill_ext_map(osb, new_fe_bh, inode);
+ if (status < 0) {
+ LOG_ERROR_STATUS(status);
+ goto abort_trans;
+ }
+
insert_inode_hash (inode);
ocfs_inode_hash_bind(osb, GET_INODE_VOTEOFF(inode), inode);
d_instantiate (dentry, inode);
@@ -1484,6 +1440,7 @@
if (status < 0)
ocfs_bh_sem_hash_cleanup_pid(ocfs_getpid());
+
LOG_EXIT_STATUS (status);
return status;
} /* ocfs_symlink */
@@ -1864,8 +1821,11 @@
if (inode && status == 0 && !(flags & FLAG_DEL_INODE)) {
SET_INODE_DELETED(inode);
- LOG_TRACE_ARGS("removing inode %lu, voteoff = %u.%u\n",
- inode->i_ino, HILO(GET_INODE_VOTEOFF(inode)));
+// printk("ocfs2: removing inode (%p, %p) %lu, voteoff = %u.%u, "
+// "feoff = %u.%u\n", inode, inode->u.generic_ip,
+// inode->i_ino,
+// HILO(GET_INODE_VOTEOFF(inode)),
+// HILO(GET_INODE_FEOFF(inode)));
ocfs_inode_hash_remove(&osb->inode_hash,
GET_INODE_VOTEOFF(inode));
}
Modified: trunk/src/nm.c
===================================================================
--- trunk/src/nm.c 2004-04-16 21:49:58 UTC (rev 846)
+++ trunk/src/nm.c 2004-04-16 22:38:55 UTC (rev 847)
@@ -31,8 +31,9 @@
/* for lack of a better name... protects oin->num_extends. */
spinlock_t oin_num_ext_lock = SPIN_LOCK_UNLOCKED;
+struct semaphore recovery_list_sem;
-static inline int get_process_vote_action(ocfs_super * osb, ocfs_lock_res *lockres, __u32 node_num, __u32 flags, int status, bool *master_alive, ocfs_inode **oin);
+static inline int get_process_vote_action(ocfs_super * osb, ocfs_lock_res *lockres, __u32 node_num, __u32 flags, int status, bool *master_alive, ocfs_inode **oin, struct inode *inode);
static int ocfs_disk_update_resource (ocfs_super * osb, ocfs_lock_res * lock_res, struct buffer_head **bh, __u32 timeout, struct inode *inode);
static int ocfs_search_commited(ocfs_super *osb, ocfs_lock_res *lockres);
static int ocfs_schedule_process_vote(ocfs_super *osb, struct buffer_head *bh, int vote_node);
@@ -43,6 +44,7 @@
{
ocfs_super *osb;
ocfs_lock_res *lockres;
+ struct inode *inode;
} ocfs_ro_cache_drop_ctxt;
@@ -658,7 +660,7 @@
} /* ocfs_find_update_res */
static inline int get_process_vote_action(ocfs_super * osb, ocfs_lock_res *lockres, __u32 node_num,
- __u32 flags, int status, bool *master_alive, ocfs_inode **oin)
+ __u32 flags, int status, bool *master_alive, ocfs_inode **oin, struct inode *inode)
{
int vote_type = INVALID_REQUEST;
bool my_node_wins = false;
@@ -668,6 +670,9 @@
HILO(lockid), node_num, flags);
*oin = NULL;
+ if (inode)
+ *oin = GET_INODE_OIN(inode);
+
*master_alive = true;
if (status < 0) {
if (status == -ETIMEDOUT) {
@@ -680,8 +685,6 @@
lockres->master_node_num, OCFS_MAXIMUM_NODES);
my_node_wins = lockres->vote_state & LOCK_STATE_IN_VOTING &&
node_num < osb->node_num;
- if (lockres->oin)
- *oin = lockres->oin;
}
if (flags & FLAG_DROP_READONLY) {
@@ -802,8 +805,9 @@
ocfs_publish *publish = (disk_vote ? ctxt->u.publish : NULL);
ocfs_dlm_msg *dlm_msg = (comm_vote ? ctxt->u.dlm_msg : NULL);
__u32 node_num = ctxt->node_num;
- __u64 lock_id, seq_num;
+ __u64 lock_id, seq_num, fe_off;
int needs_trunc = 0;
+ bool sysfile = false;
LOG_ENTRY_ARGS ("(0x%08x, 0x%08x)\n", osb, ctxt);
@@ -822,17 +826,38 @@
flags = publish->vote_type;
lock_id = publish->dir_ent;
seq_num = publish->publ_seq_num;
+ fe_off = publish->fe_off;
} else {
ocfs_dlm_req_master *req_master = (ocfs_dlm_req_master *)dlm_msg->msg_buf;
flags = req_master->flags;
lock_id = req_master->lock_id;
seq_num = req_master->lock_seq_num;
+ fe_off = req_master->fe_off;
}
lockflags = (lock_id >= osb->vol_layout.bitmap_off ? OCFS_BH_CACHED : 0);
LOG_TRACE_ARGS ("node=%u, id=%u.%u, seq=%u.%u\n", node_num,
HILO (lock_id), HILO (seq_num));
+ /* delete / rename is slightly different -- we don't want to
+ * look up the inode in the release case -- it should already
+ * be gone. Eventually what we'll really want to do is get it
+ * via the old offsets and set the new ones. */
+ if ((flags & (FLAG_FILE_DELETE | FLAG_FILE_RENAME)) && (flags & FLAG_RELEASE_LOCK))
+ inode = NULL;
+ else
+ inode = ocfs_get_inode_from_offset(osb, lock_id, fe_off, NULL);
+
+ if (inode) {
+ /* we only need i_sem for some of the operations
+ * below, but due to lock ordering, we want to take it
+ * before we acquire_lockres. */
+ down(&inode->i_sem);
+ have_i_sem = true;
+ }
+ sysfile = (lock_id <= osb->vol_layout.root_start_off) ||
+ ((fe_off != 0) && (fe_off < osb->vol_layout.root_start_off));
+
if (disk_vote) {
offset = osb->vol_layout.vote_sect_off + (osb->node_num * osb->sect_size);
status = ocfs_read_bh(osb, offset, &vote_bh, 0, NULL);
@@ -842,15 +867,6 @@
}
}
- inode = ocfs_inode_hash_lookup(osb, lock_id, false);
- if (inode) {
- /* we only need i_sem for some of the operations
- * below, but due to lock ordering, we want to take it
- * before we acquire_lockres. */
- down(&inode->i_sem);
- have_i_sem = true;
- }
-
status = ocfs_find_update_res (osb, lock_id, &lockres, NULL, NULL,
(OCFS_NM_HEARTBEAT_TIME/2), inode);
if (status < 0) {
@@ -868,14 +884,16 @@
}
vote_type = get_process_vote_action(osb, lockres, node_num, flags,
- status, &master_alive, &oin);
+ status, &master_alive, &oin, inode);
#ifdef VERBOSE_PROCESS_VOTE
- printk("(%u) ocfs_process_vote: %s request for lockid: %u.%u, action: (%u) %s, type: %s\n", ocfs_getpid(),
+ printk("(%u) ocfs_process_vote: %s request for lockid: %u.%u, fe_off: %u.%u, action: (%u) %s, type: %s\n", ocfs_getpid(),
flags & FLAG_RELEASE_LOCK ? "RELEASE" :
- (flags & FLAG_ACQUIRE_LOCK ? "ACQUIRE" : "MODIFY"), lock_id,
+ (flags & FLAG_ACQUIRE_LOCK ? "ACQUIRE" : "MODIFY"), HILO(lock_id), HILO(fe_off),
vote_type, process_vote_strings[vote_type], disk_vote ? "disk vote" : "net vote" );
#endif
+ if (!inode && !sysfile)
+ LOG_ERROR_ARGS("No Inode available for non sysfile!\n");
/* get_process_vote_action will only allow CHANGE_MASTER, RELEASE_CACHE, and
* ADD_OIN_MAP on a CACHE lock held by this node. the CHANGE_MASTER/RELEASE_CACHE
* path needs to check the readonly map to see if any nodes need to be updated. this
@@ -937,8 +955,8 @@
case UPDATE_OIN_INODE:
LOG_TRACE_STR("UPDATE_OIN_INODE");
ocfs_down_sem (&(oin->main_res), true);
- oin->needs_verification = true;
- tmpstat = ocfs_verify_update_oin(osb, oin, &needs_trunc);
+ OCFS_I(inode)->needs_verification = true;
+ tmpstat = ocfs_verify_update_inode(osb, inode, &needs_trunc);
if (tmpstat < 0)
LOG_ERROR_STATUS (tmpstat);
ocfs_up_sem (&(oin->main_res));
@@ -953,7 +971,6 @@
case DELETE_RENAME:
LOG_TRACE_STR("DELETE_RENAME");
- oin = lockres->oin;
/* all cases except open_hndl_cnt > 0 will vote YES */
vote_response = FLAG_VOTE_NODE;
@@ -961,8 +978,8 @@
if (oin) {
oin_sem = &(oin->main_res);
ocfs_down_sem (oin_sem, true);
- oin->needs_verification = true;
- tmpstat = ocfs_verify_update_oin(osb, oin, &needs_trunc);
+ OCFS_I(inode)->needs_verification = true;
+ tmpstat = ocfs_verify_update_inode(osb, inode, &needs_trunc);
if (tmpstat < 0)
LOG_ERROR_STATUS (tmpstat);
@@ -977,10 +994,7 @@
ocfs_down_sem (oin_sem, true);
}
- /* make sure that lockres->oin has not changed */
- oin = lockres->oin;
-
- if (oin && oin->open_hndl_cnt > 0) {
+ if (OCFS_I(inode)->open_hndl_cnt > 0) {
/* the NO vote for delete/rename */
vote_response = FLAG_VOTE_OIN_ALREADY_INUSE;
} else if (oin) {
@@ -1138,7 +1152,7 @@
status = 0;
if (!lockres->readonly_dropping) {
ocfs_get_lockres(lockres);
- if (ocfs_drop_readonly_cache_lock(osb, lockres) < 0) {
+ if (ocfs_drop_readonly_cache_lock(osb, lockres, inode) < 0) {
LOG_ERROR_STATUS(status = -ENOMEM);
ocfs_put_lockres(lockres);
}
@@ -1315,17 +1329,12 @@
if (flags & (FLAG_FILE_EXTEND|FLAG_FILE_TRUNCATE) &&
((flags & FLAG_ACQUIRE_LOCK && vote_response==FLAG_VOTE_NODE) ||
(flags & FLAG_RELEASE_LOCK))) {
- oin = NULL;
- if (lockres && lockres->oin)
- oin = lockres->oin;
-
+
LOG_TRACE_ARGS("responding YES to %s %s request, oin=%p, node=%u\n", flags & FLAG_FILE_EXTEND ?
"extend" : "truncate", flags & FLAG_RELEASE_LOCK ?
"release" : "acquire", oin, node_num);
if (oin && (flags & FLAG_ACQUIRE_LOCK)) {
- ocfs_down_sem (&(osb->osb_res), true);
-
spin_lock(&oin_num_ext_lock);
if (oin->num_extends < 0)
@@ -1336,7 +1345,6 @@
spin_unlock(&oin_num_ext_lock);
} else {
spin_unlock(&oin_num_ext_lock);
- ocfs_up_sem (&(osb->osb_res));
/* take the extend_sem on behalf of
* this other node. It won't be
@@ -1347,15 +1355,15 @@
* inode. */
down(&oin->extend_sem);
- ocfs_down_sem (&(osb->osb_res), true);
+ down(&recovery_list_sem);
spin_lock(&oin_num_ext_lock);
oin->num_extends++;
- list_add_tail(&oin->recovery_list, &osb->lock_recovery_lists[node_num]);
+ list_add_tail(&OCFS_I(inode)->recovery_list, &osb->lock_recovery_lists[node_num]);
spin_unlock(&oin_num_ext_lock);
+ up(&recovery_list_sem);
}
- ocfs_up_sem (&(osb->osb_res));
} else if (oin && (flags & FLAG_RELEASE_LOCK)) {
- ocfs_down_sem (&(osb->osb_res), true);
+ down(&recovery_list_sem);
spin_lock(&oin_num_ext_lock);
oin->num_extends--;
@@ -1363,13 +1371,13 @@
BUG();
if (!oin->num_extends) {
- list_del(&oin->recovery_list);
+ list_del(&OCFS_I(inode)->recovery_list);
up(&oin->extend_sem);
}
spin_unlock(&oin_num_ext_lock);
- ocfs_up_sem (&(osb->osb_res));
+ up(&recovery_list_sem);
}
}
@@ -1461,22 +1469,23 @@
{
struct list_head *iter, *temp;
ocfs_inode *oin;
-
+ struct inode *inode;
+ ocfs_inode_private *i;
+
LOG_ENTRY_ARGS("(node_num = %u)\n", node_num);
- ocfs_down_sem (&(osb->osb_res), true);
+ down(&recovery_list_sem);
list_for_each_safe (iter, temp, &osb->lock_recovery_lists[node_num]) {
- oin = list_entry (iter, ocfs_inode, recovery_list);
- if (oin->obj_id.type != OCFS_TYPE_OIN) {
- LOG_ERROR_ARGS("node %u recovery: invalid oin!\n", node_num);
- continue;
- }
+ i = list_entry (iter, ocfs_inode_private, recovery_list);
+ inode = i->inode;
+ oin = GET_INODE_OIN(inode);
spin_lock(&oin_num_ext_lock);
if (oin->num_extends) {
oin->num_extends = 0;
- list_del(&oin->recovery_list);
+ list_del(&OCFS_I(inode)->recovery_list);
+ INIT_LIST_HEAD(&OCFS_I(inode)->recovery_list);
up(&oin->extend_sem);
} else
LOG_ERROR_STR("oin is in recovery list, but has zero extend counter value!");
@@ -1484,12 +1493,13 @@
spin_unlock(&oin_num_ext_lock);
}
- ocfs_up_sem (&(osb->osb_res));
+ up (&recovery_list_sem);
LOG_EXIT();
}
-int ocfs_drop_readonly_cache_lock(ocfs_super *osb, ocfs_lock_res *lockres)
+int ocfs_drop_readonly_cache_lock(ocfs_super *osb, ocfs_lock_res *lockres,
+ struct inode *inode)
{
ocfs_ro_cache_drop_ctxt *arg;
arg = kmalloc(sizeof(ocfs_ro_cache_drop_ctxt), GFP_KERNEL);
@@ -1498,6 +1508,9 @@
arg->osb = osb;
arg->lockres = lockres;
+ arg->inode = inode;
+ if (inode)
+ atomic_inc(&inode->i_count);
kernel_thread(_ocfs_drop_readonly_cache_lock, (void *) arg,
CLONE_VM | CLONE_FS | CLONE_FILES);
@@ -1509,6 +1522,7 @@
ocfs_ro_cache_drop_ctxt *ctxt = (ocfs_ro_cache_drop_ctxt *)arg;
ocfs_super *osb = ctxt->osb;
ocfs_lock_res *lockres = ctxt->lockres;
+ struct inode *inode = ctxt->inode;
__u64 map;
int status = 0;
@@ -1548,7 +1562,8 @@
/* cannot hold lockres while waiting for vote */
ocfs_release_lockres(lockres);
- status = ocfs_send_readonly_drop_message(osb, lockres, map);
+ status = ocfs_send_readonly_drop_message(osb, lockres, map,
+ inode);
if (status >= 0) {
ocfs_acquire_lockres(lockres);
break;
@@ -1571,6 +1586,8 @@
leave:
ocfs_release_lockres(lockres);
ocfs_put_lockres(lockres);
+ if (inode)
+ iput(inode);
kfree(arg);
return status;
}
Modified: trunk/src/oin.c
===================================================================
--- trunk/src/oin.c 2004-04-16 21:49:58 UTC (rev 846)
+++ trunk/src/oin.c 2004-04-16 22:38:55 UTC (rev 847)
@@ -31,43 +31,36 @@
extern spinlock_t oin_num_ext_lock;
/*
- * ocfs_verify_update_oin()
- *
- * This function searches the cached oin list for a volume for a given
- * filename. We currently cache all the oin's. We should hash this list.
- *
+ * ocfs_verify_update_inode()
*/
-int ocfs_verify_update_oin (ocfs_super * osb, ocfs_inode * oin, int *needs_trunc)
+int ocfs_verify_update_inode (ocfs_super * osb, struct inode * inode, int *needs_trunc)
{
int status = 0;
struct buffer_head *fe_bh = NULL;
ocfs_file_entry *fe = NULL;
ocfs_lock_res *pLockRes;
- struct inode *inode = NULL;
struct list_head *iter;
struct list_head *temp_iter;
int disk_len;
__u64 offset;
ocfs_disk_lock dlock; /* ???: is this too much on the stack? */
+ ocfs_inode *oin = NULL;
/* We are setting the oin Updated flag in the end. */
LOG_ENTRY ();
- OCFS_ASSERT (oin);
+ OCFS_ASSERT (inode);
- if (!oin->inode) {
- printk(KERN_ERR "ocfs2: oin has no inode!\n");
- BUG();
- }
+ oin = GET_INODE_OIN(inode);
*needs_trunc = 0;
/* This read of feoff from the inode depends on all callers to
* make sure that unlink or rename can't be change it while we're
* in here! */
- offset = GET_INODE_FEOFF(oin->inode);
+ offset = GET_INODE_FEOFF(inode);
- status = ocfs_read_bh(osb, offset, &fe_bh, OCFS_BH_COND_CACHED, oin->inode);
+ status = ocfs_read_bh(osb, offset, &fe_bh, OCFS_BH_COND_CACHED, inode);
if (status < 0) {
LOG_ERROR_STATUS (status);
goto leave;
@@ -93,13 +86,6 @@
}
disk_len = strlen(fe->filename);
- inode = oin->inode;
- if (inode == NULL) {
- LOG_ERROR_STR ("oin has no matching inode!!!!");
- OCFS_SET_FLAG (oin->oin_flags, OCFS_OIN_INVALID);
- status = -ENOENT;
- goto leave;
- }
status = -ENOENT;
list_for_each_safe (iter, temp_iter, &(inode->i_dentry)) {
@@ -119,7 +105,7 @@
if ((oin->alloc_size != (__s64) fe->alloc_size) ||
(inode->i_size != (__s64) fe->file_size) ||
- (oin->chng_seq_num != DISK_LOCK_SEQNUM (fe)) ||
+ (OCFS_I(inode)->chng_seq_num != DISK_LOCK_SEQNUM (fe)) ||
inode->i_uid != fe->uid ||
inode->i_gid != fe->gid || inode->i_mode != fe->prot_bits) {
@@ -132,7 +118,7 @@
("Allocsize, filesize or seq no did not match");
oin->alloc_size = fe->alloc_size;
inode->i_size = fe->file_size;
- oin->chng_seq_num = DISK_LOCK_SEQNUM (fe);
+ OCFS_I(inode)->chng_seq_num = DISK_LOCK_SEQNUM (fe);
inode->i_blocks = (inode->i_size + 512) >> 9;
inode->i_uid = fe->uid;
@@ -145,7 +131,7 @@
if (!S_ISDIR (inode->i_mode) &&
(oin->alloc_size != (__s64) fe->alloc_size ||
inode->i_size != (__s64) fe->file_size ||
- oin->chng_seq_num != DISK_LOCK_SEQNUM (fe))) {
+ OCFS_I(inode)->chng_seq_num != DISK_LOCK_SEQNUM (fe))) {
*needs_trunc = 1;
}
@@ -257,7 +243,7 @@
leave:
if (status == 0)
- OIN_UPDATED (oin);
+ OCFS_I(inode)->needs_verification = false;
if (fe_bh) {
if (fe)
@@ -267,17 +253,84 @@
LOG_EXIT_STATUS (status);
return status;
-} /* ocfs_verify_update_oin */
+} /* ocfs_verify_update_inode */
+/* you should be holding i_sem and main_res in this function.
+ *
+ * Put a lockres on the oin and if needed add ourselves to the open
+ * map. Only call this on 1st open of a file. Marks the oin as "in use"
+ */
+int ocfs_inode_open(ocfs_super *osb, struct buffer_head *fe_bh,
+ ocfs_journal_handle *handle, struct inode *inode)
+{
+ int status = 0;
+ ocfs_inode *oin;
+ ocfs_file_entry *fe = NULL;
+ bool local_handle = true;
+ __u32 flags = OCFS_OIN_IN_USE;
+ LOG_ENTRY ();
+
+ if (handle)
+ local_handle = false;
+
+ oin = GET_INODE_OIN(inode);
+
+ fe = (ocfs_file_entry *) OCFS_BH_GET_DATA_READ(fe_bh); /* read */
+
+ /* why do we update these here? */
+ oin->alloc_size = fe->alloc_size;
+ OCFS_I(inode)->chng_seq_num = DISK_LOCK_SEQNUM (fe);
+ if (fe->this_sector == 0)
+ LOG_ERROR_STR ("this_sector=0");
+
+ OCFS_BH_PUT_DATA(fe_bh);
+
+ flags |= oin->oin_flags;
+
+ if (!(flags & OCFS_OIN_ROOT_DIRECTORY)) {
+ if (local_handle) {
+ handle = ocfs_start_trans(osb, OCFS_OPEN_CREDITS);
+ if (!handle) {
+ LOG_ERROR_STATUS(status = -ENOMEM);
+ goto leave;
+ }
+ /* we want this to be a really fast transaction. */
+ ocfs_handle_set_sync(handle, false);
+ ocfs_handle_set_checkpoint(handle, false);
+ }
+
+ status = ocfs_create_update_lock(osb, GET_INODE_VOTEOFF(inode),
+ flags, false, inode, handle);
+ if (status < 0) {
+ if (status != -EINTR)
+ LOG_ERROR_STATUS (status);
+ goto leave;
+ }
+ }
+ oin->oin_flags |= OCFS_OIN_IN_USE;
+
+leave:
+ if (local_handle && handle) {
+ if (status < 0)
+ ocfs_abort_trans(handle);
+ else
+ ocfs_commit_trans(handle);
+ }
+
+ LOG_EXIT_STATUS (status);
+ return status;
+}
+
+
+
/* ocfs_create_oin_from_entry()
*
*/
-int ocfs_create_oin_from_entry (ocfs_super * osb, struct buffer_head * fe_bh, ocfs_inode ** new_oin, __u64 parent_dir_off, struct inode *inode)
+int ocfs_inode_fill_ext_map(ocfs_super * osb, struct buffer_head * fe_bh, struct inode *inode)
{
int status = 0;
ocfs_inode *oin;
- __u64 lockId;
int j;
__s64 tempVbo;
__s64 tempLbo;
@@ -291,7 +344,7 @@
LOG_ENTRY ();
- *new_oin = NULL;
+ oin = GET_INODE_OIN(inode);
/* get a copy of fe, used readonly in this path and */
/* ocfs_create_new_oin will deadlock if fe_bh is locked */
@@ -303,134 +356,92 @@
tmp = OCFS_BH_GET_DATA_READ(fe_bh); /* read */
memcpy(fe, tmp, sizeof(ocfs_file_entry));
OCFS_BH_PUT_DATA(fe_bh);
+ tempoff = fe->this_sector;
- /* We have a new file on disk , so create an oin for the file */
- status = ocfs_create_new_oin (&oin, fe->alloc_size, osb);
- if (status < 0) {
- LOG_ERROR_STATUS (status);
+ /* we don't want to do the extent map stuff for a directory. */
+ if (fe->attribs & OCFS_ATTRIB_DIRECTORY)
goto leave;
- }
- oin->parent_dirnode_off = parent_dir_off;
- oin->chng_seq_num = DISK_LOCK_SEQNUM (fe);
-
- if (fe->this_sector == 0)
- LOG_ERROR_STR ("this_sector=0");
-
- tempoff = fe->this_sector;
-
- /* The oins gets Linked into the osb in this function */
-
- if (fe->attribs & OCFS_ATTRIB_DIRECTORY) {
- lockId = fe->extents[0].disk_off;
-
- status = ocfs_initialize_oin (oin, osb,
- OCFS_OIN_DIRECTORY | OCFS_OIN_IN_USE,
- tempoff, lockId, false, inode);
- if (status < 0) {
- if (status != -EINTR)
- LOG_ERROR_STATUS (status);
- goto leave;
+ if (fe->local_ext) {
+ for (j = 0; j < fe->next_free_ext; j++) {
+ tempVbo = fe->extents[j].file_off;
+ tempLbo = fe->extents[j].disk_off;
+ tempSize = fe->extents[j].num_bytes;
+
+ /* Add the Extent to extent map */
+ bRet = ocfs_add_extent_map_entry (osb,
+ &oin->map,
+ tempVbo,
+ tempLbo,
+ tempSize);
+ if (!bRet) {
+ LOG_ERROR_STATUS (status = -ENOMEM);
+ goto leave;
+ }
}
} else {
- __u32 flags = OCFS_OIN_IN_USE;
-
- if((DISK_LOCK_FILE_LOCK(fe) == OCFS_DLM_ENABLE_CACHE_LOCK)
- && (DISK_LOCK_CURRENT_MASTER(fe) == osb->node_num))
- flags |= OCFS_OIN_CACHE_UPDATE;
- status = ocfs_initialize_oin (oin, osb, flags,
- tempoff, tempoff, false, inode);
+ __u64 next_data_ext;
+
+ /* Extents are branched and we are no longer using */
+ /* Local Extents for this File Entry. */
+
+ status = ocfs_get_leaf_extent (osb, fe, 0, &extent_bh, inode);
if (status < 0) {
- if (status != -EINTR)
- LOG_ERROR_STATUS (status);
+ LOG_ERROR_STATUS (status);
goto leave;
}
-
- if (fe->local_ext) {
- for (j = 0; j < fe->next_free_ext; j++) {
- tempVbo = fe->extents[j].file_off;
- tempLbo = fe->extents[j].disk_off;
- tempSize = fe->extents[j].num_bytes;
-
+
+ while (1) {
+ extent = (ocfs_extent_group *) OCFS_BH_GET_DATA_READ(extent_bh); /* read */
+
+ if (!IS_VALID_EXTENT_DATA (extent)) {
+ LOG_ERROR_STATUS(status = -EFAIL);
+ goto leave;
+ }
+
+ for (j = 0; j < extent->next_free_ext; j++) {
+ tempVbo = extent->extents[j].file_off;
+ tempLbo = extent->extents[j].disk_off;
+ tempSize = extent->extents[j].num_bytes;
+
/* Add the Extent to extent map */
- bRet = ocfs_add_extent_map_entry (osb,
- &oin->map,
- tempVbo,
- tempLbo,
- tempSize);
+ bRet =
+ ocfs_add_extent_map_entry (osb,
+ &oin->map,
+ tempVbo,
+ tempLbo,
+ tempSize);
if (!bRet) {
- LOG_ERROR_STATUS (status = -ENOMEM);
+ LOG_ERROR_STATUS (status =
+ -ENOMEM);
goto leave;
}
}
- } else {
- __u64 next_data_ext;
-
- /* Extents are branched and we are no longer using */
- /* Local Extents for this File Entry. */
-
- status = ocfs_get_leaf_extent (osb, fe, 0, &extent_bh, inode);
- if (status < 0) {
- LOG_ERROR_STATUS (status);
- goto leave;
- }
-
- while (1) {
- extent = (ocfs_extent_group *) OCFS_BH_GET_DATA_READ(extent_bh); /* read */
-
- if (!IS_VALID_EXTENT_DATA (extent)) {
- LOG_ERROR_STATUS(status = -EFAIL);
+
+ if (extent->next_data_ext > 0) {
+ if (!extent->next_data_ext) {
+ LOG_ERROR_STATUS (status = -EFAIL);
goto leave;
}
+ next_data_ext = extent->next_data_ext;
+ OCFS_BH_PUT_DATA(extent_bh);
+ extent = NULL;
+ extent_bh = NULL;
- for (j = 0; j < extent->next_free_ext; j++) {
- tempVbo = extent->extents[j].file_off;
- tempLbo = extent->extents[j].disk_off;
- tempSize = extent->extents[j].num_bytes;
-
- /* Add the Extent to extent map */
- bRet =
- ocfs_add_extent_map_entry (osb,
- &oin->map,
- tempVbo,
- tempLbo,
- tempSize);
- if (!bRet) {
- LOG_ERROR_STATUS (status =
- -ENOMEM);
- goto leave;
- }
- }
-
- if (extent->next_data_ext > 0) {
- if (!extent->next_data_ext) {
- LOG_ERROR_STATUS (status = -EFAIL);
- goto leave;
- }
- next_data_ext = extent->next_data_ext;
- OCFS_BH_PUT_DATA(extent_bh);
- extent = NULL;
- extent_bh = NULL;
-
- status = ocfs_read_bh(osb,
+ status = ocfs_read_bh(osb,
next_data_ext,
&extent_bh,
OCFS_BH_COND_CACHED, inode);
- if (status < 0) {
- LOG_ERROR_STATUS (status);
- goto leave;
- }
- } else
- break;
- }
+ if (status < 0) {
+ LOG_ERROR_STATUS (status);
+ goto leave;
+ }
+ } else
+ break;
}
}
- *new_oin = oin;
leave:
- if (!*new_oin && oin)
- ocfs_release_oin (oin, true);
-
/* this fe was a copy */
if (fe)
ocfs_release_file_entry (fe);
@@ -445,79 +456,6 @@
return status;
} /* ocfs_create_oin_from_entry */
-
-/*
- * ocfs_initialize_oin()
- *
- * Initialize a oin structure and file object. This function is called
- * whenever a file is recognized for the first time.
- */
-int ocfs_initialize_oin (ocfs_inode * oin, ocfs_super * osb, __u32 flags, __u64 file_off, __u64 lock_id, bool new_file, struct inode *inode)
-{
- int status = 0;
-
- LOG_ENTRY ();
-
- if (!(flags & OCFS_OIN_ROOT_DIRECTORY)) {
- status = ocfs_create_update_lock (osb, oin, lock_id, flags, new_file, inode);
- if (status < 0) {
- /* This can be okay as the other node can tell us the
- * file was deleted. */
- goto leave;
- }
- }
-
- oin->osb = osb;
- oin->oin_flags |= flags;
- oin->open_hndl_cnt = 0;
- oin->journal_inode = false;
- ocfs_extent_map_init (&oin->map);
-
-leave:
- LOG_EXIT_STATUS (status);
- return status;
-} /* ocfs_initialize_oin */
-
-/*
- * ocfs_create_new_oin()
- *
- * Create a new oin.
- */
-int ocfs_create_new_oin (ocfs_inode ** Returnedoin, __u64 alloc_size, ocfs_super * osb)
-{
- int status = 0;
- ocfs_inode *oin = NULL;
-
- LOG_ENTRY_ARGS("(alloc_size = %u.%u)\n", HILO(alloc_size));
-
- OCFS_ASSERT (osb);
-
- oin = ocfs_allocate_oin ();
- *Returnedoin = oin;
-
- if (oin == NULL) {
- LOG_ERROR_STATUS (status = -ENOMEM);
- goto finally;
- }
-
- ocfs_init_sem (&(oin->main_res));
- init_MUTEX(&(oin->extend_sem));
- OCFS_SET_FLAG (oin->oin_flags, OCFS_INITIALIZED_MAIN_RESOURCE);
-
- /* Initialize the alloc size value here, file size will come
- * later in i_size */
- oin->alloc_size = alloc_size;
-
- /* Insert the pointer to osb in the oin and also Initialize
- * the OFile list */
- oin->osb = osb;
-
-finally:
-
- LOG_EXIT_STATUS (status);
- return status;
-} /* ocfs_create_new_oin */
-
/* ocfs_create_root_oin()
*
*/
@@ -525,7 +463,6 @@
{
int status = 0;
int tmpstat;
- ocfs_inode *oin = NULL;
ocfs_vol_disk_hdr *volDiskHdr = NULL;
struct buffer_head *hdr_bh = NULL;
ocfs_lock_res *LockResource = NULL;
@@ -589,36 +526,7 @@
/* if it fails, Release the memory for the OFile we allocated above */
}
- /* Create the root directory oin. This is done either here or in */
- /* FindNewoin's if it fails, Release the memory for the OFile we */
- /* allocated above */
- status = ocfs_create_new_oin (&oin, 0ULL, osb);
- if (status < 0) {
- LOG_ERROR_STATUS (status);
- goto finally;
- }
-
- /* This is for root . */
- status = ocfs_initialize_oin (oin, osb,
- OCFS_OIN_DIRECTORY | OCFS_OIN_ROOT_DIRECTORY,
- 0, osb->vol_layout.root_start_off, true, root);
- if (status < 0) {
- if (status != -EINTR)
- LOG_ERROR_STATUS (status);
- goto finally;
- }
-
- /* put the offset/inode number in the inode cache thingy. */
- ocfs_inode_hash_insert(osb, osb->vol_layout.root_start_off, 0ULL);
- // oin->Parentoin = NULL; /* Root has no parent */
-
- /* Set the Rootdirectories root Dir Node */
-
- osb->oin_root_dir = oin;
-
finally:
- if (status < 0 && oin)
- ocfs_release_oin (oin, true);
if (hdr_bh) {
lock_buffer(hdr_bh);
@@ -631,190 +539,3 @@
LOG_EXIT_STATUS (status);
return status;
} /* ocfs_create_root_oin */
-
-/*
- * ocfs_release_oin()
- *
- */
-void ocfs_release_oin (ocfs_inode * oin, bool FreeMemory)
-{
- ocfs_lock_res *lockres = NULL;
- ocfs_super *osb = NULL;
- struct inode *inode;
-
- LOG_ENTRY_ARGS ("oin = %p, free = %s\n", oin, FreeMemory? "yes" : "no");
-
- if (!oin || !oin->osb)
- goto bail;
-
- osb = oin->osb;
- lockres = oin->lock_res;
-
- if (lockres != NULL) {
- ocfs_get_lockres (lockres);
- ocfs_acquire_lockres (lockres);
- if (lockres->oin == oin)
- lockres->oin = NULL;
- ocfs_release_lockres (lockres);
- }
-
- ocfs_down_sem (&(osb->osb_res), true);
- spin_lock(&oin_num_ext_lock);
- if (oin->num_extends)
- list_del(&oin->recovery_list);
- spin_unlock(&oin_num_ext_lock);
- ocfs_up_sem (&(osb->osb_res));
-
- inode = (struct inode *) oin->inode;
-
- if (inode) {
- CLEAR_INODE_OIN(inode);
- LOG_TRACE_ARGS ("inode oin cleared / flags: %d / offset: %u.%u\n",
- inode->i_flags, GET_INODE_FEOFF(inode));
- }
-
- ocfs_extent_map_destroy (&oin->map);
-
- /* Delete the ocfs_sem objects */
- if (oin->oin_flags & OCFS_INITIALIZED_MAIN_RESOURCE) {
- ocfs_del_sem (&(oin->main_res));
- OCFS_CLEAR_FLAG (oin->oin_flags, OCFS_INITIALIZED_MAIN_RESOURCE);
- }
-
- if (FreeMemory) {
- if (oin->inode) {
- /* we don't do an iput to avoid recursive
- * calls to ocfs_put_inode */
- atomic_dec(&oin->inode->i_count);
- oin->inode = NULL;
- }
- /* clean out the oin ... why?! */
- memset(oin, 0, sizeof(ocfs_inode));
-#ifdef OCFS_MEM_DBG
- ocfs_dbg_slab_free (OcfsGlobalCtxt.oin_cache, oin);
-#else
- kmem_cache_free (OcfsGlobalCtxt.oin_cache, oin);
-#endif
- oin = NULL;
- ocfs_put_lockres (lockres);
- }
- ocfs_put_lockres (lockres);
-bail:
- LOG_EXIT ();
- return;
-} /* ocfs_release_oin */
-
-/*
- * ocfs_release_cached_oin()
- *
- */
-void ocfs_release_cached_oin (ocfs_super * osb, ocfs_inode * oin)
-{
- bool bAcquiredOIN = false;
- ocfs_lock_res *lockResource = NULL;
- ocfs_lock_res *val=NULL;
- struct dentry *dentry;
- struct list_head *iter;
- struct list_head *temp_iter;
- struct inode *inode;
- int refcount = 0;
- int status = 0;
- __u64 feoff = 0;
-
- LOG_ENTRY_ARGS ("(oin = 0x%08x)\n", oin);
-
- if (oin == NULL)
- goto bail;
-
- /*
- * If the OCFS_OSB_FLAGS_BEING_DISMOUNTED flag has
- * already been set, then the lockres hash has already
- * been cleaned out which means that we have a lock_res
- * pointer that points to free memory.
- */
- if (osb->osb_flags & OCFS_OSB_FLAGS_BEING_DISMOUNTED) {
- oin->lock_res = NULL;
- goto bail;
- }
-
- ocfs_down_sem (&(oin->main_res), true);
- bAcquiredOIN = true;
- inode = oin->inode;
-
- if (inode) {
- list_for_each_safe (iter, temp_iter, &(inode->i_dentry)) {
- dentry = list_entry (iter, struct dentry, d_alias);
- refcount += atomic_read(&dentry->d_count);
- }
- feoff = GET_INODE_FEOFF(inode);
- }
-
-
- if (refcount != 0 || oin->open_hndl_cnt != 0 ||
- oin->oin_flags & OCFS_OIN_IN_USE) {
- if (bAcquiredOIN) {
- ocfs_up_sem (&(oin->main_res));
- bAcquiredOIN = false;
- }
- goto bail;
- } else {
- OCFS_SET_FLAG (oin->oin_flags, OCFS_OIN_IN_TEARDOWN);
-
- if (bAcquiredOIN) {
- ocfs_up_sem (&(oin->main_res));
- bAcquiredOIN = false;
- }
-
- lockResource = (ocfs_lock_res *) oin->lock_res;
- if (lockResource == NULL) {
- LOG_ERROR_ARGS("lockres=null, feoff = %u.%u\n",
- HILO(feoff));
-
- goto bail;
- }
-
- if (lockResource->signature != 0x55AA) {
- LOG_ERROR_STR("Invalid lock resource");
- goto bail;
- }
- ocfs_get_lockres (lockResource);
-
- if (lockResource->sector_num == 0 || lockResource->oin != oin) {
- LOG_ERROR_STR ("id=0 or oin invalid");
- goto bail;
- }
-
- lockResource->oin = NULL;
- if (lockResource->in_cache_list) {
- list_del (& (lockResource->cache_list));
- lockResource->in_cache_list = false;
- }
-
- status = ocfs_lookup_sector_node (osb, lockResource->sector_num, &val);
- if (status >= 0) {
- if (val == lockResource)
- ocfs_remove_sector_node (osb, val);
- else
- LOG_ERROR_ARGS("(lres=0x%08x) != (val=0x%08x)",
- lockResource, val);
- ocfs_put_lockres (val);
- } else {
- if (status == -EFAIL) {
- ocfs_put_lockres (oin->lock_res);
- oin->lock_res = NULL;
- LOG_TRACE_ARGS ("hashtable already destroyed\n");
- goto bail;
- }
- LOG_ERROR_ARGS("lres=0x%08x is not in the hash!",
- lockResource);
- }
- ocfs_put_lockres (oin->lock_res);
- oin->lock_res = NULL;
- }
-
-bail:
- ocfs_put_lockres (lockResource);
- LOG_EXIT ();
- return;
-} /* ocfs_release_cached_oin */
-
Modified: trunk/src/super.c
===================================================================
--- trunk/src/super.c 2004-04-16 21:49:58 UTC (rev 846)
+++ trunk/src/super.c 2004-04-16 22:38:55 UTC (rev 847)
@@ -124,6 +124,8 @@
MODULE_PARM_DESC(comm_voting, "Enable/Disable network dlm");
#endif /* Linux 2.4 stuff */
+extern struct semaphore recovery_list_sem;
+
static int ocfs_parse_options (char *options, __u32 * uid, __u32 * gid, bool * reclaim_id);
static int __init ocfs_driver_entry (void);
static void __exit ocfs_driver_exit (void);
@@ -220,11 +222,7 @@
goto read_super_error;
}
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
- inode = ocfs_iget(sb, NULL);
-#else
- inode = iget4(sb, OCFS_ROOT_INODE_NUMBER, 0, NULL);
-#endif
+ inode = osb->root_inode;
if (!inode) {
status = -EIO;
LOG_ERROR_STATUS (status);
@@ -451,6 +449,7 @@
OcfsGlobalCtxt.comm_seq_num = 0;
spin_unlock (&OcfsGlobalCtxt.comm_seq_lock);
+ init_MUTEX (&recovery_list_sem);
/* Initialize the proc interface */
ocfs_proc_init ();
@@ -740,20 +739,6 @@
}
#endif
-static void ocfs_inode_init_once(void *p, kmem_cache_t *cachep,
- unsigned long flags)
-{
- ocfs_inode_private *i = (ocfs_inode_private *) p;
-
- if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) ==
- SLAB_CTOR_CONSTRUCTOR) {
- i->oin = NULL;
- i->voteoff = 0;
- i->feoff = 0;
- atomic_set(&i->i_clean_buffer_seq, 0);
- }
-}
-
/*
* ocfs_initialize_mem_lists()
*
@@ -762,7 +747,7 @@
{
OcfsGlobalCtxt.inode_cache = kmem_cache_create("ocfs2_inode",
sizeof(ocfs_inode_private), 0, SLAB_NO_REAP | SLAB_HWCACHE_ALIGN,
- ocfs_inode_init_once, NULL);
+ NULL, NULL);
OcfsGlobalCtxt.oin_cache = kmem_cache_create ("ocfs2_oin",
sizeof (ocfs_inode) + OCFS_POINTER_SIZE, 0, SLAB_NO_REAP | SLAB_HWCACHE_ALIGN,
@@ -826,6 +811,7 @@
ocfs_vol_label *vol_label = NULL;
int child_pid, i;
struct buffer_head *bhs[] = { NULL, NULL };
+ struct inode *inode = NULL;
LOG_ENTRY ();
@@ -1014,6 +1000,28 @@
goto leave;
}
+ /* Initialize the root inode. */
+ ocfs_inode_hash_insert(osb, osb->vol_layout.root_start_off, 0ULL);
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
+ inode = ocfs_iget(sb, NULL);
+#else
+ inode = iget4(sb, OCFS_ROOT_INODE_NUMBER, 0, NULL);
+#endif
+ if (!inode) {
+ status = -EIO;
+ LOG_ERROR_STATUS (status);
+ goto leave;
+ }
+ if (is_bad_inode(inode)) {
+ status = -EIO;
+ LOG_ERROR_STATUS (status);
+ iput(inode);
+ inode = NULL;
+ goto leave;
+ }
+ osb->root_inode = inode;
+ osb->oin_root_dir = GET_INODE_OIN(inode);
+
/* Read the publish sector for this node and cleanup dirent being */
/* modified when we crashed. */
LOG_TRACE_STR ("ocfs_check_volume...");
@@ -1118,7 +1126,6 @@
LOG_ERROR_STR("Could not set mounted flag!");
ocfs_sync_blockdev(sb);
- ocfs_release_oin (rootoin, true);
/* Destroy the Hash table */
ocfs_hash_destroy (&(osb->root_sect_node), lockres_hash_free_func);
Modified: trunk/src/sysfile.c
===================================================================
--- trunk/src/sysfile.c 2004-04-16 21:49:58 UTC (rev 846)
+++ trunk/src/sysfile.c 2004-04-16 22:38:55 UTC (rev 847)
@@ -537,7 +537,7 @@
actualLength =
(__u64) (numClusterAlloc * osb->vol_layout.cluster_size);
- status = ocfs_allocate_extent (osb, NULL, fe_bh, handle,
+ status = ocfs_allocate_extent (osb, fe_bh, handle,
actualDiskOffset, actualLength, NULL);
if (status < 0) {
LOG_ERROR_STATUS (status);
More information about the Ocfs2-commits
mailing list