Commit 7dea9665fee828fb56db3bae5b9685d9fa006d33

Authored by Matthew Garrett
Committed by Linus Torvalds
1 parent a6dc8c0421

hfsplus: fix bless ioctl when used with hardlinks

HFS+ doesn't really implement hard links - instead, hardlinks are indicated
by a magic file type which refers to an indirect node in a hidden
directory. The spec indicates that stat() should return the inode number
of the indirect node, but it turns out that this doesn't satisfy the
firmware when it's looking for a bootloader - it wants the catalog ID of
the hardlink file instead. Fix up this case.

Signed-off-by: Matthew Garrett <mjg@redhat.com>
Signed-off-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

Showing 1 changed file with 7 additions and 2 deletions Side-by-side Diff

... ... @@ -31,6 +31,7 @@
31 31 struct hfsplus_sb_info *sbi = HFSPLUS_SB(inode->i_sb);
32 32 struct hfsplus_vh *vh = sbi->s_vhdr;
33 33 struct hfsplus_vh *bvh = sbi->s_backup_vhdr;
  34 + u32 cnid = (unsigned long)dentry->d_fsdata;
34 35  
35 36 if (!capable(CAP_SYS_ADMIN))
36 37 return -EPERM;
... ... @@ -41,8 +42,12 @@
41 42 vh->finder_info[0] = bvh->finder_info[0] =
42 43 cpu_to_be32(parent_ino(dentry));
43 44  
44   - /* Bootloader */
45   - vh->finder_info[1] = bvh->finder_info[1] = cpu_to_be32(inode->i_ino);
  45 + /*
  46 + * Bootloader. Just using the inode here breaks in the case of
  47 + * hard links - the firmware wants the ID of the hard link file,
  48 + * but the inode points at the indirect inode
  49 + */
  50 + vh->finder_info[1] = bvh->finder_info[1] = cpu_to_be32(cnid);
46 51  
47 52 /* Per spec, the OS X system folder - same as finder_info[0] here */
48 53 vh->finder_info[5] = bvh->finder_info[5] =