summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSamuel Thibault <samuel.thibault@ens-lyon.org>2021-08-11 04:03:32 +0200
committerSamuel Thibault <samuel.thibault@ens-lyon.org>2021-08-11 04:03:32 +0200
commit1dc4b70101d4360258bb3131af24e1a2b5f47fcf (patch)
treeaeee6691b449ceb9da3ea184d7f4789bdba449d3
parentb011199cf330b90483b312c57f25c90a31f2577b (diff)
ext2fs: clear data when setting a translator on a symlinkv0.9.git20210811
e2fsck does not like seeing both blocks for the symlink and for the translation entry. This fixes the disappearance of /dev/urandom.
-rw-r--r--ext2fs/inode.c18
1 files changed, 18 insertions, 0 deletions
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);