| Index: emcore/trunk/tools/emcorefs/emcore.h |
| — | — | @@ -106,7 +106,7 @@ |
| 107 | 107 | int emcore_file_open(uint32_t* handle, const char* pathname, const int flags);
|
| 108 | 108 | int emcore_file_size(uint32_t* size, const uint32_t handle);
|
| 109 | 109 | int emcore_file_read(uint32_t* nread, const uint32_t handle, const uint32_t addr, const uint32_t size);
|
| 110 | | -int emcore_file_write(const uint32_t handle, const uint32_t addr, const uint32_t size);
|
| | 110 | +int emcore_file_write(uint32_t* nwrite, const uint32_t handle, const uint32_t addr, const uint32_t size);
|
| 111 | 111 | int emcore_file_seek(const uint32_t handle, const uint32_t offset, const uint32_t whence);
|
| 112 | 112 | int emcore_file_truncate(const uint32_t handle, const uint32_t length);
|
| 113 | 113 | int emcore_file_sync(const uint32_t handle);
|
| Index: emcore/trunk/tools/emcorefs/fuse.c |
| — | — | @@ -346,6 +346,98 @@ |
| 347 | 347 | return nread;
|
| 348 | 348 | }
|
| 349 | 349 |
|
| | 350 | +int emcorefs_write(const char* path, const char* buf, uint32_t size, off_t offset, struct fuse_file_info* fi) {
|
| | 351 | + fprintf(stderr, "FUSE_WRITE: path=[%s] size=[%d] offset=[%jd] fi->flags=[%d]\n", path, size, offset, fi->flags);
|
| | 352 | +
|
| | 353 | + int res;
|
| | 354 | + uint32_t emcore_errno_value, addr, nwrite = size;
|
| | 355 | +
|
| | 356 | + if (!fi->fh)
|
| | 357 | + {
|
| | 358 | + return -EIO;
|
| | 359 | + }
|
| | 360 | +
|
| | 361 | + res = emcore_malloc(&addr, size);
|
| | 362 | +
|
| | 363 | + if (EMCORE_SUCCESS != res)
|
| | 364 | + {
|
| | 365 | + return -EIO;
|
| | 366 | + }
|
| | 367 | +
|
| | 368 | + do {
|
| | 369 | + if (offset) {
|
| | 370 | + res = emcore_file_seek(fi->fh, offset, SEEK_SET);
|
| | 371 | +
|
| | 372 | + if (EMCORE_ERROR_IO == res)
|
| | 373 | + {
|
| | 374 | + res = emcore_errno(&emcore_errno_value);
|
| | 375 | +
|
| | 376 | + if (EMCORE_SUCCESS != res)
|
| | 377 | + {
|
| | 378 | + nwrite = -EIO;
|
| | 379 | + break;
|
| | 380 | + }
|
| | 381 | +
|
| | 382 | + if (EMCORE_SUCCESS != emcore_errno_value)
|
| | 383 | + {
|
| | 384 | + nwrite = -emcore_errno_value;
|
| | 385 | + break;
|
| | 386 | + }
|
| | 387 | + }
|
| | 388 | +
|
| | 389 | + if (EMCORE_SUCCESS != res)
|
| | 390 | + {
|
| | 391 | + nwrite = -EIO;
|
| | 392 | + break;
|
| | 393 | + }
|
| | 394 | + }
|
| | 395 | +
|
| | 396 | + res = emcore_write(buf, addr, nwrite);
|
| | 397 | +
|
| | 398 | + if (EMCORE_SUCCESS != res)
|
| | 399 | + {
|
| | 400 | + nwrite = -EIO;
|
| | 401 | + break;
|
| | 402 | + }
|
| | 403 | +
|
| | 404 | + res = emcore_file_write(&nwrite, fi->fh, addr, size);
|
| | 405 | +
|
| | 406 | + if (EMCORE_ERROR_IO == res)
|
| | 407 | + {
|
| | 408 | + res = emcore_errno(&emcore_errno_value);
|
| | 409 | +
|
| | 410 | + if (EMCORE_SUCCESS != res)
|
| | 411 | + {
|
| | 412 | + nwrite = -EIO;
|
| | 413 | + break;
|
| | 414 | + }
|
| | 415 | +
|
| | 416 | + if (EMCORE_SUCCESS != emcore_errno_value)
|
| | 417 | + {
|
| | 418 | + nwrite = -emcore_errno_value;
|
| | 419 | + break;
|
| | 420 | + }
|
| | 421 | + }
|
| | 422 | +
|
| | 423 | + if (EMCORE_SUCCESS != res)
|
| | 424 | + {
|
| | 425 | + nwrite = -EIO;
|
| | 426 | + }
|
| | 427 | + }
|
| | 428 | + while(0);
|
| | 429 | +
|
| | 430 | + res = emcore_free(addr);
|
| | 431 | +
|
| | 432 | + if (EMCORE_SUCCESS != res)
|
| | 433 | + {
|
| | 434 | + return -EIO;
|
| | 435 | + }
|
| | 436 | +
|
| | 437 | + cache_remove(path);
|
| | 438 | +
|
| | 439 | + return nwrite;
|
| | 440 | +}
|
| | 441 | +
|
| 350 | 442 | int emcorefs_release(const char* path, struct fuse_file_info* fi)
|
| 351 | 443 | {
|
| 352 | 444 | int res;
|
| — | — | @@ -470,7 +562,6 @@ |
| 471 | 563 |
|
| 472 | 564 | int emcorefs_unlink(const char* path)
|
| 473 | 565 | {
|
| 474 | | -
|
| 475 | 566 | int res;
|
| 476 | 567 | uint32_t emcore_errno_value;
|
| 477 | 568 |
|
| — | — | @@ -499,4 +590,95 @@ |
| 500 | 591 | cache_remove(path);
|
| 501 | 592 |
|
| 502 | 593 | return 0;
|
| 503 | | -} |
| \ No newline at end of file |
| | 594 | +}
|
| | 595 | +
|
| | 596 | +int emcorefs_rename(const char* path, const char* new_path)
|
| | 597 | +{
|
| | 598 | + int res;
|
| | 599 | + uint32_t emcore_errno_value;
|
| | 600 | +
|
| | 601 | + res = emcore_file_rename(path, new_path);
|
| | 602 | +
|
| | 603 | + if (EMCORE_ERROR_IO == res)
|
| | 604 | + {
|
| | 605 | + res = emcore_errno(&emcore_errno_value);
|
| | 606 | +
|
| | 607 | + if (EMCORE_SUCCESS != res)
|
| | 608 | + {
|
| | 609 | + return -EIO;
|
| | 610 | + }
|
| | 611 | +
|
| | 612 | + if (EMCORE_SUCCESS != emcore_errno_value)
|
| | 613 | + {
|
| | 614 | + return -emcore_errno_value;
|
| | 615 | + }
|
| | 616 | + }
|
| | 617 | +
|
| | 618 | + if (EMCORE_SUCCESS != res)
|
| | 619 | + {
|
| | 620 | + return -EIO;
|
| | 621 | + }
|
| | 622 | +
|
| | 623 | + cache_remove(path);
|
| | 624 | +
|
| | 625 | + return 0;
|
| | 626 | +}
|
| | 627 | +
|
| | 628 | +int emcorefs_truncate(const char* path, off_t size)
|
| | 629 | +{
|
| | 630 | + int res;
|
| | 631 | + struct fuse_file_info fi;
|
| | 632 | +
|
| | 633 | + res = emcorefs_open(path, &fi);
|
| | 634 | +
|
| | 635 | + if (0 != res) {
|
| | 636 | + return res;
|
| | 637 | + }
|
| | 638 | +
|
| | 639 | + res = emcorefs_ftruncate(path, size, &fi);
|
| | 640 | +
|
| | 641 | + if (0 != res) {
|
| | 642 | + return res;
|
| | 643 | + }
|
| | 644 | +
|
| | 645 | + return emcorefs_release(path, &fi);
|
| | 646 | +}
|
| | 647 | +
|
| | 648 | +int emcorefs_ftruncate(const char* path, off_t size, struct fuse_file_info* fi)
|
| | 649 | +{
|
| | 650 | + int res;
|
| | 651 | + uint32_t emcore_errno_value;
|
| | 652 | + (void)path;
|
| | 653 | +
|
| | 654 | + if (!fi->fh)
|
| | 655 | + {
|
| | 656 | + return -EIO;
|
| | 657 | + }
|
| | 658 | +
|
| | 659 | + res = emcore_file_truncate(fi->fh, size);
|
| | 660 | +
|
| | 661 | + if (EMCORE_ERROR_IO == res)
|
| | 662 | + {
|
| | 663 | + res = emcore_errno(&emcore_errno_value);
|
| | 664 | +
|
| | 665 | + if (EMCORE_SUCCESS != res)
|
| | 666 | + {
|
| | 667 | + return -EIO;
|
| | 668 | + }
|
| | 669 | +
|
| | 670 | + if (EMCORE_SUCCESS != emcore_errno_value)
|
| | 671 | + {
|
| | 672 | + return -emcore_errno_value;
|
| | 673 | + }
|
| | 674 | + }
|
| | 675 | +
|
| | 676 | + if (EMCORE_SUCCESS != res)
|
| | 677 | + {
|
| | 678 | + return -EIO;
|
| | 679 | + }
|
| | 680 | +
|
| | 681 | + cache_remove(path);
|
| | 682 | +
|
| | 683 | + return 0;
|
| | 684 | +}
|
| | 685 | +
|
| Index: emcore/trunk/tools/emcorefs/cache.c |
| — | — | @@ -83,7 +83,12 @@ |
| 84 | 84 | struct emcore_dir_entry* cache_entry; |
| 85 | 85 | char* new_name; |
| 86 | 86 | size_t new_name_len = 1; |
| 87 | | - |
| | 87 | + |
| | 88 | + if (0 == strcmp(entry->name, ".") || 0 == strcmp(entry->name, "..")) |
| | 89 | + { |
| | 90 | + return; |
| | 91 | + } |
| | 92 | + |
| 88 | 93 | new_name_len += strlen(dir_name) + strlen(entry->name); |
| 89 | 94 | |
| 90 | 95 | if (strcmp(dir_name, "/") != 0) |
| — | — | @@ -204,7 +209,7 @@ |
| 205 | 210 | |
| 206 | 211 | for (i = 0; i < emcore_dir_cache_length; ++i) |
| 207 | 212 | { |
| 208 | | - fprintf(stderr, "cache_dump: [%s] 0x%08x %d %d %lu\n", emcore_dir_entry_cache[i].name, emcore_dir_entry_cache[i].attributes, emcore_dir_entry_cache[i].size, emcore_dir_entry_cache[i].startcluster, fat_time_to_unix_ts(emcore_dir_entry_cache[i].wrtdate, emcore_dir_entry_cache[i].wrttime)); |
| | 213 | + fprintf(stderr, "cache_dump: [%s] / attr: 0x%08x / size: %d / startcluster: %d / ts: %lu\n", emcore_dir_entry_cache[i].name, emcore_dir_entry_cache[i].attributes, emcore_dir_entry_cache[i].size, emcore_dir_entry_cache[i].startcluster, fat_time_to_unix_ts(emcore_dir_entry_cache[i].wrttime, emcore_dir_entry_cache[i].wrtdate)); |
| 209 | 214 | } |
| 210 | 215 | } |
| 211 | 216 | #endif |
| Index: emcore/trunk/tools/emcorefs/emcorefs.c |
| — | — | @@ -34,17 +34,26 @@ |
| 35 | 35 | struct fuse_operations emcorefs_oper = |
| 36 | 36 | { |
| 37 | 37 | .getattr = emcorefs_getattr, |
| | 38 | + |
| 38 | 39 | .opendir = emcorefs_opendir, |
| 39 | 40 | .readdir = emcorefs_readdir, |
| 40 | 41 | .releasedir = emcorefs_releasedir, |
| | 42 | + |
| 41 | 43 | .open = emcorefs_open, |
| 42 | 44 | .read = emcorefs_read, |
| | 45 | + .write = emcorefs_write, |
| 43 | 46 | .release = emcorefs_release, |
| | 47 | + |
| 44 | 48 | .mkdir = emcorefs_mkdir, |
| 45 | 49 | .rmdir = emcorefs_rmdir, |
| | 50 | + |
| 46 | 51 | .create = emcorefs_create, |
| 47 | 52 | .mknod = emcorefs_mknod, |
| 48 | 53 | .unlink = emcorefs_unlink, |
| | 54 | + .rename = emcorefs_rename, |
| | 55 | + .truncate = emcorefs_truncate, |
| | 56 | + |
| | 57 | + .ftruncate = emcorefs_ftruncate, |
| 49 | 58 | }; |
| 50 | 59 | |
| 51 | 60 | int main(int argc, char* argv[]) |
| Index: emcore/trunk/tools/emcorefs/fuse.h |
| — | — | @@ -33,6 +33,7 @@ |
| 34 | 34 | int emcorefs_releasedir(const char* path, struct fuse_file_info* fi);
|
| 35 | 35 | int emcorefs_open(const char* path, struct fuse_file_info* fi);
|
| 36 | 36 | int emcorefs_read(const char* path, char* buf, uint32_t size, off_t offset, struct fuse_file_info* fi);
|
| | 37 | +int emcorefs_write(const char* path, const char* buf, uint32_t size, off_t offset, struct fuse_file_info* fi);
|
| 37 | 38 | int emcorefs_release(const char* path, struct fuse_file_info* fi);
|
| 38 | 39 | int emcorefs_mkdir(const char* path, mode_t mode);
|
| 39 | 40 | int emcorefs_rmdir(const char* path);
|
| — | — | @@ -39,5 +40,8 @@ |
| 40 | 41 | int emcorefs_create(const char* path, mode_t mode, struct fuse_file_info* fi);
|
| 41 | 42 | int emcorefs_mknod(const char* path, mode_t mode, dev_t dev);
|
| 42 | 43 | int emcorefs_unlink(const char* path);
|
| | 44 | +int emcorefs_rename(const char* path, const char* new_path);
|
| | 45 | +int emcorefs_truncate(const char* path, off_t size);
|
| | 46 | +int emcorefs_ftruncate(const char* path, off_t size, struct fuse_file_info* fi);
|
| 43 | 47 |
|
| 44 | 48 | #endif /* __FUSE_H__ */
|
| Index: emcore/trunk/tools/emcorefs/emcore.c |
| — | — | @@ -491,7 +491,7 @@ |
| 492 | 492 | return EMCORE_SUCCESS;
|
| 493 | 493 | }
|
| 494 | 494 |
|
| 495 | | -int emcore_file_write(const uint32_t handle, const uint32_t addr, const uint32_t size)
|
| | 495 | +int emcore_file_write(uint32_t* nwrite, const uint32_t handle, const uint32_t addr, const uint32_t size)
|
| 496 | 496 | {
|
| 497 | 497 | int res;
|
| 498 | 498 | uint32_t out[4] = { 33, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef }, in[4];
|
| — | — | @@ -512,6 +512,8 @@ |
| 513 | 513 | return EMCORE_ERROR_IO;
|
| 514 | 514 | }
|
| 515 | 515 |
|
| | 516 | + *nwrite = in[1];
|
| | 517 | +
|
| 516 | 518 | return EMCORE_SUCCESS;
|
| 517 | 519 | }
|
| 518 | 520 |
|
| Index: emcore/trunk/tools/emcorefs/Makefile |
| — | — | @@ -1,4 +1,4 @@ |
| 2 | | -CFLAGS := -O2 -Wall -Wextra -Werror $(shell pkg-config --cflags --libs libusb-1.0 fuse) |
| | 2 | +CFLAGS += -O2 -Wall -Wextra -Werror $(shell pkg-config --cflags --libs libusb-1.0 fuse) |
| 3 | 3 | SOURCES = util.c usb.c emcore.c cache.c fuse.c emcorefs.c |
| 4 | 4 | TARGET = build/emcorefs |
| 5 | 5 | |
| Index: emcore/trunk/tools/emcorefs/README |
| — | — | @@ -41,7 +41,7 @@ |
| 42 | 42 |
|
| 43 | 43 | Known bugs/issues
|
| 44 | 44 | -----------------
|
| 45 | | -* Read-only support at the moment.
|
| | 45 | +* Write support not tested very well.
|
| 46 | 46 | * Running FUSE with multithreading breaks file reading because of
|
| 47 | 47 | the way these are implemented on emCORE's side.
|
| 48 | 48 | Workaround: use the "-s" option.
|
| — | — | @@ -51,7 +51,6 @@ |
| 52 | 52 |
|
| 53 | 53 | Future plans
|
| 54 | 54 | ------------
|
| 55 | | -* Implement write support.
|
| 56 | 55 | * Merge some functions that are doing similar tasks to reduce code
|
| 57 | 56 | duplication. Return proper error codes in FS operations.
|
| 58 | 57 |
|