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