Pino Toscano
2016-Jan-22 16:37 UTC
[Libguestfs] [supermin] [PATCH] ext2: check for needed block size
Check early that there are enough free blocks to store each file,
erroring out with ENOSPC if not; this avoids slightly more obscure
errors later on.
---
src/ext2fs-c.c | 18 ++++++++++++++++++
1 file changed, 18 insertions(+)
diff --git a/src/ext2fs-c.c b/src/ext2fs-c.c
index f01ca9d..e45980a 100644
--- a/src/ext2fs-c.c
+++ b/src/ext2fs-c.c
@@ -52,6 +52,9 @@
/* fts.h in glibc is broken, forcing us to use the GNUlib alternative. */
#include "fts_.h"
+/* How many blocks of size S are needed for storing N bytes. */
+#define ROUND_UP(N, S) (((N) + (S) - 1) / (S))
+
struct ext2_data
{
ext2_filsys fs;
@@ -629,6 +632,7 @@ ext2_copy_file (struct ext2_data *data, const char *src,
const char *dest)
errcode_t err;
struct stat statbuf;
struct statvfs statvfsbuf;
+ size_t blocks;
if (data->debug >= 3)
printf ("supermin: ext2: copy_file %s -> %s\n", src, dest);
@@ -649,6 +653,20 @@ ext2_copy_file (struct ext2_data *data, const char *src,
const char *dest)
caml_copy_string (data->fs->device_name));
}
+ /* Check that we have enough free blocks to store the resulting blocks
+ * for this file. The file might need more than that in the filesystem,
+ * but at least this provides a quick check to avoid failing later on.
+ */
+ blocks = ROUND_UP (statbuf.st_size, data->fs->blocksize);
+ if (blocks > ext2fs_free_blocks_count (data->fs->super)) {
+ fprintf (stderr, "supermin: %s: needed %lu blocks (%d each) for "
+ "%lu bytes, available only %llu\n",
+ src, blocks, data->fs->blocksize, statbuf.st_size,
+ ext2fs_free_blocks_count (data->fs->super));
+ unix_error (ENOSPC, (char *) "block size",
+ data->fs->device_name ? caml_copy_string
(data->fs->device_name) : Val_none);
+ }
+
/* Sanity check the path. These rules are always true for the paths
* passed to us here from the appliance layer. The assertions just
* verify that the rules haven't changed.
--
2.5.0
Richard W.M. Jones
2016-Jan-22 18:44 UTC
Re: [Libguestfs] [supermin] [PATCH] ext2: check for needed block size
On Fri, Jan 22, 2016 at 05:37:22PM +0100, Pino Toscano wrote:> Check early that there are enough free blocks to store each file, > erroring out with ENOSPC if not; this avoids slightly more obscure > errors later on. > --- > src/ext2fs-c.c | 18 ++++++++++++++++++ > 1 file changed, 18 insertions(+) > > diff --git a/src/ext2fs-c.c b/src/ext2fs-c.c > index f01ca9d..e45980a 100644 > --- a/src/ext2fs-c.c > +++ b/src/ext2fs-c.c > @@ -52,6 +52,9 @@ > /* fts.h in glibc is broken, forcing us to use the GNUlib alternative. */ > #include "fts_.h" > > +/* How many blocks of size S are needed for storing N bytes. */ > +#define ROUND_UP(N, S) (((N) + (S) - 1) / (S)) > + > struct ext2_data > { > ext2_filsys fs; > @@ -629,6 +632,7 @@ ext2_copy_file (struct ext2_data *data, const char *src, const char *dest) > errcode_t err; > struct stat statbuf; > struct statvfs statvfsbuf; > + size_t blocks; > > if (data->debug >= 3) > printf ("supermin: ext2: copy_file %s -> %s\n", src, dest); > @@ -649,6 +653,20 @@ ext2_copy_file (struct ext2_data *data, const char *src, const char *dest) > caml_copy_string (data->fs->device_name)); > } > > + /* Check that we have enough free blocks to store the resulting blocks > + * for this file. The file might need more than that in the filesystem, > + * but at least this provides a quick check to avoid failing later on. > + */ > + blocks = ROUND_UP (statbuf.st_size, data->fs->blocksize); > + if (blocks > ext2fs_free_blocks_count (data->fs->super)) { > + fprintf (stderr, "supermin: %s: needed %lu blocks (%d each) for " > + "%lu bytes, available only %llu\n", > + src, blocks, data->fs->blocksize, statbuf.st_size, > + ext2fs_free_blocks_count (data->fs->super)); > + unix_error (ENOSPC, (char *) "block size", > + data->fs->device_name ? caml_copy_string (data->fs->device_name) : Val_none); > + } > + > /* Sanity check the path. These rules are always true for the paths > * passed to us here from the appliance layer. The assertions just > * verify that the rules haven't changed. > -- > 2.5.0ACK. Rich. -- Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones Read my programming and virtualization blog: http://rwmj.wordpress.com Fedora Windows cross-compiler. Compile Windows programs, test, and build Windows installers. Over 100 libraries supported. http://fedoraproject.org/wiki/MinGW
Maybe Matching Threads
- [PATCH supermin] ext2: fix printf formatters
- [PATCH 1/3] ext2: create a struct for the OCaml 't' type
- [PATCH] ext2: Don't load whole files into memory when copying to the appliance (RHBZ#1113065).
- [PATCH supermin] ext2: Build symbolic links correctly (RHBZ#1770304).
- [PATCH supermin] ext2: Create symlinks properly (RHBZ#1470157).