Blame view
block/ioctl.c
8.08 KB
c59ede7b7 [PATCH] move capa... |
1 |
#include <linux/capability.h> |
1da177e4c Linux-2.6.12-rc2 |
2 |
#include <linux/blkdev.h> |
5a0e3ad6a include cleanup: ... |
3 |
#include <linux/gfp.h> |
1da177e4c Linux-2.6.12-rc2 |
4 |
#include <linux/blkpg.h> |
a885c8c43 [PATCH] Add block... |
5 |
#include <linux/hdreg.h> |
1da177e4c Linux-2.6.12-rc2 |
6 7 |
#include <linux/backing-dev.h> #include <linux/buffer_head.h> |
2056a782f [PATCH] Block que... |
8 |
#include <linux/blktrace_api.h> |
1da177e4c Linux-2.6.12-rc2 |
9 10 11 12 13 14 |
#include <asm/uaccess.h> static int blkpg_ioctl(struct block_device *bdev, struct blkpg_ioctl_arg __user *arg) { struct block_device *bdevp; struct gendisk *disk; |
e71bf0d0e block: fix disk->... |
15 |
struct hd_struct *part; |
1da177e4c Linux-2.6.12-rc2 |
16 17 |
struct blkpg_ioctl_arg a; struct blkpg_partition p; |
e71bf0d0e block: fix disk->... |
18 |
struct disk_part_iter piter; |
1da177e4c Linux-2.6.12-rc2 |
19 |
long long start, length; |
cf771cb5a block: make varia... |
20 |
int partno; |
1da177e4c Linux-2.6.12-rc2 |
21 22 23 24 25 26 27 28 29 30 |
if (!capable(CAP_SYS_ADMIN)) return -EACCES; if (copy_from_user(&a, arg, sizeof(struct blkpg_ioctl_arg))) return -EFAULT; if (copy_from_user(&p, a.data, sizeof(struct blkpg_partition))) return -EFAULT; disk = bdev->bd_disk; if (bdev != bdev->bd_contains) return -EINVAL; |
cf771cb5a block: make varia... |
31 |
partno = p.pno; |
540eed563 block: make parti... |
32 |
if (partno <= 0) |
1da177e4c Linux-2.6.12-rc2 |
33 34 35 36 37 38 39 40 41 42 43 44 45 |
return -EINVAL; switch (a.op) { case BLKPG_ADD_PARTITION: start = p.start >> 9; length = p.length >> 9; /* check for fit in a hd_struct */ if (sizeof(sector_t) == sizeof(long) && sizeof(long long) > sizeof(long)) { long pstart = start, plength = length; if (pstart != start || plength != length || pstart < 0 || plength < 0) return -EINVAL; } |
88e341261 block: update add... |
46 |
|
c039e3134 [PATCH] sem2mutex... |
47 |
mutex_lock(&bdev->bd_mutex); |
88e341261 block: update add... |
48 |
|
1da177e4c Linux-2.6.12-rc2 |
49 |
/* overlap? */ |
e71bf0d0e block: fix disk->... |
50 51 52 53 54 55 |
disk_part_iter_init(&piter, disk, DISK_PITER_INCL_EMPTY); while ((part = disk_part_iter_next(&piter))) { if (!(start + length <= part->start_sect || start >= part->start_sect + part->nr_sects)) { disk_part_iter_exit(&piter); |
c039e3134 [PATCH] sem2mutex... |
56 |
mutex_unlock(&bdev->bd_mutex); |
1da177e4c Linux-2.6.12-rc2 |
57 58 59 |
return -EBUSY; } } |
e71bf0d0e block: fix disk->... |
60 |
disk_part_iter_exit(&piter); |
1da177e4c Linux-2.6.12-rc2 |
61 |
/* all seems OK */ |
ba32929a9 block: make add_p... |
62 |
part = add_partition(disk, partno, start, length, |
6d1d8050b block, partition:... |
63 |
ADDPART_FLAG_NONE, NULL); |
c039e3134 [PATCH] sem2mutex... |
64 |
mutex_unlock(&bdev->bd_mutex); |
ba32929a9 block: make add_p... |
65 |
return IS_ERR(part) ? PTR_ERR(part) : 0; |
1da177e4c Linux-2.6.12-rc2 |
66 |
case BLKPG_DEL_PARTITION: |
e71bf0d0e block: fix disk->... |
67 68 |
part = disk_get_part(disk, partno); if (!part) |
1da177e4c Linux-2.6.12-rc2 |
69 |
return -ENXIO; |
e71bf0d0e block: fix disk->... |
70 71 72 |
bdevp = bdget(part_devt(part)); disk_put_part(part); |
1da177e4c Linux-2.6.12-rc2 |
73 74 |
if (!bdevp) return -ENOMEM; |
e71bf0d0e block: fix disk->... |
75 |
|
2e7b651df [PATCH] remove th... |
76 |
mutex_lock(&bdevp->bd_mutex); |
1da177e4c Linux-2.6.12-rc2 |
77 |
if (bdevp->bd_openers) { |
c039e3134 [PATCH] sem2mutex... |
78 |
mutex_unlock(&bdevp->bd_mutex); |
1da177e4c Linux-2.6.12-rc2 |
79 80 81 82 83 |
bdput(bdevp); return -EBUSY; } /* all seems OK */ fsync_bdev(bdevp); |
f98393a64 mm: remove destro... |
84 |
invalidate_bdev(bdevp); |
1da177e4c Linux-2.6.12-rc2 |
85 |
|
6d740cd5b [PATCH] lockdep: ... |
86 |
mutex_lock_nested(&bdev->bd_mutex, 1); |
cf771cb5a block: make varia... |
87 |
delete_partition(disk, partno); |
c039e3134 [PATCH] sem2mutex... |
88 89 |
mutex_unlock(&bdev->bd_mutex); mutex_unlock(&bdevp->bd_mutex); |
1da177e4c Linux-2.6.12-rc2 |
90 91 92 93 94 95 96 97 98 99 100 101 |
bdput(bdevp); return 0; default: return -EINVAL; } } static int blkdev_reread_part(struct block_device *bdev) { struct gendisk *disk = bdev->bd_disk; int res; |
b5d0b9df0 block: introduce ... |
102 |
if (!disk_partitionable(disk) || bdev != bdev->bd_contains) |
1da177e4c Linux-2.6.12-rc2 |
103 104 105 |
return -EINVAL; if (!capable(CAP_SYS_ADMIN)) return -EACCES; |
c039e3134 [PATCH] sem2mutex... |
106 |
if (!mutex_trylock(&bdev->bd_mutex)) |
1da177e4c Linux-2.6.12-rc2 |
107 108 |
return -EBUSY; res = rescan_partitions(disk, bdev); |
c039e3134 [PATCH] sem2mutex... |
109 |
mutex_unlock(&bdev->bd_mutex); |
1da177e4c Linux-2.6.12-rc2 |
110 111 |
return res; } |
d30a2605b Add BLKDISCARD io... |
112 |
static int blk_ioctl_discard(struct block_device *bdev, uint64_t start, |
8d57a98cc block: add secure... |
113 |
uint64_t len, int secure) |
d30a2605b Add BLKDISCARD io... |
114 |
{ |
dd3932edd block: remove BLK... |
115 |
unsigned long flags = 0; |
8d57a98cc block: add secure... |
116 |
|
d30a2605b Add BLKDISCARD io... |
117 118 119 120 121 122 |
if (start & 511) return -EINVAL; if (len & 511) return -EINVAL; start >>= 9; len >>= 9; |
77304d2ab block: read i_siz... |
123 |
if (start + len > (i_size_read(bdev->bd_inode) >> 9)) |
d30a2605b Add BLKDISCARD io... |
124 |
return -EINVAL; |
8d57a98cc block: add secure... |
125 |
if (secure) |
dd3932edd block: remove BLK... |
126 |
flags |= BLKDEV_DISCARD_SECURE; |
8d57a98cc block: add secure... |
127 |
return blkdev_issue_discard(bdev, start, len, GFP_KERNEL, flags); |
d30a2605b Add BLKDISCARD io... |
128 |
} |
1da177e4c Linux-2.6.12-rc2 |
129 130 131 132 133 134 135 136 137 |
static int put_ushort(unsigned long arg, unsigned short val) { return put_user(val, (unsigned short __user *)arg); } static int put_int(unsigned long arg, int val) { return put_user(val, (int __user *)arg); } |
ac481c20e block: Topology i... |
138 139 140 141 |
static int put_uint(unsigned long arg, unsigned int val) { return put_user(val, (unsigned int __user *)arg); } |
1da177e4c Linux-2.6.12-rc2 |
142 143 144 145 146 147 148 149 150 151 152 153 154 155 |
static int put_long(unsigned long arg, long val) { return put_user(val, (long __user *)arg); } static int put_ulong(unsigned long arg, unsigned long val) { return put_user(val, (unsigned long __user *)arg); } static int put_u64(unsigned long arg, u64 val) { return put_user(val, (u64 __user *)arg); } |
633a08b81 [PATCH] introduce... |
156 157 158 159 |
int __blkdev_driver_ioctl(struct block_device *bdev, fmode_t mode, unsigned cmd, unsigned long arg) { struct gendisk *disk = bdev->bd_disk; |
d4430d62f [PATCH] beginning... |
160 161 162 |
if (disk->fops->ioctl) return disk->fops->ioctl(bdev, mode, cmd, arg); |
633a08b81 [PATCH] introduce... |
163 |
|
633a08b81 [PATCH] introduce... |
164 165 166 167 168 169 170 171 |
return -ENOTTY; } /* * For the record: _GPL here is only because somebody decided to slap it * on the previous export. Sheer idiocy, since it wasn't copyrightable * at all and could be open-coded without any exports by anybody who cares. */ EXPORT_SYMBOL_GPL(__blkdev_driver_ioctl); |
f58c4c0a1 compat_ioctl: mov... |
172 |
/* |
8a6cfeb6d block: push down ... |
173 |
* always keep this in sync with compat_blkdev_ioctl() |
f58c4c0a1 compat_ioctl: mov... |
174 |
*/ |
56b26add0 [PATCH] kill the ... |
175 |
int blkdev_ioctl(struct block_device *bdev, fmode_t mode, unsigned cmd, |
bb93e3a52 [PATCH] block: ad... |
176 177 |
unsigned long arg) { |
bb93e3a52 [PATCH] block: ad... |
178 |
struct gendisk *disk = bdev->bd_disk; |
45048d096 [PATCH] get rid o... |
179 180 |
struct backing_dev_info *bdi; loff_t size; |
bb93e3a52 [PATCH] block: ad... |
181 182 183 |
int ret, n; switch(cmd) { |
1da177e4c Linux-2.6.12-rc2 |
184 185 186 |
case BLKFLSBUF: if (!capable(CAP_SYS_ADMIN)) return -EACCES; |
bb93e3a52 [PATCH] block: ad... |
187 |
|
e436fdae7 [PATCH] get rid o... |
188 |
ret = __blkdev_driver_ioctl(bdev, mode, cmd, arg); |
bb93e3a52 [PATCH] block: ad... |
189 190 191 |
/* -EINVAL to handle old uncorrected drivers */ if (ret != -EINVAL && ret != -ENOTTY) return ret; |
1da177e4c Linux-2.6.12-rc2 |
192 |
fsync_bdev(bdev); |
f98393a64 mm: remove destro... |
193 |
invalidate_bdev(bdev); |
1da177e4c Linux-2.6.12-rc2 |
194 |
return 0; |
bb93e3a52 [PATCH] block: ad... |
195 |
|
1da177e4c Linux-2.6.12-rc2 |
196 |
case BLKROSET: |
e436fdae7 [PATCH] get rid o... |
197 |
ret = __blkdev_driver_ioctl(bdev, mode, cmd, arg); |
bb93e3a52 [PATCH] block: ad... |
198 199 200 |
/* -EINVAL to handle old uncorrected drivers */ if (ret != -EINVAL && ret != -ENOTTY) return ret; |
1da177e4c Linux-2.6.12-rc2 |
201 202 203 204 205 206 |
if (!capable(CAP_SYS_ADMIN)) return -EACCES; if (get_user(n, (int __user *)(arg))) return -EFAULT; set_device_ro(bdev, n); return 0; |
d30a2605b Add BLKDISCARD io... |
207 |
|
8d57a98cc block: add secure... |
208 209 |
case BLKDISCARD: case BLKSECDISCARD: { |
d30a2605b Add BLKDISCARD io... |
210 |
uint64_t range[2]; |
e436fdae7 [PATCH] get rid o... |
211 |
if (!(mode & FMODE_WRITE)) |
d30a2605b Add BLKDISCARD io... |
212 213 214 215 |
return -EBADF; if (copy_from_user(range, (void __user *)arg, sizeof(range))) return -EFAULT; |
8d57a98cc block: add secure... |
216 217 |
return blk_ioctl_discard(bdev, range[0], range[1], cmd == BLKSECDISCARD); |
d30a2605b Add BLKDISCARD io... |
218 |
} |
a885c8c43 [PATCH] Add block... |
219 220 221 222 223 224 225 226 227 228 229 230 |
case HDIO_GETGEO: { struct hd_geometry geo; if (!arg) return -EINVAL; if (!disk->fops->getgeo) return -ENOTTY; /* * We need to set the startsect first, the driver may * want to override it. */ |
a014741c0 block: ioctl: fix... |
231 |
memset(&geo, 0, sizeof(geo)); |
a885c8c43 [PATCH] Add block... |
232 233 234 235 236 237 238 239 240 |
geo.start = get_start_sect(bdev); ret = disk->fops->getgeo(bdev, &geo); if (ret) return ret; if (copy_to_user((struct hd_geometry __user *)arg, &geo, sizeof(geo))) return -EFAULT; return 0; } |
45048d096 [PATCH] get rid o... |
241 242 243 244 245 246 247 248 249 250 |
case BLKRAGET: case BLKFRAGET: if (!arg) return -EINVAL; bdi = blk_get_backing_dev_info(bdev); if (bdi == NULL) return -ENOTTY; return put_long(arg, (bdi->ra_pages * PAGE_CACHE_SIZE) / 512); case BLKROGET: return put_int(arg, bdev_read_only(bdev) != 0); |
ac481c20e block: Topology i... |
251 |
case BLKBSZGET: /* get block device soft block size (cf. BLKSSZGET) */ |
45048d096 [PATCH] get rid o... |
252 |
return put_int(arg, block_size(bdev)); |
ac481c20e block: Topology i... |
253 |
case BLKSSZGET: /* get block device logical block size */ |
e1defc4ff block: Do away wi... |
254 |
return put_int(arg, bdev_logical_block_size(bdev)); |
ac481c20e block: Topology i... |
255 256 257 258 259 260 261 262 |
case BLKPBSZGET: /* get block device physical block size */ return put_uint(arg, bdev_physical_block_size(bdev)); case BLKIOMIN: return put_uint(arg, bdev_io_min(bdev)); case BLKIOOPT: return put_uint(arg, bdev_io_opt(bdev)); case BLKALIGNOFF: return put_int(arg, bdev_alignment_offset(bdev)); |
98262f276 block: Allow devi... |
263 264 |
case BLKDISCARDZEROES: return put_uint(arg, bdev_discard_zeroes_data(bdev)); |
45048d096 [PATCH] get rid o... |
265 |
case BLKSECTGET: |
ae03bf639 block: Use access... |
266 |
return put_ushort(arg, queue_max_sectors(bdev_get_queue(bdev))); |
45048d096 [PATCH] get rid o... |
267 268 269 270 271 272 273 |
case BLKRASET: case BLKFRASET: if(!capable(CAP_SYS_ADMIN)) return -EACCES; bdi = blk_get_backing_dev_info(bdev); if (bdi == NULL) return -ENOTTY; |
45048d096 [PATCH] get rid o... |
274 |
bdi->ra_pages = (arg * 512) / PAGE_CACHE_SIZE; |
45048d096 [PATCH] get rid o... |
275 276 277 278 279 280 281 282 283 |
return 0; case BLKBSZSET: /* set the logical block size */ if (!capable(CAP_SYS_ADMIN)) return -EACCES; if (!arg) return -EINVAL; if (get_user(n, (int __user *) arg)) return -EFAULT; |
3c522cedb block: fix refcou... |
284 285 286 287 288 |
if (!(mode & FMODE_EXCL)) { bdgrab(bdev); if (blkdev_get(bdev, mode | FMODE_EXCL, &bdev) < 0) return -EBUSY; } |
45048d096 [PATCH] get rid o... |
289 |
ret = set_blocksize(bdev, n); |
6af3a56e1 [PATCH] get rid o... |
290 |
if (!(mode & FMODE_EXCL)) |
e525fd89d block: make blkde... |
291 |
blkdev_put(bdev, mode | FMODE_EXCL); |
bb93e3a52 [PATCH] block: ad... |
292 |
return ret; |
45048d096 [PATCH] get rid o... |
293 |
case BLKPG: |
45048d096 [PATCH] get rid o... |
294 |
ret = blkpg_ioctl(bdev, (struct blkpg_ioctl_arg __user *) arg); |
45048d096 [PATCH] get rid o... |
295 296 |
break; case BLKRRPART: |
45048d096 [PATCH] get rid o... |
297 |
ret = blkdev_reread_part(bdev); |
45048d096 [PATCH] get rid o... |
298 299 |
break; case BLKGETSIZE: |
77304d2ab block: read i_siz... |
300 |
size = i_size_read(bdev->bd_inode); |
45048d096 [PATCH] get rid o... |
301 302 303 304 |
if ((size >> 9) > ~0UL) return -EFBIG; return put_ulong(arg, size >> 9); case BLKGETSIZE64: |
77304d2ab block: read i_siz... |
305 |
return put_u64(arg, i_size_read(bdev->bd_inode)); |
45048d096 [PATCH] get rid o... |
306 307 308 309 |
case BLKTRACESTART: case BLKTRACESTOP: case BLKTRACESETUP: case BLKTRACETEARDOWN: |
45048d096 [PATCH] get rid o... |
310 |
ret = blk_trace_ioctl(bdev, cmd, (char __user *) arg); |
45048d096 [PATCH] get rid o... |
311 312 313 314 315 |
break; default: ret = __blkdev_driver_ioctl(bdev, mode, cmd, arg); } return ret; |
1da177e4c Linux-2.6.12-rc2 |
316 |
} |
68f66feb3 [PATCH] Fix root ... |
317 |
EXPORT_SYMBOL_GPL(blkdev_ioctl); |