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
b7676929
Commit
b7676929
authored
May 15, 2014
by
Dave Chinner
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'xfs-free-inode-btree' into for-next
parents
232c2f5c
53801fd9
Changes
18
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
18 changed files
with
852 additions
and
137 deletions
+852
-137
fs/xfs/xfs_ag.h
fs/xfs/xfs_ag.h
+22
-14
fs/xfs/xfs_btree.c
fs/xfs/xfs_btree.c
+4
-2
fs/xfs/xfs_btree.h
fs/xfs/xfs_btree.h
+3
-0
fs/xfs/xfs_format.h
fs/xfs/xfs_format.h
+13
-1
fs/xfs/xfs_fs.h
fs/xfs/xfs_fs.h
+1
-0
fs/xfs/xfs_fsops.c
fs/xfs/xfs_fsops.c
+35
-1
fs/xfs/xfs_ialloc.c
fs/xfs/xfs_ialloc.c
+593
-102
fs/xfs/xfs_ialloc_btree.c
fs/xfs/xfs_ialloc_btree.c
+63
-5
fs/xfs/xfs_ialloc_btree.h
fs/xfs/xfs_ialloc_btree.h
+2
-1
fs/xfs/xfs_inode.c
fs/xfs/xfs_inode.c
+26
-2
fs/xfs/xfs_itable.c
fs/xfs/xfs_itable.c
+4
-2
fs/xfs/xfs_log_recover.c
fs/xfs/xfs_log_recover.c
+2
-0
fs/xfs/xfs_sb.h
fs/xfs/xfs_sb.h
+9
-1
fs/xfs/xfs_stats.c
fs/xfs/xfs_stats.c
+1
-0
fs/xfs/xfs_stats.h
fs/xfs/xfs_stats.h
+17
-1
fs/xfs/xfs_trans_resv.c
fs/xfs/xfs_trans_resv.c
+50
-3
fs/xfs/xfs_trans_space.h
fs/xfs/xfs_trans_space.h
+6
-1
fs/xfs/xfs_types.h
fs/xfs/xfs_types.h
+1
-1
No files found.
fs/xfs/xfs_ag.h
View file @
b7676929
...
...
@@ -160,30 +160,38 @@ typedef struct xfs_agi {
* still being referenced.
*/
__be32
agi_unlinked
[
XFS_AGI_UNLINKED_BUCKETS
];
/*
* This marks the end of logging region 1 and start of logging region 2.
*/
uuid_t
agi_uuid
;
/* uuid of filesystem */
__be32
agi_crc
;
/* crc of agi sector */
__be32
agi_pad32
;
__be64
agi_lsn
;
/* last write sequence */
__be32
agi_free_root
;
/* root of the free inode btree */
__be32
agi_free_level
;
/* levels in free inode btree */
/* structure must be padded to 64 bit alignment */
}
xfs_agi_t
;
#define XFS_AGI_CRC_OFF offsetof(struct xfs_agi, agi_crc)
#define XFS_AGI_MAGICNUM 0x00000001
#define XFS_AGI_VERSIONNUM 0x00000002
#define XFS_AGI_SEQNO 0x00000004
#define XFS_AGI_LENGTH 0x00000008
#define XFS_AGI_COUNT 0x00000010
#define XFS_AGI_ROOT 0x00000020
#define XFS_AGI_LEVEL 0x00000040
#define XFS_AGI_FREECOUNT 0x00000080
#define XFS_AGI_NEWINO 0x00000100
#define XFS_AGI_DIRINO 0x00000200
#define XFS_AGI_UNLINKED 0x00000400
#define XFS_AGI_NUM_BITS 11
#define XFS_AGI_ALL_BITS ((1 << XFS_AGI_NUM_BITS) - 1)
#define XFS_AGI_MAGICNUM (1 << 0)
#define XFS_AGI_VERSIONNUM (1 << 1)
#define XFS_AGI_SEQNO (1 << 2)
#define XFS_AGI_LENGTH (1 << 3)
#define XFS_AGI_COUNT (1 << 4)
#define XFS_AGI_ROOT (1 << 5)
#define XFS_AGI_LEVEL (1 << 6)
#define XFS_AGI_FREECOUNT (1 << 7)
#define XFS_AGI_NEWINO (1 << 8)
#define XFS_AGI_DIRINO (1 << 9)
#define XFS_AGI_UNLINKED (1 << 10)
#define XFS_AGI_NUM_BITS_R1 11
/* end of the 1st agi logging region */
#define XFS_AGI_ALL_BITS_R1 ((1 << XFS_AGI_NUM_BITS_R1) - 1)
#define XFS_AGI_FREE_ROOT (1 << 11)
#define XFS_AGI_FREE_LEVEL (1 << 12)
#define XFS_AGI_NUM_BITS_R2 13
/* disk block (xfs_daddr_t) in the AG */
#define XFS_AGI_DADDR(mp) ((xfs_daddr_t)(2 << (mp)->m_sectbb_log))
...
...
fs/xfs/xfs_btree.c
View file @
b7676929
...
...
@@ -43,9 +43,10 @@ kmem_zone_t *xfs_btree_cur_zone;
* Btree magic numbers.
*/
static
const
__uint32_t
xfs_magics
[
2
][
XFS_BTNUM_MAX
]
=
{
{
XFS_ABTB_MAGIC
,
XFS_ABTC_MAGIC
,
XFS_BMAP_MAGIC
,
XFS_IBT_MAGIC
},
{
XFS_ABTB_MAGIC
,
XFS_ABTC_MAGIC
,
XFS_BMAP_MAGIC
,
XFS_IBT_MAGIC
,
XFS_FIBT_MAGIC
},
{
XFS_ABTB_CRC_MAGIC
,
XFS_ABTC_CRC_MAGIC
,
XFS_BMAP_CRC_MAGIC
,
XFS_IBT_CRC_MAGIC
}
XFS_BMAP_CRC_MAGIC
,
XFS_IBT_CRC_MAGIC
,
XFS_FIBT_CRC_MAGIC
}
};
#define xfs_btree_magic(cur) \
xfs_magics[!!((cur)->bc_flags & XFS_BTREE_CRC_BLOCKS)][cur->bc_btnum]
...
...
@@ -1115,6 +1116,7 @@ xfs_btree_set_refs(
xfs_buf_set_ref
(
bp
,
XFS_ALLOC_BTREE_REF
);
break
;
case
XFS_BTNUM_INO
:
case
XFS_BTNUM_FINO
:
xfs_buf_set_ref
(
bp
,
XFS_INO_BTREE_REF
);
break
;
case
XFS_BTNUM_BMAP
:
...
...
fs/xfs/xfs_btree.h
View file @
b7676929
...
...
@@ -62,6 +62,7 @@ union xfs_btree_rec {
#define XFS_BTNUM_CNT ((xfs_btnum_t)XFS_BTNUM_CNTi)
#define XFS_BTNUM_BMAP ((xfs_btnum_t)XFS_BTNUM_BMAPi)
#define XFS_BTNUM_INO ((xfs_btnum_t)XFS_BTNUM_INOi)
#define XFS_BTNUM_FINO ((xfs_btnum_t)XFS_BTNUM_FINOi)
/*
* For logging record fields.
...
...
@@ -92,6 +93,7 @@ do { \
case XFS_BTNUM_CNT: __XFS_BTREE_STATS_INC(abtc, stat); break; \
case XFS_BTNUM_BMAP: __XFS_BTREE_STATS_INC(bmbt, stat); break; \
case XFS_BTNUM_INO: __XFS_BTREE_STATS_INC(ibt, stat); break; \
case XFS_BTNUM_FINO: __XFS_BTREE_STATS_INC(fibt, stat); break; \
case XFS_BTNUM_MAX: ASSERT(0);
/* fucking gcc */
; break; \
} \
} while (0)
...
...
@@ -105,6 +107,7 @@ do { \
case XFS_BTNUM_CNT: __XFS_BTREE_STATS_ADD(abtc, stat, val); break; \
case XFS_BTNUM_BMAP: __XFS_BTREE_STATS_ADD(bmbt, stat, val); break; \
case XFS_BTNUM_INO: __XFS_BTREE_STATS_ADD(ibt, stat, val); break; \
case XFS_BTNUM_FINO: __XFS_BTREE_STATS_ADD(fibt, stat, val); break; \
case XFS_BTNUM_MAX: ASSERT(0);
/* fucking gcc */
; break; \
} \
} while (0)
...
...
fs/xfs/xfs_format.h
View file @
b7676929
...
...
@@ -202,6 +202,8 @@ typedef __be32 xfs_alloc_ptr_t;
*/
#define XFS_IBT_MAGIC 0x49414254
/* 'IABT' */
#define XFS_IBT_CRC_MAGIC 0x49414233
/* 'IAB3' */
#define XFS_FIBT_MAGIC 0x46494254
/* 'FIBT' */
#define XFS_FIBT_CRC_MAGIC 0x46494233
/* 'FIB3' */
typedef
__uint64_t
xfs_inofree_t
;
#define XFS_INODES_PER_CHUNK (NBBY * sizeof(xfs_inofree_t))
...
...
@@ -244,7 +246,17 @@ typedef __be32 xfs_inobt_ptr_t;
* block numbers in the AG.
*/
#define XFS_IBT_BLOCK(mp) ((xfs_agblock_t)(XFS_CNT_BLOCK(mp) + 1))
#define XFS_PREALLOC_BLOCKS(mp) ((xfs_agblock_t)(XFS_IBT_BLOCK(mp) + 1))
#define XFS_FIBT_BLOCK(mp) ((xfs_agblock_t)(XFS_IBT_BLOCK(mp) + 1))
/*
* The first data block of an AG depends on whether the filesystem was formatted
* with the finobt feature. If so, account for the finobt reserved root btree
* block.
*/
#define XFS_PREALLOC_BLOCKS(mp) \
(xfs_sb_version_hasfinobt(&((mp)->m_sb)) ? \
XFS_FIBT_BLOCK(mp) + 1 : \
XFS_IBT_BLOCK(mp) + 1)
...
...
fs/xfs/xfs_fs.h
View file @
b7676929
...
...
@@ -238,6 +238,7 @@ typedef struct xfs_fsop_resblks {
#define XFS_FSOP_GEOM_FLAGS_LAZYSB 0x4000
/* lazy superblock counters */
#define XFS_FSOP_GEOM_FLAGS_V5SB 0x8000
/* version 5 superblock */
#define XFS_FSOP_GEOM_FLAGS_FTYPE 0x10000
/* inode directory types */
#define XFS_FSOP_GEOM_FLAGS_FINOBT 0x20000
/* free inode btree */
/*
* Minimum and maximum sizes need for growth checks.
...
...
fs/xfs/xfs_fsops.c
View file @
b7676929
...
...
@@ -104,7 +104,9 @@ xfs_fs_geometry(
(
xfs_sb_version_hascrc
(
&
mp
->
m_sb
)
?
XFS_FSOP_GEOM_FLAGS_V5SB
:
0
)
|
(
xfs_sb_version_hasftype
(
&
mp
->
m_sb
)
?
XFS_FSOP_GEOM_FLAGS_FTYPE
:
0
);
XFS_FSOP_GEOM_FLAGS_FTYPE
:
0
)
|
(
xfs_sb_version_hasfinobt
(
&
mp
->
m_sb
)
?
XFS_FSOP_GEOM_FLAGS_FINOBT
:
0
);
geo
->
logsectsize
=
xfs_sb_version_hassector
(
&
mp
->
m_sb
)
?
mp
->
m_sb
.
sb_logsectsize
:
BBSIZE
;
geo
->
rtsectsize
=
mp
->
m_sb
.
sb_blocksize
;
...
...
@@ -316,6 +318,10 @@ xfs_growfs_data_private(
agi
->
agi_dirino
=
cpu_to_be32
(
NULLAGINO
);
if
(
xfs_sb_version_hascrc
(
&
mp
->
m_sb
))
uuid_copy
(
&
agi
->
agi_uuid
,
&
mp
->
m_sb
.
sb_uuid
);
if
(
xfs_sb_version_hasfinobt
(
&
mp
->
m_sb
))
{
agi
->
agi_free_root
=
cpu_to_be32
(
XFS_FIBT_BLOCK
(
mp
));
agi
->
agi_free_level
=
cpu_to_be32
(
1
);
}
for
(
bucket
=
0
;
bucket
<
XFS_AGI_UNLINKED_BUCKETS
;
bucket
++
)
agi
->
agi_unlinked
[
bucket
]
=
cpu_to_be32
(
NULLAGINO
);
...
...
@@ -407,6 +413,34 @@ xfs_growfs_data_private(
xfs_buf_relse
(
bp
);
if
(
error
)
goto
error0
;
/*
* FINO btree root block
*/
if
(
xfs_sb_version_hasfinobt
(
&
mp
->
m_sb
))
{
bp
=
xfs_growfs_get_hdr_buf
(
mp
,
XFS_AGB_TO_DADDR
(
mp
,
agno
,
XFS_FIBT_BLOCK
(
mp
)),
BTOBB
(
mp
->
m_sb
.
sb_blocksize
),
0
,
&
xfs_inobt_buf_ops
);
if
(
!
bp
)
{
error
=
ENOMEM
;
goto
error0
;
}
if
(
xfs_sb_version_hascrc
(
&
mp
->
m_sb
))
xfs_btree_init_block
(
mp
,
bp
,
XFS_FIBT_CRC_MAGIC
,
0
,
0
,
agno
,
XFS_BTREE_CRC_BLOCKS
);
else
xfs_btree_init_block
(
mp
,
bp
,
XFS_FIBT_MAGIC
,
0
,
0
,
agno
,
0
);
error
=
xfs_bwrite
(
bp
);
xfs_buf_relse
(
bp
);
if
(
error
)
goto
error0
;
}
}
xfs_trans_agblocks_delta
(
tp
,
nfree
);
/*
...
...
fs/xfs/xfs_ialloc.c
View file @
b7676929
This diff is collapsed.
Click to expand it.
fs/xfs/xfs_ialloc_btree.c
View file @
b7676929
...
...
@@ -49,7 +49,8 @@ xfs_inobt_dup_cursor(
struct
xfs_btree_cur
*
cur
)
{
return
xfs_inobt_init_cursor
(
cur
->
bc_mp
,
cur
->
bc_tp
,
cur
->
bc_private
.
a
.
agbp
,
cur
->
bc_private
.
a
.
agno
);
cur
->
bc_private
.
a
.
agbp
,
cur
->
bc_private
.
a
.
agno
,
cur
->
bc_btnum
);
}
STATIC
void
...
...
@@ -66,6 +67,21 @@ xfs_inobt_set_root(
xfs_ialloc_log_agi
(
cur
->
bc_tp
,
agbp
,
XFS_AGI_ROOT
|
XFS_AGI_LEVEL
);
}
STATIC
void
xfs_finobt_set_root
(
struct
xfs_btree_cur
*
cur
,
union
xfs_btree_ptr
*
nptr
,
int
inc
)
/* level change */
{
struct
xfs_buf
*
agbp
=
cur
->
bc_private
.
a
.
agbp
;
struct
xfs_agi
*
agi
=
XFS_BUF_TO_AGI
(
agbp
);
agi
->
agi_free_root
=
nptr
->
s
;
be32_add_cpu
(
&
agi
->
agi_free_level
,
inc
);
xfs_ialloc_log_agi
(
cur
->
bc_tp
,
agbp
,
XFS_AGI_FREE_ROOT
|
XFS_AGI_FREE_LEVEL
);
}
STATIC
int
xfs_inobt_alloc_block
(
struct
xfs_btree_cur
*
cur
,
...
...
@@ -172,6 +188,17 @@ xfs_inobt_init_ptr_from_cur(
ptr
->
s
=
agi
->
agi_root
;
}
STATIC
void
xfs_finobt_init_ptr_from_cur
(
struct
xfs_btree_cur
*
cur
,
union
xfs_btree_ptr
*
ptr
)
{
struct
xfs_agi
*
agi
=
XFS_BUF_TO_AGI
(
cur
->
bc_private
.
a
.
agbp
);
ASSERT
(
cur
->
bc_private
.
a
.
agno
==
be32_to_cpu
(
agi
->
agi_seqno
));
ptr
->
s
=
agi
->
agi_free_root
;
}
STATIC
__int64_t
xfs_inobt_key_diff
(
struct
xfs_btree_cur
*
cur
,
...
...
@@ -202,6 +229,7 @@ xfs_inobt_verify(
*/
switch
(
block
->
bb_magic
)
{
case
cpu_to_be32
(
XFS_IBT_CRC_MAGIC
):
case
cpu_to_be32
(
XFS_FIBT_CRC_MAGIC
):
if
(
!
xfs_sb_version_hascrc
(
&
mp
->
m_sb
))
return
false
;
if
(
!
uuid_equal
(
&
block
->
bb_u
.
s
.
bb_uuid
,
&
mp
->
m_sb
.
sb_uuid
))
...
...
@@ -213,6 +241,7 @@ xfs_inobt_verify(
return
false
;
/* fall through */
case
cpu_to_be32
(
XFS_IBT_MAGIC
):
case
cpu_to_be32
(
XFS_FIBT_MAGIC
):
break
;
default:
return
0
;
...
...
@@ -316,6 +345,28 @@ static const struct xfs_btree_ops xfs_inobt_ops = {
#endif
};
static
const
struct
xfs_btree_ops
xfs_finobt_ops
=
{
.
rec_len
=
sizeof
(
xfs_inobt_rec_t
),
.
key_len
=
sizeof
(
xfs_inobt_key_t
),
.
dup_cursor
=
xfs_inobt_dup_cursor
,
.
set_root
=
xfs_finobt_set_root
,
.
alloc_block
=
xfs_inobt_alloc_block
,
.
free_block
=
xfs_inobt_free_block
,
.
get_minrecs
=
xfs_inobt_get_minrecs
,
.
get_maxrecs
=
xfs_inobt_get_maxrecs
,
.
init_key_from_rec
=
xfs_inobt_init_key_from_rec
,
.
init_rec_from_key
=
xfs_inobt_init_rec_from_key
,
.
init_rec_from_cur
=
xfs_inobt_init_rec_from_cur
,
.
init_ptr_from_cur
=
xfs_finobt_init_ptr_from_cur
,
.
key_diff
=
xfs_inobt_key_diff
,
.
buf_ops
=
&
xfs_inobt_buf_ops
,
#if defined(DEBUG) || defined(XFS_WARN)
.
keys_inorder
=
xfs_inobt_keys_inorder
,
.
recs_inorder
=
xfs_inobt_recs_inorder
,
#endif
};
/*
* Allocate a new inode btree cursor.
*/
...
...
@@ -324,7 +375,8 @@ xfs_inobt_init_cursor(
struct
xfs_mount
*
mp
,
/* file system mount point */
struct
xfs_trans
*
tp
,
/* transaction pointer */
struct
xfs_buf
*
agbp
,
/* buffer for agi structure */
xfs_agnumber_t
agno
)
/* allocation group number */
xfs_agnumber_t
agno
,
/* allocation group number */
xfs_btnum_t
btnum
)
/* ialloc or free ino btree */
{
struct
xfs_agi
*
agi
=
XFS_BUF_TO_AGI
(
agbp
);
struct
xfs_btree_cur
*
cur
;
...
...
@@ -333,11 +385,17 @@ xfs_inobt_init_cursor(
cur
->
bc_tp
=
tp
;
cur
->
bc_mp
=
mp
;
cur
->
bc_nlevels
=
be32_to_cpu
(
agi
->
agi_level
);
cur
->
bc_btnum
=
XFS_BTNUM_INO
;
cur
->
bc_btnum
=
btnum
;
if
(
btnum
==
XFS_BTNUM_INO
)
{
cur
->
bc_nlevels
=
be32_to_cpu
(
agi
->
agi_level
);
cur
->
bc_ops
=
&
xfs_inobt_ops
;
}
else
{
cur
->
bc_nlevels
=
be32_to_cpu
(
agi
->
agi_free_level
);
cur
->
bc_ops
=
&
xfs_finobt_ops
;
}
cur
->
bc_blocklog
=
mp
->
m_sb
.
sb_blocklog
;
cur
->
bc_ops
=
&
xfs_inobt_ops
;
if
(
xfs_sb_version_hascrc
(
&
mp
->
m_sb
))
cur
->
bc_flags
|=
XFS_BTREE_CRC_BLOCKS
;
...
...
fs/xfs/xfs_ialloc_btree.h
View file @
b7676929
...
...
@@ -58,7 +58,8 @@ struct xfs_mount;
((index) - 1) * sizeof(xfs_inobt_ptr_t)))
extern
struct
xfs_btree_cur
*
xfs_inobt_init_cursor
(
struct
xfs_mount
*
,
struct
xfs_trans
*
,
struct
xfs_buf
*
,
xfs_agnumber_t
);
struct
xfs_trans
*
,
struct
xfs_buf
*
,
xfs_agnumber_t
,
xfs_btnum_t
);
extern
int
xfs_inobt_maxrecs
(
struct
xfs_mount
*
,
int
,
int
);
#endif
/* __XFS_IALLOC_BTREE_H__ */
fs/xfs/xfs_inode.c
View file @
b7676929
...
...
@@ -1811,9 +1811,33 @@ xfs_inactive_ifree(
int
error
;
tp
=
xfs_trans_alloc
(
mp
,
XFS_TRANS_INACTIVE
);
error
=
xfs_trans_reserve
(
tp
,
&
M_RES
(
mp
)
->
tr_ifree
,
0
,
0
);
/*
* The ifree transaction might need to allocate blocks for record
* insertion to the finobt. We don't want to fail here at ENOSPC, so
* allow ifree to dip into the reserved block pool if necessary.
*
* Freeing large sets of inodes generally means freeing inode chunks,
* directory and file data blocks, so this should be relatively safe.
* Only under severe circumstances should it be possible to free enough
* inodes to exhaust the reserve block pool via finobt expansion while
* at the same time not creating free space in the filesystem.
*
* Send a warning if the reservation does happen to fail, as the inode
* now remains allocated and sits on the unlinked list until the fs is
* repaired.
*/
tp
->
t_flags
|=
XFS_TRANS_RESERVE
;
error
=
xfs_trans_reserve
(
tp
,
&
M_RES
(
mp
)
->
tr_ifree
,
XFS_IFREE_SPACE_RES
(
mp
),
0
);
if
(
error
)
{
ASSERT
(
XFS_FORCED_SHUTDOWN
(
mp
));
if
(
error
==
ENOSPC
)
{
xfs_warn_ratelimited
(
mp
,
"Failed to remove inode(s) from unlinked list. "
"Please free space, unmount and run xfs_repair."
);
}
else
{
ASSERT
(
XFS_FORCED_SHUTDOWN
(
mp
));
}
xfs_trans_cancel
(
tp
,
XFS_TRANS_RELEASE_LOG_RES
);
return
error
;
}
...
...
fs/xfs/xfs_itable.c
View file @
b7676929
...
...
@@ -270,7 +270,8 @@ xfs_bulkstat(
/*
* Allocate and initialize a btree cursor for ialloc btree.
*/
cur
=
xfs_inobt_init_cursor
(
mp
,
NULL
,
agbp
,
agno
);
cur
=
xfs_inobt_init_cursor
(
mp
,
NULL
,
agbp
,
agno
,
XFS_BTNUM_INO
);
irbp
=
irbuf
;
irbufend
=
irbuf
+
nirbuf
;
end_of_ag
=
0
;
...
...
@@ -621,7 +622,8 @@ xfs_inumbers(
agino
=
0
;
continue
;
}
cur
=
xfs_inobt_init_cursor
(
mp
,
NULL
,
agbp
,
agno
);
cur
=
xfs_inobt_init_cursor
(
mp
,
NULL
,
agbp
,
agno
,
XFS_BTNUM_INO
);
error
=
xfs_inobt_lookup
(
cur
,
agino
,
XFS_LOOKUP_GE
,
&
tmp
);
if
(
error
)
{
...
...
fs/xfs/xfs_log_recover.c
View file @
b7676929
...
...
@@ -2138,7 +2138,9 @@ xlog_recover_validate_buf_type(
bp
->
b_ops
=
&
xfs_allocbt_buf_ops
;
break
;
case
XFS_IBT_CRC_MAGIC
:
case
XFS_FIBT_CRC_MAGIC
:
case
XFS_IBT_MAGIC
:
case
XFS_FIBT_MAGIC
:
bp
->
b_ops
=
&
xfs_inobt_buf_ops
;
break
;
case
XFS_BMAP_CRC_MAGIC
:
...
...
fs/xfs/xfs_sb.h
View file @
b7676929
...
...
@@ -587,7 +587,9 @@ xfs_sb_has_compat_feature(
return
(
sbp
->
sb_features_compat
&
feature
)
!=
0
;
}
#define XFS_SB_FEAT_RO_COMPAT_ALL 0
#define XFS_SB_FEAT_RO_COMPAT_FINOBT (1 << 0)
/* free inode btree */
#define XFS_SB_FEAT_RO_COMPAT_ALL \
(XFS_SB_FEAT_RO_COMPAT_FINOBT)
#define XFS_SB_FEAT_RO_COMPAT_UNKNOWN ~XFS_SB_FEAT_RO_COMPAT_ALL
static
inline
bool
xfs_sb_has_ro_compat_feature
(
...
...
@@ -641,6 +643,12 @@ static inline int xfs_sb_version_hasftype(struct xfs_sb *sbp)
(
sbp
->
sb_features2
&
XFS_SB_VERSION2_FTYPE
));
}
static
inline
int
xfs_sb_version_hasfinobt
(
xfs_sb_t
*
sbp
)
{
return
(
XFS_SB_VERSION_NUM
(
sbp
)
==
XFS_SB_VERSION_5
)
&&
(
sbp
->
sb_features_ro_compat
&
XFS_SB_FEAT_RO_COMPAT_FINOBT
);
}
/*
* end of superblock version macros
*/
...
...
fs/xfs/xfs_stats.c
View file @
b7676929
...
...
@@ -59,6 +59,7 @@ static int xfs_stat_proc_show(struct seq_file *m, void *v)
{
"abtc2"
,
XFSSTAT_END_ABTC_V2
},
{
"bmbt2"
,
XFSSTAT_END_BMBT_V2
},
{
"ibt2"
,
XFSSTAT_END_IBT_V2
},
{
"fibt2"
,
XFSSTAT_END_FIBT_V2
},
/* we print both series of quota information together */
{
"qm"
,
XFSSTAT_END_QM
},
};
...
...
fs/xfs/xfs_stats.h
View file @
b7676929
...
...
@@ -183,7 +183,23 @@ struct xfsstats {
__uint32_t
xs_ibt_2_alloc
;
__uint32_t
xs_ibt_2_free
;
__uint32_t
xs_ibt_2_moves
;
#define XFSSTAT_END_XQMSTAT (XFSSTAT_END_IBT_V2+6)
#define XFSSTAT_END_FIBT_V2 (XFSSTAT_END_IBT_V2+15)
__uint32_t
xs_fibt_2_lookup
;
__uint32_t
xs_fibt_2_compare
;
__uint32_t
xs_fibt_2_insrec
;
__uint32_t
xs_fibt_2_delrec
;
__uint32_t
xs_fibt_2_newroot
;
__uint32_t
xs_fibt_2_killroot
;
__uint32_t
xs_fibt_2_increment
;
__uint32_t
xs_fibt_2_decrement
;
__uint32_t
xs_fibt_2_lshift
;
__uint32_t
xs_fibt_2_rshift
;
__uint32_t
xs_fibt_2_split
;
__uint32_t
xs_fibt_2_join
;
__uint32_t
xs_fibt_2_alloc
;
__uint32_t
xs_fibt_2_free
;
__uint32_t
xs_fibt_2_moves
;
#define XFSSTAT_END_XQMSTAT (XFSSTAT_END_FIBT_V2+6)
__uint32_t
xs_qm_dqreclaims
;
__uint32_t
xs_qm_dqreclaim_misses
;
__uint32_t
xs_qm_dquot_dups
;
...
...
fs/xfs/xfs_trans_resv.c
View file @
b7676929
...
...
@@ -105,6 +105,47 @@ xfs_calc_inode_res(
2
*
XFS_BMBT_BLOCK_LEN
(
mp
));
}
/*
* The free inode btree is a conditional feature and the log reservation
* requirements differ slightly from that of the traditional inode allocation
* btree. The finobt tracks records for inode chunks with at least one free
* inode. A record can be removed from the tree for an inode allocation
* or free and thus the finobt reservation is unconditional across:
*
* - inode allocation
* - inode free
* - inode chunk allocation
*
* The 'modify' param indicates to include the record modification scenario. The
* 'alloc' param indicates to include the reservation for free space btree
* modifications on behalf of finobt modifications. This is required only for
* transactions that do not already account for free space btree modifications.
*
* the free inode btree: max depth * block size
* the allocation btrees: 2 trees * (max depth - 1) * block size
* the free inode btree entry: block size
*/
STATIC
uint
xfs_calc_finobt_res
(
struct
xfs_mount
*
mp
,
int
alloc
,
int
modify
)
{
uint
res
;
if
(
!
xfs_sb_version_hasfinobt
(
&
mp
->
m_sb
))
return
0
;
res
=
xfs_calc_buf_res
(
mp
->
m_in_maxlevels
,
XFS_FSB_TO_B
(
mp
,
1
));
if
(
alloc
)
res
+=
xfs_calc_buf_res
(
XFS_ALLOCFREE_LOG_COUNT
(
mp
,
1
),
XFS_FSB_TO_B
(
mp
,
1
));
if
(
modify
)
res
+=
(
uint
)
XFS_FSB_TO_B
(
mp
,
1
);
return
res
;
}
/*
* Various log reservation values.
*
...
...
@@ -302,6 +343,7 @@ xfs_calc_remove_reservation(
* the superblock for the nlink flag: sector size
* the directory btree: (max depth + v2) * dir block size
* the directory inode's bmap btree: (max depth + v2) * block size
* the finobt (record modification and allocation btrees)
*/
STATIC
uint
xfs_calc_create_resv_modify
(
...
...
@@ -310,7 +352,8 @@ xfs_calc_create_resv_modify(
return
xfs_calc_inode_res
(
mp
,
2
)
+
xfs_calc_buf_res
(
1
,
mp
->
m_sb
.
sb_sectsize
)
+
(
uint
)
XFS_FSB_TO_B
(
mp
,
1
)
+
xfs_calc_buf_res
(
XFS_DIROP_LOG_COUNT
(
mp
),
XFS_FSB_TO_B
(
mp
,
1
));
xfs_calc_buf_res
(
XFS_DIROP_LOG_COUNT
(
mp
),
XFS_FSB_TO_B
(
mp
,
1
))
+
xfs_calc_finobt_res
(
mp
,
1
,
1
);
}
/*
...
...
@@ -348,6 +391,7 @@ __xfs_calc_create_reservation(
* the superblock for the nlink flag: sector size
* the inode btree: max depth * blocksize
* the allocation btrees: 2 trees * (max depth - 1) * block size
* the finobt (record insertion)
*/
STATIC
uint
xfs_calc_icreate_resv_alloc
(
...
...
@@ -357,7 +401,8 @@ xfs_calc_icreate_resv_alloc(
mp
->
m_sb
.
sb_sectsize
+
xfs_calc_buf_res
(
mp
->
m_in_maxlevels
,
XFS_FSB_TO_B
(
mp
,
1
))
+
xfs_calc_buf_res
(
XFS_ALLOCFREE_LOG_COUNT
(
mp
,
1
),
XFS_FSB_TO_B
(
mp
,
1
));
XFS_FSB_TO_B
(
mp
,
1
))
+
xfs_calc_finobt_res
(
mp
,
0
,
0
);
}
STATIC
uint
...
...
@@ -425,6 +470,7 @@ xfs_calc_symlink_reservation(
* the on disk inode before ours in the agi hash list: inode cluster size
* the inode btree: max depth * blocksize
* the allocation btrees: 2 trees * (max depth - 1) * block size
* the finobt (record insertion, removal or modification)
*/
STATIC
uint
xfs_calc_ifree_reservation
(
...
...
@@ -439,7 +485,8 @@ xfs_calc_ifree_reservation(
xfs_calc_buf_res
(
2
+
mp
->
m_ialloc_blks
+
mp
->
m_in_maxlevels
,
0
)
+
xfs_calc_buf_res
(
XFS_ALLOCFREE_LOG_COUNT
(
mp
,
1
),
XFS_FSB_TO_B
(
mp
,
1
));
XFS_FSB_TO_B
(
mp
,
1
))
+
xfs_calc_finobt_res
(
mp
,
0
,
1
);
}
/*
...
...
fs/xfs/xfs_trans_space.h
View file @
b7676929
...
...
@@ -47,7 +47,9 @@
#define XFS_DIRREMOVE_SPACE_RES(mp) \
XFS_DAREMOVE_SPACE_RES(mp, XFS_DATA_FORK)
#define XFS_IALLOC_SPACE_RES(mp) \
((mp)->m_ialloc_blks + (mp)->m_in_maxlevels - 1)
((mp)->m_ialloc_blks + \
(xfs_sb_version_hasfinobt(&mp->m_sb) ? 2 : 1 * \
((mp)->m_in_maxlevels - 1)))
/*
* Space reservation values for various transactions.
...
...
@@ -82,5 +84,8 @@
(XFS_DIRREMOVE_SPACE_RES(mp) + XFS_DIRENTER_SPACE_RES(mp,nl))
#define XFS_SYMLINK_SPACE_RES(mp,nl,b) \
(XFS_IALLOC_SPACE_RES(mp) + XFS_DIRENTER_SPACE_RES(mp,nl) + (b))
#define XFS_IFREE_SPACE_RES(mp) \
(xfs_sb_version_hasfinobt(&mp->m_sb) ? (mp)->m_in_maxlevels : 0)
#endif
/* __XFS_TRANS_SPACE_H__ */
fs/xfs/xfs_types.h
View file @
b7676929
...
...
@@ -134,7 +134,7 @@ typedef enum {
typedef
enum
{
XFS_BTNUM_BNOi
,
XFS_BTNUM_CNTi
,
XFS_BTNUM_BMAPi
,
XFS_BTNUM_INOi
,
XFS_BTNUM_MAX
XFS_BTNUM_
FINOi
,
XFS_BTNUM_
MAX
}
xfs_btnum_t
;
struct
xfs_name
{
...
...
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