From 1dc4b70101d4360258bb3131af24e1a2b5f47fcf Mon Sep 17 00:00:00 2001 From: Samuel Thibault Date: Wed, 11 Aug 2021 04:03:32 +0200 Subject: ext2fs: clear data when setting a translator on a symlink e2fsck does not like seeing both blocks for the symlink and for the translation entry. This fixes the disappearance of /dev/urandom. --- ext2fs/inode.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/ext2fs/inode.c b/ext2fs/inode.c index d73d0bca..55081e2b 100644 --- a/ext2fs/inode.c +++ b/ext2fs/inode.c @@ -623,6 +623,7 @@ 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; @@ -630,6 +631,16 @@ 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) { /* Allocate block for translator */ @@ -671,6 +682,13 @@ 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