]> git.lizzy.rs Git - plan9front.git/blob - sys/src/cmd/disk/kfs/devwren.c
Add Erik Quanstrom's smart tool for ATA SMART.
[plan9front.git] / sys / src / cmd / disk / kfs / devwren.c
1 #include "all.h"
2
3 enum{
4         MAXWREN = 7,
5 };
6
7 #define WMAGIC  "kfs wren device\n"
8
9 typedef struct Wren     Wren;
10
11 struct Wren{
12         QLock;
13         Device  dev;
14         uvlong  size;
15         int     fd;
16 };
17
18 static Wren     *wrens;
19 static int      maxwren;
20 char            *wrenfile;
21 int             nwren;
22 int             badmagic;
23
24 static Wren *
25 wren(Device dev)
26 {
27         int i;
28
29         for(i = 0; i < maxwren; i++)
30                 if(devcmp(dev, wrens[i].dev) == 0)
31                         return &wrens[i];
32         panic("can't find wren for %D", dev);
33         return 0;
34 }
35
36 void
37 wreninit(Device dev)
38 {
39         char buf[MAXBUFSIZE];
40         Wren *w;
41         Dir *d;
42         int fd, i;
43
44         if(wrens == 0)
45                 wrens = ialloc(MAXWREN * sizeof *wrens);
46         w = &wrens[maxwren];
47         fd = open(wrenfile, ORDWR);
48         if(fd < 0)
49                 panic("can't open %s", wrenfile);
50         if((d = dirfstat(fd)) == nil)
51                 panic("can't stat %s\n", wrenfile);
52         seek(fd, 0, 0);
53         i = read(fd, buf, sizeof buf);
54         if(i < sizeof buf)
55                 panic("can't read %s", wrenfile);
56         badmagic = 0;
57         RBUFSIZE = 1024;
58         if(strncmp(buf+256, WMAGIC, strlen(WMAGIC)) == 0){
59                 RBUFSIZE = atol(buf+256+strlen(WMAGIC));
60                 if(RBUFSIZE % 512){
61                         fprint(2, "kfs: bad buffersize(%d): assuming 1k blocks\n", RBUFSIZE);
62                         RBUFSIZE = 1024;
63                 }
64         }else
65                 badmagic = 1;
66         w->dev = dev;
67         w->size = d->length;
68         free(d);
69         w->fd = fd;
70         maxwren++;
71 }
72
73 void
74 wrenream(Device dev)
75 {
76         Wren *w;
77         char buf[MAXBUFSIZE];
78         int fd, i;
79
80         if(RBUFSIZE % 512)
81                 panic("kfs: bad buffersize(%d): restart a multiple of 512\n", RBUFSIZE);
82         if(RBUFSIZE > sizeof(buf))
83                 panic("kfs: bad buffersize(%d): must be at most %d\n", RBUFSIZE, sizeof(buf));
84
85         print("kfs: reaming the file system using %d byte blocks\n", RBUFSIZE);
86         w = wren(dev);
87         fd = w->fd;
88         memset(buf, 0, sizeof buf);
89         sprint(buf+256, "%s%d\n", WMAGIC, RBUFSIZE);
90         qlock(w);
91         i = seek(fd, 0, 0) < 0 || write(fd, buf, RBUFSIZE) != RBUFSIZE;
92         qunlock(w);
93         if(i < 0)
94                 panic("can't ream disk");
95 }
96
97 int
98 wrentag(char *p, int tag, long qpath)
99 {
100         Tag *t;
101
102         t = (Tag*)(p+BUFSIZE);
103         return t->tag != tag || (qpath&~QPDIR) != t->path;
104 }
105
106 int
107 wrencheck(Device dev)
108 {
109         char buf[MAXBUFSIZE];
110
111         if(badmagic)
112                 return 1;
113         if(RBUFSIZE > sizeof(buf))
114                 panic("kfs: bad buffersize(%d): must be at most %d\n", RBUFSIZE, sizeof(buf));
115
116         if(wrenread(dev, wrensuper(dev), buf) || wrentag(buf, Tsuper, QPSUPER)
117         || wrenread(dev, wrenroot(dev), buf) || wrentag(buf, Tdir, QPROOT))
118                 return 1;
119         if(((Dentry *)buf)[0].mode & DALLOC)
120                 return 0;
121         return 1;
122 }
123
124 long
125 wrensize(Device dev)
126 {
127         return wren(dev)->size / RBUFSIZE;
128 }
129
130 long
131 wrensuper(Device dev)
132 {
133         USED(dev);
134         return 1;
135 }
136
137 long
138 wrenroot(Device dev)
139 {
140         USED(dev);
141         return 2;
142 }
143
144 int
145 wrenread(Device dev, long addr, void *b)
146 {
147         Wren *w;
148         int fd, i;
149
150         w = wren(dev);
151         fd = w->fd;
152         qlock(w);
153         i = seek(fd, (vlong)addr*RBUFSIZE, 0) == -1 || read(fd, b, RBUFSIZE) != RBUFSIZE;
154         qunlock(w);
155         if(i)
156                 print("wrenread failed: %r\n");
157         return i;
158 }
159
160 int
161 wrenwrite(Device dev, long addr, void *b)
162 {
163         Wren *w;
164         int fd, i;
165
166         w = wren(dev);
167         fd = w->fd;
168         qlock(w);
169         i = seek(fd, (vlong)addr*RBUFSIZE, 0) == -1 || write(fd, b, RBUFSIZE) != RBUFSIZE;
170         qunlock(w);
171         if(i)
172                 print("wrenwrite failed: %r\n");
173         return i;
174 }