|
@@ -12,31 +12,36 @@
|
|
|
// See the License for the specific language governing permissions and
|
|
// See the License for the specific language governing permissions and
|
|
|
// limitations under the License.
|
|
// limitations under the License.
|
|
|
|
|
|
|
|
-// +build linux
|
|
|
|
|
-
|
|
|
|
|
package fileutil
|
|
package fileutil
|
|
|
|
|
|
|
|
-import (
|
|
|
|
|
- "os"
|
|
|
|
|
- "syscall"
|
|
|
|
|
-)
|
|
|
|
|
|
|
+import "os"
|
|
|
|
|
|
|
|
// Preallocate tries to allocate the space for given
|
|
// Preallocate tries to allocate the space for given
|
|
|
// file. This operation is only supported on linux by a
|
|
// file. This operation is only supported on linux by a
|
|
|
// few filesystems (btrfs, ext4, etc.).
|
|
// few filesystems (btrfs, ext4, etc.).
|
|
|
// If the operation is unsupported, no error will be returned.
|
|
// If the operation is unsupported, no error will be returned.
|
|
|
// Otherwise, the error encountered will be returned.
|
|
// Otherwise, the error encountered will be returned.
|
|
|
-func Preallocate(f *os.File, sizeInBytes int) error {
|
|
|
|
|
- // use mode = 1 to keep size
|
|
|
|
|
- // see FALLOC_FL_KEEP_SIZE
|
|
|
|
|
- err := syscall.Fallocate(int(f.Fd()), 1, 0, int64(sizeInBytes))
|
|
|
|
|
|
|
+func Preallocate(f *os.File, sizeInBytes int64, extendFile bool) error {
|
|
|
|
|
+ if extendFile {
|
|
|
|
|
+ preallocExtend(f, sizeInBytes)
|
|
|
|
|
+ }
|
|
|
|
|
+ return preallocFixed(f, sizeInBytes)
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+func preallocExtendTrunc(f *os.File, sizeInBytes int64) error {
|
|
|
|
|
+ curOff, err := f.Seek(0, os.SEEK_CUR)
|
|
|
|
|
+ if err != nil {
|
|
|
|
|
+ return err
|
|
|
|
|
+ }
|
|
|
|
|
+ size, err := f.Seek(sizeInBytes, os.SEEK_END)
|
|
|
if err != nil {
|
|
if err != nil {
|
|
|
- errno, ok := err.(syscall.Errno)
|
|
|
|
|
- // treat not support as nil error
|
|
|
|
|
- if ok && errno == syscall.ENOTSUP {
|
|
|
|
|
- return nil
|
|
|
|
|
- }
|
|
|
|
|
return err
|
|
return err
|
|
|
}
|
|
}
|
|
|
- return nil
|
|
|
|
|
|
|
+ if _, err = f.Seek(curOff, os.SEEK_SET); err != nil {
|
|
|
|
|
+ return err
|
|
|
|
|
+ }
|
|
|
|
|
+ if sizeInBytes > size {
|
|
|
|
|
+ return nil
|
|
|
|
|
+ }
|
|
|
|
|
+ return f.Truncate(sizeInBytes)
|
|
|
}
|
|
}
|