From: Simon Wilkinson Date: Mon, 26 Jan 2009 13:42:15 +0000 (+0000) Subject: DEVEL15-disconnected-lseek-extension-20090126 X-Git-Tag: openafs-devel-1_5_58~179 X-Git-Url: https://git.michaelhowe.org/gitweb/?a=commitdiff_plain;h=f93da82161979d25b5bf377a98837fe1f684a42e;p=packages%2Fo%2Fopenafs.git DEVEL15-disconnected-lseek-extension-20090126 LICENSE IPL10 FIXES 124200 make extending a file by lseek make the extension-created parts as cache chunks (cherry picked from commit 7a01a35adfc8f3124a259e682ea1555cb9ed7df2) --- diff --git a/src/afs/VNOPS/afs_vnop_write.c b/src/afs/VNOPS/afs_vnop_write.c index 25189f85d..27faba07c 100644 --- a/src/afs/VNOPS/afs_vnop_write.c +++ b/src/afs/VNOPS/afs_vnop_write.c @@ -264,6 +264,10 @@ afs_MemWrite(register struct vcache *avc, struct uio *auio, int aio, osi_Assert(filePos <= avc->m.Length); #else if (filePos > avc->m.Length) { +#if AFS_DISCON_ENV + if (AFS_IS_DISCON_RW) + afs_PopulateDCache(avc, filePos, &treq); +#endif afs_Trace4(afs_iclSetp, CM_TRACE_SETLENGTH, ICL_TYPE_STRING, __FILE__, ICL_TYPE_LONG, __LINE__, ICL_TYPE_OFFSET, ICL_HANDLE_OFFSET(avc->m.Length), ICL_TYPE_OFFSET, @@ -572,6 +576,10 @@ afs_UFSWrite(register struct vcache *avc, struct uio *auio, int aio, osi_Assert(filePos <= avc->m.Length); #else if (filePos > avc->m.Length) { +# ifdef AFS_DISCON_ENV + if (AFS_IS_DISCON_RW) + afs_PopulateDCache(avc, filePos, &treq); +# endif afs_Trace4(afs_iclSetp, CM_TRACE_SETLENGTH, ICL_TYPE_STRING, __FILE__, ICL_TYPE_LONG, __LINE__, ICL_TYPE_OFFSET, ICL_HANDLE_OFFSET(avc->m.Length), ICL_TYPE_OFFSET, diff --git a/src/afs/afs_dcache.c b/src/afs/afs_dcache.c index 252798201..3d5a9eecf 100644 --- a/src/afs/afs_dcache.c +++ b/src/afs/afs_dcache.c @@ -3911,4 +3911,46 @@ void afs_DeleteShadowDir(struct vcache *avc) QRemove(&avc->shadowq); ReleaseWriteLock(&afs_disconDirtyLock); } + +/*! + * Populate a dcache with empty chunks up to a given file size, + * used before extending a file in order to avoid 'holes' which + * we can't access in disconnected mode. + * + * \param avc The vcache which is being extended (locked) + * \param alen The new length of the file + * + */ +void afs_PopulateDCache(struct vcache *avc, afs_size_t apos, struct vrequest *areq) { + struct dcache *tdc; + afs_size_t len, offset; + afs_int32 start, end; + + /* We're doing this to deal with the situation where we extend + * by writing after lseek()ing past the end of the file . If that + * extension skips chunks, then those chunks won't be created, and + * GetDCache will assume that they have to be fetched from the server. + * So, for each chunk between the current file position, and the new + * length we GetDCache for that chunk. + */ + + if (AFS_CHUNK(apos) == 0 || apos <= avc->m.Length) + return; + + if (avc->m.Length == 0) + start = 0; + else + start = AFS_CHUNK(avc->m.Length)+1; + + end = AFS_CHUNK(apos); + + while (start