[Ocfs2-commits] mfasheh commits r1053 - in trunk/src: . inc
svn-commits at oss.oracle.com
svn-commits at oss.oracle.com
Fri Jun 11 17:07:07 CDT 2004
Author: mfasheh
Date: 2004-06-11 16:07:06 -0500 (Fri, 11 Jun 2004)
New Revision: 1053
Modified:
trunk/src/alloc.c
trunk/src/dir.c
trunk/src/dlm.c
trunk/src/file.c
trunk/src/inc/ocfs.h
trunk/src/inc/proto.h
trunk/src/inode.c
trunk/src/namei.c
trunk/src/nm.c
trunk/src/super.c
Log:
* First pass at orphaned inode directory. We now can do posix style
deletes, even from one node to another! The recovery process (in case
the whole cluster takes a nosedive, etc) still needs to be completed.
* performance improvement in ocfs_mknod_locked and ocfs_bread: don't
read a newly allocated block off disk as we're about to destroy
everything in it anyway.
* Fix a bug in ocfs_free_disk_bitmap.
Modified: trunk/src/alloc.c
===================================================================
--- trunk/src/alloc.c 2004-06-11 10:22:45 UTC (rev 1052)
+++ trunk/src/alloc.c 2004-06-11 21:07:06 UTC (rev 1053)
@@ -366,8 +366,6 @@
goto abort;
}
ocfs_ugly_hack(handle, globalbh);
- brelse(ugly_hack_bh);
- ugly_hack_bh = NULL;
}
Modified: trunk/src/dir.c
===================================================================
--- trunk/src/dir.c 2004-06-11 10:22:45 UTC (rev 1052)
+++ trunk/src/dir.c 2004-06-11 21:07:06 UTC (rev 1053)
@@ -170,7 +170,7 @@
/* ocfs_find_files_on_disk()
* NOTE: this should always be called with parent dir ip_io_sem taken!
*/
-int ocfs_find_files_on_disk (ocfs_super * osb, struct dentry * dentry, __u64 *fe_off, struct inode *inode, int take_lock, struct buffer_head **dirent_bh, struct ocfs2_dir_entry **dirent)
+int ocfs_find_files_on_disk (ocfs_super * osb, const char *name, int namelen, __u64 *fe_off, struct inode *inode, int take_lock, struct buffer_head **dirent_bh, struct ocfs2_dir_entry **dirent)
{
int status = -ENOENT;
int tmpstat;
@@ -178,9 +178,10 @@
struct buffer_head *bh = NULL;
__u32 lock_type = OCFS_DLM_ENABLE_CACHE_LOCK;
__u64 parent_off = GET_INODE_FEOFF(inode);
-
- LOG_ENTRY_ARGS ("(osb=%p, parent=%llu, dentry=%p, inode=%p)\n", osb, parent_off, dentry, inode);
+ LOG_ENTRY_ARGS ("(osb=%p, parent=%llu, name='%*s', fe_off=%p, inode=%p)\n",
+ osb, parent_off, namelen, name, fe_off, inode);
+
if (take_lock) {
/* Get a lock on the directory... */
status = ocfs_acquire_lock (osb, parent_off, lock_type, FLAG_DIR|FLAG_READDIR,
@@ -195,7 +196,7 @@
}
status = -ENOENT;
- *dirent_bh = ocfs_find_entry (dentry, dirent);
+ *dirent_bh = ocfs_find_entry (name, namelen, inode, dirent);
if (!*dirent_bh || !*dirent)
goto leave;
Modified: trunk/src/dlm.c
===================================================================
--- trunk/src/dlm.c 2004-06-11 10:22:45 UTC (rev 1052)
+++ trunk/src/dlm.c 2004-06-11 21:07:06 UTC (rev 1053)
@@ -634,8 +634,7 @@
/* no need to alert master for these cases */
if (S_ISDIR (inode->i_mode) ||
lockres->master_node_num == OCFS_INVALID_NODE_NUM ||
- (!(lockres->lock_state & FLAG_ALWAYS_UPDATE_OPEN) &&
- IS_NODE_ALIVE (lockres->oin_openmap, osb->node_num, OCFS_MAXIMUM_NODES))) {
+ IS_NODE_ALIVE (lockres->oin_openmap, osb->node_num, OCFS_MAXIMUM_NODES)) {
status = 0;
goto bail;
}
@@ -862,7 +861,8 @@
if (lockres->master_node_num != osb->node_num &&
(wait_on_recovery || no_owner || owner_dead)) {
extra_lock_flags = FLAG_REMASTER;
- } else if (flags & (FLAG_FILE_DELETE | FLAG_FILE_RENAME)) {
+ } else if (flags & (FLAG_FILE_DELETE | FLAG_FILE_RENAME
+ | FLAG_RELEASE_DENTRY)) {
if (ocfs_journal_new_file_search(osb, lock_id)!=0) {
extra_lock_flags = 0;
} else if (lockres->lock_type == OCFS_DLM_ENABLE_CACHE_LOCK)
@@ -1001,7 +1001,8 @@
/* Send an update to all nodes alive, can be optimized later TODO */
if ((flags & FLAG_FILE_RENAME) || (flags & FLAG_FILE_DELETE)
- || (flags & FLAG_FILE_TRUNCATE) || (flags & FLAG_FILE_EXTEND))
+ || (flags & FLAG_RELEASE_DENTRY) || (flags & FLAG_FILE_TRUNCATE)
+ || (flags & FLAG_FILE_EXTEND))
votemap = osb->publ_map;
/* TODO: figure out how to properly handle inode updates w/no oin */
@@ -1013,7 +1014,7 @@
if (votemap == 0ULL)
goto finally;
- if (!(flags & FLAG_FILE_UPDATE_OIN) && !(flags & FLAG_FILE_DELETE))
+ if (!(flags & FLAG_FILE_UPDATE_OIN))
goto finally;
status = -EAGAIN;
@@ -1163,7 +1164,7 @@
}
lockres->lock_type = OCFS_DLM_NO_LOCK;
- if (flags & (FLAG_FILE_DELETE | FLAG_FILE_RELEASE_MASTER))
+ if (flags & FLAG_FILE_RELEASE_MASTER)
lockres->master_node_num = OCFS_INVALID_NODE_NUM;
status = ocfs_disk_release_lock (osb, lock_id, lock_type, flags, bh, inode);
@@ -1271,7 +1272,8 @@
/* figure out who to vote with */
- if (flags & (FLAG_REMASTER | FLAG_FILE_DELETE | FLAG_FILE_RENAME))
+ if (flags & (FLAG_REMASTER | FLAG_FILE_DELETE | FLAG_FILE_RENAME
+ | FLAG_RELEASE_DENTRY))
vote_map = osb->publ_map; /* broadcast */
else if (flags & FLAG_DROP_READONLY) {
/* all nodes that see this is readonly */
Modified: trunk/src/file.c
===================================================================
--- trunk/src/file.c 2004-06-11 10:22:45 UTC (rev 1052)
+++ trunk/src/file.c 2004-06-11 21:07:06 UTC (rev 1053)
@@ -356,12 +356,6 @@
if (OCFS_I(inode)->oin_flags & OCFS_OIN_OPEN_FOR_DIRECTIO)
OCFS_CLEAR_FLAG(OCFS_I(inode)->oin_flags, OCFS_OIN_OPEN_FOR_DIRECTIO);
- if (OCFS_I(inode)->oin_flags & OCFS_OIN_NEEDS_DELETION) {
- up (&(OCFS_I(inode)->priv_sem));
- LOG_ERROR_STR("Not deleting lockrse on a last close! eek!");
- goto bail;
- }
-
/* we might still be holding inode_extend_sem on
* behalf of another node, so release it here. */
down(&recovery_list_sem);
@@ -642,7 +636,6 @@
/* Set the valid bit here */
SET_VALID_BIT (fileEntry->sync_flags);
- fileEntry->sync_flags &= ~(OCFS_SYNC_FLAG_CHANGE);
flags = OCFS_FE_CACHE_FLAGS(osb, fileEntry);
OCFS_BH_PUT_DATA(bh);
@@ -1033,7 +1026,6 @@
DISK_LOCK_SEQNUM (fe) = 0;
SET_VALID_BIT (fe->sync_flags);
- fe->sync_flags &= ~(OCFS_SYNC_FLAG_CHANGE);
fe->modify_time = OCFS_CURRENT_TIME;
flags = OCFS_FE_CACHE_FLAGS(osb, fe);
@@ -1270,7 +1262,6 @@
ocfs_fe_set_attributes(fileEntry, attr);
/* Set the Valid bit and reset the change bit here... TODO */
SET_VALID_BIT (fileEntry->sync_flags);
- fileEntry->sync_flags &= ~(OCFS_SYNC_FLAG_CHANGE);
fileEntry->modify_time = OCFS_CURRENT_TIME;
tempOffset = fileEntry->this_sector;
Modified: trunk/src/inc/ocfs.h
===================================================================
--- trunk/src/inc/ocfs.h 2004-06-11 10:22:45 UTC (rev 1052)
+++ trunk/src/inc/ocfs.h 2004-06-11 21:07:06 UTC (rev 1053)
@@ -162,8 +162,8 @@
enum {
INVALID_REQUEST, // reply with a NO vote
UPDATE_OIN_INODE, // update both oin and inode
- DELETE_RENAME_ACQUIRE,// delete or rename acquire request
- DELETE_RENAME_RELEASE,// delete or rename release request
+ DELETE_ACQUIRE,// delete or rename acquire request
+ DELETE_RELEASE,// delete or rename release request
RELEASE_CACHE, // release a cache lock I hold
CHANGE_MASTER, // request to change master to requestor
ADD_OIN_MAP, // add requestor into oin map
@@ -171,7 +171,8 @@
REMASTER_THIS, // remaster lock to me
REMASTER_REQUESTOR, // remaster lock to requestor
DROP_READONLY, // RO cachelock needs to convert to RW
- READONLY // a RW or RO cachelock, requesting RO
+ READONLY, // a RW or RO cachelock, requesting RO
+ RELEASE_DENTRY
};
#define OCFS_MAX_DLM_PKT_SIZE 256
@@ -259,7 +260,7 @@
#define FLAG_FILE_CREATE_DIR 0x00000040
#define FLAG_FILE_UPDATE_OIN 0x00000080
#define FLAG_FILE_RELEASE_MASTER 0x00000100
-#define FLAG_DROP_LINK 0x00000200
+#define FLAG_RELEASE_DENTRY 0x00000200
#define FLAG_CHANGE_MASTER 0x00000400
#define FLAG_ADD_OIN_MAP 0x00000800
#define FLAG_DIR 0x00001000
@@ -310,6 +311,7 @@
#define LOG_FILE_BASE_ID (OCFS_RECOVER_LOG_SYSFILE * OCFS_MAXIMUM_NODES) // unused in version 2
#define CLEANUP_FILE_BASE_ID (OCFS_CLEANUP_LOG_SYSFILE * OCFS_MAXIMUM_NODES) // unused in version 2
#define OCFS_LOCAL_ALLOC_FILE (OCFS_VOL_BM_SYSFILE * OCFS_MAXIMUM_NODES) // was OCFS_VOL_BITMAP_FILE
+#define OCFS_ORPHAN_DIR (OCFS_ORPHAN_DIR_SYSFILE * OCFS_MAXIMUM_NODES)
#define OCFS_JOURNAL_FILE (OCFS_JOURNAL_SYSFILE * OCFS_MAXIMUM_NODES)
#define OCFS_INODE_FILE (OCFS_INODE_SYSFILE * OCFS_MAXIMUM_NODES)
#define OCFS_INODE_BITMAP (OCFS_INODE_BM_SYSFILE * OCFS_MAXIMUM_NODES)
@@ -433,11 +435,11 @@
** File Entry contains this information
*/
// SYNCFLAG MASK
-#define OCFS_SYNC_FLAG_DELETED (0)
+#define OCFS_SYNC_FLAG_UNUSED1 (0)
#define OCFS_SYNC_FLAG_VALID (0x1)
-#define OCFS_SYNC_FLAG_CHANGE (0x2)
-#define OCFS_SYNC_FLAG_MARK_FOR_DELETION (0x4)
-#define OCFS_SYNC_FLAG_NAME_DELETED (0x8)
+#define OCFS_SYNC_FLAG_UNUSED2 (0x2)
+#define OCFS_SYNC_FLAG_ORPHANED (0x4)
+#define OCFS_SYNC_FLAG_UNUSED3 (0x8)
// ATTRIBS MASK
#define OCFS_ATTRIB_DIRECTORY (0x1)
@@ -1142,7 +1144,7 @@
__u32 used_bits;
__u32 total_bits;
} ip_bitinfo;
- } u;
+ } u;
ocfs_lock_res i_lockres;
__u32 i_dir_start_lookup;
@@ -1152,10 +1154,8 @@
* merged. */
/* oin_flags flags */
#define OCFS_OIN_DIRECTORY (0x00000002)
-#define OCFS_OIN_DELETE_ON_CLOSE (0x00000008)
-#define OCFS_OIN_NEEDS_DELETION (0x00000010)
-#define OCFS_OIN_OPEN_FOR_DIRECTIO (0x00000100)
-#define OCFS_OIN_OPEN_FOR_WRITE (0x00000200)
+#define OCFS_OIN_OPEN_FOR_DIRECTIO (0x00000008)
+#define OCFS_OIN_OPEN_FOR_WRITE (0x00000010)
/* 'flags' flags. */
/* has this inode been deleted, either from this node or from another node. */
@@ -1166,6 +1166,8 @@
#define OCFS_INODE_INITIALIZED 0x00000004
/* is this a system file? */
#define OCFS_INODE_SYSTEM_FILE 0x00000008
+/* are we going to let another node deal with deletion of this inode? */
+#define OCFS_INODE_SKIP_DELETE 0x00000010
#define GET_INODE_CLEAN_SEQ(i) (atomic_t *)(&(OCFS_I(i)->i_clean_buffer_seq))
@@ -1313,6 +1315,7 @@
FILE_ALLOC_BITMAP_SYSTEM_INODE,
INODE_ALLOC_BITMAP_SYSTEM_INODE,
JOURNAL_SYSTEM_INODE,
+ ORPHAN_DIR_SYSTEM_INODE,
NUM_SYSTEM_INODES
};
@@ -1406,6 +1409,7 @@
struct semaphore vote_sem; /* protects calls to ocfs_process_vote */
struct list_head vote_obj_queue;
spinlock_t vote_obj_queue_lock;
+ unsigned long voting_ino; /* only safe from the process_vote pid */
};
typedef struct _ocfs_comm_info
@@ -1574,6 +1578,7 @@
__u32 used_bits;
__u32 total_bits;
} bitinfo;
+ __u64 i_dtime;
} u;
__u64 alloc_file_off; // NUMBER RANGE(0,ULONG_LONG_MAX)
__u32 alloc_node; // NUMBER RANGE(0,31)
Modified: trunk/src/inc/proto.h
===================================================================
--- trunk/src/inc/proto.h 2004-06-11 10:22:45 UTC (rev 1052)
+++ trunk/src/inc/proto.h 2004-06-11 21:07:06 UTC (rev 1053)
@@ -101,10 +101,10 @@
/* dir.c */
int empty_dir(struct inode *inode); /* FIXME: to namei.c */
-int ocfs_find_files_on_disk(ocfs_super *osb, struct dentry *dentry,
- __u64 *fe_off, struct inode *inode,
- int take_lock, struct buffer_head **dirent_bh,
- struct ocfs2_dir_entry **dirent);
+int ocfs_find_files_on_disk (ocfs_super * osb, const char *name, int namelen,
+ __u64 *fe_off, struct inode *inode, int take_lock,
+ struct buffer_head **dirent_bh,
+ struct ocfs2_dir_entry **dirent);
int ocfs_readdir(struct file *filp, void *dirent, filldir_t filldir);
/* dlm.c */
@@ -225,6 +225,7 @@
struct buffer_head *ocfs_bread(ocfs_journal_handle *handle,
struct inode * inode, int block,
int create, int *err, int reada);
+void ocfs_delete_inode(struct inode *inode);
void ocfs_clear_inode(struct inode *inode);
struct inode *ocfs_iget(ocfs_super *osb, __u64 feoff);
int ocfs_inode_init_private(struct inode *inode);
@@ -265,8 +266,9 @@
#else
int ocfs_create (struct inode *dir, struct dentry *dentry, int mode);
#endif
-struct buffer_head *ocfs_find_entry(struct dentry *dentry,
- struct ocfs2_dir_entry **res_dir);
+struct buffer_head * ocfs_find_entry (const char *name, int namelen,
+ struct inode *dir,
+ struct ocfs2_dir_entry ** res_dir);
int ocfs_link(struct dentry *old_dentry, struct inode *dir,
struct dentry *dentry);
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
@@ -283,11 +285,10 @@
int ocfs_symlink(struct inode *dir, struct dentry *dentry,
const char *symname);
int ocfs_unlink(struct inode *dir, struct dentry *dentry);
+int ocfs_orphan_del(ocfs_super *osb, ocfs_journal_handle *handle,
+ struct inode *orphan_dir_inode, struct inode *inode,
+ struct buffer_head *orphan_dir_bh);
-/* FIXME: only in namei.c */
-int ocfs_orphan_add(ocfs_journal_handle *handle, struct inode *inode);
-int ocfs_orphan_del(ocfs_journal_handle *handle, struct inode *inode);
-
/* nm.c */
int ocfs_drop_readonly_cache_lock(ocfs_super *osb, struct inode *inode,
int yield);
Modified: trunk/src/inode.c
===================================================================
--- trunk/src/inode.c 2004-06-11 10:22:45 UTC (rev 1052)
+++ trunk/src/inode.c 2004-06-11 21:07:06 UTC (rev 1053)
@@ -641,6 +641,179 @@
}
/*
+ * ocfs_delete_inode()
+ *
+ */
+void ocfs_delete_inode(struct inode *inode)
+{
+ struct inode *orphan_dir_inode = NULL;
+ ocfs_journal_handle *handle = NULL;
+ ocfs_super *osb = OCFS_SB(inode->i_sb);
+ int status = 0;
+ int release_disk_lock = 0;
+ struct buffer_head *orphan_dir_bh = NULL;
+ struct buffer_head *fe_bh = NULL;
+ __u32 lock_flags = FLAG_FILE_DELETE;
+ ocfs_file_entry *fe;
+
+ LOG_ENTRY_ARGS("(inode->i_ino = %lu)\n", inode->i_ino);
+
+ if (OCFS_I(inode)->flags & OCFS_INODE_SYSTEM_FILE) {
+ LOG_TRACE_STR("Skipping system file delete.");
+ goto clear_inode;
+ }
+
+ if (inode->i_ino == OCFS_ROOT_INODE_NUMBER) {
+ LOG_TRACE_STR("Skipping root inode delete.");
+ goto clear_inode;
+ }
+
+ if (OCFS_I(inode)->flags & OCFS_INODE_SKIP_DELETE) {
+ LOG_TRACE_ARGS("Skipping delete of %lu because another node "
+ "has done this for us.\n", inode->i_ino);
+ goto clear_inode;
+ }
+
+ /* If we're coming from process_vote we can't go into our own
+ * voting [hello, deadlock city!], so unforuntately we just
+ * have to skip deleting this guy. That's OK though because
+ * the node who's doing the actual deleting should handle it
+ * anyway. */
+ if (osb->voting_ino == inode->i_ino) {
+ LOG_TRACE_ARGS("Skipping delete of %lu because we're currently"
+ "in process_vote\n", inode->i_ino);
+ goto clear_inode;
+ }
+
+ orphan_dir_inode = igrab(osb->system_inodes[ORPHAN_DIR_SYSTEM_INODE]);
+ if (!orphan_dir_inode) {
+ LOG_ERROR_STATUS(-EFAIL);
+ goto clear_inode;
+ }
+
+ lock_kernel();
+
+ /* Oop, lets be carefull of lock / trans ordering here... */
+ handle = ocfs_start_trans(osb, OCFS_FILE_DELETE_CREDITS);
+ if (handle == NULL) {
+ unlock_kernel();
+ LOG_ERROR_STATUS(-ENOMEM);
+ goto clear_inode;
+ }
+
+ ocfs_handle_add_inode(handle, orphan_dir_inode);
+
+ status = ocfs_acquire_lock(osb, GET_INODE_FEOFF(orphan_dir_inode),
+ OCFS_DLM_EXCLUSIVE_LOCK,
+ FLAG_FILE_CREATE | FLAG_DIR,
+ &orphan_dir_bh, orphan_dir_inode);
+ if (status < 0) {
+ LOG_ERROR_STATUS(status);
+ goto bail_locked;
+ }
+ ocfs_handle_add_lock(handle, OCFS_DLM_EXCLUSIVE_LOCK,
+ FLAG_FILE_CREATE | FLAG_DIR, orphan_dir_bh,
+ orphan_dir_inode, 1);
+
+ /* take ip_io_sem on the inode, only to avoid a warning in
+ * acquire_lockres. We can get rid of it when we get rid of
+ * acquire_lockres */
+ down(&OCFS_I(inode)->ip_io_sem);
+ if (S_ISDIR(inode->i_mode))
+ lock_flags |= FLAG_DIR;
+ status = ocfs_acquire_lock(osb, GET_INODE_FEOFF(inode),
+ OCFS_DLM_EXCLUSIVE_LOCK, lock_flags,
+ &fe_bh, inode);
+ up(&OCFS_I(inode)->ip_io_sem);
+ if (status < 0) {
+ /* EBUSY here is assumed to mean that other nodes are
+ * still using the inode. We're done here though, so
+ * avoid doing anything on disk and let them worry
+ * about deleting it. */
+ if (status != -EBUSY)
+ LOG_ERROR_STATUS(status);
+ goto bail_locked;
+ }
+ release_disk_lock = 1;
+
+ /* check OCFS_SYNC_FLAG_ORPHANED */
+ fe = OCFS_BH_GET_DATA_READ(fe_bh);
+ if (!(fe->sync_flags & OCFS_SYNC_FLAG_ORPHANED)) {
+ OCFS_BH_PUT_DATA(fe_bh);
+ /* for lack of a better error? */
+ status = -EEXIST;
+ LOG_ERROR_STATUS(status);
+ goto bail_locked;
+ }
+
+ /* has someone already deleted us?! baaad... */
+ if (fe->u.i_dtime) {
+ OCFS_BH_PUT_DATA(fe_bh);
+
+ status = -EEXIST;
+ LOG_ERROR_STATUS(status);
+ goto bail_locked;
+ }
+ OCFS_BH_PUT_DATA(fe_bh);
+
+ status = ocfs_orphan_del(osb, handle, orphan_dir_inode, inode,
+ orphan_dir_bh);
+
+ /* set the inodes dtime */
+ status = ocfs_journal_access(handle, fe_bh, OCFS_JOURNAL_ACCESS_WRITE);
+ if (status < 0) {
+ LOG_ERROR_STATUS(status);
+ goto bail_locked;
+ }
+
+ fe = OCFS_BH_GET_DATA_WRITE(fe_bh);
+ fe->u.i_dtime = CURRENT_TIME;
+ fe->sync_flags &= (~OCFS_SYNC_FLAG_VALID);
+ fe->sync_flags &= (~OCFS_SYNC_FLAG_ORPHANED);
+ OCFS_BH_PUT_DATA(fe_bh);
+
+ status = ocfs_journal_dirty(handle, fe_bh);
+ if (status < 0) {
+ LOG_ERROR_STATUS(status);
+ goto bail_locked;
+ }
+
+ /* actually delete the data and the inode */
+ status = ocfs_free_file_extents(osb, fe_bh, handle, inode);
+ if (status < 0)
+ LOG_ERROR_STATUS(status);
+
+bail_locked:
+ if (handle && (status == 0))
+ ocfs_commit_trans(handle);
+ else if (handle)
+ ocfs_abort_trans(handle);
+
+ if (release_disk_lock) {
+ down(&OCFS_I(inode)->ip_io_sem);
+ status = ocfs_release_lock(osb, GET_INODE_FEOFF(inode),
+ OCFS_DLM_EXCLUSIVE_LOCK, lock_flags,
+ fe_bh, inode);
+ up(&OCFS_I(inode)->ip_io_sem);
+ if (status < 0)
+ LOG_ERROR_STATUS(status);
+ }
+
+ unlock_kernel();
+
+ if (orphan_dir_bh)
+ brelse(orphan_dir_bh);
+ if (fe_bh)
+ brelse(fe_bh);
+
+ iput(orphan_dir_inode);
+clear_inode:
+ /* we must clear inode. */
+ clear_inode(inode);
+ LOG_EXIT();
+} /* ocfs_delete_inode */
+
+/*
* ocfs_clear_inode()
*
*/
@@ -654,8 +827,8 @@
if (!inode)
goto bail;
- LOG_TRACE_ARGS("Clearing inode feoff: %llu)\n",
- GET_INODE_FEOFF(inode));
+ LOG_TRACE_ARGS("Clearing inode feoff: %llu, nlink = %u)\n",
+ GET_INODE_FEOFF(inode), inode->i_nlink);
/* we should not really be using osb in this context. */
osb = OCFS_SB(inode->i_sb);
@@ -896,25 +1069,35 @@
if (tmperr < 0)
goto fail;
- tmperr = ocfs_read_bh(osb, lbo, &bh, readflags, inode);
- if (tmperr < 0)
- goto fail;
+ if (new) {
+ bh = getblk(OCFS_GET_BLOCKDEV(osb->sb),
+ lbo >> osb->sb->s_blocksize_bits,
+ osb->sb->s_blocksize);
+ if (!bh) {
+ tmperr = -EIO;
+ goto fail;
+ }
+ set_buffer_uptodate(bh);
+ SET_BH_SEQNUM(inode, bh);
- tmperr = 0;
- if (new) {
fatal = ocfs_journal_access(handle, bh,
OCFS_JOURNAL_ACCESS_CREATE);
- if (!fatal) {
- char *buf = OCFS_BH_GET_DATA_WRITE(bh);
- memset(buf, 0, osb->sect_size);
- set_buffer_uptodate(bh);
- OCFS_BH_PUT_DATA(bh);
- fatal = ocfs_journal_dirty(handle, bh);
- }
+ if (fatal)
+ goto fail;
+
+ char *buf = OCFS_BH_GET_DATA_WRITE(bh);
+ memset(buf, 0, osb->sect_size);
+ OCFS_BH_PUT_DATA(bh);
+ fatal = ocfs_journal_dirty(handle, bh);
+ if (fatal)
+ goto fail;
+ } else {
+ tmperr = ocfs_read_bh(osb, lbo, &bh, readflags, inode);
+ if (tmperr < 0)
+ goto fail;
}
- if (fatal)
- goto fail;
+ tmperr = 0;
*err = 0;
return bh;
@@ -1790,14 +1973,13 @@
goto leave;
/* Add checks as needed */
- if ((fe->sync_flags & OCFS_SYNC_FLAG_MARK_FOR_DELETION) ||
- (!(fe->sync_flags & OCFS_SYNC_FLAG_VALID))) {
- if (fe->sync_flags & OCFS_SYNC_FLAG_MARK_FOR_DELETION) {
- LOG_TRACE_STR
- ("File Entry is marked for deletion");
- } else {
+ if ((fe->u.i_dtime) || (!(fe->sync_flags & OCFS_SYNC_FLAG_VALID))) {
+ if (fe->u.i_dtime)
+ LOG_ERROR_ARGS("Inode %lu has dtime = %llu\n",
+ inode->i_ino, fe->u.i_dtime);
+ else
LOG_TRACE_STR ("File Entry is invalid");
- }
+
status = -ENOENT;
goto leave;
}
Modified: trunk/src/namei.c
===================================================================
--- trunk/src/namei.c 2004-06-11 10:22:45 UTC (rev 1052)
+++ trunk/src/namei.c 2004-06-11 21:07:06 UTC (rev 1053)
@@ -34,9 +34,17 @@
extern spinlock_t oin_num_ext_lock;
-static int inline search_dirblock(struct buffer_head * bh, struct inode *dir, struct dentry *dentry, unsigned long offset, struct ocfs2_dir_entry ** res_dir);
-static int ocfs_delete_entry (ocfs_journal_handle *handle, struct inode * dir, struct ocfs2_dir_entry * de_del, struct buffer_head * bh);
-static int ocfs_add_entry (ocfs_journal_handle *handle, struct dentry *dentry, struct inode *inode, __u64 inode_off, struct buffer_head *parent_fe_bh);
+static int inline search_dirblock(struct buffer_head * bh, struct inode *dir,
+ const char *name, int namelen,
+ unsigned long offset,
+ struct ocfs2_dir_entry ** res_dir);
+static int ocfs_delete_entry (ocfs_journal_handle *handle, struct inode * dir,
+ struct ocfs2_dir_entry * de_del,
+ struct buffer_head * bh);
+static int __ocfs_add_entry (ocfs_journal_handle *handle, struct inode *dir,
+ const char *name, int namelen,
+ struct inode *inode, __u64 inode_off,
+ struct buffer_head *parent_fe_bh);
static inline int ocfs_match (int len, const char * const name, struct ocfs2_dir_entry * de);
static int ocfs_mknod_locked(ocfs_super *osb, struct inode *dir,
@@ -53,10 +61,23 @@
struct buffer_head **bh2,
struct inode *inode2);
+static int ocfs_orphan_add(ocfs_super *osb, ocfs_journal_handle *handle,
+ struct inode *inode, ocfs_file_entry *fe);
+
static struct dentry_operations ocfs_dentry_ops = {
.d_revalidate = ocfs_dentry_revalidate // let's test it out!
};
+static inline int ocfs_add_entry(ocfs_journal_handle *handle,
+ struct dentry *dentry,
+ struct inode *inode, __u64 inode_off,
+ struct buffer_head *parent_fe_bh)
+{
+ return(__ocfs_add_entry(handle, dentry->d_parent->d_inode,
+ dentry->d_name.name, dentry->d_name.len,
+ inode, inode_off, parent_fe_bh));
+}
+
/*
* ocfs_lookup()
*
@@ -90,7 +111,9 @@
dir);
down(&OCFS_I(dir)->ip_io_sem);
- status = ocfs_find_files_on_disk (osb, dentry, &fe_off, dir, 1, &dirent_bh, &dirent);
+ status = ocfs_find_files_on_disk(osb, dentry->d_name.name,
+ dentry->d_name.len, &fe_off, dir, 1,
+ &dirent_bh, &dirent);
up(&OCFS_I(dir)->ip_io_sem);
if (status < 0)
goto bail_add;
@@ -312,6 +335,7 @@
__u64 bitmapOffset = 0;
__u64 fileOffset = 0;
struct inode *inode_alloc_inode = NULL;
+ struct super_block *sb = osb->sb;
LOG_ENTRY_ARGS ("(0x%p, 0x%p, %d, %d, '%*s')\n", dir, dentry, mode,
dev, dentry->d_name.len, dentry->d_name.name);
@@ -336,8 +360,16 @@
goto leave;
}
- status = ocfs_read_bh(osb, bitmapOffset, new_fe_bh,
- OCFS_BH_CACHED, inode);
+ *new_fe_bh = getblk (OCFS_GET_BLOCKDEV(sb),
+ bitmapOffset >> sb->s_blocksize_bits,
+ sb->s_blocksize);
+ if (!*new_fe_bh) {
+ status = -EIO;
+ LOG_ERROR_STATUS(status);
+ goto leave;
+ }
+ set_buffer_uptodate(*new_fe_bh);
+ SET_BH_SEQNUM(inode, *new_fe_bh);
status = ocfs_journal_access(handle, *new_fe_bh, OCFS_JOURNAL_ACCESS_CREATE);
if (status < 0) {
@@ -391,7 +423,6 @@
fe->last_ext_ptr = 0;
strcpy (fe->signature, OCFS_FILE_ENTRY_SIGNATURE);
SET_VALID_BIT (fe->sync_flags);
- fe->sync_flags &= ~(OCFS_SYNC_FLAG_CHANGE);
DISK_LOCK_SEQNUM (fe) = 0;
DISK_LOCK_CURRENT_MASTER (fe) = osb->node_num;
DISK_LOCK_FILE_LOCK (fe) = OCFS_DLM_ENABLE_CACHE_LOCK;
@@ -501,16 +532,14 @@
__u64 fe_off = GET_INODE_FEOFF(inode);
struct inode *parentInode = dentry->d_parent->d_inode;
ocfs_file_entry *fe = NULL;
- __u32 lockFlags = (S_ISDIR (inode->i_mode) ? (FLAG_FILE_DELETE | FLAG_DIR) : FLAG_FILE_DELETE);
+ __u32 lockFlags = (S_ISDIR (inode->i_mode) ? (FLAG_RELEASE_DENTRY | FLAG_DIR) : FLAG_RELEASE_DENTRY);
struct buffer_head *fe_bh = NULL;
struct buffer_head *parent_node_bh = NULL; /* parent locknode */
ocfs_journal_handle *handle = NULL;
__u64 parent_off = GET_INODE_FEOFF(parentInode);
struct ocfs2_dir_entry *dirent = NULL;
struct buffer_head *dirent_bh = NULL;
- int drop_inode = 0, dec_parent = 0;
-
LOG_ENTRY_ARGS ("(0x%p, 0x%p, '%*s')\n", dir, dentry,
dentry->d_name.len, dentry->d_name.name);
@@ -521,10 +550,9 @@
if (S_ISDIR (inode->i_mode) && !empty_dir(inode)) {
LOG_TRACE_STR ("dentry is not empty, cannot delete");
goto bail;
- } else if (OCFS_I(inode)->open_hndl_cnt > 0) {
- LOG_TRACE_ARGS ("Cannot remove an open file (open_hndl_cnt = %u, fe_off = %llu, d_count=%u)\n", OCFS_I(inode)->open_hndl_cnt, fe_off, atomic_read(&dentry->d_count));
- goto bail;
- } else if (inode == osb->root_inode) {
+ }
+
+ if (inode == osb->root_inode) {
LOG_TRACE_STR ("Cannot delete the root directory");
status = -EPERM;
goto bail;
@@ -565,9 +593,10 @@
got_parent = 1;
/* this will re-read the directory now with the EXCLUSIVE */
- /* lock already held; it will also return the fe_bh to us */
- status = ocfs_find_files_on_disk (osb, dentry, &fe_off, parentInode,
- 0, &dirent_bh, &dirent);
+ /* lock already held */
+ status = ocfs_find_files_on_disk (osb, dentry->d_name.name,
+ dentry->d_name.len, &fe_off,
+ parentInode, 0, &dirent_bh, &dirent);
if (status < 0) {
LOG_ERROR_STATUS(status);
goto leave;
@@ -590,7 +619,7 @@
goto leave;
}
got_file = 1;
-
+
if (S_ISDIR (inode->i_mode)) {
if (!empty_dir(inode)) {
status = -ENOTEMPTY;
@@ -607,90 +636,78 @@
goto leave;
}
- /* need to preserve locking order, so take a 'write' lock on
- * the dirnode sector first. it won't get passed to
- * journal_dirty until ocfs_remove_file so clean up the write
- * lock on errors before that */
status = ocfs_read_bh(osb, parent_off, &parent_node_bh,
OCFS_BH_CACHED, parentInode);
if (status < 0) {
LOG_ERROR_STATUS (status);
goto leave;
}
- OCFS_BH_GET_DATA_WRITE(parent_node_bh);
- OCFS_BH_PUT_DATA(parent_node_bh);
- /* we call ocfs_clear_buffer_modified in several error cases
- * here if we set the modify bit on this buffer, but haven't
- * journal_dirtied it yet. Otherwise, it'll stay modified even
- * after the abort_trans. */
fe = OCFS_BH_GET_DATA_WRITE(fe_bh);
+ if (fe->link_cnt != inode->i_nlink) {
+ printk("ocfs_unlink: hmm, inode has nlink = %u, fe has link_cnt = %u. Setting inode from fe.\n", inode->i_nlink, fe->link_cnt);
+ inode->i_nlink = fe->link_cnt;
+ }
+
if (S_ISDIR (inode->i_mode))
fe->link_cnt = 0;
- else
+ else
fe->link_cnt--;
+
if (!fe->link_cnt) {
- drop_inode = 1;
- OCFS_SET_FLAG (fe->sync_flags, OCFS_SYNC_FLAG_MARK_FOR_DELETION);
- fe->sync_flags &= (~OCFS_SYNC_FLAG_VALID);
+ status = ocfs_orphan_add(osb, handle, inode, fe);
+ if (status < 0) {
+ OCFS_BH_PUT_DATA(fe_bh);
+ LOG_ERROR_STATUS(status);
+ goto leave;
+ }
}
OCFS_BH_PUT_DATA(fe_bh);
- if (drop_inode) {
- /* Free up all the bits in the bitmap. */
- /* mark all the extents (and extent metadata) for
- * this file so we can remove them after commit. */
- /* TODO: delay this. see orphan comment below */
- status = ocfs_free_file_extents (osb, fe_bh, handle, inode);
+ status = ocfs_journal_dirty(handle, fe_bh);
+ if (status < 0) {
+ LOG_ERROR_STATUS(status);
+ goto leave;
+ }
+
+ /* delete the name from the parent dir */
+ status = ocfs_delete_entry (handle, parentInode, dirent, dirent_bh);
+ if (status < 0) {
+ LOG_ERROR_STATUS(status);
+ goto leave;
+ }
+
+ if (S_ISDIR (inode->i_mode)) {
+ ocfs_file_entry *dirfe;
+ status = ocfs_journal_access(handle, parent_node_bh,
+ OCFS_JOURNAL_ACCESS_WRITE);
if (status < 0) {
- ocfs_clear_buffer_modified(fe_bh);
- ocfs_clear_buffer_modified(parent_node_bh);
- LOG_ERROR_STATUS (status);
+ LOG_ERROR_STATUS(status);
goto leave;
}
-
- /* delete the name from the parent dir */
- status = ocfs_delete_entry (handle, parentInode, dirent, dirent_bh);
+ dirfe = OCFS_BH_GET_DATA_WRITE(parent_node_bh);
+ dirfe->link_cnt--;
+ OCFS_BH_PUT_DATA(parent_node_bh);
+ status = ocfs_journal_dirty(handle, fe_bh);
if (status < 0) {
LOG_ERROR_STATUS(status);
goto leave;
}
- /*
- * TODO: we should link this entry into the local orphan dir after
- * deleting the name from the parent. do NOT do the free_file_extents
- * in this function. delay it until triggered by orphan_del (by
- * delete_inode, truncate or similar)
- */
- if (S_ISDIR (inode->i_mode)) {
- ocfs_file_entry *dirfe;
- status = ocfs_journal_access(handle, parent_node_bh,
- OCFS_JOURNAL_ACCESS_WRITE);
- if (status < 0) {
- LOG_ERROR_STATUS(status);
- goto leave;
- }
- dirfe = OCFS_BH_GET_DATA_WRITE(parent_node_bh);
- dirfe->link_cnt--;
- OCFS_BH_PUT_DATA(parent_node_bh);
- status = ocfs_journal_dirty(handle, fe_bh);
- if (status < 0) {
- LOG_ERROR_STATUS(status);
- goto leave;
- }
- dec_parent=1;
- }
}
- status = ocfs_journal_dirty(handle, fe_bh);
- if (status < 0)
- LOG_ERROR_STATUS(status);
-
leave:
if (handle) {
if (status < 0)
ocfs_abort_trans(handle);
- else
+ else {
ocfs_commit_trans(handle);
+ // already checked to make sure dir has nlink==2
+ if (S_ISDIR (inode->i_mode)) {
+ inode->i_nlink = 0;
+ dir->i_nlink--;
+ } else
+ inode->i_nlink--;
+ }
}
/* need this to alert dentry-owners on other nodes */
@@ -714,19 +731,6 @@
}
- if (status >= 0) {
- // already checked to make sure dir has nlink==2
- if (S_ISDIR (inode->i_mode))
- inode->i_nlink = 0;
- else
- inode->i_nlink--;
- if (dec_parent)
- dir->i_nlink--;
-#warning is INODE_DELETED needed anymore?
- if (drop_inode)
- SET_INODE_DELETED(inode);
- }
-
up(&OCFS_I(inode)->ip_io_sem);
up(&OCFS_I(dir)->ip_io_sem);
bail:
@@ -887,7 +891,6 @@
struct buffer_head *oldfe_bh = NULL;
struct buffer_head *newfe_bh = NULL;
struct buffer_head *insert_bh = NULL;
- ocfs_file_entry *tmpfe = NULL;
ocfs_super *osb = NULL;
__u64 oldOffset, newDirOff, oldDirOff;
__u64 newfe_lockid = 0;
@@ -895,9 +898,9 @@
__u32 dir_lock_flags = FLAG_FILE_CREATE | FLAG_DIR;
struct buffer_head *old_dir_bh = NULL;
struct buffer_head *new_dir_bh = NULL;
- __u32 oldfe_flags = 0;
- __u32 newfe_flags = 0;
- int needs_trunc = 0, drop_inode = 0;
+ __u32 oldfe_flags = FLAG_RELEASE_DENTRY | FLAG_FILE_RENAME;
+ __u32 newfe_flags = FLAG_RELEASE_DENTRY;
+ int needs_trunc = 0;
int got_oldlock = 0, got_newlock = 0;
struct ocfs2_dir_entry *old_de = NULL, *new_de = NULL; // dirent for old_dentry
// and new_dentry
@@ -921,7 +924,7 @@
/* new parent dir offset */
newDirOff = GET_INODE_FEOFF(new_dir);
-
+
double_down(&OCFS_I(old_dir)->ip_io_sem, &OCFS_I(new_dir)->ip_io_sem);
down(&OCFS_I(old_inode)->ip_io_sem);
@@ -958,18 +961,6 @@
}
spin_unlock(&oin_num_ext_lock);
- /* Don't ever take the main resource for the OIN before this as */
- /* Locking hierarchy will be broken */
-
- if (new_inode) {
- down (&(OCFS_I(new_inode)->priv_sem));
- status = ocfs_verify_update_inode (osb, new_inode,
- &needs_trunc, 0);
- up (&(OCFS_I(new_inode)->priv_sem));
- if (needs_trunc)
- ocfs_truncate_inode_pages(new_inode, 0);
- }
-
/* start our transaction */
handle = ocfs_start_trans(osb, OCFS_FILE_RENAME_CREDITS);
if (handle == NULL) {
@@ -977,12 +968,6 @@
goto bail;
}
- /* for the (possibly two) parent directory locks, we just put
- * them in the journal handle to be released by
- * commit/abort. For rename, this is only a convenience and if
- * it is a problem, we can move the release_locks into the
- * bottom of this function. */
-
/* if old and new are the same, this'll just do one lock. */
status = ocfs_double_lock(osb, handle,
oldDirOff, OCFS_DLM_EXCLUSIVE_LOCK,
@@ -1012,11 +997,6 @@
if (S_ISDIR(old_inode->i_mode))
oldfe_flags = FLAG_DIR;
- if (old_dir != new_dir)
- oldfe_flags |= FLAG_FILE_DELETE;
- else
- oldfe_flags |= FLAG_FILE_RENAME;
-
status = ocfs_acquire_lock(osb, oldOffset, OCFS_DLM_EXCLUSIVE_LOCK,
oldfe_flags, NULL, old_inode);
if (status < 0) {
@@ -1040,7 +1020,9 @@
}
status = -ENOENT;
- old_de_bh = ocfs_find_entry (old_dentry, &old_de);
+ old_de_bh = ocfs_find_entry (old_dentry->d_name.name,
+ old_dentry->d_name.len,
+ old_dir, &old_de);
if (!old_de_bh)
goto finally;
@@ -1055,7 +1037,8 @@
/* check if the target already exists (in which case we need
* to delete it */
- status = ocfs_find_files_on_disk(osb, new_dentry, &newfe_lockid,
+ status = ocfs_find_files_on_disk(osb, new_dentry->d_name.name,
+ new_dentry->d_name.len, &newfe_lockid,
new_dir, 0, &new_de_bh, &new_de);
/* The only error we allow here is -ENOENT because the new
* file not existing is perfectly valid. */
@@ -1066,31 +1049,21 @@
goto finally;
}
+ if (!new_de && new_inode)
+ LOG_ERROR_ARGS("inode %lu does not exist in it's parent "
+ "directory!", new_inode->i_ino);
+
/* In case we need to overwrite an existing file, we blow it
* away first */
if (new_de) {
+ if (!new_inode)
+ BUG();
+
if (newfe_lockid != GET_INODE_FEOFF(new_inode))
BUG();
- status = ocfs_read_bh(osb, newfe_lockid, &newfe_bh,
- OCFS_BH_CACHED, new_inode);
- if (status < 0) {
- LOG_ERROR_STATUS(status);
- goto finally;
- }
-
- /* TODO: change this block to the ext3-style orphan model */
- newfe = OCFS_BH_GET_DATA_READ(newfe_bh);
- if (newfe->attribs & OCFS_ATTRIB_DIRECTORY)
+ if (S_ISDIR(new_inode->i_mode))
newfe_flags = FLAG_DIR;
- newfe_flags |= FLAG_FILE_DELETE;
-
- if (newfe_lockid != newfe->this_sector)
- BUG();
-
- OCFS_BH_PUT_DATA(newfe_bh);
- newfe = NULL;
-
status = ocfs_acquire_lock(osb, newfe_lockid,
OCFS_DLM_EXCLUSIVE_LOCK,
newfe_flags, &newfe_bh,
@@ -1100,76 +1073,64 @@
goto finally;
}
got_newlock = 1;
- LOG_ERROR_ARGS("aha rename over existing... new_de=%p newlockid=%llu newfebh=%p bhblocknr=%llu\n",
+
+ /* if our caching is working right, then after the
+ * verify_update_inode, newfe->i_nlink ==
+ * new_inode->i_nlink */
+ down (&(OCFS_I(new_inode)->priv_sem));
+ status = ocfs_verify_update_inode (osb, new_inode,
+ &needs_trunc, 0);
+ up (&(OCFS_I(new_inode)->priv_sem));
+ if (needs_trunc)
+ ocfs_truncate_inode_pages(new_inode, 0);
+
+ LOG_TRACE_ARGS("aha rename over existing... new_de=%p "
+ "newlockid=%llu newfebh=%p bhblocknr=%llu\n",
new_de, newfe_lockid, newfe_bh, newfe_bh ?
(unsigned long long)newfe_bh->b_blocknr : 0ULL);
- status = ocfs_journal_access(handle, newfe_bh, OCFS_JOURNAL_ACCESS_WRITE);
+ status = ocfs_journal_access(handle, newfe_bh,
+ OCFS_JOURNAL_ACCESS_WRITE);
if (status < 0) {
LOG_ERROR_STATUS (status);
goto finally;
}
-
- /* need to preserve locking order, so take a 'write' lock on
- * the dirnode sector first. it won't get passed to
- * journal_dirty until ocfs_remove_file so clean up the write
- * lock on errors before that */
- OCFS_BH_GET_DATA_WRITE(new_dir_bh);
- OCFS_BH_PUT_DATA(new_dir_bh);
- /* we call ocfs_clear_buffer_modified in several error cases
- * here if we set the modify bit on this buffer, but haven't
- * journal_dirtied it yet. Otherwise, it'll stay modified even
- * after the abort_trans. */
- newfe = OCFS_BH_GET_DATA_WRITE(newfe_bh);
- if (S_ISDIR (new_inode->i_mode) && !empty_dir(new_inode)) {
- status = -ENOTEMPTY;
- OCFS_BH_PUT_DATA(newfe_bh);
- newfe = NULL;
- ocfs_clear_buffer_modified(new_dir_bh);
- goto finally;
+ if (S_ISDIR (new_inode->i_mode)) {
+ if (!empty_dir(new_inode) || new_inode->i_nlink != 2) {
+ status = -ENOTEMPTY;
+ goto finally;
+ }
}
+ newfe = OCFS_BH_GET_DATA_WRITE(newfe_bh);
if (S_ISDIR (new_inode->i_mode))
newfe->link_cnt = 0;
else
newfe->link_cnt--;
+
if (!newfe->link_cnt) {
- OCFS_SET_FLAG (newfe->sync_flags, OCFS_SYNC_FLAG_MARK_FOR_DELETION);
- newfe->sync_flags &= (~OCFS_SYNC_FLAG_VALID);
- drop_inode = 1;
+ status = ocfs_orphan_add(osb, handle, new_inode,
+ newfe);
+ if (status < 0) {
+ OCFS_BH_PUT_DATA(newfe_bh);
+ LOG_ERROR_STATUS(status);
+ goto finally;
+ }
}
+
OCFS_BH_PUT_DATA(newfe_bh);
newfe = NULL;
- if (drop_inode) {
- /* Free up all the bits in the bitmap. */
- /* mark all the extents (and extent metadata) for
- * this file so we can remove them after commit. */
- /* TODO: delay this. see orphan comment below */
- status = ocfs_free_file_extents (osb, newfe_bh, handle, new_inode);
- if (status < 0) {
- ocfs_clear_buffer_modified(newfe_bh);
- ocfs_clear_buffer_modified(new_dir_bh);
- LOG_ERROR_STATUS (status);
- goto finally;
- }
-
- /*
- * TODO: we should link this entry into the local orphan dir after
- * deleting the name from the parent. do NOT do the free_file_extents
- * in this function. delay it until triggered by orphan_del (by
- * delete_inode, truncate or similar)
- */
- status = ocfs_journal_dirty(handle, newfe_bh);
- if (status < 0) {
- LOG_ERROR_STATUS (status);
- goto finally;
- }
+ status = ocfs_journal_dirty(handle, newfe_bh);
+ if (status < 0) {
+ LOG_ERROR_STATUS (status);
+ goto finally;
}
/* change the dirent to point to the correct inode */
- status = ocfs_journal_access(handle, new_de_bh, OCFS_JOURNAL_ACCESS_WRITE);
+ status = ocfs_journal_access(handle, new_de_bh,
+ OCFS_JOURNAL_ACCESS_WRITE);
if (status < 0) {
LOG_ERROR_STATUS (status);
goto finally;
@@ -1187,8 +1148,9 @@
} else {
/* if the name was not found in new_dir, add it now */
- status = ocfs_add_entry (handle, new_dentry, old_inode, oldOffset, new_dir_bh);
- }
+ status = ocfs_add_entry (handle, new_dentry, old_inode,
+ oldOffset, new_dir_bh);
+ }
finally:
@@ -1204,7 +1166,7 @@
status = ocfs_delete_entry(handle, old_dir, old_de, old_de_bh);
if (status < 0) {
LOG_ERROR_STATUS(status);
- goto finally;
+ goto bail;
}
if (new_inode) {
@@ -1213,7 +1175,8 @@
}
old_dir->i_ctime = old_dir->i_mtime = CURRENT_TIME;
if (old_inode_de_bh) {
- status = ocfs_journal_access(handle, old_inode_de_bh, OCFS_JOURNAL_ACCESS_WRITE);
+ status = ocfs_journal_access(handle, old_inode_de_bh,
+ OCFS_JOURNAL_ACCESS_WRITE);
if (status < 0) {
LOG_ERROR_STATUS (status);
// BAD
@@ -1237,11 +1200,8 @@
}
}
mark_inode_dirty(old_dir);
- if (new_inode) {
+ if (new_inode)
mark_inode_dirty(new_inode);
- if (!new_inode->i_nlink)
- ocfs_orphan_add(handle, new_inode);
- }
if (old_dir != new_dir) {
if (new_dir_nlink != new_dir->i_nlink)
@@ -1281,18 +1241,13 @@
iput(new_inode);
}
- if (tmpfe)
- ocfs_release_file_entry (tmpfe);
if (oldfe_bh) {
if (oldfe)
OCFS_BH_PUT_DATA(oldfe_bh);
brelse(oldfe_bh);
}
- if (newfe_bh) {
- if (newfe)
- OCFS_BH_PUT_DATA(newfe_bh);
+ if (newfe_bh)
brelse(newfe_bh);
- }
if (insert_bh)
brelse(insert_bh);
if (old_dir_bh)
@@ -1506,12 +1461,13 @@
return !memcmp(name, de->name, len);
}
-
-static int ocfs_add_entry (ocfs_journal_handle *handle, struct dentry *dentry, struct inode *inode, __u64 inode_off, struct buffer_head *parent_fe_bh)
+/* we don't always have a dentry for what we want to add, so people
+ * like orphan dir can call this instead. */
+static int __ocfs_add_entry (ocfs_journal_handle *handle, struct inode *dir,
+ const char *name, int namelen,
+ struct inode *inode, __u64 inode_off,
+ struct buffer_head *parent_fe_bh)
{
- struct inode *dir = dentry->d_parent->d_inode;
- const char *name = dentry->d_name.name;
- int namelen = dentry->d_name.len;
unsigned long offset;
unsigned short rec_len;
struct buffer_head * bh;
@@ -1680,15 +1636,13 @@
*/
static int inline search_dirblock(struct buffer_head * bh,
struct inode *dir,
- struct dentry *dentry,
+ const char *name, int namelen,
unsigned long offset,
struct ocfs2_dir_entry ** res_dir)
{
struct ocfs2_dir_entry * de;
char * dlimit;
int de_len;
- const char *name = dentry->d_name.name;
- int namelen = dentry->d_name.len;
int ret = 0;
de = OCFS_BH_GET_DATA_READ(bh);
@@ -1724,8 +1678,9 @@
-struct buffer_head * ocfs_find_entry (struct dentry *dentry,
- struct ocfs2_dir_entry ** res_dir)
+struct buffer_head * ocfs_find_entry (const char *name, int namelen,
+ struct inode *dir,
+ struct ocfs2_dir_entry ** res_dir)
{
struct super_block * sb;
struct buffer_head * bh_use[NAMEI_RA_SIZE];
@@ -1737,7 +1692,6 @@
buffer */
int num = 0;
int nblocks, i, err;
- struct inode *dir = dentry->d_parent->d_inode;
*res_dir = NULL;
sb = dir->i_sb;
@@ -1785,7 +1739,7 @@
brelse(bh);
goto next;
}
- i = search_dirblock(bh, dir, dentry,
+ i = search_dirblock(bh, dir, name, namelen,
block << OCFS_SB(sb)->sect_size_bits, res_dir);
if (i == 1) {
OCFS_I(dir)->i_dir_start_lookup = block;
@@ -1819,18 +1773,176 @@
return ret;
}
+/*
+ * ocfs_orphan_add()
+ *
+ */
+static int ocfs_orphan_add(ocfs_super *osb, ocfs_journal_handle *handle,
+ struct inode *inode, ocfs_file_entry *fe)
+{
+ struct inode *orphan_dir_inode = NULL;
+ struct buffer_head *orphan_dir_bh = NULL;
+ int status = 0;
+ char *name = NULL;
+ int namelen;
+ ocfs_file_entry *orphan_fe;
+ LOG_ENTRY_ARGS("(inode->i_ino = %lu)\n", inode->i_ino);
-int ocfs_orphan_add(ocfs_journal_handle *handle, struct inode *inode)
+ /* create a unique name here. */
+ name = ocfs_malloc(OCFS_MAX_FILENAME_LENGTH+1);
+
+ namelen = snprintf(name, OCFS_MAX_FILENAME_LENGTH+1, "%llu",
+ GET_INODE_FEOFF(inode));
+ if (namelen <= 0) {
+ if (namelen)
+ status = namelen;
+ else
+ status = -EFAIL;
+ LOG_ERROR_STATUS(status);
+ goto leave;
+ }
+
+ LOG_TRACE_ARGS("adding filename '%s' to orphan dir (len=%d)\n", name,
+ namelen);
+
+ orphan_dir_inode = igrab(osb->system_inodes[ORPHAN_DIR_SYSTEM_INODE]);
+ if (!orphan_dir_inode) {
+ status = -EFAIL;
+ LOG_ERROR_STATUS(status);
+ goto leave;
+ }
+ ocfs_handle_add_inode(handle, orphan_dir_inode);
+
+ /* disk lock orphan dir here. */
+ status = ocfs_acquire_lock(osb, GET_INODE_FEOFF(orphan_dir_inode),
+ OCFS_DLM_EXCLUSIVE_LOCK,
+ FLAG_FILE_CREATE | FLAG_DIR,
+ &orphan_dir_bh, orphan_dir_inode);
+ if (status < 0) {
+ LOG_ERROR_STATUS(status);
+ goto leave;
+ }
+ ocfs_handle_add_lock(handle, OCFS_DLM_ENABLE_CACHE_LOCK,
+ FLAG_FILE_CREATE | FLAG_DIR, orphan_dir_bh,
+ orphan_dir_inode, 1);
+
+ status = __ocfs_add_entry(handle, orphan_dir_inode, name, namelen,
+ inode, GET_INODE_FEOFF(inode),
+ orphan_dir_bh);
+ if (status < 0) {
+ LOG_ERROR_STATUS(status);
+ goto leave;
+ }
+
+ status = ocfs_journal_access(handle, orphan_dir_bh,
+ OCFS_JOURNAL_ACCESS_WRITE);
+ if (status < 0) {
+ LOG_ERROR_STATUS(status);
+ goto leave;
+ }
+
+ /* we're a cluster, and nlink can change on disk from
+ * underneath us... */
+ orphan_fe = OCFS_BH_GET_DATA_WRITE(orphan_dir_bh);
+ if (S_ISDIR(inode->i_mode))
+ orphan_fe->link_cnt++;
+ orphan_dir_inode->i_nlink = orphan_fe->link_cnt;
+ OCFS_BH_PUT_DATA(orphan_dir_bh);
+
+ status = ocfs_journal_dirty(handle, orphan_dir_bh);
+ if (status < 0) {
+ LOG_ERROR_STATUS(status);
+ goto leave;
+ }
+
+
+ OCFS_SET_FLAG (fe->sync_flags, OCFS_SYNC_FLAG_ORPHANED);
+
+leave:
+ if (orphan_dir_inode)
+ iput(orphan_dir_inode);
+
+ if (name)
+ ocfs_free(name);
+
+ if (orphan_dir_bh)
+ brelse(orphan_dir_bh);
+
+ LOG_EXIT_STATUS(status);
+ return(status);
+} /* ocfs_orphan_add */
+
+/* unlike orphan_add, we expect the orphan dir to already be locked here. */
+int ocfs_orphan_del(ocfs_super *osb, ocfs_journal_handle *handle,
+ struct inode *orphan_dir_inode, struct inode *inode,
+ struct buffer_head *orphan_dir_bh)
{
- LOG_ERROR_ARGS("need to add %llu to orphan dir, i_nlink=%d\n",
- GET_INODE_FEOFF(inode), inode->i_nlink);
- return 0;
-}
+ char *name = NULL;
+ int namelen;
+ ocfs_file_entry *orphan_fe;
+ int status = 0;
+ struct buffer_head *target_de_bh;
+ struct ocfs2_dir_entry *target_de = NULL;
-int ocfs_orphan_del(ocfs_journal_handle *handle, struct inode *inode)
-{
- return 0;
+ name = ocfs_malloc(OCFS_MAX_FILENAME_LENGTH+1);
+
+ namelen = snprintf(name, OCFS_MAX_FILENAME_LENGTH+1, "%llu",
+ GET_INODE_FEOFF(inode));
+ if (namelen <= 0) {
+ if (namelen)
+ status = namelen;
+ else
+ status = -EFAIL;
+ LOG_ERROR_STATUS(status);
+ goto leave;
+ }
+
+ LOG_TRACE_ARGS("removing '%s' from orphan dir (len=%d)\n", name,
+ namelen);
+
+ /* find it's spot in the orphan directory */
+ target_de_bh = ocfs_find_entry(name, namelen, orphan_dir_inode,
+ &target_de);
+ if (!target_de_bh) {
+ status = -EFAIL;
+ LOG_ERROR_STATUS(status);
+ goto leave;
+ }
+
+ /* remove it from the orphan directory */
+ status = ocfs_delete_entry(handle, orphan_dir_inode, target_de,
+ target_de_bh);
+ if (status < 0) {
+ LOG_ERROR_STATUS(status);
+ goto leave;
+ }
+
+ status = ocfs_journal_access(handle, orphan_dir_bh,
+ OCFS_JOURNAL_ACCESS_WRITE);
+ if (status < 0) {
+ LOG_ERROR_STATUS(status);
+ goto leave;
+ }
+
+ /* do the i_nlink dance! :) */
+ orphan_fe = OCFS_BH_GET_DATA_WRITE(orphan_dir_bh);
+ if (S_ISDIR(inode->i_mode))
+ orphan_fe->link_cnt--;
+ orphan_dir_inode->i_nlink = orphan_fe->link_cnt;
+ OCFS_BH_PUT_DATA(orphan_dir_bh);
+
+ status = ocfs_journal_dirty(handle, orphan_dir_bh);
+ if (status < 0) {
+ LOG_ERROR_STATUS(status);
+ goto leave;
+ }
+
+leave:
+ if (name)
+ ocfs_free(name);
+
+ return status;
}
#if 0
Modified: trunk/src/nm.c
===================================================================
--- trunk/src/nm.c 2004-06-11 10:22:45 UTC (rev 1052)
+++ trunk/src/nm.c 2004-06-11 21:07:06 UTC (rev 1053)
@@ -58,8 +58,8 @@
static const char *process_vote_strings[] = {
"INVALID_REQUEST", // reply with a NO vote
"UPDATE_OIN_INODE", // update both oin and inode
- "DELETE_RENAME_ACQUIRE",// delete or rename request
- "DELETE_RENAME_RELEASE",// delete or rename release request
+ "DELETE_ACQUIRE",// delete or rename request
+ "DELETE_RELEASE",// delete or rename release request
"RELEASE_CACHE", // release a cache lock I hold
"CHANGE_MASTER", // request to change master to requestor
"ADD_OIN_MAP", // add requestor into oin map
@@ -68,6 +68,7 @@
"REMASTER_REQUESTOR", // remaster lock to requestor
"DROP_READONLY", // RO cachelock needs to convert to RW
"READONLY",
+ "RELEASE_DENTRY"
};
#endif
@@ -522,10 +523,10 @@
my_node_wins = (node_num < osb->node_num);
}
-// if (flags & FLAG_DROP_LINK) {
-// vote_type = RELEASE_DENTRY;
-// goto done;
-// }
+ if (flags & (FLAG_RELEASE_DENTRY | FLAG_FILE_RENAME)) {
+ vote_type = RELEASE_DENTRY;
+ goto done;
+ }
if (flags & FLAG_DROP_READONLY) {
vote_type = DROP_READONLY;
@@ -539,11 +540,11 @@
goto done;
}
- if (flags & (FLAG_FILE_DELETE | FLAG_FILE_RENAME)) {
+ if (flags & FLAG_FILE_DELETE) {
if (flags & FLAG_RELEASE_LOCK)
- vote_type = DELETE_RENAME_RELEASE;
+ vote_type = DELETE_RELEASE;
else if (flags & FLAG_ACQUIRE_LOCK)
- vote_type = DELETE_RENAME_ACQUIRE;
+ vote_type = DELETE_ACQUIRE;
else
vote_type = INVALID_REQUEST;
} else if (flags & FLAG_FILE_RELEASE_CACHE)
@@ -568,7 +569,7 @@
vote_type = REMASTER_REQUESTOR;
}
- if (inode == NULL && vote_type != DELETE_RENAME_RELEASE)
+ if (inode == NULL && vote_type != DELETE_RELEASE)
vote_type = INVALID_REQUEST;
done:
LOG_EXIT_STATUS(vote_type);
@@ -629,7 +630,6 @@
ocfs_vote *vote = NULL;
struct buffer_head *fe_bh = NULL, *vote_bh = NULL;
int vote_type = INVALID_REQUEST, vote_response = 0;
- int oin_sem = 0;
struct inode *inode = NULL;
int master_alive = 1, is_dir = 0;
int is_locked, open_handle;
@@ -685,7 +685,7 @@
* 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))
+ if ((flags & FLAG_FILE_DELETE) && (flags & FLAG_RELEASE_LOCK))
inode = NULL;
else {
inode = ocfs_iget(osb, lock_id);
@@ -698,6 +698,11 @@
goto leave;
}
+ /* ahh, so you find yourself asking "what the
+ * heck is this?"
+ * Please see the note in ocfs_delete_inode. */
+ osb->voting_ino = inode->i_ino;
+
down(&OCFS_I(inode)->ip_io_sem);
have_io_sem = 1;
@@ -774,137 +779,117 @@
vote_response = FLAG_VOTE_OIN_UPDATED;
break;
-#if 0
case RELEASE_DENTRY:
if (!inode)
BUG();
/* we always vote yes on this one. */
vote_response = FLAG_VOTE_NODE;
- printk("going to prune dentries for inode %lu\n",
- inode->i_ino);
+ /* do nothing in the release case... hmm,
+ * perhaps we should just do a verify_update
+ * or something in case the guy aborted... */
+ if (flags & FLAG_RELEASE_LOCK)
+ break;
+
d_prune_aliases (inode);
- inode->i_nlink--;
+
+ /* for rename, we don't drop link counts */
+ if (!(flags & FLAG_FILE_RENAME)) {
+ if (S_ISDIR(inode->i_mode))
+ inode->i_nlink = 0;
+ else
+ inode->i_nlink--;
+ }
+
+ LOG_TRACE_ARGS("pruned dentries for inode %lu, nlink "
+ "= %u\n", inode->i_ino, inode->i_nlink);
break;
-#endif
- case DELETE_RENAME_RELEASE:
+
+ case DELETE_RELEASE:
/* ACK and done */
vote_response = FLAG_VOTE_NODE;
break;
- case DELETE_RENAME_ACQUIRE:
- LOG_TRACE_STR("DELETE_RENAME");
+ case DELETE_ACQUIRE:
+ LOG_TRACE_STR("DELETE_ACQUIRE");
- /* all cases except open_hndl_cnt > 0 will vote YES */
- vote_response = FLAG_VOTE_NODE;
+ down (&(OCFS_I(inode)->priv_sem));
+ OCFS_I(inode)->needs_verification = 1;
+ tmpstat = ocfs_verify_update_inode(osb, inode,
+ &needs_trunc,
+ 1);
+ if (tmpstat < 0)
+ LOG_ERROR_STATUS (tmpstat);
- if (inode) {
- oin_sem = 1;
- down (&(OCFS_I(inode)->priv_sem));
- OCFS_I(inode)->needs_verification = 1;
- tmpstat = ocfs_verify_update_inode(osb, inode,
- &needs_trunc,
- 1);
- if (tmpstat < 0)
- LOG_ERROR_STATUS (tmpstat);
-
- if (needs_trunc) {
- ocfs_truncate_inode_pages(inode, 0);
- needs_trunc = 0;
- }
+ if (needs_trunc)
+ ocfs_truncate_inode_pages(inode, 0);
- if (OCFS_I(inode)->open_hndl_cnt > 0) {
- /* the NO vote for delete/rename */
- vote_response = FLAG_VOTE_OIN_ALREADY_INUSE;
- } else {
- spin_lock(&oin_num_ext_lock);
- if (OCFS_I(inode)->num_extends) {
- vote_response = FLAG_VOTE_OIN_ALREADY_INUSE;
- } else {
- OCFS_SET_FLAG (OCFS_I(inode)->oin_flags, OCFS_OIN_NEEDS_DELETION);
- up(&(OCFS_I(inode)->priv_sem));
- ocfs_release_lockres (lockres); // ocfs_process_vote
- lockres = NULL;
- oin_sem = 0;
- if (needs_trunc) {
- ocfs_truncate_inode_pages(inode, 0);
- needs_trunc = 0;
- }
- }
- spin_unlock(&oin_num_ext_lock);
- }
+ LOG_TRACE_ARGS("DELETE vote on inode %lu, read "
+ "lnk_cnt = %u\n", inode->i_ino,
+ inode->i_nlink);
+ /* verify_update_inode does a dirty read which
+ * might set i_nlink to an old value. */
+ if (inode->i_nlink) {
+ LOG_ERROR_ARGS("Orphaned inode %lu has link "
+ "count = %d!\n", inode->i_ino,
+ inode->i_nlink);
+ inode->i_nlink = 0;
}
- /* If the inode exists and we we're going to
- * vote yes on the delete, then lets mark it
- * deleted now. It will retain a single
- * reference for the rest of this function (we
- * can sync it and change nlink) which we iput
- * before exit. */
- if (inode && vote_response == FLAG_VOTE_NODE) {
-#warning is this needed anymore?
- SET_INODE_DELETED(inode);
+ /* vote no if the file is still open. */
+ if (OCFS_I(inode)->open_hndl_cnt > 0) {
+ vote_response = FLAG_VOTE_OIN_ALREADY_INUSE;
+ up(&(OCFS_I(inode)->priv_sem));
+ goto delete_vote_no;
}
+ up(&(OCFS_I(inode)->priv_sem));
- if (!lockres) {
- /* is there an inode to dump? */
- if (inode) {
- inode->i_nlink = 0;
- d_prune_aliases (inode);
+ /* vote no if someone's extending it. */
+ spin_lock(&oin_num_ext_lock);
+ if (OCFS_I(inode)->num_extends) {
+ spin_unlock(&oin_num_ext_lock);
+ vote_response = FLAG_VOTE_OIN_ALREADY_INUSE;
+ goto delete_vote_no;
+ }
+ spin_unlock(&oin_num_ext_lock);
+
+ vote_response = FLAG_VOTE_NODE;
+
+ SET_INODE_DELETED(inode);
+ /* if we vote yes, then we set the SKIP_DELETE
+ * flag on the inode so we don't try to delete
+ * it in delete_inode ourselves. */
+ OCFS_SET_FLAG(OCFS_I(inode)->flags,
+ OCFS_INODE_SKIP_DELETE);
+
+ inode->i_nlink = 0;
+ d_prune_aliases (inode);
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
- sync_mapping_buffers(inode->i_mapping);
+ sync_mapping_buffers(inode->i_mapping);
#else
- fsync_inode_buffers (inode);
+ fsync_inode_buffers (inode);
#endif
- up(&OCFS_I(inode)->ip_io_sem);
- have_io_sem = 0;
- }
- break;
- }
+ /* Alright, for the YES case, we're done here. */
+ break;
- if (inode) {
- up(&OCFS_I(inode)->ip_io_sem);
- have_io_sem = 0;
- }
-
- /* Set the always update master on open flag */
- lockres->lock_state |= FLAG_ALWAYS_UPDATE_OPEN;
+delete_vote_no:
lockres->last_upd_seq_num = seq_num;
- if (lockres->master_node_num == OCFS_INVALID_NODE_NUM || !master_alive)
+ /* (6/11/2004): the next two conditional are
+ * likely useless relics. If we don't hit
+ * those error messages then we can delete
+ * them.*/
+ if (lockres->master_node_num == OCFS_INVALID_NODE_NUM
+ || !master_alive) {
lockres->master_node_num = node_num;
-
- /* Change the master if there is no lock */
+ LOG_ERROR_STR("Wowzers, how'd I hit this code:"
+ " master node is invalid!?!");
+ }
if (lockres->master_node_num == osb->node_num &&
lockres->lock_type < OCFS_DLM_EXCLUSIVE_LOCK) {
- /* Change the lock ownership to the node asking for vote */
- /* and write new master on the disk */
-
- status = ocfs_read_bh(osb, lock_id, &fe_bh, lockflags, inode);
- if (status < 0)
- LOG_ERROR_STATUS (status);
- if (status >= 0) {
- fe = OCFS_BH_GET_DATA_WRITE(fe_bh);
- DISK_LOCK_CURRENT_MASTER (fe) = node_num;
- OCFS_BH_PUT_DATA(fe_bh);
- status = ocfs_write_bh(osb, fe_bh, 0, inode);
- if (status < 0)
- LOG_ERROR_STATUS (status);
- else
- lockres->master_node_num = node_num;
- brelse(fe_bh);
- }
+ LOG_ERROR_STR("Wowzers, how'd I hit this "
+ "code!?!");
}
- if (oin_sem) {
- up(&(OCFS_I(inode)->priv_sem));
- oin_sem = 0;
- }
-
- if (needs_trunc) {
- ocfs_truncate_inode_pages(inode, 0);
- needs_trunc = 0;
- }
-
break;
case READONLY:
@@ -1057,8 +1042,7 @@
}
fe = OCFS_BH_GET_DATA_READ(fe_bh);
- if ((fe->sync_flags & OCFS_SYNC_FLAG_NAME_DELETED) ||
- (!(fe->sync_flags & OCFS_SYNC_FLAG_VALID))) {
+ if (!(fe->sync_flags & OCFS_SYNC_FLAG_VALID)) {
vote_response = FLAG_VOTE_FILE_DEL;
OCFS_BH_PUT_DATA(fe_bh);
} else {
@@ -1249,9 +1233,12 @@
ocfs_inc_inode_seq(osb, inode, 1);
if (have_io_sem)
up(&OCFS_I(inode)->ip_io_sem);
- iput(inode);
}
+ if (inode)
+ iput(inode);
+ osb->voting_ino = 0;
+
up(&osb->vote_sem);
LOG_EXIT_STATUS (status);
Modified: trunk/src/super.c
===================================================================
--- trunk/src/super.c 2004-06-11 10:22:45 UTC (rev 1052)
+++ trunk/src/super.c 2004-06-11 21:07:06 UTC (rev 1053)
@@ -162,7 +162,7 @@
.put_inode = ocfs_put_inode,
.clear_inode = ocfs_clear_inode,
//put_inode = force_delete,
- //delete_inode = ocfs_delete_inode,
+ .delete_inode = ocfs_delete_inode,
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
.read_inode = ocfs_read_inode,
.read_inode2 = ocfs_read_inode2,
@@ -249,6 +249,17 @@
}
osb->system_inodes[JOURNAL_SYSTEM_INODE] = new;
+ /* orphan inode dir */
+ sys_off = osb->vol_layout.root_int_off +
+ (OCFS_ORPHAN_DIR * osb->sect_size);
+ new = ocfs_iget(osb, sys_off);
+ if (!new) {
+ status = -EINVAL;
+ LOG_ERROR_STATUS(status);
+ goto bail;
+ }
+ osb->system_inodes[ORPHAN_DIR_SYSTEM_INODE] = new;
+
bail:
LOG_EXIT_STATUS(status);
return(status);
More information about the Ocfs2-commits
mailing list