commit 128f1e582d0fd5c318be60fc8b81891396a7c5d8
Author: Samuel Thibault <samuel.thibault@ens-lyon.org>
Date:   Wed Aug 11 13:52:51 2021 +0200

    ext2fs: Fix block allocation on symlink->translator conversion
    
    In diskfs_set_translator we need to truncate the existing node before
    allocating the block for the translator.

diff --git a/ext2fs/inode.c b/ext2fs/inode.c
index 55081e2b..3bfbdfdb 100644
--- a/ext2fs/inode.c
+++ b/ext2fs/inode.c
@@ -623,7 +623,6 @@ diskfs_set_translator (struct node *np, const char *name, unsigned namelen,
       daddr_t blkno;
       struct ext2_inode *di;
       char buf[block_size];
-      mode_t newmode = 0;
 
       if (namelen + 2 > block_size)
 	return ENAMETOOLONG;
@@ -631,18 +630,20 @@ diskfs_set_translator (struct node *np, const char *name, unsigned namelen,
       di = dino_ref (np->cache_id);
       blkno = di->i_translator;
 
-      if (S_ISLNK (np->dn_stat.st_mode))
-	{
-	  /* Avoid storing both a symlink and a translator,
-	   * e2fsck does not like it.  */
-	  newmode = (np->dn_stat.st_mode & ~S_IFMT) | S_IFREG;
-	  err = diskfs_validate_mode_change (np, newmode);
-	  if (err)
-	    return err;
-	}
-
       if (namelen && !blkno)
 	{
+	  mode_t newmode = 0;
+
+	  if (S_ISLNK (np->dn_stat.st_mode))
+	    {
+	      /* Avoid storing both a symlink and a translator,
+	       * e2fsck does not like it.  */
+	      newmode = (np->dn_stat.st_mode & ~S_IFMT) | S_IFREG;
+	      err = diskfs_validate_mode_change (np, newmode);
+	      if (err)
+		return err;
+	    }
+
 	  /* Allocate block for translator */
 	  blkno =
 	    ext2_new_block ((diskfs_node_disknode (np)->info.i_block_group
@@ -656,6 +657,13 @@ diskfs_set_translator (struct node *np, const char *name, unsigned namelen,
 	      return ENOSPC;
 	    }
 
+	  if (newmode)
+	    {
+	      /* Clear previous data */
+	      diskfs_truncate (np, 0);
+	      np->dn_stat.st_mode = newmode;
+	    }
+
 	  di->i_translator = blkno;
 	  diskfs_node_disknode (np)->info_i_translator = blkno;
 	  record_global_poke (di);
@@ -682,13 +690,6 @@ diskfs_set_translator (struct node *np, const char *name, unsigned namelen,
 	{
 	  void *blkptr;
 
-	  if (newmode)
-	    {
-	      /* Clear previous data */
-	      diskfs_truncate (np, 0);
-	      np->dn_stat.st_mode = newmode;
-	    }
-
 	  buf[0] = namelen & 0xFF;
 	  buf[1] = (namelen >> 8) & 0xFF;
 	  memcpy (buf + 2, name, namelen);
