Add a function named 'repair_inode_orphan_item_lowmem'.

Signed-off-by: Su Yue <suy.f...@cn.fujitsu.com>
---
 cmds-check.c | 50 +++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 49 insertions(+), 1 deletion(-)

diff --git a/cmds-check.c b/cmds-check.c
index f13ce317..fb239968 100644
--- a/cmds-check.c
+++ b/cmds-check.c
@@ -4936,6 +4936,46 @@ out:
 }
 
 /*
+ * repair ORPHAN_ITEM error
+ *
+ * Returns <0  means on error
+ * Returns  0  means successful repair
+ */
+static int repair_inode_orphan_item_lowmem(struct btrfs_root *root,
+                                          struct btrfs_path *path, u64 ino)
+{
+       struct btrfs_trans_handle *trans;
+       struct btrfs_key research_key;
+       int ret;
+       int ret2;
+
+       btrfs_item_key_to_cpu(path->nodes[0], &research_key, path->slots[0]);
+       btrfs_release_path(path);
+       trans = btrfs_start_transaction(root, 1);
+       if (IS_ERR(trans)) {
+               ret = PTR_ERR(trans);
+               goto out;
+       }
+
+       ret = btrfs_add_orphan_item(trans, root, path, ino);
+       if (ret)
+               goto out;
+
+       printf("added inode %llu orphan item root %llu", ino,
+              root->root_key.objectid);
+
+       btrfs_commit_transaction(trans, root);
+out:
+       if (ret < 0)
+               error("failed to add inode %llu orphan item root %llu due to 
%s",
+                      ino, root->root_key.objectid, strerror(-ret));
+       btrfs_release_path(path);
+       ret2 = btrfs_search_slot(NULL, root, &research_key, path, 0, 0);
+
+       return ret2 < 0 ? ret2 : ret;
+}
+
+/*
  * Check INODE_ITEM and related ITEMs (the same inode number)
  * 1. check link count
  * 2. check inode ref/extref
@@ -5088,7 +5128,15 @@ out:
                        error("root %llu INODE[%llu] nlink(%llu) not equal to 
inode_refs(%llu)",
                              root->objectid, inode_id, nlink, refs);
                } else if (!nlink) {
-                       err |= ORPHAN_ITEM;
+                       if (repair)
+                               ret = repair_inode_orphan_item_lowmem(root,
+                                                                     path,
+                                                                     inode_id);
+                       if (!repair || ret) {
+                               err |= ORPHAN_ITEM;
+                               error("root %llu INODE[%llu] is orphan item",
+                                     root->objectid, inode_id);
+                       }
                }
 
                if (!nbytes && !no_holes && extent_end < isize) {
-- 
2.11.1



--
To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to