Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
linux
Commits
8612c7e5
Commit
8612c7e5
authored
Jun 10, 2014
by
Dave Chinner
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'xfs-da-geom' into for-next
parents
b70f14e1
35f46c5f
Changes
26
Hide whitespace changes
Inline
Side-by-side
Showing
26 changed files
with
819 additions
and
778 deletions
+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
No files found.
fs/xfs/xfs_attr.c
View file @
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
View file @
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
View file @
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
View file @
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
View file @
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
View file @
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
View file @
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
View file @
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
View file @
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
View file @
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
View file @
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
View file @
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
View file @
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
View file @
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
View file @
8612c7e5
...
...
@@ -41,9 +41,10 @@
*/
static
int
xfs_dir2_leaf_lookup_int
(
xfs_da_args_t
*
args
,
struct
xfs_buf
**
lbpp
,
int
*
indexp
,
struct
xfs_buf
**
dbpp
);
static
void
xfs_dir3_leaf_log_bests
(
struct
xfs_trans
*
tp
,
struct
xfs_buf
*
bp
,
int
first
,
int
last
);
static
void
xfs_dir3_leaf_log_tail
(
struct
xfs_trans
*
tp
,
struct
xfs_buf
*
bp
);
static
void
xfs_dir3_leaf_log_bests
(
struct
xfs_da_args
*
args
,
struct
xfs_buf
*
bp
,
int
first
,
int
last
);
static
void
xfs_dir3_leaf_log_tail
(
struct
xfs_da_args
*
args
,
struct
xfs_buf
*
bp
);
/*
* Check the internal consistency of a leaf1 block.
...
...
@@ -92,6 +93,7 @@ xfs_dir3_leaf_check_int(
int
i
;
const
struct
xfs_dir_ops
*
ops
;
struct
xfs_dir3_icleaf_hdr
leafhdr
;
struct
xfs_da_geometry
*
geo
=
mp
->
m_dir_geo
;
/*
* we can be passed a null dp here from a verifier, so we need to go the
...
...
@@ -105,14 +107,14 @@ xfs_dir3_leaf_check_int(
}
ents
=
ops
->
leaf_ents_p
(
leaf
);
ltp
=
xfs_dir2_leaf_tail_p
(
mp
,
leaf
);
ltp
=
xfs_dir2_leaf_tail_p
(
geo
,
leaf
);
/*
* XXX (dgc): This value is not restrictive enough.
* Should factor in the size of the bests table as well.
* We can deduce a value for that from di_size.
*/
if
(
hdr
->
count
>
ops
->
leaf_max_ents
(
mp
))
if
(
hdr
->
count
>
ops
->
leaf_max_ents
(
geo
))
return
false
;
/* Leaves and bests don't overlap in leaf format. */
...
...
@@ -323,7 +325,7 @@ xfs_dir3_leaf_init(
if
(
type
==
XFS_DIR2_LEAF1_MAGIC
)
{
struct
xfs_dir2_leaf_tail
*
ltp
;
ltp
=
xfs_dir2_leaf_tail_p
(
mp
,
leaf
);
ltp
=
xfs_dir2_leaf_tail_p
(
mp
->
m_dir_geo
,
leaf
);
ltp
->
bestcount
=
0
;
bp
->
b_ops
=
&
xfs_dir3_leaf1_buf_ops
;
xfs_trans_buf_set_type
(
tp
,
bp
,
XFS_BLFT_DIR_LEAF1_BUF
);
...
...
@@ -347,18 +349,18 @@ xfs_dir3_leaf_get_buf(
int
error
;
ASSERT
(
magic
==
XFS_DIR2_LEAF1_MAGIC
||
magic
==
XFS_DIR2_LEAFN_MAGIC
);
ASSERT
(
bno
>=
XFS_DIR2_LEAF_FIRSTDB
(
mp
)
&&
bno
<
XFS_DIR2_FREE_FIRSTDB
(
mp
));
ASSERT
(
bno
>=
xfs_dir2_byte_to_db
(
args
->
geo
,
XFS_DIR2_LEAF_OFFSET
)
&&
bno
<
xfs_dir2_byte_to_db
(
args
->
geo
,
XFS_DIR2_FREE_OFFSET
));
error
=
xfs_da_get_buf
(
tp
,
dp
,
xfs_dir2_db_to_da
(
mp
,
bno
),
-
1
,
&
bp
,
XFS_DATA_FORK
);
error
=
xfs_da_get_buf
(
tp
,
dp
,
xfs_dir2_db_to_da
(
args
->
geo
,
bno
)
,
-
1
,
&
bp
,
XFS_DATA_FORK
);
if
(
error
)
return
error
;
xfs_dir3_leaf_init
(
mp
,
tp
,
bp
,
dp
->
i_ino
,
magic
);
xfs_dir3_leaf_log_header
(
tp
,
dp
,
bp
);
xfs_dir3_leaf_log_header
(
args
,
bp
);
if
(
magic
==
XFS_DIR2_LEAF1_MAGIC
)
xfs_dir3_leaf_log_tail
(
tp
,
bp
);
xfs_dir3_leaf_log_tail
(
args
,
bp
);
*
bpp
=
bp
;
return
0
;
}
...
...
@@ -403,8 +405,8 @@ xfs_dir2_block_to_leaf(
if
((
error
=
xfs_da_grow_inode
(
args
,
&
blkno
)))
{
return
error
;
}
ldb
=
xfs_dir2_da_to_db
(
mp
,
blkno
);
ASSERT
(
ldb
==
XFS_DIR2_LEAF_FIRSTDB
(
mp
));
ldb
=
xfs_dir2_da_to_db
(
args
->
geo
,
blkno
);
ASSERT
(
ldb
==
xfs_dir2_byte_to_db
(
args
->
geo
,
XFS_DIR2_LEAF_OFFSET
));
/*
* Initialize the leaf block, get a buffer for it.
*/
...
...
@@ -415,7 +417,7 @@ xfs_dir2_block_to_leaf(
leaf
=
lbp
->
b_addr
;
hdr
=
dbp
->
b_addr
;
xfs_dir3_data_check
(
dp
,
dbp
);
btp
=
xfs_dir2_block_tail_p
(
mp
,
hdr
);
btp
=
xfs_dir2_block_tail_p
(
args
->
geo
,
hdr
);
blp
=
xfs_dir2_block_leaf_p
(
btp
);
bf
=
dp
->
d_ops
->
data_bestfree_p
(
hdr
);
ents
=
dp
->
d_ops
->
leaf_ents_p
(
leaf
);
...
...
@@ -427,23 +429,23 @@ xfs_dir2_block_to_leaf(
leafhdr
.
count
=
be32_to_cpu
(
btp
->
count
);
leafhdr
.
stale
=
be32_to_cpu
(
btp
->
stale
);
dp
->
d_ops
->
leaf_hdr_to_disk
(
leaf
,
&
leafhdr
);
xfs_dir3_leaf_log_header
(
tp
,
dp
,
lbp
);
xfs_dir3_leaf_log_header
(
args
,
lbp
);
/*
* Could compact these but I think we always do the conversion
* after squeezing out stale entries.
*/
memcpy
(
ents
,
blp
,
be32_to_cpu
(
btp
->
count
)
*
sizeof
(
xfs_dir2_leaf_entry_t
));
xfs_dir3_leaf_log_ents
(
tp
,
dp
,
lbp
,
0
,
leafhdr
.
count
-
1
);
xfs_dir3_leaf_log_ents
(
args
,
lbp
,
0
,
leafhdr
.
count
-
1
);
needscan
=
0
;
needlog
=
1
;
/*
* Make the space formerly occupied by the leaf entries and block
* tail be free.
*/
xfs_dir2_data_make_free
(
tp
,
dp
,
dbp
,
xfs_dir2_data_make_free
(
args
,
dbp
,
(
xfs_dir2_data_aoff_t
)((
char
*
)
blp
-
(
char
*
)
hdr
),
(
xfs_dir2_data_aoff_t
)((
char
*
)
hdr
+
mp
->
m_dir
blksize
-
(
xfs_dir2_data_aoff_t
)((
char
*
)
hdr
+
args
->
geo
->
blksize
-
(
char
*
)
blp
),
&
needlog
,
&
needscan
);
/*
...
...
@@ -461,7 +463,7 @@ xfs_dir2_block_to_leaf(
/*
* Set up leaf tail and bests table.
*/
ltp
=
xfs_dir2_leaf_tail_p
(
mp
,
leaf
);
ltp
=
xfs_dir2_leaf_tail_p
(
args
->
geo
,
leaf
);
ltp
->
bestcount
=
cpu_to_be32
(
1
);
bestsp
=
xfs_dir2_leaf_bests_p
(
ltp
);
bestsp
[
0
]
=
bf
[
0
].
length
;
...
...
@@ -469,10 +471,10 @@ xfs_dir2_block_to_leaf(
* Log the data header and leaf bests table.
*/
if
(
needlog
)
xfs_dir2_data_log_header
(
tp
,
dp
,
dbp
);
xfs_dir2_data_log_header
(
args
,
dbp
);
xfs_dir3_leaf_check
(
dp
,
lbp
);
xfs_dir3_data_check
(
dp
,
dbp
);
xfs_dir3_leaf_log_bests
(
tp
,
lbp
,
0
,
0
);
xfs_dir3_leaf_log_bests
(
args
,
lbp
,
0
,
0
);
return
0
;
}
...
...
@@ -641,7 +643,7 @@ xfs_dir2_leaf_addname(
tp
=
args
->
trans
;
mp
=
dp
->
i_mount
;
error
=
xfs_dir3_leaf_read
(
tp
,
dp
,
mp
->
m_dir
leafblk
,
-
1
,
&
lbp
);
error
=
xfs_dir3_leaf_read
(
tp
,
dp
,
args
->
geo
->
leafblk
,
-
1
,
&
lbp
);
if
(
error
)
return
error
;
...
...
@@ -653,7 +655,7 @@ xfs_dir2_leaf_addname(
*/
index
=
xfs_dir2_leaf_search_hash
(
args
,
lbp
);
leaf
=
lbp
->
b_addr
;
ltp
=
xfs_dir2_leaf_tail_p
(
mp
,
leaf
);
ltp
=
xfs_dir2_leaf_tail_p
(
args
->
geo
,
leaf
);
ents
=
dp
->
d_ops
->
leaf_ents_p
(
leaf
);
dp
->
d_ops
->
leaf_hdr_from_disk
(
&
leafhdr
,
leaf
);
bestsp
=
xfs_dir2_leaf_bests_p
(
ltp
);
...
...
@@ -670,7 +672,7 @@ xfs_dir2_leaf_addname(
index
++
,
lep
++
)
{
if
(
be32_to_cpu
(
lep
->
address
)
==
XFS_DIR2_NULL_DATAPTR
)
continue
;
i
=
xfs_dir2_dataptr_to_db
(
mp
,
be32_to_cpu
(
lep
->
address
));
i
=
xfs_dir2_dataptr_to_db
(
args
->
geo
,
be32_to_cpu
(
lep
->
address
));
ASSERT
(
i
<
be32_to_cpu
(
ltp
->
bestcount
));
ASSERT
(
bestsp
[
i
]
!=
cpu_to_be16
(
NULLDATAOFF
));
if
(
be16_to_cpu
(
bestsp
[
i
])
>=
length
)
{
...
...
@@ -810,14 +812,15 @@ xfs_dir2_leaf_addname(
memmove
(
&
bestsp
[
0
],
&
bestsp
[
1
],
be32_to_cpu
(
ltp
->
bestcount
)
*
sizeof
(
bestsp
[
0
]));
be32_add_cpu
(
&
ltp
->
bestcount
,
1
);
xfs_dir3_leaf_log_tail
(
tp
,
lbp
);
xfs_dir3_leaf_log_bests
(
tp
,
lbp
,
0
,
be32_to_cpu
(
ltp
->
bestcount
)
-
1
);
xfs_dir3_leaf_log_tail
(
args
,
lbp
);
xfs_dir3_leaf_log_bests
(
args
,
lbp
,
0
,
be32_to_cpu
(
ltp
->
bestcount
)
-
1
);
}
/*
* If we're filling in a previously empty block just log it.
*/
else
xfs_dir3_leaf_log_bests
(
tp
,
lbp
,
use_block
,
use_block
);
xfs_dir3_leaf_log_bests
(
args
,
lbp
,
use_block
,
use_block
);
hdr
=
dbp
->
b_addr
;
bf
=
dp
->
d_ops
->
data_bestfree_p
(
hdr
);
bestsp
[
use_block
]
=
bf
[
0
].
length
;
...
...
@@ -828,8 +831,8 @@ xfs_dir2_leaf_addname(
* Just read that one in.
*/
error
=
xfs_dir3_data_read
(
tp
,
dp
,
xfs_dir2_db_to_da
(
mp
,
use_block
),
-
1
,
&
dbp
);
xfs_dir2_db_to_da
(
args
->
geo
,
use_block
),
-
1
,
&
dbp
);
if
(
error
)
{
xfs_trans_brelse
(
tp
,
lbp
);
return
error
;
...
...
@@ -848,7 +851,7 @@ xfs_dir2_leaf_addname(
/*
* Mark the initial part of our freespace in use for the new entry.
*/
xfs_dir2_data_use_free
(
tp
,
dp
,
dbp
,
dup
,
xfs_dir2_data_use_free
(
args
,
dbp
,
dup
,
(
xfs_dir2_data_aoff_t
)((
char
*
)
dup
-
(
char
*
)
hdr
),
length
,
&
needlog
,
&
needscan
);
/*
...
...
@@ -870,8 +873,8 @@ xfs_dir2_leaf_addname(
* Need to log the data block's header.
*/
if
(
needlog
)
xfs_dir2_data_log_header
(
tp
,
dp
,
dbp
);
xfs_dir2_data_log_entry
(
tp
,
dp
,
dbp
,
dep
);
xfs_dir2_data_log_header
(
args
,
dbp
);
xfs_dir2_data_log_entry
(
args
,
dbp
,
dep
);
/*
* If the bests table needs to be changed, do it.
* Log the change unless we've already done that.
...
...
@@ -879,7 +882,7 @@ xfs_dir2_leaf_addname(
if
(
be16_to_cpu
(
bestsp
[
use_block
])
!=
be16_to_cpu
(
bf
[
0
].
length
))
{
bestsp
[
use_block
]
=
bf
[
0
].
length
;
if
(
!
grown
)
xfs_dir3_leaf_log_bests
(
tp
,
lbp
,
use_block
,
use_block
);
xfs_dir3_leaf_log_bests
(
args
,
lbp
,
use_block
,
use_block
);
}
lep
=
xfs_dir3_leaf_find_entry
(
&
leafhdr
,
ents
,
index
,
compact
,
lowstale
,
...
...
@@ -889,14 +892,15 @@ xfs_dir2_leaf_addname(
* Fill in the new leaf entry.
*/
lep
->
hashval
=
cpu_to_be32
(
args
->
hashval
);
lep
->
address
=
cpu_to_be32
(
xfs_dir2_db_off_to_dataptr
(
mp
,
use_block
,
lep
->
address
=
cpu_to_be32
(
xfs_dir2_db_off_to_dataptr
(
args
->
geo
,
use_block
,
be16_to_cpu
(
*
tagp
)));
/*
* Log the leaf fields and give up the buffers.
*/
dp
->
d_ops
->
leaf_hdr_to_disk
(
leaf
,
&
leafhdr
);
xfs_dir3_leaf_log_header
(
tp
,
dp
,
lbp
);
xfs_dir3_leaf_log_ents
(
tp
,
dp
,
lbp
,
lfloglow
,
lfloghigh
);
xfs_dir3_leaf_log_header
(
args
,
lbp
);
xfs_dir3_leaf_log_ents
(
args
,
lbp
,
lfloglow
,
lfloghigh
);
xfs_dir3_leaf_check
(
dp
,
lbp
);
xfs_dir3_data_check
(
dp
,
dbp
);
return
0
;
...
...
@@ -948,9 +952,9 @@ xfs_dir3_leaf_compact(
leafhdr
->
stale
=
0
;
dp
->
d_ops
->
leaf_hdr_to_disk
(
leaf
,
leafhdr
);
xfs_dir3_leaf_log_header
(
args
->
trans
,
dp
,
bp
);
xfs_dir3_leaf_log_header
(
args
,
bp
);
if
(
loglow
!=
-
1
)
xfs_dir3_leaf_log_ents
(
args
->
trans
,
dp
,
bp
,
loglow
,
to
-
1
);
xfs_dir3_leaf_log_ents
(
args
,
bp
,
loglow
,
to
-
1
);
}
/*
...
...
@@ -1052,7 +1056,7 @@ xfs_dir3_leaf_compact_x1(
*/
static
void
xfs_dir3_leaf_log_bests
(
xfs_trans_t
*
tp
,
/* transaction pointer */
struct
xfs_da_args
*
args
,
struct
xfs_buf
*
bp
,
/* leaf buffer */
int
first
,
/* first entry to log */
int
last
)
/* last entry to log */
...
...
@@ -1065,10 +1069,11 @@ xfs_dir3_leaf_log_bests(
ASSERT
(
leaf
->
hdr
.
info
.
magic
==
cpu_to_be16
(
XFS_DIR2_LEAF1_MAGIC
)
||
leaf
->
hdr
.
info
.
magic
==
cpu_to_be16
(
XFS_DIR3_LEAF1_MAGIC
));
ltp
=
xfs_dir2_leaf_tail_p
(
tp
->
t_mountp
,
leaf
);
ltp
=
xfs_dir2_leaf_tail_p
(
args
->
geo
,
leaf
);
firstb
=
xfs_dir2_leaf_bests_p
(
ltp
)
+
first
;
lastb
=
xfs_dir2_leaf_bests_p
(
ltp
)
+
last
;
xfs_trans_log_buf
(
tp
,
bp
,
(
uint
)((
char
*
)
firstb
-
(
char
*
)
leaf
),
xfs_trans_log_buf
(
args
->
trans
,
bp
,
(
uint
)((
char
*
)
firstb
-
(
char
*
)
leaf
),
(
uint
)((
char
*
)
lastb
-
(
char
*
)
leaf
+
sizeof
(
*
lastb
)
-
1
));
}
...
...
@@ -1077,8 +1082,7 @@ xfs_dir3_leaf_log_bests(
*/
void
xfs_dir3_leaf_log_ents
(
struct
xfs_trans
*
tp
,
struct
xfs_inode
*
dp
,
struct
xfs_da_args
*
args
,
struct
xfs_buf
*
bp
,
int
first
,
int
last
)
...
...
@@ -1093,10 +1097,11 @@ xfs_dir3_leaf_log_ents(
leaf
->
hdr
.
info
.
magic
==
cpu_to_be16
(
XFS_DIR2_LEAFN_MAGIC
)
||
leaf
->
hdr
.
info
.
magic
==
cpu_to_be16
(
XFS_DIR3_LEAFN_MAGIC
));
ents
=
dp
->
d_ops
->
leaf_ents_p
(
leaf
);
ents
=
args
->
dp
->
d_ops
->
leaf_ents_p
(
leaf
);
firstlep
=
&
ents
[
first
];
lastlep
=
&
ents
[
last
];
xfs_trans_log_buf
(
tp
,
bp
,
(
uint
)((
char
*
)
firstlep
-
(
char
*
)
leaf
),
xfs_trans_log_buf
(
args
->
trans
,
bp
,
(
uint
)((
char
*
)
firstlep
-
(
char
*
)
leaf
),
(
uint
)((
char
*
)
lastlep
-
(
char
*
)
leaf
+
sizeof
(
*
lastlep
)
-
1
));
}
...
...
@@ -1105,8 +1110,7 @@ xfs_dir3_leaf_log_ents(
*/
void
xfs_dir3_leaf_log_header
(
struct
xfs_trans
*
tp
,
struct
xfs_inode
*
dp
,
struct
xfs_da_args
*
args
,
struct
xfs_buf
*
bp
)
{
struct
xfs_dir2_leaf
*
leaf
=
bp
->
b_addr
;
...
...
@@ -1116,8 +1120,9 @@ xfs_dir3_leaf_log_header(
leaf
->
hdr
.
info
.
magic
==
cpu_to_be16
(
XFS_DIR2_LEAFN_MAGIC
)
||
leaf
->
hdr
.
info
.
magic
==
cpu_to_be16
(
XFS_DIR3_LEAFN_MAGIC
));
xfs_trans_log_buf
(
tp
,
bp
,
(
uint
)((
char
*
)
&
leaf
->
hdr
-
(
char
*
)
leaf
),
dp
->
d_ops
->
leaf_hdr_size
-
1
);
xfs_trans_log_buf
(
args
->
trans
,
bp
,
(
uint
)((
char
*
)
&
leaf
->
hdr
-
(
char
*
)
leaf
),
args
->
dp
->
d_ops
->
leaf_hdr_size
-
1
);
}
/*
...
...
@@ -1125,21 +1130,20 @@ xfs_dir3_leaf_log_header(
*/
STATIC
void
xfs_dir3_leaf_log_tail
(
struct
xfs_
trans
*
tp
,
struct
xfs_
da_args
*
args
,
struct
xfs_buf
*
bp
)
{
struct
xfs_dir2_leaf
*
leaf
=
bp
->
b_addr
;
xfs_dir2_leaf_tail_t
*
ltp
;
/* leaf tail structure */
struct
xfs_mount
*
mp
=
tp
->
t_mountp
;
ASSERT
(
leaf
->
hdr
.
info
.
magic
==
cpu_to_be16
(
XFS_DIR2_LEAF1_MAGIC
)
||
leaf
->
hdr
.
info
.
magic
==
cpu_to_be16
(
XFS_DIR3_LEAF1_MAGIC
)
||
leaf
->
hdr
.
info
.
magic
==
cpu_to_be16
(
XFS_DIR2_LEAFN_MAGIC
)
||
leaf
->
hdr
.
info
.
magic
==
cpu_to_be16
(
XFS_DIR3_LEAFN_MAGIC
));
ltp
=
xfs_dir2_leaf_tail_p
(
mp
,
leaf
);
xfs_trans_log_buf
(
tp
,
bp
,
(
uint
)((
char
*
)
ltp
-
(
char
*
)
leaf
),
(
uint
)(
mp
->
m_dir
blksize
-
1
));
ltp
=
xfs_dir2_leaf_tail_p
(
args
->
geo
,
leaf
);
xfs_trans_log_buf
(
args
->
trans
,
bp
,
(
uint
)((
char
*
)
ltp
-
(
char
*
)
leaf
),
(
uint
)(
args
->
geo
->
blksize
-
1
));
}
/*
...
...
@@ -1185,7 +1189,7 @@ xfs_dir2_leaf_lookup(
*/
dep
=
(
xfs_dir2_data_entry_t
*
)
((
char
*
)
dbp
->
b_addr
+
xfs_dir2_dataptr_to_off
(
dp
->
i_mount
,
be32_to_cpu
(
lep
->
address
)));
xfs_dir2_dataptr_to_off
(
args
->
geo
,
be32_to_cpu
(
lep
->
address
)));
/*
* Return the found inode number & CI name if appropriate
*/
...
...
@@ -1231,7 +1235,7 @@ xfs_dir2_leaf_lookup_int(
tp
=
args
->
trans
;
mp
=
dp
->
i_mount
;
error
=
xfs_dir3_leaf_read
(
tp
,
dp
,
mp
->
m_dir
leafblk
,
-
1
,
&
lbp
);
error
=
xfs_dir3_leaf_read
(
tp
,
dp
,
args
->
geo
->
leafblk
,
-
1
,
&
lbp
);
if
(
error
)
return
error
;
...
...
@@ -1260,7 +1264,8 @@ xfs_dir2_leaf_lookup_int(
/*
* Get the new data block number.
*/
newdb
=
xfs_dir2_dataptr_to_db
(
mp
,
be32_to_cpu
(
lep
->
address
));
newdb
=
xfs_dir2_dataptr_to_db
(
args
->
geo
,
be32_to_cpu
(
lep
->
address
));
/*
* If it's not the same as the old data block number,
* need to pitch the old one and read the new one.
...
...
@@ -1269,8 +1274,8 @@ xfs_dir2_leaf_lookup_int(
if
(
dbp
)
xfs_trans_brelse
(
tp
,
dbp
);
error
=
xfs_dir3_data_read
(
tp
,
dp
,
xfs_dir2_db_to_da
(
mp
,
newdb
),
-
1
,
&
dbp
);
xfs_dir2_db_to_da
(
args
->
geo
,
newdb
),
-
1
,
&
dbp
);
if
(
error
)
{
xfs_trans_brelse
(
tp
,
lbp
);
return
error
;
...
...
@@ -1281,7 +1286,8 @@ xfs_dir2_leaf_lookup_int(
* Point to the data entry.
*/
dep
=
(
xfs_dir2_data_entry_t
*
)((
char
*
)
dbp
->
b_addr
+
xfs_dir2_dataptr_to_off
(
mp
,
be32_to_cpu
(
lep
->
address
)));
xfs_dir2_dataptr_to_off
(
args
->
geo
,
be32_to_cpu
(
lep
->
address
)));
/*
* Compare name and if it's an exact match, return the index
* and buffer. If it's the first case-insensitive match, store
...
...
@@ -1310,8 +1316,8 @@ xfs_dir2_leaf_lookup_int(
if
(
cidb
!=
curdb
)
{
xfs_trans_brelse
(
tp
,
dbp
);
error
=
xfs_dir3_data_read
(
tp
,
dp
,
xfs_dir2_db_to_da
(
mp
,
cidb
),
-
1
,
&
dbp
);
xfs_dir2_db_to_da
(
args
->
geo
,
cidb
),
-
1
,
&
dbp
);
if
(
error
)
{
xfs_trans_brelse
(
tp
,
lbp
);
return
error
;
...
...
@@ -1380,18 +1386,18 @@ xfs_dir2_leaf_removename(
* Point to the leaf entry, use that to point to the data entry.
*/
lep
=
&
ents
[
index
];
db
=
xfs_dir2_dataptr_to_db
(
mp
,
be32_to_cpu
(
lep
->
address
));
dep
=
(
xfs_dir2_data_entry_t
*
)
((
char
*
)
hdr
+
xfs_dir2_dataptr_to_off
(
mp
,
be32_to_cpu
(
lep
->
address
)));
db
=
xfs_dir2_dataptr_to_db
(
args
->
geo
,
be32_to_cpu
(
lep
->
address
));
dep
=
(
xfs_dir2_data_entry_t
*
)
((
char
*
)
hdr
+
xfs_dir2_dataptr_to_off
(
args
->
geo
,
be32_to_cpu
(
lep
->
address
)));
needscan
=
needlog
=
0
;
oldbest
=
be16_to_cpu
(
bf
[
0
].
length
);
ltp
=
xfs_dir2_leaf_tail_p
(
mp
,
leaf
);
ltp
=
xfs_dir2_leaf_tail_p
(
args
->
geo
,
leaf
);
bestsp
=
xfs_dir2_leaf_bests_p
(
ltp
);
ASSERT
(
be16_to_cpu
(
bestsp
[
db
])
==
oldbest
);
/*
* Mark the former data entry unused.
*/
xfs_dir2_data_make_free
(
tp
,
dp
,
dbp
,
xfs_dir2_data_make_free
(
args
,
dbp
,
(
xfs_dir2_data_aoff_t
)((
char
*
)
dep
-
(
char
*
)
hdr
),
dp
->
d_ops
->
data_entsize
(
dep
->
namelen
),
&
needlog
,
&
needscan
);
/*
...
...
@@ -1399,10 +1405,10 @@ xfs_dir2_leaf_removename(
*/
leafhdr
.
stale
++
;
dp
->
d_ops
->
leaf_hdr_to_disk
(
leaf
,
&
leafhdr
);
xfs_dir3_leaf_log_header
(
tp
,
dp
,
lbp
);
xfs_dir3_leaf_log_header
(
args
,
lbp
);
lep
->
address
=
cpu_to_be32
(
XFS_DIR2_NULL_DATAPTR
);
xfs_dir3_leaf_log_ents
(
tp
,
dp
,
lbp
,
index
,
index
);
xfs_dir3_leaf_log_ents
(
args
,
lbp
,
index
,
index
);
/*
* Scan the freespace in the data block again if necessary,
...
...
@@ -1411,22 +1417,22 @@ xfs_dir2_leaf_removename(
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
);
/*
* If the longest freespace in the data block has changed,
* put the new value in the bests table and log that.
*/
if
(
be16_to_cpu
(
bf
[
0
].
length
)
!=
oldbest
)
{
bestsp
[
db
]
=
bf
[
0
].
length
;
xfs_dir3_leaf_log_bests
(
tp
,
lbp
,
db
,
db
);
xfs_dir3_leaf_log_bests
(
args
,
lbp
,
db
,
db
);
}
xfs_dir3_data_check
(
dp
,
dbp
);
/*
* If the data block is now empty then get rid of the data block.
*/
if
(
be16_to_cpu
(
bf
[
0
].
length
)
==
mp
->
m_dir
blksize
-
dp
->
d_ops
->
data_entry_offset
)
{
ASSERT
(
db
!=
mp
->
m_dir
datablk
);
args
->
geo
->
blksize
-
dp
->
d_ops
->
data_entry_offset
)
{
ASSERT
(
db
!=
args
->
geo
->
datablk
);
if
((
error
=
xfs_dir2_shrink_inode
(
args
,
db
,
dbp
)))
{
/*
* Nope, can't get rid of it because it caused
...
...
@@ -1459,15 +1465,16 @@ xfs_dir2_leaf_removename(
memmove
(
&
bestsp
[
db
-
i
],
bestsp
,
(
be32_to_cpu
(
ltp
->
bestcount
)
-
(
db
-
i
))
*
sizeof
(
*
bestsp
));
be32_add_cpu
(
&
ltp
->
bestcount
,
-
(
db
-
i
));
xfs_dir3_leaf_log_tail
(
tp
,
lbp
);
xfs_dir3_leaf_log_bests
(
tp
,
lbp
,
0
,
be32_to_cpu
(
ltp
->
bestcount
)
-
1
);
xfs_dir3_leaf_log_tail
(
args
,
lbp
);
xfs_dir3_leaf_log_bests
(
args
,
lbp
,
0
,
be32_to_cpu
(
ltp
->
bestcount
)
-
1
);
}
else
bestsp
[
db
]
=
cpu_to_be16
(
NULLDATAOFF
);
}
/*
* If the data block was not the first one, drop it.
*/
else
if
(
db
!=
mp
->
m_dir
datablk
)
else
if
(
db
!=
args
->
geo
->
datablk
)
dbp
=
NULL
;
xfs_dir3_leaf_check
(
dp
,
lbp
);
...
...
@@ -1515,7 +1522,7 @@ xfs_dir2_leaf_replace(
*/
dep
=
(
xfs_dir2_data_entry_t
*
)
((
char
*
)
dbp
->
b_addr
+
xfs_dir2_dataptr_to_off
(
dp
->
i_mount
,
be32_to_cpu
(
lep
->
address
)));
xfs_dir2_dataptr_to_off
(
args
->
geo
,
be32_to_cpu
(
lep
->
address
)));
ASSERT
(
args
->
inumber
!=
be64_to_cpu
(
dep
->
inumber
));
/*
* Put the new inode number in, log it.
...
...
@@ -1523,7 +1530,7 @@ xfs_dir2_leaf_replace(
dep
->
inumber
=
cpu_to_be64
(
args
->
inumber
);
dp
->
d_ops
->
data_put_ftype
(
dep
,
args
->
filetype
);
tp
=
args
->
trans
;
xfs_dir2_data_log_entry
(
tp
,
dp
,
dbp
,
dep
);
xfs_dir2_data_log_entry
(
args
,
dbp
,
dep
);
xfs_dir3_leaf_check
(
dp
,
lbp
);
xfs_trans_brelse
(
tp
,
lbp
);
return
0
;
...
...
@@ -1609,12 +1616,13 @@ xfs_dir2_leaf_trim_data(
/*
* Read the offending data block. We need its buffer.
*/
error
=
xfs_dir3_data_read
(
tp
,
dp
,
xfs_dir2_db_to_da
(
mp
,
db
),
-
1
,
&
dbp
);
error
=
xfs_dir3_data_read
(
tp
,
dp
,
xfs_dir2_db_to_da
(
args
->
geo
,
db
),
-
1
,
&
dbp
);
if
(
error
)
return
error
;
leaf
=
lbp
->
b_addr
;
ltp
=
xfs_dir2_leaf_tail_p
(
mp
,
leaf
);
ltp
=
xfs_dir2_leaf_tail_p
(
args
->
geo
,
leaf
);
#ifdef DEBUG
{
...
...
@@ -1624,7 +1632,7 @@ xfs_dir2_leaf_trim_data(
ASSERT
(
hdr
->
magic
==
cpu_to_be32
(
XFS_DIR2_DATA_MAGIC
)
||
hdr
->
magic
==
cpu_to_be32
(
XFS_DIR3_DATA_MAGIC
));
ASSERT
(
be16_to_cpu
(
bf
[
0
].
length
)
==
mp
->
m_dir
blksize
-
dp
->
d_ops
->
data_entry_offset
);
args
->
geo
->
blksize
-
dp
->
d_ops
->
data_entry_offset
);
ASSERT
(
db
==
be32_to_cpu
(
ltp
->
bestcount
)
-
1
);
}
#endif
...
...
@@ -1643,8 +1651,8 @@ xfs_dir2_leaf_trim_data(
bestsp
=
xfs_dir2_leaf_bests_p
(
ltp
);
be32_add_cpu
(
&
ltp
->
bestcount
,
-
1
);
memmove
(
&
bestsp
[
1
],
&
bestsp
[
0
],
be32_to_cpu
(
ltp
->
bestcount
)
*
sizeof
(
*
bestsp
));
xfs_dir3_leaf_log_tail
(
tp
,
lbp
);
xfs_dir3_leaf_log_bests
(
tp
,
lbp
,
0
,
be32_to_cpu
(
ltp
->
bestcount
)
-
1
);
xfs_dir3_leaf_log_tail
(
args
,
lbp
);
xfs_dir3_leaf_log_bests
(
args
,
lbp
,
0
,
be32_to_cpu
(
ltp
->
bestcount
)
-
1
);
return
0
;
}
...
...
@@ -1711,19 +1719,19 @@ xfs_dir2_node_to_leaf(
if
((
error
=
xfs_bmap_last_offset
(
dp
,
&
fo
,
XFS_DATA_FORK
)))
{
return
error
;
}
fo
-=
mp
->
m_dirblkfsbs
;
fo
-=
args
->
geo
->
fsbcount
;
/*
* If there are freespace blocks other than the first one,
* take this opportunity to remove trailing empty freespace blocks
* that may have been left behind during no-space-reservation
* operations.
*/
while
(
fo
>
mp
->
m_dir
freeblk
)
{
while
(
fo
>
args
->
geo
->
freeblk
)
{
if
((
error
=
xfs_dir2_node_trim_free
(
args
,
fo
,
&
rval
)))
{
return
error
;
}
if
(
rval
)
fo
-=
mp
->
m_dirblkfsbs
;
fo
-=
args
->
geo
->
fsbcount
;
else
return
0
;
}
...
...
@@ -1736,7 +1744,7 @@ xfs_dir2_node_to_leaf(
/*
* If it's not the single leaf block, give up.
*/
if
(
XFS_FSB_TO_B
(
mp
,
fo
)
>
XFS_DIR2_LEAF_OFFSET
+
mp
->
m_dir
blksize
)
if
(
XFS_FSB_TO_B
(
mp
,
fo
)
>
XFS_DIR2_LEAF_OFFSET
+
args
->
geo
->
blksize
)
return
0
;
lbp
=
state
->
path
.
blk
[
0
].
bp
;
leaf
=
lbp
->
b_addr
;
...
...
@@ -1748,7 +1756,7 @@ xfs_dir2_node_to_leaf(
/*
* Read the freespace block.
*/
error
=
xfs_dir2_free_read
(
tp
,
dp
,
mp
->
m_dir
freeblk
,
&
fbp
);
error
=
xfs_dir2_free_read
(
tp
,
dp
,
args
->
geo
->
freeblk
,
&
fbp
);
if
(
error
)
return
error
;
free
=
fbp
->
b_addr
;
...
...
@@ -1760,7 +1768,7 @@ xfs_dir2_node_to_leaf(
* Now see if the leafn and free data will fit in a leaf1.
* If not, release the buffer and give up.
*/
if
(
xfs_dir3_leaf_size
(
&
leafhdr
,
freehdr
.
nvalid
)
>
mp
->
m_dir
blksize
)
{
if
(
xfs_dir3_leaf_size
(
&
leafhdr
,
freehdr
.
nvalid
)
>
args
->
geo
->
blksize
)
{
xfs_trans_brelse
(
tp
,
fbp
);
return
0
;
}
...
...
@@ -1780,7 +1788,7 @@ xfs_dir2_node_to_leaf(
/*
* Set up the leaf tail from the freespace block.
*/
ltp
=
xfs_dir2_leaf_tail_p
(
mp
,
leaf
);
ltp
=
xfs_dir2_leaf_tail_p
(
args
->
geo
,
leaf
);
ltp
->
bestcount
=
cpu_to_be32
(
freehdr
.
nvalid
);
/*
...
...
@@ -1790,15 +1798,17 @@ xfs_dir2_node_to_leaf(
freehdr
.
nvalid
*
sizeof
(
xfs_dir2_data_off_t
));
dp
->
d_ops
->
leaf_hdr_to_disk
(
leaf
,
&
leafhdr
);
xfs_dir3_leaf_log_header
(
tp
,
dp
,
lbp
);
xfs_dir3_leaf_log_bests
(
tp
,
lbp
,
0
,
be32_to_cpu
(
ltp
->
bestcount
)
-
1
);
xfs_dir3_leaf_log_tail
(
tp
,
lbp
);
xfs_dir3_leaf_log_header
(
args
,
lbp
);
xfs_dir3_leaf_log_bests
(
args
,
lbp
,
0
,
be32_to_cpu
(
ltp
->
bestcount
)
-
1
);
xfs_dir3_leaf_log_tail
(
args
,
lbp
);
xfs_dir3_leaf_check
(
dp
,
lbp
);
/*
* Get rid of the freespace block.
*/
error
=
xfs_dir2_shrink_inode
(
args
,
XFS_DIR2_FREE_FIRSTDB
(
mp
),
fbp
);
error
=
xfs_dir2_shrink_inode
(
args
,
xfs_dir2_byte_to_db
(
args
->
geo
,
XFS_DIR2_FREE_OFFSET
),
fbp
);
if
(
error
)
{
/*
* This can't fail here because it can only happen when
...
...
fs/xfs/xfs_dir2_node.c
View file @
8612c7e5
...
...
@@ -195,17 +195,18 @@ xfs_dir2_free_try_read(
static
int
xfs_dir3_free_get_buf
(
struct
xfs_trans
*
tp
,
struct
xfs_inode
*
dp
,
xfs_da_args_t
*
args
,
xfs_dir2_db_t
fbno
,
struct
xfs_buf
**
bpp
)
{
struct
xfs_trans
*
tp
=
args
->
trans
;
struct
xfs_inode
*
dp
=
args
->
dp
;
struct
xfs_mount
*
mp
=
dp
->
i_mount
;
struct
xfs_buf
*
bp
;
int
error
;
struct
xfs_dir3_icfree_hdr
hdr
;
error
=
xfs_da_get_buf
(
tp
,
dp
,
xfs_dir2_db_to_da
(
mp
,
fbno
),
error
=
xfs_da_get_buf
(
tp
,
dp
,
xfs_dir2_db_to_da
(
args
->
geo
,
fbno
),
-
1
,
&
bp
,
XFS_DATA_FORK
);
if
(
error
)
return
error
;
...
...
@@ -240,8 +241,7 @@ xfs_dir3_free_get_buf(
*/
STATIC
void
xfs_dir2_free_log_bests
(
struct
xfs_trans
*
tp
,
struct
xfs_inode
*
dp
,
struct
xfs_da_args
*
args
,
struct
xfs_buf
*
bp
,
int
first
,
/* first entry to log */
int
last
)
/* last entry to log */
...
...
@@ -250,10 +250,10 @@ xfs_dir2_free_log_bests(
__be16
*
bests
;
free
=
bp
->
b_addr
;
bests
=
dp
->
d_ops
->
free_bests_p
(
free
);
bests
=
args
->
dp
->
d_ops
->
free_bests_p
(
free
);
ASSERT
(
free
->
hdr
.
magic
==
cpu_to_be32
(
XFS_DIR2_FREE_MAGIC
)
||
free
->
hdr
.
magic
==
cpu_to_be32
(
XFS_DIR3_FREE_MAGIC
));
xfs_trans_log_buf
(
tp
,
bp
,
xfs_trans_log_buf
(
args
->
trans
,
bp
,
(
uint
)((
char
*
)
&
bests
[
first
]
-
(
char
*
)
free
),
(
uint
)((
char
*
)
&
bests
[
last
]
-
(
char
*
)
free
+
sizeof
(
bests
[
0
])
-
1
));
...
...
@@ -264,8 +264,7 @@ xfs_dir2_free_log_bests(
*/
static
void
xfs_dir2_free_log_header
(
struct
xfs_trans
*
tp
,
struct
xfs_inode
*
dp
,
struct
xfs_da_args
*
args
,
struct
xfs_buf
*
bp
)
{
#ifdef DEBUG
...
...
@@ -275,7 +274,8 @@ xfs_dir2_free_log_header(
ASSERT
(
free
->
hdr
.
magic
==
cpu_to_be32
(
XFS_DIR2_FREE_MAGIC
)
||
free
->
hdr
.
magic
==
cpu_to_be32
(
XFS_DIR3_FREE_MAGIC
));
#endif
xfs_trans_log_buf
(
tp
,
bp
,
0
,
dp
->
d_ops
->
free_hdr_size
-
1
);
xfs_trans_log_buf
(
args
->
trans
,
bp
,
0
,
args
->
dp
->
d_ops
->
free_hdr_size
-
1
);
}
/*
...
...
@@ -315,20 +315,20 @@ xfs_dir2_leaf_to_node(
if
((
error
=
xfs_dir2_grow_inode
(
args
,
XFS_DIR2_FREE_SPACE
,
&
fdb
)))
{
return
error
;
}
ASSERT
(
fdb
==
XFS_DIR2_FREE_FIRSTDB
(
mp
));
ASSERT
(
fdb
==
xfs_dir2_byte_to_db
(
args
->
geo
,
XFS_DIR2_FREE_OFFSET
));
/*
* Get the buffer for the new freespace block.
*/
error
=
xfs_dir3_free_get_buf
(
tp
,
dp
,
fdb
,
&
fbp
);
error
=
xfs_dir3_free_get_buf
(
args
,
fdb
,
&
fbp
);
if
(
error
)
return
error
;
free
=
fbp
->
b_addr
;
dp
->
d_ops
->
free_hdr_from_disk
(
&
freehdr
,
free
);
leaf
=
lbp
->
b_addr
;
ltp
=
xfs_dir2_leaf_tail_p
(
mp
,
leaf
);
ltp
=
xfs_dir2_leaf_tail_p
(
args
->
geo
,
leaf
);
ASSERT
(
be32_to_cpu
(
ltp
->
bestcount
)
<=
(
uint
)
dp
->
i_d
.
di_size
/
mp
->
m_dir
blksize
);
(
uint
)
dp
->
i_d
.
di_size
/
args
->
geo
->
blksize
);
/*
* Copy freespace entries from the leaf block to the new block.
...
...
@@ -349,8 +349,8 @@ xfs_dir2_leaf_to_node(
freehdr
.
nvalid
=
be32_to_cpu
(
ltp
->
bestcount
);
dp
->
d_ops
->
free_hdr_to_disk
(
fbp
->
b_addr
,
&
freehdr
);
xfs_dir2_free_log_bests
(
tp
,
dp
,
fbp
,
0
,
freehdr
.
nvalid
-
1
);
xfs_dir2_free_log_header
(
tp
,
dp
,
fbp
);
xfs_dir2_free_log_bests
(
args
,
fbp
,
0
,
freehdr
.
nvalid
-
1
);
xfs_dir2_free_log_header
(
args
,
fbp
);
/*
* Converting the leaf to a leafnode is just a matter of changing the
...
...
@@ -364,7 +364,7 @@ xfs_dir2_leaf_to_node(
leaf
->
hdr
.
info
.
magic
=
cpu_to_be16
(
XFS_DIR3_LEAFN_MAGIC
);
lbp
->
b_ops
=
&
xfs_dir3_leafn_buf_ops
;
xfs_trans_buf_set_type
(
tp
,
lbp
,
XFS_BLFT_DIR_LEAFN_BUF
);
xfs_dir3_leaf_log_header
(
tp
,
dp
,
lbp
);
xfs_dir3_leaf_log_header
(
args
,
lbp
);
xfs_dir3_leaf_check
(
dp
,
lbp
);
return
0
;
}
...
...
@@ -415,7 +415,7 @@ xfs_dir2_leafn_add(
* a compact.
*/
if
(
leafhdr
.
count
==
dp
->
d_ops
->
leaf_max_ents
(
mp
))
{
if
(
leafhdr
.
count
==
dp
->
d_ops
->
leaf_max_ents
(
args
->
geo
))
{
if
(
!
leafhdr
.
stale
)
return
XFS_ERROR
(
ENOSPC
);
compact
=
leafhdr
.
stale
>
1
;
...
...
@@ -450,12 +450,12 @@ xfs_dir2_leafn_add(
highstale
,
&
lfloglow
,
&
lfloghigh
);
lep
->
hashval
=
cpu_to_be32
(
args
->
hashval
);
lep
->
address
=
cpu_to_be32
(
xfs_dir2_db_off_to_dataptr
(
mp
,
lep
->
address
=
cpu_to_be32
(
xfs_dir2_db_off_to_dataptr
(
args
->
geo
,
args
->
blkno
,
args
->
index
));
dp
->
d_ops
->
leaf_hdr_to_disk
(
leaf
,
&
leafhdr
);
xfs_dir3_leaf_log_header
(
tp
,
dp
,
bp
);
xfs_dir3_leaf_log_ents
(
tp
,
dp
,
bp
,
lfloglow
,
lfloghigh
);
xfs_dir3_leaf_log_header
(
args
,
bp
);
xfs_dir3_leaf_log_ents
(
args
,
bp
,
lfloglow
,
lfloghigh
);
xfs_dir3_leaf_check
(
dp
,
bp
);
return
0
;
}
...
...
@@ -471,7 +471,8 @@ xfs_dir2_free_hdr_check(
dp
->
d_ops
->
free_hdr_from_disk
(
&
hdr
,
bp
->
b_addr
);
ASSERT
((
hdr
.
firstdb
%
dp
->
d_ops
->
free_max_bests
(
dp
->
i_mount
))
==
0
);
ASSERT
((
hdr
.
firstdb
%
dp
->
d_ops
->
free_max_bests
(
dp
->
i_mount
->
m_dir_geo
))
==
0
);
ASSERT
(
hdr
.
firstdb
<=
db
);
ASSERT
(
db
<
hdr
.
firstdb
+
hdr
.
nvalid
);
}
...
...
@@ -576,7 +577,8 @@ xfs_dir2_leafn_lookup_for_addname(
/*
* Pull the data block number from the entry.
*/
newdb
=
xfs_dir2_dataptr_to_db
(
mp
,
be32_to_cpu
(
lep
->
address
));
newdb
=
xfs_dir2_dataptr_to_db
(
args
->
geo
,
be32_to_cpu
(
lep
->
address
));
/*
* For addname, we're looking for a place to put the new entry.
* We want to use a data block with an entry of equal
...
...
@@ -593,7 +595,7 @@ xfs_dir2_leafn_lookup_for_addname(
* Convert the data block to the free block
* holding its freespace information.
*/
newfdb
=
dp
->
d_ops
->
db_to_fdb
(
mp
,
newdb
);
newfdb
=
dp
->
d_ops
->
db_to_fdb
(
args
->
geo
,
newdb
);
/*
* If it's not the one we have in hand, read it in.
*/
...
...
@@ -605,7 +607,8 @@ xfs_dir2_leafn_lookup_for_addname(
xfs_trans_brelse
(
tp
,
curbp
);
error
=
xfs_dir2_free_read
(
tp
,
dp
,
xfs_dir2_db_to_da
(
mp
,
newfdb
),
xfs_dir2_db_to_da
(
args
->
geo
,
newfdb
),
&
curbp
);
if
(
error
)
return
error
;
...
...
@@ -616,7 +619,7 @@ xfs_dir2_leafn_lookup_for_addname(
/*
* Get the index for our entry.
*/
fi
=
dp
->
d_ops
->
db_to_fdindex
(
mp
,
curdb
);
fi
=
dp
->
d_ops
->
db_to_fdindex
(
args
->
geo
,
curdb
);
/*
* If it has room, return it.
*/
...
...
@@ -721,7 +724,8 @@ xfs_dir2_leafn_lookup_for_entry(
/*
* Pull the data block number from the entry.
*/
newdb
=
xfs_dir2_dataptr_to_db
(
mp
,
be32_to_cpu
(
lep
->
address
));
newdb
=
xfs_dir2_dataptr_to_db
(
args
->
geo
,
be32_to_cpu
(
lep
->
address
));
/*
* Not adding a new entry, so we really want to find
* the name given to us.
...
...
@@ -746,7 +750,8 @@ xfs_dir2_leafn_lookup_for_entry(
curbp
=
state
->
extrablk
.
bp
;
}
else
{
error
=
xfs_dir3_data_read
(
tp
,
dp
,
xfs_dir2_db_to_da
(
mp
,
newdb
),
xfs_dir2_db_to_da
(
args
->
geo
,
newdb
),
-
1
,
&
curbp
);
if
(
error
)
return
error
;
...
...
@@ -758,7 +763,8 @@ xfs_dir2_leafn_lookup_for_entry(
* Point to the data entry.
*/
dep
=
(
xfs_dir2_data_entry_t
*
)((
char
*
)
curbp
->
b_addr
+
xfs_dir2_dataptr_to_off
(
mp
,
be32_to_cpu
(
lep
->
address
)));
xfs_dir2_dataptr_to_off
(
args
->
geo
,
be32_to_cpu
(
lep
->
address
)));
/*
* Compare the entry and if it's an exact match, return
* EEXIST immediately. If it's the first case-insensitive
...
...
@@ -844,7 +850,6 @@ xfs_dir3_leafn_moveents(
int
start_d
,
/* destination leaf index */
int
count
)
/* count of leaves to copy */
{
struct
xfs_trans
*
tp
=
args
->
trans
;
int
stale
;
/* count stale leaves copied */
trace_xfs_dir2_leafn_moveents
(
args
,
start_s
,
start_d
,
count
);
...
...
@@ -863,7 +868,7 @@ xfs_dir3_leafn_moveents(
if
(
start_d
<
dhdr
->
count
)
{
memmove
(
&
dents
[
start_d
+
count
],
&
dents
[
start_d
],
(
dhdr
->
count
-
start_d
)
*
sizeof
(
xfs_dir2_leaf_entry_t
));
xfs_dir3_leaf_log_ents
(
tp
,
args
->
dp
,
bp_d
,
start_d
+
count
,
xfs_dir3_leaf_log_ents
(
args
,
bp_d
,
start_d
+
count
,
count
+
dhdr
->
count
-
1
);
}
/*
...
...
@@ -885,8 +890,7 @@ xfs_dir3_leafn_moveents(
*/
memcpy
(
&
dents
[
start_d
],
&
sents
[
start_s
],
count
*
sizeof
(
xfs_dir2_leaf_entry_t
));
xfs_dir3_leaf_log_ents
(
tp
,
args
->
dp
,
bp_d
,
start_d
,
start_d
+
count
-
1
);
xfs_dir3_leaf_log_ents
(
args
,
bp_d
,
start_d
,
start_d
+
count
-
1
);
/*
* If there are source entries after the ones we copied,
...
...
@@ -895,8 +899,7 @@ xfs_dir3_leafn_moveents(
if
(
start_s
+
count
<
shdr
->
count
)
{
memmove
(
&
sents
[
start_s
],
&
sents
[
start_s
+
count
],
count
*
sizeof
(
xfs_dir2_leaf_entry_t
));
xfs_dir3_leaf_log_ents
(
tp
,
args
->
dp
,
bp_s
,
start_s
,
start_s
+
count
-
1
);
xfs_dir3_leaf_log_ents
(
args
,
bp_s
,
start_s
,
start_s
+
count
-
1
);
}
/*
...
...
@@ -1032,8 +1035,8 @@ xfs_dir2_leafn_rebalance(
/* log the changes made when moving the entries */
dp
->
d_ops
->
leaf_hdr_to_disk
(
leaf1
,
&
hdr1
);
dp
->
d_ops
->
leaf_hdr_to_disk
(
leaf2
,
&
hdr2
);
xfs_dir3_leaf_log_header
(
args
->
trans
,
dp
,
blk1
->
bp
);
xfs_dir3_leaf_log_header
(
args
->
trans
,
dp
,
blk2
->
bp
);
xfs_dir3_leaf_log_header
(
args
,
blk1
->
bp
);
xfs_dir3_leaf_log_header
(
args
,
blk2
->
bp
);
xfs_dir3_leaf_check
(
dp
,
blk1
->
bp
);
xfs_dir3_leaf_check
(
dp
,
blk2
->
bp
);
...
...
@@ -1076,7 +1079,6 @@ xfs_dir3_data_block_free(
struct
xfs_buf
*
fbp
,
int
longest
)
{
struct
xfs_trans
*
tp
=
args
->
trans
;
int
logfree
=
0
;
__be16
*
bests
;
struct
xfs_dir3_icfree_hdr
freehdr
;
...
...
@@ -1090,7 +1092,7 @@ xfs_dir3_data_block_free(
* value.
*/
bests
[
findex
]
=
cpu_to_be16
(
longest
);
xfs_dir2_free_log_bests
(
tp
,
dp
,
fbp
,
findex
,
findex
);
xfs_dir2_free_log_bests
(
args
,
fbp
,
findex
,
findex
);
return
0
;
}
...
...
@@ -1118,7 +1120,7 @@ xfs_dir3_data_block_free(
}
dp
->
d_ops
->
free_hdr_to_disk
(
free
,
&
freehdr
);
xfs_dir2_free_log_header
(
tp
,
dp
,
fbp
);
xfs_dir2_free_log_header
(
args
,
fbp
);
/*
* If there are no useful entries left in the block, get rid of the
...
...
@@ -1142,7 +1144,7 @@ xfs_dir3_data_block_free(
/* Log the free entry that changed, unless we got rid of it. */
if
(
logfree
)
xfs_dir2_free_log_bests
(
tp
,
dp
,
fbp
,
findex
,
findex
);
xfs_dir2_free_log_bests
(
args
,
fbp
,
findex
,
findex
);
return
0
;
}
...
...
@@ -1193,9 +1195,9 @@ xfs_dir2_leafn_remove(
/*
* Extract the data block and offset from the entry.
*/
db
=
xfs_dir2_dataptr_to_db
(
mp
,
be32_to_cpu
(
lep
->
address
));
db
=
xfs_dir2_dataptr_to_db
(
args
->
geo
,
be32_to_cpu
(
lep
->
address
));
ASSERT
(
dblk
->
blkno
==
db
);
off
=
xfs_dir2_dataptr_to_off
(
mp
,
be32_to_cpu
(
lep
->
address
));
off
=
xfs_dir2_dataptr_to_off
(
args
->
geo
,
be32_to_cpu
(
lep
->
address
));
ASSERT
(
dblk
->
index
==
off
);
/*
...
...
@@ -1204,10 +1206,10 @@ xfs_dir2_leafn_remove(
*/
leafhdr
.
stale
++
;
dp
->
d_ops
->
leaf_hdr_to_disk
(
leaf
,
&
leafhdr
);
xfs_dir3_leaf_log_header
(
tp
,
dp
,
bp
);
xfs_dir3_leaf_log_header
(
args
,
bp
);
lep
->
address
=
cpu_to_be32
(
XFS_DIR2_NULL_DATAPTR
);
xfs_dir3_leaf_log_ents
(
tp
,
dp
,
bp
,
index
,
index
);
xfs_dir3_leaf_log_ents
(
args
,
bp
,
index
,
index
);
/*
* Make the data entry free. Keep track of the longest freespace
...
...
@@ -1219,7 +1221,7 @@ xfs_dir2_leafn_remove(
bf
=
dp
->
d_ops
->
data_bestfree_p
(
hdr
);
longest
=
be16_to_cpu
(
bf
[
0
].
length
);
needlog
=
needscan
=
0
;
xfs_dir2_data_make_free
(
tp
,
dp
,
dbp
,
off
,
xfs_dir2_data_make_free
(
args
,
dbp
,
off
,
dp
->
d_ops
->
data_entsize
(
dep
->
namelen
),
&
needlog
,
&
needscan
);
/*
* Rescan the data block freespaces for bestfree.
...
...
@@ -1228,7 +1230,7 @@ xfs_dir2_leafn_remove(
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
);
xfs_dir3_data_check
(
dp
,
dbp
);
/*
* If the longest data block freespace changes, need to update
...
...
@@ -1245,8 +1247,9 @@ xfs_dir2_leafn_remove(
* Convert the data block number to a free block,
* read in the free block.
*/
fdb
=
dp
->
d_ops
->
db_to_fdb
(
mp
,
db
);
error
=
xfs_dir2_free_read
(
tp
,
dp
,
xfs_dir2_db_to_da
(
mp
,
fdb
),
fdb
=
dp
->
d_ops
->
db_to_fdb
(
args
->
geo
,
db
);
error
=
xfs_dir2_free_read
(
tp
,
dp
,
xfs_dir2_db_to_da
(
args
->
geo
,
fdb
),
&
fbp
);
if
(
error
)
return
error
;
...
...
@@ -1255,20 +1258,21 @@ xfs_dir2_leafn_remove(
{
struct
xfs_dir3_icfree_hdr
freehdr
;
dp
->
d_ops
->
free_hdr_from_disk
(
&
freehdr
,
free
);
ASSERT
(
freehdr
.
firstdb
==
dp
->
d_ops
->
free_max_bests
(
mp
)
*
(
fdb
-
XFS_DIR2_FREE_FIRSTDB
(
mp
)));
ASSERT
(
freehdr
.
firstdb
==
dp
->
d_ops
->
free_max_bests
(
args
->
geo
)
*
(
fdb
-
xfs_dir2_byte_to_db
(
args
->
geo
,
XFS_DIR2_FREE_OFFSET
)));
}
#endif
/*
* Calculate which entry we need to fix.
*/
findex
=
dp
->
d_ops
->
db_to_fdindex
(
mp
,
db
);
findex
=
dp
->
d_ops
->
db_to_fdindex
(
args
->
geo
,
db
);
longest
=
be16_to_cpu
(
bf
[
0
].
length
);
/*
* If the data block is now empty we can get rid of it
* (usually).
*/
if
(
longest
==
mp
->
m_dir
blksize
-
if
(
longest
==
args
->
geo
->
blksize
-
dp
->
d_ops
->
data_entry_offset
)
{
/*
* Try to punch out the data block.
...
...
@@ -1303,7 +1307,7 @@ xfs_dir2_leafn_remove(
*/
*
rval
=
(
dp
->
d_ops
->
leaf_hdr_size
+
(
uint
)
sizeof
(
ents
[
0
])
*
(
leafhdr
.
count
-
leafhdr
.
stale
))
<
mp
->
m_dir_
magicpct
;
args
->
geo
->
magicpct
;
return
0
;
}
...
...
@@ -1336,7 +1340,7 @@ xfs_dir2_leafn_split(
/*
* Initialize the new leaf block.
*/
error
=
xfs_dir3_leaf_get_buf
(
args
,
xfs_dir2_da_to_db
(
mp
,
blkno
),
error
=
xfs_dir3_leaf_get_buf
(
args
,
xfs_dir2_da_to_db
(
args
->
geo
,
blkno
),
&
newblk
->
bp
,
XFS_DIR2_LEAFN_MAGIC
);
if
(
error
)
return
error
;
...
...
@@ -1410,7 +1414,7 @@ xfs_dir2_leafn_toosmall(
count
=
leafhdr
.
count
-
leafhdr
.
stale
;
bytes
=
dp
->
d_ops
->
leaf_hdr_size
+
count
*
sizeof
(
ents
[
0
]);
if
(
bytes
>
(
state
->
bloc
ksize
>>
1
))
{
if
(
bytes
>
(
state
->
args
->
geo
->
bl
ksize
>>
1
))
{
/*
* Blk over 50%, don't try to join.
*/
...
...
@@ -1463,7 +1467,8 @@ xfs_dir2_leafn_toosmall(
* Count bytes in the two blocks combined.
*/
count
=
leafhdr
.
count
-
leafhdr
.
stale
;
bytes
=
state
->
blocksize
-
(
state
->
blocksize
>>
2
);
bytes
=
state
->
args
->
geo
->
blksize
-
(
state
->
args
->
geo
->
blksize
>>
2
);
leaf
=
bp
->
b_addr
;
dp
->
d_ops
->
leaf_hdr_from_disk
(
&
hdr2
,
leaf
);
...
...
@@ -1560,8 +1565,8 @@ xfs_dir2_leafn_unbalance(
/* log the changes made when moving the entries */
dp
->
d_ops
->
leaf_hdr_to_disk
(
save_leaf
,
&
savehdr
);
dp
->
d_ops
->
leaf_hdr_to_disk
(
drop_leaf
,
&
drophdr
);
xfs_dir3_leaf_log_header
(
args
->
trans
,
dp
,
save_blk
->
bp
);
xfs_dir3_leaf_log_header
(
args
->
trans
,
dp
,
drop_blk
->
bp
);
xfs_dir3_leaf_log_header
(
args
,
save_blk
->
bp
);
xfs_dir3_leaf_log_header
(
args
,
drop_blk
->
bp
);
xfs_dir3_leaf_check
(
dp
,
save_blk
->
bp
);
xfs_dir3_leaf_check
(
dp
,
drop_blk
->
bp
);
...
...
@@ -1587,8 +1592,6 @@ xfs_dir2_node_addname(
state
=
xfs_da_state_alloc
();
state
->
args
=
args
;
state
->
mp
=
args
->
dp
->
i_mount
;
state
->
blocksize
=
state
->
mp
->
m_dirblksize
;
state
->
node_ents
=
state
->
mp
->
m_dir_node_ents
;
/*
* Look up the name. We're not supposed to find it, but
* this gives us the insertion point.
...
...
@@ -1729,7 +1732,7 @@ xfs_dir2_node_addname_int(
if
((
error
=
xfs_bmap_last_offset
(
dp
,
&
fo
,
XFS_DATA_FORK
)))
return
error
;
lastfbno
=
xfs_dir2_da_to_db
(
mp
,
(
xfs_dablk_t
)
fo
);
lastfbno
=
xfs_dir2_da_to_db
(
args
->
geo
,
(
xfs_dablk_t
)
fo
);
fbno
=
ifbno
;
}
/*
...
...
@@ -1747,7 +1750,8 @@ xfs_dir2_node_addname_int(
* us a freespace block to start with.
*/
if
(
++
fbno
==
0
)
fbno
=
XFS_DIR2_FREE_FIRSTDB
(
mp
);
fbno
=
xfs_dir2_byte_to_db
(
args
->
geo
,
XFS_DIR2_FREE_OFFSET
);
/*
* If it's ifbno we already looked at it.
*/
...
...
@@ -1765,8 +1769,8 @@ xfs_dir2_node_addname_int(
* to avoid it.
*/
error
=
xfs_dir2_free_try_read
(
tp
,
dp
,
xfs_dir2_db_to_da
(
mp
,
fbno
),
&
fbp
);
xfs_dir2_db_to_da
(
args
->
geo
,
fbno
),
&
fbp
);
if
(
error
)
return
error
;
if
(
!
fbp
)
...
...
@@ -1834,10 +1838,10 @@ xfs_dir2_node_addname_int(
* Get the freespace block corresponding to the data block
* that was just allocated.
*/
fbno
=
dp
->
d_ops
->
db_to_fdb
(
mp
,
dbno
);
fbno
=
dp
->
d_ops
->
db_to_fdb
(
args
->
geo
,
dbno
);
error
=
xfs_dir2_free_try_read
(
tp
,
dp
,
xfs_dir2_db_to_da
(
mp
,
fbno
),
&
fbp
);
xfs_dir2_db_to_da
(
args
->
geo
,
fbno
),
&
fbp
);
if
(
error
)
return
error
;
...
...
@@ -1851,12 +1855,13 @@ xfs_dir2_node_addname_int(
if
(
error
)
return
error
;
if
(
unlikely
(
dp
->
d_ops
->
db_to_fdb
(
mp
,
dbno
)
!=
fbno
)
)
{
if
(
dp
->
d_ops
->
db_to_fdb
(
args
->
geo
,
dbno
)
!=
fbno
)
{
xfs_alert
(
mp
,
"%s: dir ino %llu needed freesp block %lld for
\n
"
" data block %lld, got %lld ifbno %llu lastfbno %d"
,
__func__
,
(
unsigned
long
long
)
dp
->
i_ino
,
(
long
long
)
dp
->
d_ops
->
db_to_fdb
(
mp
,
dbno
),
(
long
long
)
dp
->
d_ops
->
db_to_fdb
(
args
->
geo
,
dbno
),
(
long
long
)
dbno
,
(
long
long
)
fbno
,
(
unsigned
long
long
)
ifbno
,
lastfbno
);
if
(
fblk
)
{
...
...
@@ -1877,7 +1882,7 @@ xfs_dir2_node_addname_int(
/*
* Get a buffer for the new block.
*/
error
=
xfs_dir3_free_get_buf
(
tp
,
dp
,
fbno
,
&
fbp
);
error
=
xfs_dir3_free_get_buf
(
args
,
fbno
,
&
fbp
);
if
(
error
)
return
error
;
free
=
fbp
->
b_addr
;
...
...
@@ -1887,8 +1892,10 @@ xfs_dir2_node_addname_int(
/*
* Remember the first slot as our empty slot.
*/
freehdr
.
firstdb
=
(
fbno
-
XFS_DIR2_FREE_FIRSTDB
(
mp
))
*
dp
->
d_ops
->
free_max_bests
(
mp
);
freehdr
.
firstdb
=
(
fbno
-
xfs_dir2_byte_to_db
(
args
->
geo
,
XFS_DIR2_FREE_OFFSET
))
*
dp
->
d_ops
->
free_max_bests
(
args
->
geo
);
}
else
{
free
=
fbp
->
b_addr
;
bests
=
dp
->
d_ops
->
free_bests_p
(
free
);
...
...
@@ -1898,13 +1905,13 @@ xfs_dir2_node_addname_int(
/*
* Set the freespace block index from the data block number.
*/
findex
=
dp
->
d_ops
->
db_to_fdindex
(
mp
,
dbno
);
findex
=
dp
->
d_ops
->
db_to_fdindex
(
args
->
geo
,
dbno
);
/*
* If it's after the end of the current entries in the
* freespace block, extend that table.
*/
if
(
findex
>=
freehdr
.
nvalid
)
{
ASSERT
(
findex
<
dp
->
d_ops
->
free_max_bests
(
mp
));
ASSERT
(
findex
<
dp
->
d_ops
->
free_max_bests
(
args
->
geo
));
freehdr
.
nvalid
=
findex
+
1
;
/*
* Tag new entry so nused will go up.
...
...
@@ -1918,7 +1925,7 @@ xfs_dir2_node_addname_int(
if
(
bests
[
findex
]
==
cpu_to_be16
(
NULLDATAOFF
))
{
freehdr
.
nused
++
;
dp
->
d_ops
->
free_hdr_to_disk
(
fbp
->
b_addr
,
&
freehdr
);
xfs_dir2_free_log_header
(
tp
,
dp
,
fbp
);
xfs_dir2_free_log_header
(
args
,
fbp
);
}
/*
* Update the real value in the table.
...
...
@@ -1943,7 +1950,8 @@ xfs_dir2_node_addname_int(
/*
* Read the data block in.
*/
error
=
xfs_dir3_data_read
(
tp
,
dp
,
xfs_dir2_db_to_da
(
mp
,
dbno
),
error
=
xfs_dir3_data_read
(
tp
,
dp
,
xfs_dir2_db_to_da
(
args
->
geo
,
dbno
),
-
1
,
&
dbp
);
if
(
error
)
return
error
;
...
...
@@ -1961,7 +1969,7 @@ xfs_dir2_node_addname_int(
/*
* Mark the first part of the unused space, inuse for us.
*/
xfs_dir2_data_use_free
(
tp
,
dp
,
dbp
,
dup
,
xfs_dir2_data_use_free
(
args
,
dbp
,
dup
,
(
xfs_dir2_data_aoff_t
)((
char
*
)
dup
-
(
char
*
)
hdr
),
length
,
&
needlog
,
&
needscan
);
/*
...
...
@@ -1974,7 +1982,7 @@ xfs_dir2_node_addname_int(
dp
->
d_ops
->
data_put_ftype
(
dep
,
args
->
filetype
);
tagp
=
dp
->
d_ops
->
data_entry_tag_p
(
dep
);
*
tagp
=
cpu_to_be16
((
char
*
)
dep
-
(
char
*
)
hdr
);
xfs_dir2_data_log_entry
(
tp
,
dp
,
dbp
,
dep
);
xfs_dir2_data_log_entry
(
args
,
dbp
,
dep
);
/*
* Rescan the block for bestfree if needed.
*/
...
...
@@ -1984,7 +1992,7 @@ xfs_dir2_node_addname_int(
* Log the data block header if needed.
*/
if
(
needlog
)
xfs_dir2_data_log_header
(
tp
,
dp
,
dbp
);
xfs_dir2_data_log_header
(
args
,
dbp
);
/*
* If the freespace entry is now wrong, update it.
*/
...
...
@@ -1997,7 +2005,7 @@ xfs_dir2_node_addname_int(
* Log the freespace entry if needed.
*/
if
(
logfree
)
xfs_dir2_free_log_bests
(
tp
,
dp
,
fbp
,
findex
,
findex
);
xfs_dir2_free_log_bests
(
args
,
fbp
,
findex
,
findex
);
/*
* Return the data block and offset in args, then drop the data block.
*/
...
...
@@ -2028,8 +2036,6 @@ xfs_dir2_node_lookup(
state
=
xfs_da_state_alloc
();
state
->
args
=
args
;
state
->
mp
=
args
->
dp
->
i_mount
;
state
->
blocksize
=
state
->
mp
->
m_dirblksize
;
state
->
node_ents
=
state
->
mp
->
m_dir_node_ents
;
/*
* Fill in the path to the entry in the cursor.
*/
...
...
@@ -2083,8 +2089,6 @@ xfs_dir2_node_removename(
state
=
xfs_da_state_alloc
();
state
->
args
=
args
;
state
->
mp
=
args
->
dp
->
i_mount
;
state
->
blocksize
=
state
->
mp
->
m_dirblksize
;
state
->
node_ents
=
state
->
mp
->
m_dir_node_ents
;
/* Look up the entry we're deleting, set up the cursor. */
error
=
xfs_da3_node_lookup_int
(
state
,
&
rval
);
...
...
@@ -2153,8 +2157,6 @@ xfs_dir2_node_replace(
state
=
xfs_da_state_alloc
();
state
->
args
=
args
;
state
->
mp
=
args
->
dp
->
i_mount
;
state
->
blocksize
=
state
->
mp
->
m_dirblksize
;
state
->
node_ents
=
state
->
mp
->
m_dir_node_ents
;
inum
=
args
->
inumber
;
/*
* Lookup the entry to change in the btree.
...
...
@@ -2186,15 +2188,15 @@ xfs_dir2_node_replace(
hdr
->
magic
==
cpu_to_be32
(
XFS_DIR3_DATA_MAGIC
));
dep
=
(
xfs_dir2_data_entry_t
*
)
((
char
*
)
hdr
+
xfs_dir2_dataptr_to_off
(
state
->
mp
,
be32_to_cpu
(
lep
->
address
)));
xfs_dir2_dataptr_to_off
(
args
->
geo
,
be32_to_cpu
(
lep
->
address
)));
ASSERT
(
inum
!=
be64_to_cpu
(
dep
->
inumber
));
/*
* Fill in the new inode number and log the entry.
*/
dep
->
inumber
=
cpu_to_be64
(
inum
);
args
->
dp
->
d_ops
->
data_put_ftype
(
dep
,
args
->
filetype
);
xfs_dir2_data_log_entry
(
args
->
trans
,
args
->
dp
,
state
->
extrablk
.
bp
,
dep
);
xfs_dir2_data_log_entry
(
args
,
state
->
extrablk
.
bp
,
dep
);
rval
=
0
;
}
/*
...
...
@@ -2262,9 +2264,9 @@ xfs_dir2_node_trim_free(
/*
* Blow the block away.
*/
if
((
error
=
xfs_dir2_shrink_inode
(
args
,
xfs_dir2_da_to_db
(
mp
,
(
xfs_dablk_t
)
fo
),
bp
))
)
{
error
=
xfs_dir2_shrink_inode
(
args
,
xfs_dir2_da_to_db
(
args
->
geo
,
(
xfs_dablk_t
)
fo
),
bp
);
if
(
error
)
{
/*
* Can't fail with ENOSPC since that only happens with no
* space reservation, when breaking up an extent into two
...
...
fs/xfs/xfs_dir2_priv.h
View file @
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
View file @
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
View file @
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
View file @
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
View file @
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
View file @
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
View file @
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
View file @
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
View file @
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
View file @
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 */
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment