Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openeuler
raspberrypi-kernel
提交
f477cedc
R
raspberrypi-kernel
项目概览
openeuler
/
raspberrypi-kernel
通知
13
Star
1
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
R
raspberrypi-kernel
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
f477cedc
编写于
6月 21, 2016
作者:
D
Dave Chinner
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'xfs-4.8-misc-fixes-2' into for-next
上级
9b7fad20
19b54ee6
变更
18
隐藏空白更改
内联
并排
Showing
18 changed file
with
246 addition
and
166 deletion
+246
-166
fs/xfs/libxfs/xfs_alloc.c
fs/xfs/libxfs/xfs_alloc.c
+56
-43
fs/xfs/libxfs/xfs_alloc.h
fs/xfs/libxfs/xfs_alloc.h
+2
-0
fs/xfs/libxfs/xfs_bmap.c
fs/xfs/libxfs/xfs_bmap.c
+17
-34
fs/xfs/libxfs/xfs_bmap.h
fs/xfs/libxfs/xfs_bmap.h
+10
-8
fs/xfs/libxfs/xfs_bmap_btree.c
fs/xfs/libxfs/xfs_bmap_btree.c
+1
-1
fs/xfs/libxfs/xfs_btree.c
fs/xfs/libxfs/xfs_btree.c
+19
-0
fs/xfs/libxfs/xfs_btree.h
fs/xfs/libxfs/xfs_btree.h
+2
-0
fs/xfs/libxfs/xfs_ialloc.c
fs/xfs/libxfs/xfs_ialloc.c
+9
-19
fs/xfs/xfs_bmap_util.c
fs/xfs/xfs_bmap_util.c
+25
-7
fs/xfs/xfs_bmap_util.h
fs/xfs/xfs_bmap_util.h
+0
-1
fs/xfs/xfs_buf.c
fs/xfs/xfs_buf.c
+5
-3
fs/xfs/xfs_error.c
fs/xfs/xfs_error.c
+3
-0
fs/xfs/xfs_fsops.c
fs/xfs/xfs_fsops.c
+60
-45
fs/xfs/xfs_icache.c
fs/xfs/xfs_icache.c
+1
-1
fs/xfs/xfs_icache.h
fs/xfs/xfs_icache.h
+1
-0
fs/xfs/xfs_ondisk.h
fs/xfs/xfs_ondisk.h
+23
-2
fs/xfs/xfs_super.c
fs/xfs/xfs_super.c
+11
-2
fs/xfs/xfs_trace.h
fs/xfs/xfs_trace.h
+1
-0
未找到文件。
fs/xfs/libxfs/xfs_alloc.c
浏览文件 @
f477cedc
...
...
@@ -1839,19 +1839,8 @@ void
xfs_alloc_compute_maxlevels
(
xfs_mount_t
*
mp
)
/* file system mount structure */
{
int
level
;
uint
maxblocks
;
uint
maxleafents
;
int
minleafrecs
;
int
minnoderecs
;
maxleafents
=
(
mp
->
m_sb
.
sb_agblocks
+
1
)
/
2
;
minleafrecs
=
mp
->
m_alloc_mnr
[
0
];
minnoderecs
=
mp
->
m_alloc_mnr
[
1
];
maxblocks
=
(
maxleafents
+
minleafrecs
-
1
)
/
minleafrecs
;
for
(
level
=
1
;
maxblocks
>
1
;
level
++
)
maxblocks
=
(
maxblocks
+
minnoderecs
-
1
)
/
minnoderecs
;
mp
->
m_ag_maxlevels
=
level
;
mp
->
m_ag_maxlevels
=
xfs_btree_compute_maxlevels
(
mp
,
mp
->
m_alloc_mnr
,
(
mp
->
m_sb
.
sb_agblocks
+
1
)
/
2
);
}
/*
...
...
@@ -2658,55 +2647,79 @@ xfs_alloc_vextent(
return
error
;
}
/*
* Free an extent.
* Just break up the extent address and hand off to xfs_free_ag_extent
* after fixing up the freelist.
*/
int
/* error */
xfs_free_extent
(
xfs_trans_t
*
tp
,
/* transaction pointer */
xfs_fsblock_t
bno
,
/* starting block number of extent */
xfs_extlen_t
len
)
/* length of extent */
/* Ensure that the freelist is at full capacity. */
int
xfs_free_extent_fix_freelist
(
struct
xfs_trans
*
tp
,
xfs_agnumber_t
agno
,
struct
xfs_buf
**
agbp
)
{
xfs_alloc_arg_t
args
;
int
error
;
struct
xfs_alloc_arg
args
;
int
error
;
ASSERT
(
len
!=
0
);
memset
(
&
args
,
0
,
sizeof
(
xfs_alloc_arg_t
));
memset
(
&
args
,
0
,
sizeof
(
struct
xfs_alloc_arg
));
args
.
tp
=
tp
;
args
.
mp
=
tp
->
t_mountp
;
args
.
agno
=
agno
;
/*
* validate that the block number is legal - the enables us to detect
* and handle a silent filesystem corruption rather than crashing.
*/
args
.
agno
=
XFS_FSB_TO_AGNO
(
args
.
mp
,
bno
);
if
(
args
.
agno
>=
args
.
mp
->
m_sb
.
sb_agcount
)
return
-
EFSCORRUPTED
;
args
.
agbno
=
XFS_FSB_TO_AGBNO
(
args
.
mp
,
bno
);
if
(
args
.
agbno
>=
args
.
mp
->
m_sb
.
sb_agblocks
)
return
-
EFSCORRUPTED
;
args
.
pag
=
xfs_perag_get
(
args
.
mp
,
args
.
agno
);
ASSERT
(
args
.
pag
);
error
=
xfs_alloc_fix_freelist
(
&
args
,
XFS_ALLOC_FLAG_FREEING
);
if
(
error
)
goto
error0
;
goto
out
;
*
agbp
=
args
.
agbp
;
out:
xfs_perag_put
(
args
.
pag
);
return
error
;
}
/*
* Free an extent.
* Just break up the extent address and hand off to xfs_free_ag_extent
* after fixing up the freelist.
*/
int
/* error */
xfs_free_extent
(
struct
xfs_trans
*
tp
,
/* transaction pointer */
xfs_fsblock_t
bno
,
/* starting block number of extent */
xfs_extlen_t
len
)
/* length of extent */
{
struct
xfs_mount
*
mp
=
tp
->
t_mountp
;
struct
xfs_buf
*
agbp
;
xfs_agnumber_t
agno
=
XFS_FSB_TO_AGNO
(
mp
,
bno
);
xfs_agblock_t
agbno
=
XFS_FSB_TO_AGBNO
(
mp
,
bno
);
int
error
;
ASSERT
(
len
!=
0
);
error
=
xfs_free_extent_fix_freelist
(
tp
,
agno
,
&
agbp
);
if
(
error
)
return
error
;
XFS_WANT_CORRUPTED_GOTO
(
mp
,
agbno
<
mp
->
m_sb
.
sb_agblocks
,
err
);
/* validate the extent size is legal now we have the agf locked */
if
(
args
.
agbno
+
len
>
be32_to_cpu
(
XFS_BUF_TO_AGF
(
args
.
agbp
)
->
agf_length
))
{
error
=
-
EFSCORRUPTED
;
goto
error0
;
}
XFS_WANT_CORRUPTED_GOTO
(
mp
,
agbno
+
len
<=
be32_to_cpu
(
XFS_BUF_TO_AGF
(
agbp
)
->
agf_length
),
err
);
error
=
xfs_free_ag_extent
(
tp
,
args
.
agbp
,
args
.
agno
,
args
.
agbno
,
len
,
0
);
if
(
!
error
)
xfs_extent_busy_insert
(
tp
,
args
.
agno
,
args
.
agbno
,
len
,
0
);
error0:
xfs_perag_put
(
args
.
pag
);
error
=
xfs_free_ag_extent
(
tp
,
agbp
,
agno
,
agbno
,
len
,
0
);
if
(
error
)
goto
err
;
xfs_extent_busy_insert
(
tp
,
agno
,
agbno
,
len
,
0
);
return
0
;
err:
xfs_trans_brelse
(
tp
,
agbp
);
return
error
;
}
fs/xfs/libxfs/xfs_alloc.h
浏览文件 @
f477cedc
...
...
@@ -229,5 +229,7 @@ xfs_alloc_get_rec(
int
xfs_read_agf
(
struct
xfs_mount
*
mp
,
struct
xfs_trans
*
tp
,
xfs_agnumber_t
agno
,
int
flags
,
struct
xfs_buf
**
bpp
);
int
xfs_alloc_fix_freelist
(
struct
xfs_alloc_arg
*
args
,
int
flags
);
int
xfs_free_extent_fix_freelist
(
struct
xfs_trans
*
tp
,
xfs_agnumber_t
agno
,
struct
xfs_buf
**
agbp
);
#endif
/* __XFS_ALLOC_H__ */
fs/xfs/libxfs/xfs_bmap.c
浏览文件 @
f477cedc
...
...
@@ -570,14 +570,12 @@ xfs_bmap_validate_ret(
*/
void
xfs_bmap_add_free
(
struct
xfs_mount
*
mp
,
/* mount point structure */
struct
xfs_bmap_free
*
flist
,
/* list of extents */
xfs_fsblock_t
bno
,
/* fs block number of extent */
xfs_filblks_t
len
,
/* length of extent */
xfs_bmap_free_t
*
flist
,
/* list of extents */
xfs_mount_t
*
mp
)
/* mount point structure */
xfs_filblks_t
len
)
/* length of extent */
{
xfs_bmap_free_item_t
*
cur
;
/* current (next) element */
xfs_bmap_free_item_t
*
new
;
/* new element */
xfs_bmap_free_item_t
*
prev
;
/* previous element */
struct
xfs_bmap_free_item
*
new
;
/* new element */
#ifdef DEBUG
xfs_agnumber_t
agno
;
xfs_agblock_t
agbno
;
...
...
@@ -597,17 +595,7 @@ xfs_bmap_add_free(
new
=
kmem_zone_alloc
(
xfs_bmap_free_item_zone
,
KM_SLEEP
);
new
->
xbfi_startblock
=
bno
;
new
->
xbfi_blockcount
=
(
xfs_extlen_t
)
len
;
for
(
prev
=
NULL
,
cur
=
flist
->
xbf_first
;
cur
!=
NULL
;
prev
=
cur
,
cur
=
cur
->
xbfi_next
)
{
if
(
cur
->
xbfi_startblock
>=
bno
)
break
;
}
if
(
prev
)
prev
->
xbfi_next
=
new
;
else
flist
->
xbf_first
=
new
;
new
->
xbfi_next
=
cur
;
list_add
(
&
new
->
xbfi_list
,
&
flist
->
xbf_flist
);
flist
->
xbf_count
++
;
}
...
...
@@ -617,14 +605,10 @@ xfs_bmap_add_free(
*/
void
xfs_bmap_del_free
(
xfs_bmap_free_t
*
flist
,
/* free item list header */
xfs_bmap_free_item_t
*
prev
,
/* previous item on list, if any */
xfs_bmap_free_item_t
*
free
)
/* list item to be freed */
struct
xfs_bmap_free
*
flist
,
/* free item list header */
struct
xfs_bmap_free_item
*
free
)
/* list item to be freed */
{
if
(
prev
)
prev
->
xbfi_next
=
free
->
xbfi_next
;
else
flist
->
xbf_first
=
free
->
xbfi_next
;
list_del
(
&
free
->
xbfi_list
);
flist
->
xbf_count
--
;
kmem_zone_free
(
xfs_bmap_free_item_zone
,
free
);
}
...
...
@@ -634,17 +618,16 @@ xfs_bmap_del_free(
*/
void
xfs_bmap_cancel
(
xfs_bmap_free_t
*
flist
)
/* list of bmap_free_items */
struct
xfs_bmap_free
*
flist
)
/* list of bmap_free_items */
{
xfs_bmap_free_item_t
*
free
;
/* free list item */
xfs_bmap_free_item_t
*
next
;
struct
xfs_bmap_free_item
*
free
;
/* free list item */
if
(
flist
->
xbf_count
==
0
)
return
;
ASSERT
(
flist
->
xbf_first
!=
NULL
);
for
(
free
=
flist
->
xbf_first
;
free
;
free
=
next
)
{
next
=
free
->
xbfi_next
;
xfs_bmap_del_free
(
flist
,
NULL
,
free
);
while
(
!
list_empty
(
&
flist
->
xbf_flist
))
{
free
=
list_first_entry
(
&
flist
->
xbf_flist
,
struct
xfs_bmap_free_item
,
xbfi_list
)
;
xfs_bmap_del_free
(
flist
,
free
);
}
ASSERT
(
flist
->
xbf_count
==
0
);
}
...
...
@@ -699,7 +682,7 @@ xfs_bmap_btree_to_extents(
cblock
=
XFS_BUF_TO_BLOCK
(
cbp
);
if
((
error
=
xfs_btree_check_block
(
cur
,
cblock
,
0
,
cbp
)))
return
error
;
xfs_bmap_add_free
(
cbno
,
1
,
cur
->
bc_private
.
b
.
flist
,
mp
);
xfs_bmap_add_free
(
mp
,
cur
->
bc_private
.
b
.
flist
,
cbno
,
1
);
ip
->
i_d
.
di_nblocks
--
;
xfs_trans_mod_dquot_byino
(
tp
,
ip
,
XFS_TRANS_DQ_BCOUNT
,
-
1L
);
xfs_trans_binval
(
tp
,
cbp
);
...
...
@@ -5073,8 +5056,8 @@ xfs_bmap_del_extent(
* If we need to, add to list of extents to delete.
*/
if
(
do_fx
)
xfs_bmap_add_free
(
del
->
br_startblock
,
del
->
br_blockcount
,
flist
,
mp
);
xfs_bmap_add_free
(
mp
,
flist
,
del
->
br_startblock
,
del
->
br_blockcount
);
/*
* Adjust inode # blocks in the file.
*/
...
...
fs/xfs/libxfs/xfs_bmap.h
浏览文件 @
f477cedc
...
...
@@ -62,12 +62,12 @@ struct xfs_bmalloca {
* List of extents to be free "later".
* The list is kept sorted on xbf_startblock.
*/
typedef
struct
xfs_bmap_free_item
struct
xfs_bmap_free_item
{
xfs_fsblock_t
xbfi_startblock
;
/* starting fs block number */
xfs_extlen_t
xbfi_blockcount
;
/* number of blocks in extent */
struct
xfs_bmap_free_item
*
xbfi_next
;
/* link to next entry */
}
xfs_bmap_free_item_t
;
struct
list_head
xbfi_list
;
};
/*
* Header for free extent list.
...
...
@@ -85,7 +85,7 @@ typedef struct xfs_bmap_free_item
*/
typedef
struct
xfs_bmap_free
{
xfs_bmap_free_item_t
*
xbf_fir
st
;
/* list of to-be-free extents */
struct
list_head
xbf_fli
st
;
/* list of to-be-free extents */
int
xbf_count
;
/* count of items on list */
int
xbf_low
;
/* alloc in low mode */
}
xfs_bmap_free_t
;
...
...
@@ -141,8 +141,10 @@ static inline int xfs_bmapi_aflag(int w)
static
inline
void
xfs_bmap_init
(
xfs_bmap_free_t
*
flp
,
xfs_fsblock_t
*
fbp
)
{
((
flp
)
->
xbf_first
=
NULL
,
(
flp
)
->
xbf_count
=
0
,
\
(
flp
)
->
xbf_low
=
0
,
*
(
fbp
)
=
NULLFSBLOCK
);
INIT_LIST_HEAD
(
&
flp
->
xbf_flist
);
flp
->
xbf_count
=
0
;
flp
->
xbf_low
=
0
;
*
fbp
=
NULLFSBLOCK
;
}
/*
...
...
@@ -191,8 +193,8 @@ void xfs_bmap_trace_exlist(struct xfs_inode *ip, xfs_extnum_t cnt,
int
xfs_bmap_add_attrfork
(
struct
xfs_inode
*
ip
,
int
size
,
int
rsvd
);
void
xfs_bmap_local_to_extents_empty
(
struct
xfs_inode
*
ip
,
int
whichfork
);
void
xfs_bmap_add_free
(
xfs_fsblock_t
bno
,
xfs_filblks_t
len
,
struct
xfs_bmap_free
*
flist
,
struct
xfs_mount
*
mp
);
void
xfs_bmap_add_free
(
struct
xfs_mount
*
mp
,
struct
xfs_bmap_free
*
flist
,
xfs_fsblock_t
bno
,
xfs_filblks_t
len
);
void
xfs_bmap_cancel
(
struct
xfs_bmap_free
*
flist
);
int
xfs_bmap_finish
(
struct
xfs_trans
**
tp
,
struct
xfs_bmap_free
*
flist
,
struct
xfs_inode
*
ip
);
...
...
fs/xfs/libxfs/xfs_bmap_btree.c
浏览文件 @
f477cedc
...
...
@@ -526,7 +526,7 @@ xfs_bmbt_free_block(
struct
xfs_trans
*
tp
=
cur
->
bc_tp
;
xfs_fsblock_t
fsbno
=
XFS_DADDR_TO_FSB
(
mp
,
XFS_BUF_ADDR
(
bp
));
xfs_bmap_add_free
(
fsbno
,
1
,
cur
->
bc_private
.
b
.
flist
,
mp
);
xfs_bmap_add_free
(
mp
,
cur
->
bc_private
.
b
.
flist
,
fsbno
,
1
);
ip
->
i_d
.
di_nblocks
--
;
xfs_trans_log_inode
(
tp
,
ip
,
XFS_ILOG_CORE
);
...
...
fs/xfs/libxfs/xfs_btree.c
浏览文件 @
f477cedc
...
...
@@ -4152,3 +4152,22 @@ xfs_btree_sblock_verify(
return
true
;
}
/*
* Calculate the number of btree levels needed to store a given number of
* records in a short-format btree.
*/
uint
xfs_btree_compute_maxlevels
(
struct
xfs_mount
*
mp
,
uint
*
limits
,
unsigned
long
len
)
{
uint
level
;
unsigned
long
maxblocks
;
maxblocks
=
(
len
+
limits
[
0
]
-
1
)
/
limits
[
0
];
for
(
level
=
1
;
maxblocks
>
1
;
level
++
)
maxblocks
=
(
maxblocks
+
limits
[
1
]
-
1
)
/
limits
[
1
];
return
level
;
}
fs/xfs/libxfs/xfs_btree.h
浏览文件 @
f477cedc
...
...
@@ -474,5 +474,7 @@ static inline int xfs_btree_get_level(struct xfs_btree_block *block)
bool
xfs_btree_sblock_v5hdr_verify
(
struct
xfs_buf
*
bp
);
bool
xfs_btree_sblock_verify
(
struct
xfs_buf
*
bp
,
unsigned
int
max_recs
);
uint
xfs_btree_compute_maxlevels
(
struct
xfs_mount
*
mp
,
uint
*
limits
,
unsigned
long
len
);
#endif
/* __XFS_BTREE_H__ */
fs/xfs/libxfs/xfs_ialloc.c
浏览文件 @
f477cedc
...
...
@@ -1828,9 +1828,8 @@ xfs_difree_inode_chunk(
if
(
!
xfs_inobt_issparse
(
rec
->
ir_holemask
))
{
/* not sparse, calculate extent info directly */
xfs_bmap_add_free
(
XFS_AGB_TO_FSB
(
mp
,
agno
,
XFS_AGINO_TO_AGBNO
(
mp
,
rec
->
ir_startino
)),
mp
->
m_ialloc_blks
,
flist
,
mp
);
xfs_bmap_add_free
(
mp
,
flist
,
XFS_AGB_TO_FSB
(
mp
,
agno
,
sagbno
),
mp
->
m_ialloc_blks
);
return
;
}
...
...
@@ -1873,8 +1872,8 @@ xfs_difree_inode_chunk(
ASSERT
(
agbno
%
mp
->
m_sb
.
sb_spino_align
==
0
);
ASSERT
(
contigblk
%
mp
->
m_sb
.
sb_spino_align
==
0
);
xfs_bmap_add_free
(
XFS_AGB_TO_FSB
(
mp
,
agno
,
agbno
),
contigblk
,
flist
,
mp
);
xfs_bmap_add_free
(
mp
,
flist
,
XFS_AGB_TO_FSB
(
mp
,
agno
,
agbno
)
,
contigblk
);
/* reset range to current bit and carry on... */
startidx
=
endidx
=
nextbit
;
...
...
@@ -2395,20 +2394,11 @@ void
xfs_ialloc_compute_maxlevels
(
xfs_mount_t
*
mp
)
/* file system mount structure */
{
int
level
;
uint
maxblocks
;
uint
maxleafents
;
int
minleafrecs
;
int
minnoderecs
;
maxleafents
=
(
1LL
<<
XFS_INO_AGINO_BITS
(
mp
))
>>
XFS_INODES_PER_CHUNK_LOG
;
minleafrecs
=
mp
->
m_inobt_mnr
[
0
];
minnoderecs
=
mp
->
m_inobt_mnr
[
1
];
maxblocks
=
(
maxleafents
+
minleafrecs
-
1
)
/
minleafrecs
;
for
(
level
=
1
;
maxblocks
>
1
;
level
++
)
maxblocks
=
(
maxblocks
+
minnoderecs
-
1
)
/
minnoderecs
;
mp
->
m_in_maxlevels
=
level
;
uint
inodes
;
inodes
=
(
1LL
<<
XFS_INO_AGINO_BITS
(
mp
))
>>
XFS_INODES_PER_CHUNK_LOG
;
mp
->
m_in_maxlevels
=
xfs_btree_compute_maxlevels
(
mp
,
mp
->
m_inobt_mnr
,
inodes
);
}
/*
...
...
fs/xfs/xfs_bmap_util.c
浏览文件 @
f477cedc
...
...
@@ -79,6 +79,23 @@ xfs_zero_extent(
GFP_NOFS
,
true
);
}
/* Sort bmap items by AG. */
static
int
xfs_bmap_free_list_cmp
(
void
*
priv
,
struct
list_head
*
a
,
struct
list_head
*
b
)
{
struct
xfs_mount
*
mp
=
priv
;
struct
xfs_bmap_free_item
*
ra
;
struct
xfs_bmap_free_item
*
rb
;
ra
=
container_of
(
a
,
struct
xfs_bmap_free_item
,
xbfi_list
);
rb
=
container_of
(
b
,
struct
xfs_bmap_free_item
,
xbfi_list
);
return
XFS_FSB_TO_AGNO
(
mp
,
ra
->
xbfi_startblock
)
-
XFS_FSB_TO_AGNO
(
mp
,
rb
->
xbfi_startblock
);
}
/*
* Routine to be called at transaction's end by xfs_bmapi, xfs_bunmapi
* caller. Frees all the extents that need freeing, which must be done
...
...
@@ -99,14 +116,15 @@ xfs_bmap_finish(
int
error
;
/* error return value */
int
committed
;
/* xact committed or not */
struct
xfs_bmap_free_item
*
free
;
/* free extent item */
struct
xfs_bmap_free_item
*
next
;
/* next item on free list */
ASSERT
((
*
tp
)
->
t_flags
&
XFS_TRANS_PERM_LOG_RES
);
if
(
flist
->
xbf_count
==
0
)
return
0
;
list_sort
((
*
tp
)
->
t_mountp
,
&
flist
->
xbf_flist
,
xfs_bmap_free_list_cmp
);
efi
=
xfs_trans_get_efi
(
*
tp
,
flist
->
xbf_count
);
for
(
free
=
flist
->
xbf_first
;
free
;
free
=
free
->
xbfi_nex
t
)
list_for_each_entry
(
free
,
&
flist
->
xbf_flist
,
xbfi_lis
t
)
xfs_trans_log_efi_extent
(
*
tp
,
efi
,
free
->
xbfi_startblock
,
free
->
xbfi_blockcount
);
...
...
@@ -136,15 +154,15 @@ xfs_bmap_finish(
* on error.
*/
efd
=
xfs_trans_get_efd
(
*
tp
,
efi
,
flist
->
xbf_count
);
for
(
free
=
flist
->
xbf_first
;
free
!=
NULL
;
free
=
next
)
{
next
=
free
->
xbfi_next
;
while
(
!
list_empty
(
&
flist
->
xbf_flist
)
)
{
free
=
list_first_entry
(
&
flist
->
xbf_flist
,
struct
xfs_bmap_free_item
,
xbfi_list
);
error
=
xfs_trans_free_extent
(
*
tp
,
efd
,
free
->
xbfi_startblock
,
free
->
xbfi_blockcount
);
if
(
error
)
return
error
;
xfs_bmap_del_free
(
flist
,
NULL
,
free
);
xfs_bmap_del_free
(
flist
,
free
);
}
return
0
;
...
...
@@ -797,7 +815,7 @@ xfs_bmap_punch_delalloc_range(
if
(
error
)
break
;
ASSERT
(
!
flist
.
xbf_count
&&
!
flist
.
xbf_first
);
ASSERT
(
!
flist
.
xbf_count
&&
list_empty
(
&
flist
.
xbf_flist
)
);
next_block:
start_fsb
++
;
remaining
--
;
...
...
fs/xfs/xfs_bmap_util.h
浏览文件 @
f477cedc
...
...
@@ -41,7 +41,6 @@ int xfs_getbmap(struct xfs_inode *ip, struct getbmapx *bmv,
/* functions in xfs_bmap.c that are only needed by xfs_bmap_util.c */
void
xfs_bmap_del_free
(
struct
xfs_bmap_free
*
flist
,
struct
xfs_bmap_free_item
*
prev
,
struct
xfs_bmap_free_item
*
free
);
int
xfs_bmap_extsize_align
(
struct
xfs_mount
*
mp
,
struct
xfs_bmbt_irec
*
gotp
,
struct
xfs_bmbt_irec
*
prevp
,
xfs_extlen_t
extsz
,
...
...
fs/xfs/xfs_buf.c
浏览文件 @
f477cedc
...
...
@@ -944,10 +944,12 @@ xfs_buf_trylock(
int
locked
;
locked
=
down_trylock
(
&
bp
->
b_sema
)
==
0
;
if
(
locked
)
if
(
locked
)
{
XB_SET_OWNER
(
bp
);
trace_xfs_buf_trylock
(
bp
,
_RET_IP_
);
trace_xfs_buf_trylock
(
bp
,
_RET_IP_
);
}
else
{
trace_xfs_buf_trylock_fail
(
bp
,
_RET_IP_
);
}
return
locked
;
}
...
...
fs/xfs/xfs_error.c
浏览文件 @
f477cedc
...
...
@@ -61,6 +61,9 @@ xfs_errortag_add(int error_tag, xfs_mount_t *mp)
int
len
;
int64_t
fsid
;
if
(
error_tag
>=
XFS_ERRTAG_MAX
)
return
-
EINVAL
;
memcpy
(
&
fsid
,
mp
->
m_fixedfsid
,
sizeof
(
xfs_fsid_t
));
for
(
i
=
0
;
i
<
XFS_NUM_INJECT_ERROR
;
i
++
)
{
...
...
fs/xfs/xfs_fsops.c
浏览文件 @
f477cedc
...
...
@@ -667,8 +667,11 @@ xfs_reserve_blocks(
__uint64_t
*
inval
,
xfs_fsop_resblks_t
*
outval
)
{
__int64_t
lcounter
,
delta
,
fdblks_delta
;
__int64_t
lcounter
,
delta
;
__int64_t
fdblks_delta
=
0
;
__uint64_t
request
;
__int64_t
free
;
int
error
=
0
;
/* If inval is null, report current values and return */
if
(
inval
==
(
__uint64_t
*
)
NULL
)
{
...
...
@@ -682,24 +685,23 @@ xfs_reserve_blocks(
request
=
*
inval
;
/*
* With per-cpu counters, this becomes an interesting
*
problem. we needto work out if we are freeing or allocatio
n
*
blocks first, then we can
do the modification as necessary.
* With per-cpu counters, this becomes an interesting
problem. we need
*
to work out if we are freeing or allocation blocks first, then we ca
n
* do the modification as necessary.
*
* We do this under the m_sb_lock so that if we are near
* ENOSPC, we will hold out any changes while we work out
* what to do. This means that the amount of free space can
* change while we do this, so we need to retry if we end up
* trying to reserve more space than is available.
* We do this under the m_sb_lock so that if we are near ENOSPC, we will
* hold out any changes while we work out what to do. This means that
* the amount of free space can change while we do this, so we need to
* retry if we end up trying to reserve more space than is available.
*/
retry:
spin_lock
(
&
mp
->
m_sb_lock
);
/*
* If our previous reservation was larger than the current value,
* then move any unused blocks back to the free pool.
* then move any unused blocks back to the free pool. Modify the resblks
* counters directly since we shouldn't have any problems unreserving
* space.
*/
fdblks_delta
=
0
;
if
(
mp
->
m_resblks
>
request
)
{
lcounter
=
mp
->
m_resblks_avail
-
request
;
if
(
lcounter
>
0
)
{
/* release unused blocks */
...
...
@@ -707,54 +709,67 @@ xfs_reserve_blocks(
mp
->
m_resblks_avail
-=
lcounter
;
}
mp
->
m_resblks
=
request
;
}
else
{
__int64_t
free
;
if
(
fdblks_delta
)
{
spin_unlock
(
&
mp
->
m_sb_lock
);
error
=
xfs_mod_fdblocks
(
mp
,
fdblks_delta
,
0
);
spin_lock
(
&
mp
->
m_sb_lock
);
}
goto
out
;
}
/*
* If the request is larger than the current reservation, reserve the
* blocks before we update the reserve counters. Sample m_fdblocks and
* perform a partial reservation if the request exceeds free space.
*/
error
=
-
ENOSPC
;
do
{
free
=
percpu_counter_sum
(
&
mp
->
m_fdblocks
)
-
XFS_ALLOC_SET_ASIDE
(
mp
);
if
(
!
free
)
goto
out
;
/* ENOSPC and fdblks_delta = 0 */
break
;
delta
=
request
-
mp
->
m_resblks
;
lcounter
=
free
-
delta
;
if
(
lcounter
<
0
)
{
if
(
lcounter
<
0
)
/* We can't satisfy the request, just get what we can */
mp
->
m_resblks
+=
free
;
mp
->
m_resblks_avail
+=
free
;
fdblks_delta
=
-
free
;
}
else
{
fdblks_delta
=
-
delta
;
mp
->
m_resblks
=
request
;
mp
->
m_resblks_avail
+=
delta
;
}
}
out:
if
(
outval
)
{
outval
->
resblks
=
mp
->
m_resblks
;
outval
->
resblks_avail
=
mp
->
m_resblks_avail
;
}
spin_unlock
(
&
mp
->
m_sb_lock
);
fdblks_delta
=
free
;
else
fdblks_delta
=
delta
;
if
(
fdblks_delta
)
{
/*
* If we are putting blocks back here, m_resblks_avail is
* already at its max so this will put it in the free pool.
*
* If we need space, we'll either succeed in getting it
* from the free block count or we'll get an enospc. If
* we get a ENOSPC, it means things changed while we were
* calculating fdblks_delta and so we should try again to
* see if there is anything left to reserve.
* We'll either succeed in getting space from the free block
* count or we'll get an ENOSPC. If we get a ENOSPC, it means
* things changed while we were calculating fdblks_delta and so
* we should try again to see if there is anything left to
* reserve.
*
* Don't set the reserved flag here - we don't want to reserve
* the extra reserve blocks from the reserve.....
*/
int
error
;
error
=
xfs_mod_fdblocks
(
mp
,
fdblks_delta
,
0
);
if
(
error
==
-
ENOSPC
)
goto
retry
;
spin_unlock
(
&
mp
->
m_sb_lock
);
error
=
xfs_mod_fdblocks
(
mp
,
-
fdblks_delta
,
0
);
spin_lock
(
&
mp
->
m_sb_lock
);
}
while
(
error
==
-
ENOSPC
);
/*
* Update the reserve counters if blocks have been successfully
* allocated.
*/
if
(
!
error
&&
fdblks_delta
)
{
mp
->
m_resblks
+=
fdblks_delta
;
mp
->
m_resblks_avail
+=
fdblks_delta
;
}
return
0
;
out:
if
(
outval
)
{
outval
->
resblks
=
mp
->
m_resblks
;
outval
->
resblks_avail
=
mp
->
m_resblks_avail
;
}
spin_unlock
(
&
mp
->
m_sb_lock
);
return
error
;
}
int
...
...
fs/xfs/xfs_icache.c
浏览文件 @
f477cedc
...
...
@@ -765,7 +765,7 @@ xfs_inode_ag_walk(
* Background scanning to trim post-EOF preallocated space. This is queued
* based on the 'speculative_prealloc_lifetime' tunable (5m by default).
*/
STATIC
void
void
xfs_queue_eofblocks
(
struct
xfs_mount
*
mp
)
{
...
...
fs/xfs/xfs_icache.h
浏览文件 @
f477cedc
...
...
@@ -68,6 +68,7 @@ void xfs_inode_clear_eofblocks_tag(struct xfs_inode *ip);
int
xfs_icache_free_eofblocks
(
struct
xfs_mount
*
,
struct
xfs_eofblocks
*
);
int
xfs_inode_free_quota_eofblocks
(
struct
xfs_inode
*
ip
);
void
xfs_eofblocks_worker
(
struct
work_struct
*
);
void
xfs_queue_eofblocks
(
struct
xfs_mount
*
);
int
xfs_inode_ag_iterator
(
struct
xfs_mount
*
mp
,
int
(
*
execute
)(
struct
xfs_inode
*
ip
,
int
flags
,
void
*
args
),
...
...
fs/xfs/xfs_ondisk.h
浏览文件 @
f477cedc
...
...
@@ -22,6 +22,11 @@
BUILD_BUG_ON_MSG(sizeof(structname) != (size), "XFS: sizeof(" \
#structname ") is wrong, expected " #size)
#define XFS_CHECK_OFFSET(structname, member, off) \
BUILD_BUG_ON_MSG(offsetof(structname, member) != (off), \
"XFS: offsetof(" #structname ", " #member ") is wrong, " \
"expected " #off)
static
inline
void
__init
xfs_check_ondisk_structs
(
void
)
{
...
...
@@ -75,15 +80,28 @@ xfs_check_ondisk_structs(void)
XFS_CHECK_STRUCT_SIZE(xfs_attr_leaf_name_remote_t, 12);
*/
XFS_CHECK_OFFSET
(
xfs_attr_leaf_name_local_t
,
valuelen
,
0
);
XFS_CHECK_OFFSET
(
xfs_attr_leaf_name_local_t
,
namelen
,
2
);
XFS_CHECK_OFFSET
(
xfs_attr_leaf_name_local_t
,
nameval
,
3
);
XFS_CHECK_OFFSET
(
xfs_attr_leaf_name_remote_t
,
valueblk
,
0
);
XFS_CHECK_OFFSET
(
xfs_attr_leaf_name_remote_t
,
valuelen
,
4
);
XFS_CHECK_OFFSET
(
xfs_attr_leaf_name_remote_t
,
namelen
,
8
);
XFS_CHECK_OFFSET
(
xfs_attr_leaf_name_remote_t
,
name
,
9
);
XFS_CHECK_STRUCT_SIZE
(
xfs_attr_leafblock_t
,
40
);
XFS_CHECK_STRUCT_SIZE
(
xfs_attr_shortform_t
,
8
);
XFS_CHECK_OFFSET
(
xfs_attr_shortform_t
,
hdr
.
totsize
,
0
);
XFS_CHECK_OFFSET
(
xfs_attr_shortform_t
,
hdr
.
count
,
2
);
XFS_CHECK_OFFSET
(
xfs_attr_shortform_t
,
list
[
0
].
namelen
,
4
);
XFS_CHECK_OFFSET
(
xfs_attr_shortform_t
,
list
[
0
].
valuelen
,
5
);
XFS_CHECK_OFFSET
(
xfs_attr_shortform_t
,
list
[
0
].
flags
,
6
);
XFS_CHECK_OFFSET
(
xfs_attr_shortform_t
,
list
[
0
].
nameval
,
7
);
XFS_CHECK_STRUCT_SIZE
(
xfs_da_blkinfo_t
,
12
);
XFS_CHECK_STRUCT_SIZE
(
xfs_da_intnode_t
,
16
);
XFS_CHECK_STRUCT_SIZE
(
xfs_da_node_entry_t
,
8
);
XFS_CHECK_STRUCT_SIZE
(
xfs_da_node_hdr_t
,
16
);
XFS_CHECK_STRUCT_SIZE
(
xfs_dir2_data_free_t
,
4
);
XFS_CHECK_STRUCT_SIZE
(
xfs_dir2_data_hdr_t
,
16
);
XFS_CHECK_STRUCT_SIZE
(
xfs_dir2_data_unused_t
,
6
);
XFS_CHECK_OFFSET
(
xfs_dir2_data_unused_t
,
freetag
,
0
);
XFS_CHECK_OFFSET
(
xfs_dir2_data_unused_t
,
length
,
2
);
XFS_CHECK_STRUCT_SIZE
(
xfs_dir2_free_hdr_t
,
16
);
XFS_CHECK_STRUCT_SIZE
(
xfs_dir2_free_t
,
16
);
XFS_CHECK_STRUCT_SIZE
(
xfs_dir2_ino4_t
,
4
);
...
...
@@ -94,6 +112,9 @@ xfs_check_ondisk_structs(void)
XFS_CHECK_STRUCT_SIZE
(
xfs_dir2_leaf_t
,
16
);
XFS_CHECK_STRUCT_SIZE
(
xfs_dir2_leaf_tail_t
,
4
);
XFS_CHECK_STRUCT_SIZE
(
xfs_dir2_sf_entry_t
,
3
);
XFS_CHECK_OFFSET
(
xfs_dir2_sf_entry_t
,
namelen
,
0
);
XFS_CHECK_OFFSET
(
xfs_dir2_sf_entry_t
,
offset
,
1
);
XFS_CHECK_OFFSET
(
xfs_dir2_sf_entry_t
,
name
,
3
);
XFS_CHECK_STRUCT_SIZE
(
xfs_dir2_sf_hdr_t
,
10
);
XFS_CHECK_STRUCT_SIZE
(
xfs_dir2_sf_off_t
,
2
);
...
...
fs/xfs/xfs_super.c
浏览文件 @
f477cedc
...
...
@@ -1294,6 +1294,7 @@ xfs_fs_remount(
*/
xfs_restore_resvblks
(
mp
);
xfs_log_work_queue
(
mp
);
xfs_queue_eofblocks
(
mp
);
}
/* rw -> ro */
...
...
@@ -1306,6 +1307,13 @@ xfs_fs_remount(
* return it to the same size.
*/
xfs_save_resvblks
(
mp
);
/*
* Cancel background eofb scanning so it cannot race with the
* final log force+buftarg wait and deadlock the remount.
*/
cancel_delayed_work_sync
(
&
mp
->
m_eofblocks_work
);
xfs_quiesce_attr
(
mp
);
mp
->
m_flags
|=
XFS_MOUNT_RDONLY
;
}
...
...
@@ -1692,8 +1700,9 @@ xfs_init_zones(void)
if
(
!
xfs_log_ticket_zone
)
goto
out_free_ioend_bioset
;
xfs_bmap_free_item_zone
=
kmem_zone_init
(
sizeof
(
xfs_bmap_free_item_t
),
"xfs_bmap_free_item"
);
xfs_bmap_free_item_zone
=
kmem_zone_init
(
sizeof
(
struct
xfs_bmap_free_item
),
"xfs_bmap_free_item"
);
if
(
!
xfs_bmap_free_item_zone
)
goto
out_destroy_log_ticket_zone
;
...
...
fs/xfs/xfs_trace.h
浏览文件 @
f477cedc
...
...
@@ -354,6 +354,7 @@ DEFINE_BUF_EVENT(xfs_buf_submit_wait);
DEFINE_BUF_EVENT
(
xfs_buf_bawrite
);
DEFINE_BUF_EVENT
(
xfs_buf_lock
);
DEFINE_BUF_EVENT
(
xfs_buf_lock_done
);
DEFINE_BUF_EVENT
(
xfs_buf_trylock_fail
);
DEFINE_BUF_EVENT
(
xfs_buf_trylock
);
DEFINE_BUF_EVENT
(
xfs_buf_unlock
);
DEFINE_BUF_EVENT
(
xfs_buf_iowait
);
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录