Guest User

Patch for mkntfs to create a ext4/ntfs chimera

a guest
Jan 15th, 2020
229
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 17.48 KB | None | 0 0
  1. --- a/ntfsprogs/mkntfs.c
  2. +++ b/ntfsprogs/mkntfs.c
  3. @@ -71,6 +71,7 @@
  4.  #ifdef ENABLE_UUID
  5.  #include <uuid/uuid.h>
  6.  #endif
  7. +#include <sys/ioctl.h>
  8.  
  9.  
  10.  #ifdef HAVE_GETOPT_H
  11. @@ -146,7 +147,7 @@
  12.  #define basename(name) name
  13.  #endif
  14.  
  15. -typedef enum { WRITE_STANDARD, WRITE_BITMAP, WRITE_LOGFILE } WRITE_TYPE;
  16. +typedef enum { WRITE_STANDARD, WRITE_BITMAP, WRITE_LOGFILE, WRITE_NONE } WRITE_TYPE;
  17.  
  18.  #ifdef NO_NTFS_DEVICE_DEFAULT_IO_OPS
  19.  #error "No default device io operations!  Cannot build mkntfs.  \
  20. @@ -204,8 +205,48 @@ static long long      g_mft_zone_end     = 0
  21.  static long long      g_num_bad_blocks   = 0;      /* Number of bad clusters */
  22.  static long long     *g_bad_blocks       = NULL;   /* Array of bad clusters */
  23.  
  24. +static int        backing_fd         = 0;
  25. +static int        backing_file_size      = 2048 * 1024;
  26. +static runlist       *reserved_runlist   = NULL;
  27. +static s64        reserved_size      = 0;
  28. +
  29.  static struct BITMAP_ALLOCATION *g_allocation    = NULL;   /* Head of cluster allocations */
  30.  
  31. +#define FE_COUNT   8000
  32. +#define FE_FLAG_LAST   (1 <<  0)
  33. +#define FE_FLAG_UNKNOWN    (1 <<  1)
  34. +#define FE_FLAG_UNALLOC    (1 <<  2)
  35. +#define FE_FLAG_NOALIGN    (1 <<  8)
  36. +
  37. +#define EXTENT_UNKNOWN (FE_FLAG_UNKNOWN | FE_FLAG_UNALLOC | FE_FLAG_NOALIGN)
  38. +
  39. +struct fe_s {
  40. +   u64 logical;
  41. +   u64 physical;
  42. +   u64 length;
  43. +   u64 reserved64[2];
  44. +   u32 flags;
  45. +   u32 reserved32[3];
  46. +};
  47. +
  48. +struct fm_s {
  49. +   u64 start;
  50. +   u64 length;
  51. +   u32 flags;
  52. +   u32 mapped_extents;
  53. +   u32 extent_count;
  54. +   u32 reserved;
  55. +};
  56. +
  57. +struct fs_s {
  58. +   struct fm_s fm;
  59. +   struct fe_s fe[FE_COUNT];
  60. +};
  61. +
  62. +struct fs_s extent_map = {};
  63. +
  64. +#define FIEMAP _IOWR('f', 11, struct fm_s)
  65. +
  66.  /**
  67.   * struct mkntfs_options
  68.   */
  69. @@ -228,6 +269,87 @@ static struct mkntfs_options {
  70.     char *label;            /* -L, volume label */
  71.  } opts;
  72.  
  73. +static BOOL bitmap_allocate(LCN lcn, s64 length);
  74. +static BOOL bitmap_deallocate(LCN lcn, s64 length);
  75. +static runlist * allocate_scattered_clusters(s64 clusters);
  76. +static void deallocate_scattered_clusters(const runlist *rl);
  77. +
  78. +static runlist *make_reserved_runlist(s64 *size)
  79. +{
  80. +   struct BITMAP_ALLOCATION *p = g_allocation;
  81. +   runlist *rl = NULL;
  82. +   int n = 0;
  83. +   while (p) {
  84. +       n++;
  85. +       p = p->next;
  86. +   }
  87. +   printf("reserved runlist entries: %d\n", n);
  88. +   rl = calloc(sizeof(*rl), n + 1);
  89. +   VCN vcn = 0LL;
  90. +   n = 0;
  91. +   p = g_allocation;
  92. +   while (p) {
  93. +       rl[n].lcn = p->lcn;
  94. +       rl[n].length = p->length;
  95. +       rl[n].vcn = vcn;
  96. +       printf("vcn=%ld lcn=%ld len=%ld\n", vcn, p->lcn, p->length);
  97. +       vcn += p->length;
  98. +       p = p->next;
  99. +       n++;
  100. +   }
  101. +   rl[n].lcn = -1LL;
  102. +   rl[n].length = 0LL;
  103. +   rl[n].vcn = vcn;
  104. +   *size = vcn * g_vol->cluster_size;
  105. +   return rl;
  106. +}
  107. +
  108. +static s64 peek_lcn(s64 size) {
  109. +   s64 mask = g_vol->cluster_size - 1;
  110. +   size = (size + mask) & ~mask;
  111. +   static int initialized = 0;
  112. +
  113. +   if (initialized == 0) {
  114. +       initialized = 1;
  115. +
  116. +       // Initialize unallocated space.
  117. +       printf("Initializing available clusters.\n");
  118. +
  119. +       // Mark everything allocated.
  120. +       bitmap_allocate(0, g_vol->nr_clusters);
  121. +
  122. +       // Punch holes where we have backing store.
  123. +       for (int i = 0; i < extent_map.fm.mapped_extents; i++) {
  124. +           s64 aligned_start = (extent_map.fe[i].physical + mask) & ~mask;
  125. +           s64 aligned_end = (extent_map.fe[i].physical + extent_map.fe[i].length) & ~mask;
  126. +           s64 length = aligned_end - aligned_start;
  127. +
  128. +           bitmap_deallocate(
  129. +               aligned_start / g_vol->cluster_size,
  130. +               length / g_vol->cluster_size);
  131. +
  132. +           if (extent_map.fe[i].flags & FE_FLAG_LAST) {
  133. +               break;
  134. +           }
  135. +       }
  136. +
  137. +       bitmap_deallocate(0, 8192 / g_vol->cluster_size);
  138. +       reserved_runlist = make_reserved_runlist(&reserved_size);
  139. +       bitmap_allocate(0, 8192 / g_vol->cluster_size);
  140. +   }
  141. +
  142. +   runlist *rl = allocate_scattered_clusters(size / g_vol->cluster_size);
  143. +
  144. +   if (rl == NULL) {
  145. +       printf("Failed to alloc disk space: %ld\n", size);
  146. +       return 0;
  147. +   }
  148. +
  149. +   s64 start_lcn = rl[0].lcn;
  150. +   deallocate_scattered_clusters(rl);
  151. +
  152. +   return start_lcn;
  153. +}
  154.  
  155.  /**
  156.   * mkntfs_license
  157. @@ -364,7 +486,7 @@ static BOOL bitmap_allocate(LCN lcn, s64
  158.         /* make sure the requested lcns were not allocated */
  159.         if ((q && ((q->lcn + q->length) > lcn))
  160.            || (p && ((lcn + length) > p->lcn))) {
  161. -           ntfs_log_error("Bitmap allocation error\n");
  162. +           ntfs_log_error("Bitmap allocation error (%ld, %ld)\n", lcn, length);
  163.             done = FALSE;
  164.         }
  165.         if (q && ((q->lcn + q->length) == lcn)) {
  166. @@ -588,12 +710,88 @@ static void mkntfs_init_options(struct m
  167.     opts2->sectors_per_track    = -1;
  168.  }
  169.  
  170. +static int update_backing_extent_map(int fd)
  171. +{
  172. +   extent_map.fm.length = ~0ULL;
  173. +   extent_map.fm.flags  = 0;
  174. +   extent_map.fm.extent_count = FE_COUNT;
  175. +
  176. +   if (-1 == ioctl(fd, FIEMAP, &extent_map)) {
  177. +       int err = errno;
  178. +       perror("ioctl(FIEMAP)");
  179. +       return err;
  180. +   }
  181. +
  182. +   if (1) fprintf(stderr, "ioctl(FIEMAP) returned %lu extents\n", (u64)extent_map.fm.mapped_extents);
  183. +   if (!extent_map.fm.mapped_extents) {
  184. +       return -EINVAL;
  185. +   } else {
  186. +       for (int i = 0; i < extent_map.fm.mapped_extents; i++) {
  187. +
  188. +           if (1) fprintf(stderr, "log=%lu phy=%lu len=%lu flags=0x%x\n",
  189. +                   extent_map.fe[i].logical, extent_map.fe[i].physical,
  190. +                   extent_map.fe[i].length, extent_map.fe[i].flags);
  191. +#if 0
  192. +           u64 phy_blk, ext_len;
  193. +           if (fs.fe[i].flags & EXTENT_UNKNOWN) {
  194. +           } else {
  195. +               phy_blk = fs.fe[i].physical / blksize;
  196. +               ext_len = fs.fe[i].length   / blksize;
  197. +           }
  198. +           //handle_extent(ext, sectors_per_block, start_lba);
  199. +#endif
  200. +
  201. +           if (extent_map.fe[i].flags & FE_FLAG_LAST) {
  202. +               /*
  203. +                * Hit an ext4 bug in 2.6.29.4, where some FIEMAP calls
  204. +                * had the LAST flag set in the final returned extent,
  205. +                * even though there were *plenty* more extents to be had
  206. +                * from continued FIEMAP calls.
  207. +                *
  208. +                * So, we'll ignore it here, and instead rely on getting
  209. +                * a zero count back from fs.fm.mapped_extents at the end.
  210. +                */
  211. +               if (0) fprintf(stderr, "%s: ignoring LAST bit\n", __func__);
  212. +               //done = 1;
  213. +           }
  214. +
  215. +       }
  216. +       //fs.fm.start = (fs.fe[i-1].logical + fs.fe[i-1].length);
  217. +   }
  218. +   return 0;
  219. +}
  220. +
  221. +static int backing_file_init(const char *name)
  222. +{
  223. +   backing_fd = open(name, O_CREAT|O_TRUNC|O_RDWR, 0644);
  224. +   if (backing_fd == -1) {
  225. +       perror("open");
  226. +       return 0;
  227. +   }
  228. +
  229. +   const char buf[1024] = {0x55};
  230. +   for (int i = 0; i < backing_file_size / 1024; i++) {
  231. +       if (write(backing_fd, buf, sizeof(buf)) == -1) {
  232. +           perror("write");
  233. +           return 0;
  234. +       }
  235. +   }
  236. +   fsync(backing_fd);
  237. +   fdatasync(backing_fd);
  238. +
  239. +   if (update_backing_extent_map(backing_fd) != 0) {
  240. +       return 0;
  241. +   }
  242. +
  243. +   return 1;
  244. +}
  245. +
  246.  /**
  247.   * mkntfs_parse_options
  248.   */
  249.  static int mkntfs_parse_options(int argc, char *argv[], struct mkntfs_options *opts2)
  250.  {
  251. -   static const char *sopt = "-c:CfFhH:IlL:np:qQs:S:TUvVz:";
  252. +   static const char *sopt = "-c:CfFhH:IlL:np:qQs:S:TUvVz:B:";
  253.     static const struct option lopt[] = {
  254.         { "cluster-size",   required_argument,  NULL, 'c' },
  255.         { "debug",      no_argument,        NULL, 'Z' },
  256. @@ -616,6 +814,7 @@ static int mkntfs_parse_options(int argc
  257.         { "verbose",        no_argument,        NULL, 'v' },
  258.         { "version",        no_argument,        NULL, 'V' },
  259.         { "zero-time",      no_argument,        NULL, 'T' },
  260. +       { "backing-file",   required_argument,  NULL, 'B' },
  261.         { NULL, 0, NULL, 0 }
  262.     };
  263.  
  264. @@ -728,13 +927,22 @@ static int mkntfs_parse_options(int argc
  265.                         &opts2->mft_zone_multiplier))
  266.                 err++;
  267.             break;
  268. +       case 'B':
  269. +           // Skip initializing all blocks with zeroes.
  270. +           opts2->quick_format = TRUE;
  271. +           if (!backing_file_init(optarg)) {
  272. +               ntfs_log_error("Could not open backing file: %s\n", optarg);
  273. +               err++;
  274. +           }
  275. +           break;
  276.         default:
  277.             if (ntfs_log_parse_option (argv[optind-1]))
  278.                 break;
  279.             if (((optopt == 'c') || (optopt == 'H') ||
  280.                  (optopt == 'L') || (optopt == 'p') ||
  281.                  (optopt == 's') || (optopt == 'S') ||
  282. -                (optopt == 'N') || (optopt == 'z')) &&
  283. +                (optopt == 'N') || (optopt == 'z') ||
  284. +                (optopt == 'B')) &&
  285.                  (!optarg)) {
  286.                 ntfs_log_error("Option '%s' requires an "
  287.                         "argument.\n", argv[optind-1]);
  288. @@ -904,6 +1112,7 @@ static s64 ntfs_rlwrite(struct ntfs_devi
  289.         return val_len;
  290.     total = 0LL;
  291.     delta = 0LL;
  292. +   if (!val) printf("ntfs_rlwrite: val is NULL\n");
  293.     for (i = 0; rl[i].length; i++) {
  294.         length = rl[i].length * g_vol->cluster_size;
  295.         /* Don't write sparse runs. */
  296. @@ -939,6 +1148,9 @@ static s64 ntfs_rlwrite(struct ntfs_devi
  297.                 bytes_written = mkntfs_logfile_write(dev,
  298.                     total, length);
  299.                 break;
  300. +           case WRITE_NONE :
  301. +               bytes_written = length;
  302. +               break;
  303.             default :
  304.                 bytes_written = dev->d_ops->write(dev,
  305.                     val + total, length);
  306. @@ -966,6 +1178,7 @@ static s64 ntfs_rlwrite(struct ntfs_devi
  307.             return total;
  308.         }
  309.     }
  310. +   if (!val) printf("total=%ld delta=%ld\n", total, delta);
  311.     if (delta) {
  312.         int eo;
  313.         char *b = ntfs_calloc(delta);
  314. @@ -1511,6 +1724,7 @@ static int insert_positioned_attr_in_mft
  315.     for (i = 0, highest_vcn = 0LL; rl[i].length; i++)
  316.         highest_vcn += rl[i].length;
  317.     /* Does the value fit inside the allocated size? */
  318. +   ntfs_log_error("val_len: %ld vcn_len: %ld\n", val_len, highest_vcn * g_vol->cluster_size);
  319.     if (highest_vcn * g_vol->cluster_size < val_len) {
  320.         ntfs_log_error("BUG: Allocated size is smaller than data size!\n");
  321.         err = -EINVAL;
  322. @@ -1562,6 +1776,7 @@ static int insert_positioned_attr_in_mft
  323.     a->data_size = cpu_to_sle64(val_len);
  324.     if (name_len)
  325.         memcpy((char*)a + hdr_size, uname, name_len << 1);
  326. +   ntfs_log_error("write data\n");
  327.     if (flags & ATTR_COMPRESSION_MASK) {
  328.         if (flags & ATTR_COMPRESSION_MASK & ~ATTR_IS_COMPRESSED) {
  329.             ntfs_log_error("Unknown compression format. Reverting "
  330. @@ -1583,10 +1798,18 @@ static int insert_positioned_attr_in_mft
  331.                  == const_cpu_to_le32(FILE_LogFile)))
  332.             bw = ntfs_rlwrite(g_vol->dev, rl, val, val_len,
  333.                     &inited_size, WRITE_LOGFILE);
  334. -       else
  335. -           bw = ntfs_rlwrite(g_vol->dev, rl, val, val_len,
  336. -                   &inited_size, WRITE_STANDARD);
  337. +       else {
  338. +           if (rl == reserved_runlist) {
  339. +               printf("WRITE_NONE\n");
  340. +               bw = ntfs_rlwrite(g_vol->dev, rl, val, val_len,
  341. +                       &inited_size, WRITE_NONE);
  342. +           } else {
  343. +               bw = ntfs_rlwrite(g_vol->dev, rl, val, val_len,
  344. +                       &inited_size, WRITE_STANDARD);
  345. +           }
  346. +       }
  347.         if (bw != val_len) {
  348. +           ntfs_log_error("bw=%ld val_len=%ld\n", bw, val_len);
  349.             ntfs_log_error("Error writing non-resident attribute "
  350.                     "value.\n");
  351.             return -errno;
  352. @@ -1601,6 +1824,7 @@ static int insert_positioned_attr_in_mft
  353.         /* remove attribute */
  354.         if (err >= 0)
  355.             err = -EIO;
  356. +       ntfs_log_error("bw=%ld val_len=%ld\n", bw, val_len);
  357.         ntfs_log_error("insert_positioned_attr_in_mft_record failed "
  358.                 "with error %i.\n", err < 0 ? err : (int)bw);
  359.     }
  360. @@ -3449,6 +3673,64 @@ static void mkntfs_cleanup(void)
  361.     }
  362.  }
  363.  
  364. +#define DEV_FD(dev)        (*(int *)dev->d_private)
  365. +
  366. +static s64 backing_pwrite(struct ntfs_device *dev, const void *buf, s64 count, s64 offset)
  367. +{
  368. +   if (offset == 0) {
  369. +       // Write the bootsector directly
  370. +       ssize_t written = pwrite(DEV_FD(dev), buf, 512, 0);
  371. +       (void)written;
  372. +       return count;
  373. +   }
  374. +   // Everything else gets translated into writes to the backing file.
  375. +   for (int i = 0; i < extent_map.fm.mapped_extents; i++) {
  376. +       s64 phy_start = extent_map.fe[i].physical;
  377. +       s64 phy_end = phy_start + extent_map.fe[i].length;
  378. +       s64 delta = offset - phy_start;
  379. +       s64 log_offset = extent_map.fe[i].logical + delta;
  380. +       if (offset >= phy_start && offset < phy_end) {
  381. +           printf("%ld -(%ld)-> %ld\n", offset, delta, log_offset);
  382. +           if (offset + count < phy_end) {
  383. +               return pwrite(backing_fd, buf, count, log_offset);
  384. +           } else {
  385. +               return pwrite(backing_fd, buf, phy_end - offset, log_offset);
  386. +           }
  387. +       }
  388. +       if (extent_map.fe[i].flags & FE_FLAG_LAST)
  389. +           break;
  390. +   }
  391. +   printf("bad write: %ld %ld\n", offset, count);
  392. +   errno = EIO;
  393. +   return -1;
  394. +}
  395. +
  396. +static s64 restricted_pwrite(struct ntfs_device *dev, const void *buf,
  397. +       s64 count, s64 offset)
  398. +{
  399. +   if (NDevReadOnly(dev)) {
  400. +       errno = EROFS;
  401. +       return -1;
  402. +   }
  403. +
  404. +   NDevSetDirty(dev);
  405. +   return backing_pwrite(dev, buf, count, offset);
  406. +}
  407. +
  408. +static s64 restricted_write(struct ntfs_device *dev, const void *buf,
  409. +       s64 count)
  410. +{
  411. +   if (NDevReadOnly(dev)) {
  412. +       errno = EROFS;
  413. +       return -1;
  414. +   }
  415. +   int fd = DEV_FD(dev);
  416. +   off_t offset = lseek(fd, 0, SEEK_CUR);
  417. +
  418. +   s64 nwritten = restricted_pwrite(dev, buf, count, offset);
  419. +   lseek(fd, nwritten, SEEK_CUR);
  420. +   return nwritten;
  421. +}
  422.  
  423.  /**
  424.   * mkntfs_open_partition -
  425. @@ -3459,12 +3741,17 @@ static BOOL mkntfs_open_partition(ntfs_v
  426.     int i;
  427.     struct stat sbuf;
  428.     unsigned long mnt_flags;
  429. +   struct ntfs_device_operations io_ops;
  430. +   memcpy(&io_ops, &ntfs_device_default_io_ops, sizeof(io_ops));
  431. +
  432. +   io_ops.write = restricted_write;
  433. +   io_ops.pwrite = restricted_pwrite;
  434.  
  435.     /*
  436.      * Allocate and initialize an ntfs device structure and attach it to
  437.      * the volume.
  438.      */
  439. -   vol->dev = ntfs_device_alloc(opts.dev_name, 0, &ntfs_device_default_io_ops, NULL);
  440. +   vol->dev = ntfs_device_alloc(opts.dev_name, 0, &io_ops, NULL);
  441.     if (!vol->dev) {
  442.         ntfs_log_perror("Could not create device");
  443.         goto done;
  444. @@ -3912,9 +4199,9 @@ static BOOL mkntfs_initialize_bitmaps(vo
  445.         return FALSE;
  446.  
  447.     g_rl_mft_bmp[0].vcn = 0LL;
  448. -   /* Mft bitmap is right after $Boot's data. */
  449. -   i = (8192 + g_vol->cluster_size - 1) / g_vol->cluster_size;
  450. +   i = peek_lcn(g_vol->cluster_size);
  451.     g_rl_mft_bmp[0].lcn = i;
  452. +   printf("MFT bitmap placed at LCN %ld\n", i);
  453.     /*
  454.      * Size is always one cluster, even though valid data size and
  455.      * initialized data size are only 8 bytes.
  456. @@ -3937,14 +4224,8 @@ static BOOL mkntfs_initialize_rl_mft(voi
  457.  
  458.     /* If user didn't specify the mft lcn, determine it now. */
  459.     if (!g_mft_lcn) {
  460. -       /*
  461. -        * We start at the higher value out of 16kiB and just after the
  462. -        * mft bitmap.
  463. -        */
  464. -       g_mft_lcn = g_rl_mft_bmp[0].lcn + g_rl_mft_bmp[0].length;
  465. -       if (g_mft_lcn * g_vol->cluster_size < 16 * 1024)
  466. -           g_mft_lcn = (16 * 1024 + g_vol->cluster_size - 1) /
  467. -                   g_vol->cluster_size;
  468. +       g_mft_lcn = peek_lcn(g_mft_size);
  469. +       printf("MFT placed at LCN %lld\n", g_mft_lcn);
  470.     }
  471.     ntfs_log_debug("$MFT logical cluster number = 0x%llx\n", g_mft_lcn);
  472.     /* Determine MFT zone size. */
  473. @@ -3986,9 +4267,8 @@ static BOOL mkntfs_initialize_rl_mft(voi
  474.     g_rl_mft[1].length = 0LL;
  475.     /* Allocate clusters for mft. */
  476.     bitmap_allocate(g_mft_lcn,j);
  477. -   /* Determine mftmirr_lcn (middle of volume). */
  478. -   g_mftmirr_lcn = (opts.num_sectors * opts.sector_size >> 1)
  479. -           / g_vol->cluster_size;
  480. +   g_mftmirr_lcn = peek_lcn(g_mft_size);
  481. +   printf("MFT mirror at LCN %lld\n", g_mftmirr_lcn);
  482.     ntfs_log_debug("$MFTMirr logical cluster number = 0x%llx\n",
  483.             g_mftmirr_lcn);
  484.     /* Create runlist for mft mirror. */
  485. @@ -4015,6 +4295,7 @@ static BOOL mkntfs_initialize_rl_mft(voi
  486.     g_logfile_lcn = g_mftmirr_lcn + j;
  487.     ntfs_log_debug("$LogFile logical cluster number = 0x%llx\n",
  488.             g_logfile_lcn);
  489. +   printf("LogFile at LCN %lld\n", g_logfile_lcn);
  490.     return (done);
  491.  }
  492.  
  493. @@ -4032,7 +4313,8 @@ static BOOL mkntfs_initialize_rl_logfile
  494.         return FALSE;
  495.  
  496.  
  497. -   volume_size = g_vol->nr_clusters << g_vol->cluster_size_bits;
  498. +   //volume_size = g_vol->nr_clusters << g_vol->cluster_size_bits;
  499. +   volume_size = backing_file_size;
  500.  
  501.     g_rl_logfile[0].vcn = 0LL;
  502.     g_rl_logfile[0].lcn = g_logfile_lcn;
  503. @@ -4078,6 +4360,7 @@ static BOOL mkntfs_initialize_rl_logfile
  504.             ~(g_vol->cluster_size - 1);
  505.     ntfs_log_debug("$LogFile (journal) size = %ikiB\n",
  506.             g_logfile_size / 1024);
  507. +   printf("LogFile size %d\n", g_logfile_size);
  508.     /*
  509.      * FIXME: The 256kiB limit is arbitrary. Should find out what the real
  510.      * minimum requirement for Windows is so it doesn't blue screen.
  511. @@ -4118,8 +4401,10 @@ static BOOL mkntfs_initialize_rl_boot(vo
  512.     g_rl_boot[0].length = j;
  513.     g_rl_boot[1].lcn = -1LL;
  514.     g_rl_boot[1].length = 0LL;
  515. +
  516.     /* Allocate clusters for $Boot. */
  517. -   return (bitmap_allocate(0,j));
  518. +   return 1; // Already allocated.
  519. +   //return (bitmap_allocate(0,j));
  520.  }
  521.  
  522.  /**
  523. @@ -4445,7 +4730,7 @@ static BOOL mkntfs_create_root_structure
  524.         le32 file_attrs;
  525.  
  526.         m = (MFT_RECORD*)(g_buf + i * g_vol->mft_record_size);
  527. -       if (i < 16 || i > 23) {
  528. +       if (i < 17 || i > 23) {
  529.             m->mft_record_number = cpu_to_le32(i);
  530.             m->flags |= MFT_RECORD_IN_USE;
  531.             ntfs_bit_set(g_mft_bitmap, 0LL + i, 1);
  532. @@ -4870,6 +5155,7 @@ static BOOL mkntfs_create_root_structure
  533.             strerror(-err));
  534.         return FALSE;
  535.     }
  536. +
  537.     /* NTFS reserved system files (mft records 0xc-0xf) */
  538.     for (i = 0xc; i < 0x10; i++) {
  539.         ntfs_log_verbose("Creating system file (mft record 0x%x)\n", i);
  540. @@ -4886,6 +5172,7 @@ static BOOL mkntfs_create_root_structure
  541.             return FALSE;
  542.         }
  543.     }
  544. +
  545.     /* create systemfiles for ntfs volumes (3.1) */
  546.     /* starting with file 24 (ignoring file 16-23) */
  547.     extend_flags = FILE_ATTR_HIDDEN | FILE_ATTR_SYSTEM |
  548. @@ -4956,6 +5243,29 @@ static BOOL mkntfs_create_root_structure
  549.             strerror(-err));
  550.         return FALSE;
  551.     }
  552. +
  553. +#if 1
  554. +   /* Add entry for reserved space */
  555. +   ntfs_log_error("Creating Reserved %ld\n", reserved_size);
  556. +   int entry = 16;
  557. +   m = (MFT_RECORD*)(g_buf + entry * g_vol->mft_record_size);
  558. +   err = add_attr_data_positioned(m, "$Rsv", 0, CASE_SENSITIVE,
  559. +           const_cpu_to_le16(0), reserved_runlist,
  560. +           (const u8*)NULL, reserved_size);
  561. +   if (!err)
  562. +       err = create_hardlink(g_index_block, root_ref, m,
  563. +               MK_LE_MREF(entry, entry),
  564. +               reserved_size, reserved_size,
  565. +               FILE_ATTR_HIDDEN | FILE_ATTR_SYSTEM, 0, 0,
  566. +               "Reserved", FILE_NAME_WIN32_AND_DOS);
  567. +   if (err < 0) {
  568. +       free(bs);
  569. +       ntfs_log_error("Couldn't create $Reserved: %s\n", strerror(-err));
  570. +       return FALSE;
  571. +   }
  572. +#endif
  573. +
  574. +
  575.     return TRUE;
  576.  }
Advertisement
Add Comment
Please, Sign In to add comment