Line data Source code
1 : // SPDX-License-Identifier: GPL-2.0-or-later
2 : /*
3 : * Copyright (C) 2018-2023 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_log_format.h"
11 : #include "xfs_trans_resv.h"
12 : #include "xfs_bit.h"
13 : #include "xfs_sb.h"
14 : #include "xfs_mount.h"
15 : #include "xfs_defer.h"
16 : #include "xfs_trans.h"
17 : #include "xfs_imeta.h"
18 : #include "xfs_trace.h"
19 : #include "xfs_inode.h"
20 : #include "xfs_quota.h"
21 : #include "xfs_ialloc.h"
22 : #include "xfs_bmap_btree.h"
23 : #include "xfs_da_format.h"
24 : #include "xfs_da_btree.h"
25 : #include "xfs_trans_space.h"
26 : #include "xfs_ag.h"
27 : #include "xfs_dir2.h"
28 : #include "xfs_dir2_priv.h"
29 : #include "xfs_health.h"
30 : #include "xfs_errortag.h"
31 : #include "xfs_error.h"
32 : #include "xfs_btree.h"
33 : #include "xfs_alloc.h"
34 :
35 : /*
36 : * Metadata File Management
37 : * ========================
38 : *
39 : * These functions provide an abstraction layer for looking up, creating, and
40 : * deleting metadata inodes. These pointers live in the in-core superblock,
41 : * so the functions moderate access to those fields and take care of logging.
42 : *
43 : * For the five existing metadata inodes (real time bitmap & summary; and the
44 : * user, group, and quotas) we'll continue to maintain the in-core superblock
45 : * inodes for reads and only require xfs_imeta_create and xfs_imeta_unlink to
46 : * persist changes. New metadata inode types must only use the xfs_imeta_*
47 : * functions.
48 : *
49 : * Callers wishing to create or unlink a metadata inode must pass in a
50 : * xfs_imeta_end structure. After committing or cancelling the transaction,
51 : * this structure must be passed to xfs_imeta_end_update to free resources that
52 : * cannot be freed during the transaction.
53 : *
54 : * When the metadata directory tree (metadir) feature is enabled, we can create
55 : * a complex directory tree in which to store metadata inodes. Inodes within
56 : * the metadata directory tree should have the "metadata" inode flag set to
57 : * prevent them from being exposed to the outside world.
58 : *
59 : * Callers are not expected to take the IOLOCK of metadata directories. They
60 : * are expected to take the ILOCK of any inode in the metadata directory tree
61 : * (just like the regular to synchronize access to that inode. It is not
62 : * necessary to take the MMAPLOCK since metadata inodes should never be exposed
63 : * to user space.
64 : */
65 :
66 : /* Static metadata inode paths */
67 : static const unsigned char *rtbitmap_path[] = {"realtime", "bitmap"};
68 : static const unsigned char *rtsummary_path[] = {"realtime", "summary"};
69 : static const unsigned char *usrquota_path[] = {"quota", "user"};
70 : static const unsigned char *grpquota_path[] = {"quota", "group"};
71 : static const unsigned char *prjquota_path[] = {"quota", "project"};
72 :
73 : XFS_IMETA_DEFINE_PATH(XFS_IMETA_RTBITMAP, rtbitmap_path);
74 : XFS_IMETA_DEFINE_PATH(XFS_IMETA_RTSUMMARY, rtsummary_path);
75 : XFS_IMETA_DEFINE_PATH(XFS_IMETA_USRQUOTA, usrquota_path);
76 : XFS_IMETA_DEFINE_PATH(XFS_IMETA_GRPQUOTA, grpquota_path);
77 : XFS_IMETA_DEFINE_PATH(XFS_IMETA_PRJQUOTA, prjquota_path);
78 :
79 : const struct xfs_imeta_path XFS_IMETA_METADIR = {
80 : .im_depth = 0,
81 : .im_ftype = XFS_DIR3_FT_DIR,
82 : };
83 :
84 : /* Are these two paths equal? */
85 : STATIC bool
86 845114 : xfs_imeta_path_compare(
87 : const struct xfs_imeta_path *a,
88 : const struct xfs_imeta_path *b)
89 : {
90 845114 : unsigned int i;
91 :
92 845114 : if (a == b)
93 : return true;
94 :
95 805854 : if (a->im_depth != b->im_depth)
96 : return false;
97 :
98 199652 : for (i = 0; i < a->im_depth; i++)
99 199652 : if (a->im_path[i] != b->im_path[i] &&
100 160667 : strcmp(a->im_path[i], b->im_path[i]))
101 : return false;
102 :
103 : return true;
104 : }
105 :
106 : /* Is this path ok? */
107 : static inline bool
108 : xfs_imeta_path_check(
109 : const struct xfs_imeta_path *path)
110 : {
111 281473 : return path->im_depth <= XFS_IMETA_MAX_DEPTH;
112 : }
113 :
114 : /* Functions for storing and retrieving superblock inode values. */
115 :
116 : /* Mapping of metadata inode paths to in-core superblock values. */
117 : static const struct xfs_imeta_sbmap {
118 : const struct xfs_imeta_path *path;
119 : unsigned int offset;
120 : } xfs_imeta_sbmaps[] = {
121 : {
122 : .path = &XFS_IMETA_RTBITMAP,
123 : .offset = offsetof(struct xfs_sb, sb_rbmino),
124 : },
125 : {
126 : .path = &XFS_IMETA_RTSUMMARY,
127 : .offset = offsetof(struct xfs_sb, sb_rsumino),
128 : },
129 : {
130 : .path = &XFS_IMETA_USRQUOTA,
131 : .offset = offsetof(struct xfs_sb, sb_uquotino),
132 : },
133 : {
134 : .path = &XFS_IMETA_GRPQUOTA,
135 : .offset = offsetof(struct xfs_sb, sb_gquotino),
136 : },
137 : {
138 : .path = &XFS_IMETA_PRJQUOTA,
139 : .offset = offsetof(struct xfs_sb, sb_pquotino),
140 : },
141 : {
142 : .path = &XFS_IMETA_METADIR,
143 : .offset = offsetof(struct xfs_sb, sb_metadirino),
144 : },
145 : { NULL, 0 },
146 : };
147 :
148 : /* Return a pointer to the in-core superblock inode value. */
149 : static inline xfs_ino_t *
150 : xfs_imeta_sbmap_to_inop(
151 : struct xfs_mount *mp,
152 : const struct xfs_imeta_sbmap *map)
153 : {
154 >51351*10^7 : return (xfs_ino_t *)(((char *)&mp->m_sb) + map->offset);
155 : }
156 :
157 : /* Compute location of metadata inode pointer in the in-core superblock */
158 : static inline xfs_ino_t *
159 57423 : xfs_imeta_path_to_sb_inop(
160 : struct xfs_mount *mp,
161 : const struct xfs_imeta_path *path)
162 : {
163 57423 : const struct xfs_imeta_sbmap *p;
164 :
165 283906 : for (p = xfs_imeta_sbmaps; p->path; p++)
166 265743 : if (xfs_imeta_path_compare(p->path, path))
167 39260 : return xfs_imeta_sbmap_to_inop(mp, p);
168 :
169 : return NULL;
170 : }
171 :
172 : /* Look up a superblock metadata inode by its path. */
173 : STATIC int
174 0 : xfs_imeta_sb_lookup(
175 : struct xfs_mount *mp,
176 : const struct xfs_imeta_path *path,
177 : xfs_ino_t *inop)
178 : {
179 0 : xfs_ino_t *sb_inop;
180 :
181 0 : sb_inop = xfs_imeta_path_to_sb_inop(mp, path);
182 0 : if (!sb_inop)
183 : return -EINVAL;
184 :
185 0 : trace_xfs_imeta_sb_lookup(mp, sb_inop);
186 0 : *inop = *sb_inop;
187 0 : return 0;
188 : }
189 :
190 : /* Update inode pointers in the superblock. */
191 : static inline void
192 4097 : xfs_imeta_log_sb(
193 : struct xfs_trans *tp)
194 : {
195 4097 : struct xfs_mount *mp = tp->t_mountp;
196 4097 : struct xfs_buf *bp = xfs_trans_getsb(tp);
197 :
198 : /*
199 : * Update the inode flags in the ondisk superblock without touching
200 : * the summary counters. We have not quiesced inode chunk allocation,
201 : * so we cannot coordinate with updates to the icount and ifree percpu
202 : * counters.
203 : */
204 4097 : xfs_sb_to_disk(bp->b_addr, &mp->m_sb);
205 4097 : xfs_trans_buf_set_type(tp, bp, XFS_BLFT_SB_BUF);
206 4097 : xfs_trans_log_buf(tp, bp, 0, sizeof(struct xfs_dsb) - 1);
207 4097 : }
208 :
209 : /*
210 : * Create a new metadata inode and set a superblock pointer to this new inode.
211 : * The superblock field must not already be pointing to an inode.
212 : */
213 : STATIC int
214 4097 : xfs_imeta_sb_create(
215 : struct xfs_imeta_update *upd,
216 : umode_t mode)
217 : {
218 8194 : struct xfs_icreate_args args = {
219 4097 : .nlink = S_ISDIR(mode) ? 2 : 1,
220 : };
221 4097 : struct xfs_mount *mp = upd->mp;
222 4097 : xfs_ino_t *sb_inop;
223 4097 : xfs_ino_t ino;
224 4097 : int error;
225 :
226 : /* Files rooted in the superblock do not have parents. */
227 4097 : xfs_icreate_args_rootfile(&args, mp, mode, false);
228 :
229 : /* Reject if the sb already points to some inode. */
230 4097 : sb_inop = xfs_imeta_path_to_sb_inop(mp, upd->path);
231 4097 : if (!sb_inop)
232 : return -EINVAL;
233 :
234 4097 : if (*sb_inop != NULLFSINO)
235 : return -EEXIST;
236 :
237 : /* Create a new inode and set the sb pointer. */
238 4097 : error = xfs_dialloc(&upd->tp, NULL, mode, &ino);
239 4097 : if (error)
240 : return error;
241 4097 : error = xfs_icreate(upd->tp, ino, &args, &upd->ip);
242 4097 : if (error)
243 : return error;
244 4097 : upd->ip_locked = true;
245 :
246 : /*
247 : * If we ever need the ability to create rt metadata files on a
248 : * pre-metadir filesystem, we'll need to dqattach the child here.
249 : * Currently we assume that mkfs will create the files and quotacheck
250 : * will account for them.
251 : */
252 :
253 : /* Update superblock pointer. */
254 4097 : *sb_inop = ino;
255 4097 : xfs_imeta_log_sb(upd->tp);
256 :
257 4097 : trace_xfs_imeta_sb_create(upd);
258 4097 : return 0;
259 : }
260 :
261 : /*
262 : * Clear the given inode pointer from the superblock and drop the link count
263 : * of the metadata inode.
264 : */
265 : STATIC int
266 0 : xfs_imeta_sb_unlink(
267 : struct xfs_imeta_update *upd)
268 : {
269 0 : struct xfs_mount *mp = upd->mp;
270 0 : xfs_ino_t *sb_inop;
271 :
272 0 : ASSERT(xfs_isilocked(upd->ip, XFS_ILOCK_EXCL));
273 :
274 0 : sb_inop = xfs_imeta_path_to_sb_inop(mp, upd->path);
275 0 : if (!sb_inop)
276 : return -EINVAL;
277 :
278 : /* Reject if the sb doesn't point to the inode that was passed in. */
279 0 : if (*sb_inop != upd->ip->i_ino)
280 : return -ENOENT;
281 :
282 0 : trace_xfs_imeta_sb_unlink(upd);
283 :
284 0 : *sb_inop = NULLFSINO;
285 0 : xfs_imeta_log_sb(upd->tp);
286 0 : return xfs_droplink(upd->tp, upd->ip);
287 : }
288 :
289 : /* Set the given inode pointer in the superblock. */
290 : STATIC int
291 0 : xfs_imeta_sb_link(
292 : struct xfs_imeta_update *upd)
293 : {
294 0 : struct xfs_mount *mp = upd->mp;
295 0 : xfs_ino_t *sb_inop;
296 :
297 0 : ASSERT(xfs_isilocked(upd->ip, XFS_ILOCK_EXCL));
298 :
299 0 : sb_inop = xfs_imeta_path_to_sb_inop(mp, upd->path);
300 0 : if (!sb_inop)
301 : return -EINVAL;
302 0 : if (*sb_inop != NULLFSINO)
303 : return -EEXIST;
304 :
305 0 : trace_xfs_imeta_sb_link(upd);
306 :
307 0 : xfs_bumplink(upd->tp, upd->ip);
308 0 : xfs_imeta_log_sb(upd->tp);
309 :
310 0 : *sb_inop = upd->ip->i_ino;
311 0 : return 0;
312 : }
313 :
314 : /* Functions for storing and retrieving metadata directory inode values. */
315 :
316 : static inline void
317 1060440 : xfs_imeta_set_xname(
318 : struct xfs_name *xname,
319 : const struct xfs_imeta_path *path,
320 : unsigned int path_idx,
321 : unsigned char ftype)
322 : {
323 1060440 : xname->name = (const unsigned char *)path->im_path[path_idx];
324 1060440 : xname->len = strlen(path->im_path[path_idx]);
325 1060440 : xname->type = ftype;
326 1060440 : }
327 :
328 : /*
329 : * Look up the inode number and filetype for an exact name in a directory.
330 : * Caller must hold ILOCK_EXCL.
331 : */
332 : static inline int
333 1060440 : xfs_imeta_dir_lookup(
334 : struct xfs_inode *dp,
335 : struct xfs_name *xname,
336 : xfs_ino_t *ino)
337 : {
338 2120880 : struct xfs_da_args args = {
339 : .dp = dp,
340 1060440 : .geo = dp->i_mount->m_dir_geo,
341 1060440 : .name = xname->name,
342 1060440 : .namelen = xname->len,
343 1060440 : .hashval = xfs_dir2_hashname(dp->i_mount, xname),
344 : .whichfork = XFS_DATA_FORK,
345 : .op_flags = XFS_DA_OP_OKNOENT,
346 1060440 : .owner = dp->i_ino,
347 : };
348 1060440 : bool isblock, isleaf;
349 1060440 : int error;
350 :
351 2120880 : if (xfs_is_shutdown(dp->i_mount))
352 : return -EIO;
353 :
354 1060440 : if (dp->i_df.if_format == XFS_DINODE_FMT_LOCAL) {
355 828280 : error = xfs_dir2_sf_lookup(&args);
356 828280 : goto out_unlock;
357 : }
358 :
359 : /* dir2 functions require that the data fork is loaded */
360 232160 : error = xfs_iread_extents(NULL, dp, XFS_DATA_FORK);
361 232160 : if (error)
362 0 : goto out_unlock;
363 :
364 232160 : error = xfs_dir2_isblock(&args, &isblock);
365 232160 : if (error)
366 0 : goto out_unlock;
367 :
368 232160 : if (isblock) {
369 214063 : error = xfs_dir2_block_lookup(&args);
370 214063 : goto out_unlock;
371 : }
372 :
373 18097 : error = xfs_dir2_isleaf(&args, &isleaf);
374 18097 : if (error)
375 0 : goto out_unlock;
376 :
377 18097 : if (isleaf) {
378 1880 : error = xfs_dir2_leaf_lookup(&args);
379 1880 : goto out_unlock;
380 : }
381 :
382 16217 : error = xfs_dir2_node_lookup(&args);
383 :
384 1060440 : out_unlock:
385 1060440 : if (error == -EEXIST)
386 : error = 0;
387 112526 : if (error)
388 : return error;
389 :
390 947914 : *ino = args.inumber;
391 947914 : xname->type = args.filetype;
392 947914 : return 0;
393 : }
394 :
395 : /*
396 : * Given a parent directory @dp and a metadata inode path component @xname,
397 : * Look up the inode number in the directory, returning it in @ino.
398 : * @xname.type must match the directory entry's ftype.
399 : *
400 : * Caller must hold ILOCK_EXCL.
401 : */
402 : static inline int
403 1060440 : xfs_imeta_dir_lookup_component(
404 : struct xfs_inode *dp,
405 : struct xfs_name *xname,
406 : xfs_ino_t *ino)
407 : {
408 1060440 : int type_wanted = xname->type;
409 1060440 : int error;
410 :
411 1060440 : if (!S_ISDIR(VFS_I(dp)->i_mode)) {
412 0 : xfs_fs_mark_sick(dp->i_mount, XFS_SICK_FS_METADIR);
413 0 : return -EFSCORRUPTED;
414 : }
415 :
416 1060440 : error = xfs_imeta_dir_lookup(dp, xname, ino);
417 1060440 : if (error)
418 : return error;
419 947914 : if (!xfs_verify_ino(dp->i_mount, *ino)) {
420 0 : xfs_fs_mark_sick(dp->i_mount, XFS_SICK_FS_METADIR);
421 0 : return -EFSCORRUPTED;
422 : }
423 947914 : if (type_wanted != XFS_DIR3_FT_UNKNOWN && xname->type != type_wanted) {
424 0 : xfs_fs_mark_sick(dp->i_mount, XFS_SICK_FS_METADIR);
425 0 : return -EFSCORRUPTED;
426 : }
427 :
428 947914 : trace_xfs_imeta_dir_lookup(dp, xname, *ino);
429 947914 : return 0;
430 : }
431 :
432 : /*
433 : * Traverse a metadata directory tree path, returning the inode corresponding
434 : * to the parent of the last path component. If any of the path components do
435 : * not exist, return -ENOENT.
436 : *
437 : * @dp is returned without any locks held.
438 : */
439 : int
440 579371 : xfs_imeta_dir_parent(
441 : struct xfs_mount *mp,
442 : const struct xfs_imeta_path *path,
443 : struct xfs_inode **dpp)
444 : {
445 579371 : struct xfs_name xname;
446 579371 : struct xfs_inode *dp = NULL;
447 579371 : xfs_ino_t ino;
448 579371 : unsigned int i;
449 579371 : int error;
450 :
451 : /* Caller wanted the root, we're done! */
452 579371 : if (path->im_depth == 0)
453 0 : goto out;
454 :
455 : /* No metadata directory means no parent. */
456 579371 : if (mp->m_metadirip == NULL)
457 : return -ENOENT;
458 :
459 : /* Grab a new reference to the metadir root dir. */
460 579371 : error = xfs_imeta_iget(mp, mp->m_metadirip->i_ino, XFS_DIR3_FT_DIR,
461 : &dp);
462 579371 : if (error)
463 : return error;
464 :
465 1060440 : for (i = 0; i < path->im_depth - 1; i++) {
466 538042 : struct xfs_inode *ip = NULL;
467 :
468 538042 : xfs_ilock(dp, XFS_ILOCK_EXCL);
469 :
470 : /* Look up the name in the current directory. */
471 538042 : xfs_imeta_set_xname(&xname, path, i, XFS_DIR3_FT_DIR);
472 538042 : error = xfs_imeta_dir_lookup_component(dp, &xname, &ino);
473 538042 : if (error)
474 56973 : goto out_rele;
475 :
476 : /*
477 : * Grab the child inode while we still have the parent
478 : * directory locked.
479 : */
480 481069 : error = xfs_imeta_iget(mp, ino, XFS_DIR3_FT_DIR, &ip);
481 481069 : if (error)
482 0 : goto out_rele;
483 :
484 481069 : xfs_iunlock(dp, XFS_ILOCK_EXCL);
485 481069 : xfs_imeta_irele(dp);
486 481069 : dp = ip;
487 : }
488 :
489 522398 : out:
490 522398 : *dpp = dp;
491 522398 : return 0;
492 :
493 : out_rele:
494 56973 : xfs_iunlock(dp, XFS_ILOCK_EXCL);
495 56973 : xfs_imeta_irele(dp);
496 56973 : return error;
497 : }
498 :
499 : /*
500 : * Look up a metadata inode from the metadata directory. If the last path
501 : * component doesn't exist, return NULLFSINO. If any other part of the path
502 : * does not exist, return -ENOENT so we can distinguish the two.
503 : */
504 : STATIC int
505 496713 : xfs_imeta_dir_lookup_int(
506 : struct xfs_mount *mp,
507 : const struct xfs_imeta_path *path,
508 : xfs_ino_t *inop)
509 : {
510 496713 : struct xfs_name xname;
511 496713 : struct xfs_inode *dp = NULL;
512 496713 : xfs_ino_t ino;
513 496713 : int error;
514 :
515 : /* metadir ino is recorded in superblock */
516 496713 : if (xfs_imeta_path_compare(path, &XFS_IMETA_METADIR))
517 0 : return xfs_imeta_sb_lookup(mp, path, inop);
518 :
519 496713 : ASSERT(path->im_depth > 0);
520 :
521 : /* Find the parent of the last path component. */
522 496713 : error = xfs_imeta_dir_parent(mp, path, &dp);
523 496713 : if (error)
524 : return error;
525 :
526 439740 : xfs_ilock(dp, XFS_ILOCK_EXCL);
527 :
528 : /* Look up the name in the current directory. */
529 439740 : xfs_imeta_set_xname(&xname, path, path->im_depth - 1, path->im_ftype);
530 439740 : error = xfs_imeta_dir_lookup_component(dp, &xname, &ino);
531 439740 : switch (error) {
532 437513 : case 0:
533 437513 : *inop = ino;
534 437513 : break;
535 2219 : case -ENOENT:
536 2219 : *inop = NULLFSINO;
537 2219 : error = 0;
538 2219 : break;
539 : }
540 :
541 439740 : xfs_iunlock(dp, XFS_ILOCK_EXCL);
542 439740 : xfs_imeta_irele(dp);
543 439740 : return error;
544 : }
545 :
546 : /*
547 : * Load all the metadata inode pointers that are cached in the in-core
548 : * superblock but live somewhere in the metadata directory tree.
549 : */
550 : STATIC int
551 60399 : xfs_imeta_dir_mount(
552 : struct xfs_mount *mp)
553 : {
554 60399 : const struct xfs_imeta_sbmap *p;
555 60399 : xfs_ino_t *sb_inop;
556 60399 : int err2;
557 60399 : int error = 0;
558 :
559 362394 : for (p = xfs_imeta_sbmaps; p->path && p->path->im_depth > 0; p++) {
560 301995 : if (p->path == &XFS_IMETA_METADIR)
561 0 : continue;
562 301995 : sb_inop = xfs_imeta_sbmap_to_inop(mp, p);
563 301995 : err2 = xfs_imeta_dir_lookup_int(mp, p->path, sb_inop);
564 301995 : if (err2 == -ENOENT) {
565 56973 : *sb_inop = NULLFSINO;
566 56973 : continue;
567 : }
568 245022 : if (!error && err2)
569 4 : error = err2;
570 : }
571 :
572 60399 : return error;
573 : }
574 :
575 : /* Set up an inode to be recognized as a metadata inode. */
576 : void
577 53326 : xfs_imeta_set_iflag(
578 : struct xfs_trans *tp,
579 : struct xfs_inode *ip)
580 : {
581 53326 : VFS_I(ip)->i_mode &= ~0777;
582 53326 : VFS_I(ip)->i_uid = GLOBAL_ROOT_UID;
583 53326 : VFS_I(ip)->i_gid = GLOBAL_ROOT_GID;
584 53326 : ip->i_projid = 0;
585 53326 : ip->i_diflags |= (XFS_DIFLAG_IMMUTABLE | XFS_DIFLAG_SYNC |
586 : XFS_DIFLAG_NOATIME | XFS_DIFLAG_NODUMP |
587 : XFS_DIFLAG_NODEFRAG);
588 53326 : if (S_ISDIR(VFS_I(ip)->i_mode))
589 11997 : ip->i_diflags |= XFS_DIFLAG_NOSYMLINKS;
590 53326 : ip->i_diflags2 &= ~XFS_DIFLAG2_DAX;
591 53326 : ip->i_diflags2 |= XFS_DIFLAG2_METADIR;
592 53326 : xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
593 53326 : }
594 :
595 : /*
596 : * Create a new metadata inode accessible via the given metadata directory path.
597 : * Callers must ensure that the directory entry does not already exist; a new
598 : * one will be created.
599 : */
600 : STATIC int
601 82658 : xfs_imeta_dir_create(
602 : struct xfs_imeta_update *upd,
603 : umode_t mode)
604 : {
605 165316 : struct xfs_icreate_args args = {
606 82658 : .pip = upd->dp,
607 82658 : .nlink = S_ISDIR(mode) ? 2 : 1,
608 : };
609 82658 : struct xfs_name xname;
610 82658 : struct xfs_dir_update du = {
611 : .dp = upd->dp,
612 : .name = &xname,
613 82658 : .parent = upd->parent,
614 : };
615 82658 : struct xfs_mount *mp = upd->mp;
616 82658 : xfs_ino_t *sb_inop;
617 82658 : xfs_ino_t ino;
618 82658 : unsigned int resblks;
619 82658 : int error;
620 :
621 82658 : ASSERT(xfs_isilocked(upd->dp, XFS_ILOCK_EXCL));
622 :
623 : /* metadir ino is recorded in superblock; only mkfs gets to do this */
624 82658 : if (xfs_imeta_path_compare(upd->path, &XFS_IMETA_METADIR)) {
625 0 : error = xfs_imeta_sb_create(upd, mode);
626 0 : if (error)
627 : return error;
628 :
629 : /* Set the metadata iflag, initialize directory. */
630 0 : xfs_imeta_set_iflag(upd->tp, upd->ip);
631 0 : return xfs_dir_init(upd->tp, upd->ip, upd->ip);
632 : }
633 :
634 82658 : ASSERT(upd->path->im_depth > 0);
635 :
636 82658 : xfs_icreate_args_rootfile(&args, mp, mode, xfs_has_parent(mp));
637 :
638 : /* Check that the name does not already exist in the directory. */
639 82658 : xfs_imeta_set_xname(&xname, upd->path, upd->path->im_depth - 1,
640 : XFS_DIR3_FT_UNKNOWN);
641 82658 : error = xfs_imeta_dir_lookup_component(upd->dp, &xname, &ino);
642 82658 : switch (error) {
643 : case -ENOENT:
644 53326 : break;
645 29332 : case 0:
646 29332 : error = -EEXIST;
647 : fallthrough;
648 : default:
649 : return error;
650 : }
651 :
652 : /*
653 : * A newly created regular or special file just has one directory
654 : * entry pointing to them, but a directory also the "." entry
655 : * pointing to itself.
656 : */
657 53326 : error = xfs_dialloc(&upd->tp, upd->dp, mode, &ino);
658 53326 : if (error)
659 : return error;
660 53326 : error = xfs_icreate(upd->tp, ino, &args, &upd->ip);
661 53326 : if (error)
662 : return error;
663 53326 : du.ip = upd->ip;
664 53326 : xfs_imeta_set_iflag(upd->tp, upd->ip);
665 53326 : upd->ip_locked = true;
666 :
667 : /*
668 : * Join the directory inode to the transaction. We do not do it
669 : * earlier because xfs_dialloc rolls the transaction.
670 : */
671 53326 : xfs_trans_ijoin(upd->tp, upd->dp, 0);
672 :
673 : /* Create the entry. */
674 53326 : if (S_ISDIR(args.mode))
675 11997 : resblks = xfs_mkdir_space_res(mp, xname.len);
676 : else
677 41329 : resblks = xfs_create_space_res(mp, xname.len);
678 53326 : xname.type = xfs_mode_to_ftype(args.mode);
679 :
680 53326 : trace_xfs_imeta_dir_try_create(upd);
681 :
682 53326 : error = xfs_dir_create_child(upd->tp, resblks, &du);
683 53326 : if (error)
684 : return error;
685 :
686 : /* Metadir files are not accounted to quota. */
687 :
688 53326 : trace_xfs_imeta_dir_create(upd);
689 :
690 : /* Update the in-core superblock value if there is one. */
691 53326 : sb_inop = xfs_imeta_path_to_sb_inop(mp, upd->path);
692 53326 : if (sb_inop)
693 35163 : *sb_inop = ino;
694 : return 0;
695 : }
696 :
697 : /*
698 : * Remove the given entry from the metadata directory and drop the link count
699 : * of the metadata inode.
700 : */
701 : STATIC int
702 0 : xfs_imeta_dir_unlink(
703 : struct xfs_imeta_update *upd)
704 : {
705 0 : struct xfs_name xname;
706 0 : struct xfs_dir_update du = {
707 0 : .dp = upd->dp,
708 : .name = &xname,
709 0 : .ip = upd->ip,
710 0 : .parent = upd->parent,
711 : };
712 0 : struct xfs_mount *mp = upd->mp;
713 0 : xfs_ino_t *sb_inop;
714 0 : xfs_ino_t ino;
715 0 : unsigned int resblks;
716 0 : int error;
717 :
718 0 : ASSERT(xfs_isilocked(upd->dp, XFS_ILOCK_EXCL));
719 0 : ASSERT(xfs_isilocked(upd->ip, XFS_ILOCK_EXCL));
720 :
721 : /* Metadata directory root cannot be unlinked. */
722 0 : if (xfs_imeta_path_compare(upd->path, &XFS_IMETA_METADIR)) {
723 0 : ASSERT(0);
724 0 : xfs_fs_mark_sick(mp, XFS_SICK_FS_METADIR);
725 0 : return -EFSCORRUPTED;
726 : }
727 :
728 0 : ASSERT(upd->path->im_depth > 0);
729 :
730 : /* Look up the name in the current directory. */
731 0 : xfs_imeta_set_xname(&xname, upd->path, upd->path->im_depth - 1,
732 0 : xfs_mode_to_ftype(VFS_I(upd->ip)->i_mode));
733 0 : error = xfs_imeta_dir_lookup_component(upd->dp, &xname, &ino);
734 0 : switch (error) {
735 0 : case 0:
736 0 : if (ino != upd->ip->i_ino)
737 : error = -ENOENT;
738 : break;
739 0 : case -ENOENT:
740 0 : xfs_fs_mark_sick(mp, XFS_SICK_FS_METADIR);
741 0 : error = -EFSCORRUPTED;
742 0 : break;
743 : }
744 0 : if (error)
745 0 : return error;
746 :
747 0 : resblks = xfs_remove_space_res(mp, xname.len);
748 0 : error = xfs_dir_remove_child(upd->tp, resblks, &du);
749 0 : if (error)
750 : return error;
751 :
752 0 : trace_xfs_imeta_dir_unlink(upd);
753 :
754 : /* Update the in-core superblock value if there is one. */
755 0 : sb_inop = xfs_imeta_path_to_sb_inop(mp, upd->path);
756 0 : if (sb_inop)
757 0 : *sb_inop = NULLFSINO;
758 : return 0;
759 : }
760 :
761 : /* Set the given path in the metadata directory to point to an inode. */
762 : STATIC int
763 0 : xfs_imeta_dir_link(
764 : struct xfs_imeta_update *upd)
765 : {
766 0 : struct xfs_name xname;
767 0 : struct xfs_dir_update du = {
768 0 : .dp = upd->dp,
769 : .name = &xname,
770 0 : .ip = upd->ip,
771 0 : .parent = upd->parent,
772 : };
773 0 : struct xfs_mount *mp = upd->mp;
774 0 : xfs_ino_t *sb_inop;
775 0 : xfs_ino_t ino;
776 0 : unsigned int resblks;
777 0 : int error;
778 :
779 0 : ASSERT(xfs_isilocked(upd->dp, XFS_ILOCK_EXCL));
780 0 : ASSERT(xfs_isilocked(upd->ip, XFS_ILOCK_EXCL));
781 :
782 : /* Metadata directory root cannot be linked. */
783 0 : if (xfs_imeta_path_compare(upd->path, &XFS_IMETA_METADIR)) {
784 0 : ASSERT(0);
785 0 : xfs_fs_mark_sick(mp, XFS_SICK_FS_METADIR);
786 0 : return -EFSCORRUPTED;
787 : }
788 :
789 0 : ASSERT(upd->path->im_depth > 0);
790 :
791 : /* Look up the name in the current directory. */
792 0 : xfs_imeta_set_xname(&xname, upd->path, upd->path->im_depth - 1,
793 0 : xfs_mode_to_ftype(VFS_I(upd->ip)->i_mode));
794 0 : error = xfs_imeta_dir_lookup_component(upd->dp, &xname, &ino);
795 0 : switch (error) {
796 : case -ENOENT:
797 0 : break;
798 0 : case 0:
799 0 : error = -EEXIST;
800 : fallthrough;
801 : default:
802 : return error;
803 : }
804 :
805 0 : resblks = xfs_link_space_res(mp, xname.len);
806 0 : error = xfs_dir_add_child(upd->tp, resblks, &du);
807 0 : if (error)
808 : return error;
809 :
810 0 : trace_xfs_imeta_dir_link(upd);
811 :
812 : /* Update the in-core superblock value if there is one. */
813 0 : sb_inop = xfs_imeta_path_to_sb_inop(mp, upd->path);
814 0 : if (sb_inop)
815 0 : *sb_inop = upd->ip->i_ino;
816 : return 0;
817 : }
818 :
819 : /* General functions for managing metadata inode pointers */
820 :
821 : /*
822 : * Is this metadata inode pointer ok? We allow the fields to be set to
823 : * NULLFSINO if the metadata structure isn't present, and we don't allow
824 : * obviously incorrect inode pointers.
825 : */
826 : static inline bool
827 : xfs_imeta_verify(
828 : struct xfs_mount *mp,
829 : xfs_ino_t ino)
830 : {
831 194718 : if (ino == NULLFSINO)
832 : return true;
833 194718 : return xfs_verify_ino(mp, ino);
834 : }
835 :
836 : /* Look up a metadata inode by its path. */
837 : int
838 194718 : xfs_imeta_lookup(
839 : struct xfs_mount *mp,
840 : const struct xfs_imeta_path *path,
841 : xfs_ino_t *inop)
842 : {
843 194718 : xfs_ino_t ino;
844 194718 : int error;
845 :
846 194718 : ASSERT(xfs_imeta_path_check(path));
847 :
848 194718 : if (xfs_has_metadir(mp)) {
849 194718 : error = xfs_imeta_dir_lookup_int(mp, path, &ino);
850 194718 : if (error == -ENOENT) {
851 0 : xfs_fs_mark_sick(mp, XFS_SICK_FS_METADIR);
852 0 : return -EFSCORRUPTED;
853 : }
854 : } else {
855 0 : error = xfs_imeta_sb_lookup(mp, path, &ino);
856 : }
857 194718 : if (error)
858 : return error;
859 :
860 389436 : if (!xfs_imeta_verify(mp, ino)) {
861 0 : xfs_fs_mark_sick(mp, XFS_SICK_FS_METADIR);
862 0 : return -EFSCORRUPTED;
863 : }
864 :
865 194718 : *inop = ino;
866 194718 : return 0;
867 : }
868 :
869 : /*
870 : * Create a metadata inode with the given @mode, and insert it into the
871 : * metadata directory tree at the given @path. The path (up to the final
872 : * component) must already exist.
873 : *
874 : * The new metadata inode will be attached to the update structure @upd->ip,
875 : * with the ILOCK held until the caller releases it. @ipp is set to upd->ip
876 : * as a convenience for callers.
877 : *
878 : * Callers must ensure that the root dquots are allocated, if applicable.
879 : *
880 : * NOTE: This function may return a new inode to the caller even if it returns
881 : * a negative error code. If an inode is passed back, the caller must finish
882 : * setting up the inode before releasing it.
883 : */
884 : int
885 86755 : xfs_imeta_create(
886 : struct xfs_imeta_update *upd,
887 : umode_t mode,
888 : struct xfs_inode **ipp)
889 : {
890 86755 : struct xfs_mount *mp = upd->mp;
891 86755 : int error;
892 :
893 86755 : ASSERT(xfs_imeta_path_check(upd->path));
894 :
895 86755 : *ipp = NULL;
896 :
897 86755 : if (xfs_has_metadir(mp))
898 82658 : error = xfs_imeta_dir_create(upd, mode);
899 : else
900 4097 : error = xfs_imeta_sb_create(upd, mode);
901 86755 : *ipp = upd->ip;
902 86755 : return error;
903 : }
904 :
905 : /* Free a file from the metadata directory tree. */
906 : STATIC int
907 0 : xfs_imeta_ifree(
908 : struct xfs_trans *tp,
909 : struct xfs_inode *ip)
910 : {
911 0 : struct xfs_mount *mp = ip->i_mount;
912 0 : struct xfs_perag *pag;
913 0 : struct xfs_icluster xic = { 0 };
914 0 : int error;
915 :
916 0 : ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL));
917 0 : ASSERT(VFS_I(ip)->i_nlink == 0);
918 0 : ASSERT(ip->i_df.if_nextents == 0);
919 0 : ASSERT(ip->i_disk_size == 0 || !S_ISREG(VFS_I(ip)->i_mode));
920 0 : ASSERT(ip->i_nblocks == 0);
921 :
922 0 : pag = xfs_perag_get(mp, XFS_INO_TO_AGNO(mp, ip->i_ino));
923 :
924 0 : error = xfs_dir_ifree(tp, pag, ip, &xic);
925 0 : if (error)
926 0 : goto out;
927 :
928 : /* Metadata files do not support ownership changes or DMAPI. */
929 :
930 0 : if (xic.deleted)
931 0 : error = xfs_ifree_cluster(tp, pag, ip, &xic);
932 0 : out:
933 0 : xfs_perag_put(pag);
934 0 : return error;
935 : }
936 :
937 : /*
938 : * Unlink a metadata inode @upd->ip from the metadata directory given by @path.
939 : * The path must already exist.
940 : */
941 : int
942 0 : xfs_imeta_unlink(
943 : struct xfs_imeta_update *upd)
944 : {
945 0 : int error;
946 :
947 0 : ASSERT(xfs_imeta_path_check(upd->path));
948 0 : ASSERT(xfs_imeta_verify(upd->mp, upd->ip->i_ino));
949 :
950 0 : if (xfs_has_metadir(upd->mp))
951 0 : error = xfs_imeta_dir_unlink(upd);
952 : else
953 0 : error = xfs_imeta_sb_unlink(upd);
954 0 : if (error)
955 : return error;
956 :
957 : /*
958 : * Metadata files require explicit resource cleanup. In other words,
959 : * the inactivation system will not touch these files, so we must free
960 : * the ondisk inode by ourselves if warranted.
961 : */
962 0 : if (VFS_I(upd->ip)->i_nlink > 0)
963 : return 0;
964 :
965 0 : return xfs_imeta_ifree(upd->tp, upd->ip);
966 : }
967 :
968 : /*
969 : * Link the metadata directory given by @path to the inode @upd->ip.
970 : * The path (up to the final component) must already exist, but the final
971 : * component must not already exist.
972 : */
973 : int
974 0 : xfs_imeta_link(
975 : struct xfs_imeta_update *upd)
976 : {
977 0 : ASSERT(xfs_imeta_path_check(upd->path));
978 :
979 0 : if (xfs_has_metadir(upd->mp))
980 0 : return xfs_imeta_dir_link(upd);
981 0 : return xfs_imeta_sb_link(upd);
982 : }
983 :
984 : /* Does this inode number refer to a static metadata inode? */
985 : bool
986 86632174291 : xfs_is_static_meta_ino(
987 : struct xfs_mount *mp,
988 : xfs_ino_t ino)
989 : {
990 86632174291 : const struct xfs_imeta_sbmap *p;
991 :
992 86632174291 : if (ino == NULLFSINO)
993 : return false;
994 :
995 >59993*10^7 : for (p = xfs_imeta_sbmaps; p->path; p++)
996 >51351*10^7 : if (ino == *xfs_imeta_sbmap_to_inop(mp, p))
997 : return true;
998 :
999 : return false;
1000 : }
1001 :
1002 : /* Ensure that the in-core superblock has all the values that it should. */
1003 : int
1004 66795 : xfs_imeta_mount(
1005 : struct xfs_mount *mp)
1006 : {
1007 66795 : if (xfs_has_metadir(mp))
1008 60399 : return xfs_imeta_dir_mount(mp);
1009 :
1010 : return 0;
1011 : }
1012 :
1013 : /* Clear the metadata iflag if we're unlinking this inode. */
1014 : void
1015 81092919 : xfs_imeta_droplink(
1016 : struct xfs_inode *ip)
1017 : {
1018 81092919 : if (VFS_I(ip)->i_nlink == 0 && xfs_is_metadir_inode(ip))
1019 0 : ip->i_diflags2 &= ~XFS_DIFLAG2_METADIR;
1020 81092919 : }
1021 :
1022 : /* Create a path to a file within the metadata directory tree. */
1023 : int
1024 200884 : xfs_imeta_create_file_path(
1025 : struct xfs_mount *mp,
1026 : unsigned int nr_components,
1027 : struct xfs_imeta_path **pathp)
1028 : {
1029 200884 : struct xfs_imeta_path *p;
1030 200884 : unsigned char **components;
1031 :
1032 200884 : p = kmalloc(sizeof(struct xfs_imeta_path), GFP_KERNEL);
1033 200884 : if (!p)
1034 : return -ENOMEM;
1035 :
1036 200884 : components = kvcalloc(nr_components, sizeof(unsigned char *),
1037 : GFP_KERNEL);
1038 200884 : if (!components) {
1039 0 : kfree(p);
1040 0 : return -ENOMEM;
1041 : }
1042 :
1043 200884 : p->im_depth = nr_components;
1044 200884 : p->im_path = (const unsigned char **)components;
1045 200884 : p->im_ftype = XFS_DIR3_FT_REG_FILE;
1046 200884 : p->im_dynamicmask = 0;
1047 200884 : *pathp = p;
1048 200884 : return 0;
1049 : }
1050 :
1051 : /* Free a metadata directory tree path. */
1052 : void
1053 200884 : xfs_imeta_free_path(
1054 : struct xfs_imeta_path *path)
1055 : {
1056 200884 : unsigned int i;
1057 :
1058 602652 : for (i = 0; i < path->im_depth; i++) {
1059 401768 : if ((path->im_dynamicmask & (1ULL << i)) && path->im_path[i])
1060 200884 : kfree(path->im_path[i]);
1061 : }
1062 200884 : kfree(path->im_path);
1063 200884 : kfree(path);
1064 200884 : }
1065 :
1066 : /*
1067 : * Is the amount of space that could be allocated towards a given metadata
1068 : * file at or beneath a certain threshold?
1069 : */
1070 : static inline bool
1071 240943538 : xfs_imeta_resv_can_cover(
1072 : struct xfs_inode *ip,
1073 : int64_t rhs)
1074 : {
1075 : /*
1076 : * The amount of space that can be allocated to this metadata file is
1077 : * the remaining reservation for the particular metadata file + the
1078 : * global free block count. Take care of the first case to avoid
1079 : * touching the per-cpu counter.
1080 : */
1081 240943538 : if (ip->i_delayed_blks >= rhs)
1082 : return true;
1083 :
1084 : /*
1085 : * There aren't enough blocks left in the inode's reservation, but it
1086 : * isn't critical unless there also isn't enough free space.
1087 : */
1088 64215758 : return __percpu_counter_compare(&ip->i_mount->m_fdblocks,
1089 64215758 : rhs - ip->i_delayed_blks, 2048) >= 0;
1090 : }
1091 :
1092 : /*
1093 : * Is this metadata file critically low on blocks? For now we'll define that
1094 : * as the number of blocks we can get our hands on being less than 10% of what
1095 : * we reserved or less than some arbitrary number (maximum btree height).
1096 : */
1097 : bool
1098 120471925 : xfs_imeta_resv_critical(
1099 : struct xfs_inode *ip)
1100 : {
1101 120471925 : uint64_t asked_low_water;
1102 :
1103 120471925 : if (!ip)
1104 : return false;
1105 :
1106 120471925 : ASSERT(xfs_is_metadir_inode(ip));
1107 120471925 : trace_xfs_imeta_resv_critical(ip, 0);
1108 :
1109 120471956 : if (!xfs_imeta_resv_can_cover(ip, ip->i_mount->m_rtbtree_maxlevels))
1110 : return true;
1111 :
1112 120471905 : asked_low_water = div_u64(ip->i_meta_resv_asked, 10);
1113 120471831 : if (!xfs_imeta_resv_can_cover(ip, asked_low_water))
1114 : return true;
1115 :
1116 120471836 : return XFS_TEST_ERROR(false, ip->i_mount,
1117 : XFS_ERRTAG_IMETA_RESV_CRITICAL);
1118 : }
1119 :
1120 : /* Allocate a block from the metadata file's reservation. */
1121 : void
1122 726296 : xfs_imeta_resv_alloc_extent(
1123 : struct xfs_inode *ip,
1124 : struct xfs_alloc_arg *args)
1125 : {
1126 726296 : int64_t len = args->len;
1127 :
1128 726296 : ASSERT(xfs_is_metadir_inode(ip));
1129 726296 : ASSERT(XFS_IS_DQDETACHED(ip->i_mount, ip));
1130 726296 : ASSERT(args->resv == XFS_AG_RESV_IMETA);
1131 :
1132 726296 : trace_xfs_imeta_resv_alloc_extent(ip, args->len);
1133 :
1134 : /*
1135 : * Allocate the blocks from the metadata inode's block reservation
1136 : * and update the ondisk sb counter.
1137 : */
1138 726296 : if (ip->i_delayed_blks > 0) {
1139 522346 : int64_t from_resv;
1140 :
1141 522346 : from_resv = min_t(int64_t, len, ip->i_delayed_blks);
1142 522346 : ip->i_delayed_blks -= from_resv;
1143 522346 : xfs_mod_delalloc(ip->i_mount, -from_resv);
1144 522346 : xfs_trans_mod_sb(args->tp, XFS_TRANS_SB_RES_FDBLOCKS,
1145 : -from_resv);
1146 522346 : len -= from_resv;
1147 : }
1148 :
1149 : /*
1150 : * Any allocation in excess of the reservation requires in-core and
1151 : * on-disk fdblocks updates.
1152 : */
1153 726296 : if (len)
1154 203950 : xfs_trans_mod_sb(args->tp, XFS_TRANS_SB_FDBLOCKS, -len);
1155 :
1156 726296 : ip->i_nblocks += args->len;
1157 726296 : xfs_trans_log_inode(args->tp, ip, XFS_ILOG_CORE);
1158 726295 : }
1159 :
1160 : /* Free a block to the metadata file's reservation. */
1161 : void
1162 88578 : xfs_imeta_resv_free_extent(
1163 : struct xfs_inode *ip,
1164 : struct xfs_trans *tp,
1165 : xfs_filblks_t len)
1166 : {
1167 88578 : int64_t to_resv;
1168 :
1169 88578 : ASSERT(xfs_is_metadir_inode(ip));
1170 88578 : ASSERT(XFS_IS_DQDETACHED(ip->i_mount, ip));
1171 88578 : trace_xfs_imeta_resv_free_extent(ip, len);
1172 :
1173 88578 : ip->i_nblocks -= len;
1174 88578 : xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
1175 :
1176 : /*
1177 : * Add the freed blocks back into the inode's delalloc reservation
1178 : * until it reaches the maximum size. Update the ondisk fdblocks only.
1179 : */
1180 88578 : to_resv = ip->i_meta_resv_asked - (ip->i_nblocks + ip->i_delayed_blks);
1181 88578 : if (to_resv > 0) {
1182 88578 : to_resv = min_t(int64_t, to_resv, len);
1183 88578 : ip->i_delayed_blks += to_resv;
1184 88578 : xfs_mod_delalloc(ip->i_mount, to_resv);
1185 88579 : xfs_trans_mod_sb(tp, XFS_TRANS_SB_RES_FDBLOCKS, to_resv);
1186 88579 : len -= to_resv;
1187 : }
1188 :
1189 : /*
1190 : * Everything else goes back to the filesystem, so update the in-core
1191 : * and on-disk counters.
1192 : */
1193 88579 : if (len)
1194 0 : xfs_trans_mod_sb(tp, XFS_TRANS_SB_FDBLOCKS, len);
1195 88579 : }
1196 :
1197 : /* Release a metadata file's space reservation. */
1198 : void
1199 403510 : xfs_imeta_resv_free_inode(
1200 : struct xfs_inode *ip)
1201 : {
1202 403510 : if (!ip)
1203 : return;
1204 :
1205 403190 : ASSERT(xfs_is_metadir_inode(ip));
1206 403190 : trace_xfs_imeta_resv_free(ip, 0);
1207 :
1208 403190 : xfs_mod_delalloc(ip->i_mount, -ip->i_delayed_blks);
1209 403190 : xfs_mod_fdblocks(ip->i_mount, ip->i_delayed_blks, true);
1210 403190 : ip->i_delayed_blks = 0;
1211 403190 : ip->i_meta_resv_asked = 0;
1212 : }
1213 :
1214 : /* Set up a metadata file's space reservation. */
1215 : int
1216 396650 : xfs_imeta_resv_init_inode(
1217 : struct xfs_inode *ip,
1218 : xfs_filblks_t ask)
1219 : {
1220 396650 : xfs_filblks_t hidden_space;
1221 396650 : xfs_filblks_t used;
1222 396650 : int error;
1223 :
1224 396650 : if (!ip || ip->i_meta_resv_asked > 0)
1225 : return 0;
1226 :
1227 396290 : ASSERT(xfs_is_metadir_inode(ip));
1228 :
1229 : /*
1230 : * Space taken by all other metadata btrees are accounted on-disk as
1231 : * used space. We therefore only hide the space that is reserved but
1232 : * not used by the trees.
1233 : */
1234 396290 : used = ip->i_nblocks;
1235 396290 : if (used > ask)
1236 : ask = used;
1237 396290 : hidden_space = ask - used;
1238 :
1239 396290 : error = xfs_mod_fdblocks(ip->i_mount, -(int64_t)hidden_space, true);
1240 396290 : if (error) {
1241 3 : trace_xfs_imeta_resv_init_error(ip, error, _RET_IP_);
1242 3 : return error;
1243 : }
1244 :
1245 396287 : xfs_mod_delalloc(ip->i_mount, hidden_space);
1246 396287 : ip->i_delayed_blks = hidden_space;
1247 396287 : ip->i_meta_resv_asked = ask;
1248 :
1249 396287 : trace_xfs_imeta_resv_init(ip, ask);
1250 396287 : return 0;
1251 : }
|