mirror of https://gitee.com/openkylin/linux.git
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: Jan Kara <jack@suse.cz>
This commit is contained in:
parent
49521de119
commit
d664b6af60
|
@ -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,
|
||||||
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,
|
||||||
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,
|
||||||
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,
|
||||||
} 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,
|
||||||
}
|
}
|
||||||
|
|
||||||
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,
|
||||||
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,
|
||||||
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,
|
||||||
}
|
}
|
||||||
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)
|
||||||
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)
|
||||||
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 *,
|
||||||
|
|
Loading…
Reference in New Issue