From 128f1e582d0fd5c318be60fc8b81891396a7c5d8 Mon Sep 17 00:00:00 2001 From: Samuel Thibault Date: Wed, 11 Aug 2021 13:52:51 +0200 Subject: 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. --- ext2fs/inode.c | 37 +++++++++++++++++++------------------ 1 file changed, 19 insertions(+), 18 deletions(-) (limited to 'ext2fs/inode.c') 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); -- cgit v1.2.3