Blame view
fs/hfsplus/ioctl.c
3.64 KB
b24413180 License cleanup: ... |
1 |
// SPDX-License-Identifier: GPL-2.0 |
1da177e4c Linux-2.6.12-rc2 |
2 3 4 5 6 7 8 9 10 11 12 13 14 |
/* * linux/fs/hfsplus/ioctl.c * * Copyright (C) 2003 * Ethan Benson <erbenson@alaska.net> * partially derived from linux/fs/ext2/ioctl.c * Copyright (C) 1993, 1994, 1995 * Remy Card (card@masi.ibp.fr) * Laboratoire MASI - Institut Blaise Pascal * Universite Pierre et Marie Curie (Paris VI) * * hfsplus ioctls */ |
16f7e0fe2 [PATCH] capable/c... |
15 |
#include <linux/capability.h> |
1da177e4c Linux-2.6.12-rc2 |
16 |
#include <linux/fs.h> |
42a74f206 [PATCH] r/o bind ... |
17 |
#include <linux/mount.h> |
1da177e4c Linux-2.6.12-rc2 |
18 |
#include <linux/sched.h> |
7c0f6ba68 Replace <asm/uacc... |
19 |
#include <linux/uaccess.h> |
1da177e4c Linux-2.6.12-rc2 |
20 |
#include "hfsplus_fs.h" |
a051f71ce hfsplus: add an i... |
21 22 23 24 25 26 27 |
/* * "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; |
2b0143b5c VFS: normal files... |
28 |
struct inode *inode = d_inode(dentry); |
a051f71ce hfsplus: add an i... |
29 30 31 |
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; |
7dea9665f hfsplus: fix bles... |
32 |
u32 cnid = (unsigned long)dentry->d_fsdata; |
a051f71ce hfsplus: add an i... |
33 34 35 36 37 38 39 40 41 |
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)); |
7dea9665f hfsplus: fix bles... |
42 43 44 45 46 47 |
/* * Bootloader. Just using the inode here breaks in the case of * hard links - the firmware wants the ID of the hard link file, * but the inode points at the indirect inode */ vh->finder_info[1] = bvh->finder_info[1] = cpu_to_be32(cnid); |
a051f71ce hfsplus: add an i... |
48 49 50 51 52 53 54 55 |
/* 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; } |
94744567f hfsplus: split hf... |
56 |
static int hfsplus_ioctl_getflags(struct file *file, int __user *user_flags) |
1da177e4c Linux-2.6.12-rc2 |
57 |
{ |
496ad9aa8 new helper: file_... |
58 |
struct inode *inode = file_inode(file); |
6af502de2 hfsplus: fix HFSP... |
59 |
struct hfsplus_inode_info *hip = HFSPLUS_I(inode); |
94744567f hfsplus: split hf... |
60 |
unsigned int flags = 0; |
722c55d13 hfsplus: remove s... |
61 |
if (inode->i_flags & S_IMMUTABLE) |
94744567f hfsplus: split hf... |
62 |
flags |= FS_IMMUTABLE_FL; |
596276c35 hfsplus: fix an a... |
63 |
if (inode->i_flags & S_APPEND) |
94744567f hfsplus: split hf... |
64 |
flags |= FS_APPEND_FL; |
6af502de2 hfsplus: fix HFSP... |
65 |
if (hip->userflags & HFSPLUS_FLG_NODUMP) |
94744567f hfsplus: split hf... |
66 67 68 69 70 71 72 |
flags |= FS_NODUMP_FL; return put_user(flags, user_flags); } static int hfsplus_ioctl_setflags(struct file *file, int __user *user_flags) { |
496ad9aa8 new helper: file_... |
73 |
struct inode *inode = file_inode(file); |
6af502de2 hfsplus: fix HFSP... |
74 |
struct hfsplus_inode_info *hip = HFSPLUS_I(inode); |
73d28d571 fs/hfsplus: atomi... |
75 |
unsigned int flags, new_fl = 0; |
94744567f hfsplus: split hf... |
76 |
int err = 0; |
1da177e4c Linux-2.6.12-rc2 |
77 |
|
a561be710 switch a bunch of... |
78 |
err = mnt_want_write_file(file); |
94744567f hfsplus: split hf... |
79 |
if (err) |
6333816ad hfsplus: protect ... |
80 |
goto out; |
1da177e4c Linux-2.6.12-rc2 |
81 |
|
2e1496707 userns: rename is... |
82 |
if (!inode_owner_or_capable(inode)) { |
94744567f hfsplus: split hf... |
83 84 85 |
err = -EACCES; goto out_drop_write; } |
1da177e4c Linux-2.6.12-rc2 |
86 |
|
94744567f hfsplus: split hf... |
87 88 89 90 |
if (get_user(flags, user_flags)) { err = -EFAULT; goto out_drop_write; } |
5955102c9 wrappers for ->i_... |
91 |
inode_lock(inode); |
6333816ad hfsplus: protect ... |
92 |
|
722c55d13 hfsplus: remove s... |
93 94 |
if ((flags & (FS_IMMUTABLE_FL|FS_APPEND_FL)) || inode->i_flags & (S_IMMUTABLE|S_APPEND)) { |
94744567f hfsplus: split hf... |
95 96 |
if (!capable(CAP_LINUX_IMMUTABLE)) { err = -EPERM; |
6333816ad hfsplus: protect ... |
97 |
goto out_unlock_inode; |
1da177e4c Linux-2.6.12-rc2 |
98 |
} |
1da177e4c Linux-2.6.12-rc2 |
99 |
} |
94744567f hfsplus: split hf... |
100 101 102 103 |
/* don't silently ignore unsupported ext2 flags */ if (flags & ~(FS_IMMUTABLE_FL|FS_APPEND_FL|FS_NODUMP_FL)) { err = -EOPNOTSUPP; |
6333816ad hfsplus: protect ... |
104 |
goto out_unlock_inode; |
94744567f hfsplus: split hf... |
105 |
} |
722c55d13 hfsplus: remove s... |
106 107 |
if (flags & FS_IMMUTABLE_FL) |
73d28d571 fs/hfsplus: atomi... |
108 |
new_fl |= S_IMMUTABLE; |
722c55d13 hfsplus: remove s... |
109 110 |
if (flags & FS_APPEND_FL) |
73d28d571 fs/hfsplus: atomi... |
111 112 113 |
new_fl |= S_APPEND; inode_set_flags(inode, new_fl, S_IMMUTABLE | S_APPEND); |
722c55d13 hfsplus: remove s... |
114 |
|
94744567f hfsplus: split hf... |
115 |
if (flags & FS_NODUMP_FL) |
6af502de2 hfsplus: fix HFSP... |
116 |
hip->userflags |= HFSPLUS_FLG_NODUMP; |
94744567f hfsplus: split hf... |
117 |
else |
6af502de2 hfsplus: fix HFSP... |
118 |
hip->userflags &= ~HFSPLUS_FLG_NODUMP; |
94744567f hfsplus: split hf... |
119 |
|
02027d42c fs: Replace CURRE... |
120 |
inode->i_ctime = current_time(inode); |
94744567f hfsplus: split hf... |
121 |
mark_inode_dirty(inode); |
6333816ad hfsplus: protect ... |
122 |
out_unlock_inode: |
5955102c9 wrappers for ->i_... |
123 |
inode_unlock(inode); |
94744567f hfsplus: split hf... |
124 |
out_drop_write: |
2a79f17e4 vfs: mnt_drop_wri... |
125 |
mnt_drop_write_file(file); |
6333816ad hfsplus: protect ... |
126 |
out: |
94744567f hfsplus: split hf... |
127 128 129 130 131 132 133 134 135 136 137 138 |
return err; } long hfsplus_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { void __user *argp = (void __user *)arg; switch (cmd) { case HFSPLUS_IOC_EXT2_GETFLAGS: return hfsplus_ioctl_getflags(file, argp); case HFSPLUS_IOC_EXT2_SETFLAGS: return hfsplus_ioctl_setflags(file, argp); |
a051f71ce hfsplus: add an i... |
139 140 |
case HFSPLUS_IOC_BLESS: return hfsplus_ioctl_bless(file, argp); |
1da177e4c Linux-2.6.12-rc2 |
141 142 143 144 |
default: return -ENOTTY; } } |