summaryrefslogtreecommitdiff
path: root/sys/src/cmd/hjfs/dev.c
diff options
context:
space:
mode:
authoraiju <aiju@phicode.de>2012-08-07 17:57:04 +0200
committeraiju <aiju@phicode.de>2012-08-07 17:57:04 +0200
commitb21b9ba89cf66a8fac6f94efb79cfb425a2c4df2 (patch)
tree42047f997cda3eddec9faeafeb74435cc72a4786 /sys/src/cmd/hjfs/dev.c
parentef1c1863051d0530a31b291f4e334ee7601c318c (diff)
added hjfs
Diffstat (limited to 'sys/src/cmd/hjfs/dev.c')
-rw-r--r--sys/src/cmd/hjfs/dev.c93
1 files changed, 93 insertions, 0 deletions
diff --git a/sys/src/cmd/hjfs/dev.c b/sys/src/cmd/hjfs/dev.c
new file mode 100644
index 000000000..9afdeba16
--- /dev/null
+++ b/sys/src/cmd/hjfs/dev.c
@@ -0,0 +1,93 @@
+#include <u.h>
+#include <libc.h>
+#include <thread.h>
+#include "dat.h"
+#include "fns.h"
+
+Dev *devs;
+
+void
+devwork(void *v)
+{
+ Dev *d;
+ Buf *b;
+ Channel *r;
+ uchar buf[BLOCK];
+
+ d = v;
+ for(;;){
+ qlock(&d->workl);
+ while(d->work.wnext == &d->work)
+ rsleep(&d->workr);
+ b = d->work.wnext;
+ b->wnext->wprev = b->wprev;
+ b->wprev->wnext = b->wnext;
+ b->wnext = b->wprev = nil;
+ qunlock(&d->workl);
+ if(b->d == nil) /* this is a sync request */
+ goto reply;
+ if(b->off >= d->size){
+ b->error = Einval;
+ goto reply;
+ }
+ seek(d->fd, b->off * BLOCK, 0);
+ b->error = nil;
+ if(b->op & BWRITE){
+ memset(buf, 0, sizeof(buf));
+ pack(b, buf);
+ if(write(d->fd, buf, BLOCK) < BLOCK){
+ dprint("hjfs: write: %r\n");
+ b->error = Eio;
+ }
+ }else{
+ if(readn(d->fd, buf, BLOCK) < 0){
+ dprint("hjfs: read: %r\n");
+ b->error = Eio;
+ }else
+ unpack(b, buf);
+ }
+ reply:
+ r = b->resp;
+ b->resp = nil;
+ if(r != nil)
+ send(r, &b);
+ }
+}
+
+Dev *
+newdev(char *file)
+{
+ Dev *d, **e;
+ Dir *dir;
+ Buf *b;
+
+ d = emalloc(sizeof(*d));
+ d->fd = open(file, ORDWR);
+ if(d->fd < 0){
+ free(d);
+ return nil;
+ }
+ dir = dirfstat(d->fd);
+ if(dir == nil){
+ error:
+ close(d->fd);
+ free(d);
+ return nil;
+ }
+ d->size = dir->length / BLOCK;
+ free(dir);
+ if(d->size == 0){
+ werrstr("device file too short");
+ goto error;
+ }
+ d->name = strdup(file);
+ for(b = d->buf; b < d->buf + BUFHASH + 1; b++)
+ b->dnext = b->dprev = b;
+ d->workr.l = &d->workl;
+ d->work.wnext = d->work.wprev = &d->work;
+ proccreate(devwork, d, mainstacksize);
+ for(e = &devs; *e != nil; e = &(*e)->next)
+ ;
+ *e = d;
+ return d;
+}