From: Jim Rees <rees@umich.edu>
To: Benny Halevy <bhalevy@panasas.com>
Cc: linux-nfs@vger.kernel.org, peter honeyman <honey@citi.umich.edu>
Subject: [PATCH 31/33] pnfsblock: note written INVAL areas for layoutcommit
Date: Mon, 13 Jun 2011 22:33:18 -0400 [thread overview]
Message-ID: <401cb5fef730f0c1d0b24e9ee86b33256bf0e384.1308017749.git.rees@umich.edu> (raw)
In-Reply-To: <cover.1308017749.git.rees@umich.edu>
From: Fred Isaman <iisaman@citi.umich.edu>
[SQUASHME: pnfs: blocklayout: port block layout code]
Signed-off-by: Peng Tao <peng_tao@emc.com>
Signed-off-by: Fred Isaman <iisaman@citi.umich.edu>
Signed-off-by: Benny Halevy <bhalevy@panasas.com>
---
fs/nfs/blocklayout/blocklayout.c | 32 +++++++++++++
fs/nfs/blocklayout/blocklayout.h | 2 +
fs/nfs/blocklayout/extents.c | 95 ++++++++++++++++++++++++++++++++++++++
3 files changed, 129 insertions(+), 0 deletions(-)
diff --git a/fs/nfs/blocklayout/blocklayout.c b/fs/nfs/blocklayout/blocklayout.c
index 6fe039c8..6de800f 100644
--- a/fs/nfs/blocklayout/blocklayout.c
+++ b/fs/nfs/blocklayout/blocklayout.c
@@ -320,6 +320,30 @@ bl_read_pagelist(struct nfs_read_data *rdata)
return PNFS_NOT_ATTEMPTED;
}
+static void mark_extents_written(struct pnfs_block_layout *bl,
+ __u64 offset, __u32 count)
+{
+ sector_t isect, end;
+ struct pnfs_block_extent *be;
+
+ dprintk("%s(%llu, %u)\n", __func__, offset, count);
+ if (count == 0)
+ return;
+ isect = (offset & (long)(PAGE_CACHE_MASK)) >> 9;
+ end = (offset + count + PAGE_CACHE_SIZE - 1) & (long)(PAGE_CACHE_MASK);
+ end >>= 9;
+ while (isect < end) {
+ sector_t len;
+ be = find_get_extent(bl, isect, NULL);
+ BUG_ON(!be); /* FIXME */
+ len = min(end, be->be_f_offset + be->be_length) - isect;
+ if (be->be_state == PNFS_BLOCK_INVALID_DATA)
+ mark_for_commit(be, isect, len); /* What if fails? */
+ isect += len;
+ put_extent(be);
+ }
+}
+
/* STUB - this needs thought */
static inline void
bl_done_with_wpage(struct page *page, const int ok)
@@ -367,6 +391,14 @@ static void bl_write_cleanup(struct work_struct *work)
dprintk("%s enter\n", __func__);
task = container_of(work, struct rpc_task, u.tk_work);
wdata = container_of(task, struct nfs_write_data, task);
+ if (!wdata->task.tk_status) {
+ /* Marks for LAYOUTCOMMIT */
+ /* BUG - this should be called after each bio, not after
+ * all finish, unless have some way of storing success/failure
+ */
+ mark_extents_written(BLK_LSEG2EXT(wdata->lseg),
+ wdata->args.offset, wdata->args.count);
+ }
pnfs_ld_write_done(wdata);
}
diff --git a/fs/nfs/blocklayout/blocklayout.h b/fs/nfs/blocklayout/blocklayout.h
index 5a7d0be..6b7718b 100644
--- a/fs/nfs/blocklayout/blocklayout.h
+++ b/fs/nfs/blocklayout/blocklayout.h
@@ -267,6 +267,8 @@ void clean_pnfs_block_layoutupdate(struct pnfs_block_layout *bl,
int status);
int add_and_merge_extent(struct pnfs_block_layout *bl,
struct pnfs_block_extent *new);
+int mark_for_commit(struct pnfs_block_extent *be,
+ sector_t offset, sector_t length);
#include <linux/sunrpc/simple_rpc_pipefs.h>
diff --git a/fs/nfs/blocklayout/extents.c b/fs/nfs/blocklayout/extents.c
index 1447bfc..a62d29f 100644
--- a/fs/nfs/blocklayout/extents.c
+++ b/fs/nfs/blocklayout/extents.c
@@ -217,6 +217,48 @@ int is_sector_initialized(struct pnfs_inval_markings *marks, sector_t isect)
return rv;
}
+/* Assume start, end already sector aligned */
+static int
+_range_has_tag(struct my_tree_t *tree, u64 start, u64 end, int32_t tag)
+{
+ struct pnfs_inval_tracking *pos;
+ u64 expect = 0;
+
+ dprintk("%s(%llu, %llu, %i) enter\n", __func__, start, end, tag);
+ list_for_each_entry_reverse(pos, &tree->mtt_stub, it_link) {
+ if (pos->it_sector >= end)
+ continue;
+ if (!expect) {
+ if ((pos->it_sector == end - tree->mtt_step_size) &&
+ (pos->it_tags & (1 << tag))) {
+ expect = pos->it_sector - tree->mtt_step_size;
+ if (pos->it_sector < tree->mtt_step_size || expect < start)
+ return 1;
+ continue;
+ } else {
+ return 0;
+ }
+ }
+ if (pos->it_sector != expect || !(pos->it_tags & (1 << tag)))
+ return 0;
+ expect -= tree->mtt_step_size;
+ if (expect < start)
+ return 1;
+ }
+ return 0;
+}
+
+static int is_range_written(struct pnfs_inval_markings *marks,
+ sector_t start, sector_t end)
+{
+ int rv;
+
+ spin_lock(&marks->im_lock);
+ rv = _range_has_tag(&marks->im_tree, start, end, EXTENT_WRITTEN);
+ spin_unlock(&marks->im_lock);
+ return rv;
+}
+
/* Marks sectors in [offest, offset_length) as having been initialized.
* All lengths are step-aligned, where step is min(pagesize, blocksize).
* Notes where partial block is initialized, and helps prepare it for
@@ -394,6 +436,59 @@ static void add_to_commitlist(struct pnfs_block_layout *bl,
print_clist(clist, bl->bl_count);
}
+/* Note the range described by offset, length is guaranteed to be contained
+ * within be.
+ */
+int mark_for_commit(struct pnfs_block_extent *be,
+ sector_t offset, sector_t length)
+{
+ sector_t new_end, end = offset + length;
+ struct pnfs_block_short_extent *new;
+ struct pnfs_block_layout *bl = container_of(be->be_inval,
+ struct pnfs_block_layout,
+ bl_inval);
+
+ new = kmalloc(sizeof(*new), GFP_KERNEL);
+ if (!new)
+ return -ENOMEM;
+
+ mark_written_sectors(be->be_inval, offset, length);
+ /* We want to add the range to commit list, but it must be
+ * block-normalized, and verified that the normalized range has
+ * been entirely written to disk.
+ */
+ new->bse_f_offset = offset;
+ offset = normalize(offset, bl->bl_blocksize);
+ if (offset < new->bse_f_offset) {
+ if (is_range_written(be->be_inval, offset, new->bse_f_offset))
+ new->bse_f_offset = offset;
+ else
+ new->bse_f_offset = offset + bl->bl_blocksize;
+ }
+ new_end = normalize_up(end, bl->bl_blocksize);
+ if (end < new_end) {
+ if (is_range_written(be->be_inval, end, new_end))
+ end = new_end;
+ else
+ end = new_end - bl->bl_blocksize;
+ }
+ if (end <= new->bse_f_offset) {
+ kfree(new);
+ return 0;
+ }
+ new->bse_length = end - new->bse_f_offset;
+ new->bse_devid = be->be_devid;
+ new->bse_mdev = be->be_mdev;
+
+ spin_lock(&bl->bl_ext_lock);
+ /* new will be freed, either by add_to_commitlist if it decides not
+ * to use it, or after LAYOUTCOMMIT uses it in the commitlist.
+ */
+ add_to_commitlist(bl, new);
+ spin_unlock(&bl->bl_ext_lock);
+ return 0;
+}
+
static void print_bl_extent(struct pnfs_block_extent *be)
{
dprintk("PRINT EXTENT extent %p\n", be);
--
1.7.4.1
next prev parent reply other threads:[~2011-06-14 2:33 UTC|newest]
Thread overview: 35+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-06-14 2:31 [PATCH 00/33] v2 block layout patches Jim Rees
2011-06-14 2:32 ` [PATCH 01/33] pnfs: GETDEVICELIST Jim Rees
2011-06-14 2:32 ` [PATCH 02/33] pnfs: add set-clear layoutdriver interface Jim Rees
2011-06-14 2:32 ` [PATCH 03/33] pnfs: let layoutcommit code handle multiple segments Jim Rees
2011-06-14 2:32 ` [PATCH 04/33] pnfs: hook nfs_write_begin/end to allow layout driver manipulation Jim Rees
2011-06-14 2:32 ` [PATCH 05/33] pnfs: ask for layout_blksize and save it in nfs_server Jim Rees
2011-06-14 2:32 ` [PATCH 06/33] pnfs: cleanup_layoutcommit Jim Rees
2011-06-14 2:32 ` [PATCH 07/33] pnfsblock: define PNFS_BLOCK Kconfig option Jim Rees
2011-06-14 2:32 ` [PATCH 08/33] pnfsblock: blocklayout stub Jim Rees
2011-06-14 2:32 ` [PATCH 09/33] pnfsblock: layout alloc and free Jim Rees
2011-06-14 2:32 ` [PATCH 10/33] pnfsblock: add support for simple rpc pipefs Jim Rees
2011-06-14 15:52 ` Benny Halevy
2011-06-14 2:32 ` [PATCH 11/33] pnfsblock: add block device discovery pipe Jim Rees
2011-06-14 2:32 ` [PATCH 12/33] pnfsblock: basic extent code Jim Rees
2011-06-14 2:32 ` [PATCH 13/33] pnfsblock: add device operations Jim Rees
2011-06-14 2:32 ` [PATCH 14/33] pnfsblock: remove " Jim Rees
2011-06-14 2:32 ` [PATCH 15/33] pnfsblock: lseg alloc and free Jim Rees
2011-06-14 2:32 ` [PATCH 16/33] pnfsblock: merge extents Jim Rees
2011-06-14 2:32 ` [PATCH 17/33] pnfsblock: call and parse getdevicelist Jim Rees
2011-06-14 2:32 ` [PATCH 18/33] pnfsblock: allow use of PG_owner_priv_1 flag Jim Rees
2011-06-14 2:32 ` [PATCH 19/33] pnfsblock: xdr decode pnfs_block_layout4 Jim Rees
2011-06-14 2:32 ` [PATCH 20/33] pnfsblock: find_get_extent Jim Rees
2011-06-14 2:32 ` [PATCH 21/33] pnfsblock: SPLITME: add extent manipulation functions Jim Rees
2011-06-14 2:32 ` [PATCH 22/33] pnfsblock: merge rw extents Jim Rees
2011-06-14 2:32 ` [PATCH 23/33] pnfsblock: encode_layoutcommit Jim Rees
2011-06-14 2:33 ` [PATCH 24/33] pnfsblock: cleanup_layoutcommit Jim Rees
2011-06-14 2:33 ` [PATCH 25/33] pnfsblock: bl_read_pagelist Jim Rees
2011-06-14 2:33 ` [PATCH 26/33] pnfsblock: write_begin Jim Rees
2011-06-14 2:33 ` [PATCH 27/33] pnfsblock: write_end Jim Rees
2011-06-14 2:33 ` [PATCH 28/33] pnfsblock: write_end_cleanup Jim Rees
2011-06-14 2:33 ` [PATCH 29/33] pnfsblock: bl_write_pagelist support functions Jim Rees
2011-06-14 2:33 ` [PATCH 30/33] pnfsblock: bl_write_pagelist Jim Rees
2011-06-14 2:33 ` Jim Rees [this message]
2011-06-14 2:33 ` [PATCH 32/33] pnfsblock: Implement release_inval_marks Jim Rees
2011-06-14 2:33 ` [PATCH 33/33] pnfsblock DEVONLY: Add configurable prefetch size for layoutget Jim Rees
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=401cb5fef730f0c1d0b24e9ee86b33256bf0e384.1308017749.git.rees@umich.edu \
--to=rees@umich.edu \
--cc=bhalevy@panasas.com \
--cc=honey@citi.umich.edu \
--cc=linux-nfs@vger.kernel.org \
/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).