]> git.lizzy.rs Git - plan9front.git/blob - sys/src/cmd/hjfs/dev.c
hjfs: disable hjfs check until more functionality is complete
[plan9front.git] / sys / src / cmd / hjfs / dev.c
1 #include <u.h>
2 #include <libc.h>
3 #include <thread.h>
4 #include "dat.h"
5 #include "fns.h"
6
7 Dev *devs;
8
9 void
10 devwork(void *v)
11 {
12         Dev *d;
13         Buf *b;
14         Channel *r;
15         uchar buf[BLOCK];
16         
17         d = v;
18         for(;;){
19                 qlock(&d->workl);
20                 while(d->work.wnext == &d->work)
21                         rsleep(&d->workr);
22                 b = d->work.wnext;
23                 b->wnext->wprev = b->wprev;
24                 b->wprev->wnext = b->wnext;
25                 b->wnext = b->wprev = nil;
26                 qunlock(&d->workl);
27                 if(b->d == nil) /* this is a sync request */
28                         goto reply;
29                 if(b->off >= d->size){
30                         b->error = Einval;
31                         goto reply;
32                 }
33                 b->error = nil;
34                 if(b->op & BWRITE){
35                         memset(buf, 0, sizeof(buf));
36                         pack(b, buf);
37                         if(pwrite(d->fd, buf, BLOCK, b->off*BLOCK) < BLOCK){
38                                 dprint("write: %r\n");
39                                 b->error = Eio;
40                         }
41                 }else{
42                         int n, m;
43
44                         for(n = 0; n < BLOCK; n += m){
45                                 m = pread(d->fd, buf+n, BLOCK-n, b->off*BLOCK+n);
46                                 if(m < 0)
47                                         dprint("read: %r\n");
48                                 if(m <= 0)
49                                         break;
50                         }
51                         if(n < BLOCK)
52                                 b->error = Eio;
53                         else
54                                 unpack(b, buf);
55                 }
56         reply:
57                 r = b->resp;
58                 b->resp = nil;
59                 if(r != nil)
60                         send(r, &b);
61         }
62 }
63
64 Dev *
65 newdev(char *file)
66 {
67         Dev *d, **e;
68         Dir *dir;
69         Buf *b;
70         
71         d = emalloc(sizeof(*d));
72         d->fd = open(file, ORDWR);
73         if(d->fd < 0){
74                 free(d);
75                 return nil;
76         }
77         dir = dirfstat(d->fd);
78         if(dir == nil){
79         error:
80                 close(d->fd);
81                 free(d);
82                 return nil;
83         }
84         d->size = dir->length / BLOCK;
85         free(dir);
86         if(d->size == 0){
87                 werrstr("device file too short");
88                 goto error;
89         }
90         d->name = estrdup(file);
91         for(b = d->buf; b < d->buf + BUFHASH + 1; b++)
92                 b->dnext = b->dprev = b;
93         d->workr.l = &d->workl;
94         d->work.wnext = d->work.wprev = &d->work;
95         proccreate(devwork, d, mainstacksize);
96         for(e = &devs; *e != nil; e = &(*e)->next)
97                 ;
98         *e = d;
99         return d;
100 }