Commit a051f71ce97c53cde3ac64de64eb02d658d9308e
Committed by
Al Viro
1 parent
0347b6e95c
Exists in
master
and in
20 other branches
hfsplus: add an ioctl to bless files
Making an hfsplus partition bootable requires the ability to "bless" a file by putting its inode number in the volume header. Doing this from userspace on a mounted filesystem is impractical since the kernel will write back the original values on unmount. Add an ioctl to allow userspace to update the volume header information based on the target file. Signed-off-by: Matthew Garrett <mjg@redhat.com> Signed-off-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Showing 3 changed files with 40 additions and 0 deletions Side-by-side Diff
Documentation/ioctl/ioctl-number.txt
... | ... | @@ -218,6 +218,7 @@ |
218 | 218 | 'h' 00-7F conflict! Charon filesystem |
219 | 219 | <mailto:zapman@interlan.net> |
220 | 220 | 'h' 00-1F linux/hpet.h conflict! |
221 | +'h' 80-8F fs/hfsplus/ioctl.c | |
221 | 222 | 'i' 00-3F linux/i2o-dev.h conflict! |
222 | 223 | 'i' 0B-1F linux/ipmi.h conflict! |
223 | 224 | 'i' 80-8F linux/i8k.h |
fs/hfsplus/hfsplus_fs.h
fs/hfsplus/ioctl.c
... | ... | @@ -20,6 +20,38 @@ |
20 | 20 | #include <asm/uaccess.h> |
21 | 21 | #include "hfsplus_fs.h" |
22 | 22 | |
23 | +/* | |
24 | + * "Blessing" an HFS+ filesystem writes metadata to the superblock informing | |
25 | + * the platform firmware which file to boot from | |
26 | + */ | |
27 | +static int hfsplus_ioctl_bless(struct file *file, int __user *user_flags) | |
28 | +{ | |
29 | + struct dentry *dentry = file->f_path.dentry; | |
30 | + struct inode *inode = dentry->d_inode; | |
31 | + struct hfsplus_sb_info *sbi = HFSPLUS_SB(inode->i_sb); | |
32 | + struct hfsplus_vh *vh = sbi->s_vhdr; | |
33 | + struct hfsplus_vh *bvh = sbi->s_backup_vhdr; | |
34 | + | |
35 | + if (!capable(CAP_SYS_ADMIN)) | |
36 | + return -EPERM; | |
37 | + | |
38 | + mutex_lock(&sbi->vh_mutex); | |
39 | + | |
40 | + /* Directory containing the bootable system */ | |
41 | + vh->finder_info[0] = bvh->finder_info[0] = | |
42 | + cpu_to_be32(parent_ino(dentry)); | |
43 | + | |
44 | + /* Bootloader */ | |
45 | + vh->finder_info[1] = bvh->finder_info[1] = cpu_to_be32(inode->i_ino); | |
46 | + | |
47 | + /* Per spec, the OS X system folder - same as finder_info[0] here */ | |
48 | + vh->finder_info[5] = bvh->finder_info[5] = | |
49 | + cpu_to_be32(parent_ino(dentry)); | |
50 | + | |
51 | + mutex_unlock(&sbi->vh_mutex); | |
52 | + return 0; | |
53 | +} | |
54 | + | |
23 | 55 | static int hfsplus_ioctl_getflags(struct file *file, int __user *user_flags) |
24 | 56 | { |
25 | 57 | struct inode *inode = file->f_path.dentry->d_inode; |
... | ... | @@ -108,6 +140,8 @@ |
108 | 140 | return hfsplus_ioctl_getflags(file, argp); |
109 | 141 | case HFSPLUS_IOC_EXT2_SETFLAGS: |
110 | 142 | return hfsplus_ioctl_setflags(file, argp); |
143 | + case HFSPLUS_IOC_BLESS: | |
144 | + return hfsplus_ioctl_bless(file, argp); | |
111 | 145 | default: |
112 | 146 | return -ENOTTY; |
113 | 147 | } |