* \param[in] adc pointer to directory dcache
* \param[in] page number of the desired directory page
* \param[out] entry buffer to return requested page
+ * \param[out] physerr (optional) pointer to return errno, if any
*
* \retval 0 success
- * \retval non-zero invalid directory or internal IO error
+ * \retval non-zero invalid directory or internal IO error;
+ * if physerr is supplied by caller, it will be set:
+ * 0 logical error
+ * errno physical error
*/
int
-DRead(struct dcache *adc, int page, struct DirBuffer *entry)
+DReadWithErrno(struct dcache *adc, int page, struct DirBuffer *entry, int *physerr)
{
/* Read a page from the disk. */
struct buffer *tb, *tb2;
AFS_STATCNT(DRead);
+ if (physerr != NULL)
+ *physerr = 0;
+
memset(entry, 0, sizeof(struct DirBuffer));
if (adc->f.chunk == 0 && adc->f.chunkBytes == 0) {
AFS_BUFFER_PAGESIZE);
afs_CFileClose(tfile);
if (code < AFS_BUFFER_PAGESIZE) {
+ if (code < 0 && physerr != NULL)
+ *physerr = -code;
code = EIO;
goto error;
}
return code;
}
+/*!
+ * Read and return the requested directory page.
+ *
+ * \param[in] adc pointer to directory dcache
+ * \param[in] page number of the desired directory page
+ * \param[out] entry buffer to return requested page
+ *
+ * \retval 0 success
+ * \retval non-zero invalid directory or internal IO error;
+ */
+int
+DRead(struct dcache *adc, int page, struct DirBuffer *entry)
+{
+ return DReadWithErrno(adc, page, entry, NULL);
+}
+
static void
FixupBucket(struct buffer *ap)
{
if (tp == NULL)
return;
- tp = entry->buffer;
ObtainWriteLock(&tp->lock, 261);
tp->lockers--;
if (flag)
return 0;
}
+/*!
+ * Prepare a new directory page buffer
+ *
+ * \param adc pointer to the directory object dcache
+ * \param nblobs page we want
+ * \param entry buffer to return requested page
+ *
+ * \retval 0 success; entry is updated
+ * \retval non-zero internal error or IO error writing to disk
+ */
int
DNew(struct dcache *adc, int page, struct DirBuffer *entry)
{
/* Same as read, only do *not* even try to read the page, since it
* probably doesn't exist. */
struct buffer *tb;
+ int code;
+
AFS_STATCNT(DNew);
ObtainWriteLock(&afs_bufferLock, 264);
* DFlush due to lock hierarchy issues */
if ((page + 1) * AFS_BUFFER_PAGESIZE > adc->f.chunkBytes) {
afs_AdjustSize(adc, (page + 1) * AFS_BUFFER_PAGESIZE);
- osi_Assert(afs_WriteDCache(adc, 1) == 0);
+ code = afs_WriteDCache(adc, 1);
+ if (code) {
+ ReleaseWriteLock(&afs_bufferLock);
+ return code;
+ }
}
ObtainWriteLock(&tb->lock, 265);
tb->lockers++;