ubifs: fix host xattr_len when changing xattr
When an extended attribute is changed, xattr_len of host inode is recalculated. ui->data_len is updated before computation and result is wrong. This patch adds a temporary variable to fix computation. To reproduce the issue: ~# > a.txt ~# attr -s an-attr -V a-value a.txt ~# attr -s an-attr -V a-bit-bigger-value a.txt Now host inode xattr_len is wrong. Forcing dbg_check_filesystem() generates the following error: [ 130.620140] UBIFS (ubi0:2): background thread "ubifs_bgt0_2" started, PID 565 [ 131.470790] UBIFS error (ubi0:2 pid 564): check_inodes: inode 646 has xattr size 240, but calculated size is 256 [ 131.481697] UBIFS (ubi0:2): dump of the inode 646 sitting in LEB 29:114688 [ 131.488953] magic 0x6101831 [ 131.492876] crc 0x9fce9091 [ 131.496836] node_type 0 (inode node) [ 131.501193] group_type 1 (in node group) [ 131.505788] sqnum 9278 [ 131.509191] len 160 [ 131.512549] key (646, inode) [ 131.516688] creat_sqnum 9270 [ 131.520133] size 0 [ 131.523264] nlink 1 [ 131.526398] atime 1053025857.0 [ 131.530574] mtime 1053025857.0 [ 131.534714] ctime 1053025906.0 [ 131.538849] uid 0 [ 131.542009] gid 0 [ 131.545140] mode 33188 [ 131.548636] flags 0x1 [ 131.551977] xattr_cnt 1 [ 131.555108] xattr_size 240 [ 131.558420] xattr_names 12 [ 131.561670] compr_type 0x1 [ 131.564983] data len 0 [ 131.568125] UBIFS error (ubi0:2 pid 564): dbg_check_filesystem: file-system check failed with error -22 [ 131.578074] CPU: 0 PID: 564 Comm: mount Not tainted 4.4.12-g3639bea54a #24 [ 131.585352] Hardware name: Generic AM33XX (Flattened Device Tree) [ 131.591918] [<c00151c0>] (unwind_backtrace) from [<c0012acc>] (show_stack+0x10/0x14) [ 131.600177] [<c0012acc>] (show_stack) from [<c01c950c>] (dbg_check_filesystem+0x464/0x4d0) [ 131.608934] [<c01c950c>] (dbg_check_filesystem) from [<c019f36c>] (ubifs_mount+0x14f8/0x2130) [ 131.617991] [<c019f36c>] (ubifs_mount) from [<c00d7088>] (mount_fs+0x14/0x98) [ 131.625572] [<c00d7088>] (mount_fs) from [<c00ed674>] (vfs_kern_mount+0x4c/0xd4) [ 131.633435] [<c00ed674>] (vfs_kern_mount) from [<c00efb5c>] (do_mount+0x988/0xb50) [ 131.641471] [<c00efb5c>] (do_mount) from [<c00f004c>] (SyS_mount+0x74/0xa0) [ 131.648837] [<c00f004c>] (SyS_mount) from [<c000fe20>] (ret_fast_syscall+0x0/0x3c) [ 131.665315] UBIFS (ubi0:2): background thread "ubifs_bgt0_2" stops Signed-off-by: Pascal Eberhard <pascal.eberhard@gmail.com> Signed-off-by: Richard Weinberger <richard@nod.at>
This commit is contained in:
parent
1e03953388
commit
74e9c700bc
|
@ -200,6 +200,7 @@ static int change_xattr(struct ubifs_info *c, struct inode *host,
|
|||
struct ubifs_inode *host_ui = ubifs_inode(host);
|
||||
struct ubifs_inode *ui = ubifs_inode(inode);
|
||||
void *buf = NULL;
|
||||
int old_size;
|
||||
struct ubifs_budget_req req = { .dirtied_ino = 2,
|
||||
.dirtied_ino_d = ALIGN(size, 8) + ALIGN(host_ui->data_len, 8) };
|
||||
|
||||
|
@ -217,12 +218,13 @@ static int change_xattr(struct ubifs_info *c, struct inode *host,
|
|||
kfree(ui->data);
|
||||
ui->data = buf;
|
||||
inode->i_size = ui->ui_size = size;
|
||||
old_size = ui->data_len;
|
||||
ui->data_len = size;
|
||||
mutex_unlock(&ui->ui_mutex);
|
||||
|
||||
mutex_lock(&host_ui->ui_mutex);
|
||||
host->i_ctime = ubifs_current_time(host);
|
||||
host_ui->xattr_size -= CALC_XATTR_BYTES(ui->data_len);
|
||||
host_ui->xattr_size -= CALC_XATTR_BYTES(old_size);
|
||||
host_ui->xattr_size += CALC_XATTR_BYTES(size);
|
||||
|
||||
/*
|
||||
|
@ -241,7 +243,7 @@ static int change_xattr(struct ubifs_info *c, struct inode *host,
|
|||
|
||||
out_cancel:
|
||||
host_ui->xattr_size -= CALC_XATTR_BYTES(size);
|
||||
host_ui->xattr_size += CALC_XATTR_BYTES(ui->data_len);
|
||||
host_ui->xattr_size += CALC_XATTR_BYTES(old_size);
|
||||
mutex_unlock(&host_ui->ui_mutex);
|
||||
make_bad_inode(inode);
|
||||
out_free:
|
||||
|
|
Loading…
Reference in New Issue