Преглед на файлове

mingw32: Make NTFS sparse file on --file-allocation=trunc

Tatsuhiro Tsujikawa преди 12 години
родител
ревизия
e0ea88ebcf

+ 13 - 1
src/AbstractDiskWriter.cc

@@ -463,11 +463,23 @@ void AbstractDiskWriter::truncate(int64_t length)
     }
 }
 
-void AbstractDiskWriter::allocate(int64_t offset, int64_t length)
+void AbstractDiskWriter::allocate(int64_t offset, int64_t length, bool sparse)
 {
   if(fd_ == A2_BAD_FD) {
     throw DL_ABORT_EX("File not yet opened.");
   }
+  if(sparse) {
+#ifdef __MINGW32__
+    DWORD bytesReturned;
+    if(!DeviceIoControl(fd_, FSCTL_SET_SPARSE, 0, 0, 0, 0,
+                        &bytesReturned, 0)) {
+      A2_LOG_WARN(fmt("Making file sparse failed or pending: %s",
+                      fileStrerror(GetLastError()).c_str()));
+    }
+#endif // __MINGW32__
+    truncate(offset+length);
+    return;
+  }
 #ifdef  HAVE_SOME_FALLOCATE
 # ifdef __MINGW32__
   truncate(offset+length);

+ 1 - 1
src/AbstractDiskWriter.h

@@ -84,7 +84,7 @@ public:
   virtual void truncate(int64_t length);
 
   // File must be opened before calling this function.
-  virtual void allocate(int64_t offset, int64_t length);
+  virtual void allocate(int64_t offset, int64_t length, bool sparse);
 
   virtual int64_t size();
 

+ 1 - 1
src/AdaptiveFileAllocationIterator.cc

@@ -62,7 +62,7 @@ void AdaptiveFileAllocationIterator::allocateChunk()
       if(offset_ < totalLength_) {
         int64_t len = std::min(totalLength_-offset_,
                                static_cast<int64_t>(4096));
-        stream_->allocate(offset_, len);
+        stream_->allocate(offset_, len, false);
         offset_ += len;
       }
       A2_LOG_DEBUG("File system supports fallocate.");

+ 3 - 2
src/BinaryStream.h

@@ -55,8 +55,9 @@ public:
   virtual void truncate(int64_t length) {}
 
   // Allocates given length bytes of disk space from given offset. The
-  // default implementation does nothing.
-  virtual void allocate(int64_t offset, int64_t length) {}
+  // default implementation does nothing. If sparse is true, the
+  // implementation may create sparse file (with holes).
+  virtual void allocate(int64_t offset, int64_t length, bool sparse) {}
 };
 
 } // namespace aria2

+ 1 - 1
src/FallocFileAllocationIterator.cc

@@ -44,7 +44,7 @@ FallocFileAllocationIterator::FallocFileAllocationIterator
 void FallocFileAllocationIterator::allocateChunk()
 {
   if(offset_ < totalLength_) {
-    stream_->allocate(offset_, totalLength_-offset_);
+    stream_->allocate(offset_, totalLength_-offset_, false);
     offset_ = totalLength_;
   } else {
     stream_->truncate(totalLength_);

+ 1 - 1
src/TruncFileAllocationIterator.cc

@@ -46,7 +46,7 @@ TruncFileAllocationIterator::TruncFileAllocationIterator
 
 void TruncFileAllocationIterator::allocateChunk()
 {
-  stream_->truncate(totalLength_);
+  stream_->allocate(0, totalLength_, true);
   offset_ = totalLength_;
 }