[Ocfs2-commits] mfasheh commits r872 - in trunk/src: . inc
svn-commits at oss.oracle.com
svn-commits at oss.oracle.com
Tue Apr 27 21:37:05 CDT 2004
Author: mfasheh
Date: 2004-04-27 20:37:04 -0500 (Tue, 27 Apr 2004)
New Revision: 872
Modified:
trunk/src/alloc.c
trunk/src/dlm.c
trunk/src/hash.c
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/osb.c
trunk/src/super.c
trunk/src/sysfile.c
Log:
* turn ocfs_get_inode_from_offset into ocfs_iget. All functions can call
this to create an inode now, and the 2.4.x/2.6.x paths are unified at last.
The function will try it's hardest to create an inode based on the
information provided.
* Teach the ocfs inode stuff about system files. We can now create inodes
for them on demand, including objects which have no file entry, such as the
volume bitmap.
* Unify the 2.6.x and 2.4.x read_inode functionality into
__ocfs_read_inode2.
* Add ocfs_read_inode_nofe to "read" inodes that have no file entry.
* create the most commonly used system file inodes at startup -- vol bitmap,
dir alloc bitmap, metadata alloc bitmap and journal inode (that one was
already being created, but move it to ocfs_init_system_inodes)
* All calls to ocfs_acquire_lock have an inode now. This is absolutely
necessary as fe_off needs to be properly propagated during votes and this
can't happen without an inode. The same goes for ocfs_release_lock.
* remove a redundant variable in ocfs_inode_open()
Modified: trunk/src/alloc.c
===================================================================
--- trunk/src/alloc.c 2004-04-28 00:11:13 UTC (rev 871)
+++ trunk/src/alloc.c 2004-04-28 01:37:04 UTC (rev 872)
@@ -71,11 +71,13 @@
ocfs_free_rec *freelog);
static int ocfs_alloc_new_window(ocfs_super *osb, struct buffer_head *lock_bh,
+ struct inode *bm_inode,
ocfs_journal_handle *hanlde);
static int ocfs_sync_local_to_main(ocfs_super *osb,
ocfs_bitmap_free_head **f,
struct buffer_head *local_alloc_bh,
struct buffer_head *bm_lock_bh,
+ struct inode *bm_inode,
bool in_recovery);
static __u32 ocfs_alloc_count_bits(ocfs_local_alloc *alloc);
static void ocfs_clear_local_alloc(ocfs_local_alloc *alloc);
@@ -186,6 +188,9 @@
ocfs_lock_res **extnode_lockres = NULL;
ocfs_lock_res *vol_lockres = NULL;
ocfs_free_rec *tmp_log;
+ struct inode **dirnode_inode = NULL;
+ struct inode **extnode_inode = NULL;
+ struct inode *vol_inode = NULL;
__u32 tmp_indx;
__u64 lock_id;
struct buffer_head *globalbh = NULL;
@@ -209,11 +214,17 @@
OCFS_MAXIMUM_NODES * sizeof (ocfs_lock_res *), status);
ALLOC_BLOCK(extnode_lockres,
OCFS_MAXIMUM_NODES * sizeof (ocfs_lock_res *), status);
+ ALLOC_BLOCK(dirnode_inode,
+ OCFS_MAXIMUM_NODES * sizeof (struct inode *), status);
+ ALLOC_BLOCK(extnode_inode,
+ OCFS_MAXIMUM_NODES * sizeof (struct inode *), status);
/* init */
for (i = 0; i < OCFS_MAXIMUM_NODES; i++) {
free_dir_node[i] = NULL;
free_ext_node[i] = NULL;
+ dirnode_inode[i] = NULL;
+ extnode_inode[i] = NULL;
}
/* alloc memory */
@@ -290,10 +301,18 @@
osb->vol_layout.root_int_off;
for (i = 0; i < OCFS_MAXIMUM_NODES; i++, lock_id += osb->sect_size) {
if (free_dir_node[i] != NULL) {
+ dirnode_inode[i] = ocfs_iget(osb, lock_id, lock_id,
+ NULL);
+ if (!dirnode_inode[i]) {
+ status = -EINVAL;
+ LOG_ERROR_STATUS (status);
+ goto finally;
+ }
status = ocfs_acquire_lock (osb, lock_id,
OCFS_DLM_EXCLUSIVE_LOCK,
FLAG_FILE_CREATE,
- &(dirnode_lockres[i]), NULL, NULL);
+ &(dirnode_lockres[i]),
+ NULL, dirnode_inode[i]);
if (status < 0) {
if (status != -EINTR)
LOG_ERROR_STATUS (status);
@@ -306,10 +325,18 @@
osb->vol_layout.root_int_off;
for (i = 0; i < OCFS_MAXIMUM_NODES; i++, lock_id += osb->sect_size) {
if (free_ext_node[i] != NULL) {
+ extnode_inode[i] = ocfs_iget(osb, lock_id, lock_id,
+ NULL);
+ if (!extnode_inode[i]) {
+ status = -EINVAL;
+ LOG_ERROR_STATUS (status);
+ goto finally;
+ }
status = ocfs_acquire_lock (osb, lock_id,
OCFS_DLM_EXCLUSIVE_LOCK,
FLAG_FILE_CREATE,
- &(extnode_lockres[i]), NULL, NULL);
+ &(extnode_lockres[i]),
+ NULL, extnode_inode[i]);
if (status < 0) {
if (status != -EINTR)
LOG_ERROR_STATUS (status);
@@ -319,9 +346,17 @@
}
if (free_vol_bits != NULL) {
+ vol_inode = ocfs_iget(osb, OCFS_BITMAP_LOCK_OFFSET, 0, NULL);
+ if (!vol_inode) {
+ status = -EINVAL;
+ LOG_ERROR_STATUS (status);
+ goto finally;
+ }
+
status = ocfs_acquire_lock (osb, OCFS_BITMAP_LOCK_OFFSET,
OCFS_DLM_EXCLUSIVE_LOCK,
- FLAG_FILE_CREATE, &vol_lockres, &globalbh, NULL);
+ FLAG_FILE_CREATE, &vol_lockres,
+ &globalbh, vol_inode);
if (status < 0) {
if (status != -EINTR)
LOG_ERROR_STATUS (status);
@@ -361,7 +396,7 @@
}
status = ocfs_release_lock (osb, OCFS_BITMAP_LOCK_OFFSET,
OCFS_DLM_EXCLUSIVE_LOCK,
- FLAG_FILE_CREATE, vol_lockres, globalbh, NULL);
+ FLAG_FILE_CREATE, vol_lockres, globalbh, vol_inode);
if (status < 0) {
LOG_ERROR_STATUS (status);
goto finally;
@@ -375,7 +410,8 @@
status = ocfs_release_lock (osb, lock_id,
OCFS_DLM_EXCLUSIVE_LOCK,
FLAG_FILE_CREATE,
- dirnode_lockres[i], NULL, NULL);
+ dirnode_lockres[i], NULL,
+ dirnode_inode[i]);
if (status < 0) {
LOG_ERROR_STATUS (status);
goto finally;
@@ -390,7 +426,8 @@
status = ocfs_release_lock (osb, lock_id,
OCFS_DLM_EXCLUSIVE_LOCK,
FLAG_FILE_CREATE,
- extnode_lockres[i], NULL, NULL);
+ extnode_lockres[i], NULL,
+ extnode_inode[i]);
if (status < 0) {
LOG_ERROR_STATUS (status);
goto finally;
@@ -406,9 +443,15 @@
ocfs_put_lockres (dirnode_lockres[i]);
if (free_ext_node[i])
ocfs_put_lockres (extnode_lockres[i]);
+ if (extnode_inode[i])
+ iput(extnode_inode[i]);
+ if (dirnode_inode[i])
+ iput(dirnode_inode[i]);
}
if (globalbh)
brelse(globalbh);
+ if (vol_inode)
+ iput(vol_inode);
ocfs_put_lockres (vol_lockres);
@@ -421,6 +464,8 @@
ocfs_safefree (free_ext_node);
ocfs_safefree (dirnode_lockres);
ocfs_safefree (extnode_lockres);
+ ocfs_safefree (dirnode_inode);
+ ocfs_safefree (extnode_inode);
ocfs_safefree (free_vol_bits);
@@ -2703,10 +2748,10 @@
*
* Returns 0 on success, < 0 on error.
*
- * Pass in 'lock_bh' only if you've already taken the vol_alloc
- * semaphore, and you've done the acquire_lock on the bitmap.
+ * Pass in 'lock_bh' and bitmap_inode only if you've already taken the
+ * vol_alloc semaphore, and you've done the acquire_lock on the bitmap.
*/
-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_find_contiguous_space_from_bitmap (ocfs_super * osb, __u64 file_size, __u64 * cluster_off, __u64 * cluster_count, bool sysfile, struct buffer_head *lock_bh, struct inode *bitmap_inode)
{
int status = 0, tmpstat, startbh, numblocks;
__u32 bitoffset = 0, ClusterCount = 0;
@@ -2720,6 +2765,7 @@
ocfs_bitmap_lock *bm_lock = NULL;
__u32 bitmapblocks; /* we only care about the valid blocks */
bool local_lock = true;
+ bool local_inode = false;
LOG_ENTRY ();
@@ -2728,15 +2774,24 @@
if (lock_bh) {
local_lock = false;
bh = lock_bh;
+ } else /* local lock */
+ ocfs_down_sem (&(osb->vol_alloc_lock), true);
+
+ if (!bitmap_inode) {
+ bitmap_inode = ocfs_iget(osb, OCFS_BITMAP_LOCK_OFFSET, 0, NULL);
+ if (!bitmap_inode) {
+ status = -EINVAL;
+ LOG_ERROR_STR("Could not get bitmap inode!");
+ goto leave;
+ }
+ local_inode = true;
}
if (local_lock) {
- ocfs_down_sem (&(osb->vol_alloc_lock), true);
-
/* Get the allocation lock here */
status = ocfs_acquire_lock (osb, OCFS_BITMAP_LOCK_OFFSET,
OCFS_DLM_EXCLUSIVE_LOCK, 0,
- &lockres, &bh, NULL);
+ &lockres, &bh, bitmap_inode);
if (status < 0) {
if (status != -EINTR)
LOG_ERROR_STATUS (status);
@@ -2878,7 +2933,7 @@
OCFS_BITMAP_LOCK_OFFSET,
OCFS_DLM_EXCLUSIVE_LOCK,
0, lockres, bh,
- NULL);
+ bitmap_inode);
if (tmpstat < 0)
LOG_ERROR_STATUS (tmpstat);
}
@@ -2887,6 +2942,9 @@
ocfs_put_lockres (lockres);
}
+ if (local_inode)
+ iput(bitmap_inode);
+
LOG_EXIT_STATUS (status);
return status;
} /* ocfs_find_contiguous_space_from_bitmap */
@@ -2921,6 +2979,7 @@
ocfs_file_entry *fe = NULL;
bool needs_uninit = false;
bool delay_lockrel = false;
+ struct inode *inode = NULL; /* alloc bitmap file inode */
LOG_ENTRY_ARGS("(FileSize = (%llu), Type=%d)\n", FileSize,Type);
@@ -2943,10 +3002,16 @@
OCFS_ASSERT (blockSize);
lockId = (bm_file * OCFS_SECTOR_SIZE) + osb->vol_layout.root_int_off;
+ inode = ocfs_iget(osb, lockId, lockId, NULL);
+ if (!inode) {
+ status = -EINVAL;
+ LOG_ERROR_STATUS(status);
+ goto leave;
+ }
/* Get a lock on the file */
status = ocfs_acquire_lock (osb, lockId, OCFS_DLM_EXCLUSIVE_LOCK,
- FLAG_FILE_CREATE, &lockres, &bh, NULL);
+ FLAG_FILE_CREATE, &lockres, &bh, inode);
if (status < 0) {
LOG_ERROR_STATUS (status);
goto leave;
@@ -3110,16 +3175,19 @@
if (bLockAcquired && delay_lockrel) {
ocfs_journal_add_lock(handle, OCFS_DLM_EXCLUSIVE_LOCK,
FLAG_FILE_CREATE,
- lockres, bh, NULL);
+ lockres, bh, inode);
tmpstat = 0;
} else if (bLockAcquired) {
tmpstat =
ocfs_release_lock (osb, lockId, OCFS_DLM_EXCLUSIVE_LOCK,
- FLAG_FILE_CREATE, lockres, bh, NULL);
+ FLAG_FILE_CREATE, lockres, bh, inode);
ocfs_put_lockres (lockres);
}
+ if (inode)
+ iput(inode);
+
if (tmpstat < 0)
status = tmpstat;
if (bh != NULL)
@@ -3383,6 +3451,7 @@
ocfs_bitmap_free_head **f,
struct buffer_head *local_alloc_bh,
struct buffer_head *bm_lock_bh,
+ struct inode *bm_inode,
bool in_recovery)
{
int status = 0, tmpstat;
@@ -3393,6 +3462,7 @@
ocfs_local_alloc *alloc = NULL;
bool local_lock = true;
void *bitmap;
+ struct inode *local_inode = NULL;
LOG_ENTRY();
@@ -3411,6 +3481,18 @@
local_lock = false;
bh = bm_lock_bh;
}
+
+ if (bm_inode) {
+ atomic_inc(&bm_inode->i_count);
+ local_inode = bm_inode;
+ } else {
+ local_inode = ocfs_iget(osb, OCFS_BITMAP_LOCK_OFFSET, 0, NULL);
+ if (!local_inode) {
+ status = -EINVAL;
+ LOG_ERROR_STATUS(status);
+ goto bail;
+ }
+ }
if (local_lock) {
ocfs_down_sem (&(osb->vol_alloc_lock), true);
@@ -3420,7 +3502,7 @@
OCFS_DLM_EXCLUSIVE_LOCK,
(in_recovery) ? FLAG_FILE_RECOVERY
: 0,
- &lockres, &bh, NULL);
+ &lockres, &bh, local_inode);
if (status < 0) {
if (status != -EINTR)
LOG_ERROR_STATUS (status);
@@ -3486,7 +3568,8 @@
tmpstat = ocfs_release_lock (osb,
OCFS_BITMAP_LOCK_OFFSET,
OCFS_DLM_EXCLUSIVE_LOCK,
- 0, lockres, bh, NULL);
+ 0, lockres, bh,
+ local_inode);
if (tmpstat < 0)
LOG_ERROR_STATUS (tmpstat);
ocfs_put_lockres (lockres);
@@ -3495,6 +3578,9 @@
brelse(bh);
}
+ if (local_inode)
+ iput(local_inode);
+
LOG_EXIT_STATUS(status);
return(status);
} /* ocfs_sync_local_to_main */
@@ -3505,6 +3591,7 @@
* pass it the bitmap lock in lock_bh if you have it.
*/
static int ocfs_alloc_new_window(ocfs_super *osb, struct buffer_head *lock_bh,
+ struct inode *bm_inode,
ocfs_journal_handle *handle)
{
int status = 0;
@@ -3529,7 +3616,7 @@
status = ocfs_find_contiguous_space_from_bitmap(osb, alloc_bytes,
&cluster_off,
&cluster_count, false,
- lock_bh);
+ lock_bh, bm_inode);
if (status < 0) {
LOG_ERROR_STATUS(status);
goto bail;
@@ -3642,6 +3729,7 @@
__u32 tmpwanted;
/* main bitmap variables. */
struct buffer_head *main_bm_bh = NULL;
+ struct inode *main_bm_inode = NULL;
ocfs_lock_res *lockres = NULL;
void *bitmap;
@@ -3671,7 +3759,8 @@
alloc = NULL;
LOG_TRACE_STR("Allocating a new window...");
- status = ocfs_alloc_new_window(osb, main_bm_bh, handle);
+ status = ocfs_alloc_new_window(osb, main_bm_bh, main_bm_inode,
+ handle);
if (status < 0) {
if (status == -ENOSPC) {
/* TODO: Remove this printk */
@@ -3713,10 +3802,22 @@
/* lock bitmap here */
ocfs_down_sem (&(osb->vol_alloc_lock), true);
+ if (!main_bm_inode)
+ main_bm_inode = ocfs_iget(osb, OCFS_BITMAP_LOCK_OFFSET,
+ 0, NULL);
+
+ if (!main_bm_inode) {
+ ocfs_up_sem (&(osb->vol_alloc_lock));
+ status = -EINVAL;
+ LOG_ERROR_STATUS (status);
+ goto bail;
+ }
+
/* Get the allocation lock here */
status = ocfs_acquire_lock (osb, OCFS_BITMAP_LOCK_OFFSET,
OCFS_DLM_EXCLUSIVE_LOCK, 0,
- &lockres, &main_bm_bh, NULL);
+ &lockres, &main_bm_bh,
+ main_bm_inode);
if (status < 0) {
ocfs_up_sem (&(osb->vol_alloc_lock));
if (status != -EINTR)
@@ -3725,7 +3826,8 @@
}
status = ocfs_sync_local_to_main(osb, &(handle->commit_bits),
- NULL, main_bm_bh, false);
+ NULL, main_bm_bh,
+ main_bm_inode, false);
if (status < 0) {
LOG_ERROR_STATUS(status);
goto bail;
@@ -3782,7 +3884,8 @@
tmpstat = ocfs_release_lock (osb,
OCFS_BITMAP_LOCK_OFFSET,
OCFS_DLM_EXCLUSIVE_LOCK,
- 0, lockres, main_bm_bh, NULL);
+ 0, lockres, main_bm_bh,
+ main_bm_inode);
if (tmpstat < 0)
LOG_ERROR_STATUS (tmpstat);
ocfs_put_lockres (lockres);
@@ -3792,6 +3895,9 @@
if (alloc && osb->local_alloc_bh)
OCFS_BH_PUT_DATA(osb->local_alloc_bh);
+ if (main_bm_inode)
+ iput(main_bm_inode);
+
LOG_EXIT_STATUS(status);
return(status);
} /* ocfs_find_space_from_local */
@@ -3853,7 +3959,8 @@
status = ocfs_find_contiguous_space_from_bitmap(osb, file_size,
cluster_off,
cluster_count,
- sysfile, NULL);
+ sysfile, NULL,
+ NULL);
if (status < 0)
LOG_ERROR_STATUS(status);
@@ -3992,7 +4099,8 @@
else
bh = osb->local_alloc_bh;
- status = ocfs_sync_local_to_main(osb, &f, NULL, NULL, in_recovery);
+ status = ocfs_sync_local_to_main(osb, &f, NULL, NULL, NULL,
+ in_recovery);
if (status < 0)
LOG_ERROR_STATUS(status);
else if (f)
Modified: trunk/src/dlm.c
===================================================================
--- trunk/src/dlm.c 2004-04-28 00:11:13 UTC (rev 871)
+++ trunk/src/dlm.c 2004-04-28 01:37:04 UTC (rev 872)
@@ -1097,6 +1097,7 @@
OCFS_ASSERT(lock_type != OCFS_DLM_NO_LOCK);
OCFS_ASSERT(lock_type != OCFS_DLM_SHARED_LOCK);
+ OCFS_ASSERT(inode);
if (bh != NULL)
b = bh;
@@ -1497,6 +1498,8 @@
LOG_ENTRY_ARGS ("(0x%08x, %u.%u, %u, %u, 0x%08x)\n", osb, HI (lock_id),
LO (lock_id), lock_type, flags, lockres);
+ OCFS_ASSERT(inode);
+
flags |= FLAG_RELEASE_LOCK;
again:
Modified: trunk/src/hash.c
===================================================================
--- trunk/src/hash.c 2004-04-28 00:11:13 UTC (rev 871)
+++ trunk/src/hash.c 2004-04-28 01:37:04 UTC (rev 872)
@@ -1271,7 +1271,7 @@
if (inum->i_inode) {
/* this log_error_args is mainly for debugging */
- if (atomic_read(&inum->i_inode->i_count) > 2)
+ if (atomic_read(&inum->i_inode->i_count) > 1)
LOG_ERROR_ARGS("inode (%lu) with i_count = %u "
"left in system, (voteoff = "
"%u.%u, fileoff = %u.%u)\n",
@@ -1742,131 +1742,3 @@
}
#endif
-/*
- * ocfs_get_inode_from_offset()
- *
- * 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 voteoff, __u64 feoff,
- struct buffer_head *fe_bh)
-{
- struct inode *inode = NULL;
- struct super_block *sb = osb->sb;
- ocfs_file_entry *fe;
- ocfs_find_inode_args args;
-
- LOG_ENTRY_ARGS("(voteoff = %u.%u, feoff = %u.%u, fe_bh = %p)\n",
- HILO(voteoff), HILO(feoff), fe_bh);
-
- /* 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(feoff));
-
- inode = osb->sb->s_root->d_inode;
-
- /* should we iget it or not? i suppose if you're in
- * here and you've asked for the root inode you don't
- * know what it is and will prolly iput it later... */
- if (inode) {
- if (ocfs_inc_icount(inode) < 0)
- BUG();
- }
- goto bail;
- }
-
- /* 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);
- } else {
- if ((voteoff == 0) || (feoff == 0)) {
- LOG_ERROR_STATUS(-EINVAL);
- goto bail;
- }
- }
-
- /* 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 < (OCFS_JOURNAL_FILE * osb->sect_size
- + osb->vol_layout.root_int_off)
- ||
- feoff >= ((OCFS_JOURNAL_FILE + 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 = 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, voteoff, feoff);
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
- inode = ocfs_iget (sb, &args);
-#else
- inode =
- iget4 (sb, args.ino,
- (find_inode_t) ocfs_find_inode,
- (void *) (&args));
-#endif
- if (inode == NULL) {
- LOG_ERROR_STR("access error");
- inode = NULL;
- goto bail;
- }
- if (is_bad_inode (inode)) {
- LOG_ERROR_STR("access error (bad inode)");
- iput (inode);
- inode = NULL;
- goto bail;
- }
- }
-
-bail:
- if (inode)
- LOG_TRACE_ARGS("returning inode with number %lu\n",
- inode->i_ino);
-
- LOG_EXIT_PTR(inode);
-
- return(inode);
-} /* ocfs_get_inode_from_offset */
-
-
Modified: trunk/src/inc/ocfs.h
===================================================================
--- trunk/src/inc/ocfs.h 2004-04-28 00:11:13 UTC (rev 871)
+++ trunk/src/inc/ocfs.h 2004-04-28 01:37:04 UTC (rev 872)
@@ -1758,6 +1758,10 @@
#define OCFS_INODE_JOURNAL 0x00000002
/* set on init_private, cleared on clear_inode */
#define OCFS_INODE_INITIALIZED 0x00000004
+/* is this a system file? */
+#define OCFS_INODE_SYSFILE 0x00000008
+/* only valid for system files. */
+#define OCFS_INODE_NOFE 0x00000010
#define GET_INODE_CLEAN_SEQ(i) (atomic_t *)(&(OCFS_I(i)->i_clean_buffer_seq))
@@ -2578,12 +2582,18 @@
typedef struct _ocfs_find_inode_args
{
- __u64 offset;
+ __u64 voteoff;
+ __u64 feoff;
struct buffer_head *fe_bh;
int skip_bind;
unsigned long ino;
+ __u32 flags;
}
ocfs_find_inode_args;
+
+#define OCFS_FIND_INODE_FLAG_SYSFILE 0x00000002
+#define OCFS_FIND_INODE_FLAG_NOFE 0x00000008
+
/* timeout structure taken from Ben's aio.c */
typedef struct _ocfs_timeout {
struct timer_list timer;
Modified: trunk/src/inc/proto.h
===================================================================
--- trunk/src/inc/proto.h 2004-04-28 00:11:13 UTC (rev 871)
+++ trunk/src/inc/proto.h 2004-04-28 01:37:04 UTC (rev 872)
@@ -32,7 +32,7 @@
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, __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_find_contiguous_space_from_bitmap (ocfs_super * osb, __u64 file_size, __u64 * cluster_off, __u64 * cluster_count, bool sysfile, struct buffer_head *lock_bh, struct inode *bitmap_inode);
int ocfs_alloc_node_block (ocfs_super * osb, __u64 FileSize, __u64 * DiskOffset, __u64 * file_off, __u32 NodeNum, __u32 Type, ocfs_journal_handle *handle);
int ocfs_free_directory_block (ocfs_super * osb, ocfs_file_entry * fe, ocfs_journal_handle *handle, struct inode *inode);
int ocfs_free_file_extents (ocfs_super * osb, struct buffer_head *fe_bh, ocfs_journal_handle *handle, struct inode *inode);
@@ -91,11 +91,10 @@
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_populate_inode (struct inode *inode, ocfs_file_entry *fe, umode_t mode, 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);
void ocfs_read_inode (struct inode *inode);
-struct inode * ocfs_iget(struct super_block *sb, ocfs_find_inode_args *args);
void ocfs_put_inode (struct inode *inode);
void ocfs_clear_inode (struct inode *inode);
int ocfs_block_symlink (struct inode *inode, const char *symname, int len);
@@ -308,9 +307,8 @@
__u64 oldoff,
__u64 newoff,
__u64 new_fe_off);
-struct inode *ocfs_get_inode_from_offset(ocfs_super *osb,
- __u64 voteoff, __u64 feoff,
- struct buffer_head *fe_bh);
+struct inode *ocfs_iget(ocfs_super *osb, __u64 voteoff, __u64 feoff,
+ struct buffer_head *fe_bh);
struct inode *ocfs_inode_hash_lookup(ocfs_super *osb,
__u64 voteoff,
bool reverse);
Modified: trunk/src/inode.c
===================================================================
--- trunk/src/inode.c 2004-04-28 00:11:13 UTC (rev 871)
+++ trunk/src/inode.c 2004-04-28 01:37:04 UTC (rev 872)
@@ -58,6 +58,10 @@
int ocfs_kvec_rw(struct file *filp, int rw, kvec_cb_t cb, size_t size, loff_t pos);
#endif /* AIO_ENABLED */
+static void __ocfs_read_inode2(struct inode *inode,
+ ocfs_find_inode_args *args);
+static void ocfs_read_inode_nofe(ocfs_super *osb, struct inode *inode,
+ __u64 voteoff);
static struct address_space_operations ocfs_aops = {
.readpage = ocfs_readpage,
@@ -124,7 +128,159 @@
follow_link: ocfs_follow_link
};
+/*
+ * ocfs_iget()
+ *
+ * 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.
+ * If AND ONLY IF the inode has no file entry (as in the main bitmap),
+ * are you allowed to have feoff = 0.
+ *
+ * If you give me both, I'll prefer fe_bh.
+ */
+struct inode *ocfs_iget(ocfs_super *osb, __u64 voteoff, __u64 feoff,
+ struct buffer_head *fe_bh)
+{
+ struct inode *inode = NULL;
+ struct super_block *sb = osb->sb;
+ ocfs_file_entry *fe;
+ ocfs_find_inode_args args;
+ __u32 flags = 0;
+ LOG_ENTRY_ARGS("(voteoff = %u.%u, feoff = %u.%u, fe_bh = %p)\n",
+ HILO(voteoff), HILO(feoff), fe_bh);
+
+ /* 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(feoff));
+
+ inode = osb->sb->s_root->d_inode;
+
+ /* should we iget it or not? i suppose if you're in
+ * here and you've asked for the root inode you don't
+ * know what it is and will prolly iput it later... */
+ if (inode) {
+ if (ocfs_inc_icount(inode) < 0)
+ BUG();
+ }
+ goto bail;
+ }
+
+ /* This shouldn't happen anymore. */
+ if (osb->vol_layout.root_start_off == 0) {
+ LOG_ERROR_ARGS("root_start_off = 0! Skipping inode create for "
+ "%u.%u, %u.%u\n", HILO(voteoff), HILO(feoff));
+ goto bail;
+ }
+
+ /* 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);
+ }
+
+ /* Ok. By now we've either got the offsets passed to us by the
+ * caller, or we just pulled them off the bh. Lets do some
+ * sanity checks to make sure they're OK. */
+ if (voteoff == 0) {
+ LOG_ERROR_STATUS(-EINVAL);
+ goto bail;
+ }
+
+ /* feoff = 0 is only valid for root inode and other system files. */
+ if ((feoff == 0) && (voteoff > osb->vol_layout.root_start_off)) {
+ LOG_ERROR_STATUS(-EINVAL);
+ goto bail;
+ }
+
+ /* try to detect whether this is a system file. */
+ if (feoff < osb->vol_layout.root_start_off) {
+ flags |= OCFS_FIND_INODE_FLAG_SYSFILE;
+
+ /* We're not done yet. Some sysfiles (ok, currently
+ * only the main bitmap sysfile) don't have a file
+ * entry. Figure out whether we're one of those. */
+ if (voteoff == OCFS_BITMAP_LOCK_OFFSET)
+ flags |= OCFS_FIND_INODE_FLAG_NOFE;
+ }
+
+ 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.feoff = feoff;
+ args.voteoff = voteoff;
+ args.fe_bh = fe_bh;
+ args.skip_bind = 0;
+ args.flags = flags;
+
+ /* 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, voteoff, feoff);
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
+ inode = iget5_locked (sb, args->ino, ocfs_find_actor,
+ ocfs_init_locked_inode, args);
+#else
+ inode =
+ iget4 (sb, args.ino,
+ (find_inode_t) ocfs_find_inode,
+ (void *) (&args));
+#endif
+ if (inode == NULL) {
+ LOG_ERROR_STR("access error");
+ inode = NULL;
+ goto bail;
+ }
+ if (is_bad_inode (inode)) {
+ LOG_ERROR_STR("access error (bad inode)");
+ iput (inode);
+ inode = NULL;
+ goto bail;
+ }
+ }
+
+bail:
+ if (inode) {
+ LOG_TRACE_ARGS("returning inode with number %lu\n",
+ inode->i_ino);
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
+ /* inode was *not* in the inode cache. 2.6.x requires
+ * us to do our own read_inode call and unlock it
+ * afterwards. */
+ if (inode->i_state & I_NEW) {
+ LOG_TRACE_STR("Inode was not in inode cache, reading "
+ "it.");
+ ocfs_read_locked_inode(inode, args);
+ unlock_new_inode(inode);
+ }
+#endif
+ }
+
+ LOG_EXIT_PTR(inode);
+
+ return(inode);
+} /* ocfs_iget */
+
/*
* here's how inodes get read from disk:
* iget4 -> find_inode -> OCFS_FIND_INODE
@@ -157,7 +313,8 @@
if (ino != inode->i_ino)
goto bail;
- if (GET_INODE_FEOFF(inode) != args->offset) {
+ if ((GET_INODE_FEOFF(inode) != args->feoff)
+ || (GET_INODE_VOTEOFF(inode) != args->feoff)) {
LOG_ERROR_STATUS(-EINVAL);
goto bail;
}
@@ -189,15 +346,10 @@
return -ENOMEM;
i = (ocfs_inode_private *) inode->u.generic_ip;
-
memset(i, 0, sizeof(ocfs_inode_private));
i->flags = 0;
atomic_set(&i->i_clean_buffer_seq, 0);
-
- /* Init old OIN stuff. */
-// oin->obj_id.type = OCFS_TYPE_OIN;
-// oin->obj_id.size = sizeof (ocfs_inode);
ocfs_init_sem (&(i->main_res));
init_MUTEX(&(i->inode_extend_sem));
i->open_hndl_cnt = 0;
@@ -217,7 +369,7 @@
* ocfs_populate_inode()
*
*/
-void ocfs_populate_inode (struct inode *inode, ocfs_file_entry *fe, umode_t mode, void *genptr, bool create_ino)
+void ocfs_populate_inode (struct inode *inode, ocfs_file_entry *fe, umode_t mode, bool create_ino)
{
struct super_block *sb;
ocfs_super *osb;
@@ -314,143 +466,135 @@
*/
void ocfs_read_locked_inode (struct inode *inode, ocfs_find_inode_args *args)
{
- struct super_block *sb;
- ocfs_super *osb;
- umode_t mode;
- __u64 voteoff;
- ocfs_file_entry *fe = NULL;
- struct buffer_head *bh = NULL;
- int status;
+ __ocfs_read_inode2(inode, args);
+ return;
+} /* ocfs_read_locked_inode */
- LOG_ENTRY_ARGS ("(%p, %p)\n", inode, args);
+#else
- if (inode == NULL || inode->i_sb == NULL) {
- LOG_ERROR_STR ("bad inode");
- goto bail;
- }
- sb = inode->i_sb;
- osb = ((ocfs_super *)(sb->s_fs_info));
- 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);
- 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;
- }
+/*
+ * ocfs_read_inode2()
+ *
+ * by this point, i_sb, i_dev, i_ino are filled in
+ *
+ */
+void ocfs_read_inode2 (struct inode *inode, void *opaque)
+{
+ __ocfs_read_inode2(inode, (ocfs_find_inode_args *) opaque);
+ return;
+} /* ocfs_read_inode2 */
- inode->i_mode = S_IFDIR | osb->vol_layout.prot_bits;
- inode->i_blksize = 512; /* TODO: fix */
- inode->i_blkbits = 9;
- inode->i_blocks = 0;
- inode->i_mapping->a_ops = &ocfs_aops;
- inode->i_atime = CURRENT_TIME;
- inode->i_mtime = CURRENT_TIME;
- inode->i_ctime = CURRENT_TIME;
- inode->i_flags |= S_NOATIME;
- inode->i_op = &ocfs_dir_iops;
- inode->i_fop = &ocfs_dops;
- inode->i_uid = osb->vol_layout.uid;
- inode->i_gid = osb->vol_layout.gid;
- SET_INODE_VOTEOFF(inode, osb->vol_layout.root_start_off);
- SET_INODE_FEOFF(inode, 0);
+/*
+ * ocfs_read_inode()
+ * Only used in Linux 2.4
+ */
+void ocfs_read_inode (struct inode *inode)
+{
+ make_bad_inode (inode);
+} /* ocfs_read_inode() */
+#endif
- OCFS_I(inode)->alloc_size = 0ULL;
- OCFS_I(inode)->inode = inode;
- OCFS_I(inode)->chng_seq_num = 0ULL;
- OCFS_I(inode)->oin_flags |= OCFS_OIN_DIRECTORY;
+/* ocfs_read_inode_nofe()
+ *
+ * This function is ugly. Because we haven't got any file entries to
+ * look at, we have to special case every single offset.
+ *
+ * Right now, the only inodes this function knows about are:
+ * - root inode
+ * - volume bitmap inode
+ */
+static void ocfs_read_inode_nofe(ocfs_super *osb, struct inode *inode,
+ __u64 voteoff)
+{
+ LOG_ENTRY();
- ocfs_inode_hash_bind(osb, GET_INODE_VOTEOFF(inode), inode);
- goto bail;
+ /* add other offsets to this 'if' as needed. */
+ if (voteoff != OCFS_BITMAP_LOCK_OFFSET
+ && voteoff != osb->vol_layout.root_start_off) {
+ printk("ocfs2: yowzah! Asked to create an inode for offset"
+ "%u.%u, but I haven't yet learned what to do!\n",
+ HILO(voteoff));
+
+ BUG();
}
- LOG_TRACE_ARGS("Populating non-root inode (i_ino = %lu)\n", inode->i_ino);
-
- if (!args) {
- make_bad_inode (inode);
+ 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;
}
- /* 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;
+ /* Initialize common fields, then do the specific ones below. */
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
+ /* why is this different from 2.4!?!*/
+ inode->i_blksize = 512;
+ inode->i_blkbits = 9;
+#else
+ inode->i_blksize = (__u32) osb->vol_layout.cluster_size;
+ inode->i_attr_flags |= ATTR_FLAG_NOATIME;
+#endif
+ inode->i_mapping->a_ops = &ocfs_aops;
+ inode->i_atime = CURRENT_TIME;
+ inode->i_mtime = CURRENT_TIME;
+ inode->i_ctime = CURRENT_TIME;
+ inode->i_flags |= S_NOATIME;
+ inode->i_uid = osb->vol_layout.uid;
+ inode->i_gid = osb->vol_layout.gid;
+ SET_INODE_FEOFF(inode, 0);
- fe = (ocfs_file_entry *) OCFS_BH_GET_DATA_READ(bh);
-
- mode = fe->prot_bits;
- switch (fe->attribs) {
- case OCFS_ATTRIB_DIRECTORY:
- mode |= S_IFDIR;
- break;
- case OCFS_ATTRIB_CHAR:
- inode->i_rdev = MKDEV (fe->dev_major, fe->dev_minor);
- mode |= S_IFCHR;
- break;
- case OCFS_ATTRIB_BLOCK:
- inode->i_rdev = MKDEV (fe->dev_major, fe->dev_minor);
- mode |= S_IFBLK;
- 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;
- }
- ocfs_populate_inode (inode, fe, mode, NULL, false);
+ OCFS_I(inode)->inode = inode;
+ OCFS_I(inode)->chng_seq_num = 0ULL;
- voteoff = S_ISDIR (mode) ? fe->extents[0].disk_off : fe->this_sector;
- if (!args->skip_bind)
- ocfs_inode_hash_bind(osb, voteoff, inode);
+ OCFS_SET_FLAG(OCFS_I(inode)->flags, OCFS_INODE_NOFE);
-bail:
- if (fe)
- OCFS_BH_PUT_DATA(bh);
+ if (inode->i_ino == OCFS_ROOT_INODE_NUMBER) {
+ inode->i_mode = S_IFDIR | osb->vol_layout.prot_bits;
- if (args && !args->fe_bh && bh)
- brelse(bh);
+ inode->i_op = &ocfs_dir_iops;
+ inode->i_fop = &ocfs_dops;
+ OCFS_I(inode)->oin_flags |= OCFS_OIN_DIRECTORY;
+ OCFS_I(inode)->alloc_size = 0ULL;
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
+ inode->i_blocks = 0;
+#else
+ inode->i_blocks = OCFS_DEFAULT_DIR_NODE_SIZE;
+ inode->i_size = OCFS_DEFAULT_DIR_NODE_SIZE;
+#endif
+ SET_INODE_VOTEOFF(inode, osb->vol_layout.root_start_off);
+ } else /* volume bitmap inode */ {
+ inode->i_mode = S_IFREG | osb->vol_layout.prot_bits;
- LOG_EXIT ();
+ /* i_op and f_op should prolly be something a bit more
+ * appropriate. */
+ inode->i_op = &ocfs_file_iops;
+ inode->i_fop = &ocfs_fops;
+ OCFS_I(inode)->oin_flags = 0;
+ OCFS_I(inode)->alloc_size = ONE_MEGA_BYTE;
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
+ inode->i_blocks = 0;
+#else
+ inode->i_blocks = ONE_MEGA_BYTE / OCFS_BITMAP_CHUNK;
+ inode->i_size = ONE_MEGA_BYTE;
+#endif
+ SET_INODE_VOTEOFF(inode, OCFS_BITMAP_LOCK_OFFSET);
+ }
+
+bail:
+ LOG_EXIT();
return;
-} /* ocfs_read_locked_inode */
+}
-#else
-
-/*
- * ocfs_read_inode2()
- *
- * by this point, i_sb, i_dev, i_ino are filled in
- *
- */
-void ocfs_read_inode2 (struct inode *inode, void *opaque)
+static void __ocfs_read_inode2(struct inode *inode, ocfs_find_inode_args *args)
{
struct super_block *sb;
- ocfs_find_inode_args *args = NULL;
ocfs_super *osb;
umode_t mode;
+ __u64 voteoff;
ocfs_file_entry *fe = NULL;
- __u64 voteoff;
struct buffer_head *bh = NULL;
int status;
- LOG_ENTRY_ARGS ("(0x%08x, 0x%08x)\n", inode, opaque);
+ LOG_ENTRY_ARGS ("(0x%08x, 0x%08x)\n", inode, args);
if (inode == NULL || inode->i_sb == NULL) {
LOG_ERROR_STR ("bad inode");
@@ -459,53 +603,35 @@
sb = inode->i_sb;
osb = (ocfs_super *) OCFS_GENERIC_SB_P(sb);
if (inode->i_ino == OCFS_ROOT_INODE_NUMBER) {
- 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;
- }
+ ocfs_read_inode_nofe(osb, inode,
+ osb->vol_layout.root_start_off);
- inode->i_mode = S_IFDIR | osb->vol_layout.prot_bits;
- inode->i_blksize = (__u32) osb->vol_layout.cluster_size;
- inode->i_size = OCFS_DEFAULT_DIR_NODE_SIZE;
- inode->i_blocks = OCFS_DEFAULT_DIR_NODE_SIZE;
- inode->i_mapping->a_ops = &ocfs_aops;
- inode->i_atime = OCFS_CURRENT_TIME;
- inode->i_attr_flags |= ATTR_FLAG_NOATIME;
- inode->i_flags |= S_NOATIME;
- inode->i_mtime = OCFS_CURRENT_TIME;
- inode->i_ctime = OCFS_CURRENT_TIME;
- inode->i_attr_flags |= ATTR_FLAG_NOATIME;
- inode->i_flags |= S_NOATIME;
- inode->i_op = &ocfs_dir_iops;
- inode->i_fop = &ocfs_dops;
- inode->i_uid = osb->vol_layout.uid;
- inode->i_gid = osb->vol_layout.gid;
- SET_INODE_VOTEOFF(inode, osb->vol_layout.root_start_off);
- SET_INODE_FEOFF(inode, 0);
+ /* should I set the sysfile flag or not? */
+ OCFS_SET_FLAG(OCFS_I(inode)->flags, OCFS_INODE_SYSFILE);
- OCFS_I(inode)->alloc_size = 0ULL;
- OCFS_I(inode)->inode = inode;
- OCFS_I(inode)->chng_seq_num = 0ULL;
- OCFS_I(inode)->oin_flags |= OCFS_OIN_DIRECTORY;
-
ocfs_inode_hash_bind(osb, GET_INODE_VOTEOFF(inode), inode);
goto bail;
}
- if (opaque == NULL) {
+ if (!args) {
+ LOG_ERROR_STR("bad inode args");
make_bad_inode (inode);
goto bail;
}
- args = (ocfs_find_inode_args *) opaque;
+ voteoff = args->voteoff;
+ if (args->flags & OCFS_FIND_INODE_FLAG_NOFE) {
+ ocfs_read_inode_nofe(osb, inode, args->voteoff);
+ goto skip_fe;
+ }
+
/* 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);
+ status = ocfs_read_bh(osb, args->feoff, &bh, 0, NULL);
if (status < 0) {
LOG_ERROR_STATUS(status);
make_bad_inode (inode);
@@ -544,9 +670,17 @@
mode |= S_IFREG;
break;
}
- ocfs_populate_inode (inode, fe, mode, NULL, false);
+ ocfs_populate_inode (inode, fe, mode, false);
voteoff = S_ISDIR (mode) ? fe->extents[0].disk_off : fe->this_sector;
+
+ if (voteoff != args->voteoff)
+ BUG();
+
+skip_fe:
+ if (args->flags & OCFS_FIND_INODE_FLAG_SYSFILE)
+ OCFS_SET_FLAG(OCFS_I(inode)->flags, OCFS_INODE_SYSFILE);
+
if (!args->skip_bind)
ocfs_inode_hash_bind(osb, voteoff, inode);
@@ -559,18 +693,8 @@
LOG_EXIT ();
return;
-} /* ocfs_read_inode2 */
+}
-/*
- * ocfs_read_inode()
- * Only used in Linux 2.4
- */
-void ocfs_read_inode (struct inode *inode)
-{
- make_bad_inode (inode);
-} /* ocfs_read_inode() */
-#endif
-
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
/*
* here's how inodes get read from disk:
@@ -603,7 +727,8 @@
goto bail;
args = (ocfs_find_inode_args *) opaque;
- if (GET_INODE_FEOFF(inode) != args->offset) {
+ if ((GET_INODE_FEOFF(inode) != args->feoff)
+ || (GET_INODE_VOTEOFF(inode) != args->voteoff)) {
LOG_ERROR_STATUS(-EINVAL);
goto bail;
}
@@ -642,51 +767,6 @@
return(ret);
}
-/*
- * ocfs_iget()
- *
- * expects sb and args to be already filled out.
- * specifically, need fe->extents[0].disk_off, args->offset
- * if we're called from ocfs_fill_super, args == NULL
- */
-struct inode * ocfs_iget(struct super_block *sb, ocfs_find_inode_args *args)
-{
- struct inode *inode = NULL;
-
- LOG_ENTRY();
-
- if (!sb)
- goto bail;
-
- /* if args == NULL, we want the root inode */
- if (!args) {
- LOG_TRACE_STR("looking for root inode");
- inode = iget5_locked(sb, OCFS_ROOT_INODE_NUMBER,
- ocfs_find_actor, ocfs_init_locked_inode,
- NULL);
- } else {
- LOG_TRACE_STR("looking for non-root inode");
- /* Need to verify that ocfs_find_inode does the right thing,
- * and need to actually write ocfs_init_inode */
- inode = iget5_locked(sb, args->ino, ocfs_find_actor,
- ocfs_init_locked_inode, args);
- }
-
- if (!inode)
- goto bail;
-
- /* inode was *not* in the inode cache */
- if (inode->i_state & I_NEW) {
- LOG_TRACE_STR("Inode was not in inode cache, reading it.");
- ocfs_read_locked_inode(inode, args);
- unlock_new_inode(inode);
- }
-
-bail:
- LOG_EXIT_PTR(inode);
- return(inode);
-}
-
#endif /* 2.6 kernel stuff */
Modified: trunk/src/journal.c
===================================================================
--- trunk/src/journal.c 2004-04-28 00:11:13 UTC (rev 871)
+++ trunk/src/journal.c 2004-04-28 01:37:04 UTC (rev 872)
@@ -847,7 +847,7 @@
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);
+ inode = ocfs_iget(osb, lock_id, lock_id, NULL);
if (inode == NULL) {
LOG_ERROR_STR("access error");
status = -EACCES;
@@ -1026,7 +1026,7 @@
status = ocfs_release_lock (osb, journal->lock_id,
OCFS_DLM_EXCLUSIVE_LOCK,
FLAG_FILE_CREATE, journal->lock_res,
- journal->lockbh, NULL);
+ journal->lockbh, inode);
if (status < 0)
LOG_ERROR_STATUS (status);
@@ -1416,7 +1416,7 @@
+ 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);
+ inode = ocfs_iget(osb, lock_id, lock_id, NULL);
if (inode == NULL) {
LOG_ERROR_STR("access error");
status = -EACCES;
@@ -1529,9 +1529,6 @@
CLEAR_NODE_IN_RECOVERY(osb, node_num);
ocfs_recover_oin_locks(osb, node_num);
done:
- if (inode)
- iput(inode);
-
if (recovery_lock)
up(&(osb->recovery_lock));
@@ -1540,7 +1537,10 @@
status = ocfs_release_lock(osb, lock_id,
OCFS_DLM_EXCLUSIVE_LOCK,
FLAG_FILE_CREATE|FLAG_FILE_RECOVERY,
- lockres, bh, NULL);
+ lockres, bh, inode);
+ if (inode)
+ iput(inode);
+
if (bh)
brelse(bh);
Modified: trunk/src/namei.c
===================================================================
--- trunk/src/namei.c 2004-04-28 00:11:13 UTC (rev 871)
+++ trunk/src/namei.c 2004-04-28 01:37:04 UTC (rev 872)
@@ -65,15 +65,13 @@
#endif
{
int status;
- ocfs_find_inode_args args;
ocfs_file_entry *fe = NULL;
struct buffer_head *fe_bh = NULL;
- __u64 parentOffset, fe_off;
+ __u64 parentOffset;
struct inode *inode = NULL;
struct super_block *sb = dir->i_sb;
struct dentry *ret;
ocfs_super *osb = (ocfs_super *) OCFS_GENERIC_SB_P(sb);
- __u64 inode_off;
LOG_ENTRY_ARGS ("(0x%08x, 0x%08x, '%*s')\n", dir, dentry,
dentry->d_name.len, dentry->d_name.name);
@@ -99,47 +97,13 @@
parentOffset, dentry->d_name.len, dentry->d_name.name);
BUG();
}
-
- args.offset = fe->this_sector;
- args.fe_bh = fe_bh;
- args.skip_bind = 0;
- if (fe->attribs & OCFS_ATTRIB_DIRECTORY)
- inode_off = fe->extents[0].disk_off;
- else
- inode_off = fe->this_sector;
- fe_off = fe->this_sector;
OCFS_BH_PUT_DATA(fe_bh);
- fe = NULL;
- /* first, check if we've already got an inode in the hash. */
- inode = ocfs_inode_hash_lookup(osb, inode_off, false);
+ inode = ocfs_iget(osb, 0, 0, fe_bh);
if (!inode) {
- /* we should put this guy in the hash now... */
- LOG_TRACE_STR("calling iget4");
- /* 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, inode_off, fe_off);
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
- inode = ocfs_iget (sb, &args);
-#else
- inode =
- iget4 (sb, args.ino,
- (find_inode_t) ocfs_find_inode,
- (void *) (&args));
-#endif
- if (inode == NULL) {
- LOG_ERROR_STR("access error");
- ret = ERR_PTR (-EACCES);
- goto bail;
- }
- if (is_bad_inode (inode)) {
- LOG_ERROR_STR("access error (bad inode)");
- iput (inode);
- inode = NULL;
- ret = ERR_PTR (-EACCES);
- goto bail;
- }
+ LOG_ERROR_STR("Could not create inode!");
+ ret = ERR_PTR (-EACCES);
+ goto bail;
}
bail_add:
@@ -238,7 +202,7 @@
parent_off = GET_INODE_VOTEOFF(dir);
- ocfs_populate_inode (inode, fe, mode, NULL, true);
+ ocfs_populate_inode (inode, fe, mode, true);
insert_inode_hash (inode);
ocfs_inode_hash_bind(osb, GET_INODE_VOTEOFF(inode), inode);
@@ -1438,7 +1402,7 @@
inode->i_rdev = OCFS_NODEV;
fe = (ocfs_file_entry *) OCFS_BH_GET_DATA_READ(new_fe_bh); /* read */
- ocfs_populate_inode (inode, fe, S_IFLNK | S_IRWXUGO, NULL, true);
+ ocfs_populate_inode (inode, fe, S_IFLNK | S_IRWXUGO, true);
OCFS_BH_PUT_DATA(new_fe_bh);
fe = NULL;
Modified: trunk/src/nm.c
===================================================================
--- trunk/src/nm.c 2004-04-28 00:11:13 UTC (rev 871)
+++ trunk/src/nm.c 2004-04-28 01:37:04 UTC (rev 872)
@@ -809,7 +809,6 @@
__u32 node_num = ctxt->node_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);
@@ -848,7 +847,7 @@
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);
+ inode = ocfs_iget(osb, lock_id, fe_off, NULL);
if (inode) {
/* we only need i_sem for some of the operations
@@ -857,8 +856,6 @@
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);
@@ -894,8 +891,6 @@
(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
Modified: trunk/src/oin.c
===================================================================
--- trunk/src/oin.c 2004-04-28 00:11:13 UTC (rev 871)
+++ trunk/src/oin.c 2004-04-28 01:37:04 UTC (rev 872)
@@ -265,7 +265,6 @@
int status = 0;
ocfs_file_entry *fe = NULL;
bool local_handle = true;
- __u32 flags = 0;
LOG_ENTRY ();
@@ -282,8 +281,6 @@
OCFS_BH_PUT_DATA(fe_bh);
- flags |= OCFS_I(inode)->oin_flags;
-
if (inode->i_ino != OCFS_ROOT_INODE_NUMBER) {
if (local_handle) {
handle = ocfs_start_trans(osb, OCFS_OPEN_CREDITS);
@@ -297,7 +294,8 @@
}
status = ocfs_create_update_lock(osb, GET_INODE_VOTEOFF(inode),
- flags, false, inode, handle);
+ OCFS_I(inode)->oin_flags,
+ false, inode, handle);
if (status < 0) {
if (status != -EINTR)
LOG_ERROR_STATUS (status);
@@ -319,7 +317,7 @@
-/* ocfs_create_oin_from_entry()
+/* ocfs_inode_fill_ext_map()
*
*/
int ocfs_inode_fill_ext_map(ocfs_super * osb, struct buffer_head * fe_bh, struct inode *inode)
@@ -447,4 +445,4 @@
LOG_EXIT_STATUS (status);
return status;
-} /* ocfs_create_oin_from_entry */
+} /* ocfs_inode_fill_ext_map */
Modified: trunk/src/osb.c
===================================================================
--- trunk/src/osb.c 2004-04-28 00:11:13 UTC (rev 871)
+++ trunk/src/osb.c 2004-04-28 01:37:04 UTC (rev 872)
@@ -393,7 +393,6 @@
}
}
-skip_load:
/* 'mounted' flag in publish sector should not be set until
* after we successfully load the journal. */
status = ocfs_journal_set_mounted(osb, osb->node_num);
Modified: trunk/src/super.c
===================================================================
--- trunk/src/super.c 2004-04-28 00:11:13 UTC (rev 871)
+++ trunk/src/super.c 2004-04-28 01:37:04 UTC (rev 872)
@@ -142,6 +142,8 @@
static int ocfs_statfs (struct super_block *sb, struct statfs *buf);
#endif
+static int ocfs_init_system_inodes(ocfs_super *osb);
+
static struct super_operations ocfs_sops = {
.statfs = ocfs_statfs,
.put_inode = ocfs_put_inode,
@@ -178,6 +180,71 @@
}
/*
+ * ocfs_init_system_inodes()
+ */
+static int ocfs_init_system_inodes(ocfs_super *osb)
+{
+ struct inode *new = NULL;
+ __u64 sys_off = 0;
+ int status = 0;
+
+ LOG_ENTRY();
+
+ /* Why the iputs below? Because we get an extra reference
+ * which we don't need (the purpose of this function is to
+ * just get the system inodes in the inode hash. */
+
+ /* the vol bitmap */
+ sys_off = OCFS_BITMAP_LOCK_OFFSET;
+ new = ocfs_iget(osb, sys_off, 0, NULL);
+ if (!new) {
+ status = -EINVAL;
+ LOG_ERROR_STATUS(status);
+ goto bail;
+ }
+ iput(new);
+
+ /* file alloc bitmap */
+ sys_off = osb->vol_layout.root_int_off +
+ ((OCFS_FILE_FILE_ALLOC_BITMAP + osb->node_num)
+ * osb->sect_size);
+ new = ocfs_iget(osb, sys_off, sys_off, NULL);
+ if (!new) {
+ status = -EINVAL;
+ LOG_ERROR_STATUS(status);
+ goto bail;
+ }
+ iput(new);
+
+ /* dir alloc bitmap */
+ sys_off = osb->vol_layout.root_int_off +
+ ((OCFS_FILE_DIR_ALLOC_BITMAP + osb->node_num)
+ * osb->sect_size);
+ new = ocfs_iget(osb, sys_off, sys_off, NULL);
+ if (!new) {
+ status = -EINVAL;
+ LOG_ERROR_STATUS(status);
+ goto bail;
+ }
+ iput(new);
+
+ /* journal file */
+ sys_off = osb->vol_layout.root_int_off +
+ ((OCFS_JOURNAL_FILE + osb->node_num) * osb->sect_size);
+ new = ocfs_iget(osb, sys_off, sys_off, NULL);
+ if (!new) {
+ status = -EINVAL;
+ LOG_ERROR_STATUS(status);
+ goto bail;
+ }
+ iput(new);
+
+bail:
+ LOG_EXIT_STATUS(status);
+ return(status);
+} /* ocfs_init_system_inodes */
+
+/*
* __ocfs_read_super()
*
*/
@@ -240,6 +307,12 @@
sb->s_root = root;
+ status = ocfs_init_system_inodes(osb);
+ if (status < 0) {
+ LOG_ERROR_STATUS(status);
+ goto read_super_error;
+ }
+
printk ("ocfs2: Mounting device (%u,%u) on %s (node %d)\n",
MAJOR(sb->s_dev), MINOR(sb->s_dev),
osb->node_cfg_info[osb->node_num]->node_name, osb->node_num);
@@ -927,9 +1000,11 @@
up (&(osb->osb_res));
/* Initialize the root inode. */
+ /* We need a better way of getting our root inode during startup. */
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);
+ inode = iget5_locked(sb, OCFS_ROOT_INODE_NUMBER,
+ ocfs_find_actor, ocfs_init_locked_inode, NULL);
#else
inode = iget4(sb, OCFS_ROOT_INODE_NUMBER, 0, NULL);
#endif
@@ -945,6 +1020,14 @@
inode = NULL;
goto leave;
}
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
+ if (inode->i_state & I_NEW) {
+ ocfs_read_locked_inode(inode, NULL);
+ unlock_new_inode(inode);
+ }
+#endif
+
osb->root_inode = inode;
/* Read the publish sector for this node and cleanup dirent being */
Modified: trunk/src/sysfile.c
===================================================================
--- trunk/src/sysfile.c 2004-04-28 00:11:13 UTC (rev 871)
+++ trunk/src/sysfile.c 2004-04-28 01:37:04 UTC (rev 872)
@@ -312,7 +312,7 @@
FileSize - alloc_size,
&BitmapOffset,
&numClusterAlloc, true,
- NULL);
+ NULL, NULL);
if (status < 0) {
LOG_ERROR_STATUS (status);
goto leave;
More information about the Ocfs2-commits
mailing list