aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBoaz Harrosh <bharrosh@panasas.com>2010-02-09 04:43:21 -0500
committerBoaz Harrosh <bharrosh@panasas.com>2010-02-28 06:44:43 -0500
commit96391e2bae0f8882b6f44809202a68be66e91dce (patch)
treef2a6ece9b3973143293e1221e992c60b07109429
parent86093aaff5be5b214613eb60553e236bdb389c84 (diff)
exofs: Error recovery if object is missing from storage
If an object is referenced by a directory but does not exist on a target, it is a very serious corruption that means: 1. Either a power failure with very slim chance of it happening. Because the directory update is always submitted much after object creation, but if a directory is written to one device and the object creation to another it might theoretically happen. 2. It only ever happened to me while developing with BUGs causing file corruption. Crashes could also cause it but they are more like case 1. In any way the object does not exist, so data is surely lost. If there is a mix-up in the obj-id or data-map, then lost objects can be salvaged by off-line fsck. The only recoverable information is the directory name. By letting it appear as a regular empty file, with date==0 (1970 Jan 1st) ownership to root, we enable recovery of the only useful information. And also enable deletion or over-write. I can see how this can hurt. Signed-off-by: Boaz Harrosh <bharrosh@panasas.com>
-rw-r--r--fs/exofs/inode.c12
1 files changed, 11 insertions, 1 deletions
diff --git a/fs/exofs/inode.c b/fs/exofs/inode.c
index 6ca0b0117f04..5514f3c2c2f4 100644
--- a/fs/exofs/inode.c
+++ b/fs/exofs/inode.c
@@ -903,8 +903,18 @@ static int exofs_get_inode(struct super_block *sb, struct exofs_i_info *oi,
903 ios->in_attr_len = ARRAY_SIZE(attrs); 903 ios->in_attr_len = ARRAY_SIZE(attrs);
904 904
905 ret = exofs_sbi_read(ios); 905 ret = exofs_sbi_read(ios);
906 if (ret) 906 if (unlikely(ret)) {
907 EXOFS_ERR("object(0x%llx) corrupted, return empty file=>%d\n",
908 _LLU(ios->obj.id), ret);
909 memset(inode, 0, sizeof(*inode));
910 inode->i_mode = 0040000 | (0777 & ~022);
911 /* If object is lost on target we might as well enable it's
912 * delete.
913 */
914 if ((ret == -ENOENT) || (ret == -EINVAL))
915 ret = 0;
907 goto out; 916 goto out;
917 }
908 918
909 ret = extract_attr_from_ios(ios, &attrs[0]); 919 ret = extract_attr_from_ios(ios, &attrs[0]);
910 if (ret) { 920 if (ret) {