rsc | d3df308 | 2003-12-06 18:08:52 +0000 | [diff] [blame] | 1 | /* Copyright (C) 2003 Russ Cox, Massachusetts Institute of Technology */ |
| 2 | /* See COPYRIGHT */ |
| 3 | |
| 4 | #include <u.h> |
| 5 | #include <libc.h> |
| 6 | #include <fcall.h> |
| 7 | #include <fs.h> |
| 8 | #include "fsimpl.h" |
| 9 | |
rsc | 5a8e63b | 2004-02-29 22:10:26 +0000 | [diff] [blame] | 10 | static long |
| 11 | _fspwrite(Fid *fid, void *buf, long n, vlong offset) |
rsc | d3df308 | 2003-12-06 18:08:52 +0000 | [diff] [blame] | 12 | { |
| 13 | Fcall tx, rx; |
| 14 | void *freep; |
| 15 | |
rsc | ceb0477 | 2003-12-09 06:06:07 +0000 | [diff] [blame] | 16 | tx.type = Twrite; |
| 17 | tx.fid = fid->fid; |
rsc | d3df308 | 2003-12-06 18:08:52 +0000 | [diff] [blame] | 18 | if(offset == -1){ |
rsc | ceb0477 | 2003-12-09 06:06:07 +0000 | [diff] [blame] | 19 | qlock(&fid->lk); |
| 20 | tx.offset = fid->offset; |
| 21 | qunlock(&fid->lk); |
rsc | d3df308 | 2003-12-06 18:08:52 +0000 | [diff] [blame] | 22 | }else |
| 23 | tx.offset = offset; |
| 24 | tx.count = n; |
| 25 | tx.data = buf; |
| 26 | |
rsc | 15680d5 | 2004-03-05 05:53:11 +0000 | [diff] [blame] | 27 | if(fsrpc(fid->fs, &tx, &rx, &freep) < 0) |
| 28 | return -1; |
rsc | d3df308 | 2003-12-06 18:08:52 +0000 | [diff] [blame] | 29 | if(rx.type == Rerror){ |
rsc | d3df308 | 2003-12-06 18:08:52 +0000 | [diff] [blame] | 30 | werrstr("%s", rx.ename); |
| 31 | free(freep); |
| 32 | return -1; |
| 33 | } |
rsc | ceb0477 | 2003-12-09 06:06:07 +0000 | [diff] [blame] | 34 | if(offset == -1 && rx.count){ |
| 35 | qlock(&fid->lk); |
| 36 | fid->offset += rx.count; |
| 37 | qunlock(&fid->lk); |
| 38 | } |
rsc | d3df308 | 2003-12-06 18:08:52 +0000 | [diff] [blame] | 39 | free(freep); |
| 40 | return rx.count; |
| 41 | } |
| 42 | |
| 43 | long |
rsc | 5a8e63b | 2004-02-29 22:10:26 +0000 | [diff] [blame] | 44 | fspwrite(Fid *fid, void *buf, long n, vlong offset) |
| 45 | { |
rsc | 493f3d0 | 2004-10-22 17:14:17 +0000 | [diff] [blame] | 46 | long tot, want, got, first; |
rsc | 5a8e63b | 2004-02-29 22:10:26 +0000 | [diff] [blame] | 47 | uint msize; |
| 48 | |
| 49 | msize = fid->fs->msize - IOHDRSZ; |
| 50 | tot = 0; |
rsc | 493f3d0 | 2004-10-22 17:14:17 +0000 | [diff] [blame] | 51 | first = 1; |
| 52 | while(tot < n || first){ |
rsc | 5a8e63b | 2004-02-29 22:10:26 +0000 | [diff] [blame] | 53 | want = n - tot; |
| 54 | if(want > msize) |
| 55 | want = msize; |
| 56 | got = _fspwrite(fid, buf, want, offset); |
rsc | 493f3d0 | 2004-10-22 17:14:17 +0000 | [diff] [blame] | 57 | first = 0; |
rsc | 5a8e63b | 2004-02-29 22:10:26 +0000 | [diff] [blame] | 58 | if(got < 0){ |
| 59 | if(tot == 0) |
| 60 | return got; |
| 61 | break; |
| 62 | } |
| 63 | tot += got; |
| 64 | if(offset != -1) |
| 65 | offset += got; |
| 66 | } |
| 67 | return tot; |
| 68 | } |
| 69 | |
| 70 | long |
rsc | ceb0477 | 2003-12-09 06:06:07 +0000 | [diff] [blame] | 71 | fswrite(Fid *fid, void *buf, long n) |
rsc | d3df308 | 2003-12-06 18:08:52 +0000 | [diff] [blame] | 72 | { |
rsc | ceb0477 | 2003-12-09 06:06:07 +0000 | [diff] [blame] | 73 | return fspwrite(fid, buf, n, -1); |
rsc | d3df308 | 2003-12-06 18:08:52 +0000 | [diff] [blame] | 74 | } |