xref: /linux/fs/xfs/libxfs/xfs_rtgroup.c (revision 6b3582aca37180fa1270867d7964e4023a59302f)
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * Copyright (c) 2022-2024 Oracle.  All Rights Reserved.
4  * Author: Darrick J. Wong <djwong@kernel.org>
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 #include "xfs_metafile.h"
34 #include "xfs_metadir.h"
35 
36 int
37 xfs_rtgroup_alloc(
38 	struct xfs_mount	*mp,
39 	xfs_rgnumber_t		rgno,
40 	xfs_rgnumber_t		rgcount,
41 	xfs_rtbxlen_t		rextents)
42 {
43 	struct xfs_rtgroup	*rtg;
44 	int			error;
45 
46 	rtg = kzalloc(sizeof(struct xfs_rtgroup), GFP_KERNEL);
47 	if (!rtg)
48 		return -ENOMEM;
49 
50 	error = xfs_group_insert(mp, rtg_group(rtg), rgno, XG_TYPE_RTG);
51 	if (error)
52 		goto out_free_rtg;
53 	return 0;
54 
55 out_free_rtg:
56 	kfree(rtg);
57 	return error;
58 }
59 
60 void
61 xfs_rtgroup_free(
62 	struct xfs_mount	*mp,
63 	xfs_rgnumber_t		rgno)
64 {
65 	xfs_group_free(mp, rgno, XG_TYPE_RTG, NULL);
66 }
67 
68 /* Free a range of incore rtgroup objects. */
69 void
70 xfs_free_rtgroups(
71 	struct xfs_mount	*mp,
72 	xfs_rgnumber_t		first_rgno,
73 	xfs_rgnumber_t		end_rgno)
74 {
75 	xfs_rgnumber_t		rgno;
76 
77 	for (rgno = first_rgno; rgno < end_rgno; rgno++)
78 		xfs_rtgroup_free(mp, rgno);
79 }
80 
81 /* Initialize some range of incore rtgroup objects. */
82 int
83 xfs_initialize_rtgroups(
84 	struct xfs_mount	*mp,
85 	xfs_rgnumber_t		first_rgno,
86 	xfs_rgnumber_t		end_rgno,
87 	xfs_rtbxlen_t		rextents)
88 {
89 	xfs_rgnumber_t		index;
90 	int			error;
91 
92 	if (first_rgno >= end_rgno)
93 		return 0;
94 
95 	for (index = first_rgno; index < end_rgno; index++) {
96 		error = xfs_rtgroup_alloc(mp, index, end_rgno, rextents);
97 		if (error)
98 			goto out_unwind_new_rtgs;
99 	}
100 
101 	return 0;
102 
103 out_unwind_new_rtgs:
104 	xfs_free_rtgroups(mp, first_rgno, index);
105 	return error;
106 }
107 
108 /* Compute the number of rt extents in this realtime group. */
109 xfs_rtxnum_t
110 __xfs_rtgroup_extents(
111 	struct xfs_mount	*mp,
112 	xfs_rgnumber_t		rgno,
113 	xfs_rgnumber_t		rgcount,
114 	xfs_rtbxlen_t		rextents)
115 {
116 	ASSERT(rgno < rgcount);
117 	if (rgno == rgcount - 1)
118 		return rextents - ((xfs_rtxnum_t)rgno * mp->m_sb.sb_rgextents);
119 
120 	ASSERT(xfs_has_rtgroups(mp));
121 	return mp->m_sb.sb_rgextents;
122 }
123 
124 xfs_rtxnum_t
125 xfs_rtgroup_extents(
126 	struct xfs_mount	*mp,
127 	xfs_rgnumber_t		rgno)
128 {
129 	return __xfs_rtgroup_extents(mp, rgno, mp->m_sb.sb_rgcount,
130 			mp->m_sb.sb_rextents);
131 }
132 
133 /*
134  * Update the rt extent count of the previous tail rtgroup if it changed during
135  * recovery (i.e. recovery of a growfs).
136  */
137 int
138 xfs_update_last_rtgroup_size(
139 	struct xfs_mount	*mp,
140 	xfs_rgnumber_t		prev_rgcount)
141 {
142 	struct xfs_rtgroup	*rtg;
143 
144 	ASSERT(prev_rgcount > 0);
145 
146 	rtg = xfs_rtgroup_grab(mp, prev_rgcount - 1);
147 	if (!rtg)
148 		return -EFSCORRUPTED;
149 	rtg->rtg_extents = __xfs_rtgroup_extents(mp, prev_rgcount - 1,
150 			mp->m_sb.sb_rgcount, mp->m_sb.sb_rextents);
151 	xfs_rtgroup_rele(rtg);
152 	return 0;
153 }
154 
155 /* Lock metadata inodes associated with this rt group. */
156 void
157 xfs_rtgroup_lock(
158 	struct xfs_rtgroup	*rtg,
159 	unsigned int		rtglock_flags)
160 {
161 	ASSERT(!(rtglock_flags & ~XFS_RTGLOCK_ALL_FLAGS));
162 	ASSERT(!(rtglock_flags & XFS_RTGLOCK_BITMAP_SHARED) ||
163 	       !(rtglock_flags & XFS_RTGLOCK_BITMAP));
164 
165 	if (rtglock_flags & XFS_RTGLOCK_BITMAP) {
166 		/*
167 		 * Lock both realtime free space metadata inodes for a freespace
168 		 * update.
169 		 */
170 		xfs_ilock(rtg->rtg_inodes[XFS_RTGI_BITMAP], XFS_ILOCK_EXCL);
171 		xfs_ilock(rtg->rtg_inodes[XFS_RTGI_SUMMARY], XFS_ILOCK_EXCL);
172 	} else if (rtglock_flags & XFS_RTGLOCK_BITMAP_SHARED) {
173 		xfs_ilock(rtg->rtg_inodes[XFS_RTGI_BITMAP], XFS_ILOCK_SHARED);
174 	}
175 }
176 
177 /* Unlock metadata inodes associated with this rt group. */
178 void
179 xfs_rtgroup_unlock(
180 	struct xfs_rtgroup	*rtg,
181 	unsigned int		rtglock_flags)
182 {
183 	ASSERT(!(rtglock_flags & ~XFS_RTGLOCK_ALL_FLAGS));
184 	ASSERT(!(rtglock_flags & XFS_RTGLOCK_BITMAP_SHARED) ||
185 	       !(rtglock_flags & XFS_RTGLOCK_BITMAP));
186 
187 	if (rtglock_flags & XFS_RTGLOCK_BITMAP) {
188 		xfs_iunlock(rtg->rtg_inodes[XFS_RTGI_SUMMARY], XFS_ILOCK_EXCL);
189 		xfs_iunlock(rtg->rtg_inodes[XFS_RTGI_BITMAP], XFS_ILOCK_EXCL);
190 	} else if (rtglock_flags & XFS_RTGLOCK_BITMAP_SHARED) {
191 		xfs_iunlock(rtg->rtg_inodes[XFS_RTGI_BITMAP], XFS_ILOCK_SHARED);
192 	}
193 }
194 
195 /*
196  * Join realtime group metadata inodes to the transaction.  The ILOCKs will be
197  * released on transaction commit.
198  */
199 void
200 xfs_rtgroup_trans_join(
201 	struct xfs_trans	*tp,
202 	struct xfs_rtgroup	*rtg,
203 	unsigned int		rtglock_flags)
204 {
205 	ASSERT(!(rtglock_flags & ~XFS_RTGLOCK_ALL_FLAGS));
206 	ASSERT(!(rtglock_flags & XFS_RTGLOCK_BITMAP_SHARED));
207 
208 	if (rtglock_flags & XFS_RTGLOCK_BITMAP) {
209 		xfs_trans_ijoin(tp, rtg->rtg_inodes[XFS_RTGI_BITMAP],
210 				XFS_ILOCK_EXCL);
211 		xfs_trans_ijoin(tp, rtg->rtg_inodes[XFS_RTGI_SUMMARY],
212 				XFS_ILOCK_EXCL);
213 	}
214 }
215 
216 #ifdef CONFIG_PROVE_LOCKING
217 static struct lock_class_key xfs_rtginode_lock_class;
218 
219 static int
220 xfs_rtginode_ilock_cmp_fn(
221 	const struct lockdep_map	*m1,
222 	const struct lockdep_map	*m2)
223 {
224 	const struct xfs_inode *ip1 =
225 		container_of(m1, struct xfs_inode, i_lock.dep_map);
226 	const struct xfs_inode *ip2 =
227 		container_of(m2, struct xfs_inode, i_lock.dep_map);
228 
229 	if (ip1->i_projid < ip2->i_projid)
230 		return -1;
231 	if (ip1->i_projid > ip2->i_projid)
232 		return 1;
233 	return 0;
234 }
235 
236 static inline void
237 xfs_rtginode_ilock_print_fn(
238 	const struct lockdep_map	*m)
239 {
240 	const struct xfs_inode *ip =
241 		container_of(m, struct xfs_inode, i_lock.dep_map);
242 
243 	printk(KERN_CONT " rgno=%u", ip->i_projid);
244 }
245 
246 /*
247  * Most of the time each of the RTG inode locks are only taken one at a time.
248  * But when committing deferred ops, more than one of a kind can be taken.
249  * However, deferred rt ops will be committed in rgno order so there is no
250  * potential for deadlocks.  The code here is needed to tell lockdep about this
251  * order.
252  */
253 static inline void
254 xfs_rtginode_lockdep_setup(
255 	struct xfs_inode	*ip,
256 	xfs_rgnumber_t		rgno,
257 	enum xfs_rtg_inodes	type)
258 {
259 	lockdep_set_class_and_subclass(&ip->i_lock, &xfs_rtginode_lock_class,
260 			type);
261 	lock_set_cmp_fn(&ip->i_lock, xfs_rtginode_ilock_cmp_fn,
262 			xfs_rtginode_ilock_print_fn);
263 }
264 #else
265 #define xfs_rtginode_lockdep_setup(ip, rgno, type)	do { } while (0)
266 #endif /* CONFIG_PROVE_LOCKING */
267 
268 struct xfs_rtginode_ops {
269 	const char		*name;	/* short name */
270 
271 	enum xfs_metafile_type	metafile_type;
272 
273 	/* Does the fs have this feature? */
274 	bool			(*enabled)(struct xfs_mount *mp);
275 
276 	/* Create this rtgroup metadata inode and initialize it. */
277 	int			(*create)(struct xfs_rtgroup *rtg,
278 					  struct xfs_inode *ip,
279 					  struct xfs_trans *tp,
280 					  bool init);
281 };
282 
283 static const struct xfs_rtginode_ops xfs_rtginode_ops[XFS_RTGI_MAX] = {
284 	[XFS_RTGI_BITMAP] = {
285 		.name		= "bitmap",
286 		.metafile_type	= XFS_METAFILE_RTBITMAP,
287 		.create		= xfs_rtbitmap_create,
288 	},
289 	[XFS_RTGI_SUMMARY] = {
290 		.name		= "summary",
291 		.metafile_type	= XFS_METAFILE_RTSUMMARY,
292 		.create		= xfs_rtsummary_create,
293 	},
294 };
295 
296 /* Return the shortname of this rtgroup inode. */
297 const char *
298 xfs_rtginode_name(
299 	enum xfs_rtg_inodes	type)
300 {
301 	return xfs_rtginode_ops[type].name;
302 }
303 
304 /* Return the metafile type of this rtgroup inode. */
305 enum xfs_metafile_type
306 xfs_rtginode_metafile_type(
307 	enum xfs_rtg_inodes	type)
308 {
309 	return xfs_rtginode_ops[type].metafile_type;
310 }
311 
312 /* Should this rtgroup inode be present? */
313 bool
314 xfs_rtginode_enabled(
315 	struct xfs_rtgroup	*rtg,
316 	enum xfs_rtg_inodes	type)
317 {
318 	const struct xfs_rtginode_ops *ops = &xfs_rtginode_ops[type];
319 
320 	if (!ops->enabled)
321 		return true;
322 	return ops->enabled(rtg_mount(rtg));
323 }
324 
325 /* Load and existing rtgroup inode into the rtgroup structure. */
326 int
327 xfs_rtginode_load(
328 	struct xfs_rtgroup	*rtg,
329 	enum xfs_rtg_inodes	type,
330 	struct xfs_trans	*tp)
331 {
332 	struct xfs_mount	*mp = tp->t_mountp;
333 	struct xfs_inode	*ip;
334 	const struct xfs_rtginode_ops *ops = &xfs_rtginode_ops[type];
335 	int			error;
336 
337 	if (!xfs_rtginode_enabled(rtg, type))
338 		return 0;
339 
340 	if (!xfs_has_rtgroups(mp)) {
341 		xfs_ino_t	ino;
342 
343 		switch (type) {
344 		case XFS_RTGI_BITMAP:
345 			ino = mp->m_sb.sb_rbmino;
346 			break;
347 		case XFS_RTGI_SUMMARY:
348 			ino = mp->m_sb.sb_rsumino;
349 			break;
350 		default:
351 			/* None of the other types exist on !rtgroups */
352 			return 0;
353 		}
354 
355 		error = xfs_trans_metafile_iget(tp, ino, ops->metafile_type,
356 				&ip);
357 	} else {
358 		const char	*path;
359 
360 		if (!mp->m_rtdirip)
361 			return -EFSCORRUPTED;
362 
363 		path = xfs_rtginode_path(rtg_rgno(rtg), type);
364 		if (!path)
365 			return -ENOMEM;
366 		error = xfs_metadir_load(tp, mp->m_rtdirip, path,
367 				ops->metafile_type, &ip);
368 		kfree(path);
369 	}
370 
371 	if (error)
372 		return error;
373 
374 	if (XFS_IS_CORRUPT(mp, ip->i_df.if_format != XFS_DINODE_FMT_EXTENTS &&
375 			       ip->i_df.if_format != XFS_DINODE_FMT_BTREE)) {
376 		xfs_irele(ip);
377 		return -EFSCORRUPTED;
378 	}
379 
380 	if (XFS_IS_CORRUPT(mp, ip->i_projid != rtg_rgno(rtg))) {
381 		xfs_irele(ip);
382 		return -EFSCORRUPTED;
383 	}
384 
385 	xfs_rtginode_lockdep_setup(ip, rtg_rgno(rtg), type);
386 	rtg->rtg_inodes[type] = ip;
387 	return 0;
388 }
389 
390 /* Release an rtgroup metadata inode. */
391 void
392 xfs_rtginode_irele(
393 	struct xfs_inode	**ipp)
394 {
395 	if (*ipp)
396 		xfs_irele(*ipp);
397 	*ipp = NULL;
398 }
399 
400 /* Add a metadata inode for a realtime rmap btree. */
401 int
402 xfs_rtginode_create(
403 	struct xfs_rtgroup		*rtg,
404 	enum xfs_rtg_inodes		type,
405 	bool				init)
406 {
407 	const struct xfs_rtginode_ops	*ops = &xfs_rtginode_ops[type];
408 	struct xfs_mount		*mp = rtg_mount(rtg);
409 	struct xfs_metadir_update	upd = {
410 		.dp			= mp->m_rtdirip,
411 		.metafile_type		= ops->metafile_type,
412 	};
413 	int				error;
414 
415 	if (!xfs_rtginode_enabled(rtg, type))
416 		return 0;
417 
418 	if (!mp->m_rtdirip)
419 		return -EFSCORRUPTED;
420 
421 	upd.path = xfs_rtginode_path(rtg_rgno(rtg), type);
422 	if (!upd.path)
423 		return -ENOMEM;
424 
425 	error = xfs_metadir_start_create(&upd);
426 	if (error)
427 		goto out_path;
428 
429 	error = xfs_metadir_create(&upd, S_IFREG);
430 	if (error)
431 		return error;
432 
433 	xfs_rtginode_lockdep_setup(upd.ip, rtg_rgno(rtg), type);
434 
435 	upd.ip->i_projid = rtg_rgno(rtg);
436 	error = ops->create(rtg, upd.ip, upd.tp, init);
437 	if (error)
438 		goto out_cancel;
439 
440 	error = xfs_metadir_commit(&upd);
441 	if (error)
442 		goto out_path;
443 
444 	kfree(upd.path);
445 	xfs_finish_inode_setup(upd.ip);
446 	rtg->rtg_inodes[type] = upd.ip;
447 	return 0;
448 
449 out_cancel:
450 	xfs_metadir_cancel(&upd, error);
451 	/* Have to finish setting up the inode to ensure it's deleted. */
452 	if (upd.ip) {
453 		xfs_finish_inode_setup(upd.ip);
454 		xfs_irele(upd.ip);
455 	}
456 out_path:
457 	kfree(upd.path);
458 	return error;
459 }
460 
461 /* Create the parent directory for all rtgroup inodes and load it. */
462 int
463 xfs_rtginode_mkdir_parent(
464 	struct xfs_mount	*mp)
465 {
466 	if (!mp->m_metadirip)
467 		return -EFSCORRUPTED;
468 
469 	return xfs_metadir_mkdir(mp->m_metadirip, "rtgroups", &mp->m_rtdirip);
470 }
471 
472 /* Load the parent directory of all rtgroup inodes. */
473 int
474 xfs_rtginode_load_parent(
475 	struct xfs_trans	*tp)
476 {
477 	struct xfs_mount	*mp = tp->t_mountp;
478 
479 	if (!mp->m_metadirip)
480 		return -EFSCORRUPTED;
481 
482 	return xfs_metadir_load(tp, mp->m_metadirip, "rtgroups",
483 			XFS_METAFILE_DIR, &mp->m_rtdirip);
484 }
485