Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openeuler
raspberrypi-kernel
提交
8612c7e5
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看板
提交
8612c7e5
编写于
6月 10, 2014
作者:
D
Dave Chinner
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'xfs-da-geom' into for-next
上级
b70f14e1
35f46c5f
变更
26
展开全部
隐藏空白更改
内联
并排
Showing
26 changed file
with
819 addition
and
778 deletion
+819
-778
fs/xfs/xfs_attr.c
fs/xfs/xfs_attr.c
+4
-13
fs/xfs/xfs_attr_leaf.c
fs/xfs/xfs_attr_leaf.c
+89
-95
fs/xfs/xfs_attr_leaf.h
fs/xfs/xfs_attr_leaf.h
+1
-2
fs/xfs/xfs_attr_list.c
fs/xfs/xfs_attr_list.c
+1
-0
fs/xfs/xfs_attr_remote.c
fs/xfs/xfs_attr_remote.c
+29
-26
fs/xfs/xfs_bmap.c
fs/xfs/xfs_bmap.c
+2
-1
fs/xfs/xfs_da_btree.c
fs/xfs/xfs_da_btree.c
+29
-36
fs/xfs/xfs_da_btree.h
fs/xfs/xfs_da_btree.h
+18
-2
fs/xfs/xfs_da_format.c
fs/xfs/xfs_da_format.c
+20
-16
fs/xfs/xfs_da_format.h
fs/xfs/xfs_da_format.h
+0
-154
fs/xfs/xfs_dir2.c
fs/xfs/xfs_dir2.c
+85
-47
fs/xfs/xfs_dir2.h
fs/xfs/xfs_dir2.h
+17
-13
fs/xfs/xfs_dir2_block.c
fs/xfs/xfs_dir2_block.c
+45
-43
fs/xfs/xfs_dir2_data.c
fs/xfs/xfs_dir2_data.c
+39
-41
fs/xfs/xfs_dir2_leaf.c
fs/xfs/xfs_dir2_leaf.c
+105
-95
fs/xfs/xfs_dir2_node.c
fs/xfs/xfs_dir2_node.c
+95
-93
fs/xfs/xfs_dir2_priv.h
fs/xfs/xfs_dir2_priv.h
+136
-2
fs/xfs/xfs_dir2_readdir.c
fs/xfs/xfs_dir2_readdir.c
+72
-70
fs/xfs/xfs_dir2_sf.c
fs/xfs/xfs_dir2_sf.c
+10
-8
fs/xfs/xfs_fsops.c
fs/xfs/xfs_fsops.c
+3
-1
fs/xfs/xfs_log_rlimit.c
fs/xfs/xfs_log_rlimit.c
+1
-1
fs/xfs/xfs_mount.c
fs/xfs/xfs_mount.c
+9
-7
fs/xfs/xfs_mount.h
fs/xfs/xfs_mount.h
+3
-9
fs/xfs/xfs_symlink.c
fs/xfs/xfs_symlink.c
+1
-0
fs/xfs/xfs_trans_resv.c
fs/xfs/xfs_trans_resv.c
+2
-1
fs/xfs/xfs_trans_space.h
fs/xfs/xfs_trans_space.h
+3
-2
未找到文件。
fs/xfs/xfs_attr.c
浏览文件 @
8612c7e5
...
...
@@ -88,6 +88,7 @@ xfs_attr_args_init(
return
EINVAL
;
memset
(
args
,
0
,
sizeof
(
*
args
));
args
->
geo
=
dp
->
i_mount
->
m_attr_geo
;
args
->
whichfork
=
XFS_ATTR_FORK
;
args
->
dp
=
dp
;
args
->
flags
=
flags
;
...
...
@@ -173,12 +174,10 @@ xfs_attr_calc_size(
* Determine space new attribute will use, and if it would be
* "local" or "remote" (note: local != inline).
*/
size
=
xfs_attr_leaf_newentsize
(
args
->
namelen
,
args
->
valuelen
,
mp
->
m_sb
.
sb_blocksize
,
local
);
size
=
xfs_attr_leaf_newentsize
(
args
,
local
);
nblks
=
XFS_DAENTER_SPACE_RES
(
mp
,
XFS_ATTR_FORK
);
if
(
*
local
)
{
if
(
size
>
(
mp
->
m_sb
.
sb_blocksize
>>
1
))
{
if
(
size
>
(
args
->
geo
->
blksize
/
2
))
{
/* Double split possible */
nblks
*=
2
;
}
...
...
@@ -864,7 +863,7 @@ xfs_attr_leaf_get(xfs_da_args_t *args)
}
/*========================================================================
* External routines when attribute list size >
XFS_LBSIZE(mp).
* External routines when attribute list size >
geo->blksize
*========================================================================*/
/*
...
...
@@ -897,8 +896,6 @@ xfs_attr_node_addname(xfs_da_args_t *args)
state
=
xfs_da_state_alloc
();
state
->
args
=
args
;
state
->
mp
=
mp
;
state
->
blocksize
=
state
->
mp
->
m_sb
.
sb_blocksize
;
state
->
node_ents
=
state
->
mp
->
m_attr_node_ents
;
/*
* Search to see if name already exists, and get back a pointer
...
...
@@ -1076,8 +1073,6 @@ xfs_attr_node_addname(xfs_da_args_t *args)
state
=
xfs_da_state_alloc
();
state
->
args
=
args
;
state
->
mp
=
mp
;
state
->
blocksize
=
state
->
mp
->
m_sb
.
sb_blocksize
;
state
->
node_ents
=
state
->
mp
->
m_attr_node_ents
;
state
->
inleaf
=
0
;
error
=
xfs_da3_node_lookup_int
(
state
,
&
retval
);
if
(
error
)
...
...
@@ -1168,8 +1163,6 @@ xfs_attr_node_removename(xfs_da_args_t *args)
state
=
xfs_da_state_alloc
();
state
->
args
=
args
;
state
->
mp
=
dp
->
i_mount
;
state
->
blocksize
=
state
->
mp
->
m_sb
.
sb_blocksize
;
state
->
node_ents
=
state
->
mp
->
m_attr_node_ents
;
/*
* Search to see if name exists, and get back a pointer to it.
...
...
@@ -1431,8 +1424,6 @@ xfs_attr_node_get(xfs_da_args_t *args)
state
=
xfs_da_state_alloc
();
state
->
args
=
args
;
state
->
mp
=
args
->
dp
->
i_mount
;
state
->
blocksize
=
state
->
mp
->
m_sb
.
sb_blocksize
;
state
->
node_ents
=
state
->
mp
->
m_attr_node_ents
;
/*
* Search to see if name exists, and get back a pointer to it.
...
...
fs/xfs/xfs_attr_leaf.c
浏览文件 @
8612c7e5
...
...
@@ -80,11 +80,12 @@ STATIC int xfs_attr3_leaf_figure_balance(xfs_da_state_t *state,
/*
* Utility routines.
*/
STATIC
void
xfs_attr3_leaf_moveents
(
struct
xfs_attr_leafblock
*
src_leaf
,
STATIC
void
xfs_attr3_leaf_moveents
(
struct
xfs_da_args
*
args
,
struct
xfs_attr_leafblock
*
src_leaf
,
struct
xfs_attr3_icleaf_hdr
*
src_ichdr
,
int
src_start
,
struct
xfs_attr_leafblock
*
dst_leaf
,
struct
xfs_attr3_icleaf_hdr
*
dst_ichdr
,
int
dst_start
,
int
move_count
,
struct
xfs_mount
*
mp
);
int
move_count
);
STATIC
int
xfs_attr_leaf_entsize
(
xfs_attr_leafblock_t
*
leaf
,
int
index
);
void
...
...
@@ -711,6 +712,7 @@ xfs_attr_shortform_to_leaf(xfs_da_args_t *args)
memset
((
char
*
)
&
nargs
,
0
,
sizeof
(
nargs
));
nargs
.
dp
=
dp
;
nargs
.
geo
=
args
->
geo
;
nargs
.
firstblock
=
args
->
firstblock
;
nargs
.
flist
=
args
->
flist
;
nargs
.
total
=
args
->
total
;
...
...
@@ -805,18 +807,18 @@ xfs_attr3_leaf_to_shortform(
trace_xfs_attr_leaf_to_sf
(
args
);
tmpbuffer
=
kmem_alloc
(
XFS_LBSIZE
(
dp
->
i_mount
)
,
KM_SLEEP
);
tmpbuffer
=
kmem_alloc
(
args
->
geo
->
blksize
,
KM_SLEEP
);
if
(
!
tmpbuffer
)
return
ENOMEM
;
memcpy
(
tmpbuffer
,
bp
->
b_addr
,
XFS_LBSIZE
(
dp
->
i_mount
)
);
memcpy
(
tmpbuffer
,
bp
->
b_addr
,
args
->
geo
->
blksize
);
leaf
=
(
xfs_attr_leafblock_t
*
)
tmpbuffer
;
xfs_attr3_leaf_hdr_from_disk
(
&
ichdr
,
leaf
);
entry
=
xfs_attr3_leaf_entryp
(
leaf
);
/* XXX (dgc): buffer is about to be marked stale - why zero it? */
memset
(
bp
->
b_addr
,
0
,
XFS_LBSIZE
(
dp
->
i_mount
)
);
memset
(
bp
->
b_addr
,
0
,
args
->
geo
->
blksize
);
/*
* Clean out the prior contents of the attribute list.
...
...
@@ -838,6 +840,7 @@ xfs_attr3_leaf_to_shortform(
* Copy the attributes
*/
memset
((
char
*
)
&
nargs
,
0
,
sizeof
(
nargs
));
nargs
.
geo
=
args
->
geo
;
nargs
.
dp
=
dp
;
nargs
.
firstblock
=
args
->
firstblock
;
nargs
.
flist
=
args
->
flist
;
...
...
@@ -904,12 +907,12 @@ xfs_attr3_leaf_to_node(
/* copy leaf to new buffer, update identifiers */
xfs_trans_buf_set_type
(
args
->
trans
,
bp2
,
XFS_BLFT_ATTR_LEAF_BUF
);
bp2
->
b_ops
=
bp1
->
b_ops
;
memcpy
(
bp2
->
b_addr
,
bp1
->
b_addr
,
XFS_LBSIZE
(
mp
)
);
memcpy
(
bp2
->
b_addr
,
bp1
->
b_addr
,
args
->
geo
->
blksize
);
if
(
xfs_sb_version_hascrc
(
&
mp
->
m_sb
))
{
struct
xfs_da3_blkinfo
*
hdr3
=
bp2
->
b_addr
;
hdr3
->
blkno
=
cpu_to_be64
(
bp2
->
b_bn
);
}
xfs_trans_log_buf
(
args
->
trans
,
bp2
,
0
,
XFS_LBSIZE
(
mp
)
-
1
);
xfs_trans_log_buf
(
args
->
trans
,
bp2
,
0
,
args
->
geo
->
blksize
-
1
);
/*
* Set up the new root node.
...
...
@@ -930,7 +933,7 @@ xfs_attr3_leaf_to_node(
btree
[
0
].
before
=
cpu_to_be32
(
blkno
);
icnodehdr
.
count
=
1
;
dp
->
d_ops
->
node_hdr_to_disk
(
node
,
&
icnodehdr
);
xfs_trans_log_buf
(
args
->
trans
,
bp1
,
0
,
XFS_LBSIZE
(
mp
)
-
1
);
xfs_trans_log_buf
(
args
->
trans
,
bp1
,
0
,
args
->
geo
->
blksize
-
1
);
error
=
0
;
out:
return
error
;
...
...
@@ -966,10 +969,10 @@ xfs_attr3_leaf_create(
bp
->
b_ops
=
&
xfs_attr3_leaf_buf_ops
;
xfs_trans_buf_set_type
(
args
->
trans
,
bp
,
XFS_BLFT_ATTR_LEAF_BUF
);
leaf
=
bp
->
b_addr
;
memset
(
leaf
,
0
,
XFS_LBSIZE
(
mp
)
);
memset
(
leaf
,
0
,
args
->
geo
->
blksize
);
memset
(
&
ichdr
,
0
,
sizeof
(
ichdr
));
ichdr
.
firstused
=
XFS_LBSIZE
(
mp
)
;
ichdr
.
firstused
=
args
->
geo
->
blksize
;
if
(
xfs_sb_version_hascrc
(
&
mp
->
m_sb
))
{
struct
xfs_da3_blkinfo
*
hdr3
=
bp
->
b_addr
;
...
...
@@ -988,7 +991,7 @@ xfs_attr3_leaf_create(
ichdr
.
freemap
[
0
].
size
=
ichdr
.
firstused
-
ichdr
.
freemap
[
0
].
base
;
xfs_attr3_leaf_hdr_to_disk
(
leaf
,
&
ichdr
);
xfs_trans_log_buf
(
args
->
trans
,
bp
,
0
,
XFS_LBSIZE
(
mp
)
-
1
);
xfs_trans_log_buf
(
args
->
trans
,
bp
,
0
,
args
->
geo
->
blksize
-
1
);
*
bpp
=
bp
;
return
0
;
...
...
@@ -1074,8 +1077,7 @@ xfs_attr3_leaf_add(
leaf
=
bp
->
b_addr
;
xfs_attr3_leaf_hdr_from_disk
(
&
ichdr
,
leaf
);
ASSERT
(
args
->
index
>=
0
&&
args
->
index
<=
ichdr
.
count
);
entsize
=
xfs_attr_leaf_newentsize
(
args
->
namelen
,
args
->
valuelen
,
args
->
trans
->
t_mountp
->
m_sb
.
sb_blocksize
,
NULL
);
entsize
=
xfs_attr_leaf_newentsize
(
args
,
NULL
);
/*
* Search through freemap for first-fit on new name length.
...
...
@@ -1174,17 +1176,14 @@ xfs_attr3_leaf_add_work(
* Allocate space for the new string (at the end of the run).
*/
mp
=
args
->
trans
->
t_mountp
;
ASSERT
(
ichdr
->
freemap
[
mapindex
].
base
<
XFS_LBSIZE
(
mp
)
);
ASSERT
(
ichdr
->
freemap
[
mapindex
].
base
<
args
->
geo
->
blksize
);
ASSERT
((
ichdr
->
freemap
[
mapindex
].
base
&
0x3
)
==
0
);
ASSERT
(
ichdr
->
freemap
[
mapindex
].
size
>=
xfs_attr_leaf_newentsize
(
args
->
namelen
,
args
->
valuelen
,
mp
->
m_sb
.
sb_blocksize
,
NULL
));
ASSERT
(
ichdr
->
freemap
[
mapindex
].
size
<
XFS_LBSIZE
(
mp
));
xfs_attr_leaf_newentsize
(
args
,
NULL
));
ASSERT
(
ichdr
->
freemap
[
mapindex
].
size
<
args
->
geo
->
blksize
);
ASSERT
((
ichdr
->
freemap
[
mapindex
].
size
&
0x3
)
==
0
);
ichdr
->
freemap
[
mapindex
].
size
-=
xfs_attr_leaf_newentsize
(
args
->
namelen
,
args
->
valuelen
,
mp
->
m_sb
.
sb_blocksize
,
&
tmp
);
ichdr
->
freemap
[
mapindex
].
size
-=
xfs_attr_leaf_newentsize
(
args
,
&
tmp
);
entry
->
nameidx
=
cpu_to_be16
(
ichdr
->
freemap
[
mapindex
].
base
+
ichdr
->
freemap
[
mapindex
].
size
);
...
...
@@ -1269,14 +1268,13 @@ xfs_attr3_leaf_compact(
struct
xfs_attr_leafblock
*
leaf_dst
;
struct
xfs_attr3_icleaf_hdr
ichdr_src
;
struct
xfs_trans
*
trans
=
args
->
trans
;
struct
xfs_mount
*
mp
=
trans
->
t_mountp
;
char
*
tmpbuffer
;
trace_xfs_attr_leaf_compact
(
args
);
tmpbuffer
=
kmem_alloc
(
XFS_LBSIZE
(
mp
)
,
KM_SLEEP
);
memcpy
(
tmpbuffer
,
bp
->
b_addr
,
XFS_LBSIZE
(
mp
)
);
memset
(
bp
->
b_addr
,
0
,
XFS_LBSIZE
(
mp
)
);
tmpbuffer
=
kmem_alloc
(
args
->
geo
->
blksize
,
KM_SLEEP
);
memcpy
(
tmpbuffer
,
bp
->
b_addr
,
args
->
geo
->
blksize
);
memset
(
bp
->
b_addr
,
0
,
args
->
geo
->
blksize
);
leaf_src
=
(
xfs_attr_leafblock_t
*
)
tmpbuffer
;
leaf_dst
=
bp
->
b_addr
;
...
...
@@ -1289,7 +1287,7 @@ xfs_attr3_leaf_compact(
/* Initialise the incore headers */
ichdr_src
=
*
ichdr_dst
;
/* struct copy */
ichdr_dst
->
firstused
=
XFS_LBSIZE
(
mp
)
;
ichdr_dst
->
firstused
=
args
->
geo
->
blksize
;
ichdr_dst
->
usedbytes
=
0
;
ichdr_dst
->
count
=
0
;
ichdr_dst
->
holes
=
0
;
...
...
@@ -1304,13 +1302,13 @@ xfs_attr3_leaf_compact(
* Copy all entry's in the same (sorted) order,
* but allocate name/value pairs packed and in sequence.
*/
xfs_attr3_leaf_moveents
(
leaf_src
,
&
ichdr_src
,
0
,
leaf_dst
,
ichdr_dst
,
0
,
ichdr_src
.
count
,
mp
);
xfs_attr3_leaf_moveents
(
args
,
leaf_src
,
&
ichdr_src
,
0
,
leaf_dst
,
ichdr_dst
,
0
,
ichdr_src
.
count
);
/*
* this logs the entire buffer, but the caller must write the header
* back to the buffer when it is finished modifying it.
*/
xfs_trans_log_buf
(
trans
,
bp
,
0
,
XFS_LBSIZE
(
mp
)
-
1
);
xfs_trans_log_buf
(
trans
,
bp
,
0
,
args
->
geo
->
blksize
-
1
);
kmem_free
(
tmpbuffer
);
}
...
...
@@ -1461,8 +1459,8 @@ xfs_attr3_leaf_rebalance(
/*
* Move high entries from leaf1 to low end of leaf2.
*/
xfs_attr3_leaf_moveents
(
leaf1
,
&
ichdr1
,
ichdr1
.
count
-
count
,
leaf2
,
&
ichdr2
,
0
,
count
,
state
->
mp
);
xfs_attr3_leaf_moveents
(
args
,
leaf1
,
&
ichdr1
,
ichdr1
.
count
-
count
,
leaf2
,
&
ichdr2
,
0
,
count
);
}
else
if
(
count
>
ichdr1
.
count
)
{
/*
...
...
@@ -1490,14 +1488,14 @@ xfs_attr3_leaf_rebalance(
/*
* Move low entries from leaf2 to high end of leaf1.
*/
xfs_attr3_leaf_moveents
(
leaf2
,
&
ichdr2
,
0
,
leaf1
,
&
ichdr1
,
ichdr1
.
count
,
count
,
state
->
mp
);
xfs_attr3_leaf_moveents
(
args
,
leaf2
,
&
ichdr2
,
0
,
leaf1
,
&
ichdr1
,
ichdr1
.
count
,
count
);
}
xfs_attr3_leaf_hdr_to_disk
(
leaf1
,
&
ichdr1
);
xfs_attr3_leaf_hdr_to_disk
(
leaf2
,
&
ichdr2
);
xfs_trans_log_buf
(
args
->
trans
,
blk1
->
bp
,
0
,
state
->
blocksize
-
1
);
xfs_trans_log_buf
(
args
->
trans
,
blk2
->
bp
,
0
,
state
->
blocksize
-
1
);
xfs_trans_log_buf
(
args
->
trans
,
blk1
->
bp
,
0
,
args
->
geo
->
blksize
-
1
);
xfs_trans_log_buf
(
args
->
trans
,
blk2
->
bp
,
0
,
args
->
geo
->
blksize
-
1
);
/*
* Copy out last hashval in each block for B-tree code.
...
...
@@ -1592,11 +1590,9 @@ xfs_attr3_leaf_figure_balance(
max
=
ichdr1
->
count
+
ichdr2
->
count
;
half
=
(
max
+
1
)
*
sizeof
(
*
entry
);
half
+=
ichdr1
->
usedbytes
+
ichdr2
->
usedbytes
+
xfs_attr_leaf_newentsize
(
state
->
args
->
namelen
,
state
->
args
->
valuelen
,
state
->
blocksize
,
NULL
);
xfs_attr_leaf_newentsize
(
state
->
args
,
NULL
);
half
/=
2
;
lastdelta
=
state
->
bloc
ksize
;
lastdelta
=
state
->
args
->
geo
->
bl
ksize
;
entry
=
xfs_attr3_leaf_entryp
(
leaf1
);
for
(
count
=
index
=
0
;
count
<
max
;
entry
++
,
index
++
,
count
++
)
{
...
...
@@ -1606,10 +1602,7 @@ xfs_attr3_leaf_figure_balance(
*/
if
(
count
==
blk1
->
index
)
{
tmp
=
totallen
+
sizeof
(
*
entry
)
+
xfs_attr_leaf_newentsize
(
state
->
args
->
namelen
,
state
->
args
->
valuelen
,
state
->
blocksize
,
NULL
);
xfs_attr_leaf_newentsize
(
state
->
args
,
NULL
);
if
(
XFS_ATTR_ABS
(
half
-
tmp
)
>
lastdelta
)
break
;
lastdelta
=
XFS_ATTR_ABS
(
half
-
tmp
);
...
...
@@ -1645,10 +1638,7 @@ xfs_attr3_leaf_figure_balance(
totallen
-=
count
*
sizeof
(
*
entry
);
if
(
foundit
)
{
totallen
-=
sizeof
(
*
entry
)
+
xfs_attr_leaf_newentsize
(
state
->
args
->
namelen
,
state
->
args
->
valuelen
,
state
->
blocksize
,
NULL
);
xfs_attr_leaf_newentsize
(
state
->
args
,
NULL
);
}
*
countarg
=
count
;
...
...
@@ -1700,7 +1690,7 @@ xfs_attr3_leaf_toosmall(
bytes
=
xfs_attr3_leaf_hdr_size
(
leaf
)
+
ichdr
.
count
*
sizeof
(
xfs_attr_leaf_entry_t
)
+
ichdr
.
usedbytes
;
if
(
bytes
>
(
state
->
bloc
ksize
>>
1
))
{
if
(
bytes
>
(
state
->
args
->
geo
->
bl
ksize
>>
1
))
{
*
action
=
0
;
/* blk over 50%, don't try to join */
return
(
0
);
}
...
...
@@ -1754,7 +1744,8 @@ xfs_attr3_leaf_toosmall(
xfs_attr3_leaf_hdr_from_disk
(
&
ichdr2
,
bp
->
b_addr
);
bytes
=
state
->
blocksize
-
(
state
->
blocksize
>>
2
)
-
bytes
=
state
->
args
->
geo
->
blksize
-
(
state
->
args
->
geo
->
blksize
>>
2
)
-
ichdr
.
usedbytes
-
ichdr2
.
usedbytes
-
((
ichdr
.
count
+
ichdr2
.
count
)
*
sizeof
(
xfs_attr_leaf_entry_t
))
-
...
...
@@ -1805,7 +1796,6 @@ xfs_attr3_leaf_remove(
struct
xfs_attr_leafblock
*
leaf
;
struct
xfs_attr3_icleaf_hdr
ichdr
;
struct
xfs_attr_leaf_entry
*
entry
;
struct
xfs_mount
*
mp
=
args
->
trans
->
t_mountp
;
int
before
;
int
after
;
int
smallest
;
...
...
@@ -1819,7 +1809,7 @@ xfs_attr3_leaf_remove(
leaf
=
bp
->
b_addr
;
xfs_attr3_leaf_hdr_from_disk
(
&
ichdr
,
leaf
);
ASSERT
(
ichdr
.
count
>
0
&&
ichdr
.
count
<
XFS_LBSIZE
(
mp
)
/
8
);
ASSERT
(
ichdr
.
count
>
0
&&
ichdr
.
count
<
args
->
geo
->
blksize
/
8
);
ASSERT
(
args
->
index
>=
0
&&
args
->
index
<
ichdr
.
count
);
ASSERT
(
ichdr
.
firstused
>=
ichdr
.
count
*
sizeof
(
*
entry
)
+
xfs_attr3_leaf_hdr_size
(
leaf
));
...
...
@@ -1827,7 +1817,7 @@ xfs_attr3_leaf_remove(
entry
=
&
xfs_attr3_leaf_entryp
(
leaf
)[
args
->
index
];
ASSERT
(
be16_to_cpu
(
entry
->
nameidx
)
>=
ichdr
.
firstused
);
ASSERT
(
be16_to_cpu
(
entry
->
nameidx
)
<
XFS_LBSIZE
(
mp
)
);
ASSERT
(
be16_to_cpu
(
entry
->
nameidx
)
<
args
->
geo
->
blksize
);
/*
* Scan through free region table:
...
...
@@ -1842,8 +1832,8 @@ xfs_attr3_leaf_remove(
smallest
=
XFS_ATTR_LEAF_MAPSIZE
-
1
;
entsize
=
xfs_attr_leaf_entsize
(
leaf
,
args
->
index
);
for
(
i
=
0
;
i
<
XFS_ATTR_LEAF_MAPSIZE
;
i
++
)
{
ASSERT
(
ichdr
.
freemap
[
i
].
base
<
XFS_LBSIZE
(
mp
)
);
ASSERT
(
ichdr
.
freemap
[
i
].
size
<
XFS_LBSIZE
(
mp
)
);
ASSERT
(
ichdr
.
freemap
[
i
].
base
<
args
->
geo
->
blksize
);
ASSERT
(
ichdr
.
freemap
[
i
].
size
<
args
->
geo
->
blksize
);
if
(
ichdr
.
freemap
[
i
].
base
==
tablesize
)
{
ichdr
.
freemap
[
i
].
base
-=
sizeof
(
xfs_attr_leaf_entry_t
);
ichdr
.
freemap
[
i
].
size
+=
sizeof
(
xfs_attr_leaf_entry_t
);
...
...
@@ -1920,11 +1910,11 @@ xfs_attr3_leaf_remove(
* removing the name.
*/
if
(
smallest
)
{
tmp
=
XFS_LBSIZE
(
mp
)
;
tmp
=
args
->
geo
->
blksize
;
entry
=
xfs_attr3_leaf_entryp
(
leaf
);
for
(
i
=
ichdr
.
count
-
1
;
i
>=
0
;
entry
++
,
i
--
)
{
ASSERT
(
be16_to_cpu
(
entry
->
nameidx
)
>=
ichdr
.
firstused
);
ASSERT
(
be16_to_cpu
(
entry
->
nameidx
)
<
XFS_LBSIZE
(
mp
)
);
ASSERT
(
be16_to_cpu
(
entry
->
nameidx
)
<
args
->
geo
->
blksize
);
if
(
be16_to_cpu
(
entry
->
nameidx
)
<
tmp
)
tmp
=
be16_to_cpu
(
entry
->
nameidx
);
...
...
@@ -1947,7 +1937,7 @@ xfs_attr3_leaf_remove(
tmp
=
ichdr
.
usedbytes
+
xfs_attr3_leaf_hdr_size
(
leaf
)
+
ichdr
.
count
*
sizeof
(
xfs_attr_leaf_entry_t
);
return
tmp
<
mp
->
m_attr_
magicpct
;
/* leaf is < 37% full */
return
tmp
<
args
->
geo
->
magicpct
;
/* leaf is < 37% full */
}
/*
...
...
@@ -1964,7 +1954,6 @@ xfs_attr3_leaf_unbalance(
struct
xfs_attr3_icleaf_hdr
drophdr
;
struct
xfs_attr3_icleaf_hdr
savehdr
;
struct
xfs_attr_leaf_entry
*
entry
;
struct
xfs_mount
*
mp
=
state
->
mp
;
trace_xfs_attr_leaf_unbalance
(
state
->
args
);
...
...
@@ -1991,13 +1980,15 @@ xfs_attr3_leaf_unbalance(
*/
if
(
xfs_attr3_leaf_order
(
save_blk
->
bp
,
&
savehdr
,
drop_blk
->
bp
,
&
drophdr
))
{
xfs_attr3_leaf_moveents
(
drop_leaf
,
&
drophdr
,
0
,
xfs_attr3_leaf_moveents
(
state
->
args
,
drop_leaf
,
&
drophdr
,
0
,
save_leaf
,
&
savehdr
,
0
,
drophdr
.
count
,
mp
);
drophdr
.
count
);
}
else
{
xfs_attr3_leaf_moveents
(
drop_leaf
,
&
drophdr
,
0
,
xfs_attr3_leaf_moveents
(
state
->
args
,
drop_leaf
,
&
drophdr
,
0
,
save_leaf
,
&
savehdr
,
savehdr
.
count
,
drophdr
.
count
,
mp
);
savehdr
.
count
,
drophdr
.
count
);
}
}
else
{
/*
...
...
@@ -2007,7 +1998,7 @@ xfs_attr3_leaf_unbalance(
struct
xfs_attr_leafblock
*
tmp_leaf
;
struct
xfs_attr3_icleaf_hdr
tmphdr
;
tmp_leaf
=
kmem_zalloc
(
state
->
bloc
ksize
,
KM_SLEEP
);
tmp_leaf
=
kmem_zalloc
(
state
->
args
->
geo
->
bl
ksize
,
KM_SLEEP
);
/*
* Copy the header into the temp leaf so that all the stuff
...
...
@@ -2020,35 +2011,39 @@ xfs_attr3_leaf_unbalance(
tmphdr
.
magic
=
savehdr
.
magic
;
tmphdr
.
forw
=
savehdr
.
forw
;
tmphdr
.
back
=
savehdr
.
back
;
tmphdr
.
firstused
=
state
->
bloc
ksize
;
tmphdr
.
firstused
=
state
->
args
->
geo
->
bl
ksize
;
/* write the header to the temp buffer to initialise it */
xfs_attr3_leaf_hdr_to_disk
(
tmp_leaf
,
&
tmphdr
);
if
(
xfs_attr3_leaf_order
(
save_blk
->
bp
,
&
savehdr
,
drop_blk
->
bp
,
&
drophdr
))
{
xfs_attr3_leaf_moveents
(
drop_leaf
,
&
drophdr
,
0
,
xfs_attr3_leaf_moveents
(
state
->
args
,
drop_leaf
,
&
drophdr
,
0
,
tmp_leaf
,
&
tmphdr
,
0
,
drophdr
.
count
,
mp
);
xfs_attr3_leaf_moveents
(
save_leaf
,
&
savehdr
,
0
,
drophdr
.
count
);
xfs_attr3_leaf_moveents
(
state
->
args
,
save_leaf
,
&
savehdr
,
0
,
tmp_leaf
,
&
tmphdr
,
tmphdr
.
count
,
savehdr
.
count
,
mp
);
savehdr
.
count
);
}
else
{
xfs_attr3_leaf_moveents
(
save_leaf
,
&
savehdr
,
0
,
xfs_attr3_leaf_moveents
(
state
->
args
,
save_leaf
,
&
savehdr
,
0
,
tmp_leaf
,
&
tmphdr
,
0
,
savehdr
.
count
,
mp
);
xfs_attr3_leaf_moveents
(
drop_leaf
,
&
drophdr
,
0
,
savehdr
.
count
);
xfs_attr3_leaf_moveents
(
state
->
args
,
drop_leaf
,
&
drophdr
,
0
,
tmp_leaf
,
&
tmphdr
,
tmphdr
.
count
,
drophdr
.
count
,
mp
);
drophdr
.
count
);
}
memcpy
(
save_leaf
,
tmp_leaf
,
state
->
bloc
ksize
);
memcpy
(
save_leaf
,
tmp_leaf
,
state
->
args
->
geo
->
bl
ksize
);
savehdr
=
tmphdr
;
/* struct copy */
kmem_free
(
tmp_leaf
);
}
xfs_attr3_leaf_hdr_to_disk
(
save_leaf
,
&
savehdr
);
xfs_trans_log_buf
(
state
->
args
->
trans
,
save_blk
->
bp
,
0
,
state
->
bloc
ksize
-
1
);
state
->
args
->
geo
->
bl
ksize
-
1
);
/*
* Copy out last hashval in each block for B-tree code.
...
...
@@ -2094,7 +2089,7 @@ xfs_attr3_leaf_lookup_int(
leaf
=
bp
->
b_addr
;
xfs_attr3_leaf_hdr_from_disk
(
&
ichdr
,
leaf
);
entries
=
xfs_attr3_leaf_entryp
(
leaf
);
ASSERT
(
ichdr
.
count
<
XFS_LBSIZE
(
args
->
dp
->
i_mount
)
/
8
);
ASSERT
(
ichdr
.
count
<
args
->
geo
->
blksize
/
8
);
/*
* Binary search. (note: small blocks will skip this loop)
...
...
@@ -2198,7 +2193,7 @@ xfs_attr3_leaf_getvalue(
leaf
=
bp
->
b_addr
;
xfs_attr3_leaf_hdr_from_disk
(
&
ichdr
,
leaf
);
ASSERT
(
ichdr
.
count
<
XFS_LBSIZE
(
args
->
dp
->
i_mount
)
/
8
);
ASSERT
(
ichdr
.
count
<
args
->
geo
->
blksize
/
8
);
ASSERT
(
args
->
index
<
ichdr
.
count
);
entry
=
&
xfs_attr3_leaf_entryp
(
leaf
)[
args
->
index
];
...
...
@@ -2249,14 +2244,14 @@ xfs_attr3_leaf_getvalue(
/*ARGSUSED*/
STATIC
void
xfs_attr3_leaf_moveents
(
struct
xfs_da_args
*
args
,
struct
xfs_attr_leafblock
*
leaf_s
,
struct
xfs_attr3_icleaf_hdr
*
ichdr_s
,
int
start_s
,
struct
xfs_attr_leafblock
*
leaf_d
,
struct
xfs_attr3_icleaf_hdr
*
ichdr_d
,
int
start_d
,
int
count
,
struct
xfs_mount
*
mp
)
int
count
)
{
struct
xfs_attr_leaf_entry
*
entry_s
;
struct
xfs_attr_leaf_entry
*
entry_d
;
...
...
@@ -2276,10 +2271,10 @@ xfs_attr3_leaf_moveents(
ASSERT
(
ichdr_s
->
magic
==
XFS_ATTR_LEAF_MAGIC
||
ichdr_s
->
magic
==
XFS_ATTR3_LEAF_MAGIC
);
ASSERT
(
ichdr_s
->
magic
==
ichdr_d
->
magic
);
ASSERT
(
ichdr_s
->
count
>
0
&&
ichdr_s
->
count
<
XFS_LBSIZE
(
mp
)
/
8
);
ASSERT
(
ichdr_s
->
count
>
0
&&
ichdr_s
->
count
<
args
->
geo
->
blksize
/
8
);
ASSERT
(
ichdr_s
->
firstused
>=
(
ichdr_s
->
count
*
sizeof
(
*
entry_s
))
+
xfs_attr3_leaf_hdr_size
(
leaf_s
));
ASSERT
(
ichdr_d
->
count
<
XFS_LBSIZE
(
mp
)
/
8
);
ASSERT
(
ichdr_d
->
count
<
args
->
geo
->
blksize
/
8
);
ASSERT
(
ichdr_d
->
firstused
>=
(
ichdr_d
->
count
*
sizeof
(
*
entry_d
))
+
xfs_attr3_leaf_hdr_size
(
leaf_d
));
...
...
@@ -2331,11 +2326,11 @@ xfs_attr3_leaf_moveents(
entry_d
->
nameidx
=
cpu_to_be16
(
ichdr_d
->
firstused
);
entry_d
->
flags
=
entry_s
->
flags
;
ASSERT
(
be16_to_cpu
(
entry_d
->
nameidx
)
+
tmp
<=
XFS_LBSIZE
(
mp
)
);
<=
args
->
geo
->
blksize
);
memmove
(
xfs_attr3_leaf_name
(
leaf_d
,
desti
),
xfs_attr3_leaf_name
(
leaf_s
,
start_s
+
i
),
tmp
);
ASSERT
(
be16_to_cpu
(
entry_s
->
nameidx
)
+
tmp
<=
XFS_LBSIZE
(
mp
)
);
<=
args
->
geo
->
blksize
);
memset
(
xfs_attr3_leaf_name
(
leaf_s
,
start_s
+
i
),
0
,
tmp
);
ichdr_s
->
usedbytes
-=
tmp
;
ichdr_d
->
usedbytes
+=
tmp
;
...
...
@@ -2356,7 +2351,7 @@ xfs_attr3_leaf_moveents(
tmp
=
count
*
sizeof
(
xfs_attr_leaf_entry_t
);
entry_s
=
&
xfs_attr3_leaf_entryp
(
leaf_s
)[
start_s
];
ASSERT
(((
char
*
)
entry_s
+
tmp
)
<=
((
char
*
)
leaf_s
+
XFS_LBSIZE
(
mp
)
));
((
char
*
)
leaf_s
+
args
->
geo
->
blksize
));
memset
(
entry_s
,
0
,
tmp
);
}
else
{
/*
...
...
@@ -2371,7 +2366,7 @@ xfs_attr3_leaf_moveents(
tmp
=
count
*
sizeof
(
xfs_attr_leaf_entry_t
);
entry_s
=
&
xfs_attr3_leaf_entryp
(
leaf_s
)[
ichdr_s
->
count
];
ASSERT
(((
char
*
)
entry_s
+
tmp
)
<=
((
char
*
)
leaf_s
+
XFS_LBSIZE
(
mp
)
));
((
char
*
)
leaf_s
+
args
->
geo
->
blksize
));
memset
(
entry_s
,
0
,
tmp
);
}
...
...
@@ -2439,22 +2434,21 @@ xfs_attr_leaf_entsize(xfs_attr_leafblock_t *leaf, int index)
* a "local" or a "remote" attribute.
*/
int
xfs_attr_leaf_newentsize
(
int
namelen
,
int
valuelen
,
int
blocksize
,
int
*
local
)
xfs_attr_leaf_newentsize
(
struct
xfs_da_args
*
args
,
int
*
local
)
{
int
size
;
int
size
;
size
=
xfs_attr_leaf_entsize_local
(
namelen
,
valuelen
);
if
(
size
<
xfs_attr_leaf_entsize_local_max
(
bloc
ksize
))
{
if
(
local
)
{
size
=
xfs_attr_leaf_entsize_local
(
args
->
namelen
,
args
->
valuelen
);
if
(
size
<
xfs_attr_leaf_entsize_local_max
(
args
->
geo
->
bl
ksize
))
{
if
(
local
)
*
local
=
1
;
}
}
else
{
size
=
xfs_attr_leaf_entsize_remote
(
namelen
);
if
(
local
)
{
*
local
=
0
;
}
return
size
;
}
return
size
;
if
(
local
)
*
local
=
0
;
return
xfs_attr_leaf_entsize_remote
(
args
->
namelen
);
}
...
...
fs/xfs/xfs_attr_leaf.h
浏览文件 @
8612c7e5
...
...
@@ -96,8 +96,7 @@ int xfs_attr3_root_inactive(struct xfs_trans **trans, struct xfs_inode *dp);
xfs_dahash_t
xfs_attr_leaf_lasthash
(
struct
xfs_buf
*
bp
,
int
*
count
);
int
xfs_attr_leaf_order
(
struct
xfs_buf
*
leaf1_bp
,
struct
xfs_buf
*
leaf2_bp
);
int
xfs_attr_leaf_newentsize
(
int
namelen
,
int
valuelen
,
int
blocksize
,
int
*
local
);
int
xfs_attr_leaf_newentsize
(
struct
xfs_da_args
*
args
,
int
*
local
);
int
xfs_attr3_leaf_read
(
struct
xfs_trans
*
tp
,
struct
xfs_inode
*
dp
,
xfs_dablk_t
bno
,
xfs_daddr_t
mappedbno
,
struct
xfs_buf
**
bpp
);
...
...
fs/xfs/xfs_attr_list.c
浏览文件 @
8612c7e5
...
...
@@ -444,6 +444,7 @@ xfs_attr3_leaf_list_int(
xfs_da_args_t
args
;
memset
((
char
*
)
&
args
,
0
,
sizeof
(
args
));
args
.
geo
=
context
->
dp
->
i_mount
->
m_attr_geo
;
args
.
dp
=
context
->
dp
;
args
.
whichfork
=
XFS_ATTR_FORK
;
args
.
valuelen
=
valuelen
;
...
...
fs/xfs/xfs_attr_remote.c
浏览文件 @
8612c7e5
...
...
@@ -125,6 +125,7 @@ xfs_attr3_rmt_read_verify(
char
*
ptr
;
int
len
;
xfs_daddr_t
bno
;
int
blksize
=
mp
->
m_attr_geo
->
blksize
;
/* no verification of non-crc buffers */
if
(
!
xfs_sb_version_hascrc
(
&
mp
->
m_sb
))
...
...
@@ -133,21 +134,20 @@ xfs_attr3_rmt_read_verify(
ptr
=
bp
->
b_addr
;
bno
=
bp
->
b_bn
;
len
=
BBTOB
(
bp
->
b_length
);
ASSERT
(
len
>=
XFS_LBSIZE
(
mp
)
);
ASSERT
(
len
>=
blksize
);
while
(
len
>
0
)
{
if
(
!
xfs_verify_cksum
(
ptr
,
XFS_LBSIZE
(
mp
),
XFS_ATTR3_RMT_CRC_OFF
))
{
if
(
!
xfs_verify_cksum
(
ptr
,
blksize
,
XFS_ATTR3_RMT_CRC_OFF
))
{
xfs_buf_ioerror
(
bp
,
EFSBADCRC
);
break
;
}
if
(
!
xfs_attr3_rmt_verify
(
mp
,
ptr
,
XFS_LBSIZE
(
mp
)
,
bno
))
{
if
(
!
xfs_attr3_rmt_verify
(
mp
,
ptr
,
blksize
,
bno
))
{
xfs_buf_ioerror
(
bp
,
EFSCORRUPTED
);
break
;
}
len
-=
XFS_LBSIZE
(
mp
)
;
ptr
+=
XFS_LBSIZE
(
mp
)
;
bno
+=
mp
->
m_bsize
;
len
-=
blksize
;
ptr
+=
blksize
;
bno
+=
BTOBB
(
blksize
)
;
}
if
(
bp
->
b_error
)
...
...
@@ -165,6 +165,7 @@ xfs_attr3_rmt_write_verify(
char
*
ptr
;
int
len
;
xfs_daddr_t
bno
;
int
blksize
=
mp
->
m_attr_geo
->
blksize
;
/* no verification of non-crc buffers */
if
(
!
xfs_sb_version_hascrc
(
&
mp
->
m_sb
))
...
...
@@ -173,10 +174,10 @@ xfs_attr3_rmt_write_verify(
ptr
=
bp
->
b_addr
;
bno
=
bp
->
b_bn
;
len
=
BBTOB
(
bp
->
b_length
);
ASSERT
(
len
>=
XFS_LBSIZE
(
mp
)
);
ASSERT
(
len
>=
blksize
);
while
(
len
>
0
)
{
if
(
!
xfs_attr3_rmt_verify
(
mp
,
ptr
,
XFS_LBSIZE
(
mp
)
,
bno
))
{
if
(
!
xfs_attr3_rmt_verify
(
mp
,
ptr
,
blksize
,
bno
))
{
xfs_buf_ioerror
(
bp
,
EFSCORRUPTED
);
xfs_verifier_error
(
bp
);
return
;
...
...
@@ -187,11 +188,11 @@ xfs_attr3_rmt_write_verify(
rmt
=
(
struct
xfs_attr3_rmt_hdr
*
)
ptr
;
rmt
->
rm_lsn
=
cpu_to_be64
(
bip
->
bli_item
.
li_lsn
);
}
xfs_update_cksum
(
ptr
,
XFS_LBSIZE
(
mp
)
,
XFS_ATTR3_RMT_CRC_OFF
);
xfs_update_cksum
(
ptr
,
blksize
,
XFS_ATTR3_RMT_CRC_OFF
);
len
-=
XFS_LBSIZE
(
mp
)
;
ptr
+=
XFS_LBSIZE
(
mp
)
;
bno
+=
mp
->
m_bsize
;
len
-=
blksize
;
ptr
+=
blksize
;
bno
+=
BTOBB
(
blksize
)
;
}
ASSERT
(
len
==
0
);
}
...
...
@@ -240,12 +241,13 @@ xfs_attr_rmtval_copyout(
char
*
src
=
bp
->
b_addr
;
xfs_daddr_t
bno
=
bp
->
b_bn
;
int
len
=
BBTOB
(
bp
->
b_length
);
int
blksize
=
mp
->
m_attr_geo
->
blksize
;
ASSERT
(
len
>=
XFS_LBSIZE
(
mp
)
);
ASSERT
(
len
>=
blksize
);
while
(
len
>
0
&&
*
valuelen
>
0
)
{
int
hdr_size
=
0
;
int
byte_cnt
=
XFS_ATTR3_RMT_BUF_SPACE
(
mp
,
XFS_LBSIZE
(
mp
)
);
int
byte_cnt
=
XFS_ATTR3_RMT_BUF_SPACE
(
mp
,
blksize
);
byte_cnt
=
min
(
*
valuelen
,
byte_cnt
);
...
...
@@ -263,9 +265,9 @@ xfs_attr_rmtval_copyout(
memcpy
(
*
dst
,
src
+
hdr_size
,
byte_cnt
);
/* roll buffer forwards */
len
-=
XFS_LBSIZE
(
mp
)
;
src
+=
XFS_LBSIZE
(
mp
)
;
bno
+=
mp
->
m_bsize
;
len
-=
blksize
;
src
+=
blksize
;
bno
+=
BTOBB
(
blksize
)
;
/* roll attribute data forwards */
*
valuelen
-=
byte_cnt
;
...
...
@@ -287,12 +289,13 @@ xfs_attr_rmtval_copyin(
char
*
dst
=
bp
->
b_addr
;
xfs_daddr_t
bno
=
bp
->
b_bn
;
int
len
=
BBTOB
(
bp
->
b_length
);
int
blksize
=
mp
->
m_attr_geo
->
blksize
;
ASSERT
(
len
>=
XFS_LBSIZE
(
mp
)
);
ASSERT
(
len
>=
blksize
);
while
(
len
>
0
&&
*
valuelen
>
0
)
{
int
hdr_size
;
int
byte_cnt
=
XFS_ATTR3_RMT_BUF_SPACE
(
mp
,
XFS_LBSIZE
(
mp
)
);
int
byte_cnt
=
XFS_ATTR3_RMT_BUF_SPACE
(
mp
,
blksize
);
byte_cnt
=
min
(
*
valuelen
,
byte_cnt
);
hdr_size
=
xfs_attr3_rmt_hdr_set
(
mp
,
dst
,
ino
,
*
offset
,
...
...
@@ -304,17 +307,17 @@ xfs_attr_rmtval_copyin(
* If this is the last block, zero the remainder of it.
* Check that we are actually the last block, too.
*/
if
(
byte_cnt
+
hdr_size
<
XFS_LBSIZE
(
mp
)
)
{
if
(
byte_cnt
+
hdr_size
<
blksize
)
{
ASSERT
(
*
valuelen
-
byte_cnt
==
0
);
ASSERT
(
len
==
XFS_LBSIZE
(
mp
)
);
ASSERT
(
len
==
blksize
);
memset
(
dst
+
hdr_size
+
byte_cnt
,
0
,
XFS_LBSIZE
(
mp
)
-
hdr_size
-
byte_cnt
);
blksize
-
hdr_size
-
byte_cnt
);
}
/* roll buffer forwards */
len
-=
XFS_LBSIZE
(
mp
)
;
dst
+=
XFS_LBSIZE
(
mp
)
;
bno
+=
mp
->
m_bsize
;
len
-=
blksize
;
dst
+=
blksize
;
bno
+=
BTOBB
(
blksize
)
;
/* roll attribute data forwards */
*
valuelen
-=
byte_cnt
;
...
...
fs/xfs/xfs_bmap.c
浏览文件 @
8612c7e5
...
...
@@ -1098,10 +1098,11 @@ xfs_bmap_add_attrfork_local(
if
(
S_ISDIR
(
ip
->
i_d
.
di_mode
))
{
memset
(
&
dargs
,
0
,
sizeof
(
dargs
));
dargs
.
geo
=
ip
->
i_mount
->
m_dir_geo
;
dargs
.
dp
=
ip
;
dargs
.
firstblock
=
firstblock
;
dargs
.
flist
=
flist
;
dargs
.
total
=
ip
->
i_mount
->
m_dirblkfsbs
;
dargs
.
total
=
dargs
.
geo
->
fsbcount
;
dargs
.
whichfork
=
XFS_DATA_FORK
;
dargs
.
trans
=
tp
;
return
xfs_dir2_sf_to_block
(
&
dargs
);
...
...
fs/xfs/xfs_da_btree.c
浏览文件 @
8612c7e5
...
...
@@ -167,8 +167,8 @@ xfs_da3_node_verify(
* we don't know if the node is for and attribute or directory tree,
* so only fail if the count is outside both bounds
*/
if
(
ichdr
.
count
>
mp
->
m_dir_node_ents
&&
ichdr
.
count
>
mp
->
m_attr_node_ents
)
if
(
ichdr
.
count
>
mp
->
m_dir_
geo
->
node_ents
&&
ichdr
.
count
>
mp
->
m_attr_
geo
->
node_ents
)
return
false
;
/* XXX: hash order check? */
...
...
@@ -598,7 +598,7 @@ xfs_da3_root_split(
* Set up the new root node.
*/
error
=
xfs_da3_node_create
(
args
,
(
args
->
whichfork
==
XFS_DATA_FORK
)
?
mp
->
m_dir
leafblk
:
0
,
(
args
->
whichfork
==
XFS_DATA_FORK
)
?
args
->
geo
->
leafblk
:
0
,
level
+
1
,
&
bp
,
args
->
whichfork
);
if
(
error
)
return
error
;
...
...
@@ -616,10 +616,10 @@ xfs_da3_root_split(
#ifdef DEBUG
if
(
oldroot
->
hdr
.
info
.
magic
==
cpu_to_be16
(
XFS_DIR2_LEAFN_MAGIC
)
||
oldroot
->
hdr
.
info
.
magic
==
cpu_to_be16
(
XFS_DIR3_LEAFN_MAGIC
))
{
ASSERT
(
blk1
->
blkno
>=
mp
->
m_dir
leafblk
&&
blk1
->
blkno
<
mp
->
m_dir
freeblk
);
ASSERT
(
blk2
->
blkno
>=
mp
->
m_dir
leafblk
&&
blk2
->
blkno
<
mp
->
m_dir
freeblk
);
ASSERT
(
blk1
->
blkno
>=
args
->
geo
->
leafblk
&&
blk1
->
blkno
<
args
->
geo
->
freeblk
);
ASSERT
(
blk2
->
blkno
>=
args
->
geo
->
leafblk
&&
blk2
->
blkno
<
args
->
geo
->
freeblk
);
}
#endif
...
...
@@ -663,7 +663,7 @@ xfs_da3_node_split(
/*
* Do we have to split the node?
*/
if
(
nodehdr
.
count
+
newcount
>
state
->
node_ents
)
{
if
(
nodehdr
.
count
+
newcount
>
state
->
args
->
geo
->
node_ents
)
{
/*
* Allocate a new node, add to the doubly linked chain of
* nodes, then move some of our excess entries into it.
...
...
@@ -894,8 +894,8 @@ xfs_da3_node_add(
ASSERT
(
oldblk
->
index
>=
0
&&
oldblk
->
index
<=
nodehdr
.
count
);
ASSERT
(
newblk
->
blkno
!=
0
);
if
(
state
->
args
->
whichfork
==
XFS_DATA_FORK
)
ASSERT
(
newblk
->
blkno
>=
state
->
mp
->
m_dir
leafblk
&&
newblk
->
blkno
<
state
->
mp
->
m_dir
freeblk
);
ASSERT
(
newblk
->
blkno
>=
state
->
args
->
geo
->
leafblk
&&
newblk
->
blkno
<
state
->
args
->
geo
->
freeblk
);
/*
* We may need to make some room before we insert the new node.
...
...
@@ -1089,14 +1089,15 @@ xfs_da3_root_join(
* that could occur. For dir3 blocks we also need to update the block
* number in the buffer header.
*/
memcpy
(
root_blk
->
bp
->
b_addr
,
bp
->
b_addr
,
state
->
bloc
ksize
);
memcpy
(
root_blk
->
bp
->
b_addr
,
bp
->
b_addr
,
args
->
geo
->
bl
ksize
);
root_blk
->
bp
->
b_ops
=
bp
->
b_ops
;
xfs_trans_buf_copy_type
(
root_blk
->
bp
,
bp
);
if
(
oldroothdr
.
magic
==
XFS_DA3_NODE_MAGIC
)
{
struct
xfs_da3_blkinfo
*
da3
=
root_blk
->
bp
->
b_addr
;
da3
->
blkno
=
cpu_to_be64
(
root_blk
->
bp
->
b_bn
);
}
xfs_trans_log_buf
(
args
->
trans
,
root_blk
->
bp
,
0
,
state
->
blocksize
-
1
);
xfs_trans_log_buf
(
args
->
trans
,
root_blk
->
bp
,
0
,
args
->
geo
->
blksize
-
1
);
error
=
xfs_da_shrink_inode
(
args
,
child
,
bp
);
return
(
error
);
}
...
...
@@ -1139,7 +1140,7 @@ xfs_da3_node_toosmall(
info
=
blk
->
bp
->
b_addr
;
node
=
(
xfs_da_intnode_t
*
)
info
;
dp
->
d_ops
->
node_hdr_from_disk
(
&
nodehdr
,
node
);
if
(
nodehdr
.
count
>
(
state
->
node_ents
>>
1
))
{
if
(
nodehdr
.
count
>
(
state
->
args
->
geo
->
node_ents
>>
1
))
{
*
action
=
0
;
/* blk over 50%, don't try to join */
return
(
0
);
/* blk over 50%, don't try to join */
}
...
...
@@ -1176,8 +1177,8 @@ xfs_da3_node_toosmall(
* We prefer coalescing with the lower numbered sibling so as
* to shrink a directory over time.
*/
count
=
state
->
node_ents
;
count
-=
state
->
node_ents
>>
2
;
count
=
state
->
args
->
geo
->
node_ents
;
count
-=
state
->
args
->
geo
->
node_ents
>>
2
;
count
-=
nodehdr
.
count
;
/* start with smaller blk num */
...
...
@@ -1472,7 +1473,7 @@ xfs_da3_node_lookup_int(
* Descend thru the B-tree searching each level for the right
* node to use, until the right hashval is found.
*/
blkno
=
(
args
->
whichfork
==
XFS_DATA_FORK
)
?
state
->
mp
->
m_dir
leafblk
:
0
;
blkno
=
(
args
->
whichfork
==
XFS_DATA_FORK
)
?
args
->
geo
->
leafblk
:
0
;
for
(
blk
=
&
state
->
path
.
blk
[
0
],
state
->
path
.
active
=
1
;
state
->
path
.
active
<=
XFS_DA_NODE_MAXDEPTH
;
blk
++
,
state
->
path
.
active
++
)
{
...
...
@@ -2090,20 +2091,12 @@ xfs_da_grow_inode(
xfs_dablk_t
*
new_blkno
)
{
xfs_fileoff_t
bno
;
int
count
;
int
error
;
trace_xfs_da_grow_inode
(
args
);
if
(
args
->
whichfork
==
XFS_DATA_FORK
)
{
bno
=
args
->
dp
->
i_mount
->
m_dirleafblk
;
count
=
args
->
dp
->
i_mount
->
m_dirblkfsbs
;
}
else
{
bno
=
0
;
count
=
1
;
}
error
=
xfs_da_grow_inode_int
(
args
,
&
bno
,
count
);
bno
=
args
->
geo
->
leafblk
;
error
=
xfs_da_grow_inode_int
(
args
,
&
bno
,
args
->
geo
->
fsbcount
);
if
(
!
error
)
*
new_blkno
=
(
xfs_dablk_t
)
bno
;
return
error
;
...
...
@@ -2158,7 +2151,7 @@ xfs_da3_swap_lastblock(
w
=
args
->
whichfork
;
ASSERT
(
w
==
XFS_DATA_FORK
);
mp
=
dp
->
i_mount
;
lastoff
=
mp
->
m_dir
freeblk
;
lastoff
=
args
->
geo
->
freeblk
;
error
=
xfs_bmap_last_before
(
tp
,
dp
,
&
lastoff
,
w
);
if
(
error
)
return
error
;
...
...
@@ -2170,15 +2163,15 @@ xfs_da3_swap_lastblock(
/*
* Read the last block in the btree space.
*/
last_blkno
=
(
xfs_dablk_t
)
lastoff
-
mp
->
m_dirblkfsbs
;
last_blkno
=
(
xfs_dablk_t
)
lastoff
-
args
->
geo
->
fsbcount
;
error
=
xfs_da3_node_read
(
tp
,
dp
,
last_blkno
,
-
1
,
&
last_buf
,
w
);
if
(
error
)
return
error
;
/*
* Copy the last block into the dead buffer and log it.
*/
memcpy
(
dead_buf
->
b_addr
,
last_buf
->
b_addr
,
mp
->
m_dir
blksize
);
xfs_trans_log_buf
(
tp
,
dead_buf
,
0
,
mp
->
m_dir
blksize
-
1
);
memcpy
(
dead_buf
->
b_addr
,
last_buf
->
b_addr
,
args
->
geo
->
blksize
);
xfs_trans_log_buf
(
tp
,
dead_buf
,
0
,
args
->
geo
->
blksize
-
1
);
dead_info
=
dead_buf
->
b_addr
;
/*
* Get values from the moved block.
...
...
@@ -2247,7 +2240,7 @@ xfs_da3_swap_lastblock(
sizeof
(
sib_info
->
back
)));
sib_buf
=
NULL
;
}
par_blkno
=
mp
->
m_dir
leafblk
;
par_blkno
=
args
->
geo
->
leafblk
;
level
=
-
1
;
/*
* Walk down the tree looking for the parent of the moved block.
...
...
@@ -2357,10 +2350,7 @@ xfs_da_shrink_inode(
w
=
args
->
whichfork
;
tp
=
args
->
trans
;
mp
=
dp
->
i_mount
;
if
(
w
==
XFS_DATA_FORK
)
count
=
mp
->
m_dirblkfsbs
;
else
count
=
1
;
count
=
args
->
geo
->
fsbcount
;
for
(;;)
{
/*
* Remove extents. If we get ENOSPC for a dir we have to move
...
...
@@ -2479,7 +2469,10 @@ xfs_dabuf_map(
ASSERT
(
map
&&
*
map
);
ASSERT
(
*
nmaps
==
1
);
nfsb
=
(
whichfork
==
XFS_DATA_FORK
)
?
mp
->
m_dirblkfsbs
:
1
;
if
(
whichfork
==
XFS_DATA_FORK
)
nfsb
=
mp
->
m_dir_geo
->
fsbcount
;
else
nfsb
=
mp
->
m_attr_geo
->
fsbcount
;
/*
* Caller doesn't have a mapping. -2 means don't complain
...
...
fs/xfs/xfs_da_btree.h
浏览文件 @
8612c7e5
...
...
@@ -25,6 +25,23 @@ struct xfs_trans;
struct
zone
;
struct
xfs_dir_ops
;
/*
* Directory/attribute geometry information. There will be one of these for each
* data fork type, and it will be passed around via the xfs_da_args. Global
* structures will be attached to the xfs_mount.
*/
struct
xfs_da_geometry
{
int
blksize
;
/* da block size in bytes */
int
fsbcount
;
/* da block size in filesystem blocks */
uint8_t
fsblog
;
/* log2 of _filesystem_ block size */
uint8_t
blklog
;
/* log2 of da block size */
uint
node_ents
;
/* # of entries in a danode */
int
magicpct
;
/* 37% of block size in bytes */
xfs_dablk_t
datablk
;
/* blockno of dir data v2 */
xfs_dablk_t
leafblk
;
/* blockno of leaf data v2 */
xfs_dablk_t
freeblk
;
/* blockno of free data v2 */
};
/*========================================================================
* Btree searching and modification structure definitions.
*========================================================================*/
...
...
@@ -42,6 +59,7 @@ enum xfs_dacmp {
* Structure to ease passing around component names.
*/
typedef
struct
xfs_da_args
{
struct
xfs_da_geometry
*
geo
;
/* da block geometry */
const
__uint8_t
*
name
;
/* string (maybe not NULL terminated) */
int
namelen
;
/* length of string (maybe no NULL) */
__uint8_t
filetype
;
/* filetype of inode for directories */
...
...
@@ -110,8 +128,6 @@ typedef struct xfs_da_state_path {
typedef
struct
xfs_da_state
{
xfs_da_args_t
*
args
;
/* filename arguments */
struct
xfs_mount
*
mp
;
/* filesystem mount point */
unsigned
int
blocksize
;
/* logical block size */
unsigned
int
node_ents
;
/* how many entries in danode */
xfs_da_state_path_t
path
;
/* search/split paths */
xfs_da_state_path_t
altpath
;
/* alternate path for join */
unsigned
char
inleaf
;
/* insert into 1->lf, 0->splf */
...
...
fs/xfs/xfs_da_format.c
浏览文件 @
8612c7e5
...
...
@@ -26,8 +26,10 @@
#include "xfs_ag.h"
#include "xfs_mount.h"
#include "xfs_da_format.h"
#include "xfs_da_btree.h"
#include "xfs_inode.h"
#include "xfs_dir2.h"
#include "xfs_dir2_priv.h"
/*
* Shortform directory ops
...
...
@@ -425,9 +427,9 @@ xfs_dir3_data_unused_p(struct xfs_dir2_data_hdr *hdr)
* Directory Leaf block operations
*/
static
int
xfs_dir2_max_leaf_ents
(
struct
xfs_
mount
*
mp
)
xfs_dir2_max_leaf_ents
(
struct
xfs_
da_geometry
*
geo
)
{
return
(
mp
->
m_dir
blksize
-
sizeof
(
struct
xfs_dir2_leaf_hdr
))
/
return
(
geo
->
blksize
-
sizeof
(
struct
xfs_dir2_leaf_hdr
))
/
(
uint
)
sizeof
(
struct
xfs_dir2_leaf_entry
);
}
...
...
@@ -438,9 +440,9 @@ xfs_dir2_leaf_ents_p(struct xfs_dir2_leaf *lp)
}
static
int
xfs_dir3_max_leaf_ents
(
struct
xfs_
mount
*
mp
)
xfs_dir3_max_leaf_ents
(
struct
xfs_
da_geometry
*
geo
)
{
return
(
mp
->
m_dir
blksize
-
sizeof
(
struct
xfs_dir3_leaf_hdr
))
/
return
(
geo
->
blksize
-
sizeof
(
struct
xfs_dir3_leaf_hdr
))
/
(
uint
)
sizeof
(
struct
xfs_dir2_leaf_entry
);
}
...
...
@@ -591,9 +593,9 @@ xfs_da3_node_hdr_to_disk(
* Directory free space block operations
*/
static
int
xfs_dir2_free_max_bests
(
struct
xfs_
mount
*
mp
)
xfs_dir2_free_max_bests
(
struct
xfs_
da_geometry
*
geo
)
{
return
(
mp
->
m_dir
blksize
-
sizeof
(
struct
xfs_dir2_free_hdr
))
/
return
(
geo
->
blksize
-
sizeof
(
struct
xfs_dir2_free_hdr
))
/
sizeof
(
xfs_dir2_data_off_t
);
}
...
...
@@ -607,24 +609,25 @@ xfs_dir2_free_bests_p(struct xfs_dir2_free *free)
* Convert data space db to the corresponding free db.
*/
static
xfs_dir2_db_t
xfs_dir2_db_to_fdb
(
struct
xfs_
mount
*
mp
,
xfs_dir2_db_t
db
)
xfs_dir2_db_to_fdb
(
struct
xfs_
da_geometry
*
geo
,
xfs_dir2_db_t
db
)
{
return
XFS_DIR2_FREE_FIRSTDB
(
mp
)
+
db
/
xfs_dir2_free_max_bests
(
mp
);
return
xfs_dir2_byte_to_db
(
geo
,
XFS_DIR2_FREE_OFFSET
)
+
(
db
/
xfs_dir2_free_max_bests
(
geo
));
}
/*
* Convert data space db to the corresponding index in a free db.
*/
static
int
xfs_dir2_db_to_fdindex
(
struct
xfs_
mount
*
mp
,
xfs_dir2_db_t
db
)
xfs_dir2_db_to_fdindex
(
struct
xfs_
da_geometry
*
geo
,
xfs_dir2_db_t
db
)
{
return
db
%
xfs_dir2_free_max_bests
(
mp
);
return
db
%
xfs_dir2_free_max_bests
(
geo
);
}
static
int
xfs_dir3_free_max_bests
(
struct
xfs_
mount
*
mp
)
xfs_dir3_free_max_bests
(
struct
xfs_
da_geometry
*
geo
)
{
return
(
mp
->
m_dir
blksize
-
sizeof
(
struct
xfs_dir3_free_hdr
))
/
return
(
geo
->
blksize
-
sizeof
(
struct
xfs_dir3_free_hdr
))
/
sizeof
(
xfs_dir2_data_off_t
);
}
...
...
@@ -638,18 +641,19 @@ xfs_dir3_free_bests_p(struct xfs_dir2_free *free)
* Convert data space db to the corresponding free db.
*/
static
xfs_dir2_db_t
xfs_dir3_db_to_fdb
(
struct
xfs_
mount
*
mp
,
xfs_dir2_db_t
db
)
xfs_dir3_db_to_fdb
(
struct
xfs_
da_geometry
*
geo
,
xfs_dir2_db_t
db
)
{
return
XFS_DIR2_FREE_FIRSTDB
(
mp
)
+
db
/
xfs_dir3_free_max_bests
(
mp
);
return
xfs_dir2_byte_to_db
(
geo
,
XFS_DIR2_FREE_OFFSET
)
+
(
db
/
xfs_dir3_free_max_bests
(
geo
));
}
/*
* Convert data space db to the corresponding index in a free db.
*/
static
int
xfs_dir3_db_to_fdindex
(
struct
xfs_
mount
*
mp
,
xfs_dir2_db_t
db
)
xfs_dir3_db_to_fdindex
(
struct
xfs_
da_geometry
*
geo
,
xfs_dir2_db_t
db
)
{
return
db
%
xfs_dir3_free_max_bests
(
mp
);
return
db
%
xfs_dir3_free_max_bests
(
geo
);
}
static
void
...
...
fs/xfs/xfs_da_format.h
浏览文件 @
8612c7e5
...
...
@@ -19,10 +19,6 @@
#ifndef __XFS_DA_FORMAT_H__
#define __XFS_DA_FORMAT_H__
/*========================================================================
* Directory Structure when greater than XFS_LBSIZE(mp) bytes.
*========================================================================*/
/*
* This structure is common to both leaf nodes and non-leaf nodes in the Btree.
*
...
...
@@ -122,8 +118,6 @@ struct xfs_da3_icnode_hdr {
__uint16_t
level
;
};
#define XFS_LBSIZE(mp) (mp)->m_sb.sb_blocksize
/*
* Directory version 2.
*
...
...
@@ -330,8 +324,6 @@ xfs_dir2_sf_firstentry(struct xfs_dir2_sf_hdr *hdr)
#define XFS_DIR2_SPACE_SIZE (1ULL << (32 + XFS_DIR2_DATA_ALIGN_LOG))
#define XFS_DIR2_DATA_SPACE 0
#define XFS_DIR2_DATA_OFFSET (XFS_DIR2_DATA_SPACE * XFS_DIR2_SPACE_SIZE)
#define XFS_DIR2_DATA_FIRSTDB(mp) \
xfs_dir2_byte_to_db(mp, XFS_DIR2_DATA_OFFSET)
/*
* Describe a free area in the data block.
...
...
@@ -456,8 +448,6 @@ xfs_dir2_data_unused_tag_p(struct xfs_dir2_data_unused *dup)
*/
#define XFS_DIR2_LEAF_SPACE 1
#define XFS_DIR2_LEAF_OFFSET (XFS_DIR2_LEAF_SPACE * XFS_DIR2_SPACE_SIZE)
#define XFS_DIR2_LEAF_FIRSTDB(mp) \
xfs_dir2_byte_to_db(mp, XFS_DIR2_LEAF_OFFSET)
/*
* Leaf block header.
...
...
@@ -513,17 +503,6 @@ struct xfs_dir3_leaf {
#define XFS_DIR3_LEAF_CRC_OFF offsetof(struct xfs_dir3_leaf_hdr, info.crc)
/*
* Get address of the bestcount field in the single-leaf block.
*/
static
inline
struct
xfs_dir2_leaf_tail
*
xfs_dir2_leaf_tail_p
(
struct
xfs_mount
*
mp
,
struct
xfs_dir2_leaf
*
lp
)
{
return
(
struct
xfs_dir2_leaf_tail
*
)
((
char
*
)
lp
+
mp
->
m_dirblksize
-
sizeof
(
struct
xfs_dir2_leaf_tail
));
}
/*
* Get address of the bests array in the single-leaf block.
*/
...
...
@@ -533,123 +512,6 @@ xfs_dir2_leaf_bests_p(struct xfs_dir2_leaf_tail *ltp)
return
(
__be16
*
)
ltp
-
be32_to_cpu
(
ltp
->
bestcount
);
}
/*
* DB blocks here are logical directory block numbers, not filesystem blocks.
*/
/*
* Convert dataptr to byte in file space
*/
static
inline
xfs_dir2_off_t
xfs_dir2_dataptr_to_byte
(
xfs_dir2_dataptr_t
dp
)
{
return
(
xfs_dir2_off_t
)
dp
<<
XFS_DIR2_DATA_ALIGN_LOG
;
}
/*
* Convert byte in file space to dataptr. It had better be aligned.
*/
static
inline
xfs_dir2_dataptr_t
xfs_dir2_byte_to_dataptr
(
xfs_dir2_off_t
by
)
{
return
(
xfs_dir2_dataptr_t
)(
by
>>
XFS_DIR2_DATA_ALIGN_LOG
);
}
/*
* Convert byte in space to (DB) block
*/
static
inline
xfs_dir2_db_t
xfs_dir2_byte_to_db
(
struct
xfs_mount
*
mp
,
xfs_dir2_off_t
by
)
{
return
(
xfs_dir2_db_t
)
(
by
>>
(
mp
->
m_sb
.
sb_blocklog
+
mp
->
m_sb
.
sb_dirblklog
));
}
/*
* Convert dataptr to a block number
*/
static
inline
xfs_dir2_db_t
xfs_dir2_dataptr_to_db
(
struct
xfs_mount
*
mp
,
xfs_dir2_dataptr_t
dp
)
{
return
xfs_dir2_byte_to_db
(
mp
,
xfs_dir2_dataptr_to_byte
(
dp
));
}
/*
* Convert byte in space to offset in a block
*/
static
inline
xfs_dir2_data_aoff_t
xfs_dir2_byte_to_off
(
struct
xfs_mount
*
mp
,
xfs_dir2_off_t
by
)
{
return
(
xfs_dir2_data_aoff_t
)(
by
&
((
1
<<
(
mp
->
m_sb
.
sb_blocklog
+
mp
->
m_sb
.
sb_dirblklog
))
-
1
));
}
/*
* Convert dataptr to a byte offset in a block
*/
static
inline
xfs_dir2_data_aoff_t
xfs_dir2_dataptr_to_off
(
struct
xfs_mount
*
mp
,
xfs_dir2_dataptr_t
dp
)
{
return
xfs_dir2_byte_to_off
(
mp
,
xfs_dir2_dataptr_to_byte
(
dp
));
}
/*
* Convert block and offset to byte in space
*/
static
inline
xfs_dir2_off_t
xfs_dir2_db_off_to_byte
(
struct
xfs_mount
*
mp
,
xfs_dir2_db_t
db
,
xfs_dir2_data_aoff_t
o
)
{
return
((
xfs_dir2_off_t
)
db
<<
(
mp
->
m_sb
.
sb_blocklog
+
mp
->
m_sb
.
sb_dirblklog
))
+
o
;
}
/*
* Convert block (DB) to block (dablk)
*/
static
inline
xfs_dablk_t
xfs_dir2_db_to_da
(
struct
xfs_mount
*
mp
,
xfs_dir2_db_t
db
)
{
return
(
xfs_dablk_t
)(
db
<<
mp
->
m_sb
.
sb_dirblklog
);
}
/*
* Convert byte in space to (DA) block
*/
static
inline
xfs_dablk_t
xfs_dir2_byte_to_da
(
struct
xfs_mount
*
mp
,
xfs_dir2_off_t
by
)
{
return
xfs_dir2_db_to_da
(
mp
,
xfs_dir2_byte_to_db
(
mp
,
by
));
}
/*
* Convert block and offset to dataptr
*/
static
inline
xfs_dir2_dataptr_t
xfs_dir2_db_off_to_dataptr
(
struct
xfs_mount
*
mp
,
xfs_dir2_db_t
db
,
xfs_dir2_data_aoff_t
o
)
{
return
xfs_dir2_byte_to_dataptr
(
xfs_dir2_db_off_to_byte
(
mp
,
db
,
o
));
}
/*
* Convert block (dablk) to block (DB)
*/
static
inline
xfs_dir2_db_t
xfs_dir2_da_to_db
(
struct
xfs_mount
*
mp
,
xfs_dablk_t
da
)
{
return
(
xfs_dir2_db_t
)(
da
>>
mp
->
m_sb
.
sb_dirblklog
);
}
/*
* Convert block (dablk) to byte offset in space
*/
static
inline
xfs_dir2_off_t
xfs_dir2_da_to_byte
(
struct
xfs_mount
*
mp
,
xfs_dablk_t
da
)
{
return
xfs_dir2_db_off_to_byte
(
mp
,
xfs_dir2_da_to_db
(
mp
,
da
),
0
);
}
/*
* Free space block defintions for the node format.
*/
...
...
@@ -659,8 +521,6 @@ xfs_dir2_da_to_byte(struct xfs_mount *mp, xfs_dablk_t da)
*/
#define XFS_DIR2_FREE_SPACE 2
#define XFS_DIR2_FREE_OFFSET (XFS_DIR2_FREE_SPACE * XFS_DIR2_SPACE_SIZE)
#define XFS_DIR2_FREE_FIRSTDB(mp) \
xfs_dir2_byte_to_db(mp, XFS_DIR2_FREE_OFFSET)
typedef
struct
xfs_dir2_free_hdr
{
__be32
magic
;
/* XFS_DIR2_FREE_MAGIC */
...
...
@@ -735,16 +595,6 @@ typedef struct xfs_dir2_block_tail {
__be32
stale
;
/* count of stale lf entries */
}
xfs_dir2_block_tail_t
;
/*
* Pointer to the leaf header embedded in a data block (1-block format)
*/
static
inline
struct
xfs_dir2_block_tail
*
xfs_dir2_block_tail_p
(
struct
xfs_mount
*
mp
,
struct
xfs_dir2_data_hdr
*
hdr
)
{
return
((
struct
xfs_dir2_block_tail
*
)
((
char
*
)
hdr
+
mp
->
m_dirblksize
))
-
1
;
}
/*
* Pointer to the leaf entries embedded in a data block (1-block format)
*/
...
...
@@ -764,10 +614,6 @@ xfs_dir2_block_leaf_p(struct xfs_dir2_block_tail *btp)
* of an attribute name may not be unique, we may have duplicate keys. The
* internal links in the Btree are logical block offsets into the file.
*
*========================================================================
* Attribute structure when equal to XFS_LBSIZE(mp) bytes.
*========================================================================
*
* Struct leaf_entry's are packed from the top. Name/values grow from the
* bottom but are not packed. The freemap contains run-length-encoded entries
* for the free bytes after the leaf_entry's, but only the N largest such,
...
...
fs/xfs/xfs_dir2.c
浏览文件 @
8612c7e5
...
...
@@ -85,11 +85,12 @@ static struct xfs_nameops xfs_ascii_ci_nameops = {
.
compname
=
xfs_ascii_ci_compname
,
};
void
xfs_d
ir
_mount
(
xfs_mount_
t
*
mp
)
int
xfs_d
a
_mount
(
struct
xfs_moun
t
*
mp
)
{
int
nodehdr_size
;
struct
xfs_da_geometry
*
dageo
;
int
nodehdr_size
;
ASSERT
(
mp
->
m_sb
.
sb_versionnum
&
XFS_SB_VERSION_DIRV2BIT
);
...
...
@@ -99,24 +100,59 @@ xfs_dir_mount(
mp
->
m_dir_inode_ops
=
xfs_dir_get_ops
(
mp
,
NULL
);
mp
->
m_nondir_inode_ops
=
xfs_nondir_get_ops
(
mp
,
NULL
);
mp
->
m_dirblksize
=
1
<<
(
mp
->
m_sb
.
sb_blocklog
+
mp
->
m_sb
.
sb_dirblklog
);
mp
->
m_dirblkfsbs
=
1
<<
mp
->
m_sb
.
sb_dirblklog
;
mp
->
m_dirdatablk
=
xfs_dir2_db_to_da
(
mp
,
XFS_DIR2_DATA_FIRSTDB
(
mp
));
mp
->
m_dirleafblk
=
xfs_dir2_db_to_da
(
mp
,
XFS_DIR2_LEAF_FIRSTDB
(
mp
));
mp
->
m_dirfreeblk
=
xfs_dir2_db_to_da
(
mp
,
XFS_DIR2_FREE_FIRSTDB
(
mp
));
nodehdr_size
=
mp
->
m_dir_inode_ops
->
node_hdr_size
;
mp
->
m_attr_node_ents
=
(
mp
->
m_sb
.
sb_blocksize
-
nodehdr_size
)
/
mp
->
m_dir_geo
=
kmem_zalloc
(
sizeof
(
struct
xfs_da_geometry
),
KM_SLEEP
|
KM_MAYFAIL
);
mp
->
m_attr_geo
=
kmem_zalloc
(
sizeof
(
struct
xfs_da_geometry
),
KM_SLEEP
|
KM_MAYFAIL
);
if
(
!
mp
->
m_dir_geo
||
!
mp
->
m_attr_geo
)
{
kmem_free
(
mp
->
m_dir_geo
);
kmem_free
(
mp
->
m_attr_geo
);
return
ENOMEM
;
}
/* set up directory geometry */
dageo
=
mp
->
m_dir_geo
;
dageo
->
blklog
=
mp
->
m_sb
.
sb_blocklog
+
mp
->
m_sb
.
sb_dirblklog
;
dageo
->
fsblog
=
mp
->
m_sb
.
sb_blocklog
;
dageo
->
blksize
=
1
<<
dageo
->
blklog
;
dageo
->
fsbcount
=
1
<<
mp
->
m_sb
.
sb_dirblklog
;
/*
* Now we've set up the block conversion variables, we can calculate the
* segment block constants using the geometry structure.
*/
dageo
->
datablk
=
xfs_dir2_byte_to_da
(
dageo
,
XFS_DIR2_DATA_OFFSET
);
dageo
->
leafblk
=
xfs_dir2_byte_to_da
(
dageo
,
XFS_DIR2_LEAF_OFFSET
);
dageo
->
freeblk
=
xfs_dir2_byte_to_da
(
dageo
,
XFS_DIR2_FREE_OFFSET
);
dageo
->
node_ents
=
(
dageo
->
blksize
-
nodehdr_size
)
/
(
uint
)
sizeof
(
xfs_da_node_entry_t
);
mp
->
m_dir_node_ents
=
(
mp
->
m_dirblksize
-
nodehdr_size
)
/
dageo
->
magicpct
=
(
dageo
->
blksize
*
37
)
/
100
;
/* set up attribute geometry - single fsb only */
dageo
=
mp
->
m_attr_geo
;
dageo
->
blklog
=
mp
->
m_sb
.
sb_blocklog
;
dageo
->
fsblog
=
mp
->
m_sb
.
sb_blocklog
;
dageo
->
blksize
=
1
<<
dageo
->
blklog
;
dageo
->
fsbcount
=
1
;
dageo
->
node_ents
=
(
dageo
->
blksize
-
nodehdr_size
)
/
(
uint
)
sizeof
(
xfs_da_node_entry_t
);
dageo
->
magicpct
=
(
dageo
->
blksize
*
37
)
/
100
;
mp
->
m_dir_magicpct
=
(
mp
->
m_dirblksize
*
37
)
/
100
;
if
(
xfs_sb_version_hasasciici
(
&
mp
->
m_sb
))
mp
->
m_dirnameops
=
&
xfs_ascii_ci_nameops
;
else
mp
->
m_dirnameops
=
&
xfs_default_nameops
;
return
0
;
}
void
xfs_da_unmount
(
struct
xfs_mount
*
mp
)
{
kmem_free
(
mp
->
m_dir_geo
);
kmem_free
(
mp
->
m_attr_geo
);
}
/*
...
...
@@ -192,6 +228,7 @@ xfs_dir_init(
if
(
!
args
)
return
ENOMEM
;
args
->
geo
=
dp
->
i_mount
->
m_dir_geo
;
args
->
dp
=
dp
;
args
->
trans
=
tp
;
error
=
xfs_dir2_sf_create
(
args
,
pdp
->
i_ino
);
...
...
@@ -226,6 +263,7 @@ xfs_dir_createname(
if
(
!
args
)
return
ENOMEM
;
args
->
geo
=
dp
->
i_mount
->
m_dir_geo
;
args
->
name
=
name
->
name
;
args
->
namelen
=
name
->
len
;
args
->
filetype
=
name
->
type
;
...
...
@@ -244,7 +282,7 @@ xfs_dir_createname(
goto
out_free
;
}
rval
=
xfs_dir2_isblock
(
dp
,
&
v
);
rval
=
xfs_dir2_isblock
(
args
,
&
v
);
if
(
rval
)
goto
out_free
;
if
(
v
)
{
...
...
@@ -252,7 +290,7 @@ xfs_dir_createname(
goto
out_free
;
}
rval
=
xfs_dir2_isleaf
(
dp
,
&
v
);
rval
=
xfs_dir2_isleaf
(
args
,
&
v
);
if
(
rval
)
goto
out_free
;
if
(
v
)
...
...
@@ -320,6 +358,7 @@ xfs_dir_lookup(
* annotations into the reclaim path for the ilock.
*/
args
=
kmem_zalloc
(
sizeof
(
*
args
),
KM_SLEEP
|
KM_NOFS
);
args
->
geo
=
dp
->
i_mount
->
m_dir_geo
;
args
->
name
=
name
->
name
;
args
->
namelen
=
name
->
len
;
args
->
filetype
=
name
->
type
;
...
...
@@ -336,7 +375,7 @@ xfs_dir_lookup(
goto
out_check_rval
;
}
rval
=
xfs_dir2_isblock
(
dp
,
&
v
);
rval
=
xfs_dir2_isblock
(
args
,
&
v
);
if
(
rval
)
goto
out_free
;
if
(
v
)
{
...
...
@@ -344,7 +383,7 @@ xfs_dir_lookup(
goto
out_check_rval
;
}
rval
=
xfs_dir2_isleaf
(
dp
,
&
v
);
rval
=
xfs_dir2_isleaf
(
args
,
&
v
);
if
(
rval
)
goto
out_free
;
if
(
v
)
...
...
@@ -391,6 +430,7 @@ xfs_dir_removename(
if
(
!
args
)
return
ENOMEM
;
args
->
geo
=
dp
->
i_mount
->
m_dir_geo
;
args
->
name
=
name
->
name
;
args
->
namelen
=
name
->
len
;
args
->
filetype
=
name
->
type
;
...
...
@@ -408,7 +448,7 @@ xfs_dir_removename(
goto
out_free
;
}
rval
=
xfs_dir2_isblock
(
dp
,
&
v
);
rval
=
xfs_dir2_isblock
(
args
,
&
v
);
if
(
rval
)
goto
out_free
;
if
(
v
)
{
...
...
@@ -416,7 +456,7 @@ xfs_dir_removename(
goto
out_free
;
}
rval
=
xfs_dir2_isleaf
(
dp
,
&
v
);
rval
=
xfs_dir2_isleaf
(
args
,
&
v
);
if
(
rval
)
goto
out_free
;
if
(
v
)
...
...
@@ -455,6 +495,7 @@ xfs_dir_replace(
if
(
!
args
)
return
ENOMEM
;
args
->
geo
=
dp
->
i_mount
->
m_dir_geo
;
args
->
name
=
name
->
name
;
args
->
namelen
=
name
->
len
;
args
->
filetype
=
name
->
type
;
...
...
@@ -472,7 +513,7 @@ xfs_dir_replace(
goto
out_free
;
}
rval
=
xfs_dir2_isblock
(
dp
,
&
v
);
rval
=
xfs_dir2_isblock
(
args
,
&
v
);
if
(
rval
)
goto
out_free
;
if
(
v
)
{
...
...
@@ -480,7 +521,7 @@ xfs_dir_replace(
goto
out_free
;
}
rval
=
xfs_dir2_isleaf
(
dp
,
&
v
);
rval
=
xfs_dir2_isleaf
(
args
,
&
v
);
if
(
rval
)
goto
out_free
;
if
(
v
)
...
...
@@ -516,6 +557,7 @@ xfs_dir_canenter(
if
(
!
args
)
return
ENOMEM
;
args
->
geo
=
dp
->
i_mount
->
m_dir_geo
;
args
->
name
=
name
->
name
;
args
->
namelen
=
name
->
len
;
args
->
filetype
=
name
->
type
;
...
...
@@ -531,7 +573,7 @@ xfs_dir_canenter(
goto
out_free
;
}
rval
=
xfs_dir2_isblock
(
dp
,
&
v
);
rval
=
xfs_dir2_isblock
(
args
,
&
v
);
if
(
rval
)
goto
out_free
;
if
(
v
)
{
...
...
@@ -539,7 +581,7 @@ xfs_dir_canenter(
goto
out_free
;
}
rval
=
xfs_dir2_isleaf
(
dp
,
&
v
);
rval
=
xfs_dir2_isleaf
(
args
,
&
v
);
if
(
rval
)
goto
out_free
;
if
(
v
)
...
...
@@ -579,13 +621,13 @@ xfs_dir2_grow_inode(
* Set lowest possible block in the space requested.
*/
bno
=
XFS_B_TO_FSBT
(
mp
,
space
*
XFS_DIR2_SPACE_SIZE
);
count
=
mp
->
m_dirblkfsbs
;
count
=
args
->
geo
->
fsbcount
;
error
=
xfs_da_grow_inode_int
(
args
,
&
bno
,
count
);
if
(
error
)
return
error
;
*
dbp
=
xfs_dir2_da_to_db
(
mp
,
(
xfs_dablk_t
)
bno
);
*
dbp
=
xfs_dir2_da_to_db
(
args
->
geo
,
(
xfs_dablk_t
)
bno
);
/*
* Update file's size if this is the data space and it grew.
...
...
@@ -607,18 +649,16 @@ xfs_dir2_grow_inode(
*/
int
xfs_dir2_isblock
(
xfs_inode_t
*
dp
,
int
*
vp
)
/* out: 1 is block, 0 is not block */
struct
xfs_da_args
*
args
,
int
*
vp
)
/* out: 1 is block, 0 is not block */
{
xfs_fileoff_t
last
;
/* last file offset */
xfs_mount_t
*
mp
;
int
rval
;
xfs_fileoff_t
last
;
/* last file offset */
int
rval
;
mp
=
dp
->
i_mount
;
if
((
rval
=
xfs_bmap_last_offset
(
dp
,
&
last
,
XFS_DATA_FORK
)))
if
((
rval
=
xfs_bmap_last_offset
(
args
->
dp
,
&
last
,
XFS_DATA_FORK
)))
return
rval
;
rval
=
XFS_FSB_TO_B
(
mp
,
last
)
==
mp
->
m_dir
blksize
;
ASSERT
(
rval
==
0
||
dp
->
i_d
.
di_size
==
mp
->
m_dir
blksize
);
rval
=
XFS_FSB_TO_B
(
args
->
dp
->
i_mount
,
last
)
==
args
->
geo
->
blksize
;
ASSERT
(
rval
==
0
||
args
->
dp
->
i_d
.
di_size
==
args
->
geo
->
blksize
);
*
vp
=
rval
;
return
0
;
}
...
...
@@ -628,17 +668,15 @@ xfs_dir2_isblock(
*/
int
xfs_dir2_isleaf
(
xfs_inode_t
*
dp
,
int
*
vp
)
/* out: 1 is leaf, 0 is not leaf
*/
struct
xfs_da_args
*
args
,
int
*
vp
)
/* out: 1 is block, 0 is not block
*/
{
xfs_fileoff_t
last
;
/* last file offset */
xfs_mount_t
*
mp
;
int
rval
;
xfs_fileoff_t
last
;
/* last file offset */
int
rval
;
mp
=
dp
->
i_mount
;
if
((
rval
=
xfs_bmap_last_offset
(
dp
,
&
last
,
XFS_DATA_FORK
)))
if
((
rval
=
xfs_bmap_last_offset
(
args
->
dp
,
&
last
,
XFS_DATA_FORK
)))
return
rval
;
*
vp
=
last
==
mp
->
m_dirleafblk
+
(
1
<<
mp
->
m_sb
.
sb_dirblklog
)
;
*
vp
=
last
==
args
->
geo
->
leafblk
+
args
->
geo
->
fsbcount
;
return
0
;
}
...
...
@@ -666,11 +704,11 @@ xfs_dir2_shrink_inode(
dp
=
args
->
dp
;
mp
=
dp
->
i_mount
;
tp
=
args
->
trans
;
da
=
xfs_dir2_db_to_da
(
mp
,
db
);
da
=
xfs_dir2_db_to_da
(
args
->
geo
,
db
);
/*
* Unmap the fsblock(s).
*/
if
((
error
=
xfs_bunmapi
(
tp
,
dp
,
da
,
mp
->
m_dirblkfsbs
,
if
((
error
=
xfs_bunmapi
(
tp
,
dp
,
da
,
args
->
geo
->
fsbcount
,
XFS_BMAPI_METADATA
,
0
,
args
->
firstblock
,
args
->
flist
,
&
done
)))
{
/*
...
...
@@ -697,12 +735,12 @@ xfs_dir2_shrink_inode(
/*
* If it's not a data block, we're done.
*/
if
(
db
>=
XFS_DIR2_LEAF_FIRSTDB
(
mp
))
if
(
db
>=
xfs_dir2_byte_to_db
(
args
->
geo
,
XFS_DIR2_LEAF_OFFSET
))
return
0
;
/*
* If the block isn't the last one in the directory, we're done.
*/
if
(
dp
->
i_d
.
di_size
>
xfs_dir2_db_off_to_byte
(
mp
,
db
+
1
,
0
))
if
(
dp
->
i_d
.
di_size
>
xfs_dir2_db_off_to_byte
(
args
->
geo
,
db
+
1
,
0
))
return
0
;
bno
=
da
;
if
((
error
=
xfs_bmap_last_before
(
tp
,
dp
,
&
bno
,
XFS_DATA_FORK
)))
{
...
...
@@ -711,7 +749,7 @@ xfs_dir2_shrink_inode(
*/
return
error
;
}
if
(
db
==
mp
->
m_dir
datablk
)
if
(
db
==
args
->
geo
->
datablk
)
ASSERT
(
bno
==
0
);
else
ASSERT
(
bno
>
0
);
...
...
fs/xfs/xfs_dir2.h
浏览文件 @
8612c7e5
...
...
@@ -80,7 +80,7 @@ struct xfs_dir_ops {
struct
xfs_dir3_icleaf_hdr
*
from
);
void
(
*
leaf_hdr_from_disk
)(
struct
xfs_dir3_icleaf_hdr
*
to
,
struct
xfs_dir2_leaf
*
from
);
int
(
*
leaf_max_ents
)(
struct
xfs_
mount
*
mp
);
int
(
*
leaf_max_ents
)(
struct
xfs_
da_geometry
*
geo
);
struct
xfs_dir2_leaf_entry
*
(
*
leaf_ents_p
)(
struct
xfs_dir2_leaf
*
lp
);
...
...
@@ -97,10 +97,12 @@ struct xfs_dir_ops {
struct
xfs_dir3_icfree_hdr
*
from
);
void
(
*
free_hdr_from_disk
)(
struct
xfs_dir3_icfree_hdr
*
to
,
struct
xfs_dir2_free
*
from
);
int
(
*
free_max_bests
)(
struct
xfs_
mount
*
mp
);
int
(
*
free_max_bests
)(
struct
xfs_
da_geometry
*
geo
);
__be16
*
(
*
free_bests_p
)(
struct
xfs_dir2_free
*
free
);
xfs_dir2_db_t
(
*
db_to_fdb
)(
struct
xfs_mount
*
mp
,
xfs_dir2_db_t
db
);
int
(
*
db_to_fdindex
)(
struct
xfs_mount
*
mp
,
xfs_dir2_db_t
db
);
xfs_dir2_db_t
(
*
db_to_fdb
)(
struct
xfs_da_geometry
*
geo
,
xfs_dir2_db_t
db
);
int
(
*
db_to_fdindex
)(
struct
xfs_da_geometry
*
geo
,
xfs_dir2_db_t
db
);
};
extern
const
struct
xfs_dir_ops
*
...
...
@@ -112,7 +114,9 @@ extern const struct xfs_dir_ops *
* Generic directory interface routines
*/
extern
void
xfs_dir_startup
(
void
);
extern
void
xfs_dir_mount
(
struct
xfs_mount
*
mp
);
extern
int
xfs_da_mount
(
struct
xfs_mount
*
mp
);
extern
void
xfs_da_unmount
(
struct
xfs_mount
*
mp
);
extern
int
xfs_dir_isempty
(
struct
xfs_inode
*
dp
);
extern
int
xfs_dir_init
(
struct
xfs_trans
*
tp
,
struct
xfs_inode
*
dp
,
struct
xfs_inode
*
pdp
);
...
...
@@ -142,23 +146,23 @@ extern int xfs_dir2_sf_to_block(struct xfs_da_args *args);
/*
* Interface routines used by userspace utilities
*/
extern
int
xfs_dir2_isblock
(
struct
xfs_
inode
*
dp
,
int
*
r
);
extern
int
xfs_dir2_isleaf
(
struct
xfs_
inode
*
dp
,
int
*
r
);
extern
int
xfs_dir2_isblock
(
struct
xfs_
da_args
*
args
,
int
*
r
);
extern
int
xfs_dir2_isleaf
(
struct
xfs_
da_args
*
args
,
int
*
r
);
extern
int
xfs_dir2_shrink_inode
(
struct
xfs_da_args
*
args
,
xfs_dir2_db_t
db
,
struct
xfs_buf
*
bp
);
extern
void
xfs_dir2_data_freescan
(
struct
xfs_inode
*
dp
,
struct
xfs_dir2_data_hdr
*
hdr
,
int
*
loghead
);
extern
void
xfs_dir2_data_log_entry
(
struct
xfs_
trans
*
tp
,
struct
xfs_inode
*
dp
,
extern
void
xfs_dir2_data_log_entry
(
struct
xfs_
da_args
*
args
,
struct
xfs_buf
*
bp
,
struct
xfs_dir2_data_entry
*
dep
);
extern
void
xfs_dir2_data_log_header
(
struct
xfs_
trans
*
tp
,
struct
xfs_inode
*
dp
,
extern
void
xfs_dir2_data_log_header
(
struct
xfs_
da_args
*
args
,
struct
xfs_buf
*
bp
);
extern
void
xfs_dir2_data_log_unused
(
struct
xfs_
trans
*
tp
,
struct
xfs_buf
*
bp
,
struct
xfs_dir2_data_unused
*
dup
);
extern
void
xfs_dir2_data_make_free
(
struct
xfs_
trans
*
tp
,
struct
xfs_inode
*
dp
,
extern
void
xfs_dir2_data_log_unused
(
struct
xfs_
da_args
*
args
,
struct
xfs_
buf
*
bp
,
struct
xfs_
dir2_data_unused
*
dup
);
extern
void
xfs_dir2_data_make_free
(
struct
xfs_
da_args
*
args
,
struct
xfs_buf
*
bp
,
xfs_dir2_data_aoff_t
offset
,
xfs_dir2_data_aoff_t
len
,
int
*
needlogp
,
int
*
needscanp
);
extern
void
xfs_dir2_data_use_free
(
struct
xfs_
trans
*
tp
,
struct
xfs_inode
*
dp
,
extern
void
xfs_dir2_data_use_free
(
struct
xfs_
da_args
*
args
,
struct
xfs_buf
*
bp
,
struct
xfs_dir2_data_unused
*
dup
,
xfs_dir2_data_aoff_t
offset
,
xfs_dir2_data_aoff_t
len
,
int
*
needlogp
,
int
*
needscanp
);
...
...
fs/xfs/xfs_dir2_block.c
浏览文件 @
8612c7e5
...
...
@@ -136,7 +136,7 @@ xfs_dir3_block_read(
struct
xfs_mount
*
mp
=
dp
->
i_mount
;
int
err
;
err
=
xfs_da_read_buf
(
tp
,
dp
,
mp
->
m_dirdatablk
,
-
1
,
bpp
,
err
=
xfs_da_read_buf
(
tp
,
dp
,
mp
->
m_dir
_geo
->
datablk
,
-
1
,
bpp
,
XFS_DATA_FORK
,
&
xfs_dir3_block_buf_ops
);
if
(
!
err
&&
tp
)
xfs_trans_buf_set_type
(
tp
,
*
bpp
,
XFS_BLFT_DIR_BLOCK_BUF
);
...
...
@@ -281,8 +281,7 @@ xfs_dir2_block_need_space(
*/
static
void
xfs_dir2_block_compact
(
struct
xfs_trans
*
tp
,
struct
xfs_inode
*
dp
,
struct
xfs_da_args
*
args
,
struct
xfs_buf
*
bp
,
struct
xfs_dir2_data_hdr
*
hdr
,
struct
xfs_dir2_block_tail
*
btp
,
...
...
@@ -315,7 +314,7 @@ xfs_dir2_block_compact(
*
lfloglow
=
toidx
+
1
-
(
be32_to_cpu
(
btp
->
stale
)
-
1
);
*
lfloghigh
-=
be32_to_cpu
(
btp
->
stale
)
-
1
;
be32_add_cpu
(
&
btp
->
count
,
-
(
be32_to_cpu
(
btp
->
stale
)
-
1
));
xfs_dir2_data_make_free
(
tp
,
dp
,
bp
,
xfs_dir2_data_make_free
(
args
,
bp
,
(
xfs_dir2_data_aoff_t
)((
char
*
)
blp
-
(
char
*
)
hdr
),
(
xfs_dir2_data_aoff_t
)((
be32_to_cpu
(
btp
->
stale
)
-
1
)
*
sizeof
(
*
blp
)),
needlog
,
&
needscan
);
...
...
@@ -325,7 +324,7 @@ xfs_dir2_block_compact(
* This needs to happen before the next call to use_free.
*/
if
(
needscan
)
xfs_dir2_data_freescan
(
dp
,
hdr
,
needlog
);
xfs_dir2_data_freescan
(
args
->
dp
,
hdr
,
needlog
);
}
/*
...
...
@@ -377,7 +376,7 @@ xfs_dir2_block_addname(
* Set up pointers to parts of the block.
*/
hdr
=
bp
->
b_addr
;
btp
=
xfs_dir2_block_tail_p
(
mp
,
hdr
);
btp
=
xfs_dir2_block_tail_p
(
args
->
geo
,
hdr
);
blp
=
xfs_dir2_block_leaf_p
(
btp
);
/*
...
...
@@ -420,7 +419,7 @@ xfs_dir2_block_addname(
* If need to compact the leaf entries, do it now.
*/
if
(
compact
)
{
xfs_dir2_block_compact
(
tp
,
dp
,
bp
,
hdr
,
btp
,
blp
,
&
needlog
,
xfs_dir2_block_compact
(
args
,
bp
,
hdr
,
btp
,
blp
,
&
needlog
,
&
lfloghigh
,
&
lfloglow
);
/* recalculate blp post-compaction */
blp
=
xfs_dir2_block_leaf_p
(
btp
);
...
...
@@ -455,7 +454,7 @@ xfs_dir2_block_addname(
/*
* Mark the space needed for the new leaf entry, now in use.
*/
xfs_dir2_data_use_free
(
tp
,
dp
,
bp
,
enddup
,
xfs_dir2_data_use_free
(
args
,
bp
,
enddup
,
(
xfs_dir2_data_aoff_t
)
((
char
*
)
enddup
-
(
char
*
)
hdr
+
be16_to_cpu
(
enddup
->
length
)
-
sizeof
(
*
blp
)),
...
...
@@ -542,7 +541,7 @@ xfs_dir2_block_addname(
/*
* Mark space for the data entry used.
*/
xfs_dir2_data_use_free
(
tp
,
dp
,
bp
,
dup
,
xfs_dir2_data_use_free
(
args
,
bp
,
dup
,
(
xfs_dir2_data_aoff_t
)((
char
*
)
dup
-
(
char
*
)
hdr
),
(
xfs_dir2_data_aoff_t
)
len
,
&
needlog
,
&
needscan
);
/*
...
...
@@ -560,9 +559,9 @@ xfs_dir2_block_addname(
if
(
needscan
)
xfs_dir2_data_freescan
(
dp
,
hdr
,
&
needlog
);
if
(
needlog
)
xfs_dir2_data_log_header
(
tp
,
dp
,
bp
);
xfs_dir2_data_log_header
(
args
,
bp
);
xfs_dir2_block_log_tail
(
tp
,
bp
);
xfs_dir2_data_log_entry
(
tp
,
dp
,
bp
,
dep
);
xfs_dir2_data_log_entry
(
args
,
bp
,
dep
);
xfs_dir3_data_check
(
dp
,
bp
);
return
0
;
}
...
...
@@ -581,7 +580,7 @@ xfs_dir2_block_log_leaf(
xfs_dir2_leaf_entry_t
*
blp
;
xfs_dir2_block_tail_t
*
btp
;
btp
=
xfs_dir2_block_tail_p
(
tp
->
t_mountp
,
hdr
);
btp
=
xfs_dir2_block_tail_p
(
tp
->
t_mountp
->
m_dir_geo
,
hdr
);
blp
=
xfs_dir2_block_leaf_p
(
btp
);
xfs_trans_log_buf
(
tp
,
bp
,
(
uint
)((
char
*
)
&
blp
[
first
]
-
(
char
*
)
hdr
),
(
uint
)((
char
*
)
&
blp
[
last
+
1
]
-
(
char
*
)
hdr
-
1
));
...
...
@@ -598,7 +597,7 @@ xfs_dir2_block_log_tail(
xfs_dir2_data_hdr_t
*
hdr
=
bp
->
b_addr
;
xfs_dir2_block_tail_t
*
btp
;
btp
=
xfs_dir2_block_tail_p
(
tp
->
t_mountp
,
hdr
);
btp
=
xfs_dir2_block_tail_p
(
tp
->
t_mountp
->
m_dir_geo
,
hdr
);
xfs_trans_log_buf
(
tp
,
bp
,
(
uint
)((
char
*
)
btp
-
(
char
*
)
hdr
),
(
uint
)((
char
*
)(
btp
+
1
)
-
(
char
*
)
hdr
-
1
));
}
...
...
@@ -633,13 +632,14 @@ xfs_dir2_block_lookup(
mp
=
dp
->
i_mount
;
hdr
=
bp
->
b_addr
;
xfs_dir3_data_check
(
dp
,
bp
);
btp
=
xfs_dir2_block_tail_p
(
mp
,
hdr
);
btp
=
xfs_dir2_block_tail_p
(
args
->
geo
,
hdr
);
blp
=
xfs_dir2_block_leaf_p
(
btp
);
/*
* Get the offset from the leaf entry, to point to the data.
*/
dep
=
(
xfs_dir2_data_entry_t
*
)((
char
*
)
hdr
+
xfs_dir2_dataptr_to_off
(
mp
,
be32_to_cpu
(
blp
[
ent
].
address
)));
xfs_dir2_dataptr_to_off
(
args
->
geo
,
be32_to_cpu
(
blp
[
ent
].
address
)));
/*
* Fill in inode number, CI name if appropriate, release the block.
*/
...
...
@@ -685,7 +685,7 @@ xfs_dir2_block_lookup_int(
hdr
=
bp
->
b_addr
;
xfs_dir3_data_check
(
dp
,
bp
);
btp
=
xfs_dir2_block_tail_p
(
mp
,
hdr
);
btp
=
xfs_dir2_block_tail_p
(
args
->
geo
,
hdr
);
blp
=
xfs_dir2_block_leaf_p
(
btp
);
/*
* Loop doing a binary search for our hash value.
...
...
@@ -723,7 +723,7 @@ xfs_dir2_block_lookup_int(
* Get pointer to the entry from the leaf.
*/
dep
=
(
xfs_dir2_data_entry_t
*
)
((
char
*
)
hdr
+
xfs_dir2_dataptr_to_off
(
mp
,
addr
));
((
char
*
)
hdr
+
xfs_dir2_dataptr_to_off
(
args
->
geo
,
addr
));
/*
* Compare name and if it's an exact match, return the index
* and buffer. If it's the first case-insensitive match, store
...
...
@@ -790,18 +790,19 @@ xfs_dir2_block_removename(
tp
=
args
->
trans
;
mp
=
dp
->
i_mount
;
hdr
=
bp
->
b_addr
;
btp
=
xfs_dir2_block_tail_p
(
mp
,
hdr
);
btp
=
xfs_dir2_block_tail_p
(
args
->
geo
,
hdr
);
blp
=
xfs_dir2_block_leaf_p
(
btp
);
/*
* Point to the data entry using the leaf entry.
*/
dep
=
(
xfs_dir2_data_entry_t
*
)
((
char
*
)
hdr
+
xfs_dir2_dataptr_to_off
(
mp
,
be32_to_cpu
(
blp
[
ent
].
address
)));
dep
=
(
xfs_dir2_data_entry_t
*
)((
char
*
)
hdr
+
xfs_dir2_dataptr_to_off
(
args
->
geo
,
be32_to_cpu
(
blp
[
ent
].
address
)));
/*
* Mark the data entry's space free.
*/
needlog
=
needscan
=
0
;
xfs_dir2_data_make_free
(
tp
,
dp
,
bp
,
xfs_dir2_data_make_free
(
args
,
bp
,
(
xfs_dir2_data_aoff_t
)((
char
*
)
dep
-
(
char
*
)
hdr
),
dp
->
d_ops
->
data_entsize
(
dep
->
namelen
),
&
needlog
,
&
needscan
);
/*
...
...
@@ -820,7 +821,7 @@ xfs_dir2_block_removename(
if
(
needscan
)
xfs_dir2_data_freescan
(
dp
,
hdr
,
&
needlog
);
if
(
needlog
)
xfs_dir2_data_log_header
(
tp
,
dp
,
bp
);
xfs_dir2_data_log_header
(
args
,
bp
);
xfs_dir3_data_check
(
dp
,
bp
);
/*
* See if the size as a shortform is good enough.
...
...
@@ -865,20 +866,21 @@ xfs_dir2_block_replace(
dp
=
args
->
dp
;
mp
=
dp
->
i_mount
;
hdr
=
bp
->
b_addr
;
btp
=
xfs_dir2_block_tail_p
(
mp
,
hdr
);
btp
=
xfs_dir2_block_tail_p
(
args
->
geo
,
hdr
);
blp
=
xfs_dir2_block_leaf_p
(
btp
);
/*
* Point to the data entry we need to change.
*/
dep
=
(
xfs_dir2_data_entry_t
*
)
((
char
*
)
hdr
+
xfs_dir2_dataptr_to_off
(
mp
,
be32_to_cpu
(
blp
[
ent
].
address
)));
dep
=
(
xfs_dir2_data_entry_t
*
)((
char
*
)
hdr
+
xfs_dir2_dataptr_to_off
(
args
->
geo
,
be32_to_cpu
(
blp
[
ent
].
address
)));
ASSERT
(
be64_to_cpu
(
dep
->
inumber
)
!=
args
->
inumber
);
/*
* Change the inode number to the new value.
*/
dep
->
inumber
=
cpu_to_be64
(
args
->
inumber
);
dp
->
d_ops
->
data_put_ftype
(
dep
,
args
->
filetype
);
xfs_dir2_data_log_entry
(
args
->
trans
,
dp
,
bp
,
dep
);
xfs_dir2_data_log_entry
(
args
,
bp
,
dep
);
xfs_dir3_data_check
(
dp
,
bp
);
return
0
;
}
...
...
@@ -938,7 +940,7 @@ xfs_dir2_leaf_to_block(
leaf
=
lbp
->
b_addr
;
dp
->
d_ops
->
leaf_hdr_from_disk
(
&
leafhdr
,
leaf
);
ents
=
dp
->
d_ops
->
leaf_ents_p
(
leaf
);
ltp
=
xfs_dir2_leaf_tail_p
(
mp
,
leaf
);
ltp
=
xfs_dir2_leaf_tail_p
(
args
->
geo
,
leaf
);
ASSERT
(
leafhdr
.
magic
==
XFS_DIR2_LEAF1_MAGIC
||
leafhdr
.
magic
==
XFS_DIR3_LEAF1_MAGIC
);
...
...
@@ -948,13 +950,13 @@ xfs_dir2_leaf_to_block(
* been left behind during no-space-reservation operations.
* These will show up in the leaf bests table.
*/
while
(
dp
->
i_d
.
di_size
>
mp
->
m_dir
blksize
)
{
while
(
dp
->
i_d
.
di_size
>
args
->
geo
->
blksize
)
{
int
hdrsz
;
hdrsz
=
dp
->
d_ops
->
data_entry_offset
;
bestsp
=
xfs_dir2_leaf_bests_p
(
ltp
);
if
(
be16_to_cpu
(
bestsp
[
be32_to_cpu
(
ltp
->
bestcount
)
-
1
])
==
mp
->
m_dir
blksize
-
hdrsz
)
{
args
->
geo
->
blksize
-
hdrsz
)
{
if
((
error
=
xfs_dir2_leaf_trim_data
(
args
,
lbp
,
(
xfs_dir2_db_t
)(
be32_to_cpu
(
ltp
->
bestcount
)
-
1
))))
...
...
@@ -966,7 +968,7 @@ xfs_dir2_leaf_to_block(
* Read the data block if we don't already have it, give up if it fails.
*/
if
(
!
dbp
)
{
error
=
xfs_dir3_data_read
(
tp
,
dp
,
mp
->
m_dir
datablk
,
-
1
,
&
dbp
);
error
=
xfs_dir3_data_read
(
tp
,
dp
,
args
->
geo
->
datablk
,
-
1
,
&
dbp
);
if
(
error
)
return
error
;
}
...
...
@@ -982,7 +984,7 @@ xfs_dir2_leaf_to_block(
/*
* Look at the last data entry.
*/
tagp
=
(
__be16
*
)((
char
*
)
hdr
+
mp
->
m_dir
blksize
)
-
1
;
tagp
=
(
__be16
*
)((
char
*
)
hdr
+
args
->
geo
->
blksize
)
-
1
;
dup
=
(
xfs_dir2_data_unused_t
*
)((
char
*
)
hdr
+
be16_to_cpu
(
*
tagp
));
/*
* If it's not free or is too short we can't do it.
...
...
@@ -1001,12 +1003,12 @@ xfs_dir2_leaf_to_block(
/*
* Use up the space at the end of the block (blp/btp).
*/
xfs_dir2_data_use_free
(
tp
,
dp
,
dbp
,
dup
,
mp
->
m_dir
blksize
-
size
,
size
,
xfs_dir2_data_use_free
(
args
,
dbp
,
dup
,
args
->
geo
->
blksize
-
size
,
size
,
&
needlog
,
&
needscan
);
/*
* Initialize the block tail.
*/
btp
=
xfs_dir2_block_tail_p
(
mp
,
hdr
);
btp
=
xfs_dir2_block_tail_p
(
args
->
geo
,
hdr
);
btp
->
count
=
cpu_to_be32
(
leafhdr
.
count
-
leafhdr
.
stale
);
btp
->
stale
=
0
;
xfs_dir2_block_log_tail
(
tp
,
dbp
);
...
...
@@ -1027,11 +1029,11 @@ xfs_dir2_leaf_to_block(
if
(
needscan
)
xfs_dir2_data_freescan
(
dp
,
hdr
,
&
needlog
);
if
(
needlog
)
xfs_dir2_data_log_header
(
tp
,
dp
,
dbp
);
xfs_dir2_data_log_header
(
args
,
dbp
);
/*
* Pitch the old leaf block.
*/
error
=
xfs_da_shrink_inode
(
args
,
mp
->
m_dir
leafblk
,
lbp
);
error
=
xfs_da_shrink_inode
(
args
,
args
->
geo
->
leafblk
,
lbp
);
if
(
error
)
return
error
;
...
...
@@ -1140,13 +1142,13 @@ xfs_dir2_sf_to_block(
*/
dup
=
dp
->
d_ops
->
data_unused_p
(
hdr
);
needlog
=
needscan
=
0
;
xfs_dir2_data_use_free
(
tp
,
dp
,
bp
,
dup
,
mp
->
m_dirblksize
-
i
,
i
,
&
needlog
,
&
needscan
);
xfs_dir2_data_use_free
(
args
,
bp
,
dup
,
args
->
geo
->
blksize
-
i
,
i
,
&
needlog
,
&
needscan
);
ASSERT
(
needscan
==
0
);
/*
* Fill in the tail.
*/
btp
=
xfs_dir2_block_tail_p
(
mp
,
hdr
);
btp
=
xfs_dir2_block_tail_p
(
args
->
geo
,
hdr
);
btp
->
count
=
cpu_to_be32
(
sfp
->
count
+
2
);
/* ., .. */
btp
->
stale
=
0
;
blp
=
xfs_dir2_block_leaf_p
(
btp
);
...
...
@@ -1154,7 +1156,7 @@ xfs_dir2_sf_to_block(
/*
* Remove the freespace, we'll manage it.
*/
xfs_dir2_data_use_free
(
tp
,
dp
,
bp
,
dup
,
xfs_dir2_data_use_free
(
args
,
bp
,
dup
,
(
xfs_dir2_data_aoff_t
)((
char
*
)
dup
-
(
char
*
)
hdr
),
be16_to_cpu
(
dup
->
length
),
&
needlog
,
&
needscan
);
/*
...
...
@@ -1167,7 +1169,7 @@ xfs_dir2_sf_to_block(
dp
->
d_ops
->
data_put_ftype
(
dep
,
XFS_DIR3_FT_DIR
);
tagp
=
dp
->
d_ops
->
data_entry_tag_p
(
dep
);
*
tagp
=
cpu_to_be16
((
char
*
)
dep
-
(
char
*
)
hdr
);
xfs_dir2_data_log_entry
(
tp
,
dp
,
bp
,
dep
);
xfs_dir2_data_log_entry
(
args
,
bp
,
dep
);
blp
[
0
].
hashval
=
cpu_to_be32
(
xfs_dir_hash_dot
);
blp
[
0
].
address
=
cpu_to_be32
(
xfs_dir2_byte_to_dataptr
(
(
char
*
)
dep
-
(
char
*
)
hdr
));
...
...
@@ -1181,7 +1183,7 @@ xfs_dir2_sf_to_block(
dp
->
d_ops
->
data_put_ftype
(
dep
,
XFS_DIR3_FT_DIR
);
tagp
=
dp
->
d_ops
->
data_entry_tag_p
(
dep
);
*
tagp
=
cpu_to_be16
((
char
*
)
dep
-
(
char
*
)
hdr
);
xfs_dir2_data_log_entry
(
tp
,
dp
,
bp
,
dep
);
xfs_dir2_data_log_entry
(
args
,
bp
,
dep
);
blp
[
1
].
hashval
=
cpu_to_be32
(
xfs_dir_hash_dotdot
);
blp
[
1
].
address
=
cpu_to_be32
(
xfs_dir2_byte_to_dataptr
(
(
char
*
)
dep
-
(
char
*
)
hdr
));
...
...
@@ -1215,7 +1217,7 @@ xfs_dir2_sf_to_block(
dup
->
length
=
cpu_to_be16
(
newoffset
-
offset
);
*
xfs_dir2_data_unused_tag_p
(
dup
)
=
cpu_to_be16
(
((
char
*
)
dup
-
(
char
*
)
hdr
));
xfs_dir2_data_log_unused
(
tp
,
bp
,
dup
);
xfs_dir2_data_log_unused
(
args
,
bp
,
dup
);
xfs_dir2_data_freeinsert
(
hdr
,
dp
->
d_ops
->
data_bestfree_p
(
hdr
),
dup
,
&
dummy
);
...
...
@@ -1232,7 +1234,7 @@ xfs_dir2_sf_to_block(
memcpy
(
dep
->
name
,
sfep
->
name
,
dep
->
namelen
);
tagp
=
dp
->
d_ops
->
data_entry_tag_p
(
dep
);
*
tagp
=
cpu_to_be16
((
char
*
)
dep
-
(
char
*
)
hdr
);
xfs_dir2_data_log_entry
(
tp
,
dp
,
bp
,
dep
);
xfs_dir2_data_log_entry
(
args
,
bp
,
dep
);
name
.
name
=
sfep
->
name
;
name
.
len
=
sfep
->
namelen
;
blp
[
2
+
i
].
hashval
=
cpu_to_be32
(
mp
->
m_dirnameops
->
...
...
fs/xfs/xfs_dir2_data.c
浏览文件 @
8612c7e5
...
...
@@ -63,8 +63,10 @@ __xfs_dir3_data_check(
int
stale
;
/* count of stale leaves */
struct
xfs_name
name
;
const
struct
xfs_dir_ops
*
ops
;
struct
xfs_da_geometry
*
geo
;
mp
=
bp
->
b_target
->
bt_mount
;
geo
=
mp
->
m_dir_geo
;
/*
* We can be passed a null dp here from a verifier, so we need to go the
...
...
@@ -78,7 +80,7 @@ __xfs_dir3_data_check(
switch
(
hdr
->
magic
)
{
case
cpu_to_be32
(
XFS_DIR3_BLOCK_MAGIC
):
case
cpu_to_be32
(
XFS_DIR2_BLOCK_MAGIC
):
btp
=
xfs_dir2_block_tail_p
(
mp
,
hdr
);
btp
=
xfs_dir2_block_tail_p
(
geo
,
hdr
);
lep
=
xfs_dir2_block_leaf_p
(
btp
);
endp
=
(
char
*
)
lep
;
...
...
@@ -94,7 +96,7 @@ __xfs_dir3_data_check(
break
;
case
cpu_to_be32
(
XFS_DIR3_DATA_MAGIC
):
case
cpu_to_be32
(
XFS_DIR2_DATA_MAGIC
):
endp
=
(
char
*
)
hdr
+
mp
->
m_dir
blksize
;
endp
=
(
char
*
)
hdr
+
geo
->
blksize
;
break
;
default:
XFS_ERROR_REPORT
(
"Bad Magic"
,
XFS_ERRLEVEL_LOW
,
mp
);
...
...
@@ -172,9 +174,9 @@ __xfs_dir3_data_check(
lastfree
=
0
;
if
(
hdr
->
magic
==
cpu_to_be32
(
XFS_DIR2_BLOCK_MAGIC
)
||
hdr
->
magic
==
cpu_to_be32
(
XFS_DIR3_BLOCK_MAGIC
))
{
addr
=
xfs_dir2_db_off_to_dataptr
(
mp
,
mp
->
m_dir
datablk
,
(
xfs_dir2_data_aoff_t
)
((
char
*
)
dep
-
(
char
*
)
hdr
));
addr
=
xfs_dir2_db_off_to_dataptr
(
geo
,
geo
->
datablk
,
(
xfs_dir2_data_aoff_t
)
((
char
*
)
dep
-
(
char
*
)
hdr
));
name
.
name
=
dep
->
name
;
name
.
len
=
dep
->
namelen
;
hash
=
mp
->
m_dirnameops
->
hashname
(
&
name
);
...
...
@@ -509,6 +511,7 @@ xfs_dir2_data_freescan(
struct
xfs_dir2_data_free
*
bf
;
char
*
endp
;
/* end of block's data */
char
*
p
;
/* current entry pointer */
struct
xfs_da_geometry
*
geo
=
dp
->
i_mount
->
m_dir_geo
;
ASSERT
(
hdr
->
magic
==
cpu_to_be32
(
XFS_DIR2_DATA_MAGIC
)
||
hdr
->
magic
==
cpu_to_be32
(
XFS_DIR3_DATA_MAGIC
)
||
...
...
@@ -527,10 +530,10 @@ xfs_dir2_data_freescan(
p
=
(
char
*
)
dp
->
d_ops
->
data_entry_p
(
hdr
);
if
(
hdr
->
magic
==
cpu_to_be32
(
XFS_DIR2_BLOCK_MAGIC
)
||
hdr
->
magic
==
cpu_to_be32
(
XFS_DIR3_BLOCK_MAGIC
))
{
btp
=
xfs_dir2_block_tail_p
(
dp
->
i_mount
,
hdr
);
btp
=
xfs_dir2_block_tail_p
(
geo
,
hdr
);
endp
=
(
char
*
)
xfs_dir2_block_leaf_p
(
btp
);
}
else
endp
=
(
char
*
)
hdr
+
dp
->
i_mount
->
m_dir
blksize
;
endp
=
(
char
*
)
hdr
+
geo
->
blksize
;
/*
* Loop over the block's entries.
*/
...
...
@@ -584,8 +587,8 @@ xfs_dir3_data_init(
/*
* Get the buffer set up for the block.
*/
error
=
xfs_da_get_buf
(
tp
,
dp
,
xfs_dir2_db_to_da
(
mp
,
blkno
),
-
1
,
&
bp
,
XFS_DATA_FORK
);
error
=
xfs_da_get_buf
(
tp
,
dp
,
xfs_dir2_db_to_da
(
args
->
geo
,
blkno
)
,
-
1
,
&
bp
,
XFS_DATA_FORK
);
if
(
error
)
return
error
;
bp
->
b_ops
=
&
xfs_dir3_data_buf_ops
;
...
...
@@ -620,15 +623,15 @@ xfs_dir3_data_init(
dup
=
dp
->
d_ops
->
data_unused_p
(
hdr
);
dup
->
freetag
=
cpu_to_be16
(
XFS_DIR2_DATA_FREE_TAG
);
t
=
mp
->
m_dir
blksize
-
(
uint
)
dp
->
d_ops
->
data_entry_offset
;
t
=
args
->
geo
->
blksize
-
(
uint
)
dp
->
d_ops
->
data_entry_offset
;
bf
[
0
].
length
=
cpu_to_be16
(
t
);
dup
->
length
=
cpu_to_be16
(
t
);
*
xfs_dir2_data_unused_tag_p
(
dup
)
=
cpu_to_be16
((
char
*
)
dup
-
(
char
*
)
hdr
);
/*
* Log it and return it.
*/
xfs_dir2_data_log_header
(
tp
,
dp
,
bp
);
xfs_dir2_data_log_unused
(
tp
,
bp
,
dup
);
xfs_dir2_data_log_header
(
args
,
bp
);
xfs_dir2_data_log_unused
(
args
,
bp
,
dup
);
*
bpp
=
bp
;
return
0
;
}
...
...
@@ -638,8 +641,7 @@ xfs_dir3_data_init(
*/
void
xfs_dir2_data_log_entry
(
struct
xfs_trans
*
tp
,
struct
xfs_inode
*
dp
,
struct
xfs_da_args
*
args
,
struct
xfs_buf
*
bp
,
xfs_dir2_data_entry_t
*
dep
)
/* data entry pointer */
{
...
...
@@ -650,8 +652,8 @@ xfs_dir2_data_log_entry(
hdr
->
magic
==
cpu_to_be32
(
XFS_DIR2_BLOCK_MAGIC
)
||
hdr
->
magic
==
cpu_to_be32
(
XFS_DIR3_BLOCK_MAGIC
));
xfs_trans_log_buf
(
tp
,
bp
,
(
uint
)((
char
*
)
dep
-
(
char
*
)
hdr
),
(
uint
)((
char
*
)(
dp
->
d_ops
->
data_entry_tag_p
(
dep
)
+
1
)
-
xfs_trans_log_buf
(
args
->
trans
,
bp
,
(
uint
)((
char
*
)
dep
-
(
char
*
)
hdr
),
(
uint
)((
char
*
)(
args
->
dp
->
d_ops
->
data_entry_tag_p
(
dep
)
+
1
)
-
(
char
*
)
hdr
-
1
));
}
...
...
@@ -660,8 +662,7 @@ xfs_dir2_data_log_entry(
*/
void
xfs_dir2_data_log_header
(
struct
xfs_trans
*
tp
,
struct
xfs_inode
*
dp
,
struct
xfs_da_args
*
args
,
struct
xfs_buf
*
bp
)
{
#ifdef DEBUG
...
...
@@ -673,7 +674,8 @@ xfs_dir2_data_log_header(
hdr
->
magic
==
cpu_to_be32
(
XFS_DIR3_BLOCK_MAGIC
));
#endif
xfs_trans_log_buf
(
tp
,
bp
,
0
,
dp
->
d_ops
->
data_entry_offset
-
1
);
xfs_trans_log_buf
(
args
->
trans
,
bp
,
0
,
args
->
dp
->
d_ops
->
data_entry_offset
-
1
);
}
/*
...
...
@@ -681,7 +683,7 @@ xfs_dir2_data_log_header(
*/
void
xfs_dir2_data_log_unused
(
struct
xfs_
trans
*
tp
,
struct
xfs_
da_args
*
args
,
struct
xfs_buf
*
bp
,
xfs_dir2_data_unused_t
*
dup
)
/* data unused pointer */
{
...
...
@@ -695,13 +697,13 @@ xfs_dir2_data_log_unused(
/*
* Log the first part of the unused entry.
*/
xfs_trans_log_buf
(
tp
,
bp
,
(
uint
)((
char
*
)
dup
-
(
char
*
)
hdr
),
xfs_trans_log_buf
(
args
->
trans
,
bp
,
(
uint
)((
char
*
)
dup
-
(
char
*
)
hdr
),
(
uint
)((
char
*
)
&
dup
->
length
+
sizeof
(
dup
->
length
)
-
1
-
(
char
*
)
hdr
));
/*
* Log the end (tag) of the unused entry.
*/
xfs_trans_log_buf
(
tp
,
bp
,
xfs_trans_log_buf
(
args
->
trans
,
bp
,
(
uint
)((
char
*
)
xfs_dir2_data_unused_tag_p
(
dup
)
-
(
char
*
)
hdr
),
(
uint
)((
char
*
)
xfs_dir2_data_unused_tag_p
(
dup
)
-
(
char
*
)
hdr
+
sizeof
(
xfs_dir2_data_off_t
)
-
1
));
...
...
@@ -713,8 +715,7 @@ xfs_dir2_data_log_unused(
*/
void
xfs_dir2_data_make_free
(
struct
xfs_trans
*
tp
,
struct
xfs_inode
*
dp
,
struct
xfs_da_args
*
args
,
struct
xfs_buf
*
bp
,
xfs_dir2_data_aoff_t
offset
,
/* starting byte offset */
xfs_dir2_data_aoff_t
len
,
/* length in bytes */
...
...
@@ -724,14 +725,12 @@ xfs_dir2_data_make_free(
xfs_dir2_data_hdr_t
*
hdr
;
/* data block pointer */
xfs_dir2_data_free_t
*
dfp
;
/* bestfree pointer */
char
*
endptr
;
/* end of data area */
xfs_mount_t
*
mp
;
/* filesystem mount point */
int
needscan
;
/* need to regen bestfree */
xfs_dir2_data_unused_t
*
newdup
;
/* new unused entry */
xfs_dir2_data_unused_t
*
postdup
;
/* unused entry after us */
xfs_dir2_data_unused_t
*
prevdup
;
/* unused entry before us */
struct
xfs_dir2_data_free
*
bf
;
mp
=
tp
->
t_mountp
;
hdr
=
bp
->
b_addr
;
/*
...
...
@@ -739,20 +738,20 @@ xfs_dir2_data_make_free(
*/
if
(
hdr
->
magic
==
cpu_to_be32
(
XFS_DIR2_DATA_MAGIC
)
||
hdr
->
magic
==
cpu_to_be32
(
XFS_DIR3_DATA_MAGIC
))
endptr
=
(
char
*
)
hdr
+
mp
->
m_dir
blksize
;
endptr
=
(
char
*
)
hdr
+
args
->
geo
->
blksize
;
else
{
xfs_dir2_block_tail_t
*
btp
;
/* block tail */
ASSERT
(
hdr
->
magic
==
cpu_to_be32
(
XFS_DIR2_BLOCK_MAGIC
)
||
hdr
->
magic
==
cpu_to_be32
(
XFS_DIR3_BLOCK_MAGIC
));
btp
=
xfs_dir2_block_tail_p
(
mp
,
hdr
);
btp
=
xfs_dir2_block_tail_p
(
args
->
geo
,
hdr
);
endptr
=
(
char
*
)
xfs_dir2_block_leaf_p
(
btp
);
}
/*
* If this isn't the start of the block, then back up to
* the previous entry and see if it's free.
*/
if
(
offset
>
dp
->
d_ops
->
data_entry_offset
)
{
if
(
offset
>
args
->
dp
->
d_ops
->
data_entry_offset
)
{
__be16
*
tagp
;
/* tag just before us */
tagp
=
(
__be16
*
)((
char
*
)
hdr
+
offset
)
-
1
;
...
...
@@ -778,7 +777,7 @@ xfs_dir2_data_make_free(
* Previous and following entries are both free,
* merge everything into a single free entry.
*/
bf
=
dp
->
d_ops
->
data_bestfree_p
(
hdr
);
bf
=
args
->
dp
->
d_ops
->
data_bestfree_p
(
hdr
);
if
(
prevdup
&&
postdup
)
{
xfs_dir2_data_free_t
*
dfp2
;
/* another bestfree pointer */
...
...
@@ -800,7 +799,7 @@ xfs_dir2_data_make_free(
be16_add_cpu
(
&
prevdup
->
length
,
len
+
be16_to_cpu
(
postdup
->
length
));
*
xfs_dir2_data_unused_tag_p
(
prevdup
)
=
cpu_to_be16
((
char
*
)
prevdup
-
(
char
*
)
hdr
);
xfs_dir2_data_log_unused
(
tp
,
bp
,
prevdup
);
xfs_dir2_data_log_unused
(
args
,
bp
,
prevdup
);
if
(
!
needscan
)
{
/*
* Has to be the case that entries 0 and 1 are
...
...
@@ -835,7 +834,7 @@ xfs_dir2_data_make_free(
be16_add_cpu
(
&
prevdup
->
length
,
len
);
*
xfs_dir2_data_unused_tag_p
(
prevdup
)
=
cpu_to_be16
((
char
*
)
prevdup
-
(
char
*
)
hdr
);
xfs_dir2_data_log_unused
(
tp
,
bp
,
prevdup
);
xfs_dir2_data_log_unused
(
args
,
bp
,
prevdup
);
/*
* If the previous entry was in the table, the new entry
* is longer, so it will be in the table too. Remove
...
...
@@ -863,7 +862,7 @@ xfs_dir2_data_make_free(
newdup
->
length
=
cpu_to_be16
(
len
+
be16_to_cpu
(
postdup
->
length
));
*
xfs_dir2_data_unused_tag_p
(
newdup
)
=
cpu_to_be16
((
char
*
)
newdup
-
(
char
*
)
hdr
);
xfs_dir2_data_log_unused
(
tp
,
bp
,
newdup
);
xfs_dir2_data_log_unused
(
args
,
bp
,
newdup
);
/*
* If the following entry was in the table, the new entry
* is longer, so it will be in the table too. Remove
...
...
@@ -890,7 +889,7 @@ xfs_dir2_data_make_free(
newdup
->
length
=
cpu_to_be16
(
len
);
*
xfs_dir2_data_unused_tag_p
(
newdup
)
=
cpu_to_be16
((
char
*
)
newdup
-
(
char
*
)
hdr
);
xfs_dir2_data_log_unused
(
tp
,
bp
,
newdup
);
xfs_dir2_data_log_unused
(
args
,
bp
,
newdup
);
xfs_dir2_data_freeinsert
(
hdr
,
bf
,
newdup
,
needlogp
);
}
*
needscanp
=
needscan
;
...
...
@@ -901,8 +900,7 @@ xfs_dir2_data_make_free(
*/
void
xfs_dir2_data_use_free
(
struct
xfs_trans
*
tp
,
struct
xfs_inode
*
dp
,
struct
xfs_da_args
*
args
,
struct
xfs_buf
*
bp
,
xfs_dir2_data_unused_t
*
dup
,
/* unused entry */
xfs_dir2_data_aoff_t
offset
,
/* starting offset to use */
...
...
@@ -933,7 +931,7 @@ xfs_dir2_data_use_free(
* Look up the entry in the bestfree table.
*/
oldlen
=
be16_to_cpu
(
dup
->
length
);
bf
=
dp
->
d_ops
->
data_bestfree_p
(
hdr
);
bf
=
args
->
dp
->
d_ops
->
data_bestfree_p
(
hdr
);
dfp
=
xfs_dir2_data_freefind
(
hdr
,
bf
,
dup
);
ASSERT
(
dfp
||
oldlen
<=
be16_to_cpu
(
bf
[
2
].
length
));
/*
...
...
@@ -965,7 +963,7 @@ xfs_dir2_data_use_free(
newdup
->
length
=
cpu_to_be16
(
oldlen
-
len
);
*
xfs_dir2_data_unused_tag_p
(
newdup
)
=
cpu_to_be16
((
char
*
)
newdup
-
(
char
*
)
hdr
);
xfs_dir2_data_log_unused
(
tp
,
bp
,
newdup
);
xfs_dir2_data_log_unused
(
args
,
bp
,
newdup
);
/*
* If it was in the table, remove it and add the new one.
*/
...
...
@@ -993,7 +991,7 @@ xfs_dir2_data_use_free(
newdup
->
length
=
cpu_to_be16
(((
char
*
)
hdr
+
offset
)
-
(
char
*
)
newdup
);
*
xfs_dir2_data_unused_tag_p
(
newdup
)
=
cpu_to_be16
((
char
*
)
newdup
-
(
char
*
)
hdr
);
xfs_dir2_data_log_unused
(
tp
,
bp
,
newdup
);
xfs_dir2_data_log_unused
(
args
,
bp
,
newdup
);
/*
* If it was in the table, remove it and add the new one.
*/
...
...
@@ -1021,13 +1019,13 @@ xfs_dir2_data_use_free(
newdup
->
length
=
cpu_to_be16
(((
char
*
)
hdr
+
offset
)
-
(
char
*
)
newdup
);
*
xfs_dir2_data_unused_tag_p
(
newdup
)
=
cpu_to_be16
((
char
*
)
newdup
-
(
char
*
)
hdr
);
xfs_dir2_data_log_unused
(
tp
,
bp
,
newdup
);
xfs_dir2_data_log_unused
(
args
,
bp
,
newdup
);
newdup2
=
(
xfs_dir2_data_unused_t
*
)((
char
*
)
hdr
+
offset
+
len
);
newdup2
->
freetag
=
cpu_to_be16
(
XFS_DIR2_DATA_FREE_TAG
);
newdup2
->
length
=
cpu_to_be16
(
oldlen
-
len
-
be16_to_cpu
(
newdup
->
length
));
*
xfs_dir2_data_unused_tag_p
(
newdup2
)
=
cpu_to_be16
((
char
*
)
newdup2
-
(
char
*
)
hdr
);
xfs_dir2_data_log_unused
(
tp
,
bp
,
newdup2
);
xfs_dir2_data_log_unused
(
args
,
bp
,
newdup2
);
/*
* If the old entry was in the table, we need to scan
* if the 3rd entry was valid, since these entries
...
...
fs/xfs/xfs_dir2_leaf.c
浏览文件 @
8612c7e5
此差异已折叠。
点击以展开。
fs/xfs/xfs_dir2_node.c
浏览文件 @
8612c7e5
此差异已折叠。
点击以展开。
fs/xfs/xfs_dir2_priv.h
浏览文件 @
8612c7e5
...
...
@@ -20,6 +20,140 @@
struct
dir_context
;
/*
* Directory offset/block conversion functions.
*
* DB blocks here are logical directory block numbers, not filesystem blocks.
*/
/*
* Convert dataptr to byte in file space
*/
static
inline
xfs_dir2_off_t
xfs_dir2_dataptr_to_byte
(
xfs_dir2_dataptr_t
dp
)
{
return
(
xfs_dir2_off_t
)
dp
<<
XFS_DIR2_DATA_ALIGN_LOG
;
}
/*
* Convert byte in file space to dataptr. It had better be aligned.
*/
static
inline
xfs_dir2_dataptr_t
xfs_dir2_byte_to_dataptr
(
xfs_dir2_off_t
by
)
{
return
(
xfs_dir2_dataptr_t
)(
by
>>
XFS_DIR2_DATA_ALIGN_LOG
);
}
/*
* Convert byte in space to (DB) block
*/
static
inline
xfs_dir2_db_t
xfs_dir2_byte_to_db
(
struct
xfs_da_geometry
*
geo
,
xfs_dir2_off_t
by
)
{
return
(
xfs_dir2_db_t
)(
by
>>
geo
->
blklog
);
}
/*
* Convert dataptr to a block number
*/
static
inline
xfs_dir2_db_t
xfs_dir2_dataptr_to_db
(
struct
xfs_da_geometry
*
geo
,
xfs_dir2_dataptr_t
dp
)
{
return
xfs_dir2_byte_to_db
(
geo
,
xfs_dir2_dataptr_to_byte
(
dp
));
}
/*
* Convert byte in space to offset in a block
*/
static
inline
xfs_dir2_data_aoff_t
xfs_dir2_byte_to_off
(
struct
xfs_da_geometry
*
geo
,
xfs_dir2_off_t
by
)
{
return
(
xfs_dir2_data_aoff_t
)(
by
&
(
geo
->
blksize
-
1
));
}
/*
* Convert dataptr to a byte offset in a block
*/
static
inline
xfs_dir2_data_aoff_t
xfs_dir2_dataptr_to_off
(
struct
xfs_da_geometry
*
geo
,
xfs_dir2_dataptr_t
dp
)
{
return
xfs_dir2_byte_to_off
(
geo
,
xfs_dir2_dataptr_to_byte
(
dp
));
}
/*
* Convert block and offset to byte in space
*/
static
inline
xfs_dir2_off_t
xfs_dir2_db_off_to_byte
(
struct
xfs_da_geometry
*
geo
,
xfs_dir2_db_t
db
,
xfs_dir2_data_aoff_t
o
)
{
return
((
xfs_dir2_off_t
)
db
<<
geo
->
blklog
)
+
o
;
}
/*
* Convert block (DB) to block (dablk)
*/
static
inline
xfs_dablk_t
xfs_dir2_db_to_da
(
struct
xfs_da_geometry
*
geo
,
xfs_dir2_db_t
db
)
{
return
(
xfs_dablk_t
)(
db
<<
(
geo
->
blklog
-
geo
->
fsblog
));
}
/*
* Convert byte in space to (DA) block
*/
static
inline
xfs_dablk_t
xfs_dir2_byte_to_da
(
struct
xfs_da_geometry
*
geo
,
xfs_dir2_off_t
by
)
{
return
xfs_dir2_db_to_da
(
geo
,
xfs_dir2_byte_to_db
(
geo
,
by
));
}
/*
* Convert block and offset to dataptr
*/
static
inline
xfs_dir2_dataptr_t
xfs_dir2_db_off_to_dataptr
(
struct
xfs_da_geometry
*
geo
,
xfs_dir2_db_t
db
,
xfs_dir2_data_aoff_t
o
)
{
return
xfs_dir2_byte_to_dataptr
(
xfs_dir2_db_off_to_byte
(
geo
,
db
,
o
));
}
/*
* Convert block (dablk) to block (DB)
*/
static
inline
xfs_dir2_db_t
xfs_dir2_da_to_db
(
struct
xfs_da_geometry
*
geo
,
xfs_dablk_t
da
)
{
return
(
xfs_dir2_db_t
)(
da
>>
(
geo
->
blklog
-
geo
->
fsblog
));
}
/*
* Convert block (dablk) to byte offset in space
*/
static
inline
xfs_dir2_off_t
xfs_dir2_da_to_byte
(
struct
xfs_da_geometry
*
geo
,
xfs_dablk_t
da
)
{
return
xfs_dir2_db_off_to_byte
(
geo
,
xfs_dir2_da_to_db
(
geo
,
da
),
0
);
}
/*
* Directory tail pointer accessor functions. Based on block geometry.
*/
static
inline
struct
xfs_dir2_block_tail
*
xfs_dir2_block_tail_p
(
struct
xfs_da_geometry
*
geo
,
struct
xfs_dir2_data_hdr
*
hdr
)
{
return
((
struct
xfs_dir2_block_tail
*
)
((
char
*
)
hdr
+
geo
->
blksize
))
-
1
;
}
static
inline
struct
xfs_dir2_leaf_tail
*
xfs_dir2_leaf_tail_p
(
struct
xfs_da_geometry
*
geo
,
struct
xfs_dir2_leaf
*
lp
)
{
return
(
struct
xfs_dir2_leaf_tail
*
)
((
char
*
)
lp
+
geo
->
blksize
-
sizeof
(
struct
xfs_dir2_leaf_tail
));
}
/* xfs_dir2.c */
extern
int
xfs_dir_ino_validate
(
struct
xfs_mount
*
mp
,
xfs_ino_t
ino
);
extern
int
xfs_dir2_grow_inode
(
struct
xfs_da_args
*
args
,
int
space
,
...
...
@@ -77,9 +211,9 @@ extern void xfs_dir3_leaf_compact_x1(struct xfs_dir3_icleaf_hdr *leafhdr,
int
*
lowstalep
,
int
*
highstalep
,
int
*
lowlogp
,
int
*
highlogp
);
extern
int
xfs_dir3_leaf_get_buf
(
struct
xfs_da_args
*
args
,
xfs_dir2_db_t
bno
,
struct
xfs_buf
**
bpp
,
__uint16_t
magic
);
extern
void
xfs_dir3_leaf_log_ents
(
struct
xfs_
trans
*
tp
,
struct
xfs_inode
*
dp
,
extern
void
xfs_dir3_leaf_log_ents
(
struct
xfs_
da_args
*
args
,
struct
xfs_buf
*
bp
,
int
first
,
int
last
);
extern
void
xfs_dir3_leaf_log_header
(
struct
xfs_
trans
*
tp
,
struct
xfs_inode
*
dp
,
extern
void
xfs_dir3_leaf_log_header
(
struct
xfs_
da_args
*
args
,
struct
xfs_buf
*
bp
);
extern
int
xfs_dir2_leaf_lookup
(
struct
xfs_da_args
*
args
);
extern
int
xfs_dir2_leaf_removename
(
struct
xfs_da_args
*
args
);
...
...
fs/xfs/xfs_dir2_readdir.c
浏览文件 @
8612c7e5
...
...
@@ -76,26 +76,25 @@ const unsigned char xfs_mode_to_ftype[S_IFMT >> S_SHIFT] = {
STATIC
int
xfs_dir2_sf_getdents
(
xfs_inode_t
*
dp
,
/* incore directory inode */
struct
xfs_da_args
*
args
,
struct
dir_context
*
ctx
)
{
int
i
;
/* shortform entry number */
xfs_mount_t
*
mp
;
/* filesystem mount point
*/
struct
xfs_inode
*
dp
=
args
->
dp
;
/* incore directory inode
*/
xfs_dir2_dataptr_t
off
;
/* current entry's offset */
xfs_dir2_sf_entry_t
*
sfep
;
/* shortform directory entry */
xfs_dir2_sf_hdr_t
*
sfp
;
/* shortform structure */
xfs_dir2_dataptr_t
dot_offset
;
xfs_dir2_dataptr_t
dotdot_offset
;
xfs_ino_t
ino
;
mp
=
dp
->
i_mount
;
struct
xfs_da_geometry
*
geo
=
args
->
geo
;
ASSERT
(
dp
->
i_df
.
if_flags
&
XFS_IFINLINE
);
/*
* Give up if the directory is way too short.
*/
if
(
dp
->
i_d
.
di_size
<
offsetof
(
xfs_dir2_sf_hdr_t
,
parent
))
{
ASSERT
(
XFS_FORCED_SHUTDOWN
(
mp
));
ASSERT
(
XFS_FORCED_SHUTDOWN
(
dp
->
i_mount
));
return
XFS_ERROR
(
EIO
);
}
...
...
@@ -109,18 +108,18 @@ xfs_dir2_sf_getdents(
/*
* If the block number in the offset is out of range, we're done.
*/
if
(
xfs_dir2_dataptr_to_db
(
mp
,
ctx
->
pos
)
>
mp
->
m_dir
datablk
)
if
(
xfs_dir2_dataptr_to_db
(
geo
,
ctx
->
pos
)
>
geo
->
datablk
)
return
0
;
/*
* Precalculate offsets for . and .. as we will always need them.
*
* XXX(hch): the second argument is sometimes 0 and sometimes
*
mp->m_dirdatablk.
*
geo->datablk
*/
dot_offset
=
xfs_dir2_db_off_to_dataptr
(
mp
,
mp
->
m_dir
datablk
,
dot_offset
=
xfs_dir2_db_off_to_dataptr
(
geo
,
geo
->
datablk
,
dp
->
d_ops
->
data_dot_offset
);
dotdot_offset
=
xfs_dir2_db_off_to_dataptr
(
mp
,
mp
->
m_dir
datablk
,
dotdot_offset
=
xfs_dir2_db_off_to_dataptr
(
geo
,
geo
->
datablk
,
dp
->
d_ops
->
data_dotdot_offset
);
/*
...
...
@@ -149,7 +148,7 @@ xfs_dir2_sf_getdents(
for
(
i
=
0
;
i
<
sfp
->
count
;
i
++
)
{
__uint8_t
filetype
;
off
=
xfs_dir2_db_off_to_dataptr
(
mp
,
mp
->
m_dir
datablk
,
off
=
xfs_dir2_db_off_to_dataptr
(
geo
,
geo
->
datablk
,
xfs_dir2_sf_get_offset
(
sfep
));
if
(
ctx
->
pos
>
off
)
{
...
...
@@ -161,13 +160,13 @@ xfs_dir2_sf_getdents(
filetype
=
dp
->
d_ops
->
sf_get_ftype
(
sfep
);
ctx
->
pos
=
off
&
0x7fffffff
;
if
(
!
dir_emit
(
ctx
,
(
char
*
)
sfep
->
name
,
sfep
->
namelen
,
ino
,
xfs_dir3_get_dtype
(
mp
,
filetype
)))
xfs_dir3_get_dtype
(
dp
->
i_mount
,
filetype
)))
return
0
;
sfep
=
dp
->
d_ops
->
sf_nextentry
(
sfp
,
sfep
);
}
ctx
->
pos
=
xfs_dir2_db_off_to_dataptr
(
mp
,
mp
->
m_dir
datablk
+
1
,
0
)
&
0x7fffffff
;
ctx
->
pos
=
xfs_dir2_db_off_to_dataptr
(
geo
,
geo
->
datablk
+
1
,
0
)
&
0x7fffffff
;
return
0
;
}
...
...
@@ -176,9 +175,10 @@ xfs_dir2_sf_getdents(
*/
STATIC
int
xfs_dir2_block_getdents
(
xfs_inode_t
*
dp
,
/* incore inode */
struct
xfs_da_args
*
args
,
struct
dir_context
*
ctx
)
{
struct
xfs_inode
*
dp
=
args
->
dp
;
/* incore directory inode */
xfs_dir2_data_hdr_t
*
hdr
;
/* block header */
struct
xfs_buf
*
bp
;
/* buffer for block */
xfs_dir2_block_tail_t
*
btp
;
/* block tail */
...
...
@@ -186,16 +186,15 @@ xfs_dir2_block_getdents(
xfs_dir2_data_unused_t
*
dup
;
/* block unused entry */
char
*
endptr
;
/* end of the data entries */
int
error
;
/* error return value */
xfs_mount_t
*
mp
;
/* filesystem mount point */
char
*
ptr
;
/* current data entry */
int
wantoff
;
/* starting block offset */
xfs_off_t
cook
;
struct
xfs_da_geometry
*
geo
=
args
->
geo
;
mp
=
dp
->
i_mount
;
/*
* If the block number in the offset is out of range, we're done.
*/
if
(
xfs_dir2_dataptr_to_db
(
mp
,
ctx
->
pos
)
>
mp
->
m_dir
datablk
)
if
(
xfs_dir2_dataptr_to_db
(
geo
,
ctx
->
pos
)
>
geo
->
datablk
)
return
0
;
error
=
xfs_dir3_block_read
(
NULL
,
dp
,
&
bp
);
...
...
@@ -206,13 +205,13 @@ xfs_dir2_block_getdents(
* Extract the byte offset we start at from the seek pointer.
* We'll skip entries before this.
*/
wantoff
=
xfs_dir2_dataptr_to_off
(
mp
,
ctx
->
pos
);
wantoff
=
xfs_dir2_dataptr_to_off
(
geo
,
ctx
->
pos
);
hdr
=
bp
->
b_addr
;
xfs_dir3_data_check
(
dp
,
bp
);
/*
* Set up values for the loop.
*/
btp
=
xfs_dir2_block_tail_p
(
mp
,
hdr
);
btp
=
xfs_dir2_block_tail_p
(
geo
,
hdr
);
ptr
=
(
char
*
)
dp
->
d_ops
->
data_entry_p
(
hdr
);
endptr
=
(
char
*
)
xfs_dir2_block_leaf_p
(
btp
);
...
...
@@ -244,7 +243,7 @@ xfs_dir2_block_getdents(
if
((
char
*
)
dep
-
(
char
*
)
hdr
<
wantoff
)
continue
;
cook
=
xfs_dir2_db_off_to_dataptr
(
mp
,
mp
->
m_dir
datablk
,
cook
=
xfs_dir2_db_off_to_dataptr
(
geo
,
geo
->
datablk
,
(
char
*
)
dep
-
(
char
*
)
hdr
);
ctx
->
pos
=
cook
&
0x7fffffff
;
...
...
@@ -254,7 +253,7 @@ xfs_dir2_block_getdents(
*/
if
(
!
dir_emit
(
ctx
,
(
char
*
)
dep
->
name
,
dep
->
namelen
,
be64_to_cpu
(
dep
->
inumber
),
xfs_dir3_get_dtype
(
mp
,
filetype
)))
{
xfs_dir3_get_dtype
(
dp
->
i_mount
,
filetype
)))
{
xfs_trans_brelse
(
NULL
,
bp
);
return
0
;
}
...
...
@@ -264,8 +263,8 @@ xfs_dir2_block_getdents(
* Reached the end of the block.
* Set the offset to a non-existent block 1 and return.
*/
ctx
->
pos
=
xfs_dir2_db_off_to_dataptr
(
mp
,
mp
->
m_dir
datablk
+
1
,
0
)
&
0x7fffffff
;
ctx
->
pos
=
xfs_dir2_db_off_to_dataptr
(
geo
,
geo
->
datablk
+
1
,
0
)
&
0x7fffffff
;
xfs_trans_brelse
(
NULL
,
bp
);
return
0
;
}
...
...
@@ -286,13 +285,13 @@ struct xfs_dir2_leaf_map_info {
STATIC
int
xfs_dir2_leaf_readbuf
(
struct
xfs_
inode
*
dp
,
struct
xfs_
da_args
*
args
,
size_t
bufsize
,
struct
xfs_dir2_leaf_map_info
*
mip
,
xfs_dir2_off_t
*
curoff
,
struct
xfs_buf
**
bpp
)
{
struct
xfs_
mount
*
mp
=
dp
->
i_mount
;
struct
xfs_
inode
*
dp
=
args
->
dp
;
struct
xfs_buf
*
bp
=
*
bpp
;
struct
xfs_bmbt_irec
*
map
=
mip
->
map
;
struct
blk_plug
plug
;
...
...
@@ -300,6 +299,7 @@ xfs_dir2_leaf_readbuf(
int
length
;
int
i
;
int
j
;
struct
xfs_da_geometry
*
geo
=
args
->
geo
;
/*
* If we have a buffer, we need to release it and
...
...
@@ -309,12 +309,12 @@ xfs_dir2_leaf_readbuf(
if
(
bp
)
{
xfs_trans_brelse
(
NULL
,
bp
);
bp
=
NULL
;
mip
->
map_blocks
-=
mp
->
m_dirblkfsbs
;
mip
->
map_blocks
-=
geo
->
fsbcount
;
/*
* Loop to get rid of the extents for the
* directory block.
*/
for
(
i
=
mp
->
m_dirblkfsbs
;
i
>
0
;
)
{
for
(
i
=
geo
->
fsbcount
;
i
>
0
;
)
{
j
=
min_t
(
int
,
map
->
br_blockcount
,
i
);
map
->
br_blockcount
-=
j
;
map
->
br_startblock
+=
j
;
...
...
@@ -333,8 +333,7 @@ xfs_dir2_leaf_readbuf(
/*
* Recalculate the readahead blocks wanted.
*/
mip
->
ra_want
=
howmany
(
bufsize
+
mp
->
m_dirblksize
,
mp
->
m_sb
.
sb_blocksize
)
-
1
;
mip
->
ra_want
=
howmany
(
bufsize
+
geo
->
blksize
,
(
1
<<
geo
->
fsblog
))
-
1
;
ASSERT
(
mip
->
ra_want
>=
0
);
/*
...
...
@@ -342,14 +341,14 @@ xfs_dir2_leaf_readbuf(
* run out of data blocks, get some more mappings.
*/
if
(
1
+
mip
->
ra_want
>
mip
->
map_blocks
&&
mip
->
map_off
<
xfs_dir2_byte_to_da
(
mp
,
XFS_DIR2_LEAF_OFFSET
))
{
mip
->
map_off
<
xfs_dir2_byte_to_da
(
geo
,
XFS_DIR2_LEAF_OFFSET
))
{
/*
* Get more bmaps, fill in after the ones
* we already have in the table.
*/
mip
->
nmap
=
mip
->
map_size
-
mip
->
map_valid
;
error
=
xfs_bmapi_read
(
dp
,
mip
->
map_off
,
xfs_dir2_byte_to_da
(
mp
,
XFS_DIR2_LEAF_OFFSET
)
-
xfs_dir2_byte_to_da
(
geo
,
XFS_DIR2_LEAF_OFFSET
)
-
mip
->
map_off
,
&
map
[
mip
->
map_valid
],
&
mip
->
nmap
,
0
);
...
...
@@ -370,7 +369,7 @@ xfs_dir2_leaf_readbuf(
i
=
mip
->
map_valid
+
mip
->
nmap
-
1
;
mip
->
map_off
=
map
[
i
].
br_startoff
+
map
[
i
].
br_blockcount
;
}
else
mip
->
map_off
=
xfs_dir2_byte_to_da
(
mp
,
mip
->
map_off
=
xfs_dir2_byte_to_da
(
geo
,
XFS_DIR2_LEAF_OFFSET
);
/*
...
...
@@ -396,18 +395,18 @@ xfs_dir2_leaf_readbuf(
* No valid mappings, so no more data blocks.
*/
if
(
!
mip
->
map_valid
)
{
*
curoff
=
xfs_dir2_da_to_byte
(
mp
,
mip
->
map_off
);
*
curoff
=
xfs_dir2_da_to_byte
(
geo
,
mip
->
map_off
);
goto
out
;
}
/*
* Read the directory block starting at the first mapping.
*/
mip
->
curdb
=
xfs_dir2_da_to_db
(
mp
,
map
->
br_startoff
);
mip
->
curdb
=
xfs_dir2_da_to_db
(
geo
,
map
->
br_startoff
);
error
=
xfs_dir3_data_read
(
NULL
,
dp
,
map
->
br_startoff
,
map
->
br_blockcount
>=
mp
->
m_dirblkfsbs
?
XFS_FSB_TO_DADDR
(
mp
,
map
->
br_startblock
)
:
-
1
,
&
bp
);
map
->
br_blockcount
>=
geo
->
fsbcount
?
XFS_FSB_TO_DADDR
(
dp
->
i_mount
,
map
->
br_startblock
)
:
-
1
,
&
bp
);
/*
* Should just skip over the data block instead of giving up.
*/
...
...
@@ -419,7 +418,7 @@ xfs_dir2_leaf_readbuf(
* was previously ra.
*/
if
(
mip
->
ra_current
)
mip
->
ra_current
-=
mp
->
m_dirblkfsbs
;
mip
->
ra_current
-=
geo
->
fsbcount
;
/*
* Do we need more readahead?
...
...
@@ -427,16 +426,16 @@ xfs_dir2_leaf_readbuf(
blk_start_plug
(
&
plug
);
for
(
mip
->
ra_index
=
mip
->
ra_offset
=
i
=
0
;
mip
->
ra_want
>
mip
->
ra_current
&&
i
<
mip
->
map_blocks
;
i
+=
mp
->
m_dirblkfsbs
)
{
i
+=
geo
->
fsbcount
)
{
ASSERT
(
mip
->
ra_index
<
mip
->
map_valid
);
/*
* Read-ahead a contiguous directory block.
*/
if
(
i
>
mip
->
ra_current
&&
map
[
mip
->
ra_index
].
br_blockcount
>=
mp
->
m_dirblkfsbs
)
{
map
[
mip
->
ra_index
].
br_blockcount
>=
geo
->
fsbcount
)
{
xfs_dir3_data_readahead
(
dp
,
map
[
mip
->
ra_index
].
br_startoff
+
mip
->
ra_offset
,
XFS_FSB_TO_DADDR
(
mp
,
XFS_FSB_TO_DADDR
(
dp
->
i_mount
,
map
[
mip
->
ra_index
].
br_startblock
+
mip
->
ra_offset
));
mip
->
ra_current
=
i
;
...
...
@@ -456,12 +455,12 @@ xfs_dir2_leaf_readbuf(
/*
* Advance offset through the mapping table.
*/
for
(
j
=
0
;
j
<
mp
->
m_dirblkfsbs
;
j
+=
length
)
{
for
(
j
=
0
;
j
<
geo
->
fsbcount
;
j
+=
length
)
{
/*
* The rest of this extent but not more than a dir
* block.
*/
length
=
min_t
(
int
,
mp
->
m_dirblkfsbs
,
length
=
min_t
(
int
,
geo
->
fsbcount
,
map
[
mip
->
ra_index
].
br_blockcount
-
mip
->
ra_offset
);
mip
->
ra_offset
+=
length
;
...
...
@@ -488,22 +487,23 @@ xfs_dir2_leaf_readbuf(
*/
STATIC
int
xfs_dir2_leaf_getdents
(
xfs_inode_t
*
dp
,
/* incore directory inode */
struct
xfs_da_args
*
args
,
struct
dir_context
*
ctx
,
size_t
bufsize
)
{
struct
xfs_inode
*
dp
=
args
->
dp
;
struct
xfs_buf
*
bp
=
NULL
;
/* data block buffer */
xfs_dir2_data_hdr_t
*
hdr
;
/* data block header */
xfs_dir2_data_entry_t
*
dep
;
/* data entry */
xfs_dir2_data_unused_t
*
dup
;
/* unused entry */
int
error
=
0
;
/* error return value */
int
length
;
/* temporary length value */
xfs_mount_t
*
mp
;
/* filesystem mount point */
int
byteoff
;
/* offset in current block */
xfs_dir2_off_t
curoff
;
/* current overall offset */
xfs_dir2_off_t
newoff
;
/* new curoff after new blk */
char
*
ptr
=
NULL
;
/* pointer to current data */
struct
xfs_dir2_leaf_map_info
*
map_info
;
struct
xfs_da_geometry
*
geo
=
args
->
geo
;
/*
* If the offset is at or past the largest allowed value,
...
...
@@ -512,15 +512,12 @@ xfs_dir2_leaf_getdents(
if
(
ctx
->
pos
>=
XFS_DIR2_MAX_DATAPTR
)
return
0
;
mp
=
dp
->
i_mount
;
/*
* Set up to bmap a number of blocks based on the caller's
* buffer size, the directory block size, and the filesystem
* block size.
*/
length
=
howmany
(
bufsize
+
mp
->
m_dirblksize
,
mp
->
m_sb
.
sb_blocksize
);
length
=
howmany
(
bufsize
+
geo
->
blksize
,
(
1
<<
geo
->
fsblog
));
map_info
=
kmem_zalloc
(
offsetof
(
struct
xfs_dir2_leaf_map_info
,
map
)
+
(
length
*
sizeof
(
struct
xfs_bmbt_irec
)),
KM_SLEEP
|
KM_NOFS
);
...
...
@@ -536,8 +533,8 @@ xfs_dir2_leaf_getdents(
* Force this conversion through db so we truncate the offset
* down to get the start of the data block.
*/
map_info
->
map_off
=
xfs_dir2_db_to_da
(
mp
,
xfs_dir2_byte_to_db
(
mp
,
curoff
));
map_info
->
map_off
=
xfs_dir2_db_to_da
(
geo
,
xfs_dir2_byte_to_db
(
geo
,
curoff
));
/*
* Loop over directory entries until we reach the end offset.
...
...
@@ -550,9 +547,9 @@ xfs_dir2_leaf_getdents(
* If we have no buffer, or we're off the end of the
* current buffer, need to get another one.
*/
if
(
!
bp
||
ptr
>=
(
char
*
)
bp
->
b_addr
+
mp
->
m_dir
blksize
)
{
if
(
!
bp
||
ptr
>=
(
char
*
)
bp
->
b_addr
+
geo
->
blksize
)
{
error
=
xfs_dir2_leaf_readbuf
(
dp
,
bufsize
,
map_info
,
error
=
xfs_dir2_leaf_readbuf
(
args
,
bufsize
,
map_info
,
&
curoff
,
&
bp
);
if
(
error
||
!
map_info
->
map_valid
)
break
;
...
...
@@ -560,7 +557,8 @@ xfs_dir2_leaf_getdents(
/*
* Having done a read, we need to set a new offset.
*/
newoff
=
xfs_dir2_db_off_to_byte
(
mp
,
map_info
->
curdb
,
0
);
newoff
=
xfs_dir2_db_off_to_byte
(
geo
,
map_info
->
curdb
,
0
);
/*
* Start of the current block.
*/
...
...
@@ -570,7 +568,7 @@ xfs_dir2_leaf_getdents(
* Make sure we're in the right block.
*/
else
if
(
curoff
>
newoff
)
ASSERT
(
xfs_dir2_byte_to_db
(
mp
,
curoff
)
==
ASSERT
(
xfs_dir2_byte_to_db
(
geo
,
curoff
)
==
map_info
->
curdb
);
hdr
=
bp
->
b_addr
;
xfs_dir3_data_check
(
dp
,
bp
);
...
...
@@ -578,7 +576,7 @@ xfs_dir2_leaf_getdents(
* Find our position in the block.
*/
ptr
=
(
char
*
)
dp
->
d_ops
->
data_entry_p
(
hdr
);
byteoff
=
xfs_dir2_byte_to_off
(
mp
,
curoff
);
byteoff
=
xfs_dir2_byte_to_off
(
geo
,
curoff
);
/*
* Skip past the header.
*/
...
...
@@ -607,10 +605,10 @@ xfs_dir2_leaf_getdents(
* Now set our real offset.
*/
curoff
=
xfs_dir2_db_off_to_byte
(
mp
,
xfs_dir2_byte_to_db
(
mp
,
curoff
),
xfs_dir2_db_off_to_byte
(
geo
,
xfs_dir2_byte_to_db
(
geo
,
curoff
),
(
char
*
)
ptr
-
(
char
*
)
hdr
);
if
(
ptr
>=
(
char
*
)
hdr
+
mp
->
m_dir
blksize
)
{
if
(
ptr
>=
(
char
*
)
hdr
+
geo
->
blksize
)
{
continue
;
}
}
...
...
@@ -637,7 +635,7 @@ xfs_dir2_leaf_getdents(
ctx
->
pos
=
xfs_dir2_byte_to_dataptr
(
curoff
)
&
0x7fffffff
;
if
(
!
dir_emit
(
ctx
,
(
char
*
)
dep
->
name
,
dep
->
namelen
,
be64_to_cpu
(
dep
->
inumber
),
xfs_dir3_get_dtype
(
mp
,
filetype
)))
xfs_dir3_get_dtype
(
dp
->
i_mount
,
filetype
)))
break
;
/*
...
...
@@ -667,13 +665,14 @@ xfs_dir2_leaf_getdents(
*/
int
xfs_readdir
(
xfs_inode_t
*
dp
,
struct
dir_context
*
ctx
,
size_t
bufsize
)
struct
xfs_inode
*
dp
,
struct
dir_context
*
ctx
,
size_t
bufsize
)
{
int
rval
;
/* return value */
int
v
;
/* type-checking value */
uint
lock_mode
;
struct
xfs_da_args
args
=
{
NULL
};
int
rval
;
int
v
;
uint
lock_mode
;
trace_xfs_readdir
(
dp
);
...
...
@@ -683,15 +682,18 @@ xfs_readdir(
ASSERT
(
S_ISDIR
(
dp
->
i_d
.
di_mode
));
XFS_STATS_INC
(
xs_dir_getdents
);
args
.
dp
=
dp
;
args
.
geo
=
dp
->
i_mount
->
m_dir_geo
;
lock_mode
=
xfs_ilock_data_map_shared
(
dp
);
if
(
dp
->
i_d
.
di_format
==
XFS_DINODE_FMT_LOCAL
)
rval
=
xfs_dir2_sf_getdents
(
dp
,
ctx
);
else
if
((
rval
=
xfs_dir2_isblock
(
dp
,
&
v
)))
rval
=
xfs_dir2_sf_getdents
(
&
args
,
ctx
);
else
if
((
rval
=
xfs_dir2_isblock
(
&
args
,
&
v
)))
;
else
if
(
v
)
rval
=
xfs_dir2_block_getdents
(
dp
,
ctx
);
rval
=
xfs_dir2_block_getdents
(
&
args
,
ctx
);
else
rval
=
xfs_dir2_leaf_getdents
(
dp
,
ctx
,
bufsize
);
rval
=
xfs_dir2_leaf_getdents
(
&
args
,
ctx
,
bufsize
);
xfs_iunlock
(
dp
,
lock_mode
);
return
rval
;
...
...
fs/xfs/xfs_dir2_sf.c
浏览文件 @
8612c7e5
...
...
@@ -82,8 +82,10 @@ xfs_dir2_block_sfsize(
xfs_ino_t
parent
=
0
;
/* parent inode number */
int
size
=
0
;
/* total computed size */
int
has_ftype
;
struct
xfs_da_geometry
*
geo
;
mp
=
dp
->
i_mount
;
geo
=
mp
->
m_dir_geo
;
/*
* if there is a filetype field, add the extra byte to the namelen
...
...
@@ -92,7 +94,7 @@ xfs_dir2_block_sfsize(
has_ftype
=
xfs_sb_version_hasftype
(
&
mp
->
m_sb
)
?
1
:
0
;
count
=
i8count
=
namelen
=
0
;
btp
=
xfs_dir2_block_tail_p
(
mp
,
hdr
);
btp
=
xfs_dir2_block_tail_p
(
geo
,
hdr
);
blp
=
xfs_dir2_block_leaf_p
(
btp
);
/*
...
...
@@ -104,8 +106,8 @@ xfs_dir2_block_sfsize(
/*
* Calculate the pointer to the entry at hand.
*/
dep
=
(
xfs_dir2_data_entry_t
*
)
((
char
*
)
hdr
+
xfs_dir2_dataptr_to_off
(
mp
,
addr
));
dep
=
(
xfs_dir2_data_entry_t
*
)
((
char
*
)
hdr
+
xfs_dir2_dataptr_to_off
(
geo
,
addr
));
/*
* Detect . and .., so we can special-case them.
* . is not included in sf directories.
...
...
@@ -195,7 +197,7 @@ xfs_dir2_block_to_sf(
/*
* Set up to loop over the block's entries.
*/
btp
=
xfs_dir2_block_tail_p
(
mp
,
hdr
);
btp
=
xfs_dir2_block_tail_p
(
args
->
geo
,
hdr
);
ptr
=
(
char
*
)
dp
->
d_ops
->
data_entry_p
(
hdr
);
endptr
=
(
char
*
)
xfs_dir2_block_leaf_p
(
btp
);
sfep
=
xfs_dir2_sf_firstentry
(
sfp
);
...
...
@@ -247,7 +249,7 @@ xfs_dir2_block_to_sf(
/* now we are done with the block, we can shrink the inode */
logflags
=
XFS_ILOG_CORE
;
error
=
xfs_dir2_shrink_inode
(
args
,
mp
->
m_dir
datablk
,
bp
);
error
=
xfs_dir2_shrink_inode
(
args
,
args
->
geo
->
datablk
,
bp
);
if
(
error
)
{
ASSERT
(
error
!=
ENOSPC
);
goto
out
;
...
...
@@ -586,7 +588,7 @@ xfs_dir2_sf_addname_pick(
* we'll go back, convert to block, then try the insert and convert
* to leaf.
*/
if
(
used
+
(
holefit
?
0
:
size
)
>
mp
->
m_dir
blksize
)
if
(
used
+
(
holefit
?
0
:
size
)
>
args
->
geo
->
blksize
)
return
0
;
/*
* If changing the inode number size, do it the hard way.
...
...
@@ -601,7 +603,7 @@ xfs_dir2_sf_addname_pick(
/*
* If it won't fit at the end then do it the hard way (use the hole).
*/
if
(
used
+
size
>
mp
->
m_dir
blksize
)
if
(
used
+
size
>
args
->
geo
->
blksize
)
return
2
;
/*
* Do it the easy way.
...
...
@@ -652,7 +654,7 @@ xfs_dir2_sf_check(
ASSERT
((
char
*
)
sfep
-
(
char
*
)
sfp
==
dp
->
i_d
.
di_size
);
ASSERT
(
offset
+
(
sfp
->
count
+
2
)
*
(
uint
)
sizeof
(
xfs_dir2_leaf_entry_t
)
+
(
uint
)
sizeof
(
xfs_dir2_block_tail_t
)
<=
mp
->
m_dir
blksize
);
(
uint
)
sizeof
(
xfs_dir2_block_tail_t
)
<=
args
->
geo
->
blksize
);
}
#endif
/* DEBUG */
...
...
fs/xfs/xfs_fsops.c
浏览文件 @
8612c7e5
...
...
@@ -24,6 +24,8 @@
#include "xfs_sb.h"
#include "xfs_ag.h"
#include "xfs_mount.h"
#include "xfs_da_format.h"
#include "xfs_da_btree.h"
#include "xfs_inode.h"
#include "xfs_trans.h"
#include "xfs_inode_item.h"
...
...
@@ -105,7 +107,7 @@ xfs_fs_geometry(
geo
->
logsectsize
=
xfs_sb_version_hassector
(
&
mp
->
m_sb
)
?
mp
->
m_sb
.
sb_logsectsize
:
BBSIZE
;
geo
->
rtsectsize
=
mp
->
m_sb
.
sb_blocksize
;
geo
->
dirblocksize
=
mp
->
m_dirblksize
;
geo
->
dirblocksize
=
mp
->
m_dir
_geo
->
blksize
;
}
if
(
new_version
>=
4
)
{
geo
->
flags
|=
...
...
fs/xfs/xfs_log_rlimit.c
浏览文件 @
8612c7e5
...
...
@@ -42,7 +42,7 @@ xfs_log_calc_max_attrsetm_res(
int
size
;
int
nblks
;
size
=
xfs_attr_leaf_entsize_local_max
(
mp
->
m_
sb
.
sb_bloc
ksize
)
-
size
=
xfs_attr_leaf_entsize_local_max
(
mp
->
m_
attr_geo
->
bl
ksize
)
-
MAXNAMELEN
-
1
;
nblks
=
XFS_DAENTER_SPACE_RES
(
mp
,
XFS_ATTR_FORK
);
nblks
+=
XFS_B_TO_FSB
(
mp
,
size
);
...
...
fs/xfs/xfs_mount.c
浏览文件 @
8612c7e5
...
...
@@ -780,12 +780,11 @@ xfs_mountfs(
mp
->
m_dmevmask
=
0
;
/* not persistent; set after each mount */
xfs_dir_mount
(
mp
);
/*
* Initialize the attribute manager's entries.
*/
mp
->
m_attr_magicpct
=
(
mp
->
m_sb
.
sb_blocksize
*
37
)
/
100
;
error
=
xfs_da_mount
(
mp
);
if
(
error
)
{
xfs_warn
(
mp
,
"Failed dir/attr init: %d"
,
error
);
goto
out_remove_uuid
;
}
/*
* Initialize the precomputed transaction reservations values.
...
...
@@ -800,7 +799,7 @@ xfs_mountfs(
error
=
xfs_initialize_perag
(
mp
,
sbp
->
sb_agcount
,
&
mp
->
m_maxagi
);
if
(
error
)
{
xfs_warn
(
mp
,
"Failed per-ag init: %d"
,
error
);
goto
out_
remove_uuid
;
goto
out_
free_dir
;
}
if
(
!
sbp
->
sb_logblocks
)
{
...
...
@@ -975,6 +974,8 @@ xfs_mountfs(
xfs_wait_buftarg
(
mp
->
m_ddev_targp
);
out_free_perag:
xfs_free_perag
(
mp
);
out_free_dir:
xfs_da_unmount
(
mp
);
out_remove_uuid:
xfs_uuid_unmount
(
mp
);
out:
...
...
@@ -1052,6 +1053,7 @@ xfs_unmountfs(
"Freespace may not be correct on next mount."
);
xfs_log_unmount
(
mp
);
xfs_da_unmount
(
mp
);
xfs_uuid_unmount
(
mp
);
#if defined(DEBUG)
...
...
fs/xfs/xfs_mount.h
浏览文件 @
8612c7e5
...
...
@@ -27,6 +27,7 @@ struct xfs_nameops;
struct
xfs_ail
;
struct
xfs_quotainfo
;
struct
xfs_dir_ops
;
struct
xfs_da_geometry
;
#ifdef HAVE_PERCPU_SB
...
...
@@ -96,6 +97,8 @@ typedef struct xfs_mount {
uint
m_readio_blocks
;
/* min read size blocks */
uint
m_writeio_log
;
/* min write size log bytes */
uint
m_writeio_blocks
;
/* min write size blocks */
struct
xfs_da_geometry
*
m_dir_geo
;
/* directory block geometry */
struct
xfs_da_geometry
*
m_attr_geo
;
/* attribute block geometry */
struct
xlog
*
m_log
;
/* log specific stuff */
int
m_logbufs
;
/* number of log buffers */
int
m_logbsize
;
/* size of each log buffer */
...
...
@@ -131,8 +134,6 @@ typedef struct xfs_mount {
int
m_fixedfsid
[
2
];
/* unchanged for life of FS */
uint
m_dmevmask
;
/* DMI events for this FS */
__uint64_t
m_flags
;
/* global mount flags */
uint
m_dir_node_ents
;
/* #entries in a dir danode */
uint
m_attr_node_ents
;
/* #entries in attr danode */
int
m_ialloc_inos
;
/* inodes in inode allocation */
int
m_ialloc_blks
;
/* blocks in inode allocation */
int
m_inoalign_mask
;
/* mask sb_inoalignmt if used */
...
...
@@ -145,17 +146,10 @@ typedef struct xfs_mount {
int
m_dalign
;
/* stripe unit */
int
m_swidth
;
/* stripe width */
int
m_sinoalign
;
/* stripe unit inode alignment */
int
m_attr_magicpct
;
/* 37% of the blocksize */
int
m_dir_magicpct
;
/* 37% of the dir blocksize */
__uint8_t
m_sectbb_log
;
/* sectlog - BBSHIFT */
const
struct
xfs_nameops
*
m_dirnameops
;
/* vector of dir name ops */
const
struct
xfs_dir_ops
*
m_dir_inode_ops
;
/* vector of dir inode ops */
const
struct
xfs_dir_ops
*
m_nondir_inode_ops
;
/* !dir inode ops */
int
m_dirblksize
;
/* directory block sz--bytes */
int
m_dirblkfsbs
;
/* directory block sz--fsbs */
xfs_dablk_t
m_dirdatablk
;
/* blockno of dir data v2 */
xfs_dablk_t
m_dirleafblk
;
/* blockno of dir non-data v2 */
xfs_dablk_t
m_dirfreeblk
;
/* blockno of dirfreeindex v2 */
uint
m_chsize
;
/* size of next field */
atomic_t
m_active_trans
;
/* number trans frozen */
#ifdef HAVE_PERCPU_SB
...
...
fs/xfs/xfs_symlink.c
浏览文件 @
8612c7e5
...
...
@@ -27,6 +27,7 @@
#include "xfs_ag.h"
#include "xfs_mount.h"
#include "xfs_da_format.h"
#include "xfs_da_btree.h"
#include "xfs_dir2.h"
#include "xfs_inode.h"
#include "xfs_ialloc.h"
...
...
fs/xfs/xfs_trans_resv.c
浏览文件 @
8612c7e5
...
...
@@ -26,6 +26,7 @@
#include "xfs_ag.h"
#include "xfs_mount.h"
#include "xfs_da_format.h"
#include "xfs_da_btree.h"
#include "xfs_inode.h"
#include "xfs_bmap_btree.h"
#include "xfs_ialloc.h"
...
...
@@ -609,7 +610,7 @@ xfs_calc_addafork_reservation(
return
XFS_DQUOT_LOGRES
(
mp
)
+
xfs_calc_inode_res
(
mp
,
1
)
+
xfs_calc_buf_res
(
2
,
mp
->
m_sb
.
sb_sectsize
)
+
xfs_calc_buf_res
(
1
,
mp
->
m_dirblksize
)
+
xfs_calc_buf_res
(
1
,
mp
->
m_dir
_geo
->
blksize
)
+
xfs_calc_buf_res
(
XFS_DAENTER_BMAP1B
(
mp
,
XFS_DATA_FORK
)
+
1
,
XFS_FSB_TO_B
(
mp
,
1
))
+
xfs_calc_buf_res
(
XFS_ALLOCFREE_LOG_COUNT
(
mp
,
1
),
...
...
fs/xfs/xfs_trans_space.h
浏览文件 @
8612c7e5
...
...
@@ -28,7 +28,8 @@
(((b + XFS_MAX_CONTIG_EXTENTS_PER_BLOCK(mp) - 1) / \
XFS_MAX_CONTIG_EXTENTS_PER_BLOCK(mp)) * \
XFS_EXTENTADD_SPACE_RES(mp,w))
#define XFS_DAENTER_1B(mp,w) ((w) == XFS_DATA_FORK ? (mp)->m_dirblkfsbs : 1)
#define XFS_DAENTER_1B(mp,w) \
((w) == XFS_DATA_FORK ? (mp)->m_dir_geo->fsbcount : 1)
#define XFS_DAENTER_DBS(mp,w) \
(XFS_DA_NODE_MAXDEPTH + (((w) == XFS_DATA_FORK) ? 2 : 0))
#define XFS_DAENTER_BLOCKS(mp,w) \
...
...
@@ -55,7 +56,7 @@
* Space reservation values for various transactions.
*/
#define XFS_ADDAFORK_SPACE_RES(mp) \
((mp)->m_dir
blkfsbs
+ XFS_DAENTER_BMAP1B(mp, XFS_DATA_FORK))
((mp)->m_dir
_geo->fsbcount
+ XFS_DAENTER_BMAP1B(mp, XFS_DATA_FORK))
#define XFS_ATTRRM_SPACE_RES(mp) \
XFS_DAREMOVE_SPACE_RES(mp, XFS_ATTR_FORK)
/* This macro is not used - see inline code in xfs_attr_set */
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录