From: Andrew Price <anprice@redhat.com>
To: cluster-devel.redhat.com
Subject: [Cluster-devel] [PATCH 12/19] libgfs2: Add extent allocation functions
Date: Tue, 2 Sep 2014 13:07:29 +0100 [thread overview]
Message-ID: <1409659656-23051-13-git-send-email-anprice@redhat.com> (raw)
In-Reply-To: <1409659656-23051-1-git-send-email-anprice@redhat.com>
In order to preallocate journals as single extents we need functions
which allow bitmap allocation separate from buffer allocation and
writing. This adds two functions, lgfs2_file_alloc and
lgfs2_alloc_extent, which solve this problem, making use of the new
lgfs2_rbm functions.
Signed-off-by: Andrew Price <anprice@redhat.com>
---
gfs2/libgfs2/fs_ops.c | 57 ++++++++++++++++++++++++++++++++++++++++++++++++++
gfs2/libgfs2/libgfs2.h | 1 +
gfs2/libgfs2/rgrp.c | 24 +++++++++++++++++++++
gfs2/libgfs2/rgrp.h | 1 +
4 files changed, 83 insertions(+)
diff --git a/gfs2/libgfs2/fs_ops.c b/gfs2/libgfs2/fs_ops.c
index c8b90ad..98db34d 100644
--- a/gfs2/libgfs2/fs_ops.c
+++ b/gfs2/libgfs2/fs_ops.c
@@ -13,6 +13,7 @@
#include <linux/types.h>
#include "libgfs2.h"
+#include "rgrp.h"
static __inline__ uint64_t *metapointer(struct gfs2_buffer_head *bh,
unsigned int height,
@@ -291,6 +292,62 @@ uint64_t lgfs2_space_for_data(const struct gfs2_sbd *sdp, const unsigned bsize,
return blks + 1;
}
+/**
+ * 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
+ * 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
+ * with errno set on error. If errno is ENOSPC then rg does not contain a
+ * large enough free extent for the given di_size.
+ */
+int lgfs2_file_alloc(lgfs2_rgrp_t rg, uint64_t di_size, struct gfs2_inode *ip, uint32_t flags, unsigned mode)
+{
+ unsigned extlen;
+ struct gfs2_dinode *di = &ip->i_di;
+ 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;
+
+ extlen = lgfs2_alloc_extent(&rbm, GFS2_BLKST_DINODE, blocks);
+ if (extlen < blocks) {
+ errno = EINVAL;
+ return 1;
+ }
+
+ ip->i_sbd = sdp;
+
+ di->di_header.mh_magic = GFS2_MAGIC;
+ di->di_header.mh_type = GFS2_METATYPE_DI;
+ di->di_header.mh_format = GFS2_FORMAT_DI;
+ di->di_size = di_size;
+ di->di_num.no_addr = lgfs2_rbm_to_block(&rbm);
+ di->di_num.no_formal_ino = sdp->md.next_inum++;
+ di->di_mode = mode;
+ di->di_nlink = 1;
+ di->di_blocks = blocks;
+ di->di_atime = di->di_mtime = di->di_ctime = sdp->time;
+ di->di_goal_data = di->di_num.no_addr + di->di_blocks - 1;
+ di->di_goal_meta = di->di_goal_data - ((di_size + sdp->bsize - 1) / sdp->bsize);
+ di->di_height = calc_tree_height(ip, di_size);
+ di->di_flags = flags;
+
+ rg->rg.rg_free -= blocks;
+ rg->rg.rg_dinodes += 1;
+
+ sdp->dinodes_alloced++;
+ sdp->blks_alloced += blocks;
+
+ return 0;
+}
+
unsigned int calc_tree_height(struct gfs2_inode *ip, uint64_t size)
{
struct gfs2_sbd *sdp = ip->i_sbd;
diff --git a/gfs2/libgfs2/libgfs2.h b/gfs2/libgfs2/libgfs2.h
index 9b1bdc2..43529a0 100644
--- a/gfs2/libgfs2/libgfs2.h
+++ b/gfs2/libgfs2/libgfs2.h
@@ -453,6 +453,7 @@ extern uint64_t data_alloc(struct gfs2_inode *ip);
extern int lgfs2_meta_alloc(struct gfs2_inode *ip, uint64_t *blkno);
extern int lgfs2_dinode_alloc(struct gfs2_sbd *sdp, const uint64_t blksreq, uint64_t *blkno);
extern uint64_t lgfs2_space_for_data(const struct gfs2_sbd *sdp, unsigned bsize, uint64_t bytes);
+extern int lgfs2_file_alloc(lgfs2_rgrp_t rg, uint64_t di_size, struct gfs2_inode *ip, uint32_t flags, unsigned mode);
extern int gfs2_readi(struct gfs2_inode *ip, void *buf, uint64_t offset,
unsigned int size);
diff --git a/gfs2/libgfs2/rgrp.c b/gfs2/libgfs2/rgrp.c
index a3fa1a4..772e6d0 100644
--- a/gfs2/libgfs2/rgrp.c
+++ b/gfs2/libgfs2/rgrp.c
@@ -841,3 +841,27 @@ res_covered_end_of_rgrp:
errno = ENOSPC;
return 1;
}
+
+/**
+ * lgfs2_alloc_extent - allocate an extent from a given bitmap
+ * @rbm: the resource group information
+ * @state: The state of the first block, GFS2_BLKST_DINODE or GFS2_BLKST_USED
+ * @elen: The requested extent length
+ * Returns the length of the extent allocated.
+ */
+unsigned lgfs2_alloc_extent(const struct lgfs2_rbm *rbm, int state, const unsigned elen)
+{
+ struct lgfs2_rbm pos = { .rgd = rbm->rgd, };
+ const uint64_t block = lgfs2_rbm_to_block(rbm);
+ unsigned len;
+
+ gfs2_set_bitmap(rbm->rgd, block, state);
+
+ for (len = 1; len < elen; len++) {
+ int ret = lgfs2_rbm_from_block(&pos, block + len);
+ if (ret || lgfs2_testbit(&pos) != GFS2_BLKST_FREE)
+ break;
+ gfs2_set_bitmap(pos.rgd, block + len, GFS2_BLKST_USED);
+ }
+ return len;
+}
diff --git a/gfs2/libgfs2/rgrp.h b/gfs2/libgfs2/rgrp.h
index 1634fbc..bd89289 100644
--- a/gfs2/libgfs2/rgrp.h
+++ b/gfs2/libgfs2/rgrp.h
@@ -45,5 +45,6 @@ static inline int lgfs2_rbm_eq(const struct lgfs2_rbm *rbm1, const struct lgfs2_
}
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);
#endif /* __RGRP_DOT_H__ */
--
1.9.3
next prev parent reply other threads:[~2014-09-02 12:07 UTC|newest]
Thread overview: 25+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-09-02 12:07 [Cluster-devel] [PATCH 00/19] gfs2-utils: Introduce extent allocation and speed up journal creation Andrew Price
2014-09-02 12:07 ` [Cluster-devel] [PATCH 01/19] libgfs2: Keep a pointer to the sbd in lgfs2_rgrps_t Andrew Price
2014-09-02 12:07 ` [Cluster-devel] [PATCH 02/19] libgfs2: Move bitmap buffers inside struct gfs2_bitmap Andrew Price
2014-09-02 12:07 ` [Cluster-devel] [PATCH 03/19] libgfs2: Fix an impossible loop condition in gfs2_rgrp_read Andrew Price
2014-09-02 12:07 ` [Cluster-devel] [PATCH 04/19] libgfs2: Introduce struct lgfs2_rbm Andrew Price
2014-09-02 12:07 ` [Cluster-devel] [PATCH 05/19] libgfs2: Move struct _lgfs2_rgrps into rgrp.h Andrew Price
2014-09-02 12:07 ` [Cluster-devel] [PATCH 06/19] libgfs2: Add functions for finding free extents Andrew Price
2014-09-03 10:17 ` Steven Whitehouse
2014-09-03 12:13 ` Andrew Price
2014-09-03 12:24 ` Steven Whitehouse
2014-09-02 12:07 ` [Cluster-devel] [PATCH 07/19] tests: Add unit tests for the new extent search functions Andrew Price
2014-09-02 12:07 ` [Cluster-devel] [PATCH 08/19] libgfs2: Ignore an empty rgrp plan if a length is specified Andrew Price
2014-09-02 12:07 ` [Cluster-devel] [PATCH 09/19] libgfs2: Add back-pointer to rgrps in lgfs2_rgrp_t Andrew Price
2014-09-02 12:07 ` [Cluster-devel] [PATCH 10/19] libgfs2: Const-ify the parameters of print functions Andrew Price
2014-09-02 12:07 ` [Cluster-devel] [PATCH 11/19] libgfs2: Allow init_dinode to accept a preallocated bh Andrew Price
2014-09-02 12:07 ` Andrew Price [this message]
2014-09-02 12:07 ` [Cluster-devel] [PATCH 13/19] libgfs2: Add support for allocating entire rgrp headers Andrew Price
2014-09-02 12:07 ` [Cluster-devel] [PATCH 14/19] libgfs2: Write file metadata sequentially Andrew Price
2014-09-02 12:07 ` [Cluster-devel] [PATCH 15/19] libgfs2: Fix alignment in lgfs2_rgsize_for_data Andrew Price
2014-09-02 12:07 ` [Cluster-devel] [PATCH 16/19] libgfs2: Handle non-zero bitmaps in lgfs2_rgrp_write Andrew Price
2014-09-02 12:07 ` [Cluster-devel] [PATCH 17/19] libgfs2: Add a speedier journal data block writing function Andrew Price
2014-09-02 12:07 ` [Cluster-devel] [PATCH 18/19] libgfs2: Create jindex directory separately from journals Andrew Price
2014-09-02 12:07 ` [Cluster-devel] [PATCH 19/19] mkfs.gfs2: Improve journal creation performance Andrew Price
2014-09-02 14:06 ` [Cluster-devel] [PATCH 00/19] gfs2-utils: Introduce extent allocation and speed up journal creation Bob Peterson
2014-09-03 10:20 ` Steven Whitehouse
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=1409659656-23051-13-git-send-email-anprice@redhat.com \
--to=anprice@redhat.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).