diff options
Diffstat (limited to 'ext2fs')
-rw-r--r-- | ext2fs/ext2fs.h | 4 | ||||
-rw-r--r-- | ext2fs/inode.c | 19 | ||||
-rw-r--r-- | ext2fs/truncate.c | 15 |
3 files changed, 37 insertions, 1 deletions
diff --git a/ext2fs/ext2fs.h b/ext2fs/ext2fs.h index 2b49d2ea..ba0eaecd 100644 --- a/ext2fs/ext2fs.h +++ b/ext2fs/ext2fs.h @@ -505,7 +505,9 @@ record_global_poke (void *ptr) block_t block = boffs_block (bptr_offs (ptr)); void *block_ptr = bptr (block); ext2_debug ("(%p = %p)", ptr, block_ptr); +#ifdef EXT2FS_DEBUG assert_backtrace (disk_cache_block_is_ref (block)); +#endif global_block_modified (block); pokel_add (&global_pokel, block_ptr, block_size); } @@ -531,7 +533,9 @@ record_indir_poke (struct node *node, void *ptr) block_t block = boffs_block (bptr_offs (ptr)); void *block_ptr = bptr (block); ext2_debug ("(%llu, %p)", node->cache_id, ptr); +#ifdef EXT2FS_DEBUG assert_backtrace (disk_cache_block_is_ref (block)); +#endif global_block_modified (block); pokel_add (&diskfs_node_disknode (node)->indir_pokel, block_ptr, block_size); } diff --git a/ext2fs/inode.c b/ext2fs/inode.c index d73d0bca..3bfbdfdb 100644 --- a/ext2fs/inode.c +++ b/ext2fs/inode.c @@ -632,6 +632,18 @@ diskfs_set_translator (struct node *np, const char *name, unsigned namelen, 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 @@ -645,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); diff --git a/ext2fs/truncate.c b/ext2fs/truncate.c index 265f7f2c..44aab3c7 100644 --- a/ext2fs/truncate.c +++ b/ext2fs/truncate.c @@ -240,7 +240,7 @@ force_delayed_copies (struct node *node, off_t length) mach_port_t obj; pager_change_attributes (pager, MAY_CACHE, MEMORY_OBJECT_COPY_NONE, 1); - obj = diskfs_get_filemap (node, VM_PROT_READ); + obj = diskfs_get_filemap (node, VM_PROT_READ | VM_PROT_WRITE); if (obj != MACH_PORT_NULL) { /* XXX should cope with errors from diskfs_get_filemap */ @@ -296,6 +296,19 @@ diskfs_truncate (struct node *node, off_t length) is true for fast symlinks, and also apparently for some device nodes in linux. */ { + off_t froblen = node->dn_stat.st_size; + off_t frobmax = sizeof(diskfs_node_disknode (node)->info.i_data); + + if (froblen > frobmax) + { + ext2_warning ("inline data was %lld, more than max %lld", + (long long) froblen, (long long) frobmax); + froblen = frobmax; + } + froblen -= length; + memset (((char *) (diskfs_node_disknode (node)->info.i_data)) + length, + 0, froblen); + node->dn_stat.st_size = length; node->dn_set_mtime = 1; node->dn_set_ctime = 1; |