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., 675 Mass Ave, Cambridge, MA 02139, USA. 17 * 18 * Author: Artem Bityutskiy 19 * 20 * UBI (Unsorted Block Images) library. 21 */ 22 23 #define PROGRAM_NAME "libubi" 24 25 #include <sys/sysmacros.h> 26 #include <stdlib.h> 27 #include <stdio.h> 28 #include <string.h> 29 #include <fcntl.h> 30 #include <dirent.h> 31 #include <unistd.h> 32 #include <limits.h> 33 #include <sys/ioctl.h> 34 #include <sys/stat.h> 35 #include <sys/types.h> 36 #include "libubi.h" 37 #include "libubi_int.h" 38 39 /** 40 * mkpath - compose full path from 2 given components. 41 * @path: the first component 42 * @name: the second component 43 * 44 * This function returns the resulting path in case of success and %NULL in 45 * case of failure. 46 */ 47 static char *mkpath(const char *path, const char *name) 48 { 49 char *n; 50 int len1 = strlen(path); 51 int len2 = strlen(name); 52 53 n = malloc(len1 + len2 + 2); 54 if (!n) { 55 sys_errmsg("cannot allocate %d bytes", len1 + len2 + 2); 56 return NULL; 57 } 58 59 memcpy(n, path, len1); 60 if (n[len1 - 1] != '/') 61 n[len1++] = '/'; 62 63 memcpy(n + len1, name, len2 + 1); 64 return n; 65 } 66 67 /** 68 * read_positive_ll - read a positive 'long long' value from a file. 69 * @file: the file to read from 70 * @value: the result is stored here 71 * 72 * This function reads file @file and interprets its contents as a positive 73 * 'long long' integer. If this is not true, it fails with %EINVAL error code. 74 * Returns %0 in case of success and %-1 in case of failure. 75 */ 76 static int read_positive_ll(const char *file, long long *value) 77 { 78 int fd, rd; 79 char buf[50]; 80 81 fd = open(file, O_RDONLY); 82 if (fd == -1) 83 return -1; 84 85 rd = read(fd, buf, sizeof(buf)); 86 if (rd == -1) { 87 sys_errmsg("cannot read \"%s\"", file); 88 goto out_error; 89 } 90 if (rd == sizeof(buf)) { 91 errmsg("contents of \"%s\" is too long", file); 92 errno = EINVAL; 93 goto out_error; 94 } 95 buf[rd] = '\0'; 96 97 if (sscanf(buf, "%lld\n", value) != 1) { 98 errmsg("cannot read integer from \"%s\"\n", file); 99 errno = EINVAL; 100 goto out_error; 101 } 102 103 if (*value < 0) { 104 errmsg("negative value %lld in \"%s\"", *value, file); 105 errno = EINVAL; 106 goto out_error; 107 } 108 109 if (close(fd)) { 110 sys_errmsg("close failed on \"%s\"", file); 111 return -1; 112 } 113 114 return 0; 115 116 out_error: 117 close(fd); 118 return -1; 119 } 120 121 /** 122 * read_positive_int - read a positive 'int' value from a file. 123 * @file: the file to read from 124 * @value: the result is stored here 125 * 126 * This function is the same as 'read_positive_ll()', but it reads an 'int' 127 * value, not 'long long'. 128 */ 129 static int read_positive_int(const char *file, int *value) 130 { 131 long long res; 132 133 if (read_positive_ll(file, &res)) 134 return -1; 135 136 /* Make sure the value is not too big */ 137 if (res > INT_MAX) { 138 errmsg("value %lld read from file \"%s\" is out of range", 139 res, file); 140 errno = EINVAL; 141 return -1; 142 } 143 144 *value = res; 145 return 0; 146 } 147 148 /** 149 * read_data - read data from a file. 150 * @file: the file to read from 151 * @buf: the buffer to read to 152 * @buf_len: buffer length 153 * 154 * This function returns number of read bytes in case of success and %-1 in 155 * case of failure. Note, if the file contains more then @buf_len bytes of 156 * date, this function fails with %EINVAL error code. 157 */ 158 static int read_data(const char *file, void *buf, int buf_len) 159 { 160 int fd, rd, tmp, tmp1; 161 162 fd = open(file, O_RDONLY); 163 if (fd == -1) 164 return -1; 165 166 rd = read(fd, buf, buf_len); 167 if (rd == -1) { 168 sys_errmsg("cannot read \"%s\"", file); 169 goto out_error; 170 } 171 172 if (rd == buf_len) { 173 errmsg("contents of \"%s\" is too long", file); 174 errno = EINVAL; 175 goto out_error; 176 } 177 178 ((char *)buf)[rd] = '\0'; 179 180 /* Make sure all data is read */ 181 tmp1 = read(fd, &tmp, 4); 182 if (tmp1 < 0) { 183 sys_errmsg("cannot read \"%s\"", file); 184 goto out_error; 185 } 186 if (tmp1) { 187 errmsg("file \"%s\" contains too much data (> %d bytes)", 188 file, buf_len); 189 errno = EINVAL; 190 goto out_error; 191 } 192 193 if (close(fd)) { 194 sys_errmsg("close failed on \"%s\"", file); 195 return -1; 196 } 197 198 return rd; 199 200 out_error: 201 close(fd); 202 return -1; 203 } 204 205 /** 206 * read_major - read major and minor numbers from a file. 207 * @file: name of the file to read from 208 * @major: major number is returned here 209 * @minor: minor number is returned here 210 * 211 * This function returns % in case of succes, and %-1 in case of failure. 212 */ 213 static int read_major(const char *file, int *major, int *minor) 214 { 215 int ret; 216 char buf[50]; 217 218 ret = read_data(file, buf, 50); 219 if (ret < 0) 220 return ret; 221 222 ret = sscanf(buf, "%d:%d\n", major, minor); 223 if (ret != 2) { 224 errno = EINVAL; 225 errmsg("\"%s\" does not have major:minor format", file); 226 return -1; 227 } 228 229 if (*major < 0 || *minor < 0) { 230 errno = EINVAL; 231 errmsg("bad major:minor %d:%d in \"%s\"", 232 *major, *minor, file); 233 return -1; 234 } 235 236 return 0; 237 } 238 239 /** 240 * dev_read_int - read a positive 'int' value from an UBI device sysfs file. 241 * @patt: file pattern to read from 242 * @dev_num: UBI device number 243 * @value: the result is stored here 244 * 245 * This function returns %0 in case of success and %-1 in case of failure. 246 */ 247 static int dev_read_int(const char *patt, int dev_num, int *value) 248 { 249 char file[strlen(patt) + 50]; 250 251 sprintf(file, patt, dev_num); 252 return read_positive_int(file, value); 253 } 254 255 /** 256 * vol_read_int - read a positive 'int' value from an UBI volume sysfs file. 257 * @patt: file pattern to read from 258 * @dev_num: UBI device number 259 * @vol_id: volume ID 260 * @value: the result is stored here 261 * 262 * This function returns %0 in case of success and %-1 in case of failure. 263 */ 264 static int vol_read_int(const char *patt, int dev_num, int vol_id, int *value) 265 { 266 char file[strlen(patt) + 100]; 267 268 sprintf(file, patt, dev_num, vol_id); 269 return read_positive_int(file, value); 270 } 271 272 /** 273 * dev_read_ll - read a positive 'long long' value from an UBI device sysfs file. 274 * @patt: file pattern to read from 275 * @dev_num: UBI device number 276 * @value: the result is stored here 277 * 278 * This function returns %0 in case of success and %-1 in case of failure. 279 */ 280 static int dev_read_ll(const char *patt, int dev_num, long long *value) 281 { 282 char file[strlen(patt) + 50]; 283 284 sprintf(file, patt, dev_num); 285 return read_positive_ll(file, value); 286 } 287 288 /** 289 * vol_read_ll - read a positive 'long long' value from an UBI volume sysfs file. 290 * @patt: file pattern to read from 291 * @dev_num: UBI device number 292 * @vol_id: volume ID 293 * @value: the result is stored here 294 * 295 * This function returns %0 in case of success and %-1 in case of failure. 296 */ 297 static int vol_read_ll(const char *patt, int dev_num, int vol_id, 298 long long *value) 299 { 300 char file[strlen(patt) + 100]; 301 302 sprintf(file, patt, dev_num, vol_id); 303 return read_positive_ll(file, value); 304 } 305 306 /** 307 * vol_read_data - read data from an UBI volume's sysfs file. 308 * @patt: file pattern to read from 309 * @dev_num: UBI device number 310 * @vol_id: volume ID 311 * @buf: buffer to read to 312 * @buf_len: buffer length 313 * 314 * This function returns number of read bytes in case of success and %-1 in 315 * case of failure. 316 */ 317 static int vol_read_data(const char *patt, int dev_num, int vol_id, void *buf, 318 int buf_len) 319 { 320 char file[strlen(patt) + 100]; 321 322 sprintf(file, patt, dev_num, vol_id); 323 return read_data(file, buf, buf_len); 324 } 325 326 /** 327 * dev_get_major - get major and minor numbers of an UBI device. 328 * @lib: libubi descriptor 329 * @dev_num: UBI device number 330 * @major: major number is returned here 331 * @minor: minor number is returned here 332 * 333 * This function returns zero in case of succes and %-1 in case of failure. 334 */ 335 static int dev_get_major(struct libubi *lib, int dev_num, int *major, int *minor) 336 { 337 char file[strlen(lib->dev_dev) + 50]; 338 339 sprintf(file, lib->dev_dev, dev_num); 340 return read_major(file, major, minor); 341 } 342 343 /** 344 * vol_get_major - get major and minor numbers of an UBI volume. 345 * @lib: libubi descriptor 346 * @dev_num: UBI device number 347 * @vol_id: volume ID 348 * @major: major number is returned here 349 * @minor: minor number is returned here 350 * 351 * This function returns zero in case of succes and %-1 in case of failure. 352 */ 353 static int vol_get_major(struct libubi *lib, int dev_num, int vol_id, 354 int *major, int *minor) 355 { 356 char file[strlen(lib->vol_dev) + 100]; 357 358 sprintf(file, lib->vol_dev, dev_num, vol_id); 359 return read_major(file, major, minor); 360 } 361 362 /** 363 * vol_node2nums - find UBI device number and volume ID by volume device node 364 * file. 365 * @lib: UBI library descriptor 366 * @node: UBI character device node name 367 * @dev_num: UBI device number is returned here 368 * @vol_id: volume ID is returned hers 369 * 370 * This function returns zero in case of succes and %-1 in case of failure. 371 */ 372 static int vol_node2nums(struct libubi *lib, const char *node, int *dev_num, 373 int *vol_id) 374 { 375 struct stat st; 376 struct ubi_info info; 377 int i, fd, major, minor; 378 char file[strlen(lib->ubi_vol) + 100]; 379 380 if (stat(node, &st)) { 381 sys_errmsg("cannot get information about \"%s\"", 382 node); 383 return -1; 384 } 385 if (!S_ISCHR(st.st_mode)) { 386 errno = EINVAL; 387 errmsg("\"%s\" is not a character device", node); 388 return -1; 389 } 390 391 major = major(st.st_rdev); 392 minor = minor(st.st_rdev); 393 394 if (minor == 0) { 395 errno = EINVAL; 396 errmsg("\"%s\" is not a volume character device", node); 397 return -1; 398 } 399 400 if (ubi_get_info((libubi_t *)lib, &info)) 401 return -1; 402 403 for (i = info.lowest_dev_num; i <= info.highest_dev_num; i++) { 404 int major1, minor1, ret; 405 406 ret = dev_get_major(lib, i, &major1, &minor1); 407 if (ret) { 408 if (errno == ENOENT) 409 continue; 410 return -1; 411 } 412 413 if (major1 == major) 414 break; 415 } 416 417 if (i > info.highest_dev_num) { 418 errno = ENODEV; 419 return -1; 420 } 421 422 /* Make sure this UBI volume exists */ 423 sprintf(file, lib->ubi_vol, i, minor - 1); 424 fd = open(file, O_RDONLY); 425 if (fd < 0) { 426 errno = ENODEV; 427 return -1; 428 } 429 430 close(fd); 431 *dev_num = i; 432 *vol_id = minor - 1; 433 errno = 0; 434 return 0; 435 } 436 437 /** 438 * dev_node2num - find UBI device number by its character device node. 439 * @lib: UBI library descriptor 440 * @node: UBI character device node name 441 * @dev_num: UBI device number is returned here 442 * 443 * This function returns %0 in case of success and %-1 in case of failure. 444 */ 445 static int dev_node2num(struct libubi *lib, const char *node, int *dev_num) 446 { 447 struct stat st; 448 struct ubi_info info; 449 int i, major, minor; 450 451 if (stat(node, &st)) { 452 sys_errmsg("cannot get information about \"%s\"", node); 453 return -1; 454 } 455 if (!S_ISCHR(st.st_mode)) { 456 errno = EINVAL; 457 errmsg("\"%s\" is not a character device", node); 458 return -1; 459 } 460 461 major = major(st.st_rdev); 462 minor = minor(st.st_rdev); 463 464 if (minor != 0) { 465 errno = EINVAL; 466 errmsg("\"%s\" is not an UBI character device", node); 467 return -1; 468 } 469 470 if (ubi_get_info((libubi_t *)lib, &info)) 471 return -1; 472 473 for (i = info.lowest_dev_num; i <= info.highest_dev_num; i++) { 474 int major1, minor1, ret; 475 476 ret = dev_get_major(lib, i, &major1, &minor1); 477 if (ret) { 478 if (errno == ENOENT) 479 continue; 480 return -1; 481 } 482 483 if (major1 == major) { 484 if (minor1 != 0) { 485 errmsg("UBI character device minor number is " 486 "%d, but must be 0", minor1); 487 errno = EINVAL; 488 return -1; 489 } 490 errno = 0; 491 *dev_num = i; 492 return 0; 493 } 494 } 495 496 errno = ENODEV; 497 return -1; 498 } 499 500 int mtd_num2ubi_dev(libubi_t desc, int mtd_num, int *dev_num) 501 { 502 struct ubi_info info; 503 int i, ret, mtd_num1; 504 struct libubi *lib = desc; 505 506 if (ubi_get_info(desc, &info)) 507 return -1; 508 509 for (i = info.lowest_dev_num; i <= info.highest_dev_num; i++) { 510 ret = dev_read_int(lib->dev_mtd_num, i, &mtd_num1); 511 if (ret) { 512 if (errno == ENOENT) 513 continue; 514 return -1; 515 } 516 517 if (mtd_num1 == mtd_num) { 518 errno = 0; 519 *dev_num = i; 520 return 0; 521 } 522 } 523 524 errno = 0; 525 return -1; 526 } 527 528 libubi_t libubi_open(void) 529 { 530 int fd, version; 531 struct libubi *lib; 532 533 lib = calloc(1, sizeof(struct libubi)); 534 if (!lib) 535 return NULL; 536 537 lib->sysfs_ctrl = mkpath("/sys", SYSFS_CTRL); 538 if (!lib->sysfs_ctrl) 539 goto out_error; 540 541 lib->ctrl_dev = mkpath(lib->sysfs_ctrl, CTRL_DEV); 542 if (!lib->ctrl_dev) 543 goto out_error; 544 545 lib->sysfs_ubi = mkpath("/sys", SYSFS_UBI); 546 if (!lib->sysfs_ubi) 547 goto out_error; 548 549 /* Make sure UBI is present */ 550 fd = open(lib->sysfs_ubi, O_RDONLY); 551 if (fd == -1) { 552 errno = 0; 553 goto out_error; 554 } 555 556 if (close(fd)) { 557 sys_errmsg("close failed on \"%s\"", lib->sysfs_ubi); 558 goto out_error; 559 } 560 561 lib->ubi_dev = mkpath(lib->sysfs_ubi, UBI_DEV_NAME_PATT); 562 if (!lib->ubi_dev) 563 goto out_error; 564 565 lib->ubi_version = mkpath(lib->sysfs_ubi, UBI_VER); 566 if (!lib->ubi_version) 567 goto out_error; 568 569 lib->dev_dev = mkpath(lib->ubi_dev, DEV_DEV); 570 if (!lib->dev_dev) 571 goto out_error; 572 573 lib->dev_avail_ebs = mkpath(lib->ubi_dev, DEV_AVAIL_EBS); 574 if (!lib->dev_avail_ebs) 575 goto out_error; 576 577 lib->dev_total_ebs = mkpath(lib->ubi_dev, DEV_TOTAL_EBS); 578 if (!lib->dev_total_ebs) 579 goto out_error; 580 581 lib->dev_bad_count = mkpath(lib->ubi_dev, DEV_BAD_COUNT); 582 if (!lib->dev_bad_count) 583 goto out_error; 584 585 lib->dev_eb_size = mkpath(lib->ubi_dev, DEV_EB_SIZE); 586 if (!lib->dev_eb_size) 587 goto out_error; 588 589 lib->dev_max_ec = mkpath(lib->ubi_dev, DEV_MAX_EC); 590 if (!lib->dev_max_ec) 591 goto out_error; 592 593 lib->dev_bad_rsvd = mkpath(lib->ubi_dev, DEV_MAX_RSVD); 594 if (!lib->dev_bad_rsvd) 595 goto out_error; 596 597 lib->dev_max_vols = mkpath(lib->ubi_dev, DEV_MAX_VOLS); 598 if (!lib->dev_max_vols) 599 goto out_error; 600 601 lib->dev_min_io_size = mkpath(lib->ubi_dev, DEV_MIN_IO_SIZE); 602 if (!lib->dev_min_io_size) 603 goto out_error; 604 605 lib->dev_mtd_num = mkpath(lib->ubi_dev, DEV_MTD_NUM); 606 if (!lib->dev_mtd_num) 607 goto out_error; 608 609 lib->ubi_vol = mkpath(lib->sysfs_ubi, UBI_VOL_NAME_PATT); 610 if (!lib->ubi_vol) 611 goto out_error; 612 613 lib->vol_type = mkpath(lib->ubi_vol, VOL_TYPE); 614 if (!lib->vol_type) 615 goto out_error; 616 617 lib->vol_dev = mkpath(lib->ubi_vol, VOL_DEV); 618 if (!lib->vol_dev) 619 goto out_error; 620 621 lib->vol_alignment = mkpath(lib->ubi_vol, VOL_ALIGNMENT); 622 if (!lib->vol_alignment) 623 goto out_error; 624 625 lib->vol_data_bytes = mkpath(lib->ubi_vol, VOL_DATA_BYTES); 626 if (!lib->vol_data_bytes) 627 goto out_error; 628 629 lib->vol_rsvd_ebs = mkpath(lib->ubi_vol, VOL_RSVD_EBS); 630 if (!lib->vol_rsvd_ebs) 631 goto out_error; 632 633 lib->vol_eb_size = mkpath(lib->ubi_vol, VOL_EB_SIZE); 634 if (!lib->vol_eb_size) 635 goto out_error; 636 637 lib->vol_corrupted = mkpath(lib->ubi_vol, VOL_CORRUPTED); 638 if (!lib->vol_corrupted) 639 goto out_error; 640 641 lib->vol_name = mkpath(lib->ubi_vol, VOL_NAME); 642 if (!lib->vol_name) 643 goto out_error; 644 645 if (read_positive_int(lib->ubi_version, &version)) 646 goto out_error; 647 if (version != LIBUBI_UBI_VERSION) { 648 errmsg("this library was made for UBI version %d, but UBI " 649 "version %d is detected\n", LIBUBI_UBI_VERSION, version); 650 goto out_error; 651 } 652 653 return lib; 654 655 out_error: 656 libubi_close((libubi_t)lib); 657 return NULL; 658 } 659 660 void libubi_close(libubi_t desc) 661 { 662 struct libubi *lib = (struct libubi *)desc; 663 664 free(lib->vol_name); 665 free(lib->vol_corrupted); 666 free(lib->vol_eb_size); 667 free(lib->vol_rsvd_ebs); 668 free(lib->vol_data_bytes); 669 free(lib->vol_alignment); 670 free(lib->vol_dev); 671 free(lib->vol_type); 672 free(lib->ubi_vol); 673 free(lib->dev_mtd_num); 674 free(lib->dev_min_io_size); 675 free(lib->dev_max_vols); 676 free(lib->dev_bad_rsvd); 677 free(lib->dev_max_ec); 678 free(lib->dev_eb_size); 679 free(lib->dev_bad_count); 680 free(lib->dev_total_ebs); 681 free(lib->dev_avail_ebs); 682 free(lib->dev_dev); 683 free(lib->ubi_version); 684 free(lib->ubi_dev); 685 free(lib->sysfs_ubi); 686 free(lib->ctrl_dev); 687 free(lib->sysfs_ctrl); 688 free(lib); 689 } 690 691 /** 692 * do_attach - perform the actual attach operation. 693 * @node: name of the UBI control character device node 694 * @r: attach request 695 * 696 * This function performs the actual UBI attach operation. Returns %0 in case of 697 * success and %-1 in case of failure. @r->ubi_num contains newly created UBI 698 * device number. 699 */ 700 static int do_attach(const char *node, const struct ubi_attach_req *r) 701 { 702 int fd, ret; 703 704 fd = open(node, O_RDONLY); 705 if (fd == -1) { 706 sys_errmsg("cannot open \"%s\"", node); 707 return -1; 708 } 709 ret = ioctl(fd, UBI_IOCATT, r); 710 close(fd); 711 if (ret == -1) 712 return -1; 713 714 #ifdef UDEV_SETTLE_HACK 715 // if (system("udevsettle") == -1) 716 // return -1; 717 usleep(100000); 718 #endif 719 return ret; 720 } 721 722 #ifndef MTD_CHAR_MAJOR 723 /* 724 * This is taken from kernel <linux/mtd/mtd.h> and is unlikely to change anytime 725 * soon. 726 */ 727 #define MTD_CHAR_MAJOR 90 728 #endif 729 730 /** 731 * mtd_node_to_num - converts device node to MTD number. 732 * @mtd_dev_node: path to device node to convert 733 * 734 * This function converts given @mtd_dev_node to MTD device number. 735 * @mtd_dev_node should contain path to the MTD device node. Returns MTD device 736 * number in case of success and %-1 in case of failure (errno is set). 737 */ 738 static int mtd_node_to_num(const char *mtd_dev_node) 739 { 740 int major, minor; 741 struct stat sb; 742 743 if (stat(mtd_dev_node, &sb) < 0) { 744 sys_errmsg("cannot stat \"%s\"", mtd_dev_node); 745 return -1; 746 } 747 748 if (!S_ISCHR(sb.st_mode)) { 749 errno = EINVAL; 750 sys_errmsg("\"%s\" is not a character device", 751 mtd_dev_node); 752 return -1; 753 } 754 755 major = major(sb.st_rdev); 756 minor = minor(sb.st_rdev); 757 758 if (major != MTD_CHAR_MAJOR) { 759 errno = EINVAL; 760 sys_errmsg("\"%s\" is not an MTD device", mtd_dev_node); 761 return -1; 762 } 763 764 return minor / 2; 765 } 766 767 int ubi_attach(libubi_t desc, const char *node, struct ubi_attach_request *req) 768 { 769 struct ubi_attach_req r; 770 int ret; 771 772 (void)desc; 773 774 if (req->mtd_dev_node) { 775 /* 776 * User has passed path to device node. Lets find out MTD 777 * device number of the device and update req->mtd_num with it 778 */ 779 req->mtd_num = mtd_node_to_num(req->mtd_dev_node); 780 if (req->mtd_num == -1) 781 return -1; 782 } 783 784 memset(&r, 0, sizeof(struct ubi_attach_req)); 785 r.ubi_num = req->dev_num; 786 r.mtd_num = req->mtd_num; 787 r.vid_hdr_offset = req->vid_hdr_offset; 788 789 if (req->max_beb_per1024) { 790 /* 791 * We first have to check if the running kernel supports the 792 * 'max_beb_per1024' parameter. To do this, we invoke the 793 * "attach" ioctl 2 times: first with incorrect value %-1 of 794 * 'max_beb_per1024'. 795 * 796 * If the ioctl succeeds, it means that the kernel doesn't 797 * support the feature and just ignored our 'max_beb_per1024' 798 * value. 799 * 800 * If the ioctl returns -EINVAL, we assume this is because 801 * 'max_beb_per1024' was set to -1, and we invoke the ioctl for 802 * the second time with the 'max_beb_per1024' value. 803 */ 804 r.max_beb_per1024 = -1; 805 ret = do_attach(node, &r); 806 if (ret == 0) { 807 req->dev_num = r.ubi_num; 808 /* 809 * The call succeeded. It means that the kernel ignored 810 * 'max_beb_per1024' parameter. 811 */ 812 return 1; 813 } else if (errno != EINVAL) 814 return ret; 815 } 816 817 r.max_beb_per1024 = req->max_beb_per1024; 818 819 ret = do_attach(node, &r); 820 if (ret == 0) 821 req->dev_num = r.ubi_num; 822 823 return ret; 824 } 825 826 int ubi_detach_mtd(libubi_t desc, const char *node, int mtd_num) 827 { 828 int ret, ubi_dev; 829 830 ret = mtd_num2ubi_dev(desc, mtd_num, &ubi_dev); 831 if (ret == -1) { 832 errno = ENODEV; 833 return ret; 834 } 835 836 return ubi_remove_dev(desc, node, ubi_dev); 837 } 838 839 int ubi_detach(libubi_t desc, const char *node, const char *mtd_dev_node) 840 { 841 int mtd_num; 842 843 if (!mtd_dev_node) { 844 errno = EINVAL; 845 return -1; 846 } 847 848 mtd_num = mtd_node_to_num(mtd_dev_node); 849 if (mtd_num == -1) 850 return -1; 851 852 return ubi_detach_mtd(desc, node, mtd_num); 853 } 854 855 int ubi_remove_dev(libubi_t desc, const char *node, int ubi_dev) 856 { 857 int fd, ret; 858 859 desc = desc; 860 861 fd = open(node, O_RDONLY); 862 if (fd == -1) { 863 sys_errmsg("cannot open \"%s\"", node); 864 return -1; 865 } 866 ret = ioctl(fd, UBI_IOCFDET, &ubi_dev); 867 if (ret == -1) 868 goto out_close; 869 870 #ifdef UDEV_SETTLE_HACK 871 // if (system("udevsettle") == -1) 872 // return -1; 873 usleep(100000); 874 #endif 875 876 out_close: 877 close(fd); 878 return ret; 879 } 880 881 int ubi_probe_node(libubi_t desc, const char *node) 882 { 883 struct stat st; 884 struct ubi_info info; 885 int i, fd, major, minor; 886 struct libubi *lib = (struct libubi *)desc; 887 char file[strlen(lib->ubi_vol) + 100]; 888 889 if (stat(node, &st)) { 890 sys_errmsg("cannot get information about \"%s\"", node); 891 return -1; 892 } 893 894 if (!S_ISCHR(st.st_mode)) { 895 errmsg("\"%s\" is not a character device", node); 896 errno = EINVAL; 897 return -1; 898 } 899 900 major = major(st.st_rdev); 901 minor = minor(st.st_rdev); 902 903 if (ubi_get_info((libubi_t *)lib, &info)) 904 return -1; 905 906 for (i = info.lowest_dev_num; i <= info.highest_dev_num; i++) { 907 int major1, minor1, ret; 908 909 ret = dev_get_major(lib, i, &major1, &minor1); 910 if (ret) { 911 if (errno == ENOENT) 912 continue; 913 if (!errno) 914 goto out_not_ubi; 915 return -1; 916 } 917 918 if (major1 == major) 919 break; 920 } 921 922 if (i > info.highest_dev_num) 923 goto out_not_ubi; 924 925 if (minor == 0) 926 return 1; 927 928 /* This is supposdely an UBI volume device node */ 929 sprintf(file, lib->ubi_vol, i, minor - 1); 930 fd = open(file, O_RDONLY); 931 if (fd < 0) 932 goto out_not_ubi; 933 934 close(fd); 935 return 2; 936 937 out_not_ubi: 938 errmsg("\"%s\" has major:minor %d:%d, but this does not correspond to " 939 "any existing UBI device or volume", node, major, minor); 940 errno = ENODEV; 941 return -1; 942 } 943 944 int ubi_get_info(libubi_t desc, struct ubi_info *info) 945 { 946 DIR *sysfs_ubi; 947 struct dirent *dirent; 948 struct libubi *lib = (struct libubi *)desc; 949 950 memset(info, 0, sizeof(struct ubi_info)); 951 952 if (read_major(lib->ctrl_dev, &info->ctrl_major, &info->ctrl_minor)) { 953 /* 954 * Older UBI versions did not have control device, so we do not 955 * panic here for compatibility reasons. May be few years later 956 * we could return -1 here, but for now just set major:minor to 957 * -1. 958 */ 959 info->ctrl_major = info->ctrl_minor = -1; 960 } 961 962 /* 963 * We have to scan the UBI sysfs directory to identify how many UBI 964 * devices are present. 965 */ 966 sysfs_ubi = opendir(lib->sysfs_ubi); 967 if (!sysfs_ubi) 968 return -1; 969 970 info->lowest_dev_num = INT_MAX; 971 while (1) { 972 int dev_num, ret; 973 char tmp_buf[256]; 974 975 errno = 0; 976 dirent = readdir(sysfs_ubi); 977 if (!dirent) 978 break; 979 980 if (strlen(dirent->d_name) >= 255) { 981 errmsg("invalid entry in %s: \"%s\"", 982 lib->sysfs_ubi, dirent->d_name); 983 errno = EINVAL; 984 goto out_close; 985 } 986 987 ret = sscanf(dirent->d_name, UBI_DEV_NAME_PATT"%s", 988 &dev_num, tmp_buf); 989 if (ret == 1) { 990 info->dev_count += 1; 991 if (dev_num > info->highest_dev_num) 992 info->highest_dev_num = dev_num; 993 if (dev_num < info->lowest_dev_num) 994 info->lowest_dev_num = dev_num; 995 } 996 } 997 998 if (!dirent && errno) { 999 sys_errmsg("readdir failed on \"%s\"", lib->sysfs_ubi); 1000 goto out_close; 1001 } 1002 1003 if (closedir(sysfs_ubi)) { 1004 sys_errmsg("closedir failed on \"%s\"", lib->sysfs_ubi); 1005 return -1; 1006 } 1007 if (info->lowest_dev_num == INT_MAX) 1008 info->lowest_dev_num = 0; 1009 1010 if (read_positive_int(lib->ubi_version, &info->version)) 1011 return -1; 1012 1013 return 0; 1014 1015 out_close: 1016 closedir(sysfs_ubi); 1017 return -1; 1018 } 1019 1020 int ubi_mkvol(libubi_t desc, const char *node, struct ubi_mkvol_request *req) 1021 { 1022 int fd, ret; 1023 struct ubi_mkvol_req r; 1024 size_t n; 1025 1026 memset(&r, 0, sizeof(struct ubi_mkvol_req)); 1027 1028 desc = desc; 1029 r.vol_id = req->vol_id; 1030 r.alignment = req->alignment; 1031 r.bytes = req->bytes; 1032 r.vol_type = req->vol_type; 1033 1034 n = strlen(req->name); 1035 if (n > UBI_MAX_VOLUME_NAME) 1036 return -1; 1037 1038 strncpy(r.name, req->name, UBI_MAX_VOLUME_NAME + 1); 1039 r.name_len = n; 1040 1041 desc = desc; 1042 fd = open(node, O_RDONLY); 1043 if (fd == -1) { 1044 sys_errmsg("cannot open \"%s\"", node); 1045 return -1; 1046 } 1047 ret = ioctl(fd, UBI_IOCMKVOL, &r); 1048 if (ret == -1) { 1049 close(fd); 1050 return ret; 1051 } 1052 1053 close(fd); 1054 req->vol_id = r.vol_id; 1055 1056 #ifdef UDEV_SETTLE_HACK 1057 // if (system("udevsettle") == -1) 1058 // return -1; 1059 usleep(100000); 1060 #endif 1061 1062 return 0; 1063 } 1064 1065 int ubi_rmvol(libubi_t desc, const char *node, int vol_id) 1066 { 1067 int fd, ret; 1068 1069 desc = desc; 1070 fd = open(node, O_RDONLY); 1071 if (fd == -1) { 1072 sys_errmsg("cannot open \"%s\"", node); 1073 return -1; 1074 } 1075 1076 ret = ioctl(fd, UBI_IOCRMVOL, &vol_id); 1077 if (ret == -1) { 1078 close(fd); 1079 return ret; 1080 } 1081 1082 close(fd); 1083 1084 #ifdef UDEV_SETTLE_HACK 1085 // if (system("udevsettle") == -1) 1086 // return -1; 1087 usleep(100000); 1088 #endif 1089 1090 return 0; 1091 } 1092 1093 int ubi_rnvols(libubi_t desc, const char *node, struct ubi_rnvol_req *rnvol) 1094 { 1095 int fd, ret; 1096 1097 desc = desc; 1098 fd = open(node, O_RDONLY); 1099 if (fd == -1) 1100 return -1; 1101 1102 ret = ioctl(fd, UBI_IOCRNVOL, rnvol); 1103 if (ret == -1) { 1104 close(fd); 1105 return ret; 1106 } 1107 1108 close(fd); 1109 1110 #ifdef UDEV_SETTLE_HACK 1111 // if (system("udevsettle") == -1) 1112 // return -1; 1113 usleep(100000); 1114 #endif 1115 1116 return 0; 1117 } 1118 1119 int ubi_rsvol(libubi_t desc, const char *node, int vol_id, long long bytes) 1120 { 1121 int fd, ret; 1122 struct ubi_rsvol_req req; 1123 1124 desc = desc; 1125 fd = open(node, O_RDONLY); 1126 if (fd == -1) { 1127 sys_errmsg("cannot open \"%s\"", node); 1128 return -1; 1129 } 1130 req.bytes = bytes; 1131 req.vol_id = vol_id; 1132 1133 ret = ioctl(fd, UBI_IOCRSVOL, &req); 1134 close(fd); 1135 return ret; 1136 } 1137 1138 int ubi_update_start(libubi_t desc, int fd, long long bytes) 1139 { 1140 desc = desc; 1141 if (ioctl(fd, UBI_IOCVOLUP, &bytes)) 1142 return -1; 1143 return 0; 1144 } 1145 1146 int ubi_leb_change_start(libubi_t desc, int fd, int lnum, int bytes) 1147 { 1148 struct ubi_leb_change_req req; 1149 1150 desc = desc; 1151 memset(&req, 0, sizeof(struct ubi_leb_change_req)); 1152 req.lnum = lnum; 1153 req.bytes = bytes; 1154 req.dtype = 3; 1155 1156 if (ioctl(fd, UBI_IOCEBCH, &req)) 1157 return -1; 1158 return 0; 1159 } 1160 1161 int ubi_dev_present(libubi_t desc, int dev_num) 1162 { 1163 struct stat st; 1164 struct libubi *lib = (struct libubi *)desc; 1165 char file[strlen(lib->ubi_dev) + 50]; 1166 1167 sprintf(file, lib->ubi_dev, dev_num); 1168 return !stat(file, &st); 1169 } 1170 1171 int ubi_get_dev_info1(libubi_t desc, int dev_num, struct ubi_dev_info *info) 1172 { 1173 DIR *sysfs_ubi; 1174 struct dirent *dirent; 1175 struct libubi *lib = (struct libubi *)desc; 1176 1177 memset(info, 0, sizeof(struct ubi_dev_info)); 1178 info->dev_num = dev_num; 1179 1180 if (!ubi_dev_present(desc, dev_num)) 1181 return -1; 1182 1183 sysfs_ubi = opendir(lib->sysfs_ubi); 1184 if (!sysfs_ubi) 1185 return -1; 1186 1187 info->lowest_vol_id = INT_MAX; 1188 1189 while (1) { 1190 int vol_id, ret, devno; 1191 char tmp_buf[256]; 1192 1193 errno = 0; 1194 dirent = readdir(sysfs_ubi); 1195 if (!dirent) 1196 break; 1197 1198 if (strlen(dirent->d_name) >= 255) { 1199 errmsg("invalid entry in %s: \"%s\"", 1200 lib->sysfs_ubi, dirent->d_name); 1201 goto out_close; 1202 } 1203 1204 ret = sscanf(dirent->d_name, UBI_VOL_NAME_PATT"%s", &devno, &vol_id, tmp_buf); 1205 if (ret == 2 && devno == dev_num) { 1206 info->vol_count += 1; 1207 if (vol_id > info->highest_vol_id) 1208 info->highest_vol_id = vol_id; 1209 if (vol_id < info->lowest_vol_id) 1210 info->lowest_vol_id = vol_id; 1211 } 1212 } 1213 1214 if (!dirent && errno) { 1215 sys_errmsg("readdir failed on \"%s\"", lib->sysfs_ubi); 1216 goto out_close; 1217 } 1218 1219 if (closedir(sysfs_ubi)) { 1220 sys_errmsg("closedir failed on \"%s\"", lib->sysfs_ubi); 1221 return -1; 1222 } 1223 if (info->lowest_vol_id == INT_MAX) 1224 info->lowest_vol_id = 0; 1225 1226 if (dev_get_major(lib, dev_num, &info->major, &info->minor)) 1227 return -1; 1228 1229 if (dev_read_int(lib->dev_mtd_num, dev_num, &info->mtd_num)) 1230 return -1; 1231 if (dev_read_int(lib->dev_avail_ebs, dev_num, &info->avail_lebs)) 1232 return -1; 1233 if (dev_read_int(lib->dev_total_ebs, dev_num, &info->total_lebs)) 1234 return -1; 1235 if (dev_read_int(lib->dev_bad_count, dev_num, &info->bad_count)) 1236 return -1; 1237 if (dev_read_int(lib->dev_eb_size, dev_num, &info->leb_size)) 1238 return -1; 1239 if (dev_read_int(lib->dev_bad_rsvd, dev_num, &info->bad_rsvd)) 1240 return -1; 1241 if (dev_read_ll(lib->dev_max_ec, dev_num, &info->max_ec)) 1242 return -1; 1243 if (dev_read_int(lib->dev_max_vols, dev_num, &info->max_vol_count)) 1244 return -1; 1245 if (dev_read_int(lib->dev_min_io_size, dev_num, &info->min_io_size)) 1246 return -1; 1247 1248 info->avail_bytes = (long long)info->avail_lebs * info->leb_size; 1249 info->total_bytes = (long long)info->total_lebs * info->leb_size; 1250 1251 return 0; 1252 1253 out_close: 1254 closedir(sysfs_ubi); 1255 return -1; 1256 } 1257 1258 int ubi_get_dev_info(libubi_t desc, const char *node, struct ubi_dev_info *info) 1259 { 1260 int err, dev_num = 0; 1261 struct libubi *lib = (struct libubi *)desc; 1262 1263 err = ubi_probe_node(desc, node); 1264 if (err != 1) { 1265 if (err == 2) 1266 errno = ENODEV; 1267 return -1; 1268 } 1269 1270 if (dev_node2num(lib, node, &dev_num)) 1271 return -1; 1272 1273 return ubi_get_dev_info1(desc, dev_num, info); 1274 } 1275 1276 int ubi_get_vol_info1(libubi_t desc, int dev_num, int vol_id, 1277 struct ubi_vol_info *info) 1278 { 1279 int ret; 1280 struct libubi *lib = (struct libubi *)desc; 1281 char buf[50]; 1282 1283 memset(info, 0, sizeof(struct ubi_vol_info)); 1284 info->dev_num = dev_num; 1285 info->vol_id = vol_id; 1286 1287 if (vol_get_major(lib, dev_num, vol_id, &info->major, &info->minor)) 1288 return -1; 1289 1290 ret = vol_read_data(lib->vol_type, dev_num, vol_id, buf, 50); 1291 if (ret < 0) 1292 return -1; 1293 1294 if (strncmp(buf, "static\n", ret) == 0) 1295 info->type = UBI_STATIC_VOLUME; 1296 else if (strncmp(buf, "dynamic\n", ret) == 0) 1297 info->type = UBI_DYNAMIC_VOLUME; 1298 else { 1299 errmsg("bad value at \"%s\"", buf); 1300 errno = EINVAL; 1301 return -1; 1302 } 1303 1304 ret = vol_read_int(lib->vol_alignment, dev_num, vol_id, 1305 &info->alignment); 1306 if (ret) 1307 return -1; 1308 ret = vol_read_ll(lib->vol_data_bytes, dev_num, vol_id, 1309 &info->data_bytes); 1310 if (ret) 1311 return -1; 1312 ret = vol_read_int(lib->vol_rsvd_ebs, dev_num, vol_id, &info->rsvd_lebs); 1313 if (ret) 1314 return -1; 1315 ret = vol_read_int(lib->vol_eb_size, dev_num, vol_id, &info->leb_size); 1316 if (ret) 1317 return -1; 1318 ret = vol_read_int(lib->vol_corrupted, dev_num, vol_id, 1319 &info->corrupted); 1320 if (ret) 1321 return -1; 1322 info->rsvd_bytes = (long long)info->leb_size * info->rsvd_lebs; 1323 1324 ret = vol_read_data(lib->vol_name, dev_num, vol_id, &info->name, 1325 UBI_VOL_NAME_MAX + 1); 1326 if (ret < 0) 1327 return -1; 1328 1329 info->name[ret - 1] = '\0'; 1330 return 0; 1331 } 1332 1333 int ubi_get_vol_info(libubi_t desc, const char *node, struct ubi_vol_info *info) 1334 { 1335 int err, vol_id = 0, dev_num = 0; 1336 struct libubi *lib = (struct libubi *)desc; 1337 1338 err = ubi_probe_node(desc, node); 1339 if (err != 2) { 1340 if (err == 1) 1341 errno = ENODEV; 1342 return -1; 1343 } 1344 1345 if (vol_node2nums(lib, node, &dev_num, &vol_id)) 1346 return -1; 1347 1348 return ubi_get_vol_info1(desc, dev_num, vol_id, info); 1349 } 1350 1351 int ubi_get_vol_info1_nm(libubi_t desc, int dev_num, const char *name, 1352 struct ubi_vol_info *info) 1353 { 1354 int i, err; 1355 unsigned int nlen = strlen(name); 1356 struct ubi_dev_info dev_info; 1357 1358 if (nlen == 0) { 1359 errmsg("bad \"name\" input parameter"); 1360 errno = EINVAL; 1361 return -1; 1362 } 1363 1364 err = ubi_get_dev_info1(desc, dev_num, &dev_info); 1365 if (err) 1366 return err; 1367 1368 for (i = dev_info.lowest_vol_id; 1369 i <= dev_info.highest_vol_id; i++) { 1370 err = ubi_get_vol_info1(desc, dev_num, i, info); 1371 if (err == -1) { 1372 if (errno == ENOENT) 1373 continue; 1374 return -1; 1375 } 1376 1377 if (nlen == strlen(info->name) && !strcmp(name, info->name)) 1378 return 0; 1379 } 1380 1381 errno = ENOENT; 1382 return -1; 1383 } 1384 1385 int ubi_set_property(int fd, uint8_t property, uint64_t value) 1386 { 1387 struct ubi_set_vol_prop_req r; 1388 1389 memset(&r, 0, sizeof(struct ubi_set_vol_prop_req)); 1390 r.property = property; 1391 r.value = value; 1392 1393 return ioctl(fd, UBI_IOCSETVOLPROP, &r); 1394 } 1395 1396 int ubi_leb_unmap(int fd, int lnum) 1397 { 1398 return ioctl(fd, UBI_IOCEBUNMAP, &lnum); 1399 } 1400 1401 int ubi_is_mapped(int fd, int lnum) 1402 { 1403 return ioctl(fd, UBI_IOCEBISMAP, &lnum); 1404 } 1405
This page was automatically generated by LXR 0.3.1. • OpenWrt