Commit | Line | Data |
---|---|---|
805e021f CE |
1 | /* |
2 | * Copyright 2000, International Business Machines Corporation and others. | |
3 | * All Rights Reserved. | |
4 | * | |
5 | * This software has been released under the terms of the IBM Public | |
6 | * License. For details, see the LICENSE file in the top-level source | |
7 | * directory or online at http://www.openafs.org/dl/license10.html | |
8 | */ | |
9 | ||
10 | #ifndef AFS_CHUNKOPS | |
11 | #define AFS_CHUNKOPS 1 | |
12 | ||
13 | /* macros to compute useful numbers from offsets. AFS_CHUNK gives the chunk | |
14 | number for a given offset; AFS_CHUNKOFFSET gives the offset into the chunk | |
15 | and AFS_CHUNKBASE gives the byte offset of the base of the chunk. | |
16 | AFS_CHUNKSIZE gives the size of the chunk containing an offset. | |
17 | AFS_CHUNKTOBASE converts a chunk # to a base position. | |
18 | Chunks are 0 based and go up by exactly 1, covering the file. | |
19 | The other fields are internal and shouldn't be used */ | |
20 | /* basic parameters */ | |
21 | ||
22 | #define AFS_OTHERCSIZE (afs_OtherCSize) | |
23 | #define AFS_LOGCHUNK (afs_LogChunk) | |
24 | #define AFS_FIRSTCSIZE (afs_FirstCSize) | |
25 | ||
26 | #define AFS_DEFAULTCSIZE 0x10000 | |
27 | #define AFS_DEFAULTLSIZE 16 | |
28 | ||
29 | #define AFS_CHUNKOFFSET(offset) ((offset < afs_FirstCSize) ? offset : \ | |
30 | ((offset - afs_FirstCSize) & (afs_OtherCSize - 1))) | |
31 | ||
32 | #define AFS_CHUNK(offset) ((offset < afs_FirstCSize) ? 0 : \ | |
33 | (((offset - afs_FirstCSize) >> afs_LogChunk) + 1)) | |
34 | ||
35 | #define AFS_CHUNKBASE(offset) ((offset < afs_FirstCSize) ? 0 : \ | |
36 | (((offset - afs_FirstCSize) & ~(afs_OtherCSize - 1)) + afs_FirstCSize)) | |
37 | ||
38 | #define AFS_CHUNKSIZE(offset) ((offset < afs_FirstCSize) ? afs_FirstCSize : \ | |
39 | afs_OtherCSize) | |
40 | ||
41 | #define AFS_CHUNKTOBASE(chunk) ((chunk == 0) ? 0 : \ | |
42 | ((afs_size_t) afs_FirstCSize + ((afs_size_t) (chunk - 1) << afs_LogChunk))) | |
43 | ||
44 | #define AFS_CHUNKTOSIZE(chunk) ((chunk == 0) ? afs_FirstCSize : afs_OtherCSize) | |
45 | ||
46 | /* sizes are a power of two */ | |
47 | #define AFS_SETCHUNKSIZE(chunk) { afs_LogChunk = chunk; \ | |
48 | afs_FirstCSize = afs_OtherCSize = (1 << chunk); } | |
49 | ||
50 | /** | |
51 | * The states a dcache slot can be in. | |
52 | */ | |
53 | typedef enum dslot_state { | |
54 | DSLOT_NEW = 0, /**< Use to create a slot if needed. */ | |
55 | DSLOT_UNUSED = 1, /**< Contains a free or discarded dcache. */ | |
56 | DSLOT_VALID = 2, /**< The dcache is known to exist and be valid. */ | |
57 | } dslot_state; | |
58 | ||
59 | /* | |
60 | * Functions exported by a cache type | |
61 | */ | |
62 | ||
63 | struct afs_cacheOps { | |
64 | void *(*open) (afs_dcache_id_t *ainode); | |
65 | int (*truncate) (struct osi_file * fp, afs_int32 len); | |
66 | int (*fread) (struct osi_file * fp, int offset, void *buf, afs_int32 len); | |
67 | int (*fwrite) (struct osi_file * fp, afs_int32 offset, void *buf, | |
68 | afs_int32 len); | |
69 | int (*close) (struct osi_file * fp); | |
70 | int (*vreadUIO) (afs_dcache_id_t *, struct uio *); | |
71 | int (*vwriteUIO) (struct vcache *, afs_dcache_id_t *, struct uio *); | |
72 | struct dcache *(*GetDSlot) (afs_int32 aslot, dslot_state type); | |
73 | struct volume *(*GetVolSlot) (afs_int32 volid, struct cell *cell); | |
74 | int (*HandleLink) (struct vcache * avc, struct vrequest * areq); | |
75 | }; | |
76 | ||
77 | /* Ideally we should have used consistent naming - like COP_OPEN, COP_TRUNCATE, etc. */ | |
78 | #define afs_CFileOpen(inode) (void *)(*(afs_cacheType->open))(inode) | |
79 | #define afs_CFileTruncate(handle, size) (*(afs_cacheType->truncate))((handle), size) | |
80 | #define afs_CFileRead(file, offset, data, size) (*(afs_cacheType->fread))(file, offset, data, size) | |
81 | #define afs_CFileWrite(file, offset, data, size) (*(afs_cacheType->fwrite))(file, offset, data, size) | |
82 | #define afs_CFileClose(handle) (*(afs_cacheType->close))(handle) | |
83 | #define afs_GetVolSlot(volid, cell) (*(afs_cacheType->GetVolSlot))((volid),(cell)) | |
84 | #define afs_HandleLink(avc, areq) (*(afs_cacheType->HandleLink))(avc, areq) | |
85 | ||
86 | /* Use afs_GetValidDSlot to get a dcache from a dcache slot number when we | |
87 | * know the dcache contains data we want (e.g. it's on the hash table) */ | |
88 | #define afs_GetValidDSlot(slot) (*(afs_cacheType->GetDSlot))(slot, DSLOT_VALID) | |
89 | /* Use afs_GetUnusedDSlot when loading a dcache entry that is on the free or | |
90 | * discard lists (the dcache does not contain valid data, but we know the | |
91 | * dcache entry itself exists). */ | |
92 | #define afs_GetUnusedDSlot(slot) (*(afs_cacheType->GetDSlot))(slot, DSLOT_UNUSED) | |
93 | /* Use afs_GetNewDSlot only when initializing dcache slots (the given slot | |
94 | * number may not exist at all). This will always succeed; if we can't find the | |
95 | * given dslot, we will create a new, empty slot. */ | |
96 | #define afs_GetNewDSlot(slot) (*(afs_cacheType->GetDSlot))(slot, DSLOT_NEW) | |
97 | ||
98 | /* These memcpys should get optimised to simple assignments when afs_dcache_id_t | |
99 | * is simple */ | |
100 | static_inline void afs_copy_inode(afs_dcache_id_t *dst, afs_dcache_id_t *src) { | |
101 | memcpy(dst, src, sizeof(afs_dcache_id_t)); | |
102 | } | |
103 | ||
104 | static_inline void afs_reset_inode(afs_dcache_id_t *i) { | |
105 | memset(i, 0, sizeof(afs_dcache_id_t)); | |
106 | } | |
107 | ||
108 | /* We need to have something we can output as the 'inode' for fstrace calls. | |
109 | * This is a hack */ | |
110 | static_inline int afs_inode2trace(afs_dcache_id_t *i) { | |
111 | return i->mem; | |
112 | } | |
113 | ||
114 | ||
115 | #endif /* AFS_CHUNKOPS */ |