On Thu, Sep 19, 2002 at 02:02:10PM -0500, Steve Lord wrote:
So, I think this would need some major auditing before putting it in,
we reference EFSCORRUPTED in about 100 places.
Yes, I was just talking to hch and sandeen about this. Attached is
another *suggestion* (ie. it needs to be verified carefully and a
couple of minor changes).
--cw
-- -- snip snip -- ouch ouch -- --
xfs_aops.c | 18 ++++++++---------
xfs_iops.c | 63 ++++++++++++++++++++++++++++++------------------------------
xfs_linux.h | 22 ++++++++++++--------
xfs_super.c | 4 +--
4 files changed, 56 insertions(+), 51 deletions(-)
Index: linux/xfs_aops.c
===================================================================
RCS file: /cvs/linux-2.4-xfs/linux/fs/xfs/linux/xfs_aops.c,v
retrieving revision 1.5
diff -u -w -b -B -r1.5 xfs_aops.c
--- linux/xfs_aops.c 2002/09/19 17:11:58 1.5
+++ linux/xfs_aops.c 2002/09/19 20:21:07
@@ -150,16 +150,14 @@
/* Are we off the end of the file ? */
if (page->index >= end_index) {
unsigned offset = inode->i_size & (PAGE_CACHE_SIZE-1);
- if ((page->index >= end_index+1) || !offset) {
- ret = -EIO;
- goto out;
+ if ((page->index >= end_index+1) || !offset)
+ goto out_flush;
}
- }
ret = delalloc_convert(inode, page, 0, 0);
-out:
if (ret < 0) {
+out_flush:
block_flushpage(page, 0);
ClearPageUptodate(page);
@@ -558,6 +556,8 @@
return err;
}
+/* maybe be called (indirectly) from Linux so we may have to fix error
+ codes */
STATIC int
linvfs_get_block_core(
struct inode *inode,
@@ -586,7 +586,7 @@
create ? flags : PBF_READ, NULL,
(struct page_buf_bmap_s *)&pbmap, &retpbbm, error);
if (error)
- return -error;
+ return linux_err_code(-error);
if (retpbbm == 0)
return 0;
@@ -690,7 +689,7 @@
struct file *unused,
struct page *page)
{
- return block_read_full_page(page, linvfs_get_block);
+ return linux_err_code(block_read_full_page(page, linvfs_get_block));
}
STATIC int
@@ -747,7 +746,7 @@
if (flagset)
current->flags &= ~PF_NOIO;
- return error;
+ return linux_err_code(error);
out_fail:
SetPageDirty(page);
@@ -873,7 +872,7 @@
length -= size;
}
- return (error ? error : (int)(total - length));
+ return (error ? linux_err_code(error) : (int)(total - length));
}
/*
Index: linux/xfs_iops.c
===================================================================
RCS file: /cvs/linux-2.4-xfs/linux/fs/xfs/linux/xfs_iops.c,v
retrieving revision 1.174
diff -u -w -b -B -r1.174 xfs_iops.c
--- linux/xfs_iops.c 2002/09/11 14:29:13 1.174
+++ linux/xfs_iops.c 2002/09/19 20:21:07
@@ -143,7 +142,7 @@
_ACL_FREE(pdacl);
}
}
- return -error;
+ return linux_err_code(-error);
}
STATIC int
@@ -152,7 +151,7 @@
struct dentry *dentry,
int mode)
{
- return linvfs_mknod(dir, dentry, mode, 0);
+ return linux_err_code(linvfs_mknod(dir, dentry, mode, 0));
}
STATIC int
@@ -161,7 +160,7 @@
struct dentry *dentry,
int mode)
{
- return linvfs_mknod(dir, dentry, mode|S_IFDIR, 0);
+ return linux_err_code(linvfs_mknod(dir, dentry, mode|S_IFDIR, 0));
}
@@ -189,6 +188,7 @@
}
error = -linvfs_revalidate_core(ip, ATTR_COMM);
}
+ /* XXX linux_err_code required here? */
if (error && (error != ENOENT))
return ERR_PTR(-error);
d_add(dentry, ip); /* Negative entry goes in if ip is NULL */
@@ -222,7 +222,7 @@
d_instantiate(dentry, ip);
mark_inode_dirty_sync(ip);
}
- return -error;
+ return linux_err_code(-error);
}
STATIC int
@@ -247,7 +247,7 @@
mark_inode_dirty_sync(dir);
}
- return -error;
+ return linux_err_code(-error);
}
STATIC int
@@ -288,7 +288,7 @@
mark_inode_dirty_sync(dir);
}
}
- return -error;
+ return linux_err_code(-error);
}
STATIC int
@@ -307,7 +307,7 @@
mark_inode_dirty_sync(inode);
mark_inode_dirty_sync(dir);
}
- return -error;
+ return linux_err_code(-error);
}
STATIC int
@@ -329,7 +329,7 @@
VOP_RENAME(fvp, odentry, tvp, ndentry, NULL, error);
if (error)
- return -error;
+ return linux_err_code(-error);
if (new_inode) {
validate_fields(new_inode);
@@ -365,7 +365,7 @@
VOP_READLINK(vp, &uio, NULL, error);
if (error)
- return -error;
+ return linux_err_code(-error);
return (size - uio.uio_resid);
}
@@ -414,7 +414,7 @@
if (error) {
kfree(uio);
kfree(link);
- return -error;
+ return linux_err_code(-error);
}
link[MAXNAMELEN - uio->uio_resid] = '\0';
@@ -423,7 +423,7 @@
/* vfs_follow_link returns (-) errors */
error = vfs_follow_link(nd, link);
kfree(link);
- return error;
+ return linux_err_code(error);
}
STATIC int
@@ -436,7 +436,7 @@
mode <<= 6; /* convert from linux to vnode access bits */
VOP_ACCESS(vp, mode, NULL, error);
- return -error;
+ return linux_err_code(-error);
}
/* Brute force approach for now - copy data into linux inode
@@ -461,7 +461,7 @@
vnode_t *vp = LINVFS_GET_VP(dentry->d_inode);
if (unlikely(vp->v_flag & VMODIFIED)) {
- return linvfs_revalidate_core(dentry->d_inode, 0);
+ return linux_err_code(linvfs_revalidate_core(dentry->d_inode,
0));
}
return 0;
}
@@ -518,7 +518,7 @@
VOP_SETATTR(vp, &vattr, flags, NULL, error);
if (error)
- return(-error); /* Positive error up from XFS */
+ return linux_err_code(-error); /* Positive error up from XFS */
if (ia_valid & ATTR_SIZE) {
error = vmtruncate(inode, attr->ia_size);
}
@@ -527,7 +527,7 @@
vn_revalidate(vp, 0);
mark_inode_dirty_sync(inode);
}
- return error;
+ return linux_err_code(error);
}
STATIC void
@@ -610,14 +610,14 @@
xfs_namespaces[SYSTEM_NAMES].namelen) == 0) {
error = -EINVAL;
if (flags & XATTR_CREATE)
- return error;
+ return linux_err_code(error);
error = -ENOATTR;
p += xfs_namespaces[SYSTEM_NAMES].namelen;
if (strcmp(p, POSIXACL_ACCESS) == 0) {
if (vp->v_flag & VMODIFIED) {
error = linvfs_revalidate_core(inode, 0);
if (error)
- return error;
+ return linux_err_code(error);
}
error = xfs_acl_vset(vp, data, size, _ACL_TYPE_ACCESS);
if (!error) {
@@ -628,7 +628,7 @@
else if (strcmp(p, POSIXACL_DEFAULT) == 0) {
error = linvfs_revalidate_core(inode, 0);
if (error)
- return error;
+ return linux_err_code(error);
error = xfs_acl_vset(vp, data, size, _ACL_TYPE_DEFAULT);
if (!error) {
VMODIFY(vp);
@@ -638,7 +638,7 @@
else if (strcmp(p, POSIXCAP) == 0) {
error = xfs_cap_vset(vp, data, size);
}
- return error;
+ return linux_err_code(error);
}
/* Convert Linux syscall to XFS internal ATTR flags */
@@ -650,11 +650,11 @@
if (strncmp(name, xfs_namespaces[ROOT_NAMES].name,
xfs_namespaces[ROOT_NAMES].namelen) == 0) {
if (!capable(CAP_SYS_ADMIN))
- return -EPERM;
+ return linux_err_code(-EPERM);
xflags |= ATTR_ROOT;
p += xfs_namespaces[ROOT_NAMES].namelen;
VOP_ATTR_SET(vp, p, data, size, xflags, NULL, error);
- return -error;
+ return linux_err_code(-error);
}
if (strncmp(name, xfs_namespaces[USER_NAMES].name,
xfs_namespaces[USER_NAMES].namelen) == 0) {
@@ -662,7 +662,7 @@
return -EPERM;
p += xfs_namespaces[USER_NAMES].namelen;
VOP_ATTR_SET(vp, p, data, size, xflags, NULL, error);
- return -error;
+ return linux_err_code(-error);
}
return -ENOATTR;
}
@@ -688,7 +688,7 @@
if (vp->v_flag & VMODIFIED) {
error = linvfs_revalidate_core(inode, 0);
if (error)
- return error;
+ return linux_err_code(error);
}
error = xfs_acl_vget(vp, data, size, _ACL_TYPE_ACCESS);
}
@@ -696,14 +696,14 @@
if (vp->v_flag & VMODIFIED) {
error = linvfs_revalidate_core(inode, 0);
if (error)
- return error;
+ return linux_err_code(error);
}
error = xfs_acl_vget(vp, data, size, _ACL_TYPE_DEFAULT);
}
else if (strcmp(p, POSIXCAP) == 0) {
error = xfs_cap_vget(vp, data, size);
}
- return error;
+ return linux_err_code(error);
}
/* Convert Linux syscall to XFS internal ATTR flags */
@@ -719,7 +719,7 @@
VOP_ATTR_GET(vp, p, data, (int *)&size, xflags, NULL, error);
if (!error)
error = -size;
- return -error;
+ return linux_err_code(-error);
}
if (strncmp(name, xfs_namespaces[USER_NAMES].name,
xfs_namespaces[USER_NAMES].namelen) == 0) {
@@ -729,7 +729,7 @@
VOP_ATTR_GET(vp, p, data, (int *)&size, xflags, NULL, error);
if (!error)
error = -size;
- return -error;
+ return linux_err_code(-error);
}
return -ENOATTR;
}
@@ -759,7 +759,7 @@
memset(&cursor, 0, sizeof(cursor));
VOP_ATTR_LIST(vp, data, size, xflags, &cursor, NULL, error);
if (error > 0)
- return -error;
+ return linux_err_code(-error);
result += -error;
k += result; /* advance start of our buffer */
@@ -801,7 +801,7 @@
error = xfs_acl_vremove(vp, _ACL_TYPE_DEFAULT);
else if (strcmp(p, POSIXCAP) == 0)
error = xfs_cap_vremove(vp);
- return error;
+ return linux_err_code(error);
}
if (strncmp(name, xfs_namespaces[ROOT_NAMES].name,
@@ -811,7 +811,7 @@
xflags |= ATTR_ROOT;
p += xfs_namespaces[ROOT_NAMES].namelen;
VOP_ATTR_REMOVE(vp, p, xflags, NULL, error);
- return -error;
+ return linux_err_code(-error);
}
if (strncmp(name, xfs_namespaces[USER_NAMES].name,
xfs_namespaces[USER_NAMES].namelen) == 0) {
@@ -819,7 +819,7 @@
if (!capable_user_xattr(inode))
return -EPERM;
VOP_ATTR_REMOVE(vp, p, xflags, NULL, error);
- return -error;
+ return linux_err_code(-error);
}
return -ENOATTR;
}
Index: linux/xfs_linux.h
===================================================================
RCS file: /cvs/linux-2.4-xfs/linux/fs/xfs/linux/xfs_linux.h,v
retrieving revision 1.84
diff -u -w -b -B -r1.84 xfs_linux.h
--- linux/xfs_linux.h 2002/09/05 05:37:11 1.84
+++ linux/xfs_linux.h 2002/09/19 20:21:07
@@ -133,17 +133,21 @@
#define EWRONGFS EINVAL /* Mount with wrong filesystem type */
/*
- * XXX EFSCORRUPTED needs a real value in errno.h. asm-i386/errno.h won't
- * return codes out of its known range in errno.
- * XXX Also note: needs to be < 1000 and fairly unique on Linux (mustn't
- * conflict with any code we use already or any code a driver may use)
- * XXX Some options (currently we do #2):
- * 1/ New error code ["Filesystem is corrupted", _after_ glibc updated]
- * 2/ 990 ["Unknown error 990"]
- * 3/ EUCLEAN ["Structure needs cleaning"]
- * 4/ Convert EFSCORRUPTED to EIO [just prior to return into userspace]
+ * EFSCORRUPTED needs to be distinct from other errors internally to
+ * the filesystem.
+ *
+ * Linux error codes are return as negative values, so externally we
+ * need to expose -EFSCORRUPTED with EIO.
+ *
+ * This however means whatever value we choose must be unique from
+ * other error codes. The present value of 990 more than suffices at
+ * present.
*/
#define EFSCORRUPTED 990 /* Filesystem is corrupted */
+/* xlate to linux error code */
+#define linux_err_code(x) (((x) == (-EFSCORRUPTED))?(-EIO):(x))
+
+
#define SYNCHRONIZE() barrier()
#define lbolt jiffies
Index: linux/xfs_super.c
===================================================================
RCS file: /cvs/linux-2.4-xfs/linux/fs/xfs/linux/xfs_super.c,v
retrieving revision 1.213
diff -u -w -b -B -r1.213 xfs_super.c
--- linux/xfs_super.c 2002/09/13 02:01:06 1.213
+++ linux/xfs_super.c 2002/09/19 20:21:07
@@ -621,7 +621,7 @@
VFS_STATVFS(vfsp, statp, NULL, error);
- return error;
+ return linux_err_code(error);
}
int
@@ -669,7 +669,7 @@
out:
kfree(args);
- return error;
+ return linux_err_code(error);
}
void
|