extern int afs_notify_change(struct dentry *dp, struct iattr *iattrp);
+
+/* This function converts a positive error code from AFS into a negative
+ * code suitable for passing into the Linux VFS layer. It checks that the
+ * error code is within the permissable bounds for the ERR_PTR mechanism.
+ *
+ * _All_ error codes which come from the AFS layer should be passed through
+ * this function before being returned to the kernel.
+ */
+
+static inline int afs_convert_code(int code) {
+ if ((code >= 0) && (code <= MAX_ERRNO))
+ return -code;
+ else
+ return -EIO;
+}
+
static ssize_t
afs_linux_read(struct file *fp, char *buf, size_t count, loff_t * offp)
{
code = afs_VerifyVCache(vcp, &treq);
if (code)
- code = -code;
+ code = afs_convert_code(code);
else {
osi_FlushPages(vcp, credp); /* ensure stale pages are gone */
AFS_GUNLOCK();
afs_FakeOpen(vcp);
ReleaseWriteLock(&vcp->lock);
if (code)
- code = -code;
+ code = afs_convert_code(code);
else {
AFS_GUNLOCK();
#ifdef DO_SYNC_READ
code = afs_InitReq(&treq, credp);
crfree(credp);
- if (code)
+ if (code) {
+ code = afs_convert_code(code);
goto out1;
+ }
afs_InitFakeStat(&fakestat);
code = afs_EvalFakeStat(&avc, &fakestat, &treq);
- if (code)
+ if (code) {
+ code = afs_convert_code(code);
goto out;
+ }
/* update the cache entry */
tagain:
code = afs_VerifyVCache(avc, &treq);
- if (code)
+ if (code) {
+ code = afs_convert_code(code);
goto out;
+ }
/* get a reference to the entire directory */
tdc = afs_GetDCache(avc, (afs_size_t) 0, &treq, &origOffset, &tlen, 1);
return code;
out_err:
- code = -code;
+ code = afs_convert_code(code);
goto out;
}
#endif
crfree(credp);
- return -code;
+ return afs_convert_code(code);
}
static int
#endif
crfree(credp);
- return -code;
+ return afs_convert_code(code);
}
static int
unlock_kernel();
#endif
crfree(credp);
- return -code;
+ return afs_convert_code(code);
}
flp->fl_end = flock.l_start + flock.l_len;
crfree(credp);
- return -code;
+ return afs_convert_code(code);
}
#ifdef STRUCT_FILE_OPERATIONS_HAS_FLOCK
flp->fl_pid = flock.l_pid;
crfree(credp);
- return -code;
+ return afs_convert_code(code);
}
#endif
AFS_GUNLOCK();
crfree(credp);
- return -code;
+ return afs_convert_code(code);
}
#if !defined(AFS_LINUX24_ENV)
#endif
crfree(credp);
- return -code;
+ return afs_convert_code(code);
}
#if defined(AFS_LINUX26_ENV)
unlock_kernel();
#endif
crfree(credp);
- return -code;
+ return afs_convert_code(code);
}
/* afs_linux_lookup */
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,10)
if (code == ENOENT)
return ERR_PTR(0);
- else if ((code >= 0) && (code <= MAX_ERRNO))
- return ERR_PTR(-code);
- else
- return ERR_PTR(-EIO);
+ else
+ return ERR_PTR(afs_convert_code(code));
#else
if (code == ENOENT)
code = 0;
- return -code;
+ return afs_convert_code(code);
#endif
}
AFS_GUNLOCK();
crfree(credp);
- return -code;
+ return afs_convert_code(code);
}
static int
unlock_kernel();
#endif
crfree(credp);
- return -code;
+ return afs_convert_code(code);
}
code = afs_symlink(VTOAFS(dip), name, &vattr, target, credp);
AFS_GUNLOCK();
crfree(credp);
- return -code;
+ return afs_convert_code(code);
}
static int
unlock_kernel();
#endif
crfree(credp);
- return -code;
+ return afs_convert_code(code);
}
static int
}
crfree(credp);
- return -code;
+ return afs_convert_code(code);
}
#endif
crfree(credp);
- return -code;
+ return afs_convert_code(code);
}
if (!code)
return maxlen - tuio.uio_resid;
else
- return -code;
+ return afs_convert_code(code);
}
#if !defined(USABLE_KERNEL_PAGE_SYMLINK_CACHE)
}
crfree(credp);
- return -code;
+ return afs_convert_code(code);
}
if (!afs_InitReq(&treq, credp))
code = afs_DoPartialWrite(vcp, &treq);
}
- code = code ? -code : count - tuio.uio_resid;
+ code = code ? afs_convert_code(code) : count - tuio.uio_resid;
vcp->states &= ~CPageWrite;
ReleaseWriteLock(&vcp->lock);
ReleaseWriteLock(&vcp->lock);
}
- code = code ? -code : count - tuio.uio_resid;
+ code = code ? afs_convert_code(code) : count - tuio.uio_resid;
afs_Trace4(afs_iclSetp, CM_TRACE_UPDATEPAGE, ICL_TYPE_POINTER, vcp,
ICL_TYPE_POINTER, pp, ICL_TYPE_INT32, page_count(pp),
ICL_TYPE_INT32, code);
AFS_GUNLOCK();
crfree(credp);
- return -code;
+ return afs_convert_code(code);
}
#if defined(AFS_LINUX24_ENV) && !(LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,28) && defined(HAVE_WRITE_BEGIN))