All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jan Kara <jack@suse.cz>
To: ocfs2-devel@oss.oracle.com
Subject: [Ocfs2-devel] [PATCH 27/29] ocfs2: Implement quota syncing thread
Date: Sat, 25 Oct 2008 00:08:20 +0200	[thread overview]
Message-ID: <1224886104833-git-send-email-jack@suse.cz> (raw)
In-Reply-To: <122488610212-git-send-email-jack@suse.cz>

This patch implements functions and timer setup which handles periodic
syncing of locally cached quota information to global quota file.

Signed-off-by: Jan Kara <jack@suse.cz>
---
 fs/ocfs2/quota.h        |    3 ++
 fs/ocfs2/quota_global.c |   71 +++++++++++++++++++++++++++++++++++++++++++++++
 fs/ocfs2/quota_local.c  |    4 ++
 3 files changed, 78 insertions(+), 0 deletions(-)

diff --git a/fs/ocfs2/quota.h b/fs/ocfs2/quota.h
index 87545ca..179c635 100644
--- a/fs/ocfs2/quota.h
+++ b/fs/ocfs2/quota.h
@@ -14,6 +14,7 @@
 #include <linux/quota.h>
 #include <linux/list.h>
 #include <linux/dqblk_qtree.h>
+#include <linux/timer.h>
 
 #include "ocfs2.h"
 
@@ -43,6 +44,7 @@ struct ocfs2_mem_dqinfo {
 	unsigned int dqi_chunks;	/* Number of chunks in local quota file */
 	unsigned int dqi_blocks;	/* Number of blocks allocated for local quota file */
 	unsigned int dqi_syncms;	/* How often should we sync with other nodes */
+	unsigned int dqi_syncjiff;	/* Precomputed dqi_syncms in jiffies */
 	struct list_head dqi_chunk;	/* List of chunks */
 	struct inode *dqi_gqinode;	/* Global quota file inode */
 	struct ocfs2_lock_res dqi_gqlock;	/* Lock protecting quota information structure */
@@ -51,6 +53,7 @@ struct ocfs2_mem_dqinfo {
 	struct buffer_head *dqi_lqi_bh;	/* Buffer head with local quota file inode */
 	struct buffer_head *dqi_ibh;	/* Buffer with information header */
 	struct qtree_mem_dqinfo dqi_gi;	/* Info about global file */
+	struct timer_list dqi_sync_timer;	/* Timer for syncing dquots */
 };
 
 static inline struct ocfs2_dquot *OCFS2_DQUOT(struct dquot *dquot)
diff --git a/fs/ocfs2/quota_global.c b/fs/ocfs2/quota_global.c
index b937f07..39b860f 100644
--- a/fs/ocfs2/quota_global.c
+++ b/fs/ocfs2/quota_global.c
@@ -1,10 +1,14 @@
 /*
  *  Implementation of operations over global quota file
  */
+#include <linux/spinlock.h>
 #include <linux/fs.h>
 #include <linux/quota.h>
 #include <linux/quotaops.h>
 #include <linux/dqblk_qtree.h>
+#include <linux/jiffies.h>
+#include <linux/timer.h>
+#include <linux/writeback.h>
 
 #define MLOG_MASK_PREFIX ML_QUOTA
 #include <cluster/masklog.h>
@@ -19,6 +23,8 @@
 #include "dlmglue.h"
 #include "quota.h"
 
+static void qsync_timer_fn(unsigned long oinfo_ptr);
+
 static void ocfs2_global_disk2memdqb(struct dquot *dquot, void *dp)
 {
 	struct ocfs2_global_disk_dqblk *d = dp;
@@ -276,6 +282,7 @@ int ocfs2_global_read_info(struct super_block *sb, int type)
 	info->dqi_bgrace = le32_to_cpu(dinfo.dqi_bgrace);
 	info->dqi_igrace = le32_to_cpu(dinfo.dqi_igrace);
 	oinfo->dqi_syncms = le32_to_cpu(dinfo.dqi_syncms);
+	oinfo->dqi_syncjiff = msecs_to_jiffies(oinfo->dqi_syncms);
 	oinfo->dqi_gi.dqi_blocks = le32_to_cpu(dinfo.dqi_blocks);
 	oinfo->dqi_gi.dqi_free_blk = le32_to_cpu(dinfo.dqi_free_blk);
 	oinfo->dqi_gi.dqi_free_entry = le32_to_cpu(dinfo.dqi_free_entry);
@@ -283,6 +290,10 @@ int ocfs2_global_read_info(struct super_block *sb, int type)
 	oinfo->dqi_gi.dqi_usable_bs = sb->s_blocksize -
 						OCFS2_QBLK_RESERVED_SPACE;
 	oinfo->dqi_gi.dqi_qtree_depth = qtree_depth(&oinfo->dqi_gi);
+	setup_timer(&oinfo->dqi_sync_timer, qsync_timer_fn,
+		    (unsigned long)oinfo);
+	mod_timer(&oinfo->dqi_sync_timer,
+		  round_jiffies(jiffies + oinfo->dqi_syncjiff));
 out_err:
 	mlog_exit(status);
 	return status;
@@ -470,6 +481,66 @@ out:
 }
 
 /*
+ *  Functions for periodic syncing of dquots with global file
+ */
+static int ocfs2_sync_dquot_helper(struct dquot *dquot, unsigned long type)
+{
+	handle_t *handle;
+	struct super_block *sb = dquot->dq_sb;
+	struct ocfs2_mem_dqinfo *oinfo = sb_dqinfo(sb, type)->dqi_priv;
+	struct ocfs2_super *osb = OCFS2_SB(sb);
+	int status = 0;
+
+	mlog_entry("id=%u qtype=%u type=%lu device=%s\n", dquot->dq_id,
+		   dquot->dq_type, type, sb->s_id);
+	if (type != dquot->dq_type)
+		goto out;
+	status = ocfs2_lock_global_qf(oinfo, 1);
+	if (status < 0)
+		goto out;
+
+	handle = ocfs2_start_trans(osb, OCFS2_QSYNC_CREDITS);
+	if (IS_ERR(handle)) {
+		status = PTR_ERR(handle);
+		mlog_errno(status);
+		goto out_ilock;
+	}
+	mutex_lock(&sb_dqopt(sb)->dqio_mutex);
+	status = ocfs2_sync_dquot(dquot);
+	mutex_unlock(&sb_dqopt(sb)->dqio_mutex);
+	if (status < 0)
+		mlog_errno(status);
+	/* We have to write local structure as well... */
+	dquot_mark_dquot_dirty(dquot);
+	status = dquot_commit(dquot);
+	if (status < 0)
+		mlog_errno(status);
+	ocfs2_commit_trans(osb, handle);
+out_ilock:
+	ocfs2_unlock_global_qf(oinfo, 1);
+out:
+	mlog_exit(status);
+	return status;
+}
+
+static void ocfs2_do_qsync(unsigned long oinfo_ptr)
+{
+	struct ocfs2_mem_dqinfo *oinfo = (struct ocfs2_mem_dqinfo *)oinfo_ptr;
+	struct super_block *sb = oinfo->dqi_gqinode->i_sb;
+
+	dquot_scan_active(sb, ocfs2_sync_dquot_helper, oinfo->dqi_type);
+}
+
+static void qsync_timer_fn(unsigned long oinfo_ptr)
+{
+	struct ocfs2_mem_dqinfo *oinfo = (struct ocfs2_mem_dqinfo *)oinfo_ptr;
+
+	pdflush_operation(ocfs2_do_qsync, oinfo_ptr);
+	mod_timer(&oinfo->dqi_sync_timer,
+		  round_jiffies(jiffies + oinfo->dqi_syncjiff));
+}
+
+/*
  *  Wrappers for generic quota functions
  */
 
diff --git a/fs/ocfs2/quota_local.c b/fs/ocfs2/quota_local.c
index 55c3f2f..1db7a16 100644
--- a/fs/ocfs2/quota_local.c
+++ b/fs/ocfs2/quota_local.c
@@ -368,6 +368,10 @@ static int ocfs2_local_free_info(struct super_block *sb, int type)
 	int mark_clean = 1, len;
 	int status;
 
+	/* At this point we know there are no more dquots and thus
+	 * even if there's some sync in the pdflush queue, it won't
+	 * find any dquots and return without doing anything */
+	del_timer_sync(&oinfo->dqi_sync_timer);
 	iput(oinfo->dqi_gqinode);
 	ocfs2_simple_drop_lockres(OCFS2_SB(sb), &oinfo->dqi_gqlock);
 	ocfs2_lock_res_free(&oinfo->dqi_gqlock);
-- 
1.5.2.4

  parent reply	other threads:[~2008-10-24 22:08 UTC|newest]

Thread overview: 55+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-10-24 22:07 [Ocfs2-devel] [PATCH 00/00] Implement quotas for OCFS2 (version 2) Jan Kara
2008-10-24 22:07 ` [Ocfs2-devel] [PATCH 01/29] quota: Add callbacks for allocating and destroying dquot structures Jan Kara
2008-10-24 22:07 ` [Ocfs2-devel] [PATCH 02/29] quota: Increase size of variables for limits and inode usage Jan Kara
2008-10-24 22:07 ` [Ocfs2-devel] [PATCH 03/29] quota: Remove bogus 'optimization' in check_idq() and check_bdq() Jan Kara
2008-10-24 22:07 ` [Ocfs2-devel] [PATCH 04/29] quota: Make _SUSPENDED just a flag Jan Kara
2008-10-24 22:07 ` [Ocfs2-devel] [PATCH 05/29] quota: Allow to separately enable quota accounting and enforcing limits Jan Kara
2008-10-24 22:07 ` [Ocfs2-devel] [PATCH 06/29] ext3: Use sb_any_quota_loaded() instead of sb_any_quota_enabled() Jan Kara
2008-10-24 22:08 ` [Ocfs2-devel] [PATCH 07/29] ext4: " Jan Kara
2008-10-24 22:08 ` [Ocfs2-devel] [PATCH 08/29] reiserfs: " Jan Kara
2008-10-24 22:08 ` [Ocfs2-devel] [PATCH 09/29] quota: Remove compatibility function sb_any_quota_enabled() Jan Kara
2008-10-24 22:08 ` [Ocfs2-devel] [PATCH 10/29] quota: Introduce DQUOT_QUOTA_SYS_FILE flag Jan Kara
2008-10-29 23:09   ` Mark Fasheh
2008-10-30  7:24     ` Jan Kara
2008-10-24 22:08 ` [Ocfs2-devel] [PATCH 11/29] quota: Move quotaio_v[12].h from include/linux/ to fs/ Jan Kara
2008-10-29 23:10   ` Mark Fasheh
2008-10-24 22:08 ` [Ocfs2-devel] [PATCH 12/29] quota: Split off quota tree handling into a separate file Jan Kara
2008-10-24 22:08 ` [Ocfs2-devel] [PATCH 13/29] quota: Convert union in mem_dqinfo to a pointer Jan Kara
2008-10-24 22:08 ` [Ocfs2-devel] [PATCH 14/29] quota: Allow negative usage of space and inodes Jan Kara
2008-10-24 22:08 ` [Ocfs2-devel] [PATCH 15/29] quota: Keep which entries were set by SETQUOTA quotactl Jan Kara
2008-10-24 22:08 ` [Ocfs2-devel] [PATCH 16/29] quota: Add helpers to allow ocfs2 specific quota initialization, freeing and recovery Jan Kara
2008-10-24 22:08 ` [Ocfs2-devel] [PATCH 17/29] quota: Implement function for scanning active dquots Jan Kara
2008-10-24 22:08 ` [Ocfs2-devel] [PATCH 18/29] mm: Export pdflush_operation() Jan Kara
2008-10-24 22:08 ` [Ocfs2-devel] [PATCH 19/29] ocfs2: Fix check of return value of ocfs2_start_trans() Jan Kara
2008-10-30 23:34   ` Mark Fasheh
2008-10-24 22:08 ` [Ocfs2-devel] [PATCH 20/29] ocfs2: Support nested transactions Jan Kara
2008-10-24 22:08 ` [Ocfs2-devel] [PATCH 21/29] ocfs2: Fix checking of return value of new_inode() Jan Kara
2008-10-30 23:51   ` Mark Fasheh
2008-10-24 22:08 ` [Ocfs2-devel] [PATCH 22/29] ocfs2: Let inode be really deleted when ocfs2_mknod_locked() fails Jan Kara
2008-10-30 23:52   ` Mark Fasheh
2008-10-31  5:05     ` Jan Kara
2008-10-24 22:08 ` [Ocfs2-devel] [PATCH 23/29] ocfs2: Assign feature bits and system inodes to quota feature and quota files Jan Kara
2008-10-28 22:16   ` Joel Becker
2008-10-29  2:32     ` Jan Kara
2008-10-24 22:08 ` [Ocfs2-devel] [PATCH 24/29] ocfs2: Mark system files as not subject to quota accounting Jan Kara
2008-10-24 22:08 ` [Ocfs2-devel] [PATCH 25/29] ocfs2: Implementation of local and global quota file handling Jan Kara
2008-10-28 19:07   ` Joel Becker
2008-10-28 19:36   ` Joel Becker
2008-10-29  2:29     ` Jan Kara
2008-10-29 10:51       ` Joel Becker
2008-10-30  7:33         ` Jan Kara
2008-10-30 20:31           ` Joel Becker
2008-10-31  5:00             ` Jan Kara
2008-11-05 22:49   ` Mark Fasheh
2008-11-20 14:53     ` Jan Kara
2008-10-24 22:08 ` [Ocfs2-devel] [PATCH 26/29] ocfs2: Add quota calls for allocation and freeing of inodes and space Jan Kara
2008-11-06  0:06   ` Mark Fasheh
2008-11-20 15:19     ` Jan Kara
2008-10-24 22:08 ` Jan Kara [this message]
2008-11-06  0:27   ` [Ocfs2-devel] [PATCH 27/29] ocfs2: Implement quota syncing thread Mark Fasheh
2008-10-24 22:08 ` [Ocfs2-devel] [PATCH 28/29] ocfs2: Implement quota recovery Jan Kara
2008-11-06  0:52   ` Mark Fasheh
2008-11-20 16:51     ` Jan Kara
2008-10-24 22:08 ` [Ocfs2-devel] [PATCH 29/29] ocfs2: Enable quota accounting on mount, disable on umount Jan Kara
2008-10-28 19:11   ` Joel Becker
2008-10-29  2:30     ` Jan Kara

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1224886104833-git-send-email-jack@suse.cz \
    --to=jack@suse.cz \
    --cc=ocfs2-devel@oss.oracle.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.