Unified · Split
| @@ -6,6 +6,8 @@ · 5 unmodified lines | |||
| 6 | #include "group.h" | 6 | #include "group.h" |
| 7 | #include "common.h" | 7 | #include "common.h" |
| 8 | 8 | ||
| 9 | #define MIN(a,b) ((a)<(b)?(a):(b)) | ||
| 10 | |||
| 9 | int mainstacksize = 65536; | 11 | int mainstacksize = 65536; |
| 10 | 12 | ||
| 11 | typedef struct Aux Aux; | 13 | typedef struct Aux Aux; |
| @@ -29,7 +31,7 @@ enum { · 17 unmodified lines | |||
| 29 | }; | 31 | }; |
| 30 | 32 | ||
| 31 | static Opts opts; | 33 | static Opts opts; |
| 32 | 34 | static u8int zero[65536]; | |
| 33 | static char Eperm[] = "permission denied"; | 35 | static char Eperm[] = "permission denied"; |
| 34 | 36 | ||
| 35 | static char * | 37 | static char * |
| @@ -103,6 +105,8 @@ haveperm(Aux *a, int p, struct ext4_inode *inodeout) · 67 unmodified lines | |||
| 103 | default: | 105 | default: |
| 104 | return 0; | 106 | return 0; |
| 105 | } | 107 | } |
| 108 | if(p & OTRUNC) | ||
| 109 | p |= AWRITE; | ||
| 106 | 110 | ||
| 107 | if((s = fullpath(a)) == nil) | 111 | if((s = fullpath(a)) == nil) |
| 108 | return -1; | 112 | return -1; |
| @@ -343,6 +347,7 @@ Nomem: · 234 unmodified lines | |||
| 343 | goto ext4errorrm; | 347 | goto ext4errorrm; |
| 344 | ext4_owner_set(s, a->uid, ext4_inode_get_gid(&inode)); | 348 | ext4_owner_set(s, a->uid, ext4_inode_get_gid(&inode)); |
| 345 | 349 | ||
| 350 | free(a->path); | ||
| 346 | a->path = strdup(strchr(s+1, '/')+1); | 351 | a->path = strdup(strchr(s+1, '/')+1); |
| 347 | free(s); | 352 | free(s); |
| 348 | r->ofcall.iounit = 0; | 353 | r->ofcall.iounit = 0; |
| @@ -445,25 +450,24 @@ static void · 96 unmodified lines | |||
| 445 | rread(Req *r) | 450 | rread(Req *r) |
| 446 | { | 451 | { |
| 447 | ulong n; | 452 | ulong n; |
| 453 | int res; | ||
| 448 | Aux *a; | 454 | Aux *a; |
| 449 | 455 | ||
| 450 | a = r->fid->aux; | 456 | a = r->fid->aux; |
| 451 | if(a->type == Adir && a->dir != nil){ | 457 | if(a->type == Adir && a->dir != nil){ |
| 452 | dirread9p(r, dirgen, a); | 458 | dirread9p(r, dirgen, a); |
| 453 | respond(r, nil); | ||
| 454 | return; | ||
| 455 | }else if(a->type == Afile && a->file != nil){ | 459 | }else if(a->type == Afile && a->file != nil){ |
| 456 | ext4_fseek(a->file, r->ifcall.offset, 0); | 460 | if(ext4_fseek(a->file, r->ifcall.offset, SEEK_SET) != 0) |
| 457 | if(ext4_fread(a->file, r->ofcall.data, r->ifcall.count, &n) != 0){ | 461 | n = 0; |
| 458 | respond(r, "i/o error"); | 462 | else if((res = ext4_fread(a->file, r->ofcall.data, r->ifcall.count, &n)) != 0){ |
| 459 | }else{ | 463 | respond(r, errno2s(res)); |
| 460 | r->ofcall.count = n; | 464 | return; |
| 461 | respond(r, nil); | ||
| 462 | } | 465 | } |
| 463 | return; | 466 | |
| 467 | r->ofcall.count = n; | ||
| 464 | } | 468 | } |
| 465 | 469 | ||
| 466 | respond(r, "eh?"); | 470 | respond(r, nil); |
| 467 | } | 471 | } |
| 468 | 472 | ||
| 469 | static void | 473 | static void |
| @@ -476,19 +480,25 @@ rwrite(Req *r) · 6 unmodified lines | |||
| 476 | a = r->fid->aux; | 480 | a = r->fid->aux; |
| 477 | if(a->type == Adir){ | 481 | if(a->type == Adir){ |
| 478 | respond(r, "can't write to dir"); | 482 | respond(r, "can't write to dir"); |
| 479 | return; | ||
| 480 | }else if(a->type == Afile){ | 483 | }else if(a->type == Afile){ |
| 481 | ext4_fseek(a->file, r->ifcall.offset, SEEK_SET); | 484 | while(ext4_fsize(a->file) < r->ifcall.offset){ |
| 482 | if((res = ext4_fwrite(a->file, r->ifcall.data, r->ifcall.count, &n)) != 0) | 485 | ext4_fseek(a->file, 0, SEEK_END); |
| 483 | respond(r, errno2s(res)); | 486 | if((res = ext4_fwrite(a->file, zero, MIN(r->ifcall.offset-ext4_fsize(a->file), sizeof(zero)), &n)) != 0) |
| 484 | else{ | 487 | goto ext4error; |
| 485 | r->ofcall.count = n; | ||
| 486 | respond(r, nil); | ||
| 487 | } | 488 | } |
| 488 | return; | 489 | if((res = ext4_fseek(a->file, r->ifcall.offset, SEEK_SET)) != 0) |
| 490 | goto ext4error; | ||
| 491 | if((res = ext4_fwrite(a->file, r->ifcall.data, r->ifcall.count, &n)) != 0) | ||
| 492 | goto ext4error; | ||
| 493 | |||
| 494 | r->ofcall.count = n; | ||
| 495 | respond(r, nil); | ||
| 489 | } | 496 | } |
| 490 | 497 | ||
| 491 | respond(r, "eh?"); | 498 | return; |
| 499 | |||
| 500 | ext4error: | ||
| 501 | respond(r, errno2s(res)); | ||
| 492 | } | 502 | } |
| 493 | 503 | ||
| 494 | static void | 504 | static void |
| @@ -758,20 +768,14 @@ rclone(Fid *oldfid, Fid *newfid) · 263 unmodified lines | |||
| 758 | Aux *a, *c; | 768 | Aux *a, *c; |
| 759 | 769 | ||
| 760 | a = oldfid->aux; | 770 | a = oldfid->aux; |
| 761 | switch(a->type){ | ||
| 762 | case Afile: | ||
| 763 | case Adir: | ||
| 764 | if((c = calloc(1, sizeof(*c))) == nil) | ||
| 765 | return "memory"; | ||
| 766 | memmove(c, a, sizeof(*c)); | ||
| 767 | c->path = strdup(a->path); | ||
| 768 | c->file = nil; | ||
| 769 | c->dir = nil; | ||
| 770 | break; | ||
| 771 | 771 | ||
| 772 | default: | 772 | if((c = calloc(1, sizeof(*c))) == nil) |
| 773 | return "unknown aux type"; | 773 | return "memory"; |
| 774 | } | 774 | memmove(c, a, sizeof(*c)); |
| 775 | c->path = strdup(a->path); | ||
| 776 | c->file = nil; | ||
| 777 | c->dir = nil; | ||
| 778 | |||
| 775 | incref(c->p); | 779 | incref(c->p); |
| 776 | newfid->aux = c; | 780 | newfid->aux = c; |
| 777 | 781 | ||
| @@ -798,12 +802,9 @@ rdestroyfid(Fid *fid) · 20 unmodified lines | |||
| 798 | ext4_fclose(a->file); | 802 | ext4_fclose(a->file); |
| 799 | free(a->file); | 803 | free(a->file); |
| 800 | } | 804 | } |
| 801 | }else{ | ||
| 802 | /* that would be a BUG */ | ||
| 803 | return; | ||
| 804 | } | 805 | } |
| 805 | 806 | ||
| 806 | if(decref(a->p) == 0) | 807 | if(decref(a->p) < 1) |
| 807 | closepart(a->p); | 808 | closepart(a->p); |
| 808 | free(a->path); | 809 | free(a->path); |
| 809 | free(a); | 810 | free(a); |