scoutfs: publish refresh_gen from dlmglue

In addition to setting NEEDS_REFRESH when locks are acquired out of NL,
we now also give them a refresh_gen counter that is increased by
incrementing a long lived counter in the super.

This gives callers a strictly increasing read-only indication that the
lock has changed.  They don't have to serialize users to clear
NEEDS_REFRESH and transfer it to some other serialized state.

scoutfs will use with the multiple inodes that are refreshed with
respect to the lock's refresh_gen.

Signed-off-by: Zach Brown <zab@versity.com>
This commit is contained in:
Zach Brown
2017-08-30 10:37:59 -07:00
parent 51e03dcb7a
commit d2a1b915fc
2 changed files with 35 additions and 2 deletions
+29 -2
View File
@@ -909,6 +909,23 @@ static void lockres_clear_flags(struct ocfs2_lock_res *lockres,
lockres_set_flags(lockres, lockres->l_flags & ~clear);
}
/*
* Make sure that a lock gets a strictly increasing number only once
* each time it needs to be refreshed. The gen needs to be larger than
* any previous gen the locked resources has seen so we maintain the gen
* in the super. The caller has serialized on the lock but lots of
* locks can all be racing on the super.
*
* This is used by callers to have a single read-only indicator that
* they need to refresh their resource while they have it locked.
*/
static void lockres_inc_refresh_gen(struct ocfs2_lock_res *lockres)
{
struct ocfs2_super *osb = ocfs2_get_lockres_osb(lockres);
lockres->l_refresh_gen = atomic64_inc_return(&osb->refresh_gen);
}
static inline void ocfs2_generic_handle_downconvert_action(struct ocfs2_lock_res *lockres)
{
BUG_ON(!(lockres->l_flags & OCFS2_LOCK_BUSY));
@@ -935,8 +952,10 @@ static inline void ocfs2_generic_handle_convert_action(struct ocfs2_lock_res *lo
* *anything* however should mark ourselves as needing an
* update */
if (lockres->l_level == DLM_LOCK_NL &&
lockres->l_ops->flags & LOCK_TYPE_REQUIRES_REFRESH)
lockres->l_ops->flags & LOCK_TYPE_REQUIRES_REFRESH) {
lockres_or_flags(lockres, OCFS2_LOCK_NEEDS_REFRESH);
lockres_inc_refresh_gen(lockres);
}
lockres->l_level = lockres->l_requested;
@@ -962,8 +981,10 @@ static inline void ocfs2_generic_handle_attach_action(struct ocfs2_lock_res *loc
if (lockres->l_requested > DLM_LOCK_NL &&
!(lockres->l_flags & OCFS2_LOCK_LOCAL) &&
lockres->l_ops->flags & LOCK_TYPE_REQUIRES_REFRESH)
lockres->l_ops->flags & LOCK_TYPE_REQUIRES_REFRESH) {
lockres_or_flags(lockres, OCFS2_LOCK_NEEDS_REFRESH);
lockres_inc_refresh_gen(lockres);
}
lockres->l_level = lockres->l_requested;
lockres_or_flags(lockres, OCFS2_LOCK_ATTACHED);
@@ -2294,6 +2315,11 @@ static inline void ocfs2_complete_lock_res_refresh(struct ocfs2_lock_res *lockre
wake_up(&lockres->l_event);
}
u64 ocfs2_lock_refresh_gen(struct ocfs2_lock_res *lockres)
{
return lockres->l_refresh_gen;
}
#if 0
/* may or may not return a bh if it went to disk. */
static int ocfs2_inode_lock_update(struct inode *inode,
@@ -4291,6 +4317,7 @@ int ocfs2_init_super(struct ocfs2_super *osb, int flags)
init_waitqueue_head(&osb->dc_event);
INIT_LIST_HEAD(&osb->blocked_lock_list);
osb->s_mount_opt = flags;
atomic64_set(&osb->refresh_gen, 0);
return 0;
}
+6
View File
@@ -103,6 +103,7 @@ struct ocfs2_lock_res {
struct list_head l_mask_waiters;
struct list_head l_holders;
u64 l_refresh_gen;
unsigned long l_flags;
char l_name[OCFS2_LOCK_ID_MAX_LEN];
unsigned int l_ro_holders;
@@ -167,6 +168,9 @@ struct ocfs2_super
struct list_head blocked_lock_list;
unsigned long blocked_lock_count;
/* refresh_gen needs to strictly increase as locks come and go */
atomic64_t refresh_gen;
unsigned long s_mount_opt;
};
/* For s_mount_opt */
@@ -317,6 +321,8 @@ void ocfs2_lock_res_init_common(struct ocfs2_super *osb,
void *priv);
void ocfs2_lock_res_free(struct ocfs2_lock_res *res);
u64 ocfs2_lock_refresh_gen(struct ocfs2_lock_res *lockres);
void ocfs2_mark_lockres_freeing(struct ocfs2_super *osb,
struct ocfs2_lock_res *lockres);
void ocfs2_simple_drop_lockres(struct ocfs2_super *osb,