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>
This commit is contained in:
Jan Kara 2023-01-25 19:31:38 +01:00
parent c2efd13a2e
commit 085cf7b7e2
2 changed files with 25 additions and 28 deletions

View File

@ -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))

View File

@ -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);