Whamcloud - gitweb
ext4.5: document the stable_inodes feature
[tools/e2fsprogs.git] / misc / mk_hugefiles.c
index 3e4274c..24acca8 100644 (file)
@@ -4,6 +4,7 @@
 
 #define _XOPEN_SOURCE 600 /* for inclusion of PATH_MAX in Solaris */
 #define _BSD_SOURCE      /* for makedev() and major() */
+#define _DEFAULT_SOURCE          /* since glibc 2.20 _BSD_SOURCE is deprecated */
 
 #include "config.h"
 #include <stdio.h>
@@ -31,9 +32,14 @@ extern int optind;
 #ifdef HAVE_ERRNO_H
 #include <errno.h>
 #endif
+#ifdef HAVE_SYS_IOCTL_H
 #include <sys/ioctl.h>
+#endif
 #include <sys/types.h>
 #include <sys/stat.h>
+#ifdef HAVE_SYS_SYSMACROS_H
+#include <sys/sysmacros.h>
+#endif
 #include <libgen.h>
 #include <limits.h>
 #include <blkid/blkid.h>
@@ -45,9 +51,9 @@ extern int optind;
 #include "e2p/e2p.h"
 #include "ext2fs/ext2fs.h"
 #include "util.h"
-#include "profile.h"
-#include "prof_err.h"
-#include "nls-enable.h"
+#include "support/profile.h"
+#include "support/prof_err.h"
+#include "support/nls-enable.h"
 #include "mke2fs.h"
 
 static int uid;
@@ -62,7 +68,7 @@ static char *fn_buf;
 static char *fn_numbuf;
 int zero_hugefile = 1;
 
-#define SYSFS_PATH_LEN 256
+#define SYSFS_PATH_LEN 300
 typedef char sysfs_path_t[SYSFS_PATH_LEN];
 
 #ifndef HAVE_SNPRINTF
@@ -287,6 +293,14 @@ static errcode_t mk_hugefile(ext2_filsys fs, blk64_t num,
        if (retval)
                return retval;
 
+       /*
+        * We don't use ext2fs_fallocate() here because hugefiles are
+        * designed to be physically contiguous (if the block group
+        * descriptors are configured to be in a single block at the
+        * beginning of the file system, by using the
+        * packed_meta_blocks layout), with the extent tree blocks
+        * allocated near the beginning of the file system.
+        */
        lblk = 0;
        left = num ? num : 1;
        while (left) {
@@ -413,7 +427,8 @@ static blk64_t calc_overhead(ext2_filsys fs, blk64_t num)
        e_blocks2 = (e_blocks + extents_per_block - 1) / extents_per_block;
        e_blocks3 = (e_blocks2 + extents_per_block - 1) / extents_per_block;
        e_blocks4 = (e_blocks3 + extents_per_block - 1) / extents_per_block;
-       return e_blocks + e_blocks2 + e_blocks3 + e_blocks4;
+       return (e_blocks + e_blocks2 + e_blocks3 + e_blocks4) *
+               EXT2FS_CLUSTER_RATIO(fs);
 }
 
 /*
@@ -437,7 +452,6 @@ static blk64_t get_start_block(ext2_filsys fs, blk64_t slack)
                                                blk, last_blk, &next);
                if (retval)
                        next = last_blk;
-               next--;
 
                if (next - blk > slack) {
                        blk += slack;
@@ -477,6 +491,9 @@ errcode_t mk_hugefiles(ext2_filsys fs, const char *device_name)
        if (!get_bool_from_profile(fs_types, "make_hugefiles", 0))
                return 0;
 
+       if (!ext2fs_has_feature_extents(fs->super))
+               return EXT2_ET_EXTENT_NOT_SUPPORTED;
+
        uid = get_int_from_profile(fs_types, "hugefiles_uid", 0);
        gid = get_int_from_profile(fs_types, "hugefiles_gid", 0);
        fs->umask = get_int_from_profile(fs_types, "hugefiles_umask", 077);
@@ -551,15 +568,15 @@ errcode_t mk_hugefiles(ext2_filsys fs, const char *device_name)
                num_blocks = fs_blocks / num_files;
        }
 
-       num_slack += calc_overhead(fs, num_blocks) * num_files;
+       num_slack += (calc_overhead(fs, num_blocks ? num_blocks : fs_blocks) *
+                     num_files);
        num_slack += (num_files / 16) + 1; /* space for dir entries */
        goal = get_start_block(fs, num_slack);
        goal = round_up_align(goal, align, part_offset);
 
        if ((num_blocks ? num_blocks : fs_blocks) >
            (0x80000000UL / fs->blocksize))
-               fs->super->s_feature_ro_compat |=
-                       EXT2_FEATURE_RO_COMPAT_LARGE_FILE;
+               ext2fs_set_feature_large_file(fs->super);
 
        if (!quiet) {
                if (zero_hugefile && verbose)