@@ -145,15 +145,40 @@ static void
bl_free_lseg(struct pnfs_layout_segment *lseg)
{
dprintk("%s enter\n", __func__);
- return;
+ kfree(lseg);
}
+/* Because the generic infrastructure does not correctly merge layouts,
+ * we pretty much ignore lseg, and store all data layout wide, so we
+ * can correctly merge. Eventually we should push some correct merge
+ * behavior up to the generic code, as the current behavior tends to
+ * cause lots of unnecessary overlapping LAYOUTGET requests.
+ */
static struct pnfs_layout_segment *
bl_alloc_lseg(struct pnfs_layout_type *lo,
struct nfs4_pnfs_layoutget_res *lgr)
{
+ struct pnfs_layout_segment *lseg;
+ int status;
+
dprintk("%s enter\n", __func__);
- return NULL;
+ lseg = kzalloc(sizeof(*lseg) + 0, GFP_KERNEL);
+ if (!lseg)
+ return NULL;
+ status = nfs4_blk_process_layoutget(lo, lgr);
+ if (status) {
+ /* We don't want to call the full-blown bl_free_lseg,
+ * since on error extents were not touched.
+ */
+ /* STUB - we really want to distinguish between 2 error
+ * conditions here. This lseg failed, but lo data structures
+ * are OK, or we hosed the lo data structures. The calling
+ * code probably needs to distinguish this too.
+ */
+ kfree(lseg);
+ return ERR_PTR(status);
+ }
+ return lseg;
}
static int
@@ -142,6 +142,7 @@ struct pnfs_block_layout {
sector_t bl_blocksize; /* Server blocksize in sectors */
};
+#define BLK_LSEG2EXT(lseg) ((struct pnfs_block_layout *)lseg->layout->ld_data)
#define BLK_LO2EXT(lo) ((struct pnfs_block_layout *)lo->ld_data)
uint32_t *blk_overflow(uint32_t *p, uint32_t *end, size_t nbytes);
@@ -183,6 +184,8 @@ int nfs4_blkdev_put(struct block_device *bdev);
struct pnfs_block_dev *nfs4_blk_decode_device(struct super_block *sb,
struct pnfs_device *dev,
struct list_head *sdlist);
+int nfs4_blk_process_layoutget(struct pnfs_layout_type *lo,
+ struct nfs4_pnfs_layoutget_res *lgr);
int nfs4_blk_create_scsi_disk_list(struct list_head *);
void nfs4_blk_destroy_disk_list(struct list_head *);
/* blocklayoutdm.c */
@@ -553,3 +553,12 @@ nfs4_blk_decode_device(struct super_block *sb,
kfree(vols);
return rv;
}
+
+/* XDR decode pnfs_block_layout4 structure */
+int
+nfs4_blk_process_layoutget(struct pnfs_layout_type *lo,
+ struct nfs4_pnfs_layoutget_res *lgr)
+{
+ /* STUB */
+ return -EIO;
+}