Blame view
fs/hfsplus/ioctl.c
5.06 KB
1da177e4c Linux-2.6.12-rc2 |
1 2 3 4 5 6 7 8 9 10 11 12 13 |
/* * 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... |
14 |
#include <linux/capability.h> |
1da177e4c Linux-2.6.12-rc2 |
15 |
#include <linux/fs.h> |
42a74f206 [PATCH] r/o bind ... |
16 |
#include <linux/mount.h> |
1da177e4c Linux-2.6.12-rc2 |
17 18 19 20 |
#include <linux/sched.h> #include <linux/xattr.h> #include <asm/uaccess.h> #include "hfsplus_fs.h" |
94744567f hfsplus: split hf... |
21 |
static int hfsplus_ioctl_getflags(struct file *file, int __user *user_flags) |
1da177e4c Linux-2.6.12-rc2 |
22 |
{ |
94744567f hfsplus: split hf... |
23 |
struct inode *inode = file->f_path.dentry->d_inode; |
6af502de2 hfsplus: fix HFSP... |
24 |
struct hfsplus_inode_info *hip = HFSPLUS_I(inode); |
94744567f hfsplus: split hf... |
25 |
unsigned int flags = 0; |
722c55d13 hfsplus: remove s... |
26 |
if (inode->i_flags & S_IMMUTABLE) |
94744567f hfsplus: split hf... |
27 |
flags |= FS_IMMUTABLE_FL; |
596276c35 hfsplus: fix an a... |
28 |
if (inode->i_flags & S_APPEND) |
94744567f hfsplus: split hf... |
29 |
flags |= FS_APPEND_FL; |
6af502de2 hfsplus: fix HFSP... |
30 |
if (hip->userflags & HFSPLUS_FLG_NODUMP) |
94744567f hfsplus: split hf... |
31 32 33 34 35 36 37 38 |
flags |= FS_NODUMP_FL; return put_user(flags, user_flags); } static int hfsplus_ioctl_setflags(struct file *file, int __user *user_flags) { struct inode *inode = file->f_path.dentry->d_inode; |
6af502de2 hfsplus: fix HFSP... |
39 |
struct hfsplus_inode_info *hip = HFSPLUS_I(inode); |
1da177e4c Linux-2.6.12-rc2 |
40 |
unsigned int flags; |
94744567f hfsplus: split hf... |
41 |
int err = 0; |
1da177e4c Linux-2.6.12-rc2 |
42 |
|
a561be710 switch a bunch of... |
43 |
err = mnt_want_write_file(file); |
94744567f hfsplus: split hf... |
44 |
if (err) |
6333816ad hfsplus: protect ... |
45 |
goto out; |
1da177e4c Linux-2.6.12-rc2 |
46 |
|
2e1496707 userns: rename is... |
47 |
if (!inode_owner_or_capable(inode)) { |
94744567f hfsplus: split hf... |
48 49 50 |
err = -EACCES; goto out_drop_write; } |
1da177e4c Linux-2.6.12-rc2 |
51 |
|
94744567f hfsplus: split hf... |
52 53 54 55 |
if (get_user(flags, user_flags)) { err = -EFAULT; goto out_drop_write; } |
6333816ad hfsplus: protect ... |
56 |
mutex_lock(&inode->i_mutex); |
722c55d13 hfsplus: remove s... |
57 58 |
if ((flags & (FS_IMMUTABLE_FL|FS_APPEND_FL)) || inode->i_flags & (S_IMMUTABLE|S_APPEND)) { |
94744567f hfsplus: split hf... |
59 60 |
if (!capable(CAP_LINUX_IMMUTABLE)) { err = -EPERM; |
6333816ad hfsplus: protect ... |
61 |
goto out_unlock_inode; |
1da177e4c Linux-2.6.12-rc2 |
62 |
} |
1da177e4c Linux-2.6.12-rc2 |
63 |
} |
94744567f hfsplus: split hf... |
64 65 66 67 |
/* don't silently ignore unsupported ext2 flags */ if (flags & ~(FS_IMMUTABLE_FL|FS_APPEND_FL|FS_NODUMP_FL)) { err = -EOPNOTSUPP; |
6333816ad hfsplus: protect ... |
68 |
goto out_unlock_inode; |
94744567f hfsplus: split hf... |
69 |
} |
722c55d13 hfsplus: remove s... |
70 71 |
if (flags & FS_IMMUTABLE_FL) |
94744567f hfsplus: split hf... |
72 |
inode->i_flags |= S_IMMUTABLE; |
722c55d13 hfsplus: remove s... |
73 |
else |
94744567f hfsplus: split hf... |
74 |
inode->i_flags &= ~S_IMMUTABLE; |
722c55d13 hfsplus: remove s... |
75 76 |
if (flags & FS_APPEND_FL) |
94744567f hfsplus: split hf... |
77 |
inode->i_flags |= S_APPEND; |
722c55d13 hfsplus: remove s... |
78 |
else |
94744567f hfsplus: split hf... |
79 |
inode->i_flags &= ~S_APPEND; |
722c55d13 hfsplus: remove s... |
80 |
|
94744567f hfsplus: split hf... |
81 |
if (flags & FS_NODUMP_FL) |
6af502de2 hfsplus: fix HFSP... |
82 |
hip->userflags |= HFSPLUS_FLG_NODUMP; |
94744567f hfsplus: split hf... |
83 |
else |
6af502de2 hfsplus: fix HFSP... |
84 |
hip->userflags &= ~HFSPLUS_FLG_NODUMP; |
94744567f hfsplus: split hf... |
85 86 87 |
inode->i_ctime = CURRENT_TIME_SEC; mark_inode_dirty(inode); |
6333816ad hfsplus: protect ... |
88 |
out_unlock_inode: |
e50fb58b5 hfsplus: fix doub... |
89 |
mutex_unlock(&inode->i_mutex); |
94744567f hfsplus: split hf... |
90 |
out_drop_write: |
2a79f17e4 vfs: mnt_drop_wri... |
91 |
mnt_drop_write_file(file); |
6333816ad hfsplus: protect ... |
92 |
out: |
94744567f hfsplus: split hf... |
93 94 95 96 97 98 99 100 101 102 103 104 |
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); |
1da177e4c Linux-2.6.12-rc2 |
105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 |
default: return -ENOTTY; } } int hfsplus_setxattr(struct dentry *dentry, const char *name, const void *value, size_t size, int flags) { struct inode *inode = dentry->d_inode; struct hfs_find_data fd; hfsplus_cat_entry entry; struct hfsplus_cat_file *file; int res; if (!S_ISREG(inode->i_mode) || HFSPLUS_IS_RSRC(inode)) return -EOPNOTSUPP; |
dd73a01a3 hfsplus: fix HFSP... |
121 |
res = hfs_find_init(HFSPLUS_SB(inode->i_sb)->cat_tree, &fd); |
1da177e4c Linux-2.6.12-rc2 |
122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 |
if (res) return res; res = hfsplus_find_cat(inode->i_sb, inode->i_ino, &fd); if (res) goto out; hfs_bnode_read(fd.bnode, &entry, fd.entryoffset, sizeof(struct hfsplus_cat_file)); file = &entry.file; if (!strcmp(name, "hfs.type")) { if (size == 4) memcpy(&file->user_info.fdType, value, 4); else res = -ERANGE; } else if (!strcmp(name, "hfs.creator")) { if (size == 4) memcpy(&file->user_info.fdCreator, value, 4); else res = -ERANGE; } else res = -EOPNOTSUPP; |
e34947056 hfsplus: optimize... |
143 |
if (!res) { |
1da177e4c Linux-2.6.12-rc2 |
144 145 |
hfs_bnode_write(fd.bnode, &entry, fd.entryoffset, sizeof(struct hfsplus_cat_file)); |
e34947056 hfsplus: optimize... |
146 147 |
hfsplus_mark_inode_dirty(inode, HFSPLUS_I_CAT_DIRTY); } |
1da177e4c Linux-2.6.12-rc2 |
148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 |
out: hfs_find_exit(&fd); return res; } ssize_t hfsplus_getxattr(struct dentry *dentry, const char *name, void *value, size_t size) { struct inode *inode = dentry->d_inode; struct hfs_find_data fd; hfsplus_cat_entry entry; struct hfsplus_cat_file *file; ssize_t res = 0; if (!S_ISREG(inode->i_mode) || HFSPLUS_IS_RSRC(inode)) return -EOPNOTSUPP; if (size) { |
dd73a01a3 hfsplus: fix HFSP... |
166 |
res = hfs_find_init(HFSPLUS_SB(inode->i_sb)->cat_tree, &fd); |
1da177e4c Linux-2.6.12-rc2 |
167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 |
if (res) return res; res = hfsplus_find_cat(inode->i_sb, inode->i_ino, &fd); if (res) goto out; hfs_bnode_read(fd.bnode, &entry, fd.entryoffset, sizeof(struct hfsplus_cat_file)); } file = &entry.file; if (!strcmp(name, "hfs.type")) { if (size >= 4) { memcpy(value, &file->user_info.fdType, 4); res = 4; } else res = size ? -ERANGE : 4; } else if (!strcmp(name, "hfs.creator")) { if (size >= 4) { memcpy(value, &file->user_info.fdCreator, 4); res = 4; } else res = size ? -ERANGE : 4; } else |
46bf36ece hfsplus: fix getx... |
190 |
res = -EOPNOTSUPP; |
1da177e4c Linux-2.6.12-rc2 |
191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 |
out: if (size) hfs_find_exit(&fd); return res; } #define HFSPLUS_ATTRLIST_SIZE (sizeof("hfs.creator")+sizeof("hfs.type")) ssize_t hfsplus_listxattr(struct dentry *dentry, char *buffer, size_t size) { struct inode *inode = dentry->d_inode; if (!S_ISREG(inode->i_mode) || HFSPLUS_IS_RSRC(inode)) return -EOPNOTSUPP; if (!buffer || !size) return HFSPLUS_ATTRLIST_SIZE; if (size < HFSPLUS_ATTRLIST_SIZE) return -ERANGE; strcpy(buffer, "hfs.type"); strcpy(buffer + sizeof("hfs.type"), "hfs.creator"); return HFSPLUS_ATTRLIST_SIZE; } |