]> git.lizzy.rs Git - plan9front.git/blob - sys/src/cmd/disk/kfs/dentry.c
Add Erik Quanstrom's smart tool for ATA SMART.
[plan9front.git] / sys / src / cmd / disk / kfs / dentry.c
1 #include        "all.h"
2
3 Dentry*
4 getdir(Iobuf *p, int slot)
5 {
6         Dentry *d;
7
8         if(!p)
9                 return 0;
10         d = (Dentry*)p->iobuf + slot%DIRPERBUF;
11         return d;
12 }
13
14 void
15 accessdir(Iobuf *p, Dentry *d, int f)
16 {
17         long t;
18
19         if(p && !isro(p->dev)) {
20                 if(!(f & (FWRITE|FWSTAT)) && noatime)
21                         return;
22                 t = time(nil);
23                 if(f & (FREAD|FWRITE|FWSTAT)){
24                         d->atime = t;
25                         p->flags |= Bmod;
26                 }
27                 if(f & FWRITE) {
28                         d->mtime = t;
29                         d->qid.version++;
30                         p->flags |= Bmod;
31                 }
32         }
33 }
34
35 void
36 dbufread(Iobuf *p, Dentry *d, long a)
37 {
38         USED(p, d, a);
39 }
40
41 long
42 rel2abs(Iobuf *p, Dentry *d, long a, int tag, int putb)
43 {
44         long addr, qpath;
45         Device dev;
46
47         if(a < 0) {
48                 print("dnodebuf: neg\n");
49                 return 0;
50         }
51         qpath = d->qid.path;
52         dev = p->dev;
53         if(a < NDBLOCK) {
54                 addr = d->dblock[a];
55                 if(!addr && tag) {
56                         addr = balloc(dev, tag, qpath);
57                         d->dblock[a] = addr;
58                         p->flags |= Bmod|Bimm;
59                 }
60                 if(putb)
61                         putbuf(p);
62                 return addr;
63         }
64         a -= NDBLOCK;
65         if(a < INDPERBUF) {
66                 addr = d->iblock;
67                 if(!addr && tag) {
68                         addr = balloc(dev, Tind1, qpath);
69                         d->iblock = addr;
70                         p->flags |= Bmod|Bimm;
71                 }
72                 if(putb)
73                         putbuf(p);
74                 addr = indfetch(p, d, addr, a, Tind1, tag);
75                 return addr;
76         }
77         a -= INDPERBUF;
78         if(a < INDPERBUF2) {
79                 addr = d->diblock;
80                 if(!addr && tag) {
81                         addr = balloc(dev, Tind2, qpath);
82                         d->diblock = addr;
83                         p->flags |= Bmod|Bimm;
84                 }
85                 if(putb)
86                         putbuf(p);
87                 addr = indfetch(p, d, addr, a/INDPERBUF, Tind2, Tind1);
88                 addr = indfetch(p, d, addr, a%INDPERBUF, Tind1, tag);
89                 return addr;
90         }
91         if(putb)
92                 putbuf(p);
93         print("dnodebuf: trip indirect\n");
94         return 0;
95 }
96
97 Iobuf*
98 dnodebuf(Iobuf *p, Dentry *d, long a, int tag)
99 {
100         long addr;
101
102         addr = rel2abs(p, d, a, tag, 0);
103         if(addr)
104                 return getbuf(p->dev, addr, Bread);
105         return 0;
106 }
107
108 /*
109  * same as dnodebuf but it calls putpuf(p)
110  * to reduce interference.
111  */
112 Iobuf*
113 dnodebuf1(Iobuf *p, Dentry *d, long a, int tag)
114 {
115         long addr;
116         Device dev;
117
118         dev = p->dev;
119         addr = rel2abs(p, d, a, tag, 1);
120         if(addr)
121                 return getbuf(dev, addr, Bread);
122         return 0;
123
124 }
125
126 long
127 indfetch(Iobuf *p, Dentry *d, long addr, long a, int itag, int tag)
128 {
129         Iobuf *bp;
130
131         if(!addr)
132                 return 0;
133         bp = getbuf(p->dev, addr, Bread);
134         if(!bp || checktag(bp, itag, d->qid.path)) {
135                 if(!bp) {
136                         print("ind fetch bp = 0\n");
137                         return 0;
138                 }
139                 print("ind fetch tag\n");
140                 putbuf(bp);
141                 return 0;
142         }
143         addr = ((long*)bp->iobuf)[a];
144         if(!addr && tag) {
145                 addr = balloc(p->dev, tag, d->qid.path);
146                 if(addr) {
147                         ((long*)bp->iobuf)[a] = addr;
148                         bp->flags |= Bmod;
149                         if(localfs || tag == Tdir)
150                                 bp->flags |= Bimm;
151                         settag(bp, itag, d->qid.path);
152                 }
153         }
154         putbuf(bp);
155         return addr;
156 }
157
158 void
159 dtrunc(Iobuf *p, Dentry *d)
160 {
161         int i;
162
163         bfree(p->dev, d->diblock, 2);
164         d->diblock = 0;
165         bfree(p->dev, d->iblock, 1);
166         d->iblock = 0;
167         for(i=NDBLOCK-1; i>=0; i--) {
168                 bfree(p->dev, d->dblock[i], 0);
169                 d->dblock[i] = 0;
170         }
171         d->size = 0;
172         p->flags |= Bmod|Bimm;
173         accessdir(p, d, FWRITE);
174 }