Blame view
fs/jfs/ioctl.c
3.94 KB
d9e902668 JFS: Add missing ... |
1 2 3 4 5 6 7 8 |
/* * linux/fs/jfs/ioctl.c * * Copyright (C) 2006 Herbert Poetzl * adapted from Remy Card's ext2/ioctl.c */ #include <linux/fs.h> |
d9e902668 JFS: Add missing ... |
9 10 |
#include <linux/ctype.h> #include <linux/capability.h> |
42a74f206 [PATCH] r/o bind ... |
11 |
#include <linux/mount.h> |
d9e902668 JFS: Add missing ... |
12 |
#include <linux/time.h> |
914e26379 [PATCH] severing ... |
13 |
#include <linux/sched.h> |
b40c2e665 fs/jfs: TRIM supp... |
14 |
#include <linux/blkdev.h> |
d9e902668 JFS: Add missing ... |
15 16 |
#include <asm/current.h> #include <asm/uaccess.h> |
b40c2e665 fs/jfs: TRIM supp... |
17 18 |
#include "jfs_filsys.h" #include "jfs_debug.h" |
d9e902668 JFS: Add missing ... |
19 20 21 |
#include "jfs_incore.h" #include "jfs_dinode.h" #include "jfs_inode.h" |
b40c2e665 fs/jfs: TRIM supp... |
22 23 |
#include "jfs_dmap.h" #include "jfs_discard.h" |
d9e902668 JFS: Add missing ... |
24 25 26 27 28 |
static struct { long jfs_flag; long ext2_flag; } jfs_map[] = { |
36695673b [PATCH] BLOCK: Mo... |
29 30 31 32 33 34 35 |
{JFS_NOATIME_FL, FS_NOATIME_FL}, {JFS_DIRSYNC_FL, FS_DIRSYNC_FL}, {JFS_SYNC_FL, FS_SYNC_FL}, {JFS_SECRM_FL, FS_SECRM_FL}, {JFS_UNRM_FL, FS_UNRM_FL}, {JFS_APPEND_FL, FS_APPEND_FL}, {JFS_IMMUTABLE_FL, FS_IMMUTABLE_FL}, |
d9e902668 JFS: Add missing ... |
36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 |
{0, 0}, }; static long jfs_map_ext2(unsigned long flags, int from) { int index=0; long mapped=0; while (jfs_map[index].jfs_flag) { if (from) { if (jfs_map[index].ext2_flag & flags) mapped |= jfs_map[index].jfs_flag; } else { if (jfs_map[index].jfs_flag & flags) mapped |= jfs_map[index].ext2_flag; } index++; } return mapped; } |
baab81fa5 BKL-removal: Use ... |
56 |
long jfs_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) |
d9e902668 JFS: Add missing ... |
57 |
{ |
496ad9aa8 new helper: file_... |
58 |
struct inode *inode = file_inode(filp); |
d9e902668 JFS: Add missing ... |
59 60 61 62 63 |
struct jfs_inode_info *jfs_inode = JFS_IP(inode); unsigned int flags; switch (cmd) { case JFS_IOC_GETFLAGS: |
3e2221c73 Copy i_flags to j... |
64 |
jfs_get_inode_flags(jfs_inode); |
d9e902668 JFS: Add missing ... |
65 66 67 68 69 |
flags = jfs_inode->mode2 & JFS_FL_USER_VISIBLE; flags = jfs_map_ext2(flags, 0); return put_user(flags, (int __user *) arg); case JFS_IOC_SETFLAGS: { unsigned int oldflags; |
42a74f206 [PATCH] r/o bind ... |
70 |
int err; |
d9e902668 JFS: Add missing ... |
71 |
|
a561be710 switch a bunch of... |
72 |
err = mnt_want_write_file(filp); |
42a74f206 [PATCH] r/o bind ... |
73 74 |
if (err) return err; |
d9e902668 JFS: Add missing ... |
75 |
|
2e1496707 userns: rename is... |
76 |
if (!inode_owner_or_capable(inode)) { |
42a74f206 [PATCH] r/o bind ... |
77 78 79 80 81 82 83 |
err = -EACCES; goto setflags_out; } if (get_user(flags, (int __user *) arg)) { err = -EFAULT; goto setflags_out; } |
d9e902668 JFS: Add missing ... |
84 85 86 87 |
flags = jfs_map_ext2(flags, 1); if (!S_ISDIR(inode->i_mode)) flags &= ~JFS_DIRSYNC_FL; |
e47776a0a Forbid user to ch... |
88 |
/* Is it quota file? Do not allow user to mess with it */ |
42a74f206 [PATCH] r/o bind ... |
89 90 91 92 |
if (IS_NOQUOTA(inode)) { err = -EPERM; goto setflags_out; } |
baab81fa5 BKL-removal: Use ... |
93 94 |
/* Lock against other parallel changes of flags */ |
5955102c9 wrappers for ->i_... |
95 |
inode_lock(inode); |
baab81fa5 BKL-removal: Use ... |
96 |
|
3e2221c73 Copy i_flags to j... |
97 |
jfs_get_inode_flags(jfs_inode); |
d9e902668 JFS: Add missing ... |
98 99 100 101 102 103 104 105 106 |
oldflags = jfs_inode->mode2; /* * The IMMUTABLE and APPEND_ONLY flags can only be changed by * the relevant capability. */ if ((oldflags & JFS_IMMUTABLE_FL) || ((flags ^ oldflags) & (JFS_APPEND_FL | JFS_IMMUTABLE_FL))) { |
baab81fa5 BKL-removal: Use ... |
107 |
if (!capable(CAP_LINUX_IMMUTABLE)) { |
5955102c9 wrappers for ->i_... |
108 |
inode_unlock(inode); |
42a74f206 [PATCH] r/o bind ... |
109 110 |
err = -EPERM; goto setflags_out; |
baab81fa5 BKL-removal: Use ... |
111 |
} |
d9e902668 JFS: Add missing ... |
112 113 114 115 116 117 118 |
} flags = flags & JFS_FL_USER_MODIFIABLE; flags |= oldflags & ~JFS_FL_USER_MODIFIABLE; jfs_inode->mode2 = flags; jfs_set_inode_flags(inode); |
5955102c9 wrappers for ->i_... |
119 |
inode_unlock(inode); |
d9e902668 JFS: Add missing ... |
120 121 |
inode->i_ctime = CURRENT_TIME_SEC; mark_inode_dirty(inode); |
42a74f206 [PATCH] r/o bind ... |
122 |
setflags_out: |
2a79f17e4 vfs: mnt_drop_wri... |
123 |
mnt_drop_write_file(filp); |
42a74f206 [PATCH] r/o bind ... |
124 |
return err; |
d9e902668 JFS: Add missing ... |
125 |
} |
b40c2e665 fs/jfs: TRIM supp... |
126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 |
case FITRIM: { struct super_block *sb = inode->i_sb; struct request_queue *q = bdev_get_queue(sb->s_bdev); struct fstrim_range range; s64 ret = 0; if (!capable(CAP_SYS_ADMIN)) return -EPERM; if (!blk_queue_discard(q)) { jfs_warn("FITRIM not supported on device"); return -EOPNOTSUPP; } if (copy_from_user(&range, (struct fstrim_range __user *)arg, sizeof(range))) return -EFAULT; range.minlen = max_t(unsigned int, range.minlen, q->limits.discard_granularity); ret = jfs_ioc_trim(inode, &range); if (ret < 0) return ret; if (copy_to_user((struct fstrim_range __user *)arg, &range, sizeof(range))) return -EFAULT; return 0; } |
d9e902668 JFS: Add missing ... |
159 160 161 162 |
default: return -ENOTTY; } } |
ef1fc2f01 BKL-removal: Impl... |
163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 |
#ifdef CONFIG_COMPAT long jfs_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) { /* While these ioctl numbers defined with 'long' and have different * numbers than the 64bit ABI, * the actual implementation only deals with ints and is compatible. */ switch (cmd) { case JFS_IOC_GETFLAGS32: cmd = JFS_IOC_GETFLAGS; break; case JFS_IOC_SETFLAGS32: cmd = JFS_IOC_SETFLAGS; break; } return jfs_ioctl(filp, cmd, arg); } #endif |