[Ocfs2-commits] mfasheh commits r2482 - trunk/fs/ocfs2
svn-commits at oss.oracle.com
svn-commits at oss.oracle.com
Thu Jul 28 16:23:05 CDT 2005
Author: mfasheh
Signed-off-by: jlbec
Signed-off-by: zab
Date: 2005-07-28 16:23:00 -0500 (Thu, 28 Jul 2005)
New Revision: 2482
Modified:
trunk/fs/ocfs2/dlmglue.c
trunk/fs/ocfs2/dlmglue.h
trunk/fs/ocfs2/inode.c
trunk/fs/ocfs2/inode.h
trunk/fs/ocfs2/ocfs2.h
trunk/fs/ocfs2/vote.c
trunk/fs/ocfs2/vote.h
Log:
* Queue up lockres for downconvert always now. The previous implementation
which tried to take an inode reference via igrab was causing problems during
delete_inode.
* Similarly the vote thread wasn't always able to get to the inode if it was
in ocfs2_delete_inode to mark it deleted. Fix this by always setting the
deleted flag.
Signed-off-by: jlbec
Signed-off-by: zab
Modified: trunk/fs/ocfs2/dlmglue.c
===================================================================
--- trunk/fs/ocfs2/dlmglue.c 2005-07-28 18:39:03 UTC (rev 2481)
+++ trunk/fs/ocfs2/dlmglue.c 2005-07-28 21:23:00 UTC (rev 2482)
@@ -54,7 +54,6 @@
#include "buffer_head_io.h"
-
static void ocfs2_inode_ast_func(void *opaque);
static void ocfs2_inode_bast_func(void *opaque,
int level);
@@ -172,8 +171,6 @@
static int ocfs2_generic_handle_bast(struct ocfs2_lock_res *lockres, int level);
static void ocfs2_schedule_blocked_lock(ocfs2_super *osb,
struct ocfs2_lock_res *lockres);
-static void ocfs2_schedule_blocked_inode_lock(struct inode *inode,
- struct ocfs2_lock_res *lockres);
static inline void ocfs2_recover_from_dlm_error(struct ocfs2_lock_res *lockres,
int convert);
#define ocfs2_log_dlm_error(_func, _stat, _lockres) do { \
@@ -559,8 +556,7 @@
lksb = &(lockres->l_lksb);
if (lksb->status != DLM_NORMAL) {
mlog(ML_ERROR, "ocfs2_inode_ast_func: lksb status value of %u "
- "on inode %"MLFu64"\n",
- lksb->status,
+ "on inode %"MLFu64"\n", lksb->status,
OCFS2_I(inode)->ip_blkno);
spin_unlock(&lockres->l_lock);
mlog_exit_void();
@@ -651,12 +647,11 @@
needs_downconvert = ocfs2_generic_handle_bast(lockres, level);
if (needs_downconvert)
- ocfs2_schedule_blocked_inode_lock(inode, lockres);
+ ocfs2_schedule_blocked_lock(osb, lockres);
spin_unlock(&lockres->l_lock);
ocfs2_kick_vote_thread(osb);
- /* TODO: Is a wake_up call here really necessary? */
wake_up(&lockres->l_event);
mlog_exit_void();
@@ -916,6 +911,33 @@
complete(&sc->sc_complete);
}
+static int ocfs2_wait_for_status_completion(struct ocfs2_status_completion *sc)
+{
+ wait_for_completion(&sc->sc_complete);
+ /* Re-arm the completion in case we want to wait on it again */
+ INIT_COMPLETION(sc->sc_complete);
+ return sc->sc_status;
+}
+
+static void ocfs2_init_fcb(struct ocfs2_lockres_flag_callback *fcb,
+ ocfs2_lock_callback cb,
+ unsigned long cb_data,
+ int stack_allocated)
+{
+ fcb->fc_cb = cb;
+ fcb->fc_data = cb_data;
+ fcb->fc_free_once_called = !stack_allocated;
+ INIT_LIST_HEAD(&fcb->fc_lockres_item);
+}
+
+/* Init a stack allocated FCB and an ocfs2_status_completion together. */
+static void ocfs2_init_completion_fcb(struct ocfs2_lockres_flag_callback *fcb,
+ struct ocfs2_status_completion *sc)
+{
+ init_completion(&sc->sc_complete);
+ ocfs2_init_fcb(fcb, ocfs2_status_completion_cb, (unsigned long) sc, 1);
+}
+
static int ocfs2_cluster_lock(ocfs2_super *osb,
struct ocfs2_lock_res *lockres,
int level,
@@ -938,10 +960,9 @@
ret = -ENOMEM;
goto out;
}
- fcb->fc_cb = cb;
- fcb->fc_data = cb_data;
- fcb->fc_free_once_called = 1;
+ ocfs2_init_fcb(fcb, cb, cb_data, 0);
+
/* A callback passed in means we'll assume async
* behavior - no waiting on dlm operations will be
* done here and the allocated fcb will call the
@@ -953,15 +974,9 @@
* stack allocated fcb for this. The status completion
* helpers defined above come in handy here. */
fcb = &sync_fcb;
-
- init_completion(&sc.sc_complete);
- fcb->fc_cb = ocfs2_status_completion_cb;
- fcb->fc_data = (unsigned long)≻
- fcb->fc_free_once_called = 0;
+ ocfs2_init_completion_fcb(fcb, &sc);
}
- INIT_LIST_HEAD(&fcb->fc_lockres_item);
-
again:
if (catch_signals && signal_pending(current)) {
ret = -ERESTARTSYS;
@@ -970,6 +985,10 @@
spin_lock(&lockres->l_lock);
+ mlog_bug_on_msg(lockres->l_flags & OCFS2_LOCK_FREEING,
+ "Cluster lock called on freeing lockres %s! flags 0x%lx\n",
+ lockres->l_name, lockres->l_flags);
+
/* We only compare against the currently granted level
* here. If the lock is blocked waiting on a downconvert,
* we'll get caught below. */
@@ -1063,12 +1082,10 @@
* to complete. We must be careful to re-initialize the
* completion before looping back. */
if (ret == -EIOCBRETRY && sync) {
- wait_for_completion(&sc.sc_complete);
- ret = sc.sc_status;
- if (ret == 0) {
- INIT_COMPLETION(sc.sc_complete);
+ ret = ocfs2_wait_for_status_completion(&sc);
+ if (ret == 0)
goto again;
- }
+ mlog_errno(ret);
}
/* Only free the async fcb on error. */
@@ -1853,7 +1870,8 @@
* hurt anything anyway */
if (status == DLM_CANCELGRANT &&
lockres->l_unlock_action == OCFS2_UNLOCK_CANCEL_CONVERT) {
- mlog(0, "Ok, got cancelgrant for %s\n", lockres->l_name);
+ mlog(0, "Got cancelgrant for %s\n", lockres->l_name);
+
/* We don't clear the busy flag in this case as it
* should have been cleared by the ast which the dlm
* has called. */
@@ -1870,6 +1888,7 @@
switch(lockres->l_unlock_action) {
case OCFS2_UNLOCK_CANCEL_CONVERT:
+ mlog(0, "Cancel convert success for %s\n", lockres->l_name);
lockres->l_action = OCFS2_AST_INVALID;
break;
case OCFS2_UNLOCK_DROP_LOCK:
@@ -1958,6 +1977,10 @@
spin_lock(&lockres->l_lock);
+ mlog_bug_on_msg(!(lockres->l_flags & OCFS2_LOCK_FREEING),
+ "lockres %s, flags 0x%lx\n",
+ lockres->l_name, lockres->l_flags);
+
while (lockres->l_flags & OCFS2_LOCK_BUSY) {
mlog(0, "waiting on busy lock \"%s\": flags = %lx, action = "
"%u, unlock_action = %u\n",
@@ -1982,16 +2005,51 @@
return __ocfs2_drop_lock(osb, lockres);
}
+/* Mark the lockres as being dropped. It will no longer be
+ * queued if blocking, but we still may have to wait on it
+ * being dequeued from the vote thread before we can consider
+ * it safe to drop.
+ *
+ * You can *not* attempt to call cluster_lock on this lockres anymore. */
+void ocfs2_mark_lockres_freeing(struct ocfs2_lock_res *lockres)
+{
+ int status;
+ struct ocfs2_status_completion sc;
+ struct ocfs2_lockres_flag_callback fcb;
+
+ ocfs2_init_completion_fcb(&fcb, &sc);
+
+ spin_lock(&lockres->l_lock);
+ lockres->l_flags |= OCFS2_LOCK_FREEING;
+ while (lockres->l_flags & OCFS2_LOCK_QUEUED) {
+ lockres_add_flag_callback(lockres, &fcb, OCFS2_LOCK_QUEUED, 0);
+ spin_unlock(&lockres->l_lock);
+
+ mlog(0, "Waiting on lockres %s\n", lockres->l_name);
+
+ status = ocfs2_wait_for_status_completion(&sc);
+ if (status)
+ mlog_errno(status);
+
+ spin_lock(&lockres->l_lock);
+ }
+ spin_unlock(&lockres->l_lock);
+}
+
static void ocfs2_drop_osb_locks(ocfs2_super *osb)
{
int status;
mlog_entry_void();
+ ocfs2_mark_lockres_freeing(&osb->osb_super_lockres);
+
status = ocfs2_drop_lock(osb, &osb->osb_super_lockres, NULL);
if (status < 0)
mlog_errno(status);
+ ocfs2_mark_lockres_freeing(&osb->osb_rename_lockres);
+
status = ocfs2_drop_lock(osb, &osb->osb_rename_lockres, NULL);
if (status < 0)
mlog_errno(status);
@@ -2020,6 +2078,9 @@
mlog_entry_void();
+ /* No need to call ocfs2_mark_lockres_freeing here -
+ * ocfs2_clear_inode has done it for us. */
+
err = ocfs2_drop_lock(OCFS2_SB(inode->i_sb),
&OCFS2_I(inode)->ip_data_lockres,
NULL);
@@ -2108,6 +2169,10 @@
/* set things up for the unlockast to know to just
* clear out the ast_action and unset busy, etc. */
lockres->l_unlock_action = OCFS2_UNLOCK_CANCEL_CONVERT;
+
+ mlog_bug_on_msg(!(lockres->l_flags & OCFS2_LOCK_BUSY),
+ "lock %s, invalid flags: 0x%lx\n",
+ lockres->l_name, lockres->l_flags);
spin_unlock(&lockres->l_lock);
ret = 0;
@@ -2138,6 +2203,8 @@
* then just drop the spinlock and allow the caller to
* requeue this lock. */
spin_unlock(&lockres->l_lock);
+
+ mlog(0, "Lockres %s, skip convert\n", lockres->l_name);
return 0;
}
@@ -2370,16 +2437,6 @@
mlog(0, "inode %"MLFu64", requeue = %d\n",
OCFS2_I(inode)->ip_blkno, *requeue);
- /* because of inode ref counting, we never want to propagate
- * up requeue requests for inode locks. Instead we do it
- * ourselves here, and lose the extra ref we got from queueing
- * when we came in. */
- if (*requeue)
- ocfs2_schedule_blocked_inode_lock(inode, lockres);
-
- iput(inode);
- *requeue = 0;
-
mlog_exit(status);
return status;
}
@@ -2403,14 +2460,6 @@
mlog(0, "inode %"MLFu64", requeue = %d\n",
OCFS2_I(inode)->ip_blkno, *requeue);
- /* if you're confused by this, see the comment in
- * ocfs2_unblock_data */
- if (*requeue)
- ocfs2_schedule_blocked_inode_lock(inode, lockres);
-
- iput(inode);
- *requeue = 0;
-
mlog_exit(status);
return status;
}
@@ -2446,6 +2495,10 @@
int status;
int requeue = 0;
+ /* Our reference to the lockres in this function can be
+ * considered valid until we remove the OCFS2_LOCK_QUEUED
+ * flag. */
+
mlog_entry_void();
BUG_ON(!lockres);
@@ -2454,15 +2507,30 @@
mlog(0, "lockres %s blocked.\n", lockres->l_name);
+ /* Detect whether a lock has been marked as going away while
+ * the vote thread was processing other things. A lock can
+ * still be marked with OCFS2_LOCK_FREEING after this check,
+ * but short circuiting here will still save us some
+ * performance. */
+ spin_lock(&lockres->l_lock);
+ if (lockres->l_flags & OCFS2_LOCK_FREEING)
+ goto unqueue;
+ spin_unlock(&lockres->l_lock);
+
status = lockres->l_ops->unblock(lockres, &requeue);
if (status < 0)
mlog_errno(status);
- if (requeue)
+ spin_lock(&lockres->l_lock);
+unqueue:
+ if (lockres->l_flags & OCFS2_LOCK_FREEING || !requeue) {
+ lockres_clear_flags(lockres, OCFS2_LOCK_QUEUED);
+ } else
ocfs2_schedule_blocked_lock(osb, lockres);
mlog(0, "lockres %s, requeue = %s.\n", lockres->l_name,
requeue ? "yes" : "no");
+ spin_unlock(&lockres->l_lock);
mlog_exit_void();
}
@@ -2472,6 +2540,19 @@
{
mlog_entry_void();
+ assert_spin_locked(&lockres->l_lock);
+
+ if (lockres->l_flags & OCFS2_LOCK_FREEING) {
+ /* Do not schedule a lock for downconvert when it's on
+ * the way to destruction - any nodes wanting access
+ * to the resource will get it soon. */
+ mlog(0, "Lockres %s won't be scheduled: flags 0x%lx\n",
+ lockres->l_name, lockres->l_flags);
+ return;
+ }
+
+ lockres_or_flags(lockres, OCFS2_LOCK_QUEUED);
+
spin_lock(&osb->vote_task_lock);
if (list_empty(&lockres->l_blocked_list)) {
list_add_tail(&lockres->l_blocked_list,
@@ -2483,23 +2564,6 @@
mlog_exit_void();
}
-/* needed for inodes as we have to take a reference on them.. */
-static void ocfs2_schedule_blocked_inode_lock(struct inode *inode,
- struct ocfs2_lock_res *lockres)
-{
- mlog_entry_void();
-
- if (!igrab(inode)) {
- mlog(0, "Inode %"MLFu64" asked to be scheduled during "
- "clear_inode!\n", OCFS2_I(inode)->ip_blkno);
- return;
- }
-
- ocfs2_schedule_blocked_lock(OCFS2_SB(inode->i_sb), lockres);
-
- mlog_exit_void();
-}
-
void ocfs2_meta_lvb_set_trunc_clusters(struct inode *inode,
unsigned int trunc_clusters)
{
Modified: trunk/fs/ocfs2/dlmglue.h
===================================================================
--- trunk/fs/ocfs2/dlmglue.h 2005-07-28 18:39:03 UTC (rev 2481)
+++ trunk/fs/ocfs2/dlmglue.h 2005-07-28 21:23:00 UTC (rev 2482)
@@ -113,6 +113,8 @@
int ex);
int ocfs2_rename_lock(ocfs2_super *osb);
void ocfs2_rename_unlock(ocfs2_super *osb);
+void ocfs2_mark_lockres_freeing(struct ocfs2_lock_res *lockres);
+
/* for the vote thread */
void ocfs2_process_blocked_lock(ocfs2_super *osb,
struct ocfs2_lock_res *lockres);
Modified: trunk/fs/ocfs2/inode.c
===================================================================
--- trunk/fs/ocfs2/inode.c 2005-07-28 18:39:03 UTC (rev 2481)
+++ trunk/fs/ocfs2/inode.c 2005-07-28 21:23:00 UTC (rev 2482)
@@ -54,6 +54,7 @@
#include "buffer_head_io.h"
#define OCFS2_FI_FLAG_NOWAIT 0x1
+#define OCFS2_FI_FLAG_DELETE 0x2
struct ocfs2_find_inode_args
{
u64 fi_blkno;
@@ -69,17 +70,20 @@
struct inode *inode,
struct buffer_head *fe_bh);
-struct inode *ocfs2_ilookup(ocfs2_super *osb, u64 blkno)
+struct inode *ocfs2_ilookup_for_vote(ocfs2_super *osb,
+ u64 blkno,
+ int delete_vote)
{
struct ocfs2_find_inode_args args;
- /* ocfs2_ilookup should *only* be called from the vote thread,
- * unless modified to conditionally set
- * OCFS2_FI_FLAG_NOWAIT */
+ /* ocfs2_ilookup_for_vote should *only* be called from the
+ * vote thread */
BUG_ON(current != osb->vote_task);
args.fi_blkno = blkno;
args.fi_flags = OCFS2_FI_FLAG_NOWAIT;
+ if (delete_vote)
+ args.fi_flags |= OCFS2_FI_FLAG_DELETE;
args.fi_ino = ino_from_blkno(osb->sb, blkno);
return ilookup5(osb->sb, args.fi_ino, ocfs2_find_actor, &args);
}
@@ -147,6 +151,7 @@
static int ocfs2_find_actor(struct inode *inode, void *opaque)
{
struct ocfs2_find_inode_args *args = NULL;
+ struct ocfs2_inode_info *oi = OCFS2_I(inode);
int ret = 0;
mlog_entry("(0x%p, %lu, 0x%p)\n", inode, inode->i_ino, opaque);
@@ -155,20 +160,30 @@
mlog_bug_on_msg(!inode, "No inode in find actor!\n");
- if (OCFS2_I(inode)->ip_blkno != args->fi_blkno)
+ if (oi->ip_blkno != args->fi_blkno)
goto bail;
- /* OCFS2_FI_FLAG_NOWAIT is *only* set from ocfs2_ilookup which
- * won't create an inode for one that isn't
- * found. ocfs2_ilookup is called from the vote thread which
- * doesn't want to get an inode which is in the process of
- * going away - otherwise the call to __wait_on_freeing_inode
- * in find_inode_fast will cause it to deadlock on an inode
- * which may be waiting on a vote (or lock release) in
- * delete_inode */
+ /* OCFS2_FI_FLAG_NOWAIT is *only* set from
+ * ocfs2_ilookup_for_vote which won't create an inode for one
+ * that isn't found. The vote thread which doesn't want to get
+ * an inode which is in the process of going away - otherwise
+ * the call to __wait_on_freeing_inode in find_inode_fast will
+ * cause it to deadlock on an inode which may be waiting on a
+ * vote (or lock release) in delete_inode */
if ((args->fi_flags & OCFS2_FI_FLAG_NOWAIT) &&
- (inode->i_state & (I_FREEING|I_CLEAR)))
+ (inode->i_state & (I_FREEING|I_CLEAR))) {
+ /* As stated above, we're not going to return an
+ * inode. In the case of a delete vote, the voting
+ * code is going to signal the other node to go
+ * ahead. Mark that state here, so this freeing inode
+ * has the state when it gets to delete_inode. */
+ if (args->fi_flags & OCFS2_FI_FLAG_DELETE) {
+ spin_lock(&oi->ip_lock);
+ ocfs2_mark_inode_remotely_deleted(inode);
+ spin_unlock(&oi->ip_lock);
+ }
goto bail;
+ }
ret = 1;
bail:
@@ -676,9 +691,9 @@
/* for lack of a better error? */
status = -EEXIST;
mlog(ML_ERROR,
- "Inode %"MLFu64" (on-disk %"MLFu64") not orphaned!\n",
- OCFS2_I(inode)->ip_blkno,
- di->i_blkno);
+ "Inode %"MLFu64" (on-disk %"MLFu64") not orphaned! "
+ "Disk flags 0x%x, inode flags 0x%x\n",
+ oi->ip_blkno, di->i_blkno, di->i_flags, oi->ip_flags);
goto bail;
}
@@ -841,6 +856,11 @@
mlog_bug_on_msg(OCFS2_SB(inode->i_sb) == NULL,
"Inode=%lu\n", inode->i_ino);
+ /* Do these before all the other work so that we don't bounce
+ * the vote thread while waiting to destroy the locks. */
+ ocfs2_mark_lockres_freeing(&oi->ip_meta_lockres);
+ ocfs2_mark_lockres_freeing(&oi->ip_data_lockres);
+
/* We very well may get a clear_inode before all an inodes
* metadata has hit disk. Of course, we can't drop any cluster
* locks until the journal has finished with it. The only
Modified: trunk/fs/ocfs2/inode.h
===================================================================
--- trunk/fs/ocfs2/inode.h 2005-07-28 18:39:03 UTC (rev 2481)
+++ trunk/fs/ocfs2/inode.h 2005-07-28 21:23:00 UTC (rev 2482)
@@ -122,7 +122,9 @@
void ocfs2_delete_inode(struct inode *inode);
void ocfs2_drop_inode(struct inode *inode);
struct inode *ocfs2_iget(ocfs2_super *osb, u64 feoff);
-struct inode *ocfs2_ilookup(ocfs2_super *osb, u64 feoff);
+struct inode *ocfs2_ilookup_for_vote(ocfs2_super *osb,
+ u64 blkno,
+ int delete_vote);
int ocfs2_inode_init_private(struct inode *inode);
int ocfs2_inode_revalidate(struct dentry *dentry);
int ocfs2_populate_inode(struct inode *inode, ocfs2_dinode *fe,
Modified: trunk/fs/ocfs2/ocfs2.h
===================================================================
--- trunk/fs/ocfs2/ocfs2.h 2005-07-28 18:39:03 UTC (rev 2481)
+++ trunk/fs/ocfs2/ocfs2.h 2005-07-28 21:23:00 UTC (rev 2482)
@@ -84,7 +84,6 @@
OCFS2_UNLOCK_DROP_LOCK,
};
-
/* ocfs2_lock_res->l_flags flags. */
#define OCFS2_LOCK_ATTACHED (0x00000001) /* have we initialized
* the lvb */
@@ -97,6 +96,12 @@
#define OCFS2_LOCK_REFRESHING (0x00000020)
#define OCFS2_LOCK_INITIALIZED (0x00000040) /* track initialization
* for shutdown paths */
+#define OCFS2_LOCK_FREEING (0x00000080) /* help dlmglue track
+ * when to skip queueing
+ * a lock because it's
+ * about to be
+ * dropped. */
+#define OCFS2_LOCK_QUEUED (0x00000100) /* queued for downconvert */
struct ocfs2_lock_res_ops;
Modified: trunk/fs/ocfs2/vote.c
===================================================================
--- trunk/fs/ocfs2/vote.c 2005-07-28 18:39:03 UTC (rev 2481)
+++ trunk/fs/ocfs2/vote.c 2005-07-28 21:23:00 UTC (rev 2482)
@@ -156,6 +156,19 @@
ocfs2_node_map_set_bit(osb, &osb->umount_map, node_num);
}
+void ocfs2_mark_inode_remotely_deleted(struct inode *inode)
+{
+ struct ocfs2_inode_info *oi = OCFS2_I(inode);
+
+ assert_spin_locked(&oi->ip_lock);
+ /* We set the SKIP_DELETE flag on the inode so we don't try to
+ * delete it in delete_inode ourselves, thus avoiding
+ * unecessary lock pinging. If the other node failed to wipe
+ * the inode as a result of a crash, then recovery will pick
+ * up the slack. */
+ oi->ip_flags |= OCFS2_INODE_DELETED|OCFS2_INODE_SKIP_DELETE;
+}
+
static int ocfs2_process_delete_request(struct inode *inode,
int *orphaned_slot)
{
@@ -234,23 +247,15 @@
}
/* Mark the inode as being wiped from disk. */
- OCFS2_I(inode)->ip_flags |= OCFS2_INODE_DELETED;
-
- /* If we get here, then we're voting 'yes', so commit the
- * delete on our side. */
- response = OCFS2_RESPONSE_OK;
-
- /* We set the SKIP_DELETE flag on the inode so we don't try to
- * delete it in delete_inode ourselves, thus avoiding
- * unecessary lock pinging. If the other node failed to wipe
- * the inode as a result of a crash, then recovery will pick
- * up the slack. */
- OCFS2_I(inode)->ip_flags |= OCFS2_INODE_SKIP_DELETE;
+ ocfs2_mark_inode_remotely_deleted(inode);
spin_unlock(&OCFS2_I(inode)->ip_lock);
/* Not sure this is necessary anymore. */
d_prune_aliases(inode);
+ /* If we get here, then we're voting 'yes', so commit the
+ * delete on our side. */
+ response = OCFS2_RESPONSE_OK;
done:
return response;
}
@@ -413,7 +418,8 @@
goto respond;
/* If we get here, then the request is against an inode. */
- inode = ocfs2_ilookup(osb, blkno);
+ inode = ocfs2_ilookup_for_vote(osb, blkno,
+ request == OCFS2_VOTE_REQ_DELETE);
/* Not finding the inode is perfectly valid - it means we're
* not interested in what the other node is about to do to it
Modified: trunk/fs/ocfs2/vote.h
===================================================================
--- trunk/fs/ocfs2/vote.h 2005-07-28 18:39:03 UTC (rev 2481)
+++ trunk/fs/ocfs2/vote.h 2005-07-28 21:23:00 UTC (rev 2482)
@@ -49,6 +49,8 @@
int ocfs2_register_net_handlers(ocfs2_super *osb);
void ocfs2_unregister_net_handlers(ocfs2_super *osb);
+void ocfs2_mark_inode_remotely_deleted(struct inode *inode);
+
void ocfs2_remove_node_from_vote_queues(ocfs2_super *osb,
int node_num);
#endif
More information about the Ocfs2-commits
mailing list