Commit d664b6af authored by Jan Kara's avatar Jan Kara

udf: Move handling of uniqueID into a helper function and protect it by a s_alloc_mutex

uniqueID handling has been duplicated in three places. Move it into a common
helper. Since we modify an LVID buffer with uniqueID update, we take
sbi->s_alloc_mutex to protect agaist other modifications of the structure.
Signed-off-by: default avatarJan Kara <jack@suse.cz>
parent 49521de1
...@@ -92,28 +92,19 @@ struct inode *udf_new_inode(struct inode *dir, int mode, int *err) ...@@ -92,28 +92,19 @@ struct inode *udf_new_inode(struct inode *dir, int mode, int *err)
return NULL; return NULL;
} }
mutex_lock(&sbi->s_alloc_mutex);
if (sbi->s_lvid_bh) { if (sbi->s_lvid_bh) {
struct logicalVolIntegrityDesc *lvid = struct logicalVolIntegrityDescImpUse *lvidiu;
(struct logicalVolIntegrityDesc *)
sbi->s_lvid_bh->b_data; iinfo->i_unique = lvid_get_unique_id(sb);
struct logicalVolIntegrityDescImpUse *lvidiu = mutex_lock(&sbi->s_alloc_mutex);
udf_sb_lvidiu(sbi); lvidiu = udf_sb_lvidiu(sbi);
struct logicalVolHeaderDesc *lvhd;
uint64_t uniqueID;
lvhd = (struct logicalVolHeaderDesc *)
(lvid->logicalVolContentsUse);
if (S_ISDIR(mode)) if (S_ISDIR(mode))
le32_add_cpu(&lvidiu->numDirs, 1); le32_add_cpu(&lvidiu->numDirs, 1);
else else
le32_add_cpu(&lvidiu->numFiles, 1); le32_add_cpu(&lvidiu->numFiles, 1);
iinfo->i_unique = uniqueID = le64_to_cpu(lvhd->uniqueID);
if (!(++uniqueID & 0x00000000FFFFFFFFUL))
uniqueID += 16;
lvhd->uniqueID = cpu_to_le64(uniqueID);
udf_updated_lvid(sb); udf_updated_lvid(sb);
}
mutex_unlock(&sbi->s_alloc_mutex); mutex_unlock(&sbi->s_alloc_mutex);
}
inode_init_owner(inode, dir, mode); inode_init_owner(inode, dir, mode);
......
...@@ -890,8 +890,8 @@ static int udf_symlink(struct inode *dir, struct dentry *dentry, ...@@ -890,8 +890,8 @@ static int udf_symlink(struct inode *dir, struct dentry *dentry,
int block; int block;
unsigned char *name = NULL; unsigned char *name = NULL;
int namelen; int namelen;
struct buffer_head *bh;
struct udf_inode_info *iinfo; struct udf_inode_info *iinfo;
struct super_block *sb = dir->i_sb;
lock_kernel(); lock_kernel();
inode = udf_new_inode(dir, S_IFLNK | S_IRWXUGO, &err); inode = udf_new_inode(dir, S_IFLNK | S_IRWXUGO, &err);
...@@ -912,7 +912,7 @@ static int udf_symlink(struct inode *dir, struct dentry *dentry, ...@@ -912,7 +912,7 @@ static int udf_symlink(struct inode *dir, struct dentry *dentry,
struct kernel_lb_addr eloc; struct kernel_lb_addr eloc;
uint32_t bsize; uint32_t bsize;
block = udf_new_block(inode->i_sb, inode, block = udf_new_block(sb, inode,
iinfo->i_location.partitionReferenceNum, iinfo->i_location.partitionReferenceNum,
iinfo->i_location.logicalBlockNum, &err); iinfo->i_location.logicalBlockNum, &err);
if (!block) if (!block)
...@@ -923,17 +923,17 @@ static int udf_symlink(struct inode *dir, struct dentry *dentry, ...@@ -923,17 +923,17 @@ static int udf_symlink(struct inode *dir, struct dentry *dentry,
eloc.logicalBlockNum = block; eloc.logicalBlockNum = block;
eloc.partitionReferenceNum = eloc.partitionReferenceNum =
iinfo->i_location.partitionReferenceNum; iinfo->i_location.partitionReferenceNum;
bsize = inode->i_sb->s_blocksize; bsize = sb->s_blocksize;
iinfo->i_lenExtents = bsize; iinfo->i_lenExtents = bsize;
udf_add_aext(inode, &epos, &eloc, bsize, 0); udf_add_aext(inode, &epos, &eloc, bsize, 0);
brelse(epos.bh); brelse(epos.bh);
block = udf_get_pblock(inode->i_sb, block, block = udf_get_pblock(sb, block,
iinfo->i_location.partitionReferenceNum, iinfo->i_location.partitionReferenceNum,
0); 0);
epos.bh = udf_tgetblk(inode->i_sb, block); epos.bh = udf_tgetblk(sb, block);
lock_buffer(epos.bh); lock_buffer(epos.bh);
memset(epos.bh->b_data, 0x00, inode->i_sb->s_blocksize); memset(epos.bh->b_data, 0x00, bsize);
set_buffer_uptodate(epos.bh); set_buffer_uptodate(epos.bh);
unlock_buffer(epos.bh); unlock_buffer(epos.bh);
mark_buffer_dirty_inode(epos.bh, inode); mark_buffer_dirty_inode(epos.bh, inode);
...@@ -941,7 +941,7 @@ static int udf_symlink(struct inode *dir, struct dentry *dentry, ...@@ -941,7 +941,7 @@ static int udf_symlink(struct inode *dir, struct dentry *dentry,
} else } else
ea = iinfo->i_ext.i_data + iinfo->i_lenEAttr; ea = iinfo->i_ext.i_data + iinfo->i_lenEAttr;
eoffset = inode->i_sb->s_blocksize - udf_ext0_offset(inode); eoffset = sb->s_blocksize - udf_ext0_offset(inode);
pc = (struct pathComponent *)ea; pc = (struct pathComponent *)ea;
if (*symname == '/') { if (*symname == '/') {
...@@ -981,7 +981,7 @@ static int udf_symlink(struct inode *dir, struct dentry *dentry, ...@@ -981,7 +981,7 @@ static int udf_symlink(struct inode *dir, struct dentry *dentry,
} }
if (pc->componentType == 5) { if (pc->componentType == 5) {
namelen = udf_put_filename(inode->i_sb, compstart, name, namelen = udf_put_filename(sb, compstart, name,
symname - compstart); symname - compstart);
if (!namelen) if (!namelen)
goto out_no_entry; goto out_no_entry;
...@@ -1015,23 +1015,11 @@ static int udf_symlink(struct inode *dir, struct dentry *dentry, ...@@ -1015,23 +1015,11 @@ static int udf_symlink(struct inode *dir, struct dentry *dentry,
fi = udf_add_entry(dir, dentry, &fibh, &cfi, &err); fi = udf_add_entry(dir, dentry, &fibh, &cfi, &err);
if (!fi) if (!fi)
goto out_no_entry; goto out_no_entry;
cfi.icb.extLength = cpu_to_le32(inode->i_sb->s_blocksize); cfi.icb.extLength = cpu_to_le32(sb->s_blocksize);
cfi.icb.extLocation = cpu_to_lelb(iinfo->i_location); cfi.icb.extLocation = cpu_to_lelb(iinfo->i_location);
bh = UDF_SB(inode->i_sb)->s_lvid_bh; if (UDF_SB(inode->i_sb)->s_lvid_bh) {
if (bh) {
struct logicalVolIntegrityDesc *lvid =
(struct logicalVolIntegrityDesc *)bh->b_data;
struct logicalVolHeaderDesc *lvhd;
uint64_t uniqueID;
lvhd = (struct logicalVolHeaderDesc *)
lvid->logicalVolContentsUse;
uniqueID = le64_to_cpu(lvhd->uniqueID);
*(__le32 *)((struct allocDescImpUse *)cfi.icb.impUse)->impUse = *(__le32 *)((struct allocDescImpUse *)cfi.icb.impUse)->impUse =
cpu_to_le32(uniqueID & 0x00000000FFFFFFFFUL); cpu_to_le32(lvid_get_unique_id(sb));
if (!(++uniqueID & 0x00000000FFFFFFFFUL))
uniqueID += 16;
lvhd->uniqueID = cpu_to_le64(uniqueID);
mark_buffer_dirty(bh);
} }
udf_write_fi(dir, &cfi, fi, &fibh, NULL, NULL); udf_write_fi(dir, &cfi, fi, &fibh, NULL, NULL);
if (UDF_I(dir)->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) if (UDF_I(dir)->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB)
...@@ -1060,7 +1048,6 @@ static int udf_link(struct dentry *old_dentry, struct inode *dir, ...@@ -1060,7 +1048,6 @@ static int udf_link(struct dentry *old_dentry, struct inode *dir,
struct udf_fileident_bh fibh; struct udf_fileident_bh fibh;
struct fileIdentDesc cfi, *fi; struct fileIdentDesc cfi, *fi;
int err; int err;
struct buffer_head *bh;
lock_kernel(); lock_kernel();
if (inode->i_nlink >= (256 << sizeof(inode->i_nlink)) - 1) { if (inode->i_nlink >= (256 << sizeof(inode->i_nlink)) - 1) {
...@@ -1075,21 +1062,9 @@ static int udf_link(struct dentry *old_dentry, struct inode *dir, ...@@ -1075,21 +1062,9 @@ static int udf_link(struct dentry *old_dentry, struct inode *dir,
} }
cfi.icb.extLength = cpu_to_le32(inode->i_sb->s_blocksize); cfi.icb.extLength = cpu_to_le32(inode->i_sb->s_blocksize);
cfi.icb.extLocation = cpu_to_lelb(UDF_I(inode)->i_location); cfi.icb.extLocation = cpu_to_lelb(UDF_I(inode)->i_location);
bh = UDF_SB(inode->i_sb)->s_lvid_bh; if (UDF_SB(inode->i_sb)->s_lvid_bh) {
if (bh) {
struct logicalVolIntegrityDesc *lvid =
(struct logicalVolIntegrityDesc *)bh->b_data;
struct logicalVolHeaderDesc *lvhd;
uint64_t uniqueID;
lvhd = (struct logicalVolHeaderDesc *)
(lvid->logicalVolContentsUse);
uniqueID = le64_to_cpu(lvhd->uniqueID);
*(__le32 *)((struct allocDescImpUse *)cfi.icb.impUse)->impUse = *(__le32 *)((struct allocDescImpUse *)cfi.icb.impUse)->impUse =
cpu_to_le32(uniqueID & 0x00000000FFFFFFFFUL); cpu_to_le32(lvid_get_unique_id(inode->i_sb));
if (!(++uniqueID & 0x00000000FFFFFFFFUL))
uniqueID += 16;
lvhd->uniqueID = cpu_to_le64(uniqueID);
mark_buffer_dirty(bh);
} }
udf_write_fi(dir, &cfi, fi, &fibh, NULL, NULL); udf_write_fi(dir, &cfi, fi, &fibh, NULL, NULL);
if (UDF_I(dir)->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) if (UDF_I(dir)->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB)
......
...@@ -1823,6 +1823,33 @@ static void udf_close_lvid(struct super_block *sb) ...@@ -1823,6 +1823,33 @@ static void udf_close_lvid(struct super_block *sb)
sbi->s_lvid_dirty = 0; sbi->s_lvid_dirty = 0;
} }
u64 lvid_get_unique_id(struct super_block *sb)
{
struct buffer_head *bh;
struct udf_sb_info *sbi = UDF_SB(sb);
struct logicalVolIntegrityDesc *lvid;
struct logicalVolHeaderDesc *lvhd;
u64 uniqueID;
u64 ret;
bh = sbi->s_lvid_bh;
if (!bh)
return 0;
lvid = (struct logicalVolIntegrityDesc *)bh->b_data;
lvhd = (struct logicalVolHeaderDesc *)lvid->logicalVolContentsUse;
mutex_lock(&sbi->s_alloc_mutex);
ret = uniqueID = le64_to_cpu(lvhd->uniqueID);
if (!(++uniqueID & 0xFFFFFFFF))
uniqueID += 16;
lvhd->uniqueID = cpu_to_le64(uniqueID);
mutex_unlock(&sbi->s_alloc_mutex);
mark_buffer_dirty(bh);
return ret;
}
static void udf_sb_free_bitmap(struct udf_bitmap *bitmap) static void udf_sb_free_bitmap(struct udf_bitmap *bitmap)
{ {
int i; int i;
......
...@@ -125,6 +125,7 @@ static inline void udf_updated_lvid(struct super_block *sb) ...@@ -125,6 +125,7 @@ static inline void udf_updated_lvid(struct super_block *sb)
sb->s_dirt = 1; sb->s_dirt = 1;
UDF_SB(sb)->s_lvid_dirty = 1; UDF_SB(sb)->s_lvid_dirty = 1;
} }
extern u64 lvid_get_unique_id(struct super_block *sb);
/* namei.c */ /* namei.c */
extern int udf_write_fi(struct inode *inode, struct fileIdentDesc *, extern int udf_write_fi(struct inode *inode, struct fileIdentDesc *,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment