summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSamuel Thibault <samuel.thibault@ens-lyon.org>2021-08-11 13:52:51 +0200
committerSamuel Thibault <samuel.thibault@ens-lyon.org>2021-08-11 13:52:51 +0200
commit128f1e582d0fd5c318be60fc8b81891396a7c5d8 (patch)
tree4908d0ce6d9e2794fd4b066347a56635e73be8bf
parent1dc4b70101d4360258bb3131af24e1a2b5f47fcf (diff)
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.
-rw-r--r--ext2fs/inode.c37
1 files changed, 19 insertions, 18 deletions
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);