aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorMatthew Garrett <mjg@redhat.com>2012-02-06 15:14:40 -0500
committerAl Viro <viro@zeniv.linux.org.uk>2012-03-20 21:29:53 -0400
commita051f71ce97c53cde3ac64de64eb02d658d9308e (patch)
treeef36c0a2e8c9e9dfb97ee12ba35fccca32858909 /fs
parent0347b6e95ceeb648631f89a0ced001e90e4daaa9 (diff)
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>
Diffstat (limited to 'fs')
-rw-r--r--fs/hfsplus/hfsplus_fs.h5
-rw-r--r--fs/hfsplus/ioctl.c34
2 files changed, 39 insertions, 0 deletions
diff --git a/fs/hfsplus/hfsplus_fs.h b/fs/hfsplus/hfsplus_fs.h
index 21a5b7fc6db4..4e75ac646fea 100644
--- a/fs/hfsplus/hfsplus_fs.h
+++ b/fs/hfsplus/hfsplus_fs.h
@@ -317,6 +317,11 @@ static inline unsigned short hfsplus_min_io_size(struct super_block *sb)
317 317
318 318
319/* 319/*
320 * hfs+-specific ioctl for making the filesystem bootable
321 */
322#define HFSPLUS_IOC_BLESS _IO('h', 0x80)
323
324/*
320 * Functions in any *.c used in other files 325 * Functions in any *.c used in other files
321 */ 326 */
322 327
diff --git a/fs/hfsplus/ioctl.c b/fs/hfsplus/ioctl.c
index f66c7655b3f7..c640ba57074b 100644
--- a/fs/hfsplus/ioctl.c
+++ b/fs/hfsplus/ioctl.c
@@ -20,6 +20,38 @@
20#include <asm/uaccess.h> 20#include <asm/uaccess.h>
21#include "hfsplus_fs.h" 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 */
27static 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
23static int hfsplus_ioctl_getflags(struct file *file, int __user *user_flags) 55static int hfsplus_ioctl_getflags(struct file *file, int __user *user_flags)
24{ 56{
25 struct inode *inode = file->f_path.dentry->d_inode; 57 struct inode *inode = file->f_path.dentry->d_inode;
@@ -108,6 +140,8 @@ long hfsplus_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
108 return hfsplus_ioctl_getflags(file, argp); 140 return hfsplus_ioctl_getflags(file, argp);
109 case HFSPLUS_IOC_EXT2_SETFLAGS: 141 case HFSPLUS_IOC_EXT2_SETFLAGS:
110 return hfsplus_ioctl_setflags(file, argp); 142 return hfsplus_ioctl_setflags(file, argp);
143 case HFSPLUS_IOC_BLESS:
144 return hfsplus_ioctl_bless(file, argp);
111 default: 145 default:
112 return -ENOTTY; 146 return -ENOTTY;
113 } 147 }