diff options
Diffstat (limited to 'fs/ocfs2')
-rw-r--r-- | fs/ocfs2/dlmglue.c | 32 |
1 files changed, 31 insertions, 1 deletions
diff --git a/fs/ocfs2/dlmglue.c b/fs/ocfs2/dlmglue.c index faa6f57db703..c8177d025d25 100644 --- a/fs/ocfs2/dlmglue.c +++ b/fs/ocfs2/dlmglue.c | |||
@@ -92,6 +92,10 @@ struct ocfs2_unblock_ctl { | |||
92 | 92 | ||
93 | static int ocfs2_unblock_meta(struct ocfs2_lock_res *lockres, | 93 | static int ocfs2_unblock_meta(struct ocfs2_lock_res *lockres, |
94 | struct ocfs2_unblock_ctl *ctl); | 94 | struct ocfs2_unblock_ctl *ctl); |
95 | static int ocfs2_check_meta_downconvert(struct ocfs2_lock_res *lockres, | ||
96 | int new_level); | ||
97 | static void ocfs2_set_meta_lvb(struct ocfs2_lock_res *lockres); | ||
98 | |||
95 | static int ocfs2_unblock_data(struct ocfs2_lock_res *lockres, | 99 | static int ocfs2_unblock_data(struct ocfs2_lock_res *lockres, |
96 | struct ocfs2_unblock_ctl *ctl); | 100 | struct ocfs2_unblock_ctl *ctl); |
97 | static int ocfs2_unblock_inode_lock(struct ocfs2_lock_res *lockres, | 101 | static int ocfs2_unblock_inode_lock(struct ocfs2_lock_res *lockres, |
@@ -179,6 +183,8 @@ static struct ocfs2_lock_res_ops ocfs2_inode_rw_lops = { | |||
179 | static struct ocfs2_lock_res_ops ocfs2_inode_meta_lops = { | 183 | static struct ocfs2_lock_res_ops ocfs2_inode_meta_lops = { |
180 | .get_osb = ocfs2_get_inode_osb, | 184 | .get_osb = ocfs2_get_inode_osb, |
181 | .unblock = ocfs2_unblock_meta, | 185 | .unblock = ocfs2_unblock_meta, |
186 | .check_downconvert = ocfs2_check_meta_downconvert, | ||
187 | .set_lvb = ocfs2_set_meta_lvb, | ||
182 | .flags = LOCK_TYPE_REQUIRES_REFRESH|LOCK_TYPE_USES_LVB, | 188 | .flags = LOCK_TYPE_REQUIRES_REFRESH|LOCK_TYPE_USES_LVB, |
183 | }; | 189 | }; |
184 | 190 | ||
@@ -2822,6 +2828,29 @@ static int ocfs2_unblock_inode_lock(struct ocfs2_lock_res *lockres, | |||
2822 | return status; | 2828 | return status; |
2823 | } | 2829 | } |
2824 | 2830 | ||
2831 | static int ocfs2_check_meta_downconvert(struct ocfs2_lock_res *lockres, | ||
2832 | int new_level) | ||
2833 | { | ||
2834 | struct inode *inode = ocfs2_lock_res_inode(lockres); | ||
2835 | int checkpointed = ocfs2_inode_fully_checkpointed(inode); | ||
2836 | |||
2837 | BUG_ON(new_level != LKM_NLMODE && new_level != LKM_PRMODE); | ||
2838 | BUG_ON(lockres->l_level != LKM_EXMODE && !checkpointed); | ||
2839 | |||
2840 | if (checkpointed) | ||
2841 | return 1; | ||
2842 | |||
2843 | ocfs2_start_checkpoint(OCFS2_SB(inode->i_sb)); | ||
2844 | return 0; | ||
2845 | } | ||
2846 | |||
2847 | static void ocfs2_set_meta_lvb(struct ocfs2_lock_res *lockres) | ||
2848 | { | ||
2849 | struct inode *inode = ocfs2_lock_res_inode(lockres); | ||
2850 | |||
2851 | __ocfs2_stuff_meta_lvb(inode); | ||
2852 | } | ||
2853 | |||
2825 | static int ocfs2_unblock_meta(struct ocfs2_lock_res *lockres, | 2854 | static int ocfs2_unblock_meta(struct ocfs2_lock_res *lockres, |
2826 | struct ocfs2_unblock_ctl *ctl) | 2855 | struct ocfs2_unblock_ctl *ctl) |
2827 | { | 2856 | { |
@@ -2835,7 +2864,8 @@ static int ocfs2_unblock_meta(struct ocfs2_lock_res *lockres, | |||
2835 | mlog(0, "unblock inode %llu\n", | 2864 | mlog(0, "unblock inode %llu\n", |
2836 | (unsigned long long)OCFS2_I(inode)->ip_blkno); | 2865 | (unsigned long long)OCFS2_I(inode)->ip_blkno); |
2837 | 2866 | ||
2838 | status = ocfs2_do_unblock_meta(inode, &ctl->requeue); | 2867 | status = ocfs2_generic_unblock_lock(OCFS2_SB(inode->i_sb), |
2868 | lockres, ctl, NULL); | ||
2839 | if (status < 0) | 2869 | if (status < 0) |
2840 | mlog_errno(status); | 2870 | mlog_errno(status); |
2841 | 2871 | ||