UBI: rename_volumes: Use UBI_METAONLY
[deliverable/linux.git] / drivers / mtd / ubi / cdev.c
CommitLineData
801c135c
AB
1/*
2 * Copyright (c) International Business Machines Corp., 2006
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
12 * the GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 *
18 * Author: Artem Bityutskiy (Битюцкий Артём)
19 */
20
21/*
22 * This file includes implementation of UBI character device operations.
23 *
24 * There are two kinds of character devices in UBI: UBI character devices and
25 * UBI volume character devices. UBI character devices allow users to
26 * manipulate whole volumes: create, remove, and re-size them. Volume character
27 * devices provide volume I/O capabilities.
28 *
29 * Major and minor numbers are assigned dynamically to both UBI and volume
30 * character devices.
9f961b57
AB
31 *
32 * Well, there is the third kind of character devices - the UBI control
33 * character device, which allows to manipulate by UBI devices - create and
34 * delete them. In other words, it is used for attaching and detaching MTD
35 * devices.
801c135c
AB
36 */
37
38#include <linux/module.h>
39#include <linux/stat.h>
5a0e3ad6 40#include <linux/slab.h>
801c135c
AB
41#include <linux/ioctl.h>
42#include <linux/capability.h>
9c9ec147 43#include <linux/uaccess.h>
f429b2ea 44#include <linux/compat.h>
3013ee31 45#include <linux/math64.h>
801c135c 46#include <mtd/ubi-user.h>
801c135c
AB
47#include "ubi.h"
48
801c135c
AB
49/**
50 * get_exclusive - get exclusive access to an UBI volume.
32608703 51 * @ubi: UBI device description object
801c135c
AB
52 * @desc: volume descriptor
53 *
54 * This function changes UBI volume open mode to "exclusive". Returns previous
55 * mode value (positive integer) in case of success and a negative error code
56 * in case of failure.
57 */
32608703 58static int get_exclusive(struct ubi_device *ubi, struct ubi_volume_desc *desc)
801c135c
AB
59{
60 int users, err;
61 struct ubi_volume *vol = desc->vol;
62
63 spin_lock(&vol->ubi->volumes_lock);
fafdd2bf 64 users = vol->readers + vol->writers + vol->exclusive + vol->metaonly;
801c135c
AB
65 ubi_assert(users > 0);
66 if (users > 1) {
32608703 67 ubi_err(ubi, "%d users for volume %d", users, vol->vol_id);
801c135c
AB
68 err = -EBUSY;
69 } else {
fafdd2bf 70 vol->readers = vol->writers = vol->metaonly = 0;
801c135c
AB
71 vol->exclusive = 1;
72 err = desc->mode;
73 desc->mode = UBI_EXCLUSIVE;
74 }
75 spin_unlock(&vol->ubi->volumes_lock);
76
77 return err;
78}
79
80/**
81 * revoke_exclusive - revoke exclusive mode.
82 * @desc: volume descriptor
83 * @mode: new mode to switch to
84 */
85static void revoke_exclusive(struct ubi_volume_desc *desc, int mode)
86{
87 struct ubi_volume *vol = desc->vol;
88
89 spin_lock(&vol->ubi->volumes_lock);
fafdd2bf 90 ubi_assert(vol->readers == 0 && vol->writers == 0 && vol->metaonly == 0);
801c135c
AB
91 ubi_assert(vol->exclusive == 1 && desc->mode == UBI_EXCLUSIVE);
92 vol->exclusive = 0;
93 if (mode == UBI_READONLY)
94 vol->readers = 1;
95 else if (mode == UBI_READWRITE)
96 vol->writers = 1;
fafdd2bf
RW
97 else if (mode == UBI_METAONLY)
98 vol->metaonly = 1;
801c135c
AB
99 else
100 vol->exclusive = 1;
101 spin_unlock(&vol->ubi->volumes_lock);
102
103 desc->mode = mode;
104}
105
106static int vol_cdev_open(struct inode *inode, struct file *file)
107{
108 struct ubi_volume_desc *desc;
e73f4459
AB
109 int vol_id = iminor(inode) - 1, mode, ubi_num;
110
111 ubi_num = ubi_major2num(imajor(inode));
7d200e88 112 if (ubi_num < 0)
e73f4459 113 return ubi_num;
801c135c
AB
114
115 if (file->f_mode & FMODE_WRITE)
116 mode = UBI_READWRITE;
117 else
118 mode = UBI_READONLY;
119
e1cf7e6d 120 dbg_gen("open device %d, volume %d, mode %d",
feddbb34 121 ubi_num, vol_id, mode);
801c135c 122
e73f4459 123 desc = ubi_open_volume(ubi_num, vol_id, mode);
801c135c
AB
124 if (IS_ERR(desc))
125 return PTR_ERR(desc);
126
127 file->private_data = desc;
128 return 0;
129}
130
131static int vol_cdev_release(struct inode *inode, struct file *file)
132{
133 struct ubi_volume_desc *desc = file->private_data;
134 struct ubi_volume *vol = desc->vol;
135
e1cf7e6d
AB
136 dbg_gen("release device %d, volume %d, mode %d",
137 vol->ubi->ubi_num, vol->vol_id, desc->mode);
801c135c
AB
138
139 if (vol->updating) {
32608703 140 ubi_warn(vol->ubi, "update of volume %d not finished, volume is damaged",
801c135c 141 vol->vol_id);
e653879c 142 ubi_assert(!vol->changing_leb);
801c135c 143 vol->updating = 0;
92ad8f37 144 vfree(vol->upd_buf);
e653879c 145 } else if (vol->changing_leb) {
049333ce
AB
146 dbg_gen("only %lld of %lld bytes received for atomic LEB change for volume %d:%d, cancel",
147 vol->upd_received, vol->upd_bytes, vol->ubi->ubi_num,
148 vol->vol_id);
e653879c
AB
149 vol->changing_leb = 0;
150 vfree(vol->upd_buf);
801c135c
AB
151 }
152
153 ubi_close_volume(desc);
154 return 0;
155}
156
157static loff_t vol_cdev_llseek(struct file *file, loff_t offset, int origin)
158{
159 struct ubi_volume_desc *desc = file->private_data;
160 struct ubi_volume *vol = desc->vol;
801c135c
AB
161
162 if (vol->updating) {
feddbb34 163 /* Update is in progress, seeking is prohibited */
32608703 164 ubi_err(vol->ubi, "updating");
801c135c
AB
165 return -EBUSY;
166 }
167
4a1f2f38 168 return fixed_size_llseek(file, offset, origin, vol->used_bytes);
801c135c
AB
169}
170
049333ce
AB
171static int vol_cdev_fsync(struct file *file, loff_t start, loff_t end,
172 int datasync)
1b24bc3a
CC
173{
174 struct ubi_volume_desc *desc = file->private_data;
175 struct ubi_device *ubi = desc->vol->ubi;
496ad9aa 176 struct inode *inode = file_inode(file);
02c24a82
JB
177 int err;
178 mutex_lock(&inode->i_mutex);
179 err = ubi_sync(ubi->ubi_num);
180 mutex_unlock(&inode->i_mutex);
181 return err;
1b24bc3a
CC
182}
183
184
801c135c
AB
185static ssize_t vol_cdev_read(struct file *file, __user char *buf, size_t count,
186 loff_t *offp)
187{
188 struct ubi_volume_desc *desc = file->private_data;
189 struct ubi_volume *vol = desc->vol;
190 struct ubi_device *ubi = vol->ubi;
ae616e1b 191 int err, lnum, off, len, tbuf_size;
801c135c
AB
192 size_t count_save = count;
193 void *tbuf;
801c135c 194
c8566350 195 dbg_gen("read %zd bytes from offset %lld of volume %d",
ae616e1b 196 count, *offp, vol->vol_id);
801c135c
AB
197
198 if (vol->updating) {
32608703 199 ubi_err(vol->ubi, "updating");
801c135c
AB
200 return -EBUSY;
201 }
202 if (vol->upd_marker) {
32608703 203 ubi_err(vol->ubi, "damaged volume, update marker is set");
801c135c
AB
204 return -EBADF;
205 }
206 if (*offp == vol->used_bytes || count == 0)
207 return 0;
208
209 if (vol->corrupted)
c8566350 210 dbg_gen("read from corrupted volume %d", vol->vol_id);
801c135c
AB
211
212 if (*offp + count > vol->used_bytes)
213 count_save = count = vol->used_bytes - *offp;
214
215 tbuf_size = vol->usable_leb_size;
216 if (count < tbuf_size)
217 tbuf_size = ALIGN(count, ubi->min_io_size);
92ad8f37 218 tbuf = vmalloc(tbuf_size);
801c135c
AB
219 if (!tbuf)
220 return -ENOMEM;
221
222 len = count > tbuf_size ? tbuf_size : count;
3013ee31 223 lnum = div_u64_rem(*offp, vol->usable_leb_size, &off);
801c135c
AB
224
225 do {
226 cond_resched();
227
228 if (off + len >= vol->usable_leb_size)
229 len = vol->usable_leb_size - off;
230
89b96b69 231 err = ubi_eba_read_leb(ubi, vol, lnum, tbuf, off, len, 0);
801c135c
AB
232 if (err)
233 break;
234
235 off += len;
236 if (off == vol->usable_leb_size) {
237 lnum += 1;
238 off -= vol->usable_leb_size;
239 }
240
241 count -= len;
242 *offp += len;
243
244 err = copy_to_user(buf, tbuf, len);
245 if (err) {
246 err = -EFAULT;
247 break;
248 }
249
250 buf += len;
251 len = count > tbuf_size ? tbuf_size : count;
252 } while (count);
253
92ad8f37 254 vfree(tbuf);
801c135c
AB
255 return err ? err : count_save - count;
256}
257
801c135c
AB
258/*
259 * This function allows to directly write to dynamic UBI volumes, without
766fb95b 260 * issuing the volume update operation.
801c135c
AB
261 */
262static ssize_t vol_cdev_direct_write(struct file *file, const char __user *buf,
263 size_t count, loff_t *offp)
264{
265 struct ubi_volume_desc *desc = file->private_data;
266 struct ubi_volume *vol = desc->vol;
267 struct ubi_device *ubi = vol->ubi;
ae616e1b 268 int lnum, off, len, tbuf_size, err = 0;
801c135c
AB
269 size_t count_save = count;
270 char *tbuf;
801c135c 271
766fb95b
SA
272 if (!vol->direct_writes)
273 return -EPERM;
274
c8566350 275 dbg_gen("requested: write %zd bytes to offset %lld of volume %u",
ae616e1b 276 count, *offp, vol->vol_id);
801c135c
AB
277
278 if (vol->vol_type == UBI_STATIC_VOLUME)
279 return -EROFS;
280
3013ee31 281 lnum = div_u64_rem(*offp, vol->usable_leb_size, &off);
cadb40cc 282 if (off & (ubi->min_io_size - 1)) {
32608703 283 ubi_err(ubi, "unaligned position");
801c135c
AB
284 return -EINVAL;
285 }
286
287 if (*offp + count > vol->used_bytes)
288 count_save = count = vol->used_bytes - *offp;
289
290 /* We can write only in fractions of the minimum I/O unit */
cadb40cc 291 if (count & (ubi->min_io_size - 1)) {
32608703 292 ubi_err(ubi, "unaligned write length");
801c135c
AB
293 return -EINVAL;
294 }
295
296 tbuf_size = vol->usable_leb_size;
297 if (count < tbuf_size)
298 tbuf_size = ALIGN(count, ubi->min_io_size);
92ad8f37 299 tbuf = vmalloc(tbuf_size);
801c135c
AB
300 if (!tbuf)
301 return -ENOMEM;
302
303 len = count > tbuf_size ? tbuf_size : count;
304
305 while (count) {
306 cond_resched();
307
308 if (off + len >= vol->usable_leb_size)
309 len = vol->usable_leb_size - off;
310
311 err = copy_from_user(tbuf, buf, len);
312 if (err) {
313 err = -EFAULT;
314 break;
315 }
316
b36a261e 317 err = ubi_eba_write_leb(ubi, vol, lnum, tbuf, off, len);
801c135c
AB
318 if (err)
319 break;
320
321 off += len;
322 if (off == vol->usable_leb_size) {
323 lnum += 1;
324 off -= vol->usable_leb_size;
325 }
326
327 count -= len;
328 *offp += len;
329 buf += len;
330 len = count > tbuf_size ? tbuf_size : count;
331 }
332
92ad8f37 333 vfree(tbuf);
801c135c
AB
334 return err ? err : count_save - count;
335}
336
801c135c
AB
337static ssize_t vol_cdev_write(struct file *file, const char __user *buf,
338 size_t count, loff_t *offp)
339{
340 int err = 0;
341 struct ubi_volume_desc *desc = file->private_data;
342 struct ubi_volume *vol = desc->vol;
343 struct ubi_device *ubi = vol->ubi;
344
e653879c 345 if (!vol->updating && !vol->changing_leb)
801c135c
AB
346 return vol_cdev_direct_write(file, buf, count, offp);
347
e653879c
AB
348 if (vol->updating)
349 err = ubi_more_update_data(ubi, vol, buf, count);
350 else
351 err = ubi_more_leb_change_data(ubi, vol, buf, count);
352
801c135c 353 if (err < 0) {
32608703 354 ubi_err(ubi, "cannot accept more %zd bytes of data, error %d",
01f7b309 355 count, err);
801c135c
AB
356 return err;
357 }
358
359 if (err) {
360 /*
e653879c
AB
361 * The operation is finished, @err contains number of actually
362 * written bytes.
801c135c
AB
363 */
364 count = err;
365
e653879c
AB
366 if (vol->changing_leb) {
367 revoke_exclusive(desc, UBI_READWRITE);
368 return count;
369 }
370
801c135c
AB
371 err = ubi_check_volume(ubi, vol->vol_id);
372 if (err < 0)
373 return err;
374
375 if (err) {
32608703 376 ubi_warn(ubi, "volume %d on UBI device %d is corrupted",
801c135c
AB
377 vol->vol_id, ubi->ubi_num);
378 vol->corrupted = 1;
379 }
380 vol->checked = 1;
0e0ee1cc 381 ubi_volume_notify(ubi, vol, UBI_VOLUME_UPDATED);
801c135c
AB
382 revoke_exclusive(desc, UBI_READWRITE);
383 }
384
801c135c
AB
385 return count;
386}
387
f429b2ea
AB
388static long vol_cdev_ioctl(struct file *file, unsigned int cmd,
389 unsigned long arg)
801c135c
AB
390{
391 int err = 0;
392 struct ubi_volume_desc *desc = file->private_data;
393 struct ubi_volume *vol = desc->vol;
394 struct ubi_device *ubi = vol->ubi;
395 void __user *argp = (void __user *)arg;
396
801c135c 397 switch (cmd) {
801c135c
AB
398 /* Volume update command */
399 case UBI_IOCVOLUP:
400 {
401 int64_t bytes, rsvd_bytes;
402
403 if (!capable(CAP_SYS_RESOURCE)) {
404 err = -EPERM;
405 break;
406 }
407
408 err = copy_from_user(&bytes, argp, sizeof(int64_t));
409 if (err) {
410 err = -EFAULT;
411 break;
412 }
413
414 if (desc->mode == UBI_READONLY) {
415 err = -EROFS;
416 break;
417 }
418
73789a3d
BL
419 rsvd_bytes = (long long)vol->reserved_pebs *
420 ubi->leb_size-vol->data_pad;
801c135c
AB
421 if (bytes < 0 || bytes > rsvd_bytes) {
422 err = -EINVAL;
423 break;
424 }
425
32608703 426 err = get_exclusive(ubi, desc);
801c135c
AB
427 if (err < 0)
428 break;
429
1b68d0ee 430 err = ubi_start_update(ubi, vol, bytes);
fda322a1
EG
431 if (bytes == 0) {
432 ubi_volume_notify(ubi, vol, UBI_VOLUME_UPDATED);
801c135c 433 revoke_exclusive(desc, UBI_READWRITE);
fda322a1 434 }
801c135c
AB
435 break;
436 }
437
e653879c
AB
438 /* Atomic logical eraseblock change command */
439 case UBI_IOCEBCH:
440 {
441 struct ubi_leb_change_req req;
442
443 err = copy_from_user(&req, argp,
444 sizeof(struct ubi_leb_change_req));
445 if (err) {
446 err = -EFAULT;
447 break;
448 }
449
450 if (desc->mode == UBI_READONLY ||
451 vol->vol_type == UBI_STATIC_VOLUME) {
452 err = -EROFS;
453 break;
454 }
455
456 /* Validate the request */
457 err = -EINVAL;
458 if (req.lnum < 0 || req.lnum >= vol->reserved_pebs ||
459 req.bytes < 0 || req.lnum >= vol->usable_leb_size)
460 break;
e653879c 461
32608703 462 err = get_exclusive(ubi, desc);
e653879c
AB
463 if (err < 0)
464 break;
465
466 err = ubi_start_leb_change(ubi, vol, &req);
467 if (req.bytes == 0)
468 revoke_exclusive(desc, UBI_READWRITE);
469 break;
470 }
471
801c135c
AB
472 /* Logical eraseblock erasure command */
473 case UBI_IOCEBER:
474 {
475 int32_t lnum;
476
bf07803a 477 err = get_user(lnum, (__user int32_t *)argp);
801c135c
AB
478 if (err) {
479 err = -EFAULT;
480 break;
481 }
482
e653879c
AB
483 if (desc->mode == UBI_READONLY ||
484 vol->vol_type == UBI_STATIC_VOLUME) {
801c135c
AB
485 err = -EROFS;
486 break;
487 }
488
489 if (lnum < 0 || lnum >= vol->reserved_pebs) {
490 err = -EINVAL;
491 break;
492 }
493
c8566350 494 dbg_gen("erase LEB %d:%d", vol->vol_id, lnum);
89b96b69 495 err = ubi_eba_unmap_leb(ubi, vol, lnum);
801c135c
AB
496 if (err)
497 break;
498
62f38455 499 err = ubi_wl_flush(ubi, UBI_ALL, UBI_ALL);
801c135c
AB
500 break;
501 }
141e6ebd
CC
502
503 /* Logical eraseblock map command */
504 case UBI_IOCEBMAP:
505 {
506 struct ubi_map_req req;
507
508 err = copy_from_user(&req, argp, sizeof(struct ubi_map_req));
509 if (err) {
510 err = -EFAULT;
511 break;
512 }
b36a261e 513 err = ubi_leb_map(desc, req.lnum);
141e6ebd
CC
514 break;
515 }
c3da23be
CC
516
517 /* Logical eraseblock un-map command */
518 case UBI_IOCEBUNMAP:
519 {
520 int32_t lnum;
521
522 err = get_user(lnum, (__user int32_t *)argp);
523 if (err) {
524 err = -EFAULT;
525 break;
526 }
527 err = ubi_leb_unmap(desc, lnum);
528 break;
529 }
a27ce8f5
CC
530
531 /* Check if logical eraseblock is mapped command */
532 case UBI_IOCEBISMAP:
533 {
534 int32_t lnum;
535
536 err = get_user(lnum, (__user int32_t *)argp);
537 if (err) {
538 err = -EFAULT;
539 break;
540 }
541 err = ubi_is_mapped(desc, lnum);
542 break;
543 }
801c135c 544
f089c0b2 545 /* Set volume property command */
6748482f 546 case UBI_IOCSETVOLPROP:
766fb95b 547 {
6748482f 548 struct ubi_set_vol_prop_req req;
766fb95b
SA
549
550 err = copy_from_user(&req, argp,
6748482f 551 sizeof(struct ubi_set_vol_prop_req));
766fb95b
SA
552 if (err) {
553 err = -EFAULT;
554 break;
555 }
556 switch (req.property) {
6748482f 557 case UBI_VOL_PROP_DIRECT_WRITE:
f089c0b2 558 mutex_lock(&ubi->device_mutex);
766fb95b 559 desc->vol->direct_writes = !!req.value;
f089c0b2 560 mutex_unlock(&ubi->device_mutex);
766fb95b
SA
561 break;
562 default:
563 err = -EINVAL;
564 break;
565 }
566 break;
567 }
568
8af87188
AB
569 /* Create a R/O block device on top of the UBI volume */
570 case UBI_IOCVOLCRBLK:
9d54c8a3
EG
571 {
572 struct ubi_volume_info vi;
573
574 ubi_get_volume_info(desc, &vi);
4d283ee2 575 err = ubiblock_create(&vi);
9d54c8a3
EG
576 break;
577 }
578
8af87188
AB
579 /* Remove the R/O block device */
580 case UBI_IOCVOLRMBLK:
9d54c8a3
EG
581 {
582 struct ubi_volume_info vi;
583
584 ubi_get_volume_info(desc, &vi);
4d283ee2 585 err = ubiblock_remove(&vi);
9d54c8a3
EG
586 break;
587 }
588
801c135c
AB
589 default:
590 err = -ENOTTY;
591 break;
592 }
801c135c
AB
593 return err;
594}
595
596/**
597 * verify_mkvol_req - verify volume creation request.
598 * @ubi: UBI device description object
599 * @req: the request to check
600 *
601 * This function zero if the request is correct, and %-EINVAL if not.
602 */
603static int verify_mkvol_req(const struct ubi_device *ubi,
604 const struct ubi_mkvol_req *req)
605{
606 int n, err = -EINVAL;
607
608 if (req->bytes < 0 || req->alignment < 0 || req->vol_type < 0 ||
609 req->name_len < 0)
610 goto bad;
611
612 if ((req->vol_id < 0 || req->vol_id >= ubi->vtbl_slots) &&
613 req->vol_id != UBI_VOL_NUM_AUTO)
614 goto bad;
615
616 if (req->alignment == 0)
617 goto bad;
618
619 if (req->bytes == 0)
620 goto bad;
621
622 if (req->vol_type != UBI_DYNAMIC_VOLUME &&
623 req->vol_type != UBI_STATIC_VOLUME)
624 goto bad;
625
626 if (req->alignment > ubi->leb_size)
627 goto bad;
628
cadb40cc 629 n = req->alignment & (ubi->min_io_size - 1);
801c135c
AB
630 if (req->alignment != 1 && n)
631 goto bad;
632
4a59c797
RW
633 if (!req->name[0] || !req->name_len)
634 goto bad;
635
801c135c
AB
636 if (req->name_len > UBI_VOL_NAME_MAX) {
637 err = -ENAMETOOLONG;
638 goto bad;
639 }
640
a6ea4407
AB
641 n = strnlen(req->name, req->name_len + 1);
642 if (n != req->name_len)
643 goto bad;
644
801c135c
AB
645 return 0;
646
647bad:
32608703 648 ubi_err(ubi, "bad volume creation request");
718c00bb 649 ubi_dump_mkvol_req(req);
801c135c
AB
650 return err;
651}
652
653/**
654 * verify_rsvol_req - verify volume re-size request.
655 * @ubi: UBI device description object
656 * @req: the request to check
657 *
658 * This function returns zero if the request is correct, and %-EINVAL if not.
659 */
660static int verify_rsvol_req(const struct ubi_device *ubi,
661 const struct ubi_rsvol_req *req)
662{
663 if (req->bytes <= 0)
664 return -EINVAL;
665
666 if (req->vol_id < 0 || req->vol_id >= ubi->vtbl_slots)
667 return -EINVAL;
668
669 return 0;
670}
671
f40ac9cd
AB
672/**
673 * rename_volumes - rename UBI volumes.
674 * @ubi: UBI device description object
675 * @req: volumes re-name request
676 *
677 * This is a helper function for the volume re-name IOCTL which validates the
678 * the request, opens the volume and calls corresponding volumes management
679 * function. Returns zero in case of success and a negative error code in case
680 * of failure.
681 */
682static int rename_volumes(struct ubi_device *ubi,
683 struct ubi_rnvol_req *req)
684{
685 int i, n, err;
686 struct list_head rename_list;
687 struct ubi_rename_entry *re, *re1;
688
689 if (req->count < 0 || req->count > UBI_MAX_RNVOL)
690 return -EINVAL;
691
692 if (req->count == 0)
693 return 0;
694
695 /* Validate volume IDs and names in the request */
696 for (i = 0; i < req->count; i++) {
697 if (req->ents[i].vol_id < 0 ||
698 req->ents[i].vol_id >= ubi->vtbl_slots)
699 return -EINVAL;
700 if (req->ents[i].name_len < 0)
701 return -EINVAL;
702 if (req->ents[i].name_len > UBI_VOL_NAME_MAX)
703 return -ENAMETOOLONG;
704 req->ents[i].name[req->ents[i].name_len] = '\0';
705 n = strlen(req->ents[i].name);
706 if (n != req->ents[i].name_len)
7fbbd057 707 return -EINVAL;
f40ac9cd
AB
708 }
709
710 /* Make sure volume IDs and names are unique */
711 for (i = 0; i < req->count - 1; i++) {
712 for (n = i + 1; n < req->count; n++) {
713 if (req->ents[i].vol_id == req->ents[n].vol_id) {
32608703 714 ubi_err(ubi, "duplicated volume id %d",
f40ac9cd
AB
715 req->ents[i].vol_id);
716 return -EINVAL;
717 }
718 if (!strcmp(req->ents[i].name, req->ents[n].name)) {
32608703 719 ubi_err(ubi, "duplicated volume name \"%s\"",
f40ac9cd
AB
720 req->ents[i].name);
721 return -EINVAL;
722 }
723 }
724 }
725
726 /* Create the re-name list */
727 INIT_LIST_HEAD(&rename_list);
728 for (i = 0; i < req->count; i++) {
729 int vol_id = req->ents[i].vol_id;
730 int name_len = req->ents[i].name_len;
731 const char *name = req->ents[i].name;
732
733 re = kzalloc(sizeof(struct ubi_rename_entry), GFP_KERNEL);
734 if (!re) {
735 err = -ENOMEM;
736 goto out_free;
737 }
738
892abde5 739 re->desc = ubi_open_volume(ubi->ubi_num, vol_id, UBI_METAONLY);
f40ac9cd
AB
740 if (IS_ERR(re->desc)) {
741 err = PTR_ERR(re->desc);
32608703
TB
742 ubi_err(ubi, "cannot open volume %d, error %d",
743 vol_id, err);
f40ac9cd
AB
744 kfree(re);
745 goto out_free;
746 }
747
748 /* Skip this re-naming if the name does not really change */
749 if (re->desc->vol->name_len == name_len &&
750 !memcmp(re->desc->vol->name, name, name_len)) {
751 ubi_close_volume(re->desc);
752 kfree(re);
753 continue;
754 }
755
756 re->new_name_len = name_len;
757 memcpy(re->new_name, name, name_len);
758 list_add_tail(&re->list, &rename_list);
719bb840 759 dbg_gen("will rename volume %d from \"%s\" to \"%s\"",
f40ac9cd
AB
760 vol_id, re->desc->vol->name, name);
761 }
762
763 if (list_empty(&rename_list))
764 return 0;
765
766 /* Find out the volumes which have to be removed */
767 list_for_each_entry(re, &rename_list, list) {
768 struct ubi_volume_desc *desc;
769 int no_remove_needed = 0;
770
771 /*
772 * Volume @re->vol_id is going to be re-named to
773 * @re->new_name, while its current name is @name. If a volume
774 * with name @re->new_name currently exists, it has to be
775 * removed, unless it is also re-named in the request (@req).
776 */
777 list_for_each_entry(re1, &rename_list, list) {
778 if (re->new_name_len == re1->desc->vol->name_len &&
779 !memcmp(re->new_name, re1->desc->vol->name,
780 re1->desc->vol->name_len)) {
781 no_remove_needed = 1;
782 break;
783 }
784 }
785
786 if (no_remove_needed)
787 continue;
788
789 /*
790 * It seems we need to remove volume with name @re->new_name,
791 * if it exists.
792 */
f2863c54
AB
793 desc = ubi_open_volume_nm(ubi->ubi_num, re->new_name,
794 UBI_EXCLUSIVE);
f40ac9cd
AB
795 if (IS_ERR(desc)) {
796 err = PTR_ERR(desc);
797 if (err == -ENODEV)
798 /* Re-naming into a non-existing volume name */
799 continue;
800
801 /* The volume exists but busy, or an error occurred */
32608703 802 ubi_err(ubi, "cannot open volume \"%s\", error %d",
f40ac9cd
AB
803 re->new_name, err);
804 goto out_free;
805 }
806
01ebc12f
JL
807 re1 = kzalloc(sizeof(struct ubi_rename_entry), GFP_KERNEL);
808 if (!re1) {
f40ac9cd
AB
809 err = -ENOMEM;
810 ubi_close_volume(desc);
811 goto out_free;
812 }
813
01ebc12f
JL
814 re1->remove = 1;
815 re1->desc = desc;
816 list_add(&re1->list, &rename_list);
719bb840 817 dbg_gen("will remove volume %d, name \"%s\"",
01ebc12f 818 re1->desc->vol->vol_id, re1->desc->vol->name);
f40ac9cd
AB
819 }
820
f089c0b2 821 mutex_lock(&ubi->device_mutex);
f40ac9cd 822 err = ubi_rename_volumes(ubi, &rename_list);
f089c0b2 823 mutex_unlock(&ubi->device_mutex);
f40ac9cd
AB
824
825out_free:
826 list_for_each_entry_safe(re, re1, &rename_list, list) {
827 ubi_close_volume(re->desc);
828 list_del(&re->list);
829 kfree(re);
830 }
831 return err;
832}
833
f429b2ea
AB
834static long ubi_cdev_ioctl(struct file *file, unsigned int cmd,
835 unsigned long arg)
801c135c
AB
836{
837 int err = 0;
838 struct ubi_device *ubi;
839 struct ubi_volume_desc *desc;
840 void __user *argp = (void __user *)arg;
841
801c135c
AB
842 if (!capable(CAP_SYS_RESOURCE))
843 return -EPERM;
844
f429b2ea 845 ubi = ubi_get_by_major(imajor(file->f_mapping->host));
e73f4459
AB
846 if (!ubi)
847 return -ENODEV;
801c135c
AB
848
849 switch (cmd) {
850 /* Create volume command */
851 case UBI_IOCMKVOL:
852 {
853 struct ubi_mkvol_req req;
854
c8566350 855 dbg_gen("create volume");
897a316c 856 err = copy_from_user(&req, argp, sizeof(struct ubi_mkvol_req));
801c135c
AB
857 if (err) {
858 err = -EFAULT;
859 break;
860 }
861
862 err = verify_mkvol_req(ubi, &req);
863 if (err)
864 break;
865
f089c0b2 866 mutex_lock(&ubi->device_mutex);
801c135c 867 err = ubi_create_volume(ubi, &req);
f089c0b2 868 mutex_unlock(&ubi->device_mutex);
801c135c
AB
869 if (err)
870 break;
871
bf07803a 872 err = put_user(req.vol_id, (__user int32_t *)argp);
801c135c
AB
873 if (err)
874 err = -EFAULT;
875
876 break;
877 }
878
879 /* Remove volume command */
880 case UBI_IOCRMVOL:
881 {
882 int vol_id;
883
c8566350 884 dbg_gen("remove volume");
bf07803a 885 err = get_user(vol_id, (__user int32_t *)argp);
801c135c
AB
886 if (err) {
887 err = -EFAULT;
888 break;
889 }
890
891 desc = ubi_open_volume(ubi->ubi_num, vol_id, UBI_EXCLUSIVE);
892 if (IS_ERR(desc)) {
893 err = PTR_ERR(desc);
894 break;
895 }
896
f089c0b2 897 mutex_lock(&ubi->device_mutex);
f40ac9cd 898 err = ubi_remove_volume(desc, 0);
f089c0b2 899 mutex_unlock(&ubi->device_mutex);
40e4d0c1 900
450f872a 901 /*
40e4d0c1
AB
902 * The volume is deleted (unless an error occurred), and the
903 * 'struct ubi_volume' object will be freed when
904 * 'ubi_close_volume()' will call 'put_device()'.
450f872a
AB
905 */
906 ubi_close_volume(desc);
801c135c
AB
907 break;
908 }
909
910 /* Re-size volume command */
911 case UBI_IOCRSVOL:
912 {
913 int pebs;
801c135c
AB
914 struct ubi_rsvol_req req;
915
c8566350 916 dbg_gen("re-size volume");
897a316c 917 err = copy_from_user(&req, argp, sizeof(struct ubi_rsvol_req));
801c135c
AB
918 if (err) {
919 err = -EFAULT;
920 break;
921 }
922
923 err = verify_rsvol_req(ubi, &req);
924 if (err)
925 break;
926
927 desc = ubi_open_volume(ubi->ubi_num, req.vol_id, UBI_EXCLUSIVE);
928 if (IS_ERR(desc)) {
929 err = PTR_ERR(desc);
930 break;
931 }
932
3013ee31
AB
933 pebs = div_u64(req.bytes + desc->vol->usable_leb_size - 1,
934 desc->vol->usable_leb_size);
801c135c 935
f089c0b2 936 mutex_lock(&ubi->device_mutex);
801c135c 937 err = ubi_resize_volume(desc, pebs);
f089c0b2 938 mutex_unlock(&ubi->device_mutex);
801c135c
AB
939 ubi_close_volume(desc);
940 break;
941 }
942
f40ac9cd
AB
943 /* Re-name volumes command */
944 case UBI_IOCRNVOL:
945 {
946 struct ubi_rnvol_req *req;
947
719bb840 948 dbg_gen("re-name volumes");
f40ac9cd
AB
949 req = kmalloc(sizeof(struct ubi_rnvol_req), GFP_KERNEL);
950 if (!req) {
951 err = -ENOMEM;
952 break;
953 };
954
955 err = copy_from_user(req, argp, sizeof(struct ubi_rnvol_req));
956 if (err) {
957 err = -EFAULT;
958 kfree(req);
959 break;
960 }
961
f40ac9cd 962 err = rename_volumes(ubi, req);
f40ac9cd
AB
963 kfree(req);
964 break;
965 }
966
801c135c
AB
967 default:
968 err = -ENOTTY;
969 break;
970 }
971
e73f4459 972 ubi_put_device(ubi);
801c135c
AB
973 return err;
974}
975
f429b2ea
AB
976static long ctrl_cdev_ioctl(struct file *file, unsigned int cmd,
977 unsigned long arg)
897a316c
AB
978{
979 int err = 0;
980 void __user *argp = (void __user *)arg;
981
982 if (!capable(CAP_SYS_RESOURCE))
983 return -EPERM;
984
985 switch (cmd) {
986 /* Attach an MTD device command */
987 case UBI_IOCATT:
988 {
989 struct ubi_attach_req req;
990 struct mtd_info *mtd;
991
c8566350 992 dbg_gen("attach MTD device");
897a316c
AB
993 err = copy_from_user(&req, argp, sizeof(struct ubi_attach_req));
994 if (err) {
995 err = -EFAULT;
996 break;
997 }
998
999 if (req.mtd_num < 0 ||
1000 (req.ubi_num < 0 && req.ubi_num != UBI_DEV_NUM_AUTO)) {
1001 err = -EINVAL;
1002 break;
1003 }
1004
1005 mtd = get_mtd_device(NULL, req.mtd_num);
1006 if (IS_ERR(mtd)) {
1007 err = PTR_ERR(mtd);
1008 break;
1009 }
1010
1011 /*
1012 * Note, further request verification is done by
1013 * 'ubi_attach_mtd_dev()'.
1014 */
1015 mutex_lock(&ubi_devices_mutex);
256334c3 1016 err = ubi_attach_mtd_dev(mtd, req.ubi_num, req.vid_hdr_offset,
db7e21c2 1017 req.max_beb_per1024);
897a316c
AB
1018 mutex_unlock(&ubi_devices_mutex);
1019 if (err < 0)
1020 put_mtd_device(mtd);
1021 else
1022 /* @err contains UBI device number */
1023 err = put_user(err, (__user int32_t *)argp);
1024
1025 break;
1026 }
1027
1028 /* Detach an MTD device command */
1029 case UBI_IOCDET:
1030 {
1031 int ubi_num;
1032
2ce7be1b 1033 dbg_gen("detach MTD device");
897a316c
AB
1034 err = get_user(ubi_num, (__user int32_t *)argp);
1035 if (err) {
1036 err = -EFAULT;
1037 break;
1038 }
1039
1040 mutex_lock(&ubi_devices_mutex);
1041 err = ubi_detach_mtd_dev(ubi_num, 0);
1042 mutex_unlock(&ubi_devices_mutex);
1043 break;
1044 }
1045
1046 default:
1047 err = -ENOTTY;
1048 break;
1049 }
1050
1051 return err;
1052}
1053
f429b2ea
AB
1054#ifdef CONFIG_COMPAT
1055static long vol_cdev_compat_ioctl(struct file *file, unsigned int cmd,
1056 unsigned long arg)
1057{
1058 unsigned long translated_arg = (unsigned long)compat_ptr(arg);
1059
1060 return vol_cdev_ioctl(file, cmd, translated_arg);
1061}
1062
1063static long ubi_cdev_compat_ioctl(struct file *file, unsigned int cmd,
1064 unsigned long arg)
1065{
1066 unsigned long translated_arg = (unsigned long)compat_ptr(arg);
1067
1068 return ubi_cdev_ioctl(file, cmd, translated_arg);
1069}
1070
1071static long ctrl_cdev_compat_ioctl(struct file *file, unsigned int cmd,
1072 unsigned long arg)
1073{
1074 unsigned long translated_arg = (unsigned long)compat_ptr(arg);
1075
1076 return ctrl_cdev_ioctl(file, cmd, translated_arg);
1077}
1078#else
1079#define vol_cdev_compat_ioctl NULL
1080#define ubi_cdev_compat_ioctl NULL
1081#define ctrl_cdev_compat_ioctl NULL
1082#endif
1083
1084/* UBI volume character device operations */
1085const struct file_operations ubi_vol_cdev_operations = {
1086 .owner = THIS_MODULE,
1087 .open = vol_cdev_open,
1088 .release = vol_cdev_release,
1089 .llseek = vol_cdev_llseek,
1090 .read = vol_cdev_read,
1091 .write = vol_cdev_write,
1b24bc3a 1092 .fsync = vol_cdev_fsync,
f429b2ea
AB
1093 .unlocked_ioctl = vol_cdev_ioctl,
1094 .compat_ioctl = vol_cdev_compat_ioctl,
9f961b57
AB
1095};
1096
801c135c 1097/* UBI character device operations */
4d187a88 1098const struct file_operations ubi_cdev_operations = {
f429b2ea
AB
1099 .owner = THIS_MODULE,
1100 .llseek = no_llseek,
1101 .unlocked_ioctl = ubi_cdev_ioctl,
1102 .compat_ioctl = ubi_cdev_compat_ioctl,
801c135c
AB
1103};
1104
f429b2ea
AB
1105/* UBI control character device operations */
1106const struct file_operations ubi_ctrl_cdev_operations = {
1107 .owner = THIS_MODULE,
1108 .unlocked_ioctl = ctrl_cdev_ioctl,
1109 .compat_ioctl = ctrl_cdev_compat_ioctl,
e10b376e 1110 .llseek = no_llseek,
801c135c 1111};
This page took 0.719754 seconds and 5 git commands to generate.