udf: cache struct udf_inode_info
cache UDF_I(struct inode *) return values when there are at least 2 uses in one function Signed-off-by: Marcin Slusarz <marcin.slusarz@gmail.com> Acked-by: Jan Kara <jack@suse.cz> Cc: Christoph Hellwig <hch@lst.de> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:

committed by
Linus Torvalds

parent
c0b344385f
commit
48d6d8ff7d
112
fs/udf/namei.c
112
fs/udf/namei.c
@@ -158,23 +158,23 @@ static struct fileIdentDesc *udf_find_entry(struct inode *dir,
|
||||
uint32_t elen;
|
||||
sector_t offset;
|
||||
struct extent_position epos = {};
|
||||
struct udf_inode_info *dinfo = UDF_I(dir);
|
||||
|
||||
size = (udf_ext0_offset(dir) + dir->i_size) >> 2;
|
||||
f_pos = (udf_ext0_offset(dir) >> 2);
|
||||
|
||||
fibh->soffset = fibh->eoffset =
|
||||
(f_pos & ((dir->i_sb->s_blocksize - 1) >> 2)) << 2;
|
||||
if (UDF_I(dir)->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB)
|
||||
if (dinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB)
|
||||
fibh->sbh = fibh->ebh = NULL;
|
||||
else if (inode_bmap(dir, f_pos >> (dir->i_sb->s_blocksize_bits - 2),
|
||||
&epos, &eloc, &elen, &offset) ==
|
||||
(EXT_RECORDED_ALLOCATED >> 30)) {
|
||||
block = udf_get_lb_pblock(dir->i_sb, eloc, offset);
|
||||
if ((++offset << dir->i_sb->s_blocksize_bits) < elen) {
|
||||
if (UDF_I(dir)->i_alloc_type == ICBTAG_FLAG_AD_SHORT)
|
||||
if (dinfo->i_alloc_type == ICBTAG_FLAG_AD_SHORT)
|
||||
epos.offset -= sizeof(short_ad);
|
||||
else if (UDF_I(dir)->i_alloc_type ==
|
||||
ICBTAG_FLAG_AD_LONG)
|
||||
else if (dinfo->i_alloc_type == ICBTAG_FLAG_AD_LONG)
|
||||
epos.offset -= sizeof(long_ad);
|
||||
} else
|
||||
offset = 0;
|
||||
@@ -351,6 +351,7 @@ static struct fileIdentDesc *udf_add_entry(struct inode *dir,
|
||||
uint32_t elen;
|
||||
sector_t offset;
|
||||
struct extent_position epos = {};
|
||||
struct udf_inode_info *dinfo;
|
||||
|
||||
if (dentry) {
|
||||
if (!dentry->d_name.len) {
|
||||
@@ -373,17 +374,17 @@ static struct fileIdentDesc *udf_add_entry(struct inode *dir,
|
||||
|
||||
fibh->soffset = fibh->eoffset =
|
||||
(f_pos & ((dir->i_sb->s_blocksize - 1) >> 2)) << 2;
|
||||
if (UDF_I(dir)->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB)
|
||||
dinfo = UDF_I(dir);
|
||||
if (dinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB)
|
||||
fibh->sbh = fibh->ebh = NULL;
|
||||
else if (inode_bmap(dir, f_pos >> (dir->i_sb->s_blocksize_bits - 2),
|
||||
&epos, &eloc, &elen, &offset) ==
|
||||
(EXT_RECORDED_ALLOCATED >> 30)) {
|
||||
block = udf_get_lb_pblock(dir->i_sb, eloc, offset);
|
||||
if ((++offset << dir->i_sb->s_blocksize_bits) < elen) {
|
||||
if (UDF_I(dir)->i_alloc_type == ICBTAG_FLAG_AD_SHORT)
|
||||
if (dinfo->i_alloc_type == ICBTAG_FLAG_AD_SHORT)
|
||||
epos.offset -= sizeof(short_ad);
|
||||
else if (UDF_I(dir)->i_alloc_type ==
|
||||
ICBTAG_FLAG_AD_LONG)
|
||||
else if (dinfo->i_alloc_type == ICBTAG_FLAG_AD_LONG)
|
||||
epos.offset -= sizeof(long_ad);
|
||||
} else
|
||||
offset = 0;
|
||||
@@ -395,10 +396,10 @@ static struct fileIdentDesc *udf_add_entry(struct inode *dir,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
block = UDF_I(dir)->i_location.logicalBlockNum;
|
||||
block = dinfo->i_location.logicalBlockNum;
|
||||
|
||||
} else {
|
||||
block = udf_get_lb_pblock(dir->i_sb, UDF_I(dir)->i_location, 0);
|
||||
block = udf_get_lb_pblock(dir->i_sb, dinfo->i_location, 0);
|
||||
fibh->sbh = fibh->ebh = NULL;
|
||||
fibh->soffset = fibh->eoffset = sb->s_blocksize;
|
||||
goto add;
|
||||
@@ -477,7 +478,7 @@ static struct fileIdentDesc *udf_add_entry(struct inode *dir,
|
||||
add:
|
||||
f_pos += nfidlen;
|
||||
|
||||
if (UDF_I(dir)->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB &&
|
||||
if (dinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB &&
|
||||
sb->s_blocksize - fibh->eoffset < nfidlen) {
|
||||
brelse(epos.bh);
|
||||
epos.bh = NULL;
|
||||
@@ -491,15 +492,15 @@ add:
|
||||
udf_expand_dir_adinicb(dir, &block, err);
|
||||
if (!fibh->sbh)
|
||||
return NULL;
|
||||
epos.block = UDF_I(dir)->i_location;
|
||||
epos.block = dinfo->i_location;
|
||||
eloc.logicalBlockNum = block;
|
||||
eloc.partitionReferenceNum =
|
||||
UDF_I(dir)->i_location.partitionReferenceNum;
|
||||
dinfo->i_location.partitionReferenceNum;
|
||||
elen = dir->i_sb->s_blocksize;
|
||||
epos.offset = udf_file_entry_alloc_offset(dir);
|
||||
if (UDF_I(dir)->i_alloc_type == ICBTAG_FLAG_AD_SHORT)
|
||||
if (dinfo->i_alloc_type == ICBTAG_FLAG_AD_SHORT)
|
||||
epos.offset += sizeof(short_ad);
|
||||
else if (UDF_I(dir)->i_alloc_type == ICBTAG_FLAG_AD_LONG)
|
||||
else if (dinfo->i_alloc_type == ICBTAG_FLAG_AD_LONG)
|
||||
epos.offset += sizeof(long_ad);
|
||||
}
|
||||
|
||||
@@ -511,13 +512,13 @@ add:
|
||||
fibh->sbh = fibh->ebh;
|
||||
}
|
||||
|
||||
if (UDF_I(dir)->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) {
|
||||
block = UDF_I(dir)->i_location.logicalBlockNum;
|
||||
if (dinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) {
|
||||
block = dinfo->i_location.logicalBlockNum;
|
||||
fi = (struct fileIdentDesc *)
|
||||
(UDF_I(dir)->i_ext.i_data +
|
||||
(dinfo->i_ext.i_data +
|
||||
fibh->soffset -
|
||||
udf_ext0_offset(dir) +
|
||||
UDF_I(dir)->i_lenEAttr);
|
||||
dinfo->i_lenEAttr);
|
||||
} else {
|
||||
block = eloc.logicalBlockNum +
|
||||
((elen - 1) >>
|
||||
@@ -575,8 +576,8 @@ add:
|
||||
if (!udf_write_fi(dir, cfi, fi, fibh, NULL, name)) {
|
||||
brelse(epos.bh);
|
||||
dir->i_size += nfidlen;
|
||||
if (UDF_I(dir)->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB)
|
||||
UDF_I(dir)->i_lenAlloc += nfidlen;
|
||||
if (dinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB)
|
||||
dinfo->i_lenAlloc += nfidlen;
|
||||
mark_inode_dirty(dir);
|
||||
return fi;
|
||||
} else {
|
||||
@@ -608,6 +609,7 @@ static int udf_create(struct inode *dir, struct dentry *dentry, int mode,
|
||||
struct inode *inode;
|
||||
struct fileIdentDesc cfi, *fi;
|
||||
int err;
|
||||
struct udf_inode_info *iinfo;
|
||||
|
||||
lock_kernel();
|
||||
inode = udf_new_inode(dir, mode, &err);
|
||||
@@ -616,7 +618,8 @@ static int udf_create(struct inode *dir, struct dentry *dentry, int mode,
|
||||
return err;
|
||||
}
|
||||
|
||||
if (UDF_I(inode)->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB)
|
||||
iinfo = UDF_I(inode);
|
||||
if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB)
|
||||
inode->i_data.a_ops = &udf_adinicb_aops;
|
||||
else
|
||||
inode->i_data.a_ops = &udf_aops;
|
||||
@@ -634,9 +637,9 @@ static int udf_create(struct inode *dir, struct dentry *dentry, int mode,
|
||||
return err;
|
||||
}
|
||||
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(iinfo->i_location);
|
||||
*(__le32 *)((struct allocDescImpUse *)cfi.icb.impUse)->impUse =
|
||||
cpu_to_le32(UDF_I(inode)->i_unique & 0x00000000FFFFFFFFUL);
|
||||
cpu_to_le32(iinfo->i_unique & 0x00000000FFFFFFFFUL);
|
||||
udf_write_fi(dir, &cfi, fi, &fibh, NULL, NULL);
|
||||
if (UDF_I(dir)->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB)
|
||||
mark_inode_dirty(dir);
|
||||
@@ -656,6 +659,7 @@ static int udf_mknod(struct inode *dir, struct dentry *dentry, int mode,
|
||||
struct udf_fileident_bh fibh;
|
||||
struct fileIdentDesc cfi, *fi;
|
||||
int err;
|
||||
struct udf_inode_info *iinfo;
|
||||
|
||||
if (!old_valid_dev(rdev))
|
||||
return -EINVAL;
|
||||
@@ -666,6 +670,7 @@ static int udf_mknod(struct inode *dir, struct dentry *dentry, int mode,
|
||||
if (!inode)
|
||||
goto out;
|
||||
|
||||
iinfo = UDF_I(inode);
|
||||
inode->i_uid = current->fsuid;
|
||||
init_special_inode(inode, mode, rdev);
|
||||
fi = udf_add_entry(dir, dentry, &fibh, &cfi, &err);
|
||||
@@ -677,9 +682,9 @@ static int udf_mknod(struct inode *dir, struct dentry *dentry, int mode,
|
||||
return err;
|
||||
}
|
||||
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(iinfo->i_location);
|
||||
*(__le32 *)((struct allocDescImpUse *)cfi.icb.impUse)->impUse =
|
||||
cpu_to_le32(UDF_I(inode)->i_unique & 0x00000000FFFFFFFFUL);
|
||||
cpu_to_le32(iinfo->i_unique & 0x00000000FFFFFFFFUL);
|
||||
udf_write_fi(dir, &cfi, fi, &fibh, NULL, NULL);
|
||||
if (UDF_I(dir)->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB)
|
||||
mark_inode_dirty(dir);
|
||||
@@ -702,6 +707,8 @@ static int udf_mkdir(struct inode *dir, struct dentry *dentry, int mode)
|
||||
struct udf_fileident_bh fibh;
|
||||
struct fileIdentDesc cfi, *fi;
|
||||
int err;
|
||||
struct udf_inode_info *dinfo = UDF_I(dir);
|
||||
struct udf_inode_info *iinfo;
|
||||
|
||||
lock_kernel();
|
||||
err = -EMLINK;
|
||||
@@ -713,6 +720,7 @@ static int udf_mkdir(struct inode *dir, struct dentry *dentry, int mode)
|
||||
if (!inode)
|
||||
goto out;
|
||||
|
||||
iinfo = UDF_I(inode);
|
||||
inode->i_op = &udf_dir_inode_operations;
|
||||
inode->i_fop = &udf_dir_operations;
|
||||
fi = udf_add_entry(inode, NULL, &fibh, &cfi, &err);
|
||||
@@ -724,9 +732,9 @@ static int udf_mkdir(struct inode *dir, struct dentry *dentry, int mode)
|
||||
}
|
||||
inode->i_nlink = 2;
|
||||
cfi.icb.extLength = cpu_to_le32(inode->i_sb->s_blocksize);
|
||||
cfi.icb.extLocation = cpu_to_lelb(UDF_I(dir)->i_location);
|
||||
cfi.icb.extLocation = cpu_to_lelb(dinfo->i_location);
|
||||
*(__le32 *)((struct allocDescImpUse *)cfi.icb.impUse)->impUse =
|
||||
cpu_to_le32(UDF_I(dir)->i_unique & 0x00000000FFFFFFFFUL);
|
||||
cpu_to_le32(dinfo->i_unique & 0x00000000FFFFFFFFUL);
|
||||
cfi.fileCharacteristics =
|
||||
FID_FILE_CHAR_DIRECTORY | FID_FILE_CHAR_PARENT;
|
||||
udf_write_fi(inode, &cfi, fi, &fibh, NULL, NULL);
|
||||
@@ -744,9 +752,9 @@ static int udf_mkdir(struct inode *dir, struct dentry *dentry, int mode)
|
||||
goto out;
|
||||
}
|
||||
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(iinfo->i_location);
|
||||
*(__le32 *)((struct allocDescImpUse *)cfi.icb.impUse)->impUse =
|
||||
cpu_to_le32(UDF_I(inode)->i_unique & 0x00000000FFFFFFFFUL);
|
||||
cpu_to_le32(iinfo->i_unique & 0x00000000FFFFFFFFUL);
|
||||
cfi.fileCharacteristics |= FID_FILE_CHAR_DIRECTORY;
|
||||
udf_write_fi(dir, &cfi, fi, &fibh, NULL, NULL);
|
||||
inc_nlink(dir);
|
||||
@@ -773,23 +781,23 @@ static int empty_dir(struct inode *dir)
|
||||
uint32_t elen;
|
||||
sector_t offset;
|
||||
struct extent_position epos = {};
|
||||
struct udf_inode_info *dinfo = UDF_I(dir);
|
||||
|
||||
f_pos = (udf_ext0_offset(dir) >> 2);
|
||||
|
||||
fibh.soffset = fibh.eoffset =
|
||||
(f_pos & ((dir->i_sb->s_blocksize - 1) >> 2)) << 2;
|
||||
|
||||
if (UDF_I(dir)->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB)
|
||||
if (dinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB)
|
||||
fibh.sbh = fibh.ebh = NULL;
|
||||
else if (inode_bmap(dir, f_pos >> (dir->i_sb->s_blocksize_bits - 2),
|
||||
&epos, &eloc, &elen, &offset) ==
|
||||
(EXT_RECORDED_ALLOCATED >> 30)) {
|
||||
block = udf_get_lb_pblock(dir->i_sb, eloc, offset);
|
||||
if ((++offset << dir->i_sb->s_blocksize_bits) < elen) {
|
||||
if (UDF_I(dir)->i_alloc_type == ICBTAG_FLAG_AD_SHORT)
|
||||
if (dinfo->i_alloc_type == ICBTAG_FLAG_AD_SHORT)
|
||||
epos.offset -= sizeof(short_ad);
|
||||
else if (UDF_I(dir)->i_alloc_type ==
|
||||
ICBTAG_FLAG_AD_LONG)
|
||||
else if (dinfo->i_alloc_type == ICBTAG_FLAG_AD_LONG)
|
||||
epos.offset -= sizeof(long_ad);
|
||||
} else
|
||||
offset = 0;
|
||||
@@ -939,38 +947,40 @@ static int udf_symlink(struct inode *dir, struct dentry *dentry,
|
||||
char name[UDF_NAME_LEN];
|
||||
int namelen;
|
||||
struct buffer_head *bh;
|
||||
struct udf_inode_info *iinfo;
|
||||
|
||||
lock_kernel();
|
||||
inode = udf_new_inode(dir, S_IFLNK, &err);
|
||||
if (!inode)
|
||||
goto out;
|
||||
|
||||
iinfo = UDF_I(inode);
|
||||
inode->i_mode = S_IFLNK | S_IRWXUGO;
|
||||
inode->i_data.a_ops = &udf_symlink_aops;
|
||||
inode->i_op = &page_symlink_inode_operations;
|
||||
|
||||
if (UDF_I(inode)->i_alloc_type != ICBTAG_FLAG_AD_IN_ICB) {
|
||||
if (iinfo->i_alloc_type != ICBTAG_FLAG_AD_IN_ICB) {
|
||||
kernel_lb_addr eloc;
|
||||
uint32_t elen;
|
||||
|
||||
block = udf_new_block(inode->i_sb, inode,
|
||||
UDF_I(inode)->i_location.partitionReferenceNum,
|
||||
UDF_I(inode)->i_location.logicalBlockNum, &err);
|
||||
iinfo->i_location.partitionReferenceNum,
|
||||
iinfo->i_location.logicalBlockNum, &err);
|
||||
if (!block)
|
||||
goto out_no_entry;
|
||||
epos.block = UDF_I(inode)->i_location;
|
||||
epos.block = iinfo->i_location;
|
||||
epos.offset = udf_file_entry_alloc_offset(inode);
|
||||
epos.bh = NULL;
|
||||
eloc.logicalBlockNum = block;
|
||||
eloc.partitionReferenceNum =
|
||||
UDF_I(inode)->i_location.partitionReferenceNum;
|
||||
iinfo->i_location.partitionReferenceNum;
|
||||
elen = inode->i_sb->s_blocksize;
|
||||
UDF_I(inode)->i_lenExtents = elen;
|
||||
iinfo->i_lenExtents = elen;
|
||||
udf_add_aext(inode, &epos, eloc, elen, 0);
|
||||
brelse(epos.bh);
|
||||
|
||||
block = udf_get_pblock(inode->i_sb, block,
|
||||
UDF_I(inode)->i_location.partitionReferenceNum,
|
||||
iinfo->i_location.partitionReferenceNum,
|
||||
0);
|
||||
epos.bh = udf_tread(inode->i_sb, block);
|
||||
lock_buffer(epos.bh);
|
||||
@@ -979,9 +989,8 @@ static int udf_symlink(struct inode *dir, struct dentry *dentry,
|
||||
unlock_buffer(epos.bh);
|
||||
mark_buffer_dirty_inode(epos.bh, inode);
|
||||
ea = epos.bh->b_data + udf_ext0_offset(inode);
|
||||
} else {
|
||||
ea = UDF_I(inode)->i_ext.i_data + UDF_I(inode)->i_lenEAttr;
|
||||
}
|
||||
} else
|
||||
ea = iinfo->i_ext.i_data + iinfo->i_lenEAttr;
|
||||
|
||||
eoffset = inode->i_sb->s_blocksize - udf_ext0_offset(inode);
|
||||
pc = (struct pathComponent *)ea;
|
||||
@@ -1049,15 +1058,15 @@ static int udf_symlink(struct inode *dir, struct dentry *dentry,
|
||||
|
||||
brelse(epos.bh);
|
||||
inode->i_size = elen;
|
||||
if (UDF_I(inode)->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB)
|
||||
UDF_I(inode)->i_lenAlloc = inode->i_size;
|
||||
if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB)
|
||||
iinfo->i_lenAlloc = inode->i_size;
|
||||
mark_inode_dirty(inode);
|
||||
|
||||
fi = udf_add_entry(dir, dentry, &fibh, &cfi, &err);
|
||||
if (!fi)
|
||||
goto out_no_entry;
|
||||
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(iinfo->i_location);
|
||||
bh = UDF_SB(inode->i_sb)->s_lvid_bh;
|
||||
if (bh) {
|
||||
struct logicalVolIntegrityDesc *lvid =
|
||||
@@ -1162,6 +1171,7 @@ static int udf_rename(struct inode *old_dir, struct dentry *old_dentry,
|
||||
struct buffer_head *dir_bh = NULL;
|
||||
int retval = -ENOENT;
|
||||
kernel_lb_addr tloc;
|
||||
struct udf_inode_info *old_iinfo = UDF_I(old_inode);
|
||||
|
||||
lock_kernel();
|
||||
ofi = udf_find_entry(old_dir, old_dentry, &ofibh, &ocfi);
|
||||
@@ -1193,10 +1203,10 @@ static int udf_rename(struct inode *old_dir, struct dentry *old_dentry,
|
||||
goto end_rename;
|
||||
}
|
||||
retval = -EIO;
|
||||
if (UDF_I(old_inode)->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) {
|
||||
if (old_iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) {
|
||||
dir_fi = udf_get_fileident(
|
||||
UDF_I(old_inode)->i_ext.i_data -
|
||||
(UDF_I(old_inode)->i_efe ?
|
||||
old_iinfo->i_ext.i_data -
|
||||
(old_iinfo->i_efe ?
|
||||
sizeof(struct extendedFileEntry) :
|
||||
sizeof(struct fileEntry)),
|
||||
old_inode->i_sb->s_blocksize, &offset);
|
||||
@@ -1258,7 +1268,7 @@ static int udf_rename(struct inode *old_dir, struct dentry *old_dentry,
|
||||
udf_update_tag((char *)dir_fi,
|
||||
(sizeof(struct fileIdentDesc) +
|
||||
le16_to_cpu(dir_fi->lengthOfImpUse) + 3) & ~3);
|
||||
if (UDF_I(old_inode)->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB)
|
||||
if (old_iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB)
|
||||
mark_inode_dirty(old_inode);
|
||||
else
|
||||
mark_buffer_dirty_inode(dir_bh, old_inode);
|
||||
|
Reference in New Issue
Block a user