Gitweb:
http://git.fedorahosted.org/git/?p=gfs2-utils.git;a=commitdiff;h=52533970...
Commit: 525339706657f324fdfa56f9538b74a6cd51752b
Parent: a1e9d5e5171079b7d2f0c2f7c9f22e3a9dff04c4
Author: Andrew Price <anprice(a)redhat.com>
AuthorDate: Tue Aug 26 15:19:01 2014 +0100
Committer: Andrew Price <anprice(a)redhat.com>
CommitterDate: Fri Sep 5 14:57:46 2014 +0100
libgfs2: Allow init_dinode to accept a preallocated bh
Previously init_dinode() always allocated the bh with bget() which meant
less control over memory allocation higher up. This patch changes the
signature of init_dinode to accept a bh pointer and only allocates a new
bh if it is NULL. Also adds error checking to init_dinode()'s callers.
Signed-off-by: Andrew Price <anprice(a)redhat.com>
---
gfs2/convert/gfs2_convert.c | 7 +++++--
gfs2/fsck/initialize.c | 12 ++++++++----
gfs2/libgfs2/fs_ops.c | 42 ++++++++++++++++++++++++------------------
gfs2/libgfs2/libgfs2.h | 6 ++----
gfs2/libgfs2/structures.c | 13 +++++++++----
5 files changed, 48 insertions(+), 32 deletions(-)
diff --git a/gfs2/convert/gfs2_convert.c b/gfs2/convert/gfs2_convert.c
index 61ed320..19a9839 100644
--- a/gfs2/convert/gfs2_convert.c
+++ b/gfs2/convert/gfs2_convert.c
@@ -1389,7 +1389,7 @@ static int fix_cdpn_symlinks(struct gfs2_sbd *sbp, osi_list_t
*cdpn_to_fix)
osi_list_foreach_safe(tmp, cdpn_to_fix, x) {
struct gfs2_inum fix, dir;
struct inode_dir_block *l_fix;
- struct gfs2_buffer_head *bh;
+ struct gfs2_buffer_head *bh = NULL;
struct gfs2_inode *fix_inode;
uint64_t eablk;
@@ -1411,7 +1411,10 @@ static int fix_cdpn_symlinks(struct gfs2_sbd *sbp, osi_list_t
*cdpn_to_fix)
}
/* initialize the symlink inode to be a directory */
- bh = init_dinode(sbp, &fix, S_IFDIR | 0755, 0, &dir);
+ error = init_dinode(sbp, &bh, &fix, S_IFDIR | 0755, 0, &dir);
+ if (error != 0)
+ return -1;
+
fix_inode = lgfs2_inode_get(sbp, bh);
if (fix_inode == NULL)
return -1;
diff --git a/gfs2/fsck/initialize.c b/gfs2/fsck/initialize.c
index 02ecd3f..4dedec2 100644
--- a/gfs2/fsck/initialize.c
+++ b/gfs2/fsck/initialize.c
@@ -419,7 +419,7 @@ static void check_rgrps_integrity(struct gfs2_sbd *sdp)
static int rebuild_master(struct gfs2_sbd *sdp)
{
struct gfs2_inum inum;
- struct gfs2_buffer_head *bh;
+ struct gfs2_buffer_head *bh = NULL;
int err = 0;
log_err(_("The system master directory seems to be destroyed.\n"));
@@ -430,7 +430,9 @@ static int rebuild_master(struct gfs2_sbd *sdp)
log_err(_("Trying to rebuild the master directory.\n"));
inum.no_formal_ino = sdp->md.next_inum++;
inum.no_addr = sdp->sd_sb.sb_master_dir.no_addr;
- bh = init_dinode(sdp, &inum, S_IFDIR | 0755, GFS2_DIF_SYSTEM, &inum);
+ err = init_dinode(sdp, &bh, &inum, S_IFDIR | 0755, GFS2_DIF_SYSTEM, &inum);
+ if (err != 0)
+ return -1;
sdp->master_dir = lgfs2_inode_get(sdp, bh);
if (sdp->master_dir == NULL) {
log_crit(_("Error reading master: %s\n"), strerror(errno));
@@ -1210,7 +1212,7 @@ static int sb_repair(struct gfs2_sbd *sdp)
sdp->md.rooti = lgfs2_inode_read(sdp, possible_root);
if (!sdp->md.rooti ||
sdp->md.rooti->i_di.di_header.mh_magic != GFS2_MAGIC) {
- struct gfs2_buffer_head *bh;
+ struct gfs2_buffer_head *bh = NULL;
log_err(_("The root dinode block is destroyed.\n"));
log_err(_("At this point I recommend "
@@ -1225,7 +1227,9 @@ static int sb_repair(struct gfs2_sbd *sdp)
}
inum.no_formal_ino = 1;
inum.no_addr = possible_root;
- bh = init_dinode(sdp, &inum, S_IFDIR | 0755, 0, &inum);
+ error = init_dinode(sdp, &bh, &inum, S_IFDIR | 0755, 0, &inum);
+ if (error != 0)
+ return -1;
brelse(bh);
}
}
diff --git a/gfs2/libgfs2/fs_ops.c b/gfs2/libgfs2/fs_ops.c
index aa95aa8..c8b90ad 100644
--- a/gfs2/libgfs2/fs_ops.c
+++ b/gfs2/libgfs2/fs_ops.c
@@ -1273,24 +1273,30 @@ int dir_add(struct gfs2_inode *dip, const char *filename, int
len,
return err;
}
-static struct gfs2_buffer_head *__init_dinode(struct gfs2_sbd *sdp,
- struct gfs2_inum *inum,
- unsigned int mode,
- uint32_t flags,
- struct gfs2_inum *parent,
- int gfs1)
+static int __init_dinode(struct gfs2_sbd *sdp, struct gfs2_buffer_head **bhp, struct
gfs2_inum *inum,
+ unsigned int mode, uint32_t flags, struct gfs2_inum *parent, int
gfs1)
{
struct gfs2_buffer_head *bh;
- struct gfs2_dinode di;
+ struct gfs2_dinode di = {{0}};
int is_dir;
if (gfs1)
is_dir = (IF2DT(mode) == GFS_FILE_DIR);
else
is_dir = S_ISDIR(mode);
- bh = bget(sdp, inum->no_addr);
- memset(&di, 0, sizeof(struct gfs2_dinode));
+ errno = EINVAL;
+ if (bhp == NULL)
+ return 1;
+
+ if (*bhp == NULL) {
+ *bhp = bget(sdp, inum->no_addr);
+ if (*bhp == NULL)
+ return 1;
+ }
+
+ bh = *bhp;
+
di.di_header.mh_magic = GFS2_MAGIC;
di.di_header.mh_type = GFS2_METATYPE_DI;
di.di_header.mh_format = GFS2_FORMAT_DI;
@@ -1340,15 +1346,13 @@ static struct gfs2_buffer_head *__init_dinode(struct gfs2_sbd
*sdp,
gfs2_dinode_out(&di, bh);
- return bh;
+ return 0;
}
-struct gfs2_buffer_head *init_dinode(struct gfs2_sbd *sdp,
- struct gfs2_inum *inum,
- unsigned int mode, uint32_t flags,
- struct gfs2_inum *parent)
+int init_dinode(struct gfs2_sbd *sdp, struct gfs2_buffer_head **bhp, struct gfs2_inum
*inum,
+ unsigned int mode, uint32_t flags, struct gfs2_inum *parent)
{
- return __init_dinode(sdp, inum, mode, flags, parent, 0);
+ return __init_dinode(sdp, bhp, inum, mode, flags, parent, 0);
}
static struct gfs2_inode *__createi(struct gfs2_inode *dip,
@@ -1358,7 +1362,7 @@ static struct gfs2_inode *__createi(struct gfs2_inode *dip,
struct gfs2_sbd *sdp = dip->i_sbd;
uint64_t bn;
struct gfs2_inum inum;
- struct gfs2_buffer_head *bh;
+ struct gfs2_buffer_head *bh = NULL;
struct gfs2_inode *ip;
int err = 0;
int is_dir;
@@ -1388,8 +1392,10 @@ static struct gfs2_inode *__createi(struct gfs2_inode *dip,
dip->i_di.di_nlink++;
}
- bh = __init_dinode(sdp, &inum, mode, flags, &dip->i_di.di_num,
- if_gfs1);
+ err = __init_dinode(sdp, &bh, &inum, mode, flags, &dip->i_di.di_num,
if_gfs1);
+ if (err != 0)
+ return NULL;
+
ip = lgfs2_inode_get(sdp, bh);
if (ip == NULL)
return NULL;
diff --git a/gfs2/libgfs2/libgfs2.h b/gfs2/libgfs2/libgfs2.h
index ed1030c..9b1bdc2 100644
--- a/gfs2/libgfs2/libgfs2.h
+++ b/gfs2/libgfs2/libgfs2.h
@@ -462,10 +462,8 @@ extern int __gfs2_writei(struct gfs2_inode *ip, void *buf, uint64_t
offset,
unsigned int size, int resize);
extern struct gfs2_buffer_head *get_file_buf(struct gfs2_inode *ip,
uint64_t lbn, int prealloc);
-extern struct gfs2_buffer_head *init_dinode(struct gfs2_sbd *sdp,
- struct gfs2_inum *inum,
- unsigned int mode, uint32_t flags,
- struct gfs2_inum *parent);
+extern int init_dinode(struct gfs2_sbd *sdp, struct gfs2_buffer_head **bhp, struct
gfs2_inum *inum,
+ unsigned int mode, uint32_t flags, struct gfs2_inum *parent);
extern struct gfs2_inode *createi(struct gfs2_inode *dip, const char *filename,
unsigned int mode, uint32_t flags);
extern struct gfs2_inode *gfs_createi(struct gfs2_inode *dip,
diff --git a/gfs2/libgfs2/structures.c b/gfs2/libgfs2/structures.c
index 9d90657..1836255 100644
--- a/gfs2/libgfs2/structures.c
+++ b/gfs2/libgfs2/structures.c
@@ -20,7 +20,7 @@ int build_master(struct gfs2_sbd *sdp)
{
struct gfs2_inum inum;
uint64_t bn;
- struct gfs2_buffer_head *bh;
+ struct gfs2_buffer_head *bh = NULL;
int err = lgfs2_dinode_alloc(sdp, 1, &bn);
if (err != 0)
@@ -29,7 +29,9 @@ int build_master(struct gfs2_sbd *sdp)
inum.no_formal_ino = sdp->md.next_inum++;
inum.no_addr = bn;
- bh = init_dinode(sdp, &inum, S_IFDIR | 0755, GFS2_DIF_SYSTEM, &inum);
+ err = init_dinode(sdp, &bh, &inum, S_IFDIR | 0755, GFS2_DIF_SYSTEM, &inum);
+ if (err != 0)
+ return -1;
sdp->master_dir = lgfs2_inode_get(sdp, bh);
if (sdp->master_dir == NULL)
@@ -479,7 +481,7 @@ int build_root(struct gfs2_sbd *sdp)
{
struct gfs2_inum inum;
uint64_t bn;
- struct gfs2_buffer_head *bh;
+ struct gfs2_buffer_head *bh = NULL;
int err = lgfs2_dinode_alloc(sdp, 1, &bn);
if (err != 0)
@@ -488,7 +490,10 @@ int build_root(struct gfs2_sbd *sdp)
inum.no_formal_ino = sdp->md.next_inum++;
inum.no_addr = bn;
- bh = init_dinode(sdp, &inum, S_IFDIR | 0755, 0, &inum);
+ err = init_dinode(sdp, &bh, &inum, S_IFDIR | 0755, 0, &inum);
+ if (err != 0)
+ return -1;
+
sdp->md.rooti = lgfs2_inode_get(sdp, bh);
if (sdp->md.rooti == NULL)
return -1;