summaryrefslogtreecommitdiffstats
path: root/fs/udf/namei.c
diff options
context:
space:
mode:
authorJan Kara <jack@suse.cz>2023-01-25 19:31:38 +0100
committerJan Kara <jack@suse.cz>2023-01-26 16:46:37 +0100
commit085cf7b7e2ef7bdd88c8f2f56a17d756bd18f1a4 (patch)
tree58e01ef1659cbaab90bdd618077e9a64de4dce12 /fs/udf/namei.c
parentc2efd13a2ed4f29bf9ef14ac2fbb7474084655f8 (diff)
downloadlinux-stable-085cf7b7e2ef7bdd88c8f2f56a17d756bd18f1a4.tar.gz
linux-stable-085cf7b7e2ef7bdd88c8f2f56a17d756bd18f1a4.tar.bz2
linux-stable-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/namei.c')
-rw-r--r--fs/udf/namei.c22
1 files changed, 22 insertions, 0 deletions
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);