diff options
-rw-r--r-- | fs/ocfs2/dlmglue.c | 50 |
1 files changed, 32 insertions, 18 deletions
diff --git a/fs/ocfs2/dlmglue.c b/fs/ocfs2/dlmglue.c index 399d6e24b8db..d92756dcd477 100644 --- a/fs/ocfs2/dlmglue.c +++ b/fs/ocfs2/dlmglue.c | |||
@@ -71,7 +71,7 @@ static struct ocfs2_super *ocfs2_get_dentry_osb(struct ocfs2_lock_res *lockres); | |||
71 | static struct ocfs2_super *ocfs2_get_inode_osb(struct ocfs2_lock_res *lockres); | 71 | static struct ocfs2_super *ocfs2_get_inode_osb(struct ocfs2_lock_res *lockres); |
72 | 72 | ||
73 | /* | 73 | /* |
74 | * Return value from ocfs2_convert_worker_t functions. | 74 | * Return value from ->downconvert_worker functions. |
75 | * | 75 | * |
76 | * These control the precise actions of ocfs2_generic_unblock_lock() | 76 | * These control the precise actions of ocfs2_generic_unblock_lock() |
77 | * and ocfs2_process_blocked_lock() | 77 | * and ocfs2_process_blocked_lock() |
@@ -98,16 +98,23 @@ static void ocfs2_set_meta_lvb(struct ocfs2_lock_res *lockres); | |||
98 | 98 | ||
99 | static int ocfs2_unblock_data(struct ocfs2_lock_res *lockres, | 99 | static int ocfs2_unblock_data(struct ocfs2_lock_res *lockres, |
100 | struct ocfs2_unblock_ctl *ctl); | 100 | struct ocfs2_unblock_ctl *ctl); |
101 | static int ocfs2_data_convert_worker(struct ocfs2_lock_res *lockres, | ||
102 | int blocking); | ||
103 | |||
101 | static int ocfs2_unblock_inode_lock(struct ocfs2_lock_res *lockres, | 104 | static int ocfs2_unblock_inode_lock(struct ocfs2_lock_res *lockres, |
102 | struct ocfs2_unblock_ctl *ctl); | 105 | struct ocfs2_unblock_ctl *ctl); |
106 | |||
103 | static int ocfs2_unblock_dentry_lock(struct ocfs2_lock_res *lockres, | 107 | static int ocfs2_unblock_dentry_lock(struct ocfs2_lock_res *lockres, |
104 | struct ocfs2_unblock_ctl *ctl); | 108 | struct ocfs2_unblock_ctl *ctl); |
105 | static int ocfs2_unblock_osb_lock(struct ocfs2_lock_res *lockres, | 109 | static int ocfs2_dentry_convert_worker(struct ocfs2_lock_res *lockres, |
106 | struct ocfs2_unblock_ctl *ctl); | 110 | int blocking); |
107 | 111 | ||
108 | static void ocfs2_dentry_post_unlock(struct ocfs2_super *osb, | 112 | static void ocfs2_dentry_post_unlock(struct ocfs2_super *osb, |
109 | struct ocfs2_lock_res *lockres); | 113 | struct ocfs2_lock_res *lockres); |
110 | 114 | ||
115 | static int ocfs2_unblock_osb_lock(struct ocfs2_lock_res *lockres, | ||
116 | struct ocfs2_unblock_ctl *ctl); | ||
117 | |||
111 | /* | 118 | /* |
112 | * OCFS2 Lock Resource Operations | 119 | * OCFS2 Lock Resource Operations |
113 | * | 120 | * |
@@ -146,6 +153,17 @@ struct ocfs2_lock_res_ops { | |||
146 | void (*set_lvb)(struct ocfs2_lock_res *); | 153 | void (*set_lvb)(struct ocfs2_lock_res *); |
147 | 154 | ||
148 | /* | 155 | /* |
156 | * Called from the downconvert thread when it is determined | ||
157 | * that a lock will be downconverted. This is called without | ||
158 | * any locks held so the function can do work that might | ||
159 | * schedule (syncing out data, etc). | ||
160 | * | ||
161 | * This should return any one of the ocfs2_unblock_action | ||
162 | * values, depending on what it wants the thread to do. | ||
163 | */ | ||
164 | int (*downconvert_worker)(struct ocfs2_lock_res *, int); | ||
165 | |||
166 | /* | ||
149 | * LOCK_TYPE_* flags which describe the specific requirements | 167 | * LOCK_TYPE_* flags which describe the specific requirements |
150 | * of a lock type. Descriptions of each individual flag follow. | 168 | * of a lock type. Descriptions of each individual flag follow. |
151 | */ | 169 | */ |
@@ -168,11 +186,9 @@ struct ocfs2_lock_res_ops { | |||
168 | */ | 186 | */ |
169 | #define LOCK_TYPE_USES_LVB 0x2 | 187 | #define LOCK_TYPE_USES_LVB 0x2 |
170 | 188 | ||
171 | typedef int (ocfs2_convert_worker_t)(struct ocfs2_lock_res *, int); | ||
172 | static int ocfs2_generic_unblock_lock(struct ocfs2_super *osb, | 189 | static int ocfs2_generic_unblock_lock(struct ocfs2_super *osb, |
173 | struct ocfs2_lock_res *lockres, | 190 | struct ocfs2_lock_res *lockres, |
174 | struct ocfs2_unblock_ctl *ctl, | 191 | struct ocfs2_unblock_ctl *ctl); |
175 | ocfs2_convert_worker_t *worker); | ||
176 | 192 | ||
177 | static struct ocfs2_lock_res_ops ocfs2_inode_rw_lops = { | 193 | static struct ocfs2_lock_res_ops ocfs2_inode_rw_lops = { |
178 | .get_osb = ocfs2_get_inode_osb, | 194 | .get_osb = ocfs2_get_inode_osb, |
@@ -191,6 +207,7 @@ static struct ocfs2_lock_res_ops ocfs2_inode_meta_lops = { | |||
191 | static struct ocfs2_lock_res_ops ocfs2_inode_data_lops = { | 207 | static struct ocfs2_lock_res_ops ocfs2_inode_data_lops = { |
192 | .get_osb = ocfs2_get_inode_osb, | 208 | .get_osb = ocfs2_get_inode_osb, |
193 | .unblock = ocfs2_unblock_data, | 209 | .unblock = ocfs2_unblock_data, |
210 | .downconvert_worker = ocfs2_data_convert_worker, | ||
194 | .flags = 0, | 211 | .flags = 0, |
195 | }; | 212 | }; |
196 | 213 | ||
@@ -208,6 +225,7 @@ static struct ocfs2_lock_res_ops ocfs2_dentry_lops = { | |||
208 | .get_osb = ocfs2_get_dentry_osb, | 225 | .get_osb = ocfs2_get_dentry_osb, |
209 | .unblock = ocfs2_unblock_dentry_lock, | 226 | .unblock = ocfs2_unblock_dentry_lock, |
210 | .post_unlock = ocfs2_dentry_post_unlock, | 227 | .post_unlock = ocfs2_dentry_post_unlock, |
228 | .downconvert_worker = ocfs2_dentry_convert_worker, | ||
211 | .flags = 0, | 229 | .flags = 0, |
212 | }; | 230 | }; |
213 | 231 | ||
@@ -2537,8 +2555,7 @@ static int ocfs2_cancel_convert(struct ocfs2_super *osb, | |||
2537 | 2555 | ||
2538 | static int ocfs2_generic_unblock_lock(struct ocfs2_super *osb, | 2556 | static int ocfs2_generic_unblock_lock(struct ocfs2_super *osb, |
2539 | struct ocfs2_lock_res *lockres, | 2557 | struct ocfs2_lock_res *lockres, |
2540 | struct ocfs2_unblock_ctl *ctl, | 2558 | struct ocfs2_unblock_ctl *ctl) |
2541 | ocfs2_convert_worker_t *worker) | ||
2542 | { | 2559 | { |
2543 | unsigned long flags; | 2560 | unsigned long flags; |
2544 | int blocking; | 2561 | int blocking; |
@@ -2594,7 +2611,7 @@ recheck: | |||
2594 | /* If we get here, then we know that there are no more | 2611 | /* If we get here, then we know that there are no more |
2595 | * incompatible holders (and anyone asking for an incompatible | 2612 | * incompatible holders (and anyone asking for an incompatible |
2596 | * lock is blocked). We can now downconvert the lock */ | 2613 | * lock is blocked). We can now downconvert the lock */ |
2597 | if (!worker) | 2614 | if (!lockres->l_ops->downconvert_worker) |
2598 | goto downconvert; | 2615 | goto downconvert; |
2599 | 2616 | ||
2600 | /* Some lockres types want to do a bit of work before | 2617 | /* Some lockres types want to do a bit of work before |
@@ -2604,7 +2621,7 @@ recheck: | |||
2604 | blocking = lockres->l_blocking; | 2621 | blocking = lockres->l_blocking; |
2605 | spin_unlock_irqrestore(&lockres->l_lock, flags); | 2622 | spin_unlock_irqrestore(&lockres->l_lock, flags); |
2606 | 2623 | ||
2607 | ctl->unblock_action = worker(lockres, blocking); | 2624 | ctl->unblock_action = lockres->l_ops->downconvert_worker(lockres, blocking); |
2608 | 2625 | ||
2609 | if (ctl->unblock_action == UNBLOCK_STOP_POST) | 2626 | if (ctl->unblock_action == UNBLOCK_STOP_POST) |
2610 | goto leave; | 2627 | goto leave; |
@@ -2692,8 +2709,7 @@ int ocfs2_unblock_data(struct ocfs2_lock_res *lockres, | |||
2692 | mlog(0, "unblock inode %llu\n", | 2709 | mlog(0, "unblock inode %llu\n", |
2693 | (unsigned long long)OCFS2_I(inode)->ip_blkno); | 2710 | (unsigned long long)OCFS2_I(inode)->ip_blkno); |
2694 | 2711 | ||
2695 | status = ocfs2_generic_unblock_lock(osb, lockres, ctl, | 2712 | status = ocfs2_generic_unblock_lock(osb, lockres, ctl); |
2696 | ocfs2_data_convert_worker); | ||
2697 | if (status < 0) | 2713 | if (status < 0) |
2698 | mlog_errno(status); | 2714 | mlog_errno(status); |
2699 | 2715 | ||
@@ -2717,7 +2733,7 @@ static int ocfs2_unblock_inode_lock(struct ocfs2_lock_res *lockres, | |||
2717 | inode = ocfs2_lock_res_inode(lockres); | 2733 | inode = ocfs2_lock_res_inode(lockres); |
2718 | 2734 | ||
2719 | status = ocfs2_generic_unblock_lock(OCFS2_SB(inode->i_sb), | 2735 | status = ocfs2_generic_unblock_lock(OCFS2_SB(inode->i_sb), |
2720 | lockres, ctl, NULL); | 2736 | lockres, ctl); |
2721 | if (status < 0) | 2737 | if (status < 0) |
2722 | mlog_errno(status); | 2738 | mlog_errno(status); |
2723 | 2739 | ||
@@ -2762,7 +2778,7 @@ static int ocfs2_unblock_meta(struct ocfs2_lock_res *lockres, | |||
2762 | (unsigned long long)OCFS2_I(inode)->ip_blkno); | 2778 | (unsigned long long)OCFS2_I(inode)->ip_blkno); |
2763 | 2779 | ||
2764 | status = ocfs2_generic_unblock_lock(OCFS2_SB(inode->i_sb), | 2780 | status = ocfs2_generic_unblock_lock(OCFS2_SB(inode->i_sb), |
2765 | lockres, ctl, NULL); | 2781 | lockres, ctl); |
2766 | if (status < 0) | 2782 | if (status < 0) |
2767 | mlog_errno(status); | 2783 | mlog_errno(status); |
2768 | 2784 | ||
@@ -2907,8 +2923,7 @@ static int ocfs2_unblock_dentry_lock(struct ocfs2_lock_res *lockres, | |||
2907 | 2923 | ||
2908 | ret = ocfs2_generic_unblock_lock(osb, | 2924 | ret = ocfs2_generic_unblock_lock(osb, |
2909 | lockres, | 2925 | lockres, |
2910 | ctl, | 2926 | ctl); |
2911 | ocfs2_dentry_convert_worker); | ||
2912 | if (ret < 0) | 2927 | if (ret < 0) |
2913 | mlog_errno(ret); | 2928 | mlog_errno(ret); |
2914 | 2929 | ||
@@ -2933,8 +2948,7 @@ static int ocfs2_unblock_osb_lock(struct ocfs2_lock_res *lockres, | |||
2933 | 2948 | ||
2934 | status = ocfs2_generic_unblock_lock(osb, | 2949 | status = ocfs2_generic_unblock_lock(osb, |
2935 | lockres, | 2950 | lockres, |
2936 | ctl, | 2951 | ctl); |
2937 | NULL); | ||
2938 | if (status < 0) | 2952 | if (status < 0) |
2939 | mlog_errno(status); | 2953 | mlog_errno(status); |
2940 | 2954 | ||