summaryrefslogtreecommitdiffstats
path: root/hfsplus-Add-an-ioctl-to-bless-files.patch
diff options
context:
space:
mode:
authorJosh Boyer <jwboyer@redhat.com>2012-02-07 09:49:17 -0500
committerJosh Boyer <jwboyer@redhat.com>2012-02-07 09:49:17 -0500
commit4efc0c70ab6ea56a586fe249058200aa46b96473 (patch)
treec138a3d8a2727171c3be0e49cd1a238c4d02fbe9 /hfsplus-Add-an-ioctl-to-bless-files.patch
parent551d759a1e821ce49c84afbd9b980a48a75a9129 (diff)
downloadkernel-4efc0c70ab6ea56a586fe249058200aa46b96473.tar.gz
kernel-4efc0c70ab6ea56a586fe249058200aa46b96473.tar.xz
kernel-4efc0c70ab6ea56a586fe249058200aa46b96473.zip
Linux 3.3-rc2-git5 (upstream 8597559a78e1cde158b999212bc9543682638eb1)
Add hfsplus file blessing patches from Matthew Garrett
Diffstat (limited to 'hfsplus-Add-an-ioctl-to-bless-files.patch')
-rw-r--r--hfsplus-Add-an-ioctl-to-bless-files.patch98
1 files changed, 98 insertions, 0 deletions
diff --git a/hfsplus-Add-an-ioctl-to-bless-files.patch b/hfsplus-Add-an-ioctl-to-bless-files.patch
new file mode 100644
index 000000000..082627f91
--- /dev/null
+++ b/hfsplus-Add-an-ioctl-to-bless-files.patch
@@ -0,0 +1,98 @@
+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>
+---
+Kept the ioctl in the hfs code, but moved it to a different range to reduce
+reduce the chances of someone stepping on it with another filesystem.
+ Documentation/ioctl/ioctl-number.txt | 1 +
+ fs/hfsplus/hfsplus_fs.h | 5 +++++
+ fs/hfsplus/ioctl.c | 34 ++++++++++++++++++++++++++++++++++
+ 3 files changed, 40 insertions(+), 0 deletions(-)
+diff --git a/Documentation/ioctl/ioctl-number.txt b/Documentation/ioctl/ioctl-number.txt
+index 4840334..37a4248 100644
+--- a/Documentation/ioctl/ioctl-number.txt
++++ b/Documentation/ioctl/ioctl-number.txt
+@@ -218,6 +218,7 @@ Code Seq#(hex) Include File Comments
+ 'h' 00-7F conflict! Charon filesystem
+ <mailto:zapman@interlan.net>
+ 'h' 00-1F linux/hpet.h conflict!
++'h' 80-8F fs/hfsplus/ioctl.c
+ 'i' 00-3F linux/i2o-dev.h conflict!
+ 'i' 0B-1F linux/ipmi.h conflict!
+ 'i' 80-8F linux/i8k.h
+diff --git a/fs/hfsplus/hfsplus_fs.h b/fs/hfsplus/hfsplus_fs.h
+index 21a5b7f..4e75ac6 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)
+
+
+ /*
++ * hfs+-specific ioctl for making the filesystem bootable
++ */
++#define HFSPLUS_IOC_BLESS _IO('h', 0x80)
++
++/*
+ * Functions in any *.c used in other files
+ */
+
+diff --git a/fs/hfsplus/ioctl.c b/fs/hfsplus/ioctl.c
+index f66c765..c640ba5 100644
+--- a/fs/hfsplus/ioctl.c
++++ b/fs/hfsplus/ioctl.c
+@@ -20,6 +20,38 @@
+ #include <asm/uaccess.h>
+ #include "hfsplus_fs.h"
+
++/*
++ * "Blessing" an HFS+ filesystem writes metadata to the superblock informing
++ * the platform firmware which file to boot from
++ */
++static int hfsplus_ioctl_bless(struct file *file, int __user *user_flags)
++{
++ struct dentry *dentry = file->f_path.dentry;
++ struct inode *inode = dentry->d_inode;
++ struct hfsplus_sb_info *sbi = HFSPLUS_SB(inode->i_sb);
++ struct hfsplus_vh *vh = sbi->s_vhdr;
++ struct hfsplus_vh *bvh = sbi->s_backup_vhdr;
++
++ if (!capable(CAP_SYS_ADMIN))
++ return -EPERM;
++
++ mutex_lock(&sbi->vh_mutex);
++
++ /* Directory containing the bootable system */
++ vh->finder_info[0] = bvh->finder_info[0] =
++ cpu_to_be32(parent_ino(dentry));
++
++ /* Bootloader */
++ vh->finder_info[1] = bvh->finder_info[1] = cpu_to_be32(inode->i_ino);
++
++ /* Per spec, the OS X system folder - same as finder_info[0] here */
++ vh->finder_info[5] = bvh->finder_info[5] =
++ cpu_to_be32(parent_ino(dentry));
++
++ mutex_unlock(&sbi->vh_mutex);
++ return 0;
++}
++
+ static int hfsplus_ioctl_getflags(struct file *file, int __user *user_flags)
+ {
+ 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)
+ return hfsplus_ioctl_getflags(file, argp);
+ case HFSPLUS_IOC_EXT2_SETFLAGS:
+ return hfsplus_ioctl_setflags(file, argp);
++ case HFSPLUS_IOC_BLESS:
++ return hfsplus_ioctl_bless(file, argp);
+ default:
+ return -ENOTTY;
+ }
+--
+1.7.7.6
+
+