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.c146
1 files changed, 146 insertions, 0 deletions
diff --git a/fs/ocfs2/dlmglue.c b/fs/ocfs2/dlmglue.c
index 9f2a7f75d1b3..058aa86490ae 100644
--- a/fs/ocfs2/dlmglue.c
+++ b/fs/ocfs2/dlmglue.c
@@ -32,6 +32,7 @@
32#include <linux/debugfs.h> 32#include <linux/debugfs.h>
33#include <linux/seq_file.h> 33#include <linux/seq_file.h>
34#include <linux/time.h> 34#include <linux/time.h>
35#include <linux/quotaops.h>
35 36
36#define MLOG_MASK_PREFIX ML_DLM_GLUE 37#define MLOG_MASK_PREFIX ML_DLM_GLUE
37#include <cluster/masklog.h> 38#include <cluster/masklog.h>
@@ -51,6 +52,7 @@
51#include "slot_map.h" 52#include "slot_map.h"
52#include "super.h" 53#include "super.h"
53#include "uptodate.h" 54#include "uptodate.h"
55#include "quota.h"
54 56
55#include "buffer_head_io.h" 57#include "buffer_head_io.h"
56 58
@@ -68,6 +70,7 @@ struct ocfs2_mask_waiter {
68static struct ocfs2_super *ocfs2_get_dentry_osb(struct ocfs2_lock_res *lockres); 70static struct ocfs2_super *ocfs2_get_dentry_osb(struct ocfs2_lock_res *lockres);
69static struct ocfs2_super *ocfs2_get_inode_osb(struct ocfs2_lock_res *lockres); 71static struct ocfs2_super *ocfs2_get_inode_osb(struct ocfs2_lock_res *lockres);
70static struct ocfs2_super *ocfs2_get_file_osb(struct ocfs2_lock_res *lockres); 72static struct ocfs2_super *ocfs2_get_file_osb(struct ocfs2_lock_res *lockres);
73static struct ocfs2_super *ocfs2_get_qinfo_osb(struct ocfs2_lock_res *lockres);
71 74
72/* 75/*
73 * Return value from ->downconvert_worker functions. 76 * Return value from ->downconvert_worker functions.
@@ -102,6 +105,7 @@ static int ocfs2_dentry_convert_worker(struct ocfs2_lock_res *lockres,
102static void ocfs2_dentry_post_unlock(struct ocfs2_super *osb, 105static void ocfs2_dentry_post_unlock(struct ocfs2_super *osb,
103 struct ocfs2_lock_res *lockres); 106 struct ocfs2_lock_res *lockres);
104 107
108static void ocfs2_set_qinfo_lvb(struct ocfs2_lock_res *lockres);
105 109
106#define mlog_meta_lvb(__level, __lockres) ocfs2_dump_meta_lvb_info(__level, __PRETTY_FUNCTION__, __LINE__, __lockres) 110#define mlog_meta_lvb(__level, __lockres) ocfs2_dump_meta_lvb_info(__level, __PRETTY_FUNCTION__, __LINE__, __lockres)
107 111
@@ -258,6 +262,12 @@ static struct ocfs2_lock_res_ops ocfs2_flock_lops = {
258 .flags = 0, 262 .flags = 0,
259}; 263};
260 264
265static struct ocfs2_lock_res_ops ocfs2_qinfo_lops = {
266 .set_lvb = ocfs2_set_qinfo_lvb,
267 .get_osb = ocfs2_get_qinfo_osb,
268 .flags = LOCK_TYPE_REQUIRES_REFRESH | LOCK_TYPE_USES_LVB,
269};
270
261static inline int ocfs2_is_inode_lock(struct ocfs2_lock_res *lockres) 271static inline int ocfs2_is_inode_lock(struct ocfs2_lock_res *lockres)
262{ 272{
263 return lockres->l_type == OCFS2_LOCK_TYPE_META || 273 return lockres->l_type == OCFS2_LOCK_TYPE_META ||
@@ -279,6 +289,13 @@ static inline struct ocfs2_dentry_lock *ocfs2_lock_res_dl(struct ocfs2_lock_res
279 return (struct ocfs2_dentry_lock *)lockres->l_priv; 289 return (struct ocfs2_dentry_lock *)lockres->l_priv;
280} 290}
281 291
292static inline struct ocfs2_mem_dqinfo *ocfs2_lock_res_qinfo(struct ocfs2_lock_res *lockres)
293{
294 BUG_ON(lockres->l_type != OCFS2_LOCK_TYPE_QINFO);
295
296 return (struct ocfs2_mem_dqinfo *)lockres->l_priv;
297}
298
282static inline struct ocfs2_super *ocfs2_get_lockres_osb(struct ocfs2_lock_res *lockres) 299static inline struct ocfs2_super *ocfs2_get_lockres_osb(struct ocfs2_lock_res *lockres)
283{ 300{
284 if (lockres->l_ops->get_osb) 301 if (lockres->l_ops->get_osb)
@@ -507,6 +524,13 @@ static struct ocfs2_super *ocfs2_get_inode_osb(struct ocfs2_lock_res *lockres)
507 return OCFS2_SB(inode->i_sb); 524 return OCFS2_SB(inode->i_sb);
508} 525}
509 526
527static struct ocfs2_super *ocfs2_get_qinfo_osb(struct ocfs2_lock_res *lockres)
528{
529 struct ocfs2_mem_dqinfo *info = lockres->l_priv;
530
531 return OCFS2_SB(info->dqi_gi.dqi_sb);
532}
533
510static struct ocfs2_super *ocfs2_get_file_osb(struct ocfs2_lock_res *lockres) 534static struct ocfs2_super *ocfs2_get_file_osb(struct ocfs2_lock_res *lockres)
511{ 535{
512 struct ocfs2_file_private *fp = lockres->l_priv; 536 struct ocfs2_file_private *fp = lockres->l_priv;
@@ -609,6 +633,17 @@ void ocfs2_file_lock_res_init(struct ocfs2_lock_res *lockres,
609 lockres->l_flags |= OCFS2_LOCK_NOCACHE; 633 lockres->l_flags |= OCFS2_LOCK_NOCACHE;
610} 634}
611 635
636void ocfs2_qinfo_lock_res_init(struct ocfs2_lock_res *lockres,
637 struct ocfs2_mem_dqinfo *info)
638{
639 ocfs2_lock_res_init_once(lockres);
640 ocfs2_build_lock_name(OCFS2_LOCK_TYPE_QINFO, info->dqi_gi.dqi_type,
641 0, lockres->l_name);
642 ocfs2_lock_res_init_common(OCFS2_SB(info->dqi_gi.dqi_sb), lockres,
643 OCFS2_LOCK_TYPE_QINFO, &ocfs2_qinfo_lops,
644 info);
645}
646
612void ocfs2_lock_res_free(struct ocfs2_lock_res *res) 647void ocfs2_lock_res_free(struct ocfs2_lock_res *res)
613{ 648{
614 mlog_entry_void(); 649 mlog_entry_void();
@@ -3445,6 +3480,117 @@ static int ocfs2_dentry_convert_worker(struct ocfs2_lock_res *lockres,
3445 return UNBLOCK_CONTINUE_POST; 3480 return UNBLOCK_CONTINUE_POST;
3446} 3481}
3447 3482
3483static void ocfs2_set_qinfo_lvb(struct ocfs2_lock_res *lockres)
3484{
3485 struct ocfs2_qinfo_lvb *lvb;
3486 struct ocfs2_mem_dqinfo *oinfo = ocfs2_lock_res_qinfo(lockres);
3487 struct mem_dqinfo *info = sb_dqinfo(oinfo->dqi_gi.dqi_sb,
3488 oinfo->dqi_gi.dqi_type);
3489
3490 mlog_entry_void();
3491
3492 lvb = (struct ocfs2_qinfo_lvb *)ocfs2_dlm_lvb(&lockres->l_lksb);
3493 lvb->lvb_version = OCFS2_QINFO_LVB_VERSION;
3494 lvb->lvb_bgrace = cpu_to_be32(info->dqi_bgrace);
3495 lvb->lvb_igrace = cpu_to_be32(info->dqi_igrace);
3496 lvb->lvb_syncms = cpu_to_be32(oinfo->dqi_syncms);
3497 lvb->lvb_blocks = cpu_to_be32(oinfo->dqi_gi.dqi_blocks);
3498 lvb->lvb_free_blk = cpu_to_be32(oinfo->dqi_gi.dqi_free_blk);
3499 lvb->lvb_free_entry = cpu_to_be32(oinfo->dqi_gi.dqi_free_entry);
3500
3501 mlog_exit_void();
3502}
3503
3504void ocfs2_qinfo_unlock(struct ocfs2_mem_dqinfo *oinfo, int ex)
3505{
3506 struct ocfs2_lock_res *lockres = &oinfo->dqi_gqlock;
3507 struct ocfs2_super *osb = OCFS2_SB(oinfo->dqi_gi.dqi_sb);
3508 int level = ex ? DLM_LOCK_EX : DLM_LOCK_PR;
3509
3510 mlog_entry_void();
3511 if (!ocfs2_is_hard_readonly(osb) && !ocfs2_mount_local(osb))
3512 ocfs2_cluster_unlock(osb, lockres, level);
3513 mlog_exit_void();
3514}
3515
3516static int ocfs2_refresh_qinfo(struct ocfs2_mem_dqinfo *oinfo)
3517{
3518 struct mem_dqinfo *info = sb_dqinfo(oinfo->dqi_gi.dqi_sb,
3519 oinfo->dqi_gi.dqi_type);
3520 struct ocfs2_lock_res *lockres = &oinfo->dqi_gqlock;
3521 struct ocfs2_qinfo_lvb *lvb = ocfs2_dlm_lvb(&lockres->l_lksb);
3522 struct buffer_head *bh;
3523 struct ocfs2_global_disk_dqinfo *gdinfo;
3524 int status = 0;
3525
3526 if (lvb->lvb_version == OCFS2_QINFO_LVB_VERSION) {
3527 info->dqi_bgrace = be32_to_cpu(lvb->lvb_bgrace);
3528 info->dqi_igrace = be32_to_cpu(lvb->lvb_igrace);
3529 oinfo->dqi_syncms = be32_to_cpu(lvb->lvb_syncms);
3530 oinfo->dqi_gi.dqi_blocks = be32_to_cpu(lvb->lvb_blocks);
3531 oinfo->dqi_gi.dqi_free_blk = be32_to_cpu(lvb->lvb_free_blk);
3532 oinfo->dqi_gi.dqi_free_entry =
3533 be32_to_cpu(lvb->lvb_free_entry);
3534 } else {
3535 bh = ocfs2_read_quota_block(oinfo->dqi_gqinode, 0, &status);
3536 if (!bh) {
3537 mlog_errno(status);
3538 goto bail;
3539 }
3540 gdinfo = (struct ocfs2_global_disk_dqinfo *)
3541 (bh->b_data + OCFS2_GLOBAL_INFO_OFF);
3542 info->dqi_bgrace = le32_to_cpu(gdinfo->dqi_bgrace);
3543 info->dqi_igrace = le32_to_cpu(gdinfo->dqi_igrace);
3544 oinfo->dqi_syncms = le32_to_cpu(gdinfo->dqi_syncms);
3545 oinfo->dqi_gi.dqi_blocks = le32_to_cpu(gdinfo->dqi_blocks);
3546 oinfo->dqi_gi.dqi_free_blk = le32_to_cpu(gdinfo->dqi_free_blk);
3547 oinfo->dqi_gi.dqi_free_entry =
3548 le32_to_cpu(gdinfo->dqi_free_entry);
3549 brelse(bh);
3550 ocfs2_track_lock_refresh(lockres);
3551 }
3552
3553bail:
3554 return status;
3555}
3556
3557/* Lock quota info, this function expects at least shared lock on the quota file
3558 * so that we can safely refresh quota info from disk. */
3559int ocfs2_qinfo_lock(struct ocfs2_mem_dqinfo *oinfo, int ex)
3560{
3561 struct ocfs2_lock_res *lockres = &oinfo->dqi_gqlock;
3562 struct ocfs2_super *osb = OCFS2_SB(oinfo->dqi_gi.dqi_sb);
3563 int level = ex ? DLM_LOCK_EX : DLM_LOCK_PR;
3564 int status = 0;
3565
3566 mlog_entry_void();
3567
3568 /* On RO devices, locking really isn't needed... */
3569 if (ocfs2_is_hard_readonly(osb)) {
3570 if (ex)
3571 status = -EROFS;
3572 goto bail;
3573 }
3574 if (ocfs2_mount_local(osb))
3575 goto bail;
3576
3577 status = ocfs2_cluster_lock(osb, lockres, level, 0, 0);
3578 if (status < 0) {
3579 mlog_errno(status);
3580 goto bail;
3581 }
3582 if (!ocfs2_should_refresh_lock_res(lockres))
3583 goto bail;
3584 /* OK, we have the lock but we need to refresh the quota info */
3585 status = ocfs2_refresh_qinfo(oinfo);
3586 if (status)
3587 ocfs2_qinfo_unlock(oinfo, ex);
3588 ocfs2_complete_lock_res_refresh(lockres, status);
3589bail:
3590 mlog_exit(status);
3591 return status;
3592}
3593
3448/* 3594/*
3449 * This is the filesystem locking protocol. It provides the lock handling 3595 * This is the filesystem locking protocol. It provides the lock handling
3450 * hooks for the underlying DLM. It has a maximum version number. 3596 * hooks for the underlying DLM. It has a maximum version number.