-
Notifications
You must be signed in to change notification settings - Fork 119
Description
Issue
The attributes, size
and blocks
, of a symlink are inconsistent before and after umount. After the symlink, they are a number. After a successful umount and remount, they become another number.
Reproduce
insmod fs_raw.ko metadata_csum=1 data_csum=1 data_parity=1 dram_struct_csum=1
mount -t NOVA -o init,data_cow,dbgmask=255 /dev/pmem0 /mnt/pmem0
touch /mnt/pmem0/foo
# create the link
ln -s /mnt/pmem0/foo /mnt/pmem0/bar
stat /mnt/pmem0/bar
# the output:
# File: /mnt/pmem0/bar -> /mnt/pmem0/foo
# Size: 14 Blocks: 0 IO Block: 4096 symbolic link
umount /mnt/pmem0
mount -t NOVA -o data_cow,dbgmask=255 /dev/pmem0 /mnt/pmem0
# after the remount, stat it again
stat /mnt/pmem0/bar
# the output:
# File: /mnt/pmem0/bar -> /mnt/pmem0/foo
# Size: 15 Blocks: 1 IO Block: 4096 symbolic link
Reason:
When allocating a new inode for a symlink, thei_size
set to inode
is len = strlen(symname)
, and the i_block
is set as 0, as below code snippets show:
Lines 268 to 270 in 976a4d1
inode = nova_new_vfs_inode(TYPE_SYMLINK, dir, pi_addr, ino, | |
S_IFLNK|0777, len, 0, | |
&dentry->d_name, epoch_id); |
Lines 1082 to 1087 in 976a4d1
inode_init_owner(inode, dir, mode); | |
inode->i_blocks = inode->i_size = 0; | |
inode->i_mtime = inode->i_atime = inode->i_ctime = current_time(inode); | |
inode->i_generation = atomic_add_return(1, &sbi->next_generation); | |
inode->i_size = size; |
When appending a file write entry to the symlink pi
, a new data block is allocated and the written size is set as len + 1
.
Lines 63 to 64 in 976a4d1
nova_init_file_write_entry(sb, sih, &entry_data, epoch_id, 0, 1, | |
name_blocknr, time, len + 1); |
Consequently, before a umount, the i_size
and i_blocks
are strlen(/mnt/pmem0/foo)
and 0
. After a remount, the i_size
and i_blocks
becomestrlen(/mnt/pmem0/foo) + 1
and 1
.
Fix:
Set the correct i_size
and i_blocks
, 'len+1' and '1', when creating a symlink.