Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ubifs: Rectify space amount budget for mkdir/tmpfile operations

UBIFS should make sure the flash has enough space to store dirty (Data
that is newer than disk) data (in memory), space budget is exactly
designed to do that. If space budget calculates less data than we need,
'make_reservation()' will do more work(return -ENOSPC if no free space
lelf, sometimes we can see "cannot reserve xxx bytes in jhead xxx, error
-28" in ubifs error messages) with ubifs inodes locked, which may effect
other syscalls.

A simple way to decide how much space do we need when make a budget:
See how much space is needed by 'make_reservation()' in ubifs_jnl_xxx()
function according to corresponding operation.

It's better to report ENOSPC in ubifs_budget_space(), as early as we can.

Fixes: 474b93704f32163 ("ubifs: Implement O_TMPFILE")
Fixes: 1e51764a3c2ac05 ("UBIFS: add new flash file system")
Signed-off-by: Zhihao Cheng <chengzhihao1@huawei.com>
Signed-off-by: Richard Weinberger <richard@nod.at>

authored by

Zhihao Cheng and committed by
Richard Weinberger
a6dab660 60eb3b9c

+8 -4
+8 -4
fs/ubifs/dir.c
··· 428 428 { 429 429 struct inode *inode; 430 430 struct ubifs_info *c = dir->i_sb->s_fs_info; 431 - struct ubifs_budget_req req = { .new_ino = 1, .new_dent = 1}; 431 + struct ubifs_budget_req req = { .new_ino = 1, .new_dent = 1, 432 + .dirtied_ino = 1}; 432 433 struct ubifs_budget_req ino_req = { .dirtied_ino = 1 }; 433 434 struct ubifs_inode *ui; 434 435 int err, instantiated = 0; 435 436 struct fscrypt_name nm; 436 437 437 438 /* 438 - * Budget request settings: new dirty inode, new direntry, 439 - * budget for dirtied inode will be released via writeback. 439 + * Budget request settings: new inode, new direntry, changing the 440 + * parent directory inode. 441 + * Allocate budget separately for new dirtied inode, the budget will 442 + * be released via writeback. 440 443 */ 441 444 442 445 dbg_gen("dent '%pd', mode %#hx in dir ino %lu", ··· 982 979 struct ubifs_inode *dir_ui = ubifs_inode(dir); 983 980 struct ubifs_info *c = dir->i_sb->s_fs_info; 984 981 int err, sz_change; 985 - struct ubifs_budget_req req = { .new_ino = 1, .new_dent = 1 }; 982 + struct ubifs_budget_req req = { .new_ino = 1, .new_dent = 1, 983 + .dirtied_ino = 1}; 986 984 struct fscrypt_name nm; 987 985 988 986 /*