Skip to content

Commit 65b1231

Browse files
author
Darrick J. Wong
committed
xfs: support caching rtgroup metadata inodes
Create the necessary per-rtgroup infrastructure that we need to load metadata inodes into memory. Signed-off-by: Darrick J. Wong <[email protected]> Reviewed-by: Christoph Hellwig <[email protected]>
1 parent c29237a commit 65b1231

File tree

4 files changed

+217
-3
lines changed

4 files changed

+217
-3
lines changed

fs/xfs/libxfs/xfs_rtgroup.c

Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@
3030
#include "xfs_icache.h"
3131
#include "xfs_rtgroup.h"
3232
#include "xfs_rtbitmap.h"
33+
#include "xfs_metafile.h"
34+
#include "xfs_metadir.h"
3335

3436
int
3537
xfs_rtgroup_alloc(
@@ -250,3 +252,124 @@ xfs_rtginode_lockdep_setup(
250252
#else
251253
#define xfs_rtginode_lockdep_setup(ip, rgno, type) do { } while (0)
252254
#endif /* CONFIG_PROVE_LOCKING */
255+
256+
struct xfs_rtginode_ops {
257+
const char *name; /* short name */
258+
259+
enum xfs_metafile_type metafile_type;
260+
261+
/* Does the fs have this feature? */
262+
bool (*enabled)(struct xfs_mount *mp);
263+
};
264+
265+
static const struct xfs_rtginode_ops xfs_rtginode_ops[XFS_RTGI_MAX] = {
266+
};
267+
268+
/* Return the shortname of this rtgroup inode. */
269+
const char *
270+
xfs_rtginode_name(
271+
enum xfs_rtg_inodes type)
272+
{
273+
return xfs_rtginode_ops[type].name;
274+
}
275+
276+
/* Return the metafile type of this rtgroup inode. */
277+
enum xfs_metafile_type
278+
xfs_rtginode_metafile_type(
279+
enum xfs_rtg_inodes type)
280+
{
281+
return xfs_rtginode_ops[type].metafile_type;
282+
}
283+
284+
/* Should this rtgroup inode be present? */
285+
bool
286+
xfs_rtginode_enabled(
287+
struct xfs_rtgroup *rtg,
288+
enum xfs_rtg_inodes type)
289+
{
290+
const struct xfs_rtginode_ops *ops = &xfs_rtginode_ops[type];
291+
292+
if (!ops->enabled)
293+
return true;
294+
return ops->enabled(rtg_mount(rtg));
295+
}
296+
297+
/* Load and existing rtgroup inode into the rtgroup structure. */
298+
int
299+
xfs_rtginode_load(
300+
struct xfs_rtgroup *rtg,
301+
enum xfs_rtg_inodes type,
302+
struct xfs_trans *tp)
303+
{
304+
struct xfs_mount *mp = tp->t_mountp;
305+
const char *path;
306+
struct xfs_inode *ip;
307+
const struct xfs_rtginode_ops *ops = &xfs_rtginode_ops[type];
308+
int error;
309+
310+
if (!xfs_rtginode_enabled(rtg, type))
311+
return 0;
312+
313+
if (!mp->m_rtdirip)
314+
return -EFSCORRUPTED;
315+
316+
path = xfs_rtginode_path(rtg_rgno(rtg), type);
317+
if (!path)
318+
return -ENOMEM;
319+
error = xfs_metadir_load(tp, mp->m_rtdirip, path, ops->metafile_type,
320+
&ip);
321+
kfree(path);
322+
323+
if (error)
324+
return error;
325+
326+
if (XFS_IS_CORRUPT(mp, ip->i_df.if_format != XFS_DINODE_FMT_EXTENTS &&
327+
ip->i_df.if_format != XFS_DINODE_FMT_BTREE)) {
328+
xfs_irele(ip);
329+
return -EFSCORRUPTED;
330+
}
331+
332+
if (XFS_IS_CORRUPT(mp, ip->i_projid != rtg_rgno(rtg))) {
333+
xfs_irele(ip);
334+
return -EFSCORRUPTED;
335+
}
336+
337+
xfs_rtginode_lockdep_setup(ip, rtg_rgno(rtg), type);
338+
rtg->rtg_inodes[type] = ip;
339+
return 0;
340+
}
341+
342+
/* Release an rtgroup metadata inode. */
343+
void
344+
xfs_rtginode_irele(
345+
struct xfs_inode **ipp)
346+
{
347+
if (*ipp)
348+
xfs_irele(*ipp);
349+
*ipp = NULL;
350+
}
351+
352+
/* Create the parent directory for all rtgroup inodes and load it. */
353+
int
354+
xfs_rtginode_mkdir_parent(
355+
struct xfs_mount *mp)
356+
{
357+
if (!mp->m_metadirip)
358+
return -EFSCORRUPTED;
359+
360+
return xfs_metadir_mkdir(mp->m_metadirip, "rtgroups", &mp->m_rtdirip);
361+
}
362+
363+
/* Load the parent directory of all rtgroup inodes. */
364+
int
365+
xfs_rtginode_load_parent(
366+
struct xfs_trans *tp)
367+
{
368+
struct xfs_mount *mp = tp->t_mountp;
369+
370+
if (!mp->m_metadirip)
371+
return -EFSCORRUPTED;
372+
373+
return xfs_metadir_load(tp, mp->m_metadirip, "rtgroups",
374+
XFS_METAFILE_DIR, &mp->m_rtdirip);
375+
}

fs/xfs/libxfs/xfs_rtgroup.h

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,23 @@
1111
struct xfs_mount;
1212
struct xfs_trans;
1313

14+
enum xfs_rtg_inodes {
15+
XFS_RTGI_MAX,
16+
};
17+
18+
#ifdef MAX_LOCKDEP_SUBCLASSES
19+
static_assert(XFS_RTGI_MAX <= MAX_LOCKDEP_SUBCLASSES);
20+
#endif
21+
1422
/*
1523
* Realtime group incore structure, similar to the per-AG structure.
1624
*/
1725
struct xfs_rtgroup {
1826
struct xfs_group rtg_group;
1927

28+
/* per-rtgroup metadata inodes */
29+
struct xfs_inode *rtg_inodes[1 /* hack */];
30+
2031
/* Number of blocks in this group */
2132
xfs_rtxnum_t rtg_extents;
2233
};
@@ -210,6 +221,22 @@ void xfs_rtgroup_lock(struct xfs_rtgroup *rtg, unsigned int rtglock_flags);
210221
void xfs_rtgroup_unlock(struct xfs_rtgroup *rtg, unsigned int rtglock_flags);
211222
void xfs_rtgroup_trans_join(struct xfs_trans *tp, struct xfs_rtgroup *rtg,
212223
unsigned int rtglock_flags);
224+
225+
int xfs_rtginode_mkdir_parent(struct xfs_mount *mp);
226+
int xfs_rtginode_load_parent(struct xfs_trans *tp);
227+
228+
const char *xfs_rtginode_name(enum xfs_rtg_inodes type);
229+
enum xfs_metafile_type xfs_rtginode_metafile_type(enum xfs_rtg_inodes type);
230+
bool xfs_rtginode_enabled(struct xfs_rtgroup *rtg, enum xfs_rtg_inodes type);
231+
int xfs_rtginode_load(struct xfs_rtgroup *rtg, enum xfs_rtg_inodes type,
232+
struct xfs_trans *tp);
233+
void xfs_rtginode_irele(struct xfs_inode **ipp);
234+
235+
static inline const char *xfs_rtginode_path(xfs_rgnumber_t rgno,
236+
enum xfs_rtg_inodes type)
237+
{
238+
return kasprintf(GFP_KERNEL, "%u.%s", rgno, xfs_rtginode_name(type));
239+
}
213240
#else
214241
static inline void xfs_free_rtgroups(struct xfs_mount *mp,
215242
xfs_rgnumber_t first_rgno, xfs_rgnumber_t end_rgno)

fs/xfs/xfs_mount.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,7 @@ typedef struct xfs_mount {
128128
struct xfs_inode *m_rsumip; /* pointer to summary inode */
129129
struct xfs_inode *m_rootip; /* pointer to root directory */
130130
struct xfs_inode *m_metadirip; /* ptr to metadata directory */
131+
struct xfs_inode *m_rtdirip; /* ptr to realtime metadir */
131132
struct xfs_quotainfo *m_quotainfo; /* disk quota information */
132133
struct xfs_buftarg *m_ddev_targp; /* data device */
133134
struct xfs_buftarg *m_logdev_targp;/* log device */

fs/xfs/xfs_rtalloc.c

Lines changed: 66 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
#include "xfs_da_format.h"
2929
#include "xfs_metafile.h"
3030
#include "xfs_rtgroup.h"
31+
#include "xfs_error.h"
3132

3233
/*
3334
* Return whether there are any free extents in the size range given
@@ -652,6 +653,16 @@ xfs_rtallocate_extent_size(
652653
return -ENOSPC;
653654
}
654655

656+
static void
657+
xfs_rtunmount_rtg(
658+
struct xfs_rtgroup *rtg)
659+
{
660+
int i;
661+
662+
for (i = 0; i < XFS_RTGI_MAX; i++)
663+
xfs_rtginode_irele(&rtg->rtg_inodes[i]);
664+
}
665+
655666
static int
656667
xfs_alloc_rsum_cache(
657668
struct xfs_mount *mp,
@@ -1127,6 +1138,43 @@ xfs_rtmount_iread_extents(
11271138
return error;
11281139
}
11291140

1141+
static void
1142+
xfs_rtgroup_unmount_inodes(
1143+
struct xfs_mount *mp)
1144+
{
1145+
struct xfs_rtgroup *rtg = NULL;
1146+
1147+
while ((rtg = xfs_rtgroup_next(mp, rtg)))
1148+
xfs_rtunmount_rtg(rtg);
1149+
xfs_rtginode_irele(&mp->m_rtdirip);
1150+
}
1151+
1152+
static int
1153+
xfs_rtmount_rtg(
1154+
struct xfs_mount *mp,
1155+
struct xfs_trans *tp,
1156+
struct xfs_rtgroup *rtg)
1157+
{
1158+
int error, i;
1159+
1160+
rtg->rtg_extents = xfs_rtgroup_extents(mp, rtg_rgno(rtg));
1161+
1162+
for (i = 0; i < XFS_RTGI_MAX; i++) {
1163+
error = xfs_rtginode_load(rtg, i, tp);
1164+
if (error)
1165+
return error;
1166+
1167+
if (rtg->rtg_inodes[i]) {
1168+
error = xfs_rtmount_iread_extents(tp,
1169+
rtg->rtg_inodes[i], 0);
1170+
if (error)
1171+
return error;
1172+
}
1173+
}
1174+
1175+
return 0;
1176+
}
1177+
11301178
/*
11311179
* Get the bitmap and summary inodes and the summary cache into the mount
11321180
* structure at mount time.
@@ -1168,15 +1216,28 @@ xfs_rtmount_inodes(
11681216
if (error)
11691217
goto out_rele_summary;
11701218

1171-
while ((rtg = xfs_rtgroup_next(mp, rtg)))
1172-
rtg->rtg_extents = xfs_rtgroup_extents(mp, rtg_rgno(rtg));
1219+
if (xfs_has_rtgroups(mp) && mp->m_sb.sb_rgcount > 0) {
1220+
error = xfs_rtginode_load_parent(tp);
1221+
if (error)
1222+
goto out_rele_summary;
1223+
}
1224+
1225+
while ((rtg = xfs_rtgroup_next(mp, rtg))) {
1226+
error = xfs_rtmount_rtg(mp, tp, rtg);
1227+
if (error) {
1228+
xfs_rtgroup_rele(rtg);
1229+
goto out_rele_inodes;
1230+
}
1231+
}
11731232

11741233
error = xfs_alloc_rsum_cache(mp, sbp->sb_rbmblocks);
11751234
if (error)
1176-
goto out_rele_summary;
1235+
goto out_rele_inodes;
11771236
xfs_trans_cancel(tp);
11781237
return 0;
11791238

1239+
out_rele_inodes:
1240+
xfs_rtgroup_unmount_inodes(mp);
11801241
out_rele_summary:
11811242
xfs_irele(mp->m_rsumip);
11821243
out_rele_bitmap:
@@ -1191,6 +1252,8 @@ xfs_rtunmount_inodes(
11911252
struct xfs_mount *mp)
11921253
{
11931254
kvfree(mp->m_rsum_cache);
1255+
1256+
xfs_rtgroup_unmount_inodes(mp);
11941257
if (mp->m_rbmip)
11951258
xfs_irele(mp->m_rbmip);
11961259
if (mp->m_rsumip)

0 commit comments

Comments
 (0)