Skip to content

Commit 87fe4c3

Browse files
author
Darrick J. Wong
committed
xfs: create incore realtime group structures
Create an incore object that will contain information about a realtime allocation group. This will eventually enable us to shard the realtime section in a similar manner to how we shard the data section, but for now just a single object for the entire RT subvolume is created. Signed-off-by: Darrick J. Wong <[email protected]> Reviewed-by: Christoph Hellwig <[email protected]>
1 parent dcfc65b commit 87fe4c3

14 files changed

+454
-5
lines changed

fs/xfs/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ xfs-y += $(addprefix libxfs/, \
6161
# xfs_rtbitmap is shared with libxfs
6262
xfs-$(CONFIG_XFS_RT) += $(addprefix libxfs/, \
6363
xfs_rtbitmap.o \
64+
xfs_rtgroup.o \
6465
)
6566

6667
# highlevel code

fs/xfs/libxfs/xfs_format.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,9 @@ typedef struct xfs_sb {
176176

177177
xfs_ino_t sb_metadirino; /* metadata directory tree root */
178178

179+
xfs_rgnumber_t sb_rgcount; /* number of realtime groups */
180+
xfs_rtxlen_t sb_rgextents; /* size of a realtime group in rtx */
181+
179182
/* must be padded to 64 bit alignment */
180183
} xfs_sb_t;
181184

fs/xfs/libxfs/xfs_rtgroup.c

Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
// SPDX-License-Identifier: GPL-2.0-or-later
2+
/*
3+
* Copyright (c) 2022-2024 Oracle. All Rights Reserved.
4+
* Author: Darrick J. Wong <[email protected]>
5+
*/
6+
#include "xfs.h"
7+
#include "xfs_fs.h"
8+
#include "xfs_shared.h"
9+
#include "xfs_format.h"
10+
#include "xfs_trans_resv.h"
11+
#include "xfs_bit.h"
12+
#include "xfs_sb.h"
13+
#include "xfs_mount.h"
14+
#include "xfs_btree.h"
15+
#include "xfs_alloc_btree.h"
16+
#include "xfs_rmap_btree.h"
17+
#include "xfs_alloc.h"
18+
#include "xfs_ialloc.h"
19+
#include "xfs_rmap.h"
20+
#include "xfs_ag.h"
21+
#include "xfs_ag_resv.h"
22+
#include "xfs_health.h"
23+
#include "xfs_error.h"
24+
#include "xfs_bmap.h"
25+
#include "xfs_defer.h"
26+
#include "xfs_log_format.h"
27+
#include "xfs_trans.h"
28+
#include "xfs_trace.h"
29+
#include "xfs_inode.h"
30+
#include "xfs_icache.h"
31+
#include "xfs_rtgroup.h"
32+
#include "xfs_rtbitmap.h"
33+
34+
int
35+
xfs_rtgroup_alloc(
36+
struct xfs_mount *mp,
37+
xfs_rgnumber_t rgno,
38+
xfs_rgnumber_t rgcount,
39+
xfs_rtbxlen_t rextents)
40+
{
41+
struct xfs_rtgroup *rtg;
42+
int error;
43+
44+
rtg = kzalloc(sizeof(struct xfs_rtgroup), GFP_KERNEL);
45+
if (!rtg)
46+
return -ENOMEM;
47+
48+
error = xfs_group_insert(mp, rtg_group(rtg), rgno, XG_TYPE_RTG);
49+
if (error)
50+
goto out_free_rtg;
51+
return 0;
52+
53+
out_free_rtg:
54+
kfree(rtg);
55+
return error;
56+
}
57+
58+
void
59+
xfs_rtgroup_free(
60+
struct xfs_mount *mp,
61+
xfs_rgnumber_t rgno)
62+
{
63+
xfs_group_free(mp, rgno, XG_TYPE_RTG, NULL);
64+
}
65+
66+
/* Free a range of incore rtgroup objects. */
67+
void
68+
xfs_free_rtgroups(
69+
struct xfs_mount *mp,
70+
xfs_rgnumber_t first_rgno,
71+
xfs_rgnumber_t end_rgno)
72+
{
73+
xfs_rgnumber_t rgno;
74+
75+
for (rgno = first_rgno; rgno < end_rgno; rgno++)
76+
xfs_rtgroup_free(mp, rgno);
77+
}
78+
79+
/* Initialize some range of incore rtgroup objects. */
80+
int
81+
xfs_initialize_rtgroups(
82+
struct xfs_mount *mp,
83+
xfs_rgnumber_t first_rgno,
84+
xfs_rgnumber_t end_rgno,
85+
xfs_rtbxlen_t rextents)
86+
{
87+
xfs_rgnumber_t index;
88+
int error;
89+
90+
if (first_rgno >= end_rgno)
91+
return 0;
92+
93+
for (index = first_rgno; index < end_rgno; index++) {
94+
error = xfs_rtgroup_alloc(mp, index, end_rgno, rextents);
95+
if (error)
96+
goto out_unwind_new_rtgs;
97+
}
98+
99+
return 0;
100+
101+
out_unwind_new_rtgs:
102+
xfs_free_rtgroups(mp, first_rgno, index);
103+
return error;
104+
}
105+
106+
/* Compute the number of rt extents in this realtime group. */
107+
xfs_rtxnum_t
108+
__xfs_rtgroup_extents(
109+
struct xfs_mount *mp,
110+
xfs_rgnumber_t rgno,
111+
xfs_rgnumber_t rgcount,
112+
xfs_rtbxlen_t rextents)
113+
{
114+
ASSERT(rgno < rgcount);
115+
if (rgno == rgcount - 1)
116+
return rextents - ((xfs_rtxnum_t)rgno * mp->m_sb.sb_rgextents);
117+
118+
ASSERT(xfs_has_rtgroups(mp));
119+
return mp->m_sb.sb_rgextents;
120+
}
121+
122+
xfs_rtxnum_t
123+
xfs_rtgroup_extents(
124+
struct xfs_mount *mp,
125+
xfs_rgnumber_t rgno)
126+
{
127+
return __xfs_rtgroup_extents(mp, rgno, mp->m_sb.sb_rgcount,
128+
mp->m_sb.sb_rextents);
129+
}
130+
131+
/*
132+
* Update the rt extent count of the previous tail rtgroup if it changed during
133+
* recovery (i.e. recovery of a growfs).
134+
*/
135+
int
136+
xfs_update_last_rtgroup_size(
137+
struct xfs_mount *mp,
138+
xfs_rgnumber_t prev_rgcount)
139+
{
140+
struct xfs_rtgroup *rtg;
141+
142+
ASSERT(prev_rgcount > 0);
143+
144+
rtg = xfs_rtgroup_grab(mp, prev_rgcount - 1);
145+
if (!rtg)
146+
return -EFSCORRUPTED;
147+
rtg->rtg_extents = __xfs_rtgroup_extents(mp, prev_rgcount - 1,
148+
mp->m_sb.sb_rgcount, mp->m_sb.sb_rextents);
149+
xfs_rtgroup_rele(rtg);
150+
return 0;
151+
}

fs/xfs/libxfs/xfs_rtgroup.h

Lines changed: 217 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,217 @@
1+
/* SPDX-License-Identifier: GPL-2.0-or-later */
2+
/*
3+
* Copyright (c) 2022-2024 Oracle. All Rights Reserved.
4+
* Author: Darrick J. Wong <[email protected]>
5+
*/
6+
#ifndef __LIBXFS_RTGROUP_H
7+
#define __LIBXFS_RTGROUP_H 1
8+
9+
#include "xfs_group.h"
10+
11+
struct xfs_mount;
12+
struct xfs_trans;
13+
14+
/*
15+
* Realtime group incore structure, similar to the per-AG structure.
16+
*/
17+
struct xfs_rtgroup {
18+
struct xfs_group rtg_group;
19+
20+
/* Number of blocks in this group */
21+
xfs_rtxnum_t rtg_extents;
22+
};
23+
24+
static inline struct xfs_rtgroup *to_rtg(struct xfs_group *xg)
25+
{
26+
return container_of(xg, struct xfs_rtgroup, rtg_group);
27+
}
28+
29+
static inline struct xfs_group *rtg_group(struct xfs_rtgroup *rtg)
30+
{
31+
return &rtg->rtg_group;
32+
}
33+
34+
static inline struct xfs_mount *rtg_mount(const struct xfs_rtgroup *rtg)
35+
{
36+
return rtg->rtg_group.xg_mount;
37+
}
38+
39+
static inline xfs_rgnumber_t rtg_rgno(const struct xfs_rtgroup *rtg)
40+
{
41+
return rtg->rtg_group.xg_gno;
42+
}
43+
44+
/* Passive rtgroup references */
45+
static inline struct xfs_rtgroup *
46+
xfs_rtgroup_get(
47+
struct xfs_mount *mp,
48+
xfs_rgnumber_t rgno)
49+
{
50+
return to_rtg(xfs_group_get(mp, rgno, XG_TYPE_RTG));
51+
}
52+
53+
static inline struct xfs_rtgroup *
54+
xfs_rtgroup_hold(
55+
struct xfs_rtgroup *rtg)
56+
{
57+
return to_rtg(xfs_group_hold(rtg_group(rtg)));
58+
}
59+
60+
static inline void
61+
xfs_rtgroup_put(
62+
struct xfs_rtgroup *rtg)
63+
{
64+
xfs_group_put(rtg_group(rtg));
65+
}
66+
67+
/* Active rtgroup references */
68+
static inline struct xfs_rtgroup *
69+
xfs_rtgroup_grab(
70+
struct xfs_mount *mp,
71+
xfs_rgnumber_t rgno)
72+
{
73+
return to_rtg(xfs_group_grab(mp, rgno, XG_TYPE_RTG));
74+
}
75+
76+
static inline void
77+
xfs_rtgroup_rele(
78+
struct xfs_rtgroup *rtg)
79+
{
80+
xfs_group_rele(rtg_group(rtg));
81+
}
82+
83+
static inline struct xfs_rtgroup *
84+
xfs_rtgroup_next_range(
85+
struct xfs_mount *mp,
86+
struct xfs_rtgroup *rtg,
87+
xfs_rgnumber_t start_rgno,
88+
xfs_rgnumber_t end_rgno)
89+
{
90+
return to_rtg(xfs_group_next_range(mp, rtg ? rtg_group(rtg) : NULL,
91+
start_rgno, end_rgno, XG_TYPE_RTG));
92+
}
93+
94+
static inline struct xfs_rtgroup *
95+
xfs_rtgroup_next(
96+
struct xfs_mount *mp,
97+
struct xfs_rtgroup *rtg)
98+
{
99+
return xfs_rtgroup_next_range(mp, rtg, 0, mp->m_sb.sb_rgcount - 1);
100+
}
101+
102+
static inline xfs_rtblock_t
103+
xfs_rgno_start_rtb(
104+
struct xfs_mount *mp,
105+
xfs_rgnumber_t rgno)
106+
{
107+
if (mp->m_rgblklog >= 0)
108+
return ((xfs_rtblock_t)rgno << mp->m_rgblklog);
109+
return ((xfs_rtblock_t)rgno * mp->m_rgblocks);
110+
}
111+
112+
static inline xfs_rtblock_t
113+
__xfs_rgbno_to_rtb(
114+
struct xfs_mount *mp,
115+
xfs_rgnumber_t rgno,
116+
xfs_rgblock_t rgbno)
117+
{
118+
return xfs_rgno_start_rtb(mp, rgno) + rgbno;
119+
}
120+
121+
static inline xfs_rtblock_t
122+
xfs_rgbno_to_rtb(
123+
struct xfs_rtgroup *rtg,
124+
xfs_rgblock_t rgbno)
125+
{
126+
return __xfs_rgbno_to_rtb(rtg_mount(rtg), rtg_rgno(rtg), rgbno);
127+
}
128+
129+
static inline xfs_rgnumber_t
130+
xfs_rtb_to_rgno(
131+
struct xfs_mount *mp,
132+
xfs_rtblock_t rtbno)
133+
{
134+
if (!xfs_has_rtgroups(mp))
135+
return 0;
136+
137+
if (mp->m_rgblklog >= 0)
138+
return rtbno >> mp->m_rgblklog;
139+
140+
return div_u64(rtbno, mp->m_rgblocks);
141+
}
142+
143+
static inline uint64_t
144+
__xfs_rtb_to_rgbno(
145+
struct xfs_mount *mp,
146+
xfs_rtblock_t rtbno)
147+
{
148+
uint32_t rem;
149+
150+
if (!xfs_has_rtgroups(mp))
151+
return rtbno;
152+
153+
if (mp->m_rgblklog >= 0)
154+
return rtbno & mp->m_rgblkmask;
155+
156+
div_u64_rem(rtbno, mp->m_rgblocks, &rem);
157+
return rem;
158+
}
159+
160+
static inline xfs_rgblock_t
161+
xfs_rtb_to_rgbno(
162+
struct xfs_mount *mp,
163+
xfs_rtblock_t rtbno)
164+
{
165+
return __xfs_rtb_to_rgbno(mp, rtbno);
166+
}
167+
168+
static inline xfs_daddr_t
169+
xfs_rtb_to_daddr(
170+
struct xfs_mount *mp,
171+
xfs_rtblock_t rtbno)
172+
{
173+
return rtbno << mp->m_blkbb_log;
174+
}
175+
176+
static inline xfs_rtblock_t
177+
xfs_daddr_to_rtb(
178+
struct xfs_mount *mp,
179+
xfs_daddr_t daddr)
180+
{
181+
return daddr >> mp->m_blkbb_log;
182+
}
183+
184+
#ifdef CONFIG_XFS_RT
185+
int xfs_rtgroup_alloc(struct xfs_mount *mp, xfs_rgnumber_t rgno,
186+
xfs_rgnumber_t rgcount, xfs_rtbxlen_t rextents);
187+
void xfs_rtgroup_free(struct xfs_mount *mp, xfs_rgnumber_t rgno);
188+
189+
void xfs_free_rtgroups(struct xfs_mount *mp, xfs_rgnumber_t first_rgno,
190+
xfs_rgnumber_t end_rgno);
191+
int xfs_initialize_rtgroups(struct xfs_mount *mp, xfs_rgnumber_t first_rgno,
192+
xfs_rgnumber_t end_rgno, xfs_rtbxlen_t rextents);
193+
194+
xfs_rtxnum_t __xfs_rtgroup_extents(struct xfs_mount *mp, xfs_rgnumber_t rgno,
195+
xfs_rgnumber_t rgcount, xfs_rtbxlen_t rextents);
196+
xfs_rtxnum_t xfs_rtgroup_extents(struct xfs_mount *mp, xfs_rgnumber_t rgno);
197+
198+
int xfs_update_last_rtgroup_size(struct xfs_mount *mp,
199+
xfs_rgnumber_t prev_rgcount);
200+
#else
201+
static inline void xfs_free_rtgroups(struct xfs_mount *mp,
202+
xfs_rgnumber_t first_rgno, xfs_rgnumber_t end_rgno)
203+
{
204+
}
205+
206+
static inline int xfs_initialize_rtgroups(struct xfs_mount *mp,
207+
xfs_rgnumber_t first_rgno, xfs_rgnumber_t end_rgno,
208+
xfs_rtbxlen_t rextents)
209+
{
210+
return 0;
211+
}
212+
213+
# define xfs_rtgroup_extents(mp, rgno) (0)
214+
# define xfs_update_last_rtgroup_size(mp, rgno) (-EOPNOTSUPP)
215+
#endif /* CONFIG_XFS_RT */
216+
217+
#endif /* __LIBXFS_RTGROUP_H */

0 commit comments

Comments
 (0)