diff options
author | Christophe Vu-Brugier <cvubrugier@yahoo.fr> | 2013-12-02 20:46:39 +0100 |
---|---|---|
committer | Christophe Vu-Brugier <cvubrugier@yahoo.fr> | 2013-12-02 20:46:39 +0100 |
commit | 3bd4d8ef7c9b154c53e8b8dd863a570bce7f5c2c (patch) | |
tree | bc97dcd7d7cfc8bc697398d28a34a6a9ff459102 | |
parent | 84d796c1eba3515cca726284f69842dc19472c16 (diff) | |
download | targetcli-3bd4d8ef7c9b154c53e8b8dd863a570bce7f5c2c.tar.gz |
Fix issue #23: use fallocate() to create fileio backstores
Python 3.3 provides the fallocate() system call which is better for
allocating disk space than ftruncate(). ftruncate() sets the file size
to the requested size but does not reserve the blocks in the file
system. Unlike ftruncate(), fallocate() fails if there is not enough
free space.
Moreover, this patch improves error handling when the file cannot be
opened or when the requested size is too large to be converted to a
long int.
Signed-off-by: Christophe Vu-Brugier <cvubrugier@yahoo.fr>
-rw-r--r-- | targetcli/ui_backstore.py | 23 |
1 files changed, 16 insertions, 7 deletions
diff --git a/targetcli/ui_backstore.py b/targetcli/ui_backstore.py index 2e978d0..467ab0e 100644 --- a/targetcli/ui_backstore.py +++ b/targetcli/ui_backstore.py @@ -258,21 +258,30 @@ class UIFileIOBackstore(UIBackstore): UIBackstore.__init__(self, 'fileio', parent) def _create_file(self, filename, size, sparse=True): - f = open(filename, "w+") + try: + f = open(filename, "w+") + except (OSError, IOError): + raise ExecutionError("Could not open %s" % filename) try: if sparse: - os.ftruncate(f.fileno(), size) + try: + os.posix_fallocate(f.fileno(), 0, size) + except AttributeError: + # Prior to version 3.3, Python does not provide fallocate + os.ftruncate(f.fileno(), size) else: - self.shell.log.info("Writing %s bytes" % size) + self.shell.log.info("Writing %d bytes" % size) while size > 0: write_size = min(size, 1024) f.write("\0" * write_size) size -= write_size - except IOError: - f.close() + except (OSError, IOError): os.remove(filename) - raise ExecutionError("Could not expand file to size") - f.close() + raise ExecutionError("Could not expand file to %d bytes" % size) + except OverflowError: + raise ExecutionError("The file size is too large (%d bytes)" % size) + finally: + f.close() def ui_command_create(self, name, file_or_dev, size=None, write_back=None, sparse=None): |