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 188714 : xfs_imeta_path_compare(
87 : const struct xfs_imeta_path *a,
88 : const struct xfs_imeta_path *b)
89 : {
90 188714 : unsigned int i;
91 :
92 188714 : if (a == b)
93 : return true;
94 :
95 180143 : if (a->im_depth != b->im_depth)
96 : return false;
97 :
98 34332 : for (i = 0; i < a->im_depth; i++)
99 34332 : if (a->im_path[i] != b->im_path[i] &&
100 25807 : 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 19282 : 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 >42120*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 11392 : xfs_imeta_path_to_sb_inop(
160 : struct xfs_mount *mp,
161 : const struct xfs_imeta_path *path)
162 : {
163 11392 : const struct xfs_imeta_sbmap *p;
164 :
165 53985 : for (p = xfs_imeta_sbmaps; p->path; p++)
166 51164 : if (xfs_imeta_path_compare(p->path, path))
167 8571 : 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 322 : xfs_imeta_log_sb(
193 : struct xfs_trans *tp)
194 : {
195 322 : struct xfs_mount *mp = tp->t_mountp;
196 322 : 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 322 : xfs_sb_to_disk(bp->b_addr, &mp->m_sb);
205 322 : xfs_trans_buf_set_type(tp, bp, XFS_BLFT_SB_BUF);
206 322 : xfs_trans_log_buf(tp, bp, 0, sizeof(struct xfs_dsb) - 1);
207 322 : }
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 322 : xfs_imeta_sb_create(
215 : struct xfs_imeta_update *upd,
216 : umode_t mode)
217 : {
218 644 : struct xfs_icreate_args args = {
219 322 : .nlink = S_ISDIR(mode) ? 2 : 1,
220 : };
221 322 : struct xfs_mount *mp = upd->mp;
222 322 : xfs_ino_t *sb_inop;
223 322 : xfs_ino_t ino;
224 322 : int error;
225 :
226 : /* Files rooted in the superblock do not have parents. */
227 322 : xfs_icreate_args_rootfile(&args, mp, mode, false);
228 :
229 : /* Reject if the sb already points to some inode. */
230 322 : sb_inop = xfs_imeta_path_to_sb_inop(mp, upd->path);
231 322 : if (!sb_inop)
232 : return -EINVAL;
233 :
234 322 : if (*sb_inop != NULLFSINO)
235 : return -EEXIST;
236 :
237 : /* Create a new inode and set the sb pointer. */
238 322 : error = xfs_dialloc(&upd->tp, NULL, mode, &ino);
239 322 : if (error)
240 : return error;
241 322 : error = xfs_icreate(upd->tp, ino, &args, &upd->ip);
242 322 : if (error)
243 : return error;
244 322 : 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 322 : *sb_inop = ino;
255 322 : xfs_imeta_log_sb(upd->tp);
256 :
257 322 : trace_xfs_imeta_sb_create(upd);
258 322 : 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 253535 : 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 253535 : xname->name = (const unsigned char *)path->im_path[path_idx];
324 253535 : xname->len = strlen(path->im_path[path_idx]);
325 253535 : xname->type = ftype;
326 253535 : }
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 253535 : xfs_imeta_dir_lookup(
334 : struct xfs_inode *dp,
335 : struct xfs_name *xname,
336 : xfs_ino_t *ino)
337 : {
338 507070 : struct xfs_da_args args = {
339 : .dp = dp,
340 253535 : .geo = dp->i_mount->m_dir_geo,
341 253535 : .name = xname->name,
342 253535 : .namelen = xname->len,
343 253535 : .hashval = xfs_dir2_hashname(dp->i_mount, xname),
344 : .whichfork = XFS_DATA_FORK,
345 : .op_flags = XFS_DA_OP_OKNOENT,
346 253535 : .owner = dp->i_ino,
347 : };
348 253535 : bool isblock, isleaf;
349 253535 : int error;
350 :
351 507070 : if (xfs_is_shutdown(dp->i_mount))
352 : return -EIO;
353 :
354 253535 : if (dp->i_df.if_format == XFS_DINODE_FMT_LOCAL) {
355 250699 : error = xfs_dir2_sf_lookup(&args);
356 250699 : goto out_unlock;
357 : }
358 :
359 : /* dir2 functions require that the data fork is loaded */
360 2836 : error = xfs_iread_extents(NULL, dp, XFS_DATA_FORK);
361 2836 : if (error)
362 0 : goto out_unlock;
363 :
364 2836 : error = xfs_dir2_isblock(&args, &isblock);
365 2836 : if (error)
366 0 : goto out_unlock;
367 :
368 2836 : if (isblock) {
369 2836 : error = xfs_dir2_block_lookup(&args);
370 2836 : goto out_unlock;
371 : }
372 :
373 0 : error = xfs_dir2_isleaf(&args, &isleaf);
374 0 : if (error)
375 0 : goto out_unlock;
376 :
377 0 : if (isleaf) {
378 0 : error = xfs_dir2_leaf_lookup(&args);
379 0 : goto out_unlock;
380 : }
381 :
382 0 : error = xfs_dir2_node_lookup(&args);
383 :
384 253535 : out_unlock:
385 253535 : if (error == -EEXIST)
386 : error = 0;
387 24808 : if (error)
388 : return error;
389 :
390 228727 : *ino = args.inumber;
391 228727 : xname->type = args.filetype;
392 228727 : 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 253535 : xfs_imeta_dir_lookup_component(
404 : struct xfs_inode *dp,
405 : struct xfs_name *xname,
406 : xfs_ino_t *ino)
407 : {
408 253535 : int type_wanted = xname->type;
409 253535 : int error;
410 :
411 253535 : 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 253535 : error = xfs_imeta_dir_lookup(dp, xname, ino);
417 253535 : if (error)
418 : return error;
419 228727 : 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 228727 : 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 228727 : trace_xfs_imeta_dir_lookup(dp, xname, *ino);
429 228727 : 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 137550 : xfs_imeta_dir_parent(
441 : struct xfs_mount *mp,
442 : const struct xfs_imeta_path *path,
443 : struct xfs_inode **dpp)
444 : {
445 137550 : struct xfs_name xname;
446 137550 : struct xfs_inode *dp = NULL;
447 137550 : xfs_ino_t ino;
448 137550 : unsigned int i;
449 137550 : int error;
450 :
451 : /* Caller wanted the root, we're done! */
452 137550 : if (path->im_depth == 0)
453 0 : goto out;
454 :
455 : /* No metadata directory means no parent. */
456 137550 : if (mp->m_metadirip == NULL)
457 : return -ENOENT;
458 :
459 : /* Grab a new reference to the metadir root dir. */
460 137550 : error = xfs_imeta_iget(mp, mp->m_metadirip->i_ino, XFS_DIR3_FT_DIR,
461 : &dp);
462 137550 : if (error)
463 : return error;
464 :
465 253535 : for (i = 0; i < path->im_depth - 1; i++) {
466 129281 : struct xfs_inode *ip = NULL;
467 :
468 129281 : xfs_ilock(dp, XFS_ILOCK_EXCL);
469 :
470 : /* Look up the name in the current directory. */
471 129281 : xfs_imeta_set_xname(&xname, path, i, XFS_DIR3_FT_DIR);
472 129281 : error = xfs_imeta_dir_lookup_component(dp, &xname, &ino);
473 129281 : if (error)
474 13296 : goto out_rele;
475 :
476 : /*
477 : * Grab the child inode while we still have the parent
478 : * directory locked.
479 : */
480 115985 : error = xfs_imeta_iget(mp, ino, XFS_DIR3_FT_DIR, &ip);
481 115985 : if (error)
482 0 : goto out_rele;
483 :
484 115985 : xfs_iunlock(dp, XFS_ILOCK_EXCL);
485 115985 : xfs_imeta_irele(dp);
486 115985 : dp = ip;
487 : }
488 :
489 124254 : out:
490 124254 : *dpp = dp;
491 124254 : return 0;
492 :
493 : out_rele:
494 13296 : xfs_iunlock(dp, XFS_ILOCK_EXCL);
495 13296 : xfs_imeta_irele(dp);
496 13296 : 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 121012 : xfs_imeta_dir_lookup_int(
506 : struct xfs_mount *mp,
507 : const struct xfs_imeta_path *path,
508 : xfs_ino_t *inop)
509 : {
510 121012 : struct xfs_name xname;
511 121012 : struct xfs_inode *dp = NULL;
512 121012 : xfs_ino_t ino;
513 121012 : int error;
514 :
515 : /* metadir ino is recorded in superblock */
516 121012 : if (xfs_imeta_path_compare(path, &XFS_IMETA_METADIR))
517 0 : return xfs_imeta_sb_lookup(mp, path, inop);
518 :
519 121012 : ASSERT(path->im_depth > 0);
520 :
521 : /* Find the parent of the last path component. */
522 121012 : error = xfs_imeta_dir_parent(mp, path, &dp);
523 121012 : if (error)
524 : return error;
525 :
526 107716 : xfs_ilock(dp, XFS_ILOCK_EXCL);
527 :
528 : /* Look up the name in the current directory. */
529 107716 : xfs_imeta_set_xname(&xname, path, path->im_depth - 1, path->im_ftype);
530 107716 : error = xfs_imeta_dir_lookup_component(dp, &xname, &ino);
531 107716 : switch (error) {
532 107274 : case 0:
533 107274 : *inop = ino;
534 107274 : break;
535 442 : case -ENOENT:
536 442 : *inop = NULLFSINO;
537 442 : error = 0;
538 442 : break;
539 : }
540 :
541 107716 : xfs_iunlock(dp, XFS_ILOCK_EXCL);
542 107716 : xfs_imeta_irele(dp);
543 107716 : 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 23718 : xfs_imeta_dir_mount(
552 : struct xfs_mount *mp)
553 : {
554 23718 : const struct xfs_imeta_sbmap *p;
555 23718 : xfs_ino_t *sb_inop;
556 23718 : int err2;
557 23718 : int error = 0;
558 :
559 142308 : for (p = xfs_imeta_sbmaps; p->path && p->path->im_depth > 0; p++) {
560 118590 : if (p->path == &XFS_IMETA_METADIR)
561 0 : continue;
562 118590 : sb_inop = xfs_imeta_sbmap_to_inop(mp, p);
563 118590 : err2 = xfs_imeta_dir_lookup_int(mp, p->path, sb_inop);
564 118590 : if (err2 == -ENOENT) {
565 13296 : *sb_inop = NULLFSINO;
566 13296 : continue;
567 : }
568 105294 : if (!error && err2)
569 0 : error = err2;
570 : }
571 :
572 23718 : return error;
573 : }
574 :
575 : /* Set up an inode to be recognized as a metadata inode. */
576 : void
577 11070 : xfs_imeta_set_iflag(
578 : struct xfs_trans *tp,
579 : struct xfs_inode *ip)
580 : {
581 11070 : VFS_I(ip)->i_mode &= ~0777;
582 11070 : VFS_I(ip)->i_uid = GLOBAL_ROOT_UID;
583 11070 : VFS_I(ip)->i_gid = GLOBAL_ROOT_GID;
584 11070 : ip->i_projid = 0;
585 11070 : ip->i_diflags |= (XFS_DIFLAG_IMMUTABLE | XFS_DIFLAG_SYNC |
586 : XFS_DIFLAG_NOATIME | XFS_DIFLAG_NODUMP |
587 : XFS_DIFLAG_NODEFRAG);
588 11070 : if (S_ISDIR(VFS_I(ip)->i_mode))
589 2801 : ip->i_diflags |= XFS_DIFLAG_NOSYMLINKS;
590 11070 : ip->i_diflags2 &= ~XFS_DIFLAG2_DAX;
591 11070 : ip->i_diflags2 |= XFS_DIFLAG2_METADIR;
592 11070 : xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
593 11070 : }
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 16538 : xfs_imeta_dir_create(
602 : struct xfs_imeta_update *upd,
603 : umode_t mode)
604 : {
605 33076 : struct xfs_icreate_args args = {
606 16538 : .pip = upd->dp,
607 16538 : .nlink = S_ISDIR(mode) ? 2 : 1,
608 : };
609 16538 : struct xfs_name xname;
610 16538 : struct xfs_dir_update du = {
611 : .dp = upd->dp,
612 : .name = &xname,
613 16538 : .parent = upd->parent,
614 : };
615 16538 : struct xfs_mount *mp = upd->mp;
616 16538 : xfs_ino_t *sb_inop;
617 16538 : xfs_ino_t ino;
618 16538 : unsigned int resblks;
619 16538 : int error;
620 :
621 16538 : ASSERT(xfs_isilocked(upd->dp, XFS_ILOCK_EXCL));
622 :
623 : /* metadir ino is recorded in superblock; only mkfs gets to do this */
624 16538 : 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 16538 : ASSERT(upd->path->im_depth > 0);
635 :
636 16538 : 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 16538 : xfs_imeta_set_xname(&xname, upd->path, upd->path->im_depth - 1,
640 : XFS_DIR3_FT_UNKNOWN);
641 16538 : error = xfs_imeta_dir_lookup_component(upd->dp, &xname, &ino);
642 16538 : switch (error) {
643 : case -ENOENT:
644 11070 : break;
645 5468 : case 0:
646 5468 : 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 11070 : error = xfs_dialloc(&upd->tp, upd->dp, mode, &ino);
658 11070 : if (error)
659 : return error;
660 11070 : error = xfs_icreate(upd->tp, ino, &args, &upd->ip);
661 11070 : if (error)
662 : return error;
663 11070 : du.ip = upd->ip;
664 11070 : xfs_imeta_set_iflag(upd->tp, upd->ip);
665 11070 : 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 11070 : xfs_trans_ijoin(upd->tp, upd->dp, 0);
672 :
673 : /* Create the entry. */
674 11070 : if (S_ISDIR(args.mode))
675 2801 : resblks = xfs_mkdir_space_res(mp, xname.len);
676 : else
677 8269 : resblks = xfs_create_space_res(mp, xname.len);
678 11070 : xname.type = xfs_mode_to_ftype(args.mode);
679 :
680 11070 : trace_xfs_imeta_dir_try_create(upd);
681 :
682 11070 : error = xfs_dir_create_child(upd->tp, resblks, &du);
683 11070 : if (error)
684 : return error;
685 :
686 : /* Metadir files are not accounted to quota. */
687 :
688 11070 : trace_xfs_imeta_dir_create(upd);
689 :
690 : /* Update the in-core superblock value if there is one. */
691 11070 : sb_inop = xfs_imeta_path_to_sb_inop(mp, upd->path);
692 11070 : if (sb_inop)
693 8249 : *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 2422 : if (ino == NULLFSINO)
832 : return true;
833 2422 : return xfs_verify_ino(mp, ino);
834 : }
835 :
836 : /* Look up a metadata inode by its path. */
837 : int
838 2422 : xfs_imeta_lookup(
839 : struct xfs_mount *mp,
840 : const struct xfs_imeta_path *path,
841 : xfs_ino_t *inop)
842 : {
843 2422 : xfs_ino_t ino;
844 2422 : int error;
845 :
846 2422 : ASSERT(xfs_imeta_path_check(path));
847 :
848 2422 : if (xfs_has_metadir(mp)) {
849 2422 : error = xfs_imeta_dir_lookup_int(mp, path, &ino);
850 2422 : 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 2422 : if (error)
858 : return error;
859 :
860 4844 : if (!xfs_imeta_verify(mp, ino)) {
861 0 : xfs_fs_mark_sick(mp, XFS_SICK_FS_METADIR);
862 0 : return -EFSCORRUPTED;
863 : }
864 :
865 2422 : *inop = ino;
866 2422 : 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 16860 : xfs_imeta_create(
886 : struct xfs_imeta_update *upd,
887 : umode_t mode,
888 : struct xfs_inode **ipp)
889 : {
890 16860 : struct xfs_mount *mp = upd->mp;
891 16860 : int error;
892 :
893 16860 : ASSERT(xfs_imeta_path_check(upd->path));
894 :
895 16860 : *ipp = NULL;
896 :
897 16860 : if (xfs_has_metadir(mp))
898 16538 : error = xfs_imeta_dir_create(upd, mode);
899 : else
900 322 : error = xfs_imeta_sb_create(upd, mode);
901 16860 : *ipp = upd->ip;
902 16860 : 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 70649401394 : xfs_is_static_meta_ino(
987 : struct xfs_mount *mp,
988 : xfs_ino_t ino)
989 : {
990 70649401394 : const struct xfs_imeta_sbmap *p;
991 :
992 70649401394 : if (ino == NULLFSINO)
993 : return false;
994 :
995 >49167*10^7 : for (p = xfs_imeta_sbmaps; p->path; p++)
996 >42120*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 24321 : xfs_imeta_mount(
1005 : struct xfs_mount *mp)
1006 : {
1007 24321 : if (xfs_has_metadir(mp))
1008 23718 : 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 47781510 : xfs_imeta_droplink(
1016 : struct xfs_inode *ip)
1017 : {
1018 47781510 : if (VFS_I(ip)->i_nlink == 0 && xfs_is_metadir_inode(ip))
1019 0 : ip->i_diflags2 &= ~XFS_DIFLAG2_METADIR;
1020 47781510 : }
1021 :
1022 : /* Create a path to a file within the metadata directory tree. */
1023 : int
1024 2442 : xfs_imeta_create_file_path(
1025 : struct xfs_mount *mp,
1026 : unsigned int nr_components,
1027 : struct xfs_imeta_path **pathp)
1028 : {
1029 2442 : struct xfs_imeta_path *p;
1030 2442 : unsigned char **components;
1031 :
1032 2442 : p = kmalloc(sizeof(struct xfs_imeta_path), GFP_KERNEL);
1033 2442 : if (!p)
1034 : return -ENOMEM;
1035 :
1036 2442 : components = kvcalloc(nr_components, sizeof(unsigned char *),
1037 : GFP_KERNEL);
1038 2442 : if (!components) {
1039 0 : kfree(p);
1040 0 : return -ENOMEM;
1041 : }
1042 :
1043 2442 : p->im_depth = nr_components;
1044 2442 : p->im_path = (const unsigned char **)components;
1045 2442 : p->im_ftype = XFS_DIR3_FT_REG_FILE;
1046 2442 : p->im_dynamicmask = 0;
1047 2442 : *pathp = p;
1048 2442 : return 0;
1049 : }
1050 :
1051 : /* Free a metadata directory tree path. */
1052 : void
1053 2442 : xfs_imeta_free_path(
1054 : struct xfs_imeta_path *path)
1055 : {
1056 2442 : unsigned int i;
1057 :
1058 7326 : for (i = 0; i < path->im_depth; i++) {
1059 4884 : if ((path->im_dynamicmask & (1ULL << i)) && path->im_path[i])
1060 2442 : kfree(path->im_path[i]);
1061 : }
1062 2442 : kfree(path->im_path);
1063 2442 : kfree(path);
1064 2442 : }
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 30009862 : 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 30009862 : 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 0 : return __percpu_counter_compare(&ip->i_mount->m_fdblocks,
1089 0 : 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 15004975 : xfs_imeta_resv_critical(
1099 : struct xfs_inode *ip)
1100 : {
1101 15004975 : uint64_t asked_low_water;
1102 :
1103 15004975 : if (!ip)
1104 : return false;
1105 :
1106 15004975 : ASSERT(xfs_is_metadir_inode(ip));
1107 15004975 : trace_xfs_imeta_resv_critical(ip, 0);
1108 :
1109 15004931 : if (!xfs_imeta_resv_can_cover(ip, ip->i_mount->m_rtbtree_maxlevels))
1110 : return true;
1111 :
1112 15004974 : asked_low_water = div_u64(ip->i_meta_resv_asked, 10);
1113 15004974 : if (!xfs_imeta_resv_can_cover(ip, asked_low_water))
1114 : return true;
1115 :
1116 15004976 : 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 162793 : xfs_imeta_resv_alloc_extent(
1123 : struct xfs_inode *ip,
1124 : struct xfs_alloc_arg *args)
1125 : {
1126 162793 : int64_t len = args->len;
1127 :
1128 162793 : ASSERT(xfs_is_metadir_inode(ip));
1129 162793 : ASSERT(XFS_IS_DQDETACHED(ip->i_mount, ip));
1130 162793 : ASSERT(args->resv == XFS_AG_RESV_IMETA);
1131 :
1132 162793 : 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 162793 : if (ip->i_delayed_blks > 0) {
1139 162793 : int64_t from_resv;
1140 :
1141 162793 : from_resv = min_t(int64_t, len, ip->i_delayed_blks);
1142 162793 : ip->i_delayed_blks -= from_resv;
1143 162793 : xfs_mod_delalloc(ip->i_mount, -from_resv);
1144 162793 : xfs_trans_mod_sb(args->tp, XFS_TRANS_SB_RES_FDBLOCKS,
1145 : -from_resv);
1146 162793 : 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 162793 : if (len)
1154 0 : xfs_trans_mod_sb(args->tp, XFS_TRANS_SB_FDBLOCKS, -len);
1155 :
1156 162793 : ip->i_nblocks += args->len;
1157 162793 : xfs_trans_log_inode(args->tp, ip, XFS_ILOG_CORE);
1158 162793 : }
1159 :
1160 : /* Free a block to the metadata file's reservation. */
1161 : void
1162 16485 : xfs_imeta_resv_free_extent(
1163 : struct xfs_inode *ip,
1164 : struct xfs_trans *tp,
1165 : xfs_filblks_t len)
1166 : {
1167 16485 : int64_t to_resv;
1168 :
1169 16485 : ASSERT(xfs_is_metadir_inode(ip));
1170 16485 : ASSERT(XFS_IS_DQDETACHED(ip->i_mount, ip));
1171 16485 : trace_xfs_imeta_resv_free_extent(ip, len);
1172 :
1173 16485 : ip->i_nblocks -= len;
1174 16485 : 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 16485 : to_resv = ip->i_meta_resv_asked - (ip->i_nblocks + ip->i_delayed_blks);
1181 16485 : if (to_resv > 0) {
1182 16485 : to_resv = min_t(int64_t, to_resv, len);
1183 16485 : ip->i_delayed_blks += to_resv;
1184 16485 : xfs_mod_delalloc(ip->i_mount, to_resv);
1185 16485 : xfs_trans_mod_sb(tp, XFS_TRANS_SB_RES_FDBLOCKS, to_resv);
1186 16485 : 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 16485 : if (len)
1194 0 : xfs_trans_mod_sb(tp, XFS_TRANS_SB_FDBLOCKS, len);
1195 16485 : }
1196 :
1197 : /* Release a metadata file's space reservation. */
1198 : void
1199 5792 : xfs_imeta_resv_free_inode(
1200 : struct xfs_inode *ip)
1201 : {
1202 5792 : if (!ip)
1203 : return;
1204 :
1205 5792 : ASSERT(xfs_is_metadir_inode(ip));
1206 5792 : trace_xfs_imeta_resv_free(ip, 0);
1207 :
1208 5792 : xfs_mod_delalloc(ip->i_mount, -ip->i_delayed_blks);
1209 5792 : xfs_mod_fdblocks(ip->i_mount, ip->i_delayed_blks, true);
1210 5792 : ip->i_delayed_blks = 0;
1211 5792 : ip->i_meta_resv_asked = 0;
1212 : }
1213 :
1214 : /* Set up a metadata file's space reservation. */
1215 : int
1216 5752 : xfs_imeta_resv_init_inode(
1217 : struct xfs_inode *ip,
1218 : xfs_filblks_t ask)
1219 : {
1220 5752 : xfs_filblks_t hidden_space;
1221 5752 : xfs_filblks_t used;
1222 5752 : int error;
1223 :
1224 5752 : if (!ip || ip->i_meta_resv_asked > 0)
1225 : return 0;
1226 :
1227 5752 : 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 5752 : used = ip->i_nblocks;
1235 5752 : if (used > ask)
1236 : ask = used;
1237 5752 : hidden_space = ask - used;
1238 :
1239 5752 : error = xfs_mod_fdblocks(ip->i_mount, -(int64_t)hidden_space, true);
1240 5752 : if (error) {
1241 0 : trace_xfs_imeta_resv_init_error(ip, error, _RET_IP_);
1242 0 : return error;
1243 : }
1244 :
1245 5752 : xfs_mod_delalloc(ip->i_mount, hidden_space);
1246 5752 : ip->i_delayed_blks = hidden_space;
1247 5752 : ip->i_meta_resv_asked = ask;
1248 :
1249 5752 : trace_xfs_imeta_resv_init(ip, ask);
1250 5752 : return 0;
1251 : }
|