Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openeuler
Kernel
提交
232c2f5c
K
Kernel
项目概览
openeuler
/
Kernel
1 年多 前同步成功
通知
8
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
K
Kernel
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
提交
232c2f5c
编写于
5月 15, 2014
作者:
D
Dave Chinner
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'xfs-filestreams-lookup' into for-next
上级
fdd3a2ae
b94acd47
变更
10
展开全部
隐藏空白更改
内联
并排
Showing
10 changed file
with
403 addition
and
806 deletion
+403
-806
fs/xfs/xfs_bmap.c
fs/xfs/xfs_bmap.c
+117
-85
fs/xfs/xfs_filestream.c
fs/xfs/xfs_filestream.c
+147
-537
fs/xfs/xfs_filestream.h
fs/xfs/xfs_filestream.h
+2
-32
fs/xfs/xfs_inode.c
fs/xfs/xfs_inode.c
+1
-34
fs/xfs/xfs_inode.h
fs/xfs/xfs_inode.h
+1
-3
fs/xfs/xfs_mru_cache.c
fs/xfs/xfs_mru_cache.c
+63
-88
fs/xfs/xfs_mru_cache.h
fs/xfs/xfs_mru_cache.h
+12
-19
fs/xfs/xfs_super.c
fs/xfs/xfs_super.c
+1
-8
fs/xfs/xfs_trace.c
fs/xfs/xfs_trace.c
+1
-0
fs/xfs/xfs_trace.h
fs/xfs/xfs_trace.h
+58
-0
未找到文件。
fs/xfs/xfs_bmap.c
浏览文件 @
232c2f5c
...
...
@@ -3515,6 +3515,67 @@ xfs_bmap_adjacent(
#undef ISVALID
}
static
int
xfs_bmap_longest_free_extent
(
struct
xfs_trans
*
tp
,
xfs_agnumber_t
ag
,
xfs_extlen_t
*
blen
,
int
*
notinit
)
{
struct
xfs_mount
*
mp
=
tp
->
t_mountp
;
struct
xfs_perag
*
pag
;
xfs_extlen_t
longest
;
int
error
=
0
;
pag
=
xfs_perag_get
(
mp
,
ag
);
if
(
!
pag
->
pagf_init
)
{
error
=
xfs_alloc_pagf_init
(
mp
,
tp
,
ag
,
XFS_ALLOC_FLAG_TRYLOCK
);
if
(
error
)
goto
out
;
if
(
!
pag
->
pagf_init
)
{
*
notinit
=
1
;
goto
out
;
}
}
longest
=
xfs_alloc_longest_free_extent
(
mp
,
pag
);
if
(
*
blen
<
longest
)
*
blen
=
longest
;
out:
xfs_perag_put
(
pag
);
return
error
;
}
static
void
xfs_bmap_select_minlen
(
struct
xfs_bmalloca
*
ap
,
struct
xfs_alloc_arg
*
args
,
xfs_extlen_t
*
blen
,
int
notinit
)
{
if
(
notinit
||
*
blen
<
ap
->
minlen
)
{
/*
* Since we did a BUF_TRYLOCK above, it is possible that
* there is space for this request.
*/
args
->
minlen
=
ap
->
minlen
;
}
else
if
(
*
blen
<
args
->
maxlen
)
{
/*
* If the best seen length is less than the request length,
* use the best as the minimum.
*/
args
->
minlen
=
*
blen
;
}
else
{
/*
* Otherwise we've seen an extent as big as maxlen, use that
* as the minimum.
*/
args
->
minlen
=
args
->
maxlen
;
}
}
STATIC
int
xfs_bmap_btalloc_nullfb
(
struct
xfs_bmalloca
*
ap
,
...
...
@@ -3522,111 +3583,74 @@ xfs_bmap_btalloc_nullfb(
xfs_extlen_t
*
blen
)
{
struct
xfs_mount
*
mp
=
ap
->
ip
->
i_mount
;
struct
xfs_perag
*
pag
;
xfs_agnumber_t
ag
,
startag
;
int
notinit
=
0
;
int
error
;
if
(
ap
->
userdata
&&
xfs_inode_is_filestream
(
ap
->
ip
))
args
->
type
=
XFS_ALLOCTYPE_NEAR_BNO
;
else
args
->
type
=
XFS_ALLOCTYPE_START_BNO
;
args
->
type
=
XFS_ALLOCTYPE_START_BNO
;
args
->
total
=
ap
->
total
;
/*
* Search for an allocation group with a single extent large enough
* for the request. If one isn't found, then adjust the minimum
* allocation size to the largest space found.
*/
startag
=
ag
=
XFS_FSB_TO_AGNO
(
mp
,
args
->
fsbno
);
if
(
startag
==
NULLAGNUMBER
)
startag
=
ag
=
0
;
pag
=
xfs_perag_get
(
mp
,
ag
);
while
(
*
blen
<
args
->
maxlen
)
{
if
(
!
pag
->
pagf_init
)
{
error
=
xfs_alloc_pagf_init
(
mp
,
args
->
tp
,
ag
,
XFS_ALLOC_FLAG_TRYLOCK
);
if
(
error
)
{
xfs_perag_put
(
pag
);
return
error
;
}
}
/*
* See xfs_alloc_fix_freelist...
*/
if
(
pag
->
pagf_init
)
{
xfs_extlen_t
longest
;
longest
=
xfs_alloc_longest_free_extent
(
mp
,
pag
);
if
(
*
blen
<
longest
)
*
blen
=
longest
;
}
else
notinit
=
1
;
if
(
xfs_inode_is_filestream
(
ap
->
ip
))
{
if
(
*
blen
>=
args
->
maxlen
)
break
;
if
(
ap
->
userdata
)
{
/*
* If startag is an invalid AG, we've
* come here once before and
* xfs_filestream_new_ag picked the
* best currently available.
*
* Don't continue looping, since we
* could loop forever.
*/
if
(
startag
==
NULLAGNUMBER
)
break
;
error
=
xfs_filestream_new_ag
(
ap
,
&
ag
);
xfs_perag_put
(
pag
);
if
(
error
)
return
error
;
error
=
xfs_bmap_longest_free_extent
(
args
->
tp
,
ag
,
blen
,
&
notinit
);
if
(
error
)
return
error
;
/* loop again to set 'blen'*/
startag
=
NULLAGNUMBER
;
pag
=
xfs_perag_get
(
mp
,
ag
);
continue
;
}
}
if
(
++
ag
==
mp
->
m_sb
.
sb_agcount
)
ag
=
0
;
if
(
ag
==
startag
)
break
;
xfs_perag_put
(
pag
);
pag
=
xfs_perag_get
(
mp
,
ag
);
}
xfs_perag_put
(
pag
);
/*
* Since the above loop did a BUF_TRYLOCK, it is
* possible that there is space for this request.
*/
if
(
notinit
||
*
blen
<
ap
->
minlen
)
args
->
minlen
=
ap
->
minlen
;
/*
* If the best seen length is less than the request
* length, use the best as the minimum.
*/
else
if
(
*
blen
<
args
->
maxlen
)
args
->
minlen
=
*
blen
;
/*
* Otherwise we've seen an extent as big as maxlen,
* use that as the minimum.
*/
else
args
->
minlen
=
args
->
maxlen
;
xfs_bmap_select_minlen
(
ap
,
args
,
blen
,
notinit
);
return
0
;
}
STATIC
int
xfs_bmap_btalloc_filestreams
(
struct
xfs_bmalloca
*
ap
,
struct
xfs_alloc_arg
*
args
,
xfs_extlen_t
*
blen
)
{
struct
xfs_mount
*
mp
=
ap
->
ip
->
i_mount
;
xfs_agnumber_t
ag
;
int
notinit
=
0
;
int
error
;
args
->
type
=
XFS_ALLOCTYPE_NEAR_BNO
;
args
->
total
=
ap
->
total
;
ag
=
XFS_FSB_TO_AGNO
(
mp
,
args
->
fsbno
);
if
(
ag
==
NULLAGNUMBER
)
ag
=
0
;
error
=
xfs_bmap_longest_free_extent
(
args
->
tp
,
ag
,
blen
,
&
notinit
);
if
(
error
)
return
error
;
if
(
*
blen
<
args
->
maxlen
)
{
error
=
xfs_filestream_new_ag
(
ap
,
&
ag
);
if
(
error
)
return
error
;
error
=
xfs_bmap_longest_free_extent
(
args
->
tp
,
ag
,
blen
,
&
notinit
);
if
(
error
)
return
error
;
}
xfs_bmap_select_minlen
(
ap
,
args
,
blen
,
notinit
);
/*
*
set the failure fallback case to look in the selected
*
AG as the stream
may have moved.
*
Set the failure fallback case to look in the selected AG as stream
* may have moved.
*/
if
(
xfs_inode_is_filestream
(
ap
->
ip
))
ap
->
blkno
=
args
->
fsbno
=
XFS_AGB_TO_FSB
(
mp
,
ag
,
0
);
ap
->
blkno
=
args
->
fsbno
=
XFS_AGB_TO_FSB
(
mp
,
ag
,
0
);
return
0
;
}
...
...
@@ -3706,7 +3730,15 @@ xfs_bmap_btalloc(
args
.
firstblock
=
*
ap
->
firstblock
;
blen
=
0
;
if
(
nullfb
)
{
error
=
xfs_bmap_btalloc_nullfb
(
ap
,
&
args
,
&
blen
);
/*
* Search for an allocation group with a single extent large
* enough for the request. If one isn't found, then adjust
* the minimum allocation size to the largest space found.
*/
if
(
ap
->
userdata
&&
xfs_inode_is_filestream
(
ap
->
ip
))
error
=
xfs_bmap_btalloc_filestreams
(
ap
,
&
args
,
&
blen
);
else
error
=
xfs_bmap_btalloc_nullfb
(
ap
,
&
args
,
&
blen
);
if
(
error
)
return
error
;
}
else
if
(
ap
->
flist
->
xbf_low
)
{
...
...
fs/xfs/xfs_filestream.c
浏览文件 @
232c2f5c
此差异已折叠。
点击以展开。
fs/xfs/xfs_filestream.h
浏览文件 @
232c2f5c
...
...
@@ -20,50 +20,20 @@
struct
xfs_mount
;
struct
xfs_inode
;
struct
xfs_perag
;
struct
xfs_bmalloca
;
#ifdef XFS_FILESTREAMS_TRACE
#define XFS_FSTRM_KTRACE_INFO 1
#define XFS_FSTRM_KTRACE_AGSCAN 2
#define XFS_FSTRM_KTRACE_AGPICK1 3
#define XFS_FSTRM_KTRACE_AGPICK2 4
#define XFS_FSTRM_KTRACE_UPDATE 5
#define XFS_FSTRM_KTRACE_FREE 6
#define XFS_FSTRM_KTRACE_ITEM_LOOKUP 7
#define XFS_FSTRM_KTRACE_ASSOCIATE 8
#define XFS_FSTRM_KTRACE_MOVEAG 9
#define XFS_FSTRM_KTRACE_ORPHAN 10
#define XFS_FSTRM_KTRACE_SIZE 16384
extern
ktrace_t
*
xfs_filestreams_trace_buf
;
#endif
/* allocation selection flags */
typedef
enum
xfs_fstrm_alloc
{
XFS_PICK_USERDATA
=
1
,
XFS_PICK_LOWSPACE
=
2
,
}
xfs_fstrm_alloc_t
;
/* prototypes for filestream.c */
int
xfs_filestream_init
(
void
);
void
xfs_filestream_uninit
(
void
);
int
xfs_filestream_mount
(
struct
xfs_mount
*
mp
);
void
xfs_filestream_unmount
(
struct
xfs_mount
*
mp
);
xfs_agnumber_t
xfs_filestream_lookup_ag
(
struct
xfs_inode
*
ip
);
int
xfs_filestream_associate
(
struct
xfs_inode
*
dip
,
struct
xfs_inode
*
ip
);
void
xfs_filestream_deassociate
(
struct
xfs_inode
*
ip
);
xfs_agnumber_t
xfs_filestream_lookup_ag
(
struct
xfs_inode
*
ip
);
int
xfs_filestream_new_ag
(
struct
xfs_bmalloca
*
ap
,
xfs_agnumber_t
*
agp
);
int
xfs_filestream_peek_ag
(
struct
xfs_mount
*
mp
,
xfs_agnumber_t
agno
);
/* filestreams for the inode? */
static
inline
int
xfs_inode_is_filestream
(
struct
xfs_inode
*
ip
)
{
return
(
ip
->
i_mount
->
m_flags
&
XFS_MOUNT_FILESTREAMS
)
||
xfs_iflags_test
(
ip
,
XFS_IFILESTREAM
)
||
(
ip
->
i_d
.
di_flags
&
XFS_DIFLAG_FILESTREAM
);
}
...
...
fs/xfs/xfs_inode.c
浏览文件 @
232c2f5c
...
...
@@ -655,7 +655,6 @@ xfs_ialloc(
uint
flags
;
int
error
;
timespec_t
tv
;
int
filestreams
=
0
;
/*
* Call the space management code to pick
...
...
@@ -772,13 +771,6 @@ xfs_ialloc(
flags
|=
XFS_ILOG_DEV
;
break
;
case
S_IFREG
:
/*
* we can't set up filestreams until after the VFS inode
* is set up properly.
*/
if
(
pip
&&
xfs_inode_is_filestream
(
pip
))
filestreams
=
1
;
/* fall through */
case
S_IFDIR
:
if
(
pip
&&
(
pip
->
i_d
.
di_flags
&
XFS_DIFLAG_ANY
))
{
uint
di_flags
=
0
;
...
...
@@ -844,15 +836,6 @@ xfs_ialloc(
/* now that we have an i_mode we can setup inode ops and unlock */
xfs_setup_inode
(
ip
);
/* now we have set up the vfs inode we can associate the filestream */
if
(
filestreams
)
{
error
=
xfs_filestream_associate
(
pip
,
ip
);
if
(
error
<
0
)
return
-
error
;
if
(
!
error
)
xfs_iflags_set
(
ip
,
XFS_IFILESTREAM
);
}
*
ipp
=
ip
;
return
0
;
}
...
...
@@ -1698,16 +1681,6 @@ xfs_release(
if
(
!
XFS_FORCED_SHUTDOWN
(
mp
))
{
int
truncated
;
/*
* If we are using filestreams, and we have an unlinked
* file that we are processing the last close on, then nothing
* will be able to reopen and write to this file. Purge this
* inode from the filestreams cache so that it doesn't delay
* teardown of the inode.
*/
if
((
ip
->
i_d
.
di_nlink
==
0
)
&&
xfs_inode_is_filestream
(
ip
))
xfs_filestream_deassociate
(
ip
);
/*
* If we previously truncated this file and removed old data
* in the process, we want to initiate "early" writeout on
...
...
@@ -2664,13 +2637,7 @@ xfs_remove(
if
(
error
)
goto
std_return
;
/*
* If we are using filestreams, kill the stream association.
* If the file is still open it may get a new one but that
* will get killed on last close in xfs_close() so we don't
* have to worry about that.
*/
if
(
!
is_dir
&&
link_zero
&&
xfs_inode_is_filestream
(
ip
))
if
(
is_dir
&&
xfs_inode_is_filestream
(
ip
))
xfs_filestream_deassociate
(
ip
);
return
0
;
...
...
fs/xfs/xfs_inode.h
浏览文件 @
232c2f5c
...
...
@@ -209,7 +209,6 @@ xfs_get_initial_prid(struct xfs_inode *dp)
#define XFS_ISTALE (1 << 1)
/* inode has been staled */
#define XFS_IRECLAIMABLE (1 << 2)
/* inode can be reclaimed */
#define XFS_INEW (1 << 3)
/* inode has just been allocated */
#define XFS_IFILESTREAM (1 << 4)
/* inode is in a filestream dir. */
#define XFS_ITRUNCATED (1 << 5)
/* truncated down so flush-on-close */
#define XFS_IDIRTY_RELEASE (1 << 6)
/* dirty release already seen */
#define __XFS_IFLOCK_BIT 7
/* inode is being flushed right now */
...
...
@@ -225,8 +224,7 @@ xfs_get_initial_prid(struct xfs_inode *dp)
*/
#define XFS_IRECLAIM_RESET_FLAGS \
(XFS_IRECLAIMABLE | XFS_IRECLAIM | \
XFS_IDIRTY_RELEASE | XFS_ITRUNCATED | \
XFS_IFILESTREAM);
XFS_IDIRTY_RELEASE | XFS_ITRUNCATED)
/*
* Synchronize processes attempting to flush the in-core inode back to disk.
...
...
fs/xfs/xfs_mru_cache.c
浏览文件 @
232c2f5c
...
...
@@ -100,14 +100,20 @@
* likely result in a loop in one of the lists. That's a sure-fire recipe for
* an infinite loop in the code.
*/
typedef
struct
xfs_mru_cache_elem
{
struct
list_head
list_node
;
unsigned
long
key
;
void
*
value
;
}
xfs_mru_cache_elem_t
;
struct
xfs_mru_cache
{
struct
radix_tree_root
store
;
/* Core storage data structure. */
struct
list_head
*
lists
;
/* Array of lists, one per grp. */
struct
list_head
reap_list
;
/* Elements overdue for reaping. */
spinlock_t
lock
;
/* Lock to protect this struct. */
unsigned
int
grp_count
;
/* Number of discrete groups. */
unsigned
int
grp_time
;
/* Time period spanned by grps. */
unsigned
int
lru_grp
;
/* Group containing time zero. */
unsigned
long
time_zero
;
/* Time first element was added. */
xfs_mru_cache_free_func_t
free_func
;
/* Function pointer for freeing. */
struct
delayed_work
work
;
/* Workqueue data for reaping. */
unsigned
int
queued
;
/* work has been queued */
};
static
kmem_zone_t
*
xfs_mru_elem_zone
;
static
struct
workqueue_struct
*
xfs_mru_reap_wq
;
/*
...
...
@@ -129,12 +135,12 @@ static struct workqueue_struct *xfs_mru_reap_wq;
*/
STATIC
unsigned
long
_xfs_mru_cache_migrate
(
xfs_mru_cache_t
*
mru
,
unsigned
long
now
)
struct
xfs_mru_cache
*
mru
,
unsigned
long
now
)
{
unsigned
int
grp
;
unsigned
int
migrated
=
0
;
struct
list_head
*
lru_list
;
unsigned
int
grp
;
unsigned
int
migrated
=
0
;
struct
list_head
*
lru_list
;
/* Nothing to do if the data store is empty. */
if
(
!
mru
->
time_zero
)
...
...
@@ -193,11 +199,11 @@ _xfs_mru_cache_migrate(
*/
STATIC
void
_xfs_mru_cache_list_insert
(
xfs_mru_cache_t
*
mru
,
xfs_mru_cache_elem_t
*
elem
)
struct
xfs_mru_cache
*
mru
,
struct
xfs_mru_cache_elem
*
elem
)
{
unsigned
int
grp
=
0
;
unsigned
long
now
=
jiffies
;
unsigned
int
grp
=
0
;
unsigned
long
now
=
jiffies
;
/*
* If the data store is empty, initialise time zero, leave grp set to
...
...
@@ -231,10 +237,10 @@ _xfs_mru_cache_list_insert(
*/
STATIC
void
_xfs_mru_cache_clear_reap_list
(
xfs_mru_cache_t
*
mru
)
__releases
(
mru
->
lock
)
__acquires
(
mru
->
lock
)
struct
xfs_mru_cache
*
mru
)
__releases
(
mru
->
lock
)
__acquires
(
mru
->
lock
)
{
xfs_mru_cache_elem_t
*
elem
,
*
next
;
struct
xfs_mru_cache_elem
*
elem
,
*
next
;
struct
list_head
tmp
;
INIT_LIST_HEAD
(
&
tmp
);
...
...
@@ -252,15 +258,8 @@ _xfs_mru_cache_clear_reap_list(
spin_unlock
(
&
mru
->
lock
);
list_for_each_entry_safe
(
elem
,
next
,
&
tmp
,
list_node
)
{
/* Remove the element from the reap list. */
list_del_init
(
&
elem
->
list_node
);
/* Call the client's free function with the key and value pointer. */
mru
->
free_func
(
elem
->
key
,
elem
->
value
);
/* Free the element structure. */
kmem_zone_free
(
xfs_mru_elem_zone
,
elem
);
mru
->
free_func
(
elem
);
}
spin_lock
(
&
mru
->
lock
);
...
...
@@ -277,7 +276,8 @@ STATIC void
_xfs_mru_cache_reap
(
struct
work_struct
*
work
)
{
xfs_mru_cache_t
*
mru
=
container_of
(
work
,
xfs_mru_cache_t
,
work
.
work
);
struct
xfs_mru_cache
*
mru
=
container_of
(
work
,
struct
xfs_mru_cache
,
work
.
work
);
unsigned
long
now
,
next
;
ASSERT
(
mru
&&
mru
->
lists
);
...
...
@@ -304,28 +304,16 @@ _xfs_mru_cache_reap(
int
xfs_mru_cache_init
(
void
)
{
xfs_mru_elem_zone
=
kmem_zone_init
(
sizeof
(
xfs_mru_cache_elem_t
),
"xfs_mru_cache_elem"
);
if
(
!
xfs_mru_elem_zone
)
goto
out
;
xfs_mru_reap_wq
=
alloc_workqueue
(
"xfs_mru_cache"
,
WQ_MEM_RECLAIM
,
1
);
if
(
!
xfs_mru_reap_wq
)
goto
out_destroy_mru_elem_zone
;
return
-
ENOMEM
;
return
0
;
out_destroy_mru_elem_zone:
kmem_zone_destroy
(
xfs_mru_elem_zone
);
out:
return
-
ENOMEM
;
}
void
xfs_mru_cache_uninit
(
void
)
{
destroy_workqueue
(
xfs_mru_reap_wq
);
kmem_zone_destroy
(
xfs_mru_elem_zone
);
}
/*
...
...
@@ -336,14 +324,14 @@ xfs_mru_cache_uninit(void)
*/
int
xfs_mru_cache_create
(
xfs_mru_cache_t
**
mrup
,
struct
xfs_mru_cache
**
mrup
,
unsigned
int
lifetime_ms
,
unsigned
int
grp_count
,
xfs_mru_cache_free_func_t
free_func
)
{
xfs_mru_cache_t
*
mru
=
NULL
;
int
err
=
0
,
grp
;
unsigned
int
grp_time
;
struct
xfs_mru_cache
*
mru
=
NULL
;
int
err
=
0
,
grp
;
unsigned
int
grp_time
;
if
(
mrup
)
*
mrup
=
NULL
;
...
...
@@ -400,7 +388,7 @@ xfs_mru_cache_create(
*/
static
void
xfs_mru_cache_flush
(
xfs_mru_cache_t
*
mru
)
struct
xfs_mru_cache
*
mru
)
{
if
(
!
mru
||
!
mru
->
lists
)
return
;
...
...
@@ -420,7 +408,7 @@ xfs_mru_cache_flush(
void
xfs_mru_cache_destroy
(
xfs_mru_cache_t
*
mru
)
struct
xfs_mru_cache
*
mru
)
{
if
(
!
mru
||
!
mru
->
lists
)
return
;
...
...
@@ -438,38 +426,30 @@ xfs_mru_cache_destroy(
*/
int
xfs_mru_cache_insert
(
xfs_mru_cache_t
*
mru
,
unsigned
long
key
,
void
*
value
)
struct
xfs_mru_cache
*
mru
,
unsigned
long
key
,
struct
xfs_mru_cache_elem
*
elem
)
{
xfs_mru_cache_elem_t
*
elem
;
int
error
;
ASSERT
(
mru
&&
mru
->
lists
);
if
(
!
mru
||
!
mru
->
lists
)
return
EINVAL
;
elem
=
kmem_zone_zalloc
(
xfs_mru_elem_zone
,
KM_SLEEP
);
if
(
!
elem
)
if
(
radix_tree_preload
(
GFP_KERNEL
))
return
ENOMEM
;
if
(
radix_tree_preload
(
GFP_KERNEL
))
{
kmem_zone_free
(
xfs_mru_elem_zone
,
elem
);
return
ENOMEM
;
}
INIT_LIST_HEAD
(
&
elem
->
list_node
);
elem
->
key
=
key
;
elem
->
value
=
value
;
spin_lock
(
&
mru
->
lock
);
radix_tree_insert
(
&
mru
->
store
,
key
,
elem
);
error
=
-
radix_tree_insert
(
&
mru
->
store
,
key
,
elem
);
radix_tree_preload_end
();
_xfs_mru_cache_list_insert
(
mru
,
elem
);
if
(
!
error
)
_xfs_mru_cache_list_insert
(
mru
,
elem
);
spin_unlock
(
&
mru
->
lock
);
return
0
;
return
error
;
}
/*
...
...
@@ -478,13 +458,12 @@ xfs_mru_cache_insert(
* the client data pointer for the removed element is returned, otherwise this
* function will return a NULL pointer.
*/
void
*
struct
xfs_mru_cache_elem
*
xfs_mru_cache_remove
(
xfs_mru_cache_t
*
mru
,
unsigned
long
key
)
struct
xfs_mru_cache
*
mru
,
unsigned
long
key
)
{
xfs_mru_cache_elem_t
*
elem
;
void
*
value
=
NULL
;
struct
xfs_mru_cache_elem
*
elem
;
ASSERT
(
mru
&&
mru
->
lists
);
if
(
!
mru
||
!
mru
->
lists
)
...
...
@@ -492,17 +471,11 @@ xfs_mru_cache_remove(
spin_lock
(
&
mru
->
lock
);
elem
=
radix_tree_delete
(
&
mru
->
store
,
key
);
if
(
elem
)
{
value
=
elem
->
value
;
if
(
elem
)
list_del
(
&
elem
->
list_node
);
}
spin_unlock
(
&
mru
->
lock
);
if
(
elem
)
kmem_zone_free
(
xfs_mru_elem_zone
,
elem
);
return
value
;
return
elem
;
}
/*
...
...
@@ -511,13 +484,14 @@ xfs_mru_cache_remove(
*/
void
xfs_mru_cache_delete
(
xfs_mru_cache_t
*
mru
,
unsigned
long
key
)
struct
xfs_mru_cache
*
mru
,
unsigned
long
key
)
{
void
*
value
=
xfs_mru_cache_remove
(
mru
,
key
)
;
struct
xfs_mru_cache_elem
*
elem
;
if
(
value
)
mru
->
free_func
(
key
,
value
);
elem
=
xfs_mru_cache_remove
(
mru
,
key
);
if
(
elem
)
mru
->
free_func
(
elem
);
}
/*
...
...
@@ -540,12 +514,12 @@ xfs_mru_cache_delete(
* status, we need to help it get it right by annotating the path that does
* not release the lock.
*/
void
*
struct
xfs_mru_cache_elem
*
xfs_mru_cache_lookup
(
xfs_mru_cache_t
*
mru
,
unsigned
long
key
)
struct
xfs_mru_cache
*
mru
,
unsigned
long
key
)
{
xfs_mru_cache_elem_t
*
elem
;
struct
xfs_mru_cache_elem
*
elem
;
ASSERT
(
mru
&&
mru
->
lists
);
if
(
!
mru
||
!
mru
->
lists
)
...
...
@@ -560,7 +534,7 @@ xfs_mru_cache_lookup(
}
else
spin_unlock
(
&
mru
->
lock
);
return
elem
?
elem
->
value
:
NULL
;
return
elem
;
}
/*
...
...
@@ -570,7 +544,8 @@ xfs_mru_cache_lookup(
*/
void
xfs_mru_cache_done
(
xfs_mru_cache_t
*
mru
)
__releases
(
mru
->
lock
)
struct
xfs_mru_cache
*
mru
)
__releases
(
mru
->
lock
)
{
spin_unlock
(
&
mru
->
lock
);
}
fs/xfs/xfs_mru_cache.h
浏览文件 @
232c2f5c
...
...
@@ -18,24 +18,15 @@
#ifndef __XFS_MRU_CACHE_H__
#define __XFS_MRU_CACHE_H__
struct
xfs_mru_cache
;
/* Function pointer type for callback to free a client's data pointer. */
typedef
void
(
*
xfs_mru_cache_free_func_t
)(
unsigned
long
,
void
*
);
struct
xfs_mru_cache_elem
{
struct
list_head
list_node
;
unsigned
long
key
;
};
typedef
struct
xfs_mru_cache
{
struct
radix_tree_root
store
;
/* Core storage data structure. */
struct
list_head
*
lists
;
/* Array of lists, one per grp. */
struct
list_head
reap_list
;
/* Elements overdue for reaping. */
spinlock_t
lock
;
/* Lock to protect this struct. */
unsigned
int
grp_count
;
/* Number of discrete groups. */
unsigned
int
grp_time
;
/* Time period spanned by grps. */
unsigned
int
lru_grp
;
/* Group containing time zero. */
unsigned
long
time_zero
;
/* Time first element was added. */
xfs_mru_cache_free_func_t
free_func
;
/* Function pointer for freeing. */
struct
delayed_work
work
;
/* Workqueue data for reaping. */
unsigned
int
queued
;
/* work has been queued */
}
xfs_mru_cache_t
;
/* Function pointer type for callback to free a client's data pointer. */
typedef
void
(
*
xfs_mru_cache_free_func_t
)(
struct
xfs_mru_cache_elem
*
elem
);
int
xfs_mru_cache_init
(
void
);
void
xfs_mru_cache_uninit
(
void
);
...
...
@@ -44,10 +35,12 @@ int xfs_mru_cache_create(struct xfs_mru_cache **mrup, unsigned int lifetime_ms,
xfs_mru_cache_free_func_t
free_func
);
void
xfs_mru_cache_destroy
(
struct
xfs_mru_cache
*
mru
);
int
xfs_mru_cache_insert
(
struct
xfs_mru_cache
*
mru
,
unsigned
long
key
,
void
*
value
);
void
*
xfs_mru_cache_remove
(
struct
xfs_mru_cache
*
mru
,
unsigned
long
key
);
struct
xfs_mru_cache_elem
*
elem
);
struct
xfs_mru_cache_elem
*
xfs_mru_cache_remove
(
struct
xfs_mru_cache
*
mru
,
unsigned
long
key
);
void
xfs_mru_cache_delete
(
struct
xfs_mru_cache
*
mru
,
unsigned
long
key
);
void
*
xfs_mru_cache_lookup
(
struct
xfs_mru_cache
*
mru
,
unsigned
long
key
);
struct
xfs_mru_cache_elem
*
xfs_mru_cache_lookup
(
struct
xfs_mru_cache
*
mru
,
unsigned
long
key
);
void
xfs_mru_cache_done
(
struct
xfs_mru_cache
*
mru
);
#endif
/* __XFS_MRU_CACHE_H__ */
fs/xfs/xfs_super.c
浏览文件 @
232c2f5c
...
...
@@ -1749,13 +1749,9 @@ init_xfs_fs(void)
if
(
error
)
goto
out_destroy_wq
;
error
=
xfs_filestream_init
();
if
(
error
)
goto
out_mru_cache_uninit
;
error
=
xfs_buf_init
();
if
(
error
)
goto
out_
filestream
_uninit
;
goto
out_
mru_cache
_uninit
;
error
=
xfs_init_procfs
();
if
(
error
)
...
...
@@ -1782,8 +1778,6 @@ init_xfs_fs(void)
xfs_cleanup_procfs
();
out_buf_terminate:
xfs_buf_terminate
();
out_filestream_uninit:
xfs_filestream_uninit
();
out_mru_cache_uninit:
xfs_mru_cache_uninit
();
out_destroy_wq:
...
...
@@ -1802,7 +1796,6 @@ exit_xfs_fs(void)
xfs_sysctl_unregister
();
xfs_cleanup_procfs
();
xfs_buf_terminate
();
xfs_filestream_uninit
();
xfs_mru_cache_uninit
();
xfs_destroy_workqueues
();
xfs_destroy_zones
();
...
...
fs/xfs/xfs_trace.c
浏览文件 @
232c2f5c
...
...
@@ -46,6 +46,7 @@
#include "xfs_log_recover.h"
#include "xfs_inode_item.h"
#include "xfs_bmap_btree.h"
#include "xfs_filestream.h"
/*
* We include this last to have the helpers above available for the trace
...
...
fs/xfs/xfs_trace.h
浏览文件 @
232c2f5c
...
...
@@ -538,6 +538,64 @@ DEFINE_BUF_ITEM_EVENT(xfs_trans_bhold_release);
DEFINE_BUF_ITEM_EVENT
(
xfs_trans_binval
);
DEFINE_BUF_ITEM_EVENT
(
xfs_trans_buf_ordered
);
DECLARE_EVENT_CLASS
(
xfs_filestream_class
,
TP_PROTO
(
struct
xfs_inode
*
ip
,
xfs_agnumber_t
agno
),
TP_ARGS
(
ip
,
agno
),
TP_STRUCT__entry
(
__field
(
dev_t
,
dev
)
__field
(
xfs_ino_t
,
ino
)
__field
(
xfs_agnumber_t
,
agno
)
__field
(
int
,
streams
)
),
TP_fast_assign
(
__entry
->
dev
=
VFS_I
(
ip
)
->
i_sb
->
s_dev
;
__entry
->
ino
=
ip
->
i_ino
;
__entry
->
agno
=
agno
;
__entry
->
streams
=
xfs_filestream_peek_ag
(
ip
->
i_mount
,
agno
);
),
TP_printk
(
"dev %d:%d ino 0x%llx agno %u streams %d"
,
MAJOR
(
__entry
->
dev
),
MINOR
(
__entry
->
dev
),
__entry
->
ino
,
__entry
->
agno
,
__entry
->
streams
)
)
#define DEFINE_FILESTREAM_EVENT(name) \
DEFINE_EVENT(xfs_filestream_class, name, \
TP_PROTO(struct xfs_inode *ip, xfs_agnumber_t agno), \
TP_ARGS(ip, agno))
DEFINE_FILESTREAM_EVENT
(
xfs_filestream_free
);
DEFINE_FILESTREAM_EVENT
(
xfs_filestream_lookup
);
DEFINE_FILESTREAM_EVENT
(
xfs_filestream_scan
);
TRACE_EVENT
(
xfs_filestream_pick
,
TP_PROTO
(
struct
xfs_inode
*
ip
,
xfs_agnumber_t
agno
,
xfs_extlen_t
free
,
int
nscan
),
TP_ARGS
(
ip
,
agno
,
free
,
nscan
),
TP_STRUCT__entry
(
__field
(
dev_t
,
dev
)
__field
(
xfs_ino_t
,
ino
)
__field
(
xfs_agnumber_t
,
agno
)
__field
(
int
,
streams
)
__field
(
xfs_extlen_t
,
free
)
__field
(
int
,
nscan
)
),
TP_fast_assign
(
__entry
->
dev
=
VFS_I
(
ip
)
->
i_sb
->
s_dev
;
__entry
->
ino
=
ip
->
i_ino
;
__entry
->
agno
=
agno
;
__entry
->
streams
=
xfs_filestream_peek_ag
(
ip
->
i_mount
,
agno
);
__entry
->
free
=
free
;
__entry
->
nscan
=
nscan
;
),
TP_printk
(
"dev %d:%d ino 0x%llx agno %u streams %d free %d nscan %d"
,
MAJOR
(
__entry
->
dev
),
MINOR
(
__entry
->
dev
),
__entry
->
ino
,
__entry
->
agno
,
__entry
->
streams
,
__entry
->
free
,
__entry
->
nscan
)
);
DECLARE_EVENT_CLASS
(
xfs_lock_class
,
TP_PROTO
(
struct
xfs_inode
*
ip
,
unsigned
lock_flags
,
unsigned
long
caller_ip
),
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录