diff options
Diffstat (limited to 'fs/ocfs2')
-rw-r--r-- | fs/ocfs2/dlmglue.c | 49 |
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, | |||
117 | static void ocfs2_dentry_post_unlock(struct ocfs2_super *osb, | 117 | static 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 | */ | ||
120 | struct ocfs2_lock_res_ops { | 125 | struct 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 | |||
128 | typedef int (ocfs2_convert_worker_t)(struct ocfs2_lock_res *, int); | 149 | typedef int (ocfs2_convert_worker_t)(struct ocfs2_lock_res *, int); |
129 | static int ocfs2_generic_unblock_lock(struct ocfs2_super *osb, | 150 | static 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 | ||
141 | static struct ocfs2_lock_res_ops ocfs2_inode_meta_lops = { | 163 | static 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 | ||
148 | static struct ocfs2_lock_res_ops ocfs2_inode_data_lops = { | 171 | static 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 | ||
155 | static struct ocfs2_lock_res_ops ocfs2_super_lops = { | 179 | static 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 | ||
162 | static struct ocfs2_lock_res_ops ocfs2_rename_lops = { | 187 | static 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 | ||
169 | static struct ocfs2_lock_res_ops ocfs2_dentry_lops = { | 195 | static 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 | ||
177 | static inline int ocfs2_is_inode_lock(struct ocfs2_lock_res *lockres) | 204 | static 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 | ||
733 | static void ocfs2_generic_ast_func(struct ocfs2_lock_res *lockres, | 758 | static 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 | ||
844 | static void ocfs2_dentry_bast_func(void *opaque, int level) | 865 | static void ocfs2_dentry_bast_func(void *opaque, int level) |