2 Copyright (C) 2003 - 2010 Chaskiel Grundman
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions
9 1. Redistributions of source code must retain the above copyright
10 notice, this list of conditions and the following disclaimer.
12 2. Redistributions in binary form must reproduce the above copyright
13 notice, this list of conditions and the following disclaimer in the
14 documentation and/or other materials provided with the distribution.
16 THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21 NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 #include <afs/param.h>
28 #include <afs/afsint.h>
29 #include <afs/vlserver.h>
30 #include <afs/vldbint.h>
38 #include "afscp_internal.h"
40 struct afs_venusfid *makefid(struct afs_cell *cell, afs_uint32 volume,
41 afs_uint32 vnode, afs_uint32 unique)
43 struct afs_venusfid *ret;
47 ret=malloc(sizeof(struct afs_venusfid));
53 ret->fid.Volume=volume;
55 ret->fid.Unique=unique;
59 struct afs_venusfid *dupfid(const struct afs_venusfid *in)
61 struct afs_venusfid *ret;
63 ret=malloc(sizeof(struct afs_venusfid));
69 ret->fid.Volume=in->fid.Volume;
70 ret->fid.Vnode=in->fid.Vnode;
71 ret->fid.Unique=in->fid.Unique;
76 static int statcompare(const void *a, const void *b)
78 const struct afs_statent *sa=a,*sb=b;
79 if (sa->me.fid.Vnode < sb->me.fid.Vnode) return -1;
80 if (sa->me.fid.Vnode > sb->me.fid.Vnode) return 1;
81 if (sa->me.fid.Unique < sb->me.fid.Unique) return -1;
82 if (sa->me.fid.Unique > sb->me.fid.Unique) return 1;
87 int afs_GetStatus(const struct afs_venusfid *fid, struct AFSFetchStatus *s)
90 struct afs_server *server;
91 struct AFSCallBack cb;
93 struct AFSFid tf = fid->fid;
94 struct afs_statent *stored,key;
99 v=afs_volumebyid(fid->cell, fid->fid.Volume);
102 memset(&key, 0, sizeof(key));
103 memcpy(&key.me,fid,sizeof(*fid));
105 cached=tfind(&key, &v->statcache, statcompare);
107 stored=*(struct afs_statent **)cached;
108 memmove(s, &stored->status,sizeof(*s));
109 afscp_dprintf(("Stat %u.%lu.%lu.%lu returning cached result\n",
110 fid->cell->id, fid->fid.Volume, fid->fid.Vnode, fid->fid.Unique));
116 for (i=0;i<v->nservers;i++) {
117 server=afs_serverbyindex(v->servers[i]);
118 if (server && server->naddrs > 0) {
119 for (j=0;j < server->naddrs;j++) {
120 code=RXAFS_FetchStatus(server->conns[j], &tf, s, &cb, &vs);
122 AddCallBack(server, &fid->fid, s, &cb); /* calls _StatStuff */
123 afscp_dprintf(("Stat %u.%" PRIu32 ".%" PRIu32 ".%" PRIu32 " ok: type %" PRId32 " size %" PRId32 "\n",
124 fid->cell->id, fid->fid.Volume, fid->fid.Vnode, fid->fid.Unique, s->FileType, s->Length));
136 int afs_stat(const struct afs_venusfid *fid, struct stat *s)
139 struct AFSFetchStatus status;
142 code=afs_GetStatus(fid, &status);
146 if (status.FileType==File)
148 else if (status.FileType==Directory)
150 else if (status.FileType==SymbolicLink)
156 s->st_mode |= (status.UnixModeBits & (~S_IFMT));
157 s->st_nlink = status.LinkCount;
158 s->st_size =status.Length;
159 s->st_uid =status.Owner;
160 /*s->st_blksize=status.SegSize;*/
161 s->st_atime=s->st_mtime=status.ClientModTime;
162 s->st_ctime=status.ServerModTime;
163 s->st_gid = status.Group;
168 int _StatInvalidate(const struct afs_venusfid *fid) {
169 struct afs_volume *v;
170 struct afs_statent key;
173 v=afs_volumebyid(fid->cell, fid->fid.Volume);
176 memmove(&key.me,fid,sizeof(*fid));
178 cached=tfind(&key, &v->statcache, statcompare);
181 tdelete(&key, &v->statcache, statcompare);
186 int _StatStuff(const struct afs_venusfid *fid, const struct AFSFetchStatus *s) {
187 struct afs_volume *v;
188 struct afs_statent key, *stored;
191 v=afs_volumebyid(fid->cell, fid->fid.Volume);
194 memmove(&key.me,fid,sizeof(*fid));
196 cached=tsearch(&key, &v->statcache, statcompare);
198 stored=malloc(sizeof(struct afs_statent));
200 memmove(&stored->me, fid, sizeof(*fid));
201 memmove(&stored->status,s,sizeof(*s));
202 *(struct afs_statent **)cached=stored;
204 tdelete(&key, &v->statcache, statcompare);
210 int afs_StoreStatus(const struct afs_venusfid *fid, struct AFSStoreStatus *s)
212 struct afs_volume *v;
213 struct afs_server *server;
214 struct AFSCallBack cb;
215 struct AFSVolSync vs;
216 struct AFSFetchStatus fst;
217 struct AFSFid tf = fid->fid;
220 v=afs_volumebyid(fid->cell, fid->fid.Volume);
226 for (i=0;i<v->nservers;i++) {
227 server=afs_serverbyindex(v->servers[i]);
228 if (server && server->naddrs > 0) {
229 for (j=0;j < server->naddrs;j++) {
230 code=RXAFS_StoreStatus(server->conns[j], &tf, s, &fst, &vs);
232 _StatStuff(fid, &fst); /* calls _StatStuff */