Gitweb:
http://git.fedorahosted.org/git/cluster.git?p=cluster.git;a=commitdiff;h=...
Commit: 3575517393317423b10a9717fc5157261993625d
Parent: 98ea28be22109e64107db447a829e0b8a42863b2
Author: Benjamin Marzinski <bmarzins(a)redhat.com>
AuthorDate: Tue Jan 25 13:39:03 2011 -0600
Committer: Benjamin Marzinski <bmarzins(a)redhat.com>
CommitterDate: Tue Jan 25 13:39:03 2011 -0600
enable gfs2_grow on completely full filesystems
The rindex file needs some pre-allocated space so that when gfs2_grow tries
to grow the filesystem, there will always be room for at least one more
rindex entry. mkfs.gfs2 and gfs2_grow now both pre-allocate space in the
rindex file.
---
gfs2/libgfs2/fs_ops.c | 6 +++---
gfs2/libgfs2/libgfs2.h | 6 ++++--
gfs2/libgfs2/structures.c | 7 ++++++-
gfs2/mkfs/main_grow.c | 35 +++++++++++++++++++++++++++++++++--
4 files changed, 46 insertions(+), 8 deletions(-)
diff --git a/gfs2/libgfs2/fs_ops.c b/gfs2/libgfs2/fs_ops.c
index 2b1fa46..e2b4f54 100644
--- a/gfs2/libgfs2/fs_ops.c
+++ b/gfs2/libgfs2/fs_ops.c
@@ -575,8 +575,8 @@ static void copy_from_mem(struct gfs2_buffer_head *bh, void **buf,
*p += size;
}
-int gfs2_writei(struct gfs2_inode *ip, void *buf,
- uint64_t offset, unsigned int size)
+int __gfs2_writei(struct gfs2_inode *ip, void *buf,
+ uint64_t offset, unsigned int size, int resize)
{
struct gfs2_sbd *sdp = ip->i_sbd;
struct gfs2_buffer_head *bh;
@@ -647,7 +647,7 @@ int gfs2_writei(struct gfs2_inode *ip, void *buf,
o = (isdir) ? sizeof(struct gfs2_meta_header) : 0;
}
- if (ip->i_di.di_size < start + copied) {
+ if (resize && ip->i_di.di_size < start + copied) {
bmodified(ip->i_bh);
ip->i_di.di_size = start + copied;
}
diff --git a/gfs2/libgfs2/libgfs2.h b/gfs2/libgfs2/libgfs2.h
index cd2042a..3e1b11d 100644
--- a/gfs2/libgfs2/libgfs2.h
+++ b/gfs2/libgfs2/libgfs2.h
@@ -443,8 +443,10 @@ extern uint64_t meta_alloc(struct gfs2_inode *ip);
extern uint64_t dinode_alloc(struct gfs2_sbd *sdp);
extern int gfs2_readi(struct gfs2_inode *ip, void *buf, uint64_t offset,
unsigned int size);
-extern int gfs2_writei(struct gfs2_inode *ip, void *buf, uint64_t offset,
- unsigned int size);
+#define gfs2_writei(ip, buf, offset, size) \
+ __gfs2_writei(ip, buf, offset, size, 1)
+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,
diff --git a/gfs2/libgfs2/structures.c b/gfs2/libgfs2/structures.c
index bb72e30..2a09214 100644
--- a/gfs2/libgfs2/structures.c
+++ b/gfs2/libgfs2/structures.c
@@ -337,10 +337,15 @@ int build_rindex(struct gfs2_sbd *sdp)
gfs2_rindex_out(&rl->ri, buf);
count = gfs2_writei(ip, buf, ip->i_di.di_size,
- sizeof(struct gfs2_rindex));
+ sizeof(struct gfs2_rindex));
if (count != sizeof(struct gfs2_rindex))
return -1;
}
+ memset(buf, 0, sizeof(struct gfs2_rindex));
+ count = __gfs2_writei(ip, buf, ip->i_di.di_size,
+ sizeof(struct gfs2_rindex), 0);
+ if (count != sizeof(struct gfs2_rindex))
+ return -1;
if (sdp->debug) {
printf("\nResource Index:\n");
diff --git a/gfs2/mkfs/main_grow.c b/gfs2/mkfs/main_grow.c
index 75b6715..f194443 100644
--- a/gfs2/mkfs/main_grow.c
+++ b/gfs2/mkfs/main_grow.c
@@ -9,7 +9,6 @@
**
*******************************************************************************
******************************************************************************/
-
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -29,6 +28,7 @@
#include <stdarg.h>
#include <linux/types.h>
#include <libintl.h>
+#include <sys/syscall.h>
#define _(String) gettext(String)
#include "libgfs2.h"
@@ -196,6 +196,7 @@ static void fix_rindex(struct gfs2_sbd *sdp, int rindex_fd, int
old_rg_count)
char *buf, *bufptr;
osi_list_t *tmp;
ssize_t writelen;
+ struct stat statbuf;
/* Count the number of new RGs. */
rg = 0;
@@ -219,14 +220,44 @@ static void fix_rindex(struct gfs2_sbd *sdp, int rindex_fd, int
old_rg_count)
gfs2_rgrp_free(&sdp->rglist);
fsync(sdp->device_fd);
if (!test) {
+ if (fstat(rindex_fd, &statbuf) != 0) {
+ log_crit("Can't stat rindex : %s\n", strerror(errno));
+ goto out;
+ }
+ if (statbuf.st_size !=
+ old_rg_count * sizeof(struct gfs2_rindex)) {
+ log_crit("Incorrect rindex size. want %ld(%d RGs), "
+ "have %ld\n",
+ old_rg_count * sizeof(struct gfs2_rindex),
+ old_rg_count, statbuf.st_size);
+ goto out;
+ }
/* Now write the new RGs to the end of the rindex */
lseek(rindex_fd, 0, SEEK_END);
count = write(rindex_fd, buf, writelen);
- if (count != writelen)
+ if (count != writelen) {
log_crit( _("Error writing new rindex entries;"
"aborted.\n"));
+ if (count > 0)
+ goto trunc;
+ else
+ goto out;
+ }
+ if (syscall(__NR_fallocate, rindex_fd, 1,
+ statbuf.st_size + writelen,
+ sizeof(struct gfs2_rindex)) != 0)
+ log_crit("Error fallocating extra space : %s\n",
+ strerror(errno));
fsync(rindex_fd);
}
+out:
+ free(buf);
+ return;
+trunc:
+ count = (count / sizeof(struct gfs2_rindex)) + old_rg_count;
+ log_crit("truncating rindex to %ld\n",
+ (off_t)count * sizeof(struct gfs2_rindex));
+ ftruncate(rindex_fd, (off_t)count * sizeof(struct gfs2_rindex));
free(buf);
}