~darkmuggle-deactivatedaccount/ubuntu/quantal/grub2/fix-872244

« back to all changes in this revision

Viewing changes to fs/ntfs.c

  • Committer: Bazaar Package Importer
  • Author(s): Colin Watson
  • Date: 2010-01-11 11:12:55 UTC
  • mfrom: (17.3.7 squeeze)
  • Revision ID: james.westby@ubuntu.com-20100111111255-lr8ebkqw5x41gq6j
Tags: 1.98~20100101-1ubuntu1
* Resynchronise with Debian. Remaining changes:
  - Adjust for default Ubuntu boot options ("quiet splash").
  - Default to hiding the menu; holding down Shift at boot will show it.
  - Set a monochromatic theme for Ubuntu.
  - Apply Ubuntu GRUB Legacy changes to legacy update-grub script: title,
    recovery mode, quiet option, tweak how memtest86+ is displayed, and
    use UUIDs where appropriate.
  - Conflict with grub (<< 0.97-54) as well as grub-legacy.
  - Fix backslash-escaping in merge_debconf_into_conf.
  - Remove "GNU/Linux" from default distributor string.
  - Add crashkernel= options if kdump and makedumpfile are available.
  - If other operating systems are installed, then automatically unhide
    the menu. Otherwise, if GRUB_HIDDEN_TIMEOUT is 0, then use keystatus
    if available to check whether Shift is pressed. If it is, show the
    menu, otherwise boot immediately. If keystatus is not available, then
    fall back to a short delay interruptible with Escape.
  - Allow Shift to interrupt 'sleep --interruptible'.
  - Don't display introductory message about line editing unless we're
    actually offering a shell prompt. Don't clear the screen just before
    booting if we never drew the menu in the first place.
  - Remove some verbose messages printed before reading the configuration
    file.
  - If the environment variable "quiet" is set to something other than 0,
    suppress progress messages as the kernel and initrd load. Set this for
    non-recovery kernel menu entries.
  - Add GRUB_DEFAULT=saved, as well as grub-set-default and grub-reboot
    utilities. Provides functionality essentially equivalent to GRUB
    Legacy's savedefault.
  - Keep the loopback file open so that subsequent changes to the "root"
    environment variable don't affect it.
  - Change prepare_grub_to_access_device to handle filesystems
    loop-mounted on file images.
  - Ignore devices loop-mounted from files in 10_linux.
  - Show the boot menu if the previous boot failed, that is if it failed
    to get to the end of one of the normal runlevels.
  - Handle RAID devices containing virtio components.
* Update savedefault patch from current Bazaar branch, fixing grub-reboot
  to have distinct behaviour from grub-set-default (LP: #497326).
* Fix grub-mkisofs compilation error with FORTIFY_SOURCE.
* Convert recordfail boilerplate in each menu entry to use a function.

Show diffs side-by-side

added added

removed removed

Lines of Context:
24
24
#include <grub/dl.h>
25
25
#include <grub/fshelp.h>
26
26
#include <grub/ntfs.h>
 
27
#include <grub/charset.h>
27
28
 
28
29
static grub_dl_t my_mod;
29
30
 
41
42
 
42
43
  ss = u16at (buf, 6) - 1;
43
44
  if (ss * (int) data->blocksize != len * GRUB_DISK_SECTOR_SIZE)
44
 
    return grub_error (GRUB_ERR_BAD_FS, "Size not match",
 
45
    return grub_error (GRUB_ERR_BAD_FS, "size not match",
45
46
                       ss * (int) data->blocksize,
46
47
                       len * GRUB_DISK_SECTOR_SIZE);
47
48
  pu = buf + u16at (buf, 4);
52
53
      buf += data->blocksize;
53
54
      pu += 2;
54
55
      if (u16at (buf, 0) != us)
55
 
        return grub_error (GRUB_ERR_BAD_FS, "Fixup signature not match");
 
56
        return grub_error (GRUB_ERR_BAD_FS, "fixup signature not match");
56
57
      v16at (buf, 0) = v16at (pu, 0);
57
58
      ss--;
58
59
    }
63
64
static grub_err_t read_mft (struct grub_ntfs_data *data, char *buf,
64
65
                            grub_uint32_t mftno);
65
66
static grub_err_t read_attr (struct grub_ntfs_attr *at, char *dest,
66
 
                             grub_uint32_t ofs, grub_uint32_t len,
 
67
                             grub_disk_addr_t ofs, grub_size_t len,
67
68
                             int cached,
68
69
                             void
69
70
                             NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t
72
73
                                                            unsigned length));
73
74
 
74
75
static grub_err_t read_data (struct grub_ntfs_attr *at, char *pa, char *dest,
75
 
                             grub_uint32_t ofs, grub_uint32_t len,
 
76
                             grub_disk_addr_t ofs, grub_size_t len,
76
77
                             int cached,
77
78
                             void
78
79
                             NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t
146
147
                  new_pos += u16at (new_pos, 4);
147
148
                }
148
149
              grub_error (GRUB_ERR_BAD_FS,
149
 
                          "Can\'t find 0x%X in attribute list",
 
150
                          "can\'t find 0x%X in attribute list",
150
151
                          (unsigned char) *at->attr_cur);
151
152
              return NULL;
152
153
            }
185
186
          if (read_data (at, pa, at->edat_buf, 0, n, 0, 0))
186
187
            {
187
188
              grub_error (GRUB_ERR_BAD_FS,
188
 
                          "Fail to read non-resident attribute list");
 
189
                          "fail to read non-resident attribute list");
189
190
              return NULL;
190
191
            }
191
192
          at->attr_nxt = at->edat_buf;
260
261
}
261
262
 
262
263
static char *
263
 
read_run_data (char *run, int nn, grub_uint32_t * val, int sig)
 
264
read_run_data (char *run, int nn, grub_disk_addr_t * val, int sig)
264
265
{
265
 
  grub_uint32_t r, v;
 
266
  grub_disk_addr_t r, v;
266
267
 
267
268
  r = 0;
268
269
  v = 1;
284
285
grub_ntfs_read_run_list (struct grub_ntfs_rlst * ctx)
285
286
{
286
287
  int c1, c2;
287
 
  grub_uint32_t val;
 
288
  grub_disk_addr_t val;
288
289
  char *run;
289
290
 
290
291
  run = ctx->cur_run;
314
315
              goto retry;
315
316
            }
316
317
        }
317
 
      return grub_error (GRUB_ERR_BAD_FS, "Run list overflown");
 
318
      return grub_error (GRUB_ERR_BAD_FS, "run list overflown");
318
319
    }
319
320
  run = read_run_data (run + 1, c1, &val, 0);   /* length of current VCN */
320
321
  ctx->curr_vcn = ctx->next_vcn;
335
336
  struct grub_ntfs_rlst *ctx;
336
337
 
337
338
  ctx = (struct grub_ntfs_rlst *) node;
338
 
  if ((grub_uint32_t) block >= ctx->next_vcn)
 
339
  if (block >= ctx->next_vcn)
339
340
    {
340
341
      if (grub_ntfs_read_run_list (ctx))
341
342
        return -1;
342
343
      return ctx->curr_lcn;
343
344
    }
344
345
  else
345
 
    return (ctx->flags & RF_BLNK) ? 0 : ((grub_uint32_t) block -
 
346
    return (ctx->flags & RF_BLNK) ? 0 : (block -
346
347
                                         ctx->curr_vcn + ctx->curr_lcn);
347
348
}
348
349
 
349
350
static grub_err_t
350
 
read_data (struct grub_ntfs_attr *at, char *pa, char *dest, grub_uint32_t ofs,
351
 
           grub_uint32_t len, int cached,
 
351
read_data (struct grub_ntfs_attr *at, char *pa, char *dest,
 
352
           grub_disk_addr_t ofs, grub_size_t len, int cached,
352
353
           void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t sector,
353
354
                                               unsigned offset,
354
355
                                               unsigned length))
355
356
{
356
 
  grub_uint32_t vcn;
 
357
  grub_disk_addr_t vcn;
357
358
  struct grub_ntfs_rlst cc, *ctx;
358
359
 
359
360
  if (len == 0)
368
369
  if (pa[8] == 0)
369
370
    {
370
371
      if (ofs + len > u32at (pa, 0x10))
371
 
        return grub_error (GRUB_ERR_BAD_FS, "Read out of range");
 
372
        return grub_error (GRUB_ERR_BAD_FS, "read out of range");
372
373
      grub_memcpy (dest, pa + u32at (pa, 0x14) + ofs, len);
373
374
      return 0;
374
375
    }
382
383
  if (ctx->flags & RF_COMP)
383
384
    {
384
385
      if (!cached)
385
 
        return grub_error (GRUB_ERR_BAD_FS, "Attribute can\'t be compressed");
 
386
        return grub_error (GRUB_ERR_BAD_FS, "attribute can\'t be compressed");
386
387
 
387
388
      if (at->sbuf)
388
389
        {
389
390
          if ((ofs & (~(COM_LEN - 1))) == at->save_pos)
390
391
            {
391
 
              grub_uint32_t n;
 
392
              grub_disk_addr_t n;
392
393
 
393
394
              n = COM_LEN - (ofs - at->save_pos);
394
395
              if (n > len)
411
412
          at->save_pos = 1;
412
413
        }
413
414
 
414
 
      vcn = ctx->target_vcn = (ofs / COM_LEN) * (COM_SEC / ctx->comp.spc);
 
415
      vcn = ctx->target_vcn = (ofs >> COM_LOG_LEN) * (COM_SEC / ctx->comp.spc);
415
416
      ctx->target_vcn &= ~0xF;
416
417
    }
417
418
  else
418
 
    vcn = ctx->target_vcn = (ofs >> BLK_SHR) / ctx->comp.spc;
 
419
    vcn = ctx->target_vcn = grub_divmod64 (ofs >> BLK_SHR, ctx->comp.spc, 0);
419
420
 
420
421
  ctx->next_vcn = u32at (pa, 0x10);
421
422
  ctx->curr_lcn = 0;
427
428
 
428
429
  if (at->flags & AF_GPOS)
429
430
    {
430
 
      grub_uint32_t st0, st1;
 
431
      grub_disk_addr_t st0, st1;
 
432
      grub_uint32_t m;
 
433
 
 
434
      grub_divmod64 (ofs >> BLK_SHR, ctx->comp.spc, &m);
431
435
 
432
436
      st0 =
433
 
        (ctx->target_vcn - ctx->curr_vcn + ctx->curr_lcn) * ctx->comp.spc +
434
 
        ((ofs >> BLK_SHR) % ctx->comp.spc);
 
437
        (ctx->target_vcn - ctx->curr_vcn + ctx->curr_lcn) * ctx->comp.spc + m;
435
438
      st1 = st0 + 1;
436
439
      if (st1 ==
437
440
          (ctx->next_vcn - ctx->curr_vcn + ctx->curr_lcn) * ctx->comp.spc)
462
465
}
463
466
 
464
467
static grub_err_t
465
 
read_attr (struct grub_ntfs_attr *at, char *dest, grub_uint32_t ofs,
466
 
           grub_uint32_t len, int cached,
 
468
read_attr (struct grub_ntfs_attr *at, char *dest, grub_disk_addr_t ofs,
 
469
           grub_size_t len, int cached,
467
470
           void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t sector,
468
471
                                               unsigned offset,
469
472
                                               unsigned length))
479
482
  if (at->flags & AF_ALST)
480
483
    {
481
484
      char *pa;
482
 
      grub_uint32_t vcn;
 
485
      grub_disk_addr_t vcn;
483
486
 
484
 
      vcn = ofs / (at->mft->data->spc << BLK_SHR);
 
487
      vcn = grub_divmod64 (ofs, at->mft->data->spc << BLK_SHR, 0);
485
488
      pa = at->attr_nxt + u16at (at->attr_nxt, 4);
486
489
      while (pa < at->attr_end)
487
490
        {
499
502
  else
500
503
    ret =
501
504
      (grub_errno) ? grub_errno : grub_error (GRUB_ERR_BAD_FS,
502
 
                                              "Attribute not found");
 
505
                                              "attribute not found");
503
506
  at->attr_cur = save_cur;
504
507
  return ret;
505
508
}
508
511
read_mft (struct grub_ntfs_data *data, char *buf, grub_uint32_t mftno)
509
512
{
510
513
  if (read_attr
511
 
      (&data->mmft.attr, buf, mftno * (data->mft_size << BLK_SHR),
 
514
      (&data->mmft.attr, buf, mftno * ((grub_disk_addr_t) data->mft_size << BLK_SHR),
512
515
       data->mft_size << BLK_SHR, 0, 0))
513
 
    return grub_error (GRUB_ERR_BAD_FS, "Read MFT 0x%X fails", mftno);
 
516
    return grub_error (GRUB_ERR_BAD_FS, "read MFT 0x%X fails", mftno);
514
517
  return fixup (data, buf, data->mft_size, "FILE");
515
518
}
516
519
 
538
541
 
539
542
      pa = locate_attr (&mft->attr, mft, AT_DATA);
540
543
      if (pa == NULL)
541
 
        return grub_error (GRUB_ERR_BAD_FS, "No $DATA in MFT 0x%X", mftno);
 
544
        return grub_error (GRUB_ERR_BAD_FS, "no $DATA in MFT 0x%X", mftno);
542
545
 
543
546
      if (!pa[8])
544
547
        mft->size = u32at (pa, 0x10);
640
643
  unsigned char *bitmap;
641
644
  struct grub_ntfs_attr attr, *at;
642
645
  char *cur_pos, *indx, *bmp;
643
 
  int bitmap_len, ret = 0;
 
646
  int ret = 0;
 
647
  grub_size_t bitmap_len;
644
648
  struct grub_ntfs_file *mft;
645
649
 
646
650
  mft = (struct grub_ntfs_file *) dir;
660
664
    {
661
665
      if ((cur_pos = find_attr (at, AT_INDEX_ROOT)) == NULL)
662
666
        {
663
 
          grub_error (GRUB_ERR_BAD_FS, "No $INDEX_ROOT");
 
667
          grub_error (GRUB_ERR_BAD_FS, "no $INDEX_ROOT");
664
668
          goto done;
665
669
        }
666
670
 
713
717
              if (read_data (at, cur_pos, bmp, 0, bitmap_len, 0, 0))
714
718
                {
715
719
                  grub_error (GRUB_ERR_BAD_FS,
716
 
                              "Fails to read non-resident $BITMAP");
 
720
                              "fails to read non-resident $BITMAP");
717
721
                  goto done;
718
722
                }
719
723
              bitmap_len = u32at (cur_pos, 0x30);
744
748
 
745
749
  if (bitmap)
746
750
    {
747
 
      grub_uint32_t v, i;
 
751
      grub_disk_addr_t v, i;
748
752
 
749
753
      indx = grub_malloc (mft->data->idx_size << BLK_SHR);
750
754
      if (indx == NULL)
751
755
        goto done;
752
756
 
753
757
      v = 1;
754
 
      for (i = 0; i < (grub_uint32_t) bitmap_len * 8; i++)
 
758
      for (i = 0; i < (grub_disk_addr_t)bitmap_len * 8; i++)
755
759
        {
756
760
          if (*bitmap & v)
757
761
            {