aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ocfs2/dlmglue.c
diff options
context:
space:
mode:
authorTao Ma <tao.ma@oracle.com>2009-08-17 23:19:58 -0400
committerJoel Becker <joel.becker@oracle.com>2009-09-22 23:09:28 -0400
commit8dec98edfe9684ce00b580a09dde3dcd21ee785b (patch)
tree3002e990974163a09ea6d427d7cf775aaca7acca /fs/ocfs2/dlmglue.c
parenta433848132d8cdfb8173745b922ddb919de11527 (diff)
ocfs2: Add new refcount tree lock resource in dlmglue.
refcount tree lock resource is used to protect refcount tree read/write among multiple nodes. Signed-off-by: Tao Ma <tao.ma@oracle.com>
Diffstat (limited to 'fs/ocfs2/dlmglue.c')
-rw-r--r--fs/ocfs2/dlmglue.c80
1 files changed, 80 insertions, 0 deletions
diff --git a/fs/ocfs2/dlmglue.c b/fs/ocfs2/dlmglue.c
index 79db0557df88..bb2fc6993e2a 100644
--- a/fs/ocfs2/dlmglue.c
+++ b/fs/ocfs2/dlmglue.c
@@ -53,6 +53,7 @@
53#include "super.h" 53#include "super.h"
54#include "uptodate.h" 54#include "uptodate.h"
55#include "quota.h" 55#include "quota.h"
56#include "refcounttree.h"
56 57
57#include "buffer_head_io.h" 58#include "buffer_head_io.h"
58 59
@@ -110,6 +111,11 @@ static void ocfs2_dentry_post_unlock(struct ocfs2_super *osb,
110 111
111static void ocfs2_set_qinfo_lvb(struct ocfs2_lock_res *lockres); 112static void ocfs2_set_qinfo_lvb(struct ocfs2_lock_res *lockres);
112 113
114static int ocfs2_check_refcount_downconvert(struct ocfs2_lock_res *lockres,
115 int new_level);
116static int ocfs2_refcount_convert_worker(struct ocfs2_lock_res *lockres,
117 int blocking);
118
113#define mlog_meta_lvb(__level, __lockres) ocfs2_dump_meta_lvb_info(__level, __PRETTY_FUNCTION__, __LINE__, __lockres) 119#define mlog_meta_lvb(__level, __lockres) ocfs2_dump_meta_lvb_info(__level, __PRETTY_FUNCTION__, __LINE__, __lockres)
114 120
115/* This aids in debugging situations where a bad LVB might be involved. */ 121/* This aids in debugging situations where a bad LVB might be involved. */
@@ -278,6 +284,12 @@ static struct ocfs2_lock_res_ops ocfs2_qinfo_lops = {
278 .flags = LOCK_TYPE_REQUIRES_REFRESH | LOCK_TYPE_USES_LVB, 284 .flags = LOCK_TYPE_REQUIRES_REFRESH | LOCK_TYPE_USES_LVB,
279}; 285};
280 286
287static struct ocfs2_lock_res_ops ocfs2_refcount_block_lops = {
288 .check_downconvert = ocfs2_check_refcount_downconvert,
289 .downconvert_worker = ocfs2_refcount_convert_worker,
290 .flags = 0,
291};
292
281static inline int ocfs2_is_inode_lock(struct ocfs2_lock_res *lockres) 293static inline int ocfs2_is_inode_lock(struct ocfs2_lock_res *lockres)
282{ 294{
283 return lockres->l_type == OCFS2_LOCK_TYPE_META || 295 return lockres->l_type == OCFS2_LOCK_TYPE_META ||
@@ -306,6 +318,12 @@ static inline struct ocfs2_mem_dqinfo *ocfs2_lock_res_qinfo(struct ocfs2_lock_re
306 return (struct ocfs2_mem_dqinfo *)lockres->l_priv; 318 return (struct ocfs2_mem_dqinfo *)lockres->l_priv;
307} 319}
308 320
321static inline struct ocfs2_refcount_tree *
322ocfs2_lock_res_refcount_tree(struct ocfs2_lock_res *res)
323{
324 return container_of(res, struct ocfs2_refcount_tree, rf_lockres);
325}
326
309static inline struct ocfs2_super *ocfs2_get_lockres_osb(struct ocfs2_lock_res *lockres) 327static inline struct ocfs2_super *ocfs2_get_lockres_osb(struct ocfs2_lock_res *lockres)
310{ 328{
311 if (lockres->l_ops->get_osb) 329 if (lockres->l_ops->get_osb)
@@ -693,6 +711,17 @@ void ocfs2_qinfo_lock_res_init(struct ocfs2_lock_res *lockres,
693 info); 711 info);
694} 712}
695 713
714void ocfs2_refcount_lock_res_init(struct ocfs2_lock_res *lockres,
715 struct ocfs2_super *osb, u64 ref_blkno,
716 unsigned int generation)
717{
718 ocfs2_lock_res_init_once(lockres);
719 ocfs2_build_lock_name(OCFS2_LOCK_TYPE_REFCOUNT, ref_blkno,
720 generation, lockres->l_name);
721 ocfs2_lock_res_init_common(osb, lockres, OCFS2_LOCK_TYPE_REFCOUNT,
722 &ocfs2_refcount_block_lops, osb);
723}
724
696void ocfs2_lock_res_free(struct ocfs2_lock_res *res) 725void ocfs2_lock_res_free(struct ocfs2_lock_res *res)
697{ 726{
698 mlog_entry_void(); 727 mlog_entry_void();
@@ -3648,6 +3677,26 @@ static int ocfs2_dentry_convert_worker(struct ocfs2_lock_res *lockres,
3648 return UNBLOCK_CONTINUE_POST; 3677 return UNBLOCK_CONTINUE_POST;
3649} 3678}
3650 3679
3680static int ocfs2_check_refcount_downconvert(struct ocfs2_lock_res *lockres,
3681 int new_level)
3682{
3683 struct ocfs2_refcount_tree *tree =
3684 ocfs2_lock_res_refcount_tree(lockres);
3685
3686 return ocfs2_ci_checkpointed(&tree->rf_ci, lockres, new_level);
3687}
3688
3689static int ocfs2_refcount_convert_worker(struct ocfs2_lock_res *lockres,
3690 int blocking)
3691{
3692 struct ocfs2_refcount_tree *tree =
3693 ocfs2_lock_res_refcount_tree(lockres);
3694
3695 ocfs2_metadata_cache_purge(&tree->rf_ci);
3696
3697 return UNBLOCK_CONTINUE;
3698}
3699
3651static void ocfs2_set_qinfo_lvb(struct ocfs2_lock_res *lockres) 3700static void ocfs2_set_qinfo_lvb(struct ocfs2_lock_res *lockres)
3652{ 3701{
3653 struct ocfs2_qinfo_lvb *lvb; 3702 struct ocfs2_qinfo_lvb *lvb;
@@ -3760,6 +3809,37 @@ bail:
3760 return status; 3809 return status;
3761} 3810}
3762 3811
3812int ocfs2_refcount_lock(struct ocfs2_refcount_tree *ref_tree, int ex)
3813{
3814 int status;
3815 int level = ex ? DLM_LOCK_EX : DLM_LOCK_PR;
3816 struct ocfs2_lock_res *lockres = &ref_tree->rf_lockres;
3817 struct ocfs2_super *osb = lockres->l_priv;
3818
3819
3820 if (ocfs2_is_hard_readonly(osb))
3821 return -EROFS;
3822
3823 if (ocfs2_mount_local(osb))
3824 return 0;
3825
3826 status = ocfs2_cluster_lock(osb, lockres, level, 0, 0);
3827 if (status < 0)
3828 mlog_errno(status);
3829
3830 return status;
3831}
3832
3833void ocfs2_refcount_unlock(struct ocfs2_refcount_tree *ref_tree, int ex)
3834{
3835 int level = ex ? DLM_LOCK_EX : DLM_LOCK_PR;
3836 struct ocfs2_lock_res *lockres = &ref_tree->rf_lockres;
3837 struct ocfs2_super *osb = lockres->l_priv;
3838
3839 if (!ocfs2_mount_local(osb))
3840 ocfs2_cluster_unlock(osb, lockres, level);
3841}
3842
3763/* 3843/*
3764 * This is the filesystem locking protocol. It provides the lock handling 3844 * This is the filesystem locking protocol. It provides the lock handling
3765 * hooks for the underlying DLM. It has a maximum version number. 3845 * hooks for the underlying DLM. It has a maximum version number.