Previously on an ext2 partition,
any small symlink would be broken in hurd when created by linux.

I noticed this because I tried to rsync my / offline (in linux) to another disk
and hurd was subsequently unable to read any of the small symlinks.

This patch makes hurd correctly read fast symlinks created by linux 
by ignoring when i_blocks != 0 for such a symlink.

I also removed the assertion when writing a fast symlink on the i_blocks to be 
0,
because linux seems to allocate 8 blocks for any fast symlink.

With this patch, all my symlinks are restored without touching the fs.

Damien 
>From ec49ad8431fd20cef877098767820243bb3b95dd Mon Sep 17 00:00:00 2001
From: Damien Zammit <dam...@zamaudio.com>
Date: Sat, 23 Nov 2019 15:08:47 +1100
Subject: [PATCH] ext2fs: Fix fast symlinks created by linux

---
 ext2fs/inode.c | 6 +-----
 1 file changed, 1 insertion(+), 5 deletions(-)

diff --git a/ext2fs/inode.c b/ext2fs/inode.c
index 472c1b43..b4ebae9c 100644
--- a/ext2fs/inode.c
+++ b/ext2fs/inode.c
@@ -769,8 +769,6 @@ write_symlink (struct node *node, const char *target)
   if (len > MAX_INODE_SYMLINK)
     return EINVAL;
 
-  assert_backtrace (node->dn_stat.st_blocks == 0);
-
   memcpy (diskfs_node_disknode (node)->info.i_data, target, len);
   node->dn_stat.st_size = len - 1;
   node->dn_set_ctime = 1;
@@ -783,11 +781,9 @@ write_symlink (struct node *node, const char *target)
 static error_t
 read_symlink (struct node *node, char *target)
 {
-  if (node->dn_stat.st_blocks)
+  if (node->dn_stat.st_size > MAX_INODE_SYMLINK)
     return EINVAL;
 
-  assert_backtrace (node->dn_stat.st_size < MAX_INODE_SYMLINK);
-
   memcpy (target, diskfs_node_disknode (node)->info.i_data,
           node->dn_stat.st_size);
   return 0;
-- 
2.23.0

Reply via email to