[pnfs] [PATCH 11/21] pnfsblock: find_get_extent
Fred Isaman
iisaman at citi.umich.edu
Thu Apr 10 10:07:27 EDT 2008
From: Fred <iisaman at citi.umich.edu>
Implement find_get_extent(), one of the core extent manipulation
routines.
Signed-off-by: Fred Isaman <iisaman at citi.umich.edu>
Signed-off-by: Benny Halevy <bhalevy at panasas.com>
pnfsblock: fix print format warnings for sector_t and size_t
gcc spews warnings about these on x86_64, e.g.:
fs/nfs/blocklayout/blocklayout.c:74: warning: format ‘%Lu’ expects type ‘long long unsigned int’, but argument 2 has type ‘sector_t’
fs/nfs/blocklayout/blocklayout.c:388: warning: format ‘%d’ expects type ‘int’, but argument 5 has type ‘size_t’
Signed-off-by: Benny Halevy <bhalevy at panasas.com>
---
fs/nfs/blocklayout/blocklayout.c | 61 ++++++++++++++++++++++++++++++++++++++
fs/nfs/blocklayout/blocklayout.h | 1 +
2 files changed, 62 insertions(+), 0 deletions(-)
diff --git a/fs/nfs/blocklayout/blocklayout.c b/fs/nfs/blocklayout/blocklayout.c
index 7a39638..1f6bb9c 100644
--- a/fs/nfs/blocklayout/blocklayout.c
+++ b/fs/nfs/blocklayout/blocklayout.c
@@ -43,6 +43,17 @@ MODULE_DESCRIPTION("The NFSv4.1 pNFS Block layout driver");
/* Callback operations to the pNFS client */
struct pnfs_client_operations *pnfs_callback_ops;
+static void print_bl_extent(struct pnfs_block_extent *be)
+{
+ dprintk("PRINT EXTENT extent %p\n", be);
+ if (be) {
+ dprintk(" be_f_offset %Lu\n", (u64)be->be_f_offset);
+ dprintk(" be_length %Lu\n", (u64)be->be_length);
+ dprintk(" be_v_offset %Lu\n", (u64)be->be_v_offset);
+ dprintk(" be_state %d\n", be->be_state);
+ }
+}
+
static void
destroy_extent(struct kref *kref)
{
@@ -63,6 +74,56 @@ put_extent(struct pnfs_block_extent *be)
}
}
+/* Returns extent, or NULL. If a second READ extent exists, it is returned
+ * in cow_read, if given.
+ *
+ * We assume about the extent list:
+ * 1. Extents are ordered by file offset, if two extents have same offset,
+ * we don't care about ordering.
+ * 2. For any given isect, there are at most two extents that match.
+ * 3. If two extents match, exactly one will have state==READ_DATA
+ */
+static struct pnfs_block_extent *
+find_get_extent(struct pnfs_layout_segment *lseg, sector_t isect,
+ struct pnfs_block_extent **cow_read)
+{
+ struct pnfs_block_layout *bl = BLK_LO(lseg);
+ struct pnfs_block_extent *be, *cow, *out;
+
+ dprintk("%s enter with isect %Lu\n", __func__, (u64)isect);
+ cow = out = NULL;
+ spin_lock(&bl->bl_ext_lock);
+ list_for_each_entry(be, &bl->bl_extents, be_node) {
+ if (isect < be->be_f_offset)
+ break;
+ if (isect < be->be_f_offset + be->be_length) {
+ /* We have found an extent, now decide if it should
+ * be returned in cow_read or not.
+ */
+ dprintk("%s Get %p (%i)\n", __func__, be,
+ atomic_read(&be->be_refcnt.refcount));
+ kref_get(&be->be_refcnt);
+ if (!out)
+ out = be;
+ else {
+ if (out->be_state == PNFS_BLOCK_READ_DATA) {
+ cow = out;
+ out = be;
+ } else
+ cow = be;
+ break;
+ }
+ }
+ }
+ spin_unlock(&bl->bl_ext_lock);
+ if (cow_read)
+ *cow_read = cow;
+ else
+ put_extent(cow);
+ print_bl_extent(out);
+ return out;
+}
+
static int
bl_commit(struct pnfs_layout_type *layoutid,
int sync,
diff --git a/fs/nfs/blocklayout/blocklayout.h b/fs/nfs/blocklayout/blocklayout.h
index b9241d8..d91d909 100644
--- a/fs/nfs/blocklayout/blocklayout.h
+++ b/fs/nfs/blocklayout/blocklayout.h
@@ -124,6 +124,7 @@ struct pnfs_block_layout {
};
#define BLK_ID(lt) ((struct block_mount_id *)(PNFS_MOUNTID(lt)->mountid))
+#define BLK_LO(lseg) ((struct pnfs_block_layout *)lseg->ld_data)
uint32_t *blk_overflow(uint32_t *p, uint32_t *end, size_t nbytes);
--
1.5.3.3
More information about the pNFS
mailing list