[Cluster-devel] [PATCH 06/19] libgfs2: Add functions for finding free extents

Andrew Price anprice at redhat.com
Wed Sep 3 12:13:05 UTC 2014


On 03/09/14 11:17, Steven Whitehouse wrote:
> Hi,
>
> You shouldn't need this for allocation in mkfs since you already know
> where the free extents are, so no need to be reading the bitmaps to find
> that out,
>
> Steve.

Well, that's true, but I'd like to use generic file allocation functions 
where possible and I wanted to make sure the new functions were able to 
allocate extents. I'd like to keep these changes in libgfs2 anyway 
because they'll be useful for future work in other tools, so how about 
an additional patch like the one below?

Andy

diff --git a/gfs2/libgfs2/fs_ops.c b/gfs2/libgfs2/fs_ops.c
index 9c9cc82..b84b7f4 100644
--- a/gfs2/libgfs2/fs_ops.c
+++ b/gfs2/libgfs2/fs_ops.c
@@ -296,7 +296,9 @@ uint64_t lgfs2_space_for_data(const struct gfs2_sbd 
*sdp, const unsigned bsize,
   * Allocate an extent for a file in a resource group's bitmaps.
   * rg: The resource group in which to allocate the extent
   * di_size: The size of the file in bytes
- * ip: A pointer to the inode structure, whose fields will be set 
appropriately
+ * ip: A pointer to the inode structure, whose fields will be set 
appropriately.
+ *     If ip->i_di.di_num.no_addr is not 0, the extent search will be 
skipped and
+ *     the file allocated from that address.
   * flags: GFS2_DIF_* flags
   * mode: File mode flags, see creat(2)
   * Returns 0 on success with the contents of ip set accordingly, or 
non-zero
@@ -310,11 +312,13 @@ int lgfs2_file_alloc(lgfs2_rgrp_t rg, uint64_t 
di_size, struct gfs2_inode *ip, u
  	struct gfs2_sbd *sdp = rg->rgrps->sdp;
  	struct lgfs2_rbm rbm = { .rgd = rg, .offset = 0, .bii = 0 };
  	uint32_t blocks = lgfs2_space_for_data(sdp, sdp->bsize, di_size);
-	int err;

-	err = lgfs2_rbm_find(&rbm, GFS2_BLKST_FREE, &blocks);
-	if (err != 0)
-		return err;
+	if (ip->i_di.di_num.no_addr != 0) {
+		if (lgfs2_rbm_from_block(&rbm, ip->i_di.di_num.no_addr) != 0)
+			return 1;
+	} else if (lgfs2_rbm_find(&rbm, GFS2_BLKST_FREE, &blocks) != 0) {
+		return 1;
+	}

  	extlen = lgfs2_alloc_extent(&rbm, GFS2_BLKST_DINODE, blocks);
  	if (extlen < blocks) {
diff --git a/gfs2/libgfs2/rgrp.c b/gfs2/libgfs2/rgrp.c
index f57ae3a..0d0f000 100644
--- a/gfs2/libgfs2/rgrp.c
+++ b/gfs2/libgfs2/rgrp.c
@@ -643,7 +643,7 @@ lgfs2_rgrp_t lgfs2_rgrp_last(lgfs2_rgrps_t rgs)
   *
   * Returns: 0 on success, or non-zero with errno set
   */
-static int lgfs2_rbm_from_block(struct lgfs2_rbm *rbm, uint64_t block)
+int lgfs2_rbm_from_block(struct lgfs2_rbm *rbm, uint64_t block)
  {
  	uint64_t rblock = block - rbm->rgd->ri.ri_data0;
  	struct gfs2_sbd *sdp = rbm_bi(rbm)->bi_bh->sdp;
diff --git a/gfs2/libgfs2/rgrp.h b/gfs2/libgfs2/rgrp.h
index bd89289..fd442b1 100644
--- a/gfs2/libgfs2/rgrp.h
+++ b/gfs2/libgfs2/rgrp.h
@@ -44,6 +44,7 @@ static inline int lgfs2_rbm_eq(const struct lgfs2_rbm 
*rbm1, const struct lgfs2_
  	        (rbm1->offset == rbm2->offset);
  }

+extern int lgfs2_rbm_from_block(struct lgfs2_rbm *rbm, uint64_t block);
  extern int lgfs2_rbm_find(struct lgfs2_rbm *rbm, uint8_t state, 
uint32_t *minext);
  extern unsigned lgfs2_alloc_extent(const struct lgfs2_rbm *rbm, int 
state, const unsigned elen);

diff --git a/gfs2/mkfs/main_mkfs.c b/gfs2/mkfs/main_mkfs.c
index 530383d..e927d82 100644
--- a/gfs2/mkfs/main_mkfs.c
+++ b/gfs2/mkfs/main_mkfs.c
@@ -694,6 +694,8 @@ static int place_journals(struct gfs2_sbd *sdp, 
lgfs2_rgrps_t rgs, struct mkfs_o
  			perror(_("Failed to allocate space for bitmap buffer"));
  			return result;
  		}
+		/* Allocate at the beginning of the rgrp, bypassing extent search */
+		in.i_di.di_num.no_addr = lgfs2_rgrp_index(rg)->ri_data0;
  		/* In order to keep writes sequential here, we have to allocate
  		   the journal, then write the rgrp header (which is now in its
  		   final form) and then write the journal out */




More information about the Cluster-devel mailing list