From: Jan Kara <jack@suse.cz>
To: ocfs2-devel@oss.oracle.com
Subject: [Ocfs2-devel] [PATCH 2/7] ocfs2: Do not map blocks from local quota file on each write
Date: Thu, 13 May 2010 21:57:58 +0200 [thread overview]
Message-ID: <1273780683-3638-3-git-send-email-jack@suse.cz> (raw)
In-Reply-To: <1273780683-3638-1-git-send-email-jack@suse.cz>
There is no need to map offset of local dquot structure to on disk block
in each quota write. It is enough to map it just once and store the physical
block number in quota structure in memory. Moreover this simplifies locking
as we do not have to take ip_alloc_sem from quota write path.
Signed-off-by: Jan Kara <jack@suse.cz>
---
fs/ocfs2/quota.h | 3 +++
fs/ocfs2/quota_global.c | 14 ++++++++++++++
fs/ocfs2/quota_local.c | 28 +++++++++++++++++++---------
3 files changed, 36 insertions(+), 9 deletions(-)
diff --git a/fs/ocfs2/quota.h b/fs/ocfs2/quota.h
index 123bc52..e22d293 100644
--- a/fs/ocfs2/quota.h
+++ b/fs/ocfs2/quota.h
@@ -23,6 +23,7 @@
struct ocfs2_dquot {
struct dquot dq_dquot; /* Generic VFS dquot */
loff_t dq_local_off; /* Offset in the local quota file */
+ u64 dq_local_phys_blk; /* Physical block carrying quota structure */
struct ocfs2_quota_chunk *dq_chunk; /* Chunk dquot is in */
unsigned int dq_use_count; /* Number of nodes having reference to this entry in global quota file */
s64 dq_origspace; /* Last globally synced space usage */
@@ -104,6 +105,8 @@ int ocfs2_lock_global_qf(struct ocfs2_mem_dqinfo *oinfo, int ex);
void ocfs2_unlock_global_qf(struct ocfs2_mem_dqinfo *oinfo, int ex);
int ocfs2_read_quota_block(struct inode *inode, u64 v_block,
struct buffer_head **bh);
+int ocfs2_read_quota_phys_block(struct inode *inode, u64 p_block,
+ struct buffer_head **bh);
extern const struct dquot_operations ocfs2_quota_operations;
extern struct quota_format_type ocfs2_quota_format;
diff --git a/fs/ocfs2/quota_global.c b/fs/ocfs2/quota_global.c
index ab42a74..e37833b 100644
--- a/fs/ocfs2/quota_global.c
+++ b/fs/ocfs2/quota_global.c
@@ -25,6 +25,7 @@
#include "dlmglue.h"
#include "uptodate.h"
#include "super.h"
+#include "buffer_head_io.h"
#include "quota.h"
static struct workqueue_struct *ocfs2_quota_wq = NULL;
@@ -137,6 +138,19 @@ int ocfs2_read_quota_block(struct inode *inode, u64 v_block,
return rc;
}
+int ocfs2_read_quota_phys_block(struct inode *inode, u64 p_block,
+ struct buffer_head **bhp)
+{
+ int rc;
+
+ *bhp = NULL;
+ rc = ocfs2_read_blocks(INODE_CACHE(inode), p_block, 1, bhp, 0,
+ ocfs2_validate_quota_block);
+ if (rc)
+ mlog_errno(rc);
+ return rc;
+}
+
static int ocfs2_get_quota_block(struct inode *inode, int block,
struct buffer_head **bh)
{
diff --git a/fs/ocfs2/quota_local.c b/fs/ocfs2/quota_local.c
index 9ad4930..dbfc8e3 100644
--- a/fs/ocfs2/quota_local.c
+++ b/fs/ocfs2/quota_local.c
@@ -870,18 +870,17 @@ static int ocfs2_local_write_dquot(struct dquot *dquot)
{
struct super_block *sb = dquot->dq_sb;
struct ocfs2_dquot *od = OCFS2_DQUOT(dquot);
- struct buffer_head *bh = NULL;
+ struct buffer_head *bh;
+ struct inode *lqinode = sb_dqopt(sb)->files[dquot->dq_type];
int status;
- status = ocfs2_read_quota_block(sb_dqopt(sb)->files[dquot->dq_type],
- ol_dqblk_file_block(sb, od->dq_local_off),
- &bh);
+ status = ocfs2_read_quota_phys_block(lqinode, od->dq_local_phys_blk,
+ &bh);
if (status) {
mlog_errno(status);
goto out;
}
- status = ocfs2_modify_bh(sb_dqopt(sb)->files[dquot->dq_type], bh,
- olq_set_dquot, od);
+ status = ocfs2_modify_bh(lqinode, bh, olq_set_dquot, od);
if (status < 0) {
mlog_errno(status);
goto out;
@@ -1219,17 +1218,27 @@ static int ocfs2_create_local_dquot(struct dquot *dquot)
struct ocfs2_dquot *od = OCFS2_DQUOT(dquot);
int offset;
int status;
+ u64 pcount;
+ down_write(&OCFS2_I(lqinode)->ip_alloc_sem);
chunk = ocfs2_find_free_entry(sb, type, &offset);
if (!chunk) {
chunk = ocfs2_extend_local_quota_file(sb, type, &offset);
- if (IS_ERR(chunk))
- return PTR_ERR(chunk);
+ if (IS_ERR(chunk)) {
+ status = PTR_ERR(chunk);
+ goto out;
+ }
} else if (IS_ERR(chunk)) {
- return PTR_ERR(chunk);
+ status = PTR_ERR(chunk);
+ goto out;
}
od->dq_local_off = ol_dqblk_off(sb, chunk->qc_num, offset);
od->dq_chunk = chunk;
+ status = ocfs2_extent_map_get_blocks(lqinode,
+ ol_dqblk_block(sb, chunk->qc_num, offset),
+ &od->dq_local_phys_blk,
+ &pcount,
+ NULL);
/* Initialize dquot structure on disk */
status = ocfs2_local_write_dquot(dquot);
@@ -1246,6 +1255,7 @@ static int ocfs2_create_local_dquot(struct dquot *dquot)
goto out;
}
out:
+ up_write(&OCFS2_I(lqinode)->ip_alloc_sem);
return status;
}
--
1.6.4.2
next prev parent reply other threads:[~2010-05-13 19:57 UTC|newest]
Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-05-13 19:57 [Ocfs2-devel] Quota locking fixes for OCFS2 Jan Kara
2010-05-13 19:57 ` [Ocfs2-devel] [PATCH 1/7] quota: Refactor dquot_transfer code so that OCFS2 can pass in its references Jan Kara
2010-05-13 23:44 ` Joel Becker
2010-05-13 19:57 ` Jan Kara [this message]
2010-05-13 23:44 ` [Ocfs2-devel] [PATCH 2/7] ocfs2: Do not map blocks from local quota file on each write Joel Becker
2010-05-14 8:06 ` Jan Kara
2010-05-13 19:57 ` [Ocfs2-devel] [PATCH 3/7] ocfs2: Avoid unnecessary block mapping when refreshing quota info Jan Kara
2010-05-13 19:58 ` [Ocfs2-devel] [PATCH 4/7] ocfs2: Fix quota locking Jan Kara
2010-05-13 19:58 ` [Ocfs2-devel] [PATCH 5/7] ocfs2: Fix estimate of credits needed for quota allocation Jan Kara
2010-05-13 19:58 ` [Ocfs2-devel] [PATCH 6/7] ocfs2: Fix NULL pointer deref when writing local dquot Jan Kara
2010-05-13 19:58 ` [Ocfs2-devel] [PATCH 7/7] ocfs2: Use __dquot_transfer to avoid lock inversion Jan Kara
2010-05-13 23:51 ` [Ocfs2-devel] Quota locking fixes for OCFS2 Joel Becker
2010-05-14 8:08 ` Jan Kara
2010-05-14 19:36 ` Joel Becker
2010-05-17 16:18 ` Jan Kara
2010-05-17 19:17 ` Joel Becker
2010-05-17 21: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=1273780683-3638-3-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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).