Browse Source

Added new file allocation method called 'trunc'

--file-allocation option can now take new value 'trunc'. 'trunc' uses
ftruncate() system call or platform-specific counterpart to truncate a
file to a specified length.
Tatsuhiro Tsujikawa 13 years ago
parent
commit
d734ff7d29

+ 5 - 1
doc/manual-src/en/aria2c.rst

@@ -1078,7 +1078,11 @@ Advanced Options
   entirely until allocation finishes. ``falloc`` may
   not be available if your system doesn't have
   :manpage:`posix_fallocate(3)` function.
-  Possible Values: ``none``, ``prealloc``, ``falloc``
+  ``trunc`` uses :manpage:`ftruncate(2)` system call or
+  platform-specific counterpart to truncate a file to a specified
+  length.
+
+  Possible Values: ``none``, ``prealloc``, ``trunc``, ``falloc``
   Default: ``prealloc``
 
 .. option:: --hash-check-only[=true|false]

+ 7 - 0
src/AbstractSingleDiskAdaptor.cc

@@ -37,6 +37,7 @@
 #include "AdaptiveFileAllocationIterator.h"
 #include "DiskWriter.h"
 #include "FileEntry.h"
+#include "TruncFileAllocationIterator.h"
 #ifdef HAVE_SOME_FALLOCATE
 # include "FallocFileAllocationIterator.h"
 #endif // HAVE_SOME_FALLOCATE
@@ -107,6 +108,12 @@ AbstractSingleDiskAdaptor::fileAllocationIterator()
     return h;
   }
 #endif // HAVE_SOME_FALLOCATE
+  case(DiskAdaptor::FILE_ALLOC_TRUNC): {
+    SharedHandle<TruncFileAllocationIterator> h
+      (new TruncFileAllocationIterator
+       (diskWriter_.get(), size(), totalLength_));
+    return h;
+  }
   default: {
     SharedHandle<AdaptiveFileAllocationIterator> h
       (new AdaptiveFileAllocationIterator

+ 2 - 0
src/DefaultPieceStorage.cc

@@ -635,6 +635,8 @@ void DefaultPieceStorage::initStorage()
   }
   if(option_->get(PREF_FILE_ALLOCATION) == V_FALLOC) {
     diskAdaptor_->setFileAllocationMethod(DiskAdaptor::FILE_ALLOC_FALLOC);
+  } else if(option_->get(PREF_FILE_ALLOCATION) == V_TRUNC) {
+    diskAdaptor_->setFileAllocationMethod(DiskAdaptor::FILE_ALLOC_TRUNC);
   }
 }
 

+ 2 - 1
src/DiskAdaptor.h

@@ -51,7 +51,8 @@ class DiskAdaptor:public BinaryStream {
 public:
   enum FileAllocationMethod {
     FILE_ALLOC_ADAPTIVE,
-    FILE_ALLOC_FALLOC
+    FILE_ALLOC_FALLOC,
+    FILE_ALLOC_TRUNC
   };
 
   DiskAdaptor();

+ 1 - 0
src/Makefile.am

@@ -192,6 +192,7 @@ SRCS =  Socket.h\
 	ContextAttribute.h\
 	TorrentAttribute.cc TorrentAttribute.h\
 	AdaptiveFileAllocationIterator.cc AdaptiveFileAllocationIterator.h\
+	TruncFileAllocationIterator.cc TruncFileAllocationIterator.h\
 	StreamFilter.cc StreamFilter.h\
 	SinkStreamFilter.cc SinkStreamFilter.h\
 	ChunkedDecodingStreamFilter.cc ChunkedDecodingStreamFilter.h\

+ 7 - 0
src/MultiFileAllocationIterator.cc

@@ -36,6 +36,7 @@
 #include "MultiDiskAdaptor.h"
 #include "FileEntry.h"
 #include "AdaptiveFileAllocationIterator.h"
+#include "TruncFileAllocationIterator.h"
 #ifdef HAVE_SOME_FALLOCATE
 # include "FallocFileAllocationIterator.h"
 #endif // HAVE_SOME_FALLOCATE
@@ -76,6 +77,12 @@ void MultiFileAllocationIterator::allocateChunk()
                                             fileEntry->getLength()));
         break;
 #endif // HAVE_SOME_FALLOCATE
+      case(DiskAdaptor::FILE_ALLOC_TRUNC):
+        fileAllocationIterator_.reset
+          (new TruncFileAllocationIterator(entry->getDiskWriter().get(),
+                                           entry->size(),
+                                           fileEntry->getLength()));
+        break;
       default:
         fileAllocationIterator_.reset
           (new AdaptiveFileAllocationIterator(entry->getDiskWriter().get(),

+ 7 - 4
src/OptionHandlerFactory.cc

@@ -354,14 +354,17 @@ OptionHandlerFactory::createOptionHandlers()
     handlers.push_back(op);
   }
   {
+    const std::string params[] = { V_NONE, V_PREALLOC, V_TRUNC,
+#ifdef HAVE_SOME_FALLOCATE
+                                   V_FALLOC
+#endif // HAVE_SOME_FALLOCATE
+    };
     SharedHandle<OptionHandler> op(new ParameterOptionHandler
                                    (PREF_FILE_ALLOCATION,
                                     TEXT_FILE_ALLOCATION,
                                     V_PREALLOC,
-                                    V_NONE, V_PREALLOC,
-#ifdef HAVE_SOME_FALLOCATE
-                                    V_FALLOC,
-#endif // HAVE_SOME_FALLOCATE
+                                    std::vector<std::string>
+                                    (vbegin(params), vend(params)),
                                     'a'));
     op->addTag(TAG_BASIC);
     op->addTag(TAG_FILE);

+ 68 - 0
src/TruncFileAllocationIterator.cc

@@ -0,0 +1,68 @@
+/* <!-- copyright */
+/*
+ * aria2 - The high speed download utility
+ *
+ * Copyright (C) 2012 Tatsuhiro Tsujikawa
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the
+ * OpenSSL library under certain conditions as described in each
+ * individual source file, and distribute linked combinations
+ * including the two.
+ * You must obey the GNU General Public License in all respects
+ * for all of the code used other than OpenSSL.  If you modify
+ * file(s) with this exception, you may extend this exception to your
+ * version of the file(s), but you are not obligated to do so.  If you
+ * do not wish to do so, delete this exception statement from your
+ * version.  If you delete this exception statement from all source
+ * files in the program, then also delete it here.
+ */
+/* copyright --> */
+#include "TruncFileAllocationIterator.h"
+#include "DlAbortEx.h"
+
+namespace aria2 {
+
+TruncFileAllocationIterator::TruncFileAllocationIterator
+(BinaryStream* stream, int64_t offset, int64_t totalLength)
+  : stream_(stream),
+    offset_(offset),
+    totalLength_(totalLength)
+{}
+
+void TruncFileAllocationIterator::allocateChunk()
+{
+  stream_->truncate(totalLength_);
+  offset_ = totalLength_;
+}
+
+bool TruncFileAllocationIterator::finished()
+{
+  return offset_ == totalLength_;
+}
+
+int64_t TruncFileAllocationIterator::getCurrentLength()
+{
+  return offset_;
+}
+
+int64_t TruncFileAllocationIterator::getTotalLength()
+{
+  return totalLength_;
+}
+
+} // namespace aria2

+ 66 - 0
src/TruncFileAllocationIterator.h

@@ -0,0 +1,66 @@
+/* <!-- copyright */
+/*
+ * aria2 - The high speed download utility
+ *
+ * Copyright (C) 2012 Tatsuhiro Tsujikawa
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the
+ * OpenSSL library under certain conditions as described in each
+ * individual source file, and distribute linked combinations
+ * including the two.
+ * You must obey the GNU General Public License in all respects
+ * for all of the code used other than OpenSSL.  If you modify
+ * file(s) with this exception, you may extend this exception to your
+ * version of the file(s), but you are not obligated to do so.  If you
+ * do not wish to do so, delete this exception statement from your
+ * version.  If you delete this exception statement from all source
+ * files in the program, then also delete it here.
+ */
+/* copyright --> */
+#ifndef D_TRUNC_FILE_ALLOCATION_ITERATOR_H
+#define D_TRUNC_FILE_ALLOCATION_ITERATOR_H
+
+#include "FileAllocationIterator.h"
+#include "BinaryStream.h"
+
+namespace aria2 {
+
+// Use ftruncate() system call or platform-specific counterpart to set
+// file length. This allocator may not allocate file space, it just
+// changes file length information.
+class TruncFileAllocationIterator:public FileAllocationIterator {
+private:
+  BinaryStream* stream_;
+  int64_t offset_;
+  int64_t totalLength_;
+public:
+  TruncFileAllocationIterator(BinaryStream* stream, int64_t offset,
+                              int64_t totalLength);
+
+  virtual void allocateChunk();
+
+  virtual bool finished();
+
+  virtual int64_t getCurrentLength();
+
+  virtual int64_t getTotalLength();
+};
+
+} // namespace aria2
+
+#endif // D_TRUNC_FILE_ALLOCATION_ITERATOR_H

+ 1 - 0
src/prefs.cc

@@ -132,6 +132,7 @@ const std::string A2_V_FULL("full");
 const std::string A2_V_GEOM("geom");
 const std::string V_PREALLOC("prealloc");
 const std::string V_FALLOC("falloc");
+const std::string V_TRUNC("trunc");
 const std::string V_DEBUG("debug");
 const std::string V_INFO("info");
 const std::string V_NOTICE("notice");

+ 1 - 0
src/prefs.h

@@ -75,6 +75,7 @@ extern const std::string A2_V_FULL;
 extern const std::string A2_V_GEOM;
 extern const std::string V_PREALLOC;
 extern const std::string V_FALLOC;
+extern const std::string V_TRUNC;
 extern const std::string V_DEBUG;
 extern const std::string V_INFO;
 extern const std::string V_NOTICE;

+ 4 - 1
src/usage_text.h

@@ -137,7 +137,10 @@
     "                              takes almost same time as 'prealloc' and it\n" \
     "                              blocks aria2 entirely until allocation finishes.\n" \
     "                              'falloc' may not be available if your system\n" \
-    "                              doesn't have posix_fallocate() function.")
+    "                              doesn't have posix_fallocate() function.\n" \
+    "                              'trunc' uses ftruncate() system call or\n" \
+    "                              platform-specific counterpart to truncate a file\n" \
+    "                              to a specified length.")
 #define TEXT_NO_FILE_ALLOCATION_LIMIT                                   \
   _(" --no-file-allocation-limit=SIZE No file allocation is made for files whose\n" \
     "                              size is smaller than SIZE.\n"        \