[Ocfs2-commits] mfasheh commits r1889 - trunk/fs/ocfs2
svn-commits at oss.oracle.com
svn-commits at oss.oracle.com
Thu Feb 17 17:52:43 CST 2005
Author: mfasheh
Date: 2005-02-17 17:52:41 -0600 (Thu, 17 Feb 2005)
New Revision: 1889
Modified:
trunk/fs/ocfs2/dlmglue.c
Log:
* only do lvb updates on a metadata lock if it's inode resource has
been refreshed. Fixes a potential race with this where we might
never get to actually update the inode before releasing it's lock.
* better handling of signals.
Modified: trunk/fs/ocfs2/dlmglue.c
===================================================================
--- trunk/fs/ocfs2/dlmglue.c 2005-02-10 19:59:00 UTC (rev 1888)
+++ trunk/fs/ocfs2/dlmglue.c 2005-02-17 23:52:41 UTC (rev 1889)
@@ -794,9 +794,8 @@
{
LOG_ENTRY();
- wait_event_interruptible(lockres->l_event,
- !ocfs2_check_wait_flag(lockres,
- OCFS2_LOCK_BUSY));
+ wait_event(lockres->l_event,
+ !ocfs2_check_wait_flag(lockres, OCFS2_LOCK_BUSY));
LOG_EXIT();
}
@@ -804,9 +803,8 @@
{
LOG_ENTRY();
- wait_event_interruptible(lockres->l_event,
- !ocfs2_check_wait_flag(lockres,
- OCFS2_LOCK_BLOCKED));
+ wait_event(lockres->l_event,
+ !ocfs2_check_wait_flag(lockres, OCFS2_LOCK_BLOCKED));
LOG_EXIT();
}
@@ -814,9 +812,8 @@
{
LOG_ENTRY();
- wait_event_interruptible(lockres->l_event,
- !ocfs2_check_wait_flag(lockres,
- OCFS2_LOCK_REFRESHING));
+ wait_event(lockres->l_event,
+ !ocfs2_check_wait_flag(lockres, OCFS2_LOCK_REFRESHING));
LOG_EXIT();
}
@@ -837,12 +834,13 @@
int lkm_flags)
{
int ret;
+ int catch_signals = 1;
dlm_status status;
LOG_ENTRY();
again:
- if (signal_pending(current)) {
+ if (catch_signals && signal_pending(current)) {
ret = -EINTR;
goto bail;
}
@@ -920,6 +918,10 @@
lockres->l_name);
ocfs2_wait_on_busy_lock(lockres);
+
+ /* At this point we've gone inside the dlm and need to
+ * complete our work regardless. */
+ catch_signals = 0;
goto again;
}
@@ -1071,24 +1073,6 @@
LOG_EXIT();
}
-static inline int ocfs2_wait_on_recovery(ocfs_super *osb)
-{
- int ret;
-
- LOG_ENTRY();
-
- wait_event_interruptible(osb->recovery_event,
- ocfs_node_map_is_empty(osb,
- &osb->recovery_map));
-
- ret = 0;
- if (signal_pending(current))
- ret = -EINTR;
-
- LOG_EXIT_STATUS(ret);
- return ret;
-}
-
/* Call this with the lockres locked. I am reasonably sure we don't
* need ip_lock in this function as anyone who would be changing those
* values is supposed to be blocked in ocfs2_meta_lock right now.
@@ -1203,9 +1187,10 @@
/* Determine whether a lock resource needs to be refreshed, and
* arbitrate who gets to refresh it.
*
- * < 0 means error, 0 means no refresh needed, > 0 means you need to
- * refresh this and you MUST call ocfs2_complete_lock_res_refresh
- * afterwards. */
+ * 0 means no refresh needed.
+ *
+ * > 0 means you need to refresh this and you MUST call
+ * ocfs2_complete_lock_res_refresh afterwards. */
static int ocfs2_should_refresh_lock_res(ocfs2_lock_res *lockres)
{
@@ -1221,10 +1206,7 @@
if (lockres->l_flags & OCFS2_LOCK_REFRESHING) {
spin_unlock(&lockres->l_lock);
- if (signal_pending(current)) {
- status = -EINTR;
- goto bail;
- }
+
ocfs2_wait_on_refreshing_lock(lockres);
goto refresh_check;
}
@@ -1262,7 +1244,6 @@
struct buffer_head **bh)
{
int status = 0;
- int needs_refresh;
u32 trustable_clusters = 0;
ocfs2_lock_res *lockres;
ocfs2_dinode *fe;
@@ -1271,15 +1252,8 @@
lockres = &OCFS_I(inode)->ip_meta_lockres;
- needs_refresh = ocfs2_should_refresh_lock_res(lockres);
- if (!needs_refresh)
+ if (!ocfs2_should_refresh_lock_res(lockres))
goto bail;
- if (needs_refresh < 0) {
- status = needs_refresh;
- if (status != -EINTR)
- LOG_ERROR_STATUS(status);
- goto bail;
- }
if (ocfs2_lvb_is_trustable(lockres)) {
/* yay, fastpath! */
@@ -1294,7 +1268,7 @@
OCFS_BH_CACHED, inode);
if (status < 0) {
LOG_ERROR_STATUS(status);
- goto bail;
+ goto bail_refresh;
}
fe = (ocfs2_dinode *) (*bh)->b_data;
@@ -1319,7 +1293,9 @@
ocfs2_set_local_seq_from_lvb(lockres);
ocfs2_reset_meta_lvb_values(inode);
- ocfs2_complete_lock_res_refresh(lockres, 0);
+ status = 0;
+bail_refresh:
+ ocfs2_complete_lock_res_refresh(lockres, status);
bail:
LOG_EXIT_STATUS(status);
return status;
@@ -1346,12 +1322,14 @@
dprintk("inode %llu, take %s META lock\n", OCFS_I(inode)->ip_blkno,
ex ? "EXMODE" : "PRMODE");
- if (!(flags & OCFS2_META_LOCK_RECOVERY)) {
- status = ocfs2_wait_on_recovery(osb);
- if (status < 0)
- goto bail;
- }
+ if (!(flags & OCFS2_META_LOCK_RECOVERY))
+ wait_event_interruptible(osb->recovery_event,
+ ocfs_node_map_is_empty(osb,
+ &osb->recovery_map));
+ if (signal_pending(current))
+ return -EINTR;
+
lockres = &OCFS_I(inode)->ip_meta_lockres;
level = ex ? LKM_EXMODE : LKM_PRMODE;
dlm_flags = 0;
@@ -1365,11 +1343,14 @@
goto bail;
}
- if (!(flags & OCFS2_META_LOCK_RECOVERY)) {
- status = ocfs2_wait_on_recovery(osb);
- if (status < 0)
- goto bail;
- }
+ /* We wait twice because a node may have died while we were in
+ * the lower dlm layers. The second time though, we've
+ * committed to owning this lock so we don't allow signals to
+ * abort the operation. */
+ if (!(flags & OCFS2_META_LOCK_RECOVERY))
+ wait_event(osb->recovery_event,
+ ocfs_node_map_is_empty(osb,
+ &osb->recovery_map));
status = ocfs2_meta_lock_update(inode, &bh);
if (status < 0) {
@@ -1778,7 +1759,12 @@
LOG_ENTRY();
OCFS_ASSERT(new_level == LKM_NLMODE || new_level == LKM_PRMODE);
- if (new_level == LKM_PRMODE)
+
+ if (lockres->l_flags & OCFS2_LOCK_REFRESHING) {
+ ret = 0;
+ dprintk("lockres %s currently being refreshed -- backing "
+ "off!\n", lockres->l_name);
+ } else if (new_level == LKM_PRMODE)
ret = !lockres->l_ex_holders &&
ocfs_inode_fully_checkpointed(inode);
else /* Must be NLMODE we're converting to. */
@@ -1833,11 +1819,21 @@
lockres->l_level, lockres->l_blocking, new_level);
if (ocfs2_can_downconvert_meta_lock(inode, lockres, new_level)) {
- if (lockres->l_level == LKM_EXMODE) {
- __ocfs2_stuff_meta_lvb(inode);
+ if (lockres->l_level == LKM_EXMODE)
set_lvb = 1;
- }
- __ocfs2_lvb_on_downconvert(lockres, new_level);
+
+ /* If the lock hasn't been refreshed yet (rare), then our
+ * memory inode values are old and we skip stuffing
+ * the lvb. Additionally we cannot incrememnt the lvb
+ * sequence numbers */
+ if (!(lockres->l_flags & OCFS2_LOCK_NEEDS_REFRESH)) {
+ if (set_lvb)
+ __ocfs2_stuff_meta_lvb(inode);
+ __ocfs2_lvb_on_downconvert(lockres, new_level);
+ } else
+ dprintk("lockres %s: downconverting stale lock!\n",
+ lockres->l_name);
+
LOG_TRACE_ARGS("calling __ocfs2_downconvert_lock with "
"l_level=%d, l_blocking=%d, new_level=%d\n",
lockres->l_level, lockres->l_blocking,
More information about the Ocfs2-commits
mailing list