aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ocfs2/dlmglue.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/ocfs2/dlmglue.c')
-rw-r--r--fs/ocfs2/dlmglue.c49
1 files changed, 35 insertions, 14 deletions
diff --git a/fs/ocfs2/dlmglue.c b/fs/ocfs2/dlmglue.c
index ecb3cba22814..c1891787fb9d 100644
--- a/fs/ocfs2/dlmglue.c
+++ b/fs/ocfs2/dlmglue.c
@@ -117,14 +117,35 @@ static int ocfs2_unblock_osb_lock(struct ocfs2_lock_res *lockres,
117static void ocfs2_dentry_post_unlock(struct ocfs2_super *osb, 117static void ocfs2_dentry_post_unlock(struct ocfs2_super *osb,
118 struct ocfs2_lock_res *lockres); 118 struct ocfs2_lock_res *lockres);
119 119
120/*
121 * OCFS2 Lock Resource Operations
122 *
123 * These fine tune the behavior of the generic dlmglue locking infrastructure.
124 */
120struct ocfs2_lock_res_ops { 125struct ocfs2_lock_res_ops {
121 void (*ast)(void *); 126 void (*ast)(void *);
122 void (*bast)(void *, int); 127 void (*bast)(void *, int);
123 void (*unlock_ast)(void *, enum dlm_status); 128 void (*unlock_ast)(void *, enum dlm_status);
124 int (*unblock)(struct ocfs2_lock_res *, struct ocfs2_unblock_ctl *); 129 int (*unblock)(struct ocfs2_lock_res *, struct ocfs2_unblock_ctl *);
125 void (*post_unlock)(struct ocfs2_super *, struct ocfs2_lock_res *); 130 void (*post_unlock)(struct ocfs2_super *, struct ocfs2_lock_res *);
131
132 /*
133 * LOCK_TYPE_* flags which describe the specific requirements
134 * of a lock type. Descriptions of each individual flag follow.
135 */
136 int flags;
126}; 137};
127 138
139/*
140 * Some locks want to "refresh" potentially stale data when a
141 * meaningful (PRMODE or EXMODE) lock level is first obtained. If this
142 * flag is set, the OCFS2_LOCK_NEEDS_REFRESH flag will be set on the
143 * individual lockres l_flags member from the ast function. It is
144 * expected that the locking wrapper will clear the
145 * OCFS2_LOCK_NEEDS_REFRESH flag when done.
146 */
147#define LOCK_TYPE_REQUIRES_REFRESH 0x1
148
128typedef int (ocfs2_convert_worker_t)(struct ocfs2_lock_res *, int); 149typedef int (ocfs2_convert_worker_t)(struct ocfs2_lock_res *, int);
129static int ocfs2_generic_unblock_lock(struct ocfs2_super *osb, 150static int ocfs2_generic_unblock_lock(struct ocfs2_super *osb,
130 struct ocfs2_lock_res *lockres, 151 struct ocfs2_lock_res *lockres,
@@ -136,6 +157,7 @@ static struct ocfs2_lock_res_ops ocfs2_inode_rw_lops = {
136 .bast = ocfs2_inode_bast_func, 157 .bast = ocfs2_inode_bast_func,
137 .unlock_ast = ocfs2_unlock_ast_func, 158 .unlock_ast = ocfs2_unlock_ast_func,
138 .unblock = ocfs2_unblock_inode_lock, 159 .unblock = ocfs2_unblock_inode_lock,
160 .flags = 0,
139}; 161};
140 162
141static struct ocfs2_lock_res_ops ocfs2_inode_meta_lops = { 163static struct ocfs2_lock_res_ops ocfs2_inode_meta_lops = {
@@ -143,6 +165,7 @@ static struct ocfs2_lock_res_ops ocfs2_inode_meta_lops = {
143 .bast = ocfs2_inode_bast_func, 165 .bast = ocfs2_inode_bast_func,
144 .unlock_ast = ocfs2_unlock_ast_func, 166 .unlock_ast = ocfs2_unlock_ast_func,
145 .unblock = ocfs2_unblock_meta, 167 .unblock = ocfs2_unblock_meta,
168 .flags = LOCK_TYPE_REQUIRES_REFRESH,
146}; 169};
147 170
148static struct ocfs2_lock_res_ops ocfs2_inode_data_lops = { 171static struct ocfs2_lock_res_ops ocfs2_inode_data_lops = {
@@ -150,6 +173,7 @@ static struct ocfs2_lock_res_ops ocfs2_inode_data_lops = {
150 .bast = ocfs2_inode_bast_func, 173 .bast = ocfs2_inode_bast_func,
151 .unlock_ast = ocfs2_unlock_ast_func, 174 .unlock_ast = ocfs2_unlock_ast_func,
152 .unblock = ocfs2_unblock_data, 175 .unblock = ocfs2_unblock_data,
176 .flags = 0,
153}; 177};
154 178
155static struct ocfs2_lock_res_ops ocfs2_super_lops = { 179static struct ocfs2_lock_res_ops ocfs2_super_lops = {
@@ -157,6 +181,7 @@ static struct ocfs2_lock_res_ops ocfs2_super_lops = {
157 .bast = ocfs2_super_bast_func, 181 .bast = ocfs2_super_bast_func,
158 .unlock_ast = ocfs2_unlock_ast_func, 182 .unlock_ast = ocfs2_unlock_ast_func,
159 .unblock = ocfs2_unblock_osb_lock, 183 .unblock = ocfs2_unblock_osb_lock,
184 .flags = LOCK_TYPE_REQUIRES_REFRESH,
160}; 185};
161 186
162static struct ocfs2_lock_res_ops ocfs2_rename_lops = { 187static struct ocfs2_lock_res_ops ocfs2_rename_lops = {
@@ -164,6 +189,7 @@ static struct ocfs2_lock_res_ops ocfs2_rename_lops = {
164 .bast = ocfs2_rename_bast_func, 189 .bast = ocfs2_rename_bast_func,
165 .unlock_ast = ocfs2_unlock_ast_func, 190 .unlock_ast = ocfs2_unlock_ast_func,
166 .unblock = ocfs2_unblock_osb_lock, 191 .unblock = ocfs2_unblock_osb_lock,
192 .flags = 0,
167}; 193};
168 194
169static struct ocfs2_lock_res_ops ocfs2_dentry_lops = { 195static struct ocfs2_lock_res_ops ocfs2_dentry_lops = {
@@ -172,6 +198,7 @@ static struct ocfs2_lock_res_ops ocfs2_dentry_lops = {
172 .unlock_ast = ocfs2_unlock_ast_func, 198 .unlock_ast = ocfs2_unlock_ast_func,
173 .unblock = ocfs2_unblock_dentry_lock, 199 .unblock = ocfs2_unblock_dentry_lock,
174 .post_unlock = ocfs2_dentry_post_unlock, 200 .post_unlock = ocfs2_dentry_post_unlock,
201 .flags = 0,
175}; 202};
176 203
177static inline int ocfs2_is_inode_lock(struct ocfs2_lock_res *lockres) 204static inline int ocfs2_is_inode_lock(struct ocfs2_lock_res *lockres)
@@ -569,7 +596,8 @@ static inline void ocfs2_generic_handle_convert_action(struct ocfs2_lock_res *lo
569 * information is already up to data. Convert from NL to 596 * information is already up to data. Convert from NL to
570 * *anything* however should mark ourselves as needing an 597 * *anything* however should mark ourselves as needing an
571 * update */ 598 * update */
572 if (lockres->l_level == LKM_NLMODE) 599 if (lockres->l_level == LKM_NLMODE &&
600 lockres->l_ops->flags & LOCK_TYPE_REQUIRES_REFRESH)
573 lockres_or_flags(lockres, OCFS2_LOCK_NEEDS_REFRESH); 601 lockres_or_flags(lockres, OCFS2_LOCK_NEEDS_REFRESH);
574 602
575 lockres->l_level = lockres->l_requested; 603 lockres->l_level = lockres->l_requested;
@@ -586,7 +614,8 @@ static inline void ocfs2_generic_handle_attach_action(struct ocfs2_lock_res *loc
586 BUG_ON(lockres->l_flags & OCFS2_LOCK_ATTACHED); 614 BUG_ON(lockres->l_flags & OCFS2_LOCK_ATTACHED);
587 615
588 if (lockres->l_requested > LKM_NLMODE && 616 if (lockres->l_requested > LKM_NLMODE &&
589 !(lockres->l_flags & OCFS2_LOCK_LOCAL)) 617 !(lockres->l_flags & OCFS2_LOCK_LOCAL) &&
618 lockres->l_ops->flags & LOCK_TYPE_REQUIRES_REFRESH)
590 lockres_or_flags(lockres, OCFS2_LOCK_NEEDS_REFRESH); 619 lockres_or_flags(lockres, OCFS2_LOCK_NEEDS_REFRESH);
591 620
592 lockres->l_level = lockres->l_requested; 621 lockres->l_level = lockres->l_requested;
@@ -645,10 +674,6 @@ static void ocfs2_inode_ast_func(void *opaque)
645 BUG(); 674 BUG();
646 } 675 }
647 676
648 /* data and rw locking ignores refresh flag for now. */
649 if (lockres->l_type != OCFS2_LOCK_TYPE_META)
650 lockres_clear_flags(lockres, OCFS2_LOCK_NEEDS_REFRESH);
651
652 /* set it to something invalid so if we get called again we 677 /* set it to something invalid so if we get called again we
653 * can catch it. */ 678 * can catch it. */
654 lockres->l_action = OCFS2_AST_INVALID; 679 lockres->l_action = OCFS2_AST_INVALID;
@@ -730,8 +755,7 @@ static void ocfs2_inode_bast_func(void *opaque, int level)
730 mlog_exit_void(); 755 mlog_exit_void();
731} 756}
732 757
733static void ocfs2_generic_ast_func(struct ocfs2_lock_res *lockres, 758static void ocfs2_generic_ast_func(struct ocfs2_lock_res *lockres)
734 int ignore_refresh)
735{ 759{
736 struct dlm_lockstatus *lksb = &lockres->l_lksb; 760 struct dlm_lockstatus *lksb = &lockres->l_lksb;
737 unsigned long flags; 761 unsigned long flags;
@@ -759,9 +783,6 @@ static void ocfs2_generic_ast_func(struct ocfs2_lock_res *lockres,
759 BUG(); 783 BUG();
760 } 784 }
761 785
762 if (ignore_refresh)
763 lockres_clear_flags(lockres, OCFS2_LOCK_NEEDS_REFRESH);
764
765 /* set it to something invalid so if we get called again we 786 /* set it to something invalid so if we get called again we
766 * can catch it. */ 787 * can catch it. */
767 lockres->l_action = OCFS2_AST_INVALID; 788 lockres->l_action = OCFS2_AST_INVALID;
@@ -778,7 +799,7 @@ static void ocfs2_super_ast_func(void *opaque)
778 mlog(0, "Superblock AST fired\n"); 799 mlog(0, "Superblock AST fired\n");
779 800
780 BUG_ON(!ocfs2_is_super_lock(lockres)); 801 BUG_ON(!ocfs2_is_super_lock(lockres));
781 ocfs2_generic_ast_func(lockres, 0); 802 ocfs2_generic_ast_func(lockres);
782 803
783 mlog_exit_void(); 804 mlog_exit_void();
784} 805}
@@ -809,7 +830,7 @@ static void ocfs2_rename_ast_func(void *opaque)
809 830
810 BUG_ON(!ocfs2_is_rename_lock(lockres)); 831 BUG_ON(!ocfs2_is_rename_lock(lockres));
811 832
812 ocfs2_generic_ast_func(lockres, 1); 833 ocfs2_generic_ast_func(lockres);
813 834
814 mlog_exit_void(); 835 mlog_exit_void();
815} 836}
@@ -838,7 +859,7 @@ static void ocfs2_dentry_ast_func(void *opaque)
838 859
839 BUG_ON(!lockres); 860 BUG_ON(!lockres);
840 861
841 ocfs2_generic_ast_func(lockres, 1); 862 ocfs2_generic_ast_func(lockres);
842} 863}
843 864
844static void ocfs2_dentry_bast_func(void *opaque, int level) 865static void ocfs2_dentry_bast_func(void *opaque, int level)