mirror of
https://git.openafs.org/openafs.git
synced 2025-01-22 17:00:15 +00:00
9bf314d90a
The afs_write() code for memory and disk cache suffered from exactly the same duplication problems as the afs_read() code. Apply a similar fix - unify afs_UFSWrite and afs_MemWrite into a single afs_write function, place the UFS specific code into afs_UFSWriteUIO, and make use of the existing afs_MemWriteUIO for the memcache case. Change-Id: I074e1f56597e5cf04d13a45bcda5ad5fedb6377f Reviewed-on: http://gerrit.openafs.org/4465 Tested-by: BuildBot <buildbot@rampaginggeek.com> Reviewed-by: Derrick Brashear <shadow@dementia.org>
97 lines
3.8 KiB
C
97 lines
3.8 KiB
C
/*
|
|
* Copyright 2000, International Business Machines Corporation and others.
|
|
* All Rights Reserved.
|
|
*
|
|
* This software has been released under the terms of the IBM Public
|
|
* License. For details, see the LICENSE file in the top-level source
|
|
* directory or online at http://www.openafs.org/dl/license10.html
|
|
*/
|
|
|
|
#ifndef AFS_CHUNKOPS
|
|
#define AFS_CHUNKOPS 1
|
|
|
|
/* macros to compute useful numbers from offsets. AFS_CHUNK gives the chunk
|
|
number for a given offset; AFS_CHUNKOFFSET gives the offset into the chunk
|
|
and AFS_CHUNKBASE gives the byte offset of the base of the chunk.
|
|
AFS_CHUNKSIZE gives the size of the chunk containing an offset.
|
|
AFS_CHUNKTOBASE converts a chunk # to a base position.
|
|
Chunks are 0 based and go up by exactly 1, covering the file.
|
|
The other fields are internal and shouldn't be used */
|
|
/* basic parameters */
|
|
|
|
#define AFS_OTHERCSIZE (afs_OtherCSize)
|
|
#define AFS_LOGCHUNK (afs_LogChunk)
|
|
#define AFS_FIRSTCSIZE (afs_FirstCSize)
|
|
|
|
#define AFS_DEFAULTCSIZE 0x10000
|
|
#define AFS_DEFAULTLSIZE 16
|
|
|
|
#define AFS_CHUNKOFFSET(offset) ((offset < afs_FirstCSize) ? offset : \
|
|
((offset - afs_FirstCSize) & (afs_OtherCSize - 1)))
|
|
|
|
#define AFS_CHUNK(offset) ((offset < afs_FirstCSize) ? 0 : \
|
|
(((offset - afs_FirstCSize) >> afs_LogChunk) + 1))
|
|
|
|
#define AFS_CHUNKBASE(offset) ((offset < afs_FirstCSize) ? 0 : \
|
|
(((offset - afs_FirstCSize) & ~(afs_OtherCSize - 1)) + afs_FirstCSize))
|
|
|
|
#define AFS_CHUNKSIZE(offset) ((offset < afs_FirstCSize) ? afs_FirstCSize : \
|
|
afs_OtherCSize)
|
|
|
|
#define AFS_CHUNKTOBASE(chunk) ((chunk == 0) ? 0 : \
|
|
((afs_size_t) afs_FirstCSize + ((afs_size_t) (chunk - 1) << afs_LogChunk)))
|
|
|
|
#define AFS_CHUNKTOSIZE(chunk) ((chunk == 0) ? afs_FirstCSize : afs_OtherCSize)
|
|
|
|
/* sizes are a power of two */
|
|
#define AFS_SETCHUNKSIZE(chunk) { afs_LogChunk = chunk; \
|
|
afs_FirstCSize = afs_OtherCSize = (1 << chunk); }
|
|
|
|
/*
|
|
* Functions exported by a cache type
|
|
*/
|
|
|
|
struct afs_cacheOps {
|
|
void *(*open) (afs_dcache_id_t *ainode);
|
|
int (*truncate) (struct osi_file * fp, afs_int32 len);
|
|
int (*fread) (struct osi_file * fp, int offset, void *buf, afs_int32 len);
|
|
int (*fwrite) (struct osi_file * fp, afs_int32 offset, void *buf,
|
|
afs_int32 len);
|
|
int (*close) (struct osi_file * fp);
|
|
int (*vreadUIO) (afs_dcache_id_t *, struct uio *);
|
|
int (*vwriteUIO) (struct vcache *, afs_dcache_id_t *, struct uio *);
|
|
struct dcache *(*GetDSlot) (afs_int32 aslot,
|
|
struct dcache * tmpdc);
|
|
struct volume *(*GetVolSlot) (void);
|
|
int (*HandleLink) (struct vcache * avc, struct vrequest * areq);
|
|
};
|
|
|
|
/* Ideally we should have used consistent naming - like COP_OPEN, COP_TRUNCATE, etc. */
|
|
#define afs_CFileOpen(inode) (void *)(*(afs_cacheType->open))(inode)
|
|
#define afs_CFileTruncate(handle, size) (*(afs_cacheType->truncate))((handle), size)
|
|
#define afs_CFileRead(file, offset, data, size) (*(afs_cacheType->fread))(file, offset, data, size)
|
|
#define afs_CFileWrite(file, offset, data, size) (*(afs_cacheType->fwrite))(file, offset, data, size)
|
|
#define afs_CFileClose(handle) (*(afs_cacheType->close))(handle)
|
|
#define afs_GetDSlot(slot, adc) (*(afs_cacheType->GetDSlot))(slot, adc)
|
|
#define afs_GetVolSlot() (*(afs_cacheType->GetVolSlot))()
|
|
#define afs_HandleLink(avc, areq) (*(afs_cacheType->HandleLink))(avc, areq)
|
|
|
|
/* These memcpys should get optimised to simple assignments when afs_dcache_id_t
|
|
* is simple */
|
|
static_inline void afs_copy_inode(afs_dcache_id_t *dst, afs_dcache_id_t *src) {
|
|
memcpy(dst, src, sizeof(afs_dcache_id_t));
|
|
}
|
|
|
|
static_inline void afs_reset_inode(afs_dcache_id_t *i) {
|
|
memset(i, 0, sizeof(afs_dcache_id_t));
|
|
}
|
|
|
|
/* We need to have something we can output as the 'inode' for fstrace calls.
|
|
* This is a hack */
|
|
static_inline int afs_inode2trace(afs_dcache_id_t *i) {
|
|
return i->mem;
|
|
}
|
|
|
|
|
|
#endif /* AFS_CHUNKOPS */
|