X-Git-Url: http://git.openafs.org/?p=openafs.git;a=blobdiff_plain;f=src%2Flibafscp%2Fafscp_fid.c;h=536f8f1fdc99eddbe0221580b2ac78fbe89263a1;hp=a85fde2ee5335a5f05f6f9b2ee8bd0370172cbc9;hb=53377153eca062ae6252dc8c71e7f6cb16214076;hpb=f2e91cc3fe61956e7661eae9da82ddf746e63824 diff --git a/src/libafscp/afscp_fid.c b/src/libafscp/afscp_fid.c index a85fde2..536f8f1 100644 --- a/src/libafscp/afscp_fid.c +++ b/src/libafscp/afscp_fid.c @@ -24,217 +24,255 @@ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +#include #include -#include + +#include + +#include + #include #include -#include -#include -#include -#include -#include -#include #include "afscp.h" #include "afscp_internal.h" -struct afs_venusfid *makefid(struct afs_cell *cell, afs_uint32 volume, - afs_uint32 vnode, afs_uint32 unique) +/* + * Allocate and populate an afscp_venusfid struct from component parts + */ +struct afscp_venusfid * +afscp_MakeFid(struct afscp_cell *cell, afs_uint32 volume, + afs_uint32 vnode, afs_uint32 unique) { - struct afs_venusfid *ret; - - if (!cell) - return NULL; - ret=malloc(sizeof(struct afs_venusfid)); - if (!ret) { - afs_errno=errno; - return NULL; - } - ret->cell=cell; - ret->fid.Volume=volume; - ret->fid.Vnode=vnode; - ret->fid.Unique=unique; - return ret; + struct afscp_venusfid *ret; + + if (cell == NULL) { + return NULL; + } + ret = malloc(sizeof(struct afscp_venusfid)); + if (ret == NULL) { + afscp_errno = errno; + return NULL; + } + ret->cell = cell; + ret->fid.Volume = volume; + ret->fid.Vnode = vnode; + ret->fid.Unique = unique; + return ret; } -struct afs_venusfid *dupfid(const struct afs_venusfid *in) +/* + * Duplicate an existing afscp_venusfid struct + */ +struct afscp_venusfid * +afscp_DupFid(const struct afscp_venusfid *in) { - struct afs_venusfid *ret; - - ret=malloc(sizeof(struct afs_venusfid)); - if (!ret) { - afs_errno=errno; - return NULL; - } - ret->cell=in->cell; - ret->fid.Volume=in->fid.Volume; - ret->fid.Vnode=in->fid.Vnode; - ret->fid.Unique=in->fid.Unique; - return ret; + struct afscp_venusfid *ret; + + ret = malloc(sizeof(struct afscp_venusfid)); + if (ret == NULL) { + afscp_errno = errno; + return NULL; + } + ret->cell = in->cell; + ret->fid.Volume = in->fid.Volume; + ret->fid.Vnode = in->fid.Vnode; + ret->fid.Unique = in->fid.Unique; + return ret; } - -static int statcompare(const void *a, const void *b) +void +afscp_FreeFid(struct afscp_venusfid *avfp) { - const struct afs_statent *sa=a,*sb=b; - if (sa->me.fid.Vnode < sb->me.fid.Vnode) return -1; - if (sa->me.fid.Vnode > sb->me.fid.Vnode) return 1; - if (sa->me.fid.Unique < sb->me.fid.Unique) return -1; - if (sa->me.fid.Unique > sb->me.fid.Unique) return 1; - return 0; + if (avfp != NULL) + free(avfp); } - -int afs_GetStatus(const struct afs_venusfid *fid, struct AFSFetchStatus *s) +static int +statcompare(const void *a, const void *b) { - struct afs_volume *v; - struct afs_server *server; - struct AFSCallBack cb; - struct AFSVolSync vs; - struct AFSFid tf = fid->fid; - struct afs_statent *stored,key; - void *cached; - - int code,i,j; - - v=afs_volumebyid(fid->cell, fid->fid.Volume); - if (!v) - return -1; - memset(&key, 0, sizeof(key)); - memcpy(&key.me,fid,sizeof(*fid)); - - cached=tfind(&key, &v->statcache, statcompare); - if (cached) { - stored=*(struct afs_statent **)cached; - memmove(s, &stored->status,sizeof(*s)); - afscp_dprintf(("Stat %u.%lu.%lu.%lu returning cached result\n", - fid->cell->id, fid->fid.Volume, fid->fid.Vnode, fid->fid.Unique)); - return 0; - } - - - code=ENOENT; - for (i=0;inservers;i++) { - server=afs_serverbyindex(v->servers[i]); - if (server && server->naddrs > 0) { - for (j=0;j < server->naddrs;j++) { - code=RXAFS_FetchStatus(server->conns[j], &tf, s, &cb, &vs); - if (!code) { - AddCallBack(server, &fid->fid, s, &cb); /* calls _StatStuff */ - afscp_dprintf(("Stat %u.%" PRIu32 ".%" PRIu32 ".%" PRIu32 " ok: type %" PRId32 " size %" PRId32 "\n", - fid->cell->id, fid->fid.Volume, fid->fid.Vnode, fid->fid.Unique, s->FileType, s->Length)); - return 0; - } - } - } - } - afs_errno=code; - return -1; + const struct afscp_statent *sa = a, *sb = b; + if (sa->me.fid.Vnode < sb->me.fid.Vnode) + return -1; + if (sa->me.fid.Vnode > sb->me.fid.Vnode) + return 1; + if (sa->me.fid.Unique < sb->me.fid.Unique) + return -1; + if (sa->me.fid.Unique > sb->me.fid.Unique) + return 1; + return 0; } - - -int afs_stat(const struct afs_venusfid *fid, struct stat *s) +int +afscp_GetStatus(const struct afscp_venusfid *fid, struct AFSFetchStatus *s) { - - struct AFSFetchStatus status; - int code; - - code=afs_GetStatus(fid, &status); - if (code) - return code; - - if (status.FileType==File) - s->st_mode=S_IFREG; - else if (status.FileType==Directory) - s->st_mode=S_IFDIR; - else if (status.FileType==SymbolicLink) - s->st_mode=S_IFLNK; - else { - afs_errno=EINVAL; - return -1; - } - s->st_mode |= (status.UnixModeBits & (~S_IFMT)); - s->st_nlink = status.LinkCount; - s->st_size =status.Length; - s->st_uid =status.Owner; - /*s->st_blksize=status.SegSize;*/ - s->st_atime=s->st_mtime=status.ClientModTime; - s->st_ctime=status.ServerModTime; - s->st_gid = status.Group; - return 0; + struct afscp_volume *v; + struct afscp_server *server; + struct AFSCallBack cb; + struct AFSVolSync vs; + struct AFSFid tf = fid->fid; + struct afscp_statent *stored, key; + void *cached; + int code, i, j; + time_t now; + + v = afscp_VolumeById(fid->cell, fid->fid.Volume); + if (v == NULL) { + return -1; + } + memset(&key, 0, sizeof(key)); + memcpy(&key.me, fid, sizeof(*fid)); + + cached = tfind(&key, &v->statcache, statcompare); + if (cached != NULL) { + stored = *(struct afscp_statent **)cached; + memmove(s, &stored->status, sizeof(*s)); + afs_dprintf(("Stat %u.%lu.%lu.%lu returning cached result\n", + fid->cell->id, fid->fid.Volume, fid->fid.Vnode, + fid->fid.Unique)); + return 0; + } + + code = ENOENT; + for (i = 0; i < v->nservers; i++) { + server = afscp_ServerByIndex(v->servers[i]); + if (server && server->naddrs > 0) { + for (j = 0; j < server->naddrs; j++) { + time(&now); + code = RXAFS_FetchStatus(server->conns[j], &tf, s, &cb, &vs); + if (code == 0) { + afscp_AddCallBack(server, &fid->fid, s, &cb, now); /* calls _StatStuff */ + afs_dprintf(("Stat %d.%lu.%lu.%lu" + " ok: type %ld size %ld\n", + fid->cell->id, + afs_printable_uint32_lu(fid->fid.Volume), + afs_printable_uint32_lu(fid->fid.Vnode), + afs_printable_uint32_lu(fid->fid.Unique), + afs_printable_int32_ld(s->FileType), + afs_printable_int32_ld(s->Length))); + return 0; + } + } + } + } + afscp_errno = code; + return -1; } +int +afscp_Stat(const struct afscp_venusfid *fid, struct stat *s) +{ -int _StatInvalidate(const struct afs_venusfid *fid) { - struct afs_volume *v; - struct afs_statent key; - void **cached; - - v=afs_volumebyid(fid->cell, fid->fid.Volume); - if (!v) - return -1; - memmove(&key.me,fid,sizeof(*fid)); + struct AFSFetchStatus status; + int code; + + + if (s == NULL || fid == NULL) { + fprintf(stderr, "NULL args given to afscp_Stat, cannot continue\n"); + return -1; + } + + code = afscp_GetStatus(fid, &status); + if (code != 0) { + return code; + } + + if (status.FileType == File) + s->st_mode = S_IFREG; + else if (status.FileType == Directory) + s->st_mode = S_IFDIR; + else if (status.FileType == SymbolicLink) + s->st_mode = S_IFLNK; + else { + afscp_errno = EINVAL; + return -1; + } + s->st_mode |= (status.UnixModeBits & (~S_IFMT)); + s->st_nlink = status.LinkCount; + s->st_size = status.Length; + s->st_uid = status.Owner; + /*s->st_blksize=status.SegSize; */ + s->st_atime = s->st_mtime = status.ClientModTime; + s->st_ctime = status.ServerModTime; + s->st_gid = status.Group; + return 0; +} - cached=tfind(&key, &v->statcache, statcompare); - if (cached) { - free(*cached); - tdelete(&key, &v->statcache, statcompare); - } - return 0; +int +_StatInvalidate(const struct afscp_venusfid *fid) +{ + struct afscp_volume *v; + struct afscp_statent key; + void **cached; + + v = afscp_VolumeById(fid->cell, fid->fid.Volume); + if (v == NULL) { + return -1; + } + memmove(&key.me, fid, sizeof(*fid)); + + cached = tfind(&key, &v->statcache, statcompare); + if (cached != NULL) { + free(*cached); + tdelete(&key, &v->statcache, statcompare); + } + return 0; } -int _StatStuff(const struct afs_venusfid *fid, const struct AFSFetchStatus *s) { - struct afs_volume *v; - struct afs_statent key, *stored; - void **cached; - - v=afs_volumebyid(fid->cell, fid->fid.Volume); - if (!v) - return -1; - memmove(&key.me,fid,sizeof(*fid)); - - cached=tsearch(&key, &v->statcache, statcompare); - if (cached) { - stored=malloc(sizeof(struct afs_statent)); - if (stored) { - memmove(&stored->me, fid, sizeof(*fid)); - memmove(&stored->status,s,sizeof(*s)); - *(struct afs_statent **)cached=stored; - } else { - tdelete(&key, &v->statcache, statcompare); - } - } - return 0; +int +_StatStuff(const struct afscp_venusfid *fid, const struct AFSFetchStatus *s) +{ + struct afscp_volume *v; + struct afscp_statent key, *stored; + void **cached; + + v = afscp_VolumeById(fid->cell, fid->fid.Volume); + if (v == NULL) { + return -1; + } + memmove(&key.me, fid, sizeof(*fid)); + + cached = tsearch(&key, &v->statcache, statcompare); + if (cached != NULL) { + stored = malloc(sizeof(struct afscp_statent)); + if (stored != NULL) { + memmove(&stored->me, fid, sizeof(*fid)); + memmove(&stored->status, s, sizeof(*s)); + *(struct afscp_statent **)cached = stored; + } else { + tdelete(&key, &v->statcache, statcompare); + } + } + return 0; } -int afs_StoreStatus(const struct afs_venusfid *fid, struct AFSStoreStatus *s) +int +afscp_StoreStatus(const struct afscp_venusfid *fid, struct AFSStoreStatus *s) { - struct afs_volume *v; - struct afs_server *server; - struct AFSCallBack cb; - struct AFSVolSync vs; - struct AFSFetchStatus fst; - struct AFSFid tf = fid->fid; - int code,i,j; - - v=afs_volumebyid(fid->cell, fid->fid.Volume); - if (!v) - return -1; - - - code=ENOENT; - for (i=0;inservers;i++) { - server=afs_serverbyindex(v->servers[i]); - if (server && server->naddrs > 0) { - for (j=0;j < server->naddrs;j++) { - code=RXAFS_StoreStatus(server->conns[j], &tf, s, &fst, &vs); - if (!code) { - _StatStuff(fid, &fst); /* calls _StatStuff */ - return 0; - } - } - } - } - afs_errno=code; - return -1; + struct afscp_volume *v; + struct afscp_server *server; + struct AFSVolSync vs; + struct AFSFetchStatus fst; + struct AFSFid tf = fid->fid; + int code, i, j; + + v = afscp_VolumeById(fid->cell, fid->fid.Volume); + if (v == NULL) { + return -1; + } + + code = ENOENT; + for (i = 0; i < v->nservers; i++) { + server = afscp_ServerByIndex(v->servers[i]); + if (server && server->naddrs > 0) { + for (j = 0; j < server->naddrs; j++) { + code = RXAFS_StoreStatus(server->conns[j], &tf, s, &fst, &vs); + if (code == 0) { + _StatStuff(fid, &fst); /* calls _StatStuff */ + return 0; + } + } + } + } + afscp_errno = code; + return -1; }