mirror of
https://github.com/torvalds/linux.git
synced 2024-11-07 20:51:47 +00:00
99600051b0
This patch implements extent caching in case of file reading. While reading a file, currently, UDF reads metadata serially which takes a lot of time depending on the number of extents present in the file. Caching last accessd extent improves metadata read time. Instead of reading file metadata from start, now we read from the cached extent. This patch considerably improves the time spent by CPU in kernel mode. For example, while reading a 10.9 GB file using dd: Time before applying patch: 11677022208 bytes (10.9GB) copied, 1529.748921 seconds, 7.3MB/s real 25m 29.85s user 0m 12.41s sys 15m 34.75s Time after applying patch: 11677022208 bytes (10.9GB) copied, 1469.338231 seconds, 7.6MB/s real 24m 29.44s user 0m 15.73s sys 3m 27.61s [JK: Fix bh refcounting issues, simplify initialization] Signed-off-by: Namjae Jeon <namjae.jeon@samsung.com> Signed-off-by: Ashish Sangwan <a.sangwan@samsung.com> Signed-off-by: Bonggil Bak <bgbak@samsung.com> Signed-off-by: Jan Kara <jack@suse.cz>
63 lines
1.7 KiB
C
63 lines
1.7 KiB
C
#ifndef _UDF_I_H
|
|
#define _UDF_I_H
|
|
|
|
struct extent_position {
|
|
struct buffer_head *bh;
|
|
uint32_t offset;
|
|
struct kernel_lb_addr block;
|
|
};
|
|
|
|
struct udf_ext_cache {
|
|
/* Extent position */
|
|
struct extent_position epos;
|
|
/* Start logical offset in bytes */
|
|
loff_t lstart;
|
|
};
|
|
|
|
/*
|
|
* The i_data_sem and i_mutex serve for protection of allocation information
|
|
* of a regular files and symlinks. This includes all extents belonging to
|
|
* the file/symlink, a fact whether data are in-inode or in external data
|
|
* blocks, preallocation, goal block information... When extents are read,
|
|
* i_mutex or i_data_sem must be held (for reading is enough in case of
|
|
* i_data_sem). When extents are changed, i_data_sem must be held for writing
|
|
* and also i_mutex must be held.
|
|
*
|
|
* For directories i_mutex is used for all the necessary protection.
|
|
*/
|
|
|
|
struct udf_inode_info {
|
|
struct timespec i_crtime;
|
|
/* Physical address of inode */
|
|
struct kernel_lb_addr i_location;
|
|
__u64 i_unique;
|
|
__u32 i_lenEAttr;
|
|
__u32 i_lenAlloc;
|
|
__u64 i_lenExtents;
|
|
__u32 i_next_alloc_block;
|
|
__u32 i_next_alloc_goal;
|
|
__u32 i_checkpoint;
|
|
unsigned i_alloc_type : 3;
|
|
unsigned i_efe : 1; /* extendedFileEntry */
|
|
unsigned i_use : 1; /* unallocSpaceEntry */
|
|
unsigned i_strat4096 : 1;
|
|
unsigned reserved : 26;
|
|
union {
|
|
struct short_ad *i_sad;
|
|
struct long_ad *i_lad;
|
|
__u8 *i_data;
|
|
} i_ext;
|
|
struct rw_semaphore i_data_sem;
|
|
struct udf_ext_cache cached_extent;
|
|
/* Spinlock for protecting extent cache */
|
|
spinlock_t i_extent_cache_lock;
|
|
struct inode vfs_inode;
|
|
};
|
|
|
|
static inline struct udf_inode_info *UDF_I(struct inode *inode)
|
|
{
|
|
return list_entry(inode, struct udf_inode_info, vfs_inode);
|
|
}
|
|
|
|
#endif /* _UDF_I_H) */
|