0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025 #include <linux/module.h>
0026 #include <linux/stat.h>
0027 #include <linux/slab.h>
0028 #include <linux/ioctl.h>
0029 #include <linux/capability.h>
0030 #include <linux/uaccess.h>
0031 #include <linux/compat.h>
0032 #include <linux/math64.h>
0033 #include <mtd/ubi-user.h>
0034 #include "ubi.h"
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044 static int get_exclusive(struct ubi_volume_desc *desc)
0045 {
0046 int users, err;
0047 struct ubi_volume *vol = desc->vol;
0048
0049 spin_lock(&vol->ubi->volumes_lock);
0050 users = vol->readers + vol->writers + vol->exclusive + vol->metaonly;
0051 ubi_assert(users > 0);
0052 if (users > 1) {
0053 ubi_err(vol->ubi, "%d users for volume %d", users, vol->vol_id);
0054 err = -EBUSY;
0055 } else {
0056 vol->readers = vol->writers = vol->metaonly = 0;
0057 vol->exclusive = 1;
0058 err = desc->mode;
0059 desc->mode = UBI_EXCLUSIVE;
0060 }
0061 spin_unlock(&vol->ubi->volumes_lock);
0062
0063 return err;
0064 }
0065
0066
0067
0068
0069
0070
0071 static void revoke_exclusive(struct ubi_volume_desc *desc, int mode)
0072 {
0073 struct ubi_volume *vol = desc->vol;
0074
0075 spin_lock(&vol->ubi->volumes_lock);
0076 ubi_assert(vol->readers == 0 && vol->writers == 0 && vol->metaonly == 0);
0077 ubi_assert(vol->exclusive == 1 && desc->mode == UBI_EXCLUSIVE);
0078 vol->exclusive = 0;
0079 if (mode == UBI_READONLY)
0080 vol->readers = 1;
0081 else if (mode == UBI_READWRITE)
0082 vol->writers = 1;
0083 else if (mode == UBI_METAONLY)
0084 vol->metaonly = 1;
0085 else
0086 vol->exclusive = 1;
0087 spin_unlock(&vol->ubi->volumes_lock);
0088
0089 desc->mode = mode;
0090 }
0091
0092 static int vol_cdev_open(struct inode *inode, struct file *file)
0093 {
0094 struct ubi_volume_desc *desc;
0095 int vol_id = iminor(inode) - 1, mode, ubi_num;
0096
0097 ubi_num = ubi_major2num(imajor(inode));
0098 if (ubi_num < 0)
0099 return ubi_num;
0100
0101 if (file->f_mode & FMODE_WRITE)
0102 mode = UBI_READWRITE;
0103 else
0104 mode = UBI_READONLY;
0105
0106 dbg_gen("open device %d, volume %d, mode %d",
0107 ubi_num, vol_id, mode);
0108
0109 desc = ubi_open_volume(ubi_num, vol_id, mode);
0110 if (IS_ERR(desc))
0111 return PTR_ERR(desc);
0112
0113 file->private_data = desc;
0114 return 0;
0115 }
0116
0117 static int vol_cdev_release(struct inode *inode, struct file *file)
0118 {
0119 struct ubi_volume_desc *desc = file->private_data;
0120 struct ubi_volume *vol = desc->vol;
0121
0122 dbg_gen("release device %d, volume %d, mode %d",
0123 vol->ubi->ubi_num, vol->vol_id, desc->mode);
0124
0125 if (vol->updating) {
0126 ubi_warn(vol->ubi, "update of volume %d not finished, volume is damaged",
0127 vol->vol_id);
0128 ubi_assert(!vol->changing_leb);
0129 vol->updating = 0;
0130 vfree(vol->upd_buf);
0131 } else if (vol->changing_leb) {
0132 dbg_gen("only %lld of %lld bytes received for atomic LEB change for volume %d:%d, cancel",
0133 vol->upd_received, vol->upd_bytes, vol->ubi->ubi_num,
0134 vol->vol_id);
0135 vol->changing_leb = 0;
0136 vfree(vol->upd_buf);
0137 }
0138
0139 ubi_close_volume(desc);
0140 return 0;
0141 }
0142
0143 static loff_t vol_cdev_llseek(struct file *file, loff_t offset, int origin)
0144 {
0145 struct ubi_volume_desc *desc = file->private_data;
0146 struct ubi_volume *vol = desc->vol;
0147
0148 if (vol->updating) {
0149
0150 ubi_err(vol->ubi, "updating");
0151 return -EBUSY;
0152 }
0153
0154 return fixed_size_llseek(file, offset, origin, vol->used_bytes);
0155 }
0156
0157 static int vol_cdev_fsync(struct file *file, loff_t start, loff_t end,
0158 int datasync)
0159 {
0160 struct ubi_volume_desc *desc = file->private_data;
0161 struct ubi_device *ubi = desc->vol->ubi;
0162 struct inode *inode = file_inode(file);
0163 int err;
0164 inode_lock(inode);
0165 err = ubi_sync(ubi->ubi_num);
0166 inode_unlock(inode);
0167 return err;
0168 }
0169
0170
0171 static ssize_t vol_cdev_read(struct file *file, __user char *buf, size_t count,
0172 loff_t *offp)
0173 {
0174 struct ubi_volume_desc *desc = file->private_data;
0175 struct ubi_volume *vol = desc->vol;
0176 struct ubi_device *ubi = vol->ubi;
0177 int err, lnum, off, len, tbuf_size;
0178 size_t count_save = count;
0179 void *tbuf;
0180
0181 dbg_gen("read %zd bytes from offset %lld of volume %d",
0182 count, *offp, vol->vol_id);
0183
0184 if (vol->updating) {
0185 ubi_err(vol->ubi, "updating");
0186 return -EBUSY;
0187 }
0188 if (vol->upd_marker) {
0189 ubi_err(vol->ubi, "damaged volume, update marker is set");
0190 return -EBADF;
0191 }
0192 if (*offp == vol->used_bytes || count == 0)
0193 return 0;
0194
0195 if (vol->corrupted)
0196 dbg_gen("read from corrupted volume %d", vol->vol_id);
0197
0198 if (*offp + count > vol->used_bytes)
0199 count_save = count = vol->used_bytes - *offp;
0200
0201 tbuf_size = vol->usable_leb_size;
0202 if (count < tbuf_size)
0203 tbuf_size = ALIGN(count, ubi->min_io_size);
0204 tbuf = vmalloc(tbuf_size);
0205 if (!tbuf)
0206 return -ENOMEM;
0207
0208 len = count > tbuf_size ? tbuf_size : count;
0209 lnum = div_u64_rem(*offp, vol->usable_leb_size, &off);
0210
0211 do {
0212 cond_resched();
0213
0214 if (off + len >= vol->usable_leb_size)
0215 len = vol->usable_leb_size - off;
0216
0217 err = ubi_eba_read_leb(ubi, vol, lnum, tbuf, off, len, 0);
0218 if (err)
0219 break;
0220
0221 off += len;
0222 if (off == vol->usable_leb_size) {
0223 lnum += 1;
0224 off -= vol->usable_leb_size;
0225 }
0226
0227 count -= len;
0228 *offp += len;
0229
0230 err = copy_to_user(buf, tbuf, len);
0231 if (err) {
0232 err = -EFAULT;
0233 break;
0234 }
0235
0236 buf += len;
0237 len = count > tbuf_size ? tbuf_size : count;
0238 } while (count);
0239
0240 vfree(tbuf);
0241 return err ? err : count_save - count;
0242 }
0243
0244
0245
0246
0247
0248 static ssize_t vol_cdev_direct_write(struct file *file, const char __user *buf,
0249 size_t count, loff_t *offp)
0250 {
0251 struct ubi_volume_desc *desc = file->private_data;
0252 struct ubi_volume *vol = desc->vol;
0253 struct ubi_device *ubi = vol->ubi;
0254 int lnum, off, len, tbuf_size, err = 0;
0255 size_t count_save = count;
0256 char *tbuf;
0257
0258 if (!vol->direct_writes)
0259 return -EPERM;
0260
0261 dbg_gen("requested: write %zd bytes to offset %lld of volume %u",
0262 count, *offp, vol->vol_id);
0263
0264 if (vol->vol_type == UBI_STATIC_VOLUME)
0265 return -EROFS;
0266
0267 lnum = div_u64_rem(*offp, vol->usable_leb_size, &off);
0268 if (off & (ubi->min_io_size - 1)) {
0269 ubi_err(ubi, "unaligned position");
0270 return -EINVAL;
0271 }
0272
0273 if (*offp + count > vol->used_bytes)
0274 count_save = count = vol->used_bytes - *offp;
0275
0276
0277 if (count & (ubi->min_io_size - 1)) {
0278 ubi_err(ubi, "unaligned write length");
0279 return -EINVAL;
0280 }
0281
0282 tbuf_size = vol->usable_leb_size;
0283 if (count < tbuf_size)
0284 tbuf_size = ALIGN(count, ubi->min_io_size);
0285 tbuf = vmalloc(tbuf_size);
0286 if (!tbuf)
0287 return -ENOMEM;
0288
0289 len = count > tbuf_size ? tbuf_size : count;
0290
0291 while (count) {
0292 cond_resched();
0293
0294 if (off + len >= vol->usable_leb_size)
0295 len = vol->usable_leb_size - off;
0296
0297 err = copy_from_user(tbuf, buf, len);
0298 if (err) {
0299 err = -EFAULT;
0300 break;
0301 }
0302
0303 err = ubi_eba_write_leb(ubi, vol, lnum, tbuf, off, len);
0304 if (err)
0305 break;
0306
0307 off += len;
0308 if (off == vol->usable_leb_size) {
0309 lnum += 1;
0310 off -= vol->usable_leb_size;
0311 }
0312
0313 count -= len;
0314 *offp += len;
0315 buf += len;
0316 len = count > tbuf_size ? tbuf_size : count;
0317 }
0318
0319 vfree(tbuf);
0320 return err ? err : count_save - count;
0321 }
0322
0323 static ssize_t vol_cdev_write(struct file *file, const char __user *buf,
0324 size_t count, loff_t *offp)
0325 {
0326 int err = 0;
0327 struct ubi_volume_desc *desc = file->private_data;
0328 struct ubi_volume *vol = desc->vol;
0329 struct ubi_device *ubi = vol->ubi;
0330
0331 if (!vol->updating && !vol->changing_leb)
0332 return vol_cdev_direct_write(file, buf, count, offp);
0333
0334 if (vol->updating)
0335 err = ubi_more_update_data(ubi, vol, buf, count);
0336 else
0337 err = ubi_more_leb_change_data(ubi, vol, buf, count);
0338
0339 if (err < 0) {
0340 ubi_err(ubi, "cannot accept more %zd bytes of data, error %d",
0341 count, err);
0342 return err;
0343 }
0344
0345 if (err) {
0346
0347
0348
0349
0350 count = err;
0351
0352 if (vol->changing_leb) {
0353 revoke_exclusive(desc, UBI_READWRITE);
0354 return count;
0355 }
0356
0357
0358
0359
0360
0361 err = ubi_check_volume(ubi, vol->vol_id);
0362 if (err < 0)
0363 return err;
0364
0365 if (err) {
0366 ubi_warn(ubi, "volume %d on UBI device %d is corrupted",
0367 vol->vol_id, ubi->ubi_num);
0368 vol->corrupted = 1;
0369 }
0370 vol->checked = 1;
0371 ubi_volume_notify(ubi, vol, UBI_VOLUME_UPDATED);
0372 revoke_exclusive(desc, UBI_READWRITE);
0373 }
0374
0375 return count;
0376 }
0377
0378 static long vol_cdev_ioctl(struct file *file, unsigned int cmd,
0379 unsigned long arg)
0380 {
0381 int err = 0;
0382 struct ubi_volume_desc *desc = file->private_data;
0383 struct ubi_volume *vol = desc->vol;
0384 struct ubi_device *ubi = vol->ubi;
0385 void __user *argp = (void __user *)arg;
0386
0387 switch (cmd) {
0388
0389 case UBI_IOCVOLUP:
0390 {
0391 int64_t bytes, rsvd_bytes;
0392
0393 if (!capable(CAP_SYS_RESOURCE)) {
0394 err = -EPERM;
0395 break;
0396 }
0397
0398 err = copy_from_user(&bytes, argp, sizeof(int64_t));
0399 if (err) {
0400 err = -EFAULT;
0401 break;
0402 }
0403
0404 if (desc->mode == UBI_READONLY) {
0405 err = -EROFS;
0406 break;
0407 }
0408
0409 rsvd_bytes = (long long)vol->reserved_pebs *
0410 vol->usable_leb_size;
0411 if (bytes < 0 || bytes > rsvd_bytes) {
0412 err = -EINVAL;
0413 break;
0414 }
0415
0416 err = get_exclusive(desc);
0417 if (err < 0)
0418 break;
0419
0420 err = ubi_start_update(ubi, vol, bytes);
0421 if (bytes == 0) {
0422 ubi_volume_notify(ubi, vol, UBI_VOLUME_UPDATED);
0423 revoke_exclusive(desc, UBI_READWRITE);
0424 }
0425 break;
0426 }
0427
0428
0429 case UBI_IOCEBCH:
0430 {
0431 struct ubi_leb_change_req req;
0432
0433 err = copy_from_user(&req, argp,
0434 sizeof(struct ubi_leb_change_req));
0435 if (err) {
0436 err = -EFAULT;
0437 break;
0438 }
0439
0440 if (desc->mode == UBI_READONLY ||
0441 vol->vol_type == UBI_STATIC_VOLUME) {
0442 err = -EROFS;
0443 break;
0444 }
0445
0446
0447 err = -EINVAL;
0448 if (!ubi_leb_valid(vol, req.lnum) ||
0449 req.bytes < 0 || req.bytes > vol->usable_leb_size)
0450 break;
0451
0452 err = get_exclusive(desc);
0453 if (err < 0)
0454 break;
0455
0456 err = ubi_start_leb_change(ubi, vol, &req);
0457 if (req.bytes == 0)
0458 revoke_exclusive(desc, UBI_READWRITE);
0459 break;
0460 }
0461
0462
0463 case UBI_IOCEBER:
0464 {
0465 int32_t lnum;
0466
0467 err = get_user(lnum, (__user int32_t *)argp);
0468 if (err) {
0469 err = -EFAULT;
0470 break;
0471 }
0472
0473 if (desc->mode == UBI_READONLY ||
0474 vol->vol_type == UBI_STATIC_VOLUME) {
0475 err = -EROFS;
0476 break;
0477 }
0478
0479 if (!ubi_leb_valid(vol, lnum)) {
0480 err = -EINVAL;
0481 break;
0482 }
0483
0484 dbg_gen("erase LEB %d:%d", vol->vol_id, lnum);
0485 err = ubi_eba_unmap_leb(ubi, vol, lnum);
0486 if (err)
0487 break;
0488
0489 err = ubi_wl_flush(ubi, UBI_ALL, UBI_ALL);
0490 break;
0491 }
0492
0493
0494 case UBI_IOCEBMAP:
0495 {
0496 struct ubi_map_req req;
0497
0498 err = copy_from_user(&req, argp, sizeof(struct ubi_map_req));
0499 if (err) {
0500 err = -EFAULT;
0501 break;
0502 }
0503 err = ubi_leb_map(desc, req.lnum);
0504 break;
0505 }
0506
0507
0508 case UBI_IOCEBUNMAP:
0509 {
0510 int32_t lnum;
0511
0512 err = get_user(lnum, (__user int32_t *)argp);
0513 if (err) {
0514 err = -EFAULT;
0515 break;
0516 }
0517 err = ubi_leb_unmap(desc, lnum);
0518 break;
0519 }
0520
0521
0522 case UBI_IOCEBISMAP:
0523 {
0524 int32_t lnum;
0525
0526 err = get_user(lnum, (__user int32_t *)argp);
0527 if (err) {
0528 err = -EFAULT;
0529 break;
0530 }
0531 err = ubi_is_mapped(desc, lnum);
0532 break;
0533 }
0534
0535
0536 case UBI_IOCSETVOLPROP:
0537 {
0538 struct ubi_set_vol_prop_req req;
0539
0540 err = copy_from_user(&req, argp,
0541 sizeof(struct ubi_set_vol_prop_req));
0542 if (err) {
0543 err = -EFAULT;
0544 break;
0545 }
0546 switch (req.property) {
0547 case UBI_VOL_PROP_DIRECT_WRITE:
0548 mutex_lock(&ubi->device_mutex);
0549 desc->vol->direct_writes = !!req.value;
0550 mutex_unlock(&ubi->device_mutex);
0551 break;
0552 default:
0553 err = -EINVAL;
0554 break;
0555 }
0556 break;
0557 }
0558
0559
0560 case UBI_IOCVOLCRBLK:
0561 {
0562 struct ubi_volume_info vi;
0563
0564 ubi_get_volume_info(desc, &vi);
0565 err = ubiblock_create(&vi);
0566 break;
0567 }
0568
0569
0570 case UBI_IOCVOLRMBLK:
0571 {
0572 struct ubi_volume_info vi;
0573
0574 ubi_get_volume_info(desc, &vi);
0575 err = ubiblock_remove(&vi);
0576 break;
0577 }
0578
0579 default:
0580 err = -ENOTTY;
0581 break;
0582 }
0583 return err;
0584 }
0585
0586
0587
0588
0589
0590
0591
0592
0593 static int verify_mkvol_req(const struct ubi_device *ubi,
0594 const struct ubi_mkvol_req *req)
0595 {
0596 int n, err = -EINVAL;
0597
0598 if (req->bytes < 0 || req->alignment < 0 || req->vol_type < 0 ||
0599 req->name_len < 0)
0600 goto bad;
0601
0602 if ((req->vol_id < 0 || req->vol_id >= ubi->vtbl_slots) &&
0603 req->vol_id != UBI_VOL_NUM_AUTO)
0604 goto bad;
0605
0606 if (req->alignment == 0)
0607 goto bad;
0608
0609 if (req->bytes == 0)
0610 goto bad;
0611
0612 if (req->vol_type != UBI_DYNAMIC_VOLUME &&
0613 req->vol_type != UBI_STATIC_VOLUME)
0614 goto bad;
0615
0616 if (req->flags & ~UBI_VOL_VALID_FLGS)
0617 goto bad;
0618
0619 if (req->flags & UBI_VOL_SKIP_CRC_CHECK_FLG &&
0620 req->vol_type != UBI_STATIC_VOLUME)
0621 goto bad;
0622
0623 if (req->alignment > ubi->leb_size)
0624 goto bad;
0625
0626 n = req->alignment & (ubi->min_io_size - 1);
0627 if (req->alignment != 1 && n)
0628 goto bad;
0629
0630 if (!req->name[0] || !req->name_len)
0631 goto bad;
0632
0633 if (req->name_len > UBI_VOL_NAME_MAX) {
0634 err = -ENAMETOOLONG;
0635 goto bad;
0636 }
0637
0638 n = strnlen(req->name, req->name_len + 1);
0639 if (n != req->name_len)
0640 goto bad;
0641
0642 return 0;
0643
0644 bad:
0645 ubi_err(ubi, "bad volume creation request");
0646 ubi_dump_mkvol_req(req);
0647 return err;
0648 }
0649
0650
0651
0652
0653
0654
0655
0656
0657 static int verify_rsvol_req(const struct ubi_device *ubi,
0658 const struct ubi_rsvol_req *req)
0659 {
0660 if (req->bytes <= 0)
0661 return -EINVAL;
0662
0663 if (req->vol_id < 0 || req->vol_id >= ubi->vtbl_slots)
0664 return -EINVAL;
0665
0666 return 0;
0667 }
0668
0669
0670
0671
0672
0673
0674
0675
0676
0677
0678
0679 static int rename_volumes(struct ubi_device *ubi,
0680 struct ubi_rnvol_req *req)
0681 {
0682 int i, n, err;
0683 struct list_head rename_list;
0684 struct ubi_rename_entry *re, *re1;
0685
0686 if (req->count < 0 || req->count > UBI_MAX_RNVOL)
0687 return -EINVAL;
0688
0689 if (req->count == 0)
0690 return 0;
0691
0692
0693 for (i = 0; i < req->count; i++) {
0694 if (req->ents[i].vol_id < 0 ||
0695 req->ents[i].vol_id >= ubi->vtbl_slots)
0696 return -EINVAL;
0697 if (req->ents[i].name_len < 0)
0698 return -EINVAL;
0699 if (req->ents[i].name_len > UBI_VOL_NAME_MAX)
0700 return -ENAMETOOLONG;
0701 req->ents[i].name[req->ents[i].name_len] = '\0';
0702 n = strlen(req->ents[i].name);
0703 if (n != req->ents[i].name_len)
0704 return -EINVAL;
0705 }
0706
0707
0708 for (i = 0; i < req->count - 1; i++) {
0709 for (n = i + 1; n < req->count; n++) {
0710 if (req->ents[i].vol_id == req->ents[n].vol_id) {
0711 ubi_err(ubi, "duplicated volume id %d",
0712 req->ents[i].vol_id);
0713 return -EINVAL;
0714 }
0715 if (!strcmp(req->ents[i].name, req->ents[n].name)) {
0716 ubi_err(ubi, "duplicated volume name \"%s\"",
0717 req->ents[i].name);
0718 return -EINVAL;
0719 }
0720 }
0721 }
0722
0723
0724 INIT_LIST_HEAD(&rename_list);
0725 for (i = 0; i < req->count; i++) {
0726 int vol_id = req->ents[i].vol_id;
0727 int name_len = req->ents[i].name_len;
0728 const char *name = req->ents[i].name;
0729
0730 re = kzalloc(sizeof(struct ubi_rename_entry), GFP_KERNEL);
0731 if (!re) {
0732 err = -ENOMEM;
0733 goto out_free;
0734 }
0735
0736 re->desc = ubi_open_volume(ubi->ubi_num, vol_id, UBI_METAONLY);
0737 if (IS_ERR(re->desc)) {
0738 err = PTR_ERR(re->desc);
0739 ubi_err(ubi, "cannot open volume %d, error %d",
0740 vol_id, err);
0741 kfree(re);
0742 goto out_free;
0743 }
0744
0745
0746 if (re->desc->vol->name_len == name_len &&
0747 !memcmp(re->desc->vol->name, name, name_len)) {
0748 ubi_close_volume(re->desc);
0749 kfree(re);
0750 continue;
0751 }
0752
0753 re->new_name_len = name_len;
0754 memcpy(re->new_name, name, name_len);
0755 list_add_tail(&re->list, &rename_list);
0756 dbg_gen("will rename volume %d from \"%s\" to \"%s\"",
0757 vol_id, re->desc->vol->name, name);
0758 }
0759
0760 if (list_empty(&rename_list))
0761 return 0;
0762
0763
0764 list_for_each_entry(re, &rename_list, list) {
0765 struct ubi_volume_desc *desc;
0766 int no_remove_needed = 0;
0767
0768
0769
0770
0771
0772
0773
0774 list_for_each_entry(re1, &rename_list, list) {
0775 if (re->new_name_len == re1->desc->vol->name_len &&
0776 !memcmp(re->new_name, re1->desc->vol->name,
0777 re1->desc->vol->name_len)) {
0778 no_remove_needed = 1;
0779 break;
0780 }
0781 }
0782
0783 if (no_remove_needed)
0784 continue;
0785
0786
0787
0788
0789
0790 desc = ubi_open_volume_nm(ubi->ubi_num, re->new_name,
0791 UBI_EXCLUSIVE);
0792 if (IS_ERR(desc)) {
0793 err = PTR_ERR(desc);
0794 if (err == -ENODEV)
0795
0796 continue;
0797
0798
0799 ubi_err(ubi, "cannot open volume \"%s\", error %d",
0800 re->new_name, err);
0801 goto out_free;
0802 }
0803
0804 re1 = kzalloc(sizeof(struct ubi_rename_entry), GFP_KERNEL);
0805 if (!re1) {
0806 err = -ENOMEM;
0807 ubi_close_volume(desc);
0808 goto out_free;
0809 }
0810
0811 re1->remove = 1;
0812 re1->desc = desc;
0813 list_add(&re1->list, &rename_list);
0814 dbg_gen("will remove volume %d, name \"%s\"",
0815 re1->desc->vol->vol_id, re1->desc->vol->name);
0816 }
0817
0818 mutex_lock(&ubi->device_mutex);
0819 err = ubi_rename_volumes(ubi, &rename_list);
0820 mutex_unlock(&ubi->device_mutex);
0821
0822 out_free:
0823 list_for_each_entry_safe(re, re1, &rename_list, list) {
0824 ubi_close_volume(re->desc);
0825 list_del(&re->list);
0826 kfree(re);
0827 }
0828 return err;
0829 }
0830
0831 static long ubi_cdev_ioctl(struct file *file, unsigned int cmd,
0832 unsigned long arg)
0833 {
0834 int err = 0;
0835 struct ubi_device *ubi;
0836 struct ubi_volume_desc *desc;
0837 void __user *argp = (void __user *)arg;
0838
0839 if (!capable(CAP_SYS_RESOURCE))
0840 return -EPERM;
0841
0842 ubi = ubi_get_by_major(imajor(file->f_mapping->host));
0843 if (!ubi)
0844 return -ENODEV;
0845
0846 switch (cmd) {
0847
0848 case UBI_IOCMKVOL:
0849 {
0850 struct ubi_mkvol_req req;
0851
0852 dbg_gen("create volume");
0853 err = copy_from_user(&req, argp, sizeof(struct ubi_mkvol_req));
0854 if (err) {
0855 err = -EFAULT;
0856 break;
0857 }
0858
0859 err = verify_mkvol_req(ubi, &req);
0860 if (err)
0861 break;
0862
0863 mutex_lock(&ubi->device_mutex);
0864 err = ubi_create_volume(ubi, &req);
0865 mutex_unlock(&ubi->device_mutex);
0866 if (err)
0867 break;
0868
0869 err = put_user(req.vol_id, (__user int32_t *)argp);
0870 if (err)
0871 err = -EFAULT;
0872
0873 break;
0874 }
0875
0876
0877 case UBI_IOCRMVOL:
0878 {
0879 int vol_id;
0880
0881 dbg_gen("remove volume");
0882 err = get_user(vol_id, (__user int32_t *)argp);
0883 if (err) {
0884 err = -EFAULT;
0885 break;
0886 }
0887
0888 desc = ubi_open_volume(ubi->ubi_num, vol_id, UBI_EXCLUSIVE);
0889 if (IS_ERR(desc)) {
0890 err = PTR_ERR(desc);
0891 break;
0892 }
0893
0894 mutex_lock(&ubi->device_mutex);
0895 err = ubi_remove_volume(desc, 0);
0896 mutex_unlock(&ubi->device_mutex);
0897
0898
0899
0900
0901
0902
0903 ubi_close_volume(desc);
0904 break;
0905 }
0906
0907
0908 case UBI_IOCRSVOL:
0909 {
0910 int pebs;
0911 struct ubi_rsvol_req req;
0912
0913 dbg_gen("re-size volume");
0914 err = copy_from_user(&req, argp, sizeof(struct ubi_rsvol_req));
0915 if (err) {
0916 err = -EFAULT;
0917 break;
0918 }
0919
0920 err = verify_rsvol_req(ubi, &req);
0921 if (err)
0922 break;
0923
0924 desc = ubi_open_volume(ubi->ubi_num, req.vol_id, UBI_EXCLUSIVE);
0925 if (IS_ERR(desc)) {
0926 err = PTR_ERR(desc);
0927 break;
0928 }
0929
0930 pebs = div_u64(req.bytes + desc->vol->usable_leb_size - 1,
0931 desc->vol->usable_leb_size);
0932
0933 mutex_lock(&ubi->device_mutex);
0934 err = ubi_resize_volume(desc, pebs);
0935 mutex_unlock(&ubi->device_mutex);
0936 ubi_close_volume(desc);
0937 break;
0938 }
0939
0940
0941 case UBI_IOCRNVOL:
0942 {
0943 struct ubi_rnvol_req *req;
0944
0945 dbg_gen("re-name volumes");
0946 req = kmalloc(sizeof(struct ubi_rnvol_req), GFP_KERNEL);
0947 if (!req) {
0948 err = -ENOMEM;
0949 break;
0950 }
0951
0952 err = copy_from_user(req, argp, sizeof(struct ubi_rnvol_req));
0953 if (err) {
0954 err = -EFAULT;
0955 kfree(req);
0956 break;
0957 }
0958
0959 err = rename_volumes(ubi, req);
0960 kfree(req);
0961 break;
0962 }
0963
0964
0965 case UBI_IOCRPEB:
0966 {
0967 int pnum;
0968
0969 err = get_user(pnum, (__user int32_t *)argp);
0970 if (err) {
0971 err = -EFAULT;
0972 break;
0973 }
0974
0975 err = ubi_bitflip_check(ubi, pnum, 0);
0976 break;
0977 }
0978
0979
0980 case UBI_IOCSPEB:
0981 {
0982 int pnum;
0983
0984 err = get_user(pnum, (__user int32_t *)argp);
0985 if (err) {
0986 err = -EFAULT;
0987 break;
0988 }
0989
0990 err = ubi_bitflip_check(ubi, pnum, 1);
0991 break;
0992 }
0993
0994 default:
0995 err = -ENOTTY;
0996 break;
0997 }
0998
0999 ubi_put_device(ubi);
1000 return err;
1001 }
1002
1003 static long ctrl_cdev_ioctl(struct file *file, unsigned int cmd,
1004 unsigned long arg)
1005 {
1006 int err = 0;
1007 void __user *argp = (void __user *)arg;
1008
1009 if (!capable(CAP_SYS_RESOURCE))
1010 return -EPERM;
1011
1012 switch (cmd) {
1013
1014 case UBI_IOCATT:
1015 {
1016 struct ubi_attach_req req;
1017 struct mtd_info *mtd;
1018
1019 dbg_gen("attach MTD device");
1020 err = copy_from_user(&req, argp, sizeof(struct ubi_attach_req));
1021 if (err) {
1022 err = -EFAULT;
1023 break;
1024 }
1025
1026 if (req.mtd_num < 0 ||
1027 (req.ubi_num < 0 && req.ubi_num != UBI_DEV_NUM_AUTO)) {
1028 err = -EINVAL;
1029 break;
1030 }
1031
1032 mtd = get_mtd_device(NULL, req.mtd_num);
1033 if (IS_ERR(mtd)) {
1034 err = PTR_ERR(mtd);
1035 break;
1036 }
1037
1038
1039
1040
1041
1042 mutex_lock(&ubi_devices_mutex);
1043 err = ubi_attach_mtd_dev(mtd, req.ubi_num, req.vid_hdr_offset,
1044 req.max_beb_per1024);
1045 mutex_unlock(&ubi_devices_mutex);
1046 if (err < 0)
1047 put_mtd_device(mtd);
1048 else
1049
1050 err = put_user(err, (__user int32_t *)argp);
1051
1052 break;
1053 }
1054
1055
1056 case UBI_IOCDET:
1057 {
1058 int ubi_num;
1059
1060 dbg_gen("detach MTD device");
1061 err = get_user(ubi_num, (__user int32_t *)argp);
1062 if (err) {
1063 err = -EFAULT;
1064 break;
1065 }
1066
1067 mutex_lock(&ubi_devices_mutex);
1068 err = ubi_detach_mtd_dev(ubi_num, 0);
1069 mutex_unlock(&ubi_devices_mutex);
1070 break;
1071 }
1072
1073 default:
1074 err = -ENOTTY;
1075 break;
1076 }
1077
1078 return err;
1079 }
1080
1081
1082 const struct file_operations ubi_vol_cdev_operations = {
1083 .owner = THIS_MODULE,
1084 .open = vol_cdev_open,
1085 .release = vol_cdev_release,
1086 .llseek = vol_cdev_llseek,
1087 .read = vol_cdev_read,
1088 .write = vol_cdev_write,
1089 .fsync = vol_cdev_fsync,
1090 .unlocked_ioctl = vol_cdev_ioctl,
1091 .compat_ioctl = compat_ptr_ioctl,
1092 };
1093
1094
1095 const struct file_operations ubi_cdev_operations = {
1096 .owner = THIS_MODULE,
1097 .llseek = no_llseek,
1098 .unlocked_ioctl = ubi_cdev_ioctl,
1099 .compat_ioctl = compat_ptr_ioctl,
1100 };
1101
1102
1103 const struct file_operations ubi_ctrl_cdev_operations = {
1104 .owner = THIS_MODULE,
1105 .unlocked_ioctl = ctrl_cdev_ioctl,
1106 .compat_ioctl = compat_ptr_ioctl,
1107 .llseek = no_llseek,
1108 };