diff options
author | Jan Kara <jack@suse.cz> | 2023-01-25 19:31:38 +0100 |
---|---|---|
committer | Jan Kara <jack@suse.cz> | 2023-01-26 16:46:37 +0100 |
commit | 085cf7b7e2ef7bdd88c8f2f56a17d756bd18f1a4 (patch) | |
tree | 58e01ef1659cbaab90bdd618077e9a64de4dce12 /fs/udf | |
parent | udf: Limit file size to 4TB (diff) | |
download | linux-085cf7b7e2ef7bdd88c8f2f56a17d756bd18f1a4.tar.xz linux-085cf7b7e2ef7bdd88c8f2f56a17d756bd18f1a4.zip |
udf: Fix file counting in LVID
numFiles entry in LVID should actually contain number for non-dir file
entries, not the number of non-dir inodes. Move the counting from inode
allocation / deallocation into directory entry handling functions.
Signed-off-by: Jan Kara <jack@suse.cz>
Diffstat (limited to 'fs/udf')
-rw-r--r-- | fs/udf/ialloc.c | 31 | ||||
-rw-r--r-- | fs/udf/namei.c | 22 |
2 files changed, 25 insertions, 28 deletions
diff --git a/fs/udf/ialloc.c b/fs/udf/ialloc.c index b5d611cee749..ffd9ccbce0d0 100644 --- a/fs/udf/ialloc.c +++ b/fs/udf/ialloc.c @@ -28,21 +28,7 @@ void udf_free_inode(struct inode *inode) { - struct super_block *sb = inode->i_sb; - struct udf_sb_info *sbi = UDF_SB(sb); - struct logicalVolIntegrityDescImpUse *lvidiu = udf_sb_lvidiu(sb); - - if (lvidiu) { - mutex_lock(&sbi->s_alloc_mutex); - if (S_ISDIR(inode->i_mode)) - le32_add_cpu(&lvidiu->numDirs, -1); - else - le32_add_cpu(&lvidiu->numFiles, -1); - udf_updated_lvid(sb); - mutex_unlock(&sbi->s_alloc_mutex); - } - - udf_free_blocks(sb, NULL, &UDF_I(inode)->i_location, 0, 1); + udf_free_blocks(inode->i_sb, NULL, &UDF_I(inode)->i_location, 0, 1); } struct inode *udf_new_inode(struct inode *dir, umode_t mode) @@ -54,7 +40,6 @@ struct inode *udf_new_inode(struct inode *dir, umode_t mode) uint32_t start = UDF_I(dir)->i_location.logicalBlockNum; struct udf_inode_info *iinfo; struct udf_inode_info *dinfo = UDF_I(dir); - struct logicalVolIntegrityDescImpUse *lvidiu; int err; inode = new_inode(sb); @@ -92,18 +77,8 @@ struct inode *udf_new_inode(struct inode *dir, umode_t mode) return ERR_PTR(err); } - lvidiu = udf_sb_lvidiu(sb); - if (lvidiu) { - iinfo->i_unique = lvid_get_unique_id(sb); - inode->i_generation = iinfo->i_unique; - mutex_lock(&sbi->s_alloc_mutex); - if (S_ISDIR(mode)) - le32_add_cpu(&lvidiu->numDirs, 1); - else - le32_add_cpu(&lvidiu->numFiles, 1); - udf_updated_lvid(sb); - mutex_unlock(&sbi->s_alloc_mutex); - } + iinfo->i_unique = lvid_get_unique_id(sb); + inode->i_generation = iinfo->i_unique; inode_init_owner(&init_user_ns, inode, dir, mode); if (UDF_QUERY_FLAG(sb, UDF_FLAG_UID_SET)) diff --git a/fs/udf/namei.c b/fs/udf/namei.c index d68a0c2b58b7..55b0d78a581f 100644 --- a/fs/udf/namei.c +++ b/fs/udf/namei.c @@ -336,6 +336,21 @@ static void udf_fiiter_delete_entry(struct udf_fileident_iter *iter) udf_fiiter_write_fi(iter, NULL); } +static void udf_add_fid_counter(struct super_block *sb, bool dir, int val) +{ + struct logicalVolIntegrityDescImpUse *lvidiu = udf_sb_lvidiu(sb); + + if (!lvidiu) + return; + mutex_lock(&UDF_SB(sb)->s_alloc_mutex); + if (dir) + le32_add_cpu(&lvidiu->numDirs, val); + else + le32_add_cpu(&lvidiu->numFiles, val); + udf_updated_lvid(sb); + mutex_unlock(&UDF_SB(sb)->s_alloc_mutex); +} + static int udf_add_nondir(struct dentry *dentry, struct inode *inode) { struct udf_inode_info *iinfo = UDF_I(inode); @@ -357,6 +372,7 @@ static int udf_add_nondir(struct dentry *dentry, struct inode *inode) dir->i_ctime = dir->i_mtime = current_time(dir); mark_inode_dirty(dir); udf_fiiter_release(&iter); + udf_add_fid_counter(dir->i_sb, false, 1); d_instantiate_new(dentry, inode); return 0; @@ -457,6 +473,7 @@ static int udf_mkdir(struct user_namespace *mnt_userns, struct inode *dir, iter.fi.fileCharacteristics |= FID_FILE_CHAR_DIRECTORY; udf_fiiter_write_fi(&iter, NULL); udf_fiiter_release(&iter); + udf_add_fid_counter(dir->i_sb, true, 1); inc_nlink(dir); dir->i_ctime = dir->i_mtime = current_time(dir); mark_inode_dirty(dir); @@ -509,6 +526,7 @@ static int udf_rmdir(struct inode *dir, struct dentry *dentry) clear_nlink(inode); inode->i_size = 0; inode_dec_link_count(dir); + udf_add_fid_counter(dir->i_sb, true, -1); inode->i_ctime = dir->i_ctime = dir->i_mtime = current_time(inode); mark_inode_dirty(dir); @@ -544,6 +562,7 @@ static int udf_unlink(struct inode *dir, struct dentry *dentry) dir->i_ctime = dir->i_mtime = current_time(dir); mark_inode_dirty(dir); inode_dec_link_count(inode); + udf_add_fid_counter(dir->i_sb, false, -1); inode->i_ctime = dir->i_ctime; ret = 0; end_unlink: @@ -730,6 +749,7 @@ static int udf_link(struct dentry *old_dentry, struct inode *dir, udf_fiiter_release(&iter); inc_nlink(inode); + udf_add_fid_counter(dir->i_sb, false, 1); inode->i_ctime = current_time(inode); mark_inode_dirty(inode); dir->i_ctime = dir->i_mtime = current_time(dir); @@ -854,6 +874,8 @@ static int udf_rename(struct user_namespace *mnt_userns, struct inode *old_dir, if (new_inode) { new_inode->i_ctime = current_time(new_inode); inode_dec_link_count(new_inode); + udf_add_fid_counter(old_dir->i_sb, S_ISDIR(new_inode->i_mode), + -1); } old_dir->i_ctime = old_dir->i_mtime = current_time(old_dir); new_dir->i_ctime = new_dir->i_mtime = current_time(new_dir); |