Line data Source code
1 : // SPDX-License-Identifier: GPL-2.0
2 : /*
3 : * Copyright (c) 2000-2006 Silicon Graphics, Inc.
4 : * All Rights Reserved.
5 : */
6 :
7 : #include "xfs.h"
8 : #include "xfs_fs.h"
9 : #include "xfs_shared.h"
10 : #include "xfs_format.h"
11 : #include "xfs_log_format.h"
12 : #include "xfs_trans_resv.h"
13 : #include "xfs_mount.h"
14 : #include "xfs_inode.h"
15 : #include "xfs_trans.h"
16 : #include "xfs_inode_item.h"
17 : #include "xfs_btree.h"
18 : #include "xfs_bmap_btree.h"
19 : #include "xfs_bmap.h"
20 : #include "xfs_error.h"
21 : #include "xfs_trace.h"
22 : #include "xfs_da_format.h"
23 : #include "xfs_da_btree.h"
24 : #include "xfs_dir2_priv.h"
25 : #include "xfs_attr_leaf.h"
26 : #include "xfs_types.h"
27 : #include "xfs_errortag.h"
28 :
29 : struct kmem_cache *xfs_ifork_cache;
30 :
31 : void
32 121057354 : xfs_init_local_fork(
33 : struct xfs_inode *ip,
34 : int whichfork,
35 : const void *data,
36 : int64_t size)
37 : {
38 121057354 : struct xfs_ifork *ifp = xfs_ifork_ptr(ip, whichfork);
39 121052458 : int mem_size = size;
40 121052458 : bool zero_terminate;
41 :
42 : /*
43 : * If we are using the local fork to store a symlink body we need to
44 : * zero-terminate it so that we can pass it back to the VFS directly.
45 : * Overallocate the in-memory fork by one for that and add a zero
46 : * to terminate it below.
47 : */
48 121052458 : zero_terminate = S_ISLNK(VFS_I(ip)->i_mode);
49 121052458 : if (zero_terminate)
50 15311837 : mem_size++;
51 :
52 121052458 : if (size) {
53 121052458 : ifp->if_u1.if_data = kmem_alloc(mem_size, KM_NOFS);
54 242121666 : memcpy(ifp->if_u1.if_data, data, size);
55 121060833 : if (zero_terminate)
56 15317654 : ifp->if_u1.if_data[size] = '\0';
57 : } else {
58 0 : ifp->if_u1.if_data = NULL;
59 : }
60 :
61 121060833 : ifp->if_bytes = size;
62 121060833 : }
63 :
64 : /*
65 : * The file is in-lined in the on-disk inode.
66 : */
67 : STATIC int
68 112437240 : xfs_iformat_local(
69 : struct xfs_inode *ip,
70 : struct xfs_dinode *dip,
71 : int whichfork,
72 : int size)
73 : {
74 : /*
75 : * If the size is unreasonable, then something
76 : * is wrong and we just bail out rather than crash in
77 : * kmem_alloc() or memcpy() below.
78 : */
79 112437457 : if (unlikely(size > XFS_DFORK_SIZE(dip, ip->i_mount, whichfork))) {
80 0 : xfs_warn(ip->i_mount,
81 : "corrupt inode %llu (bad size %d for local fork, size = %zd).",
82 : (unsigned long long) ip->i_ino, size,
83 : XFS_DFORK_SIZE(dip, ip->i_mount, whichfork));
84 0 : xfs_inode_verifier_error(ip, -EFSCORRUPTED,
85 : "xfs_iformat_local", dip, sizeof(*dip),
86 0 : __this_address);
87 0 : return -EFSCORRUPTED;
88 : }
89 :
90 224874115 : xfs_init_local_fork(ip, whichfork, XFS_DFORK_PTR(dip, whichfork), size);
91 112437240 : return 0;
92 : }
93 :
94 : /*
95 : * The file consists of a set of extents all of which fit into the on-disk
96 : * inode.
97 : */
98 : STATIC int
99 187159494 : xfs_iformat_extents(
100 : struct xfs_inode *ip,
101 : struct xfs_dinode *dip,
102 : int whichfork)
103 : {
104 187159494 : struct xfs_mount *mp = ip->i_mount;
105 187159494 : struct xfs_ifork *ifp = xfs_ifork_ptr(ip, whichfork);
106 187153194 : int state = xfs_bmap_fork_to_state(whichfork);
107 187153194 : xfs_extnum_t nex = xfs_dfork_nextents(dip, whichfork);
108 187166931 : int size = nex * sizeof(xfs_bmbt_rec_t);
109 187166931 : struct xfs_iext_cursor icur;
110 187166931 : struct xfs_bmbt_rec *dp;
111 187166931 : struct xfs_bmbt_irec new;
112 187166931 : int i;
113 :
114 : /*
115 : * If the number of extents is unreasonable, then something is wrong and
116 : * we just bail out rather than crash in kmem_alloc() or memcpy() below.
117 : */
118 187167417 : if (unlikely(size < 0 || size > XFS_DFORK_SIZE(dip, mp, whichfork))) {
119 0 : xfs_warn(ip->i_mount, "corrupt inode %llu ((a)extents = %llu).",
120 : ip->i_ino, nex);
121 0 : xfs_inode_verifier_error(ip, -EFSCORRUPTED,
122 : "xfs_iformat_extents(1)", dip, sizeof(*dip),
123 0 : __this_address);
124 0 : return -EFSCORRUPTED;
125 : }
126 :
127 187166931 : ifp->if_bytes = 0;
128 187166931 : ifp->if_u1.if_root = NULL;
129 187166931 : ifp->if_height = 0;
130 187166931 : if (size) {
131 241198254 : dp = (xfs_bmbt_rec_t *) XFS_DFORK_PTR(dip, whichfork);
132 :
133 120600821 : xfs_iext_first(ifp, &icur);
134 747221392 : for (i = 0; i < nex; i++, dp++) {
135 506028943 : xfs_failaddr_t fa;
136 :
137 506028943 : xfs_bmbt_disk_get_all(dp, &new);
138 506032384 : fa = xfs_bmap_validate_extent(ip, whichfork, &new);
139 506031345 : if (fa) {
140 0 : xfs_inode_verifier_error(ip, -EFSCORRUPTED,
141 : "xfs_iformat_extents(2)",
142 : dp, sizeof(*dp), fa);
143 0 : return xfs_bmap_complain_bad_rec(ip, whichfork,
144 : fa, &new);
145 : }
146 :
147 506031345 : xfs_iext_insert(ip, &icur, &new, state);
148 506024780 : trace_xfs_read_extent(ip, &icur, state, _THIS_IP_);
149 506025455 : xfs_iext_next(ifp, &icur);
150 : }
151 : }
152 : return 0;
153 : }
154 :
155 : /*
156 : * The file has too many extents to fit into
157 : * the inode, so they are in B-tree format.
158 : * Allocate a buffer for the root of the B-tree
159 : * and copy the root into it. The i_extents
160 : * field will remain NULL until all of the
161 : * extents are read in (when they are needed).
162 : */
163 : STATIC int
164 5927595 : xfs_iformat_btree(
165 : struct xfs_inode *ip,
166 : struct xfs_dinode *dip,
167 : int whichfork)
168 : {
169 5927595 : struct xfs_mount *mp = ip->i_mount;
170 5927595 : xfs_bmdr_block_t *dfp;
171 5927595 : struct xfs_ifork *ifp;
172 : /* REFERENCED */
173 5927595 : int nrecs;
174 5927595 : int size;
175 5927595 : int level;
176 :
177 5927595 : ifp = xfs_ifork_ptr(ip, whichfork);
178 11855189 : dfp = (xfs_bmdr_block_t *)XFS_DFORK_PTR(dip, whichfork);
179 5927595 : size = XFS_BMAP_BROOT_SPACE(mp, dfp);
180 5927595 : nrecs = be16_to_cpu(dfp->bb_numrecs);
181 5927595 : level = be16_to_cpu(dfp->bb_level);
182 :
183 : /*
184 : * blow out if -- fork has less extents than can fit in
185 : * fork (fork shouldn't be a btree format), root btree
186 : * block has more records than can fit into the fork,
187 : * or the number of extents is greater than the number of
188 : * blocks.
189 : */
190 5927595 : if (unlikely(ifp->if_nextents <= XFS_IFORK_MAXEXT(ip, whichfork) ||
191 : nrecs == 0 ||
192 : XFS_BMDR_SPACE_CALC(nrecs) >
193 : XFS_DFORK_SIZE(dip, mp, whichfork) ||
194 5927595 : ifp->if_nextents > ip->i_nblocks) ||
195 5927595 : level == 0 || level > XFS_BM_MAXLEVELS(mp, whichfork)) {
196 0 : xfs_warn(mp, "corrupt inode %llu (btree).",
197 : (unsigned long long) ip->i_ino);
198 0 : xfs_inode_verifier_error(ip, -EFSCORRUPTED,
199 : "xfs_iformat_btree", dfp, size,
200 0 : __this_address);
201 0 : return -EFSCORRUPTED;
202 : }
203 :
204 5927596 : ifp->if_broot_bytes = size;
205 5927596 : ifp->if_broot = kmem_alloc(size, KM_NOFS);
206 5927598 : ASSERT(ifp->if_broot != NULL);
207 : /*
208 : * Copy and convert from the on-disk structure
209 : * to the in-memory structure.
210 : */
211 5927598 : xfs_bmdr_to_bmbt(ip, dfp, XFS_DFORK_SIZE(dip, ip->i_mount, whichfork),
212 : ifp->if_broot, size);
213 :
214 5927594 : ifp->if_bytes = 0;
215 5927594 : ifp->if_u1.if_root = NULL;
216 5927594 : ifp->if_height = 0;
217 5927594 : return 0;
218 : }
219 :
220 : int
221 392485702 : xfs_iformat_data_fork(
222 : struct xfs_inode *ip,
223 : struct xfs_dinode *dip)
224 : {
225 392485702 : struct inode *inode = VFS_I(ip);
226 392485702 : int error;
227 :
228 : /*
229 : * Initialize the extent count early, as the per-format routines may
230 : * depend on it. Use release semantics to set needextents /after/ we
231 : * set the format. This ensures that we can use acquire semantics on
232 : * needextents in xfs_need_iread_extents() and be guaranteed to see a
233 : * valid format value after that load.
234 : */
235 392485702 : ip->i_df.if_format = dip->di_format;
236 392485702 : ip->i_df.if_nextents = xfs_dfork_data_extents(dip);
237 392485702 : smp_store_release(&ip->i_df.if_needextents,
238 : ip->i_df.if_format == XFS_DINODE_FMT_BTREE ? 1 : 0);
239 :
240 392431570 : switch (inode->i_mode & S_IFMT) {
241 131276379 : case S_IFIFO:
242 : case S_IFCHR:
243 : case S_IFBLK:
244 : case S_IFSOCK:
245 131276379 : ip->i_disk_size = 0;
246 131276379 : inode->i_rdev = xfs_to_linux_dev_t(xfs_dinode_get_rdev(dip));
247 131276379 : return 0;
248 261155191 : case S_IFREG:
249 : case S_IFLNK:
250 : case S_IFDIR:
251 261155191 : switch (ip->i_df.if_format) {
252 70162985 : case XFS_DINODE_FMT_LOCAL:
253 70162985 : error = xfs_iformat_local(ip, dip, XFS_DATA_FORK,
254 70162985 : be64_to_cpu(dip->di_size));
255 70163872 : if (!error)
256 70163857 : error = xfs_ifork_verify_local_data(ip);
257 : return error;
258 185064652 : case XFS_DINODE_FMT_EXTENTS:
259 185064652 : return xfs_iformat_extents(ip, dip, XFS_DATA_FORK);
260 5927554 : case XFS_DINODE_FMT_BTREE:
261 5927554 : return xfs_iformat_btree(ip, dip, XFS_DATA_FORK);
262 : default:
263 0 : xfs_inode_verifier_error(ip, -EFSCORRUPTED, __func__,
264 0 : dip, sizeof(*dip), __this_address);
265 0 : return -EFSCORRUPTED;
266 : }
267 0 : break;
268 : default:
269 0 : xfs_inode_verifier_error(ip, -EFSCORRUPTED, __func__, dip,
270 0 : sizeof(*dip), __this_address);
271 0 : return -EFSCORRUPTED;
272 : }
273 : }
274 :
275 : static uint16_t
276 : xfs_dfork_attr_shortform_size(
277 : struct xfs_dinode *dip)
278 : {
279 84547862 : struct xfs_attr_shortform *atp =
280 84547862 : (struct xfs_attr_shortform *)XFS_DFORK_APTR(dip);
281 :
282 42273931 : return be16_to_cpu(atp->hdr.totsize);
283 : }
284 :
285 : void
286 4927275 : xfs_ifork_init_attr(
287 : struct xfs_inode *ip,
288 : enum xfs_dinode_fmt format,
289 : xfs_extnum_t nextents)
290 : {
291 : /*
292 : * Initialize the extent count early, as the per-format routines may
293 : * depend on it. Use release semantics to set needextents /after/ we
294 : * set the format. This ensures that we can use acquire semantics on
295 : * needextents in xfs_need_iread_extents() and be guaranteed to see a
296 : * valid format value after that load.
297 : */
298 49270691 : ip->i_af.if_format = format;
299 49270691 : ip->i_af.if_nextents = nextents;
300 4927275 : smp_store_release(&ip->i_af.if_needextents,
301 : ip->i_af.if_format == XFS_DINODE_FMT_BTREE ? 1 : 0);
302 4927031 : }
303 :
304 : void
305 441885893 : xfs_ifork_zap_attr(
306 : struct xfs_inode *ip)
307 : {
308 441885893 : xfs_idestroy_fork(&ip->i_af);
309 441935904 : memset(&ip->i_af, 0, sizeof(struct xfs_ifork));
310 441935904 : ip->i_af.if_format = XFS_DINODE_FMT_EXTENTS;
311 441935904 : }
312 :
313 : int
314 44343416 : xfs_iformat_attr_fork(
315 : struct xfs_inode *ip,
316 : struct xfs_dinode *dip)
317 : {
318 44343416 : xfs_extnum_t naextents = xfs_dfork_attr_extents(dip);
319 44343416 : int error = 0;
320 :
321 : /*
322 : * Initialize the extent count early, as the per-format routines may
323 : * depend on it.
324 : */
325 44343416 : xfs_ifork_init_attr(ip, dip->di_aformat, naextents);
326 :
327 44343354 : switch (ip->i_af.if_format) {
328 : case XFS_DINODE_FMT_LOCAL:
329 84547856 : error = xfs_iformat_local(ip, dip, XFS_ATTR_FORK,
330 : xfs_dfork_attr_shortform_size(dip));
331 42273897 : if (!error)
332 42273899 : error = xfs_ifork_verify_local_attr(ip);
333 : break;
334 2069383 : case XFS_DINODE_FMT_EXTENTS:
335 2069383 : error = xfs_iformat_extents(ip, dip, XFS_ATTR_FORK);
336 2069383 : break;
337 40 : case XFS_DINODE_FMT_BTREE:
338 40 : error = xfs_iformat_btree(ip, dip, XFS_ATTR_FORK);
339 40 : break;
340 : default:
341 0 : xfs_inode_verifier_error(ip, error, __func__, dip,
342 0 : sizeof(*dip), __this_address);
343 0 : error = -EFSCORRUPTED;
344 0 : break;
345 : }
346 :
347 44343361 : if (error)
348 0 : xfs_ifork_zap_attr(ip);
349 44343361 : return error;
350 : }
351 :
352 : /*
353 : * Reallocate the space for if_broot based on the number of records
354 : * being added or deleted as indicated in rec_diff. Move the records
355 : * and pointers in if_broot to fit the new size. When shrinking this
356 : * will eliminate holes between the records and pointers created by
357 : * the caller. When growing this will create holes to be filled in
358 : * by the caller.
359 : *
360 : * The caller must not request to add more records than would fit in
361 : * the on-disk inode root. If the if_broot is currently NULL, then
362 : * if we are adding records, one will be allocated. The caller must also
363 : * not request that the number of records go below zero, although
364 : * it can go to zero.
365 : *
366 : * ip -- the inode whose if_broot area is changing
367 : * ext_diff -- the change in the number of records, positive or negative,
368 : * requested for the if_broot array.
369 : */
370 : void
371 1451201 : xfs_iroot_realloc(
372 : xfs_inode_t *ip,
373 : int rec_diff,
374 : int whichfork)
375 : {
376 1451201 : struct xfs_mount *mp = ip->i_mount;
377 1451201 : int cur_max;
378 1451201 : struct xfs_ifork *ifp;
379 1451201 : struct xfs_btree_block *new_broot;
380 1451201 : int new_max;
381 1451201 : size_t new_size;
382 1451201 : char *np;
383 1451201 : char *op;
384 :
385 : /*
386 : * Handle the degenerate case quietly.
387 : */
388 1451201 : if (rec_diff == 0) {
389 : return;
390 : }
391 :
392 1451201 : ifp = xfs_ifork_ptr(ip, whichfork);
393 1451196 : if (rec_diff > 0) {
394 : /*
395 : * If there wasn't any memory allocated before, just
396 : * allocate it now and get out.
397 : */
398 897155 : if (ifp->if_broot_bytes == 0) {
399 814701 : new_size = XFS_BMAP_BROOT_SPACE_CALC(mp, rec_diff);
400 814701 : ifp->if_broot = kmem_alloc(new_size, KM_NOFS);
401 814704 : ifp->if_broot_bytes = (int)new_size;
402 814704 : return;
403 : }
404 :
405 : /*
406 : * If there is already an existing if_broot, then we need
407 : * to realloc() it and shift the pointers to their new
408 : * location. The records don't change location because
409 : * they are kept butted up against the btree block header.
410 : */
411 82454 : cur_max = xfs_bmbt_maxrecs(mp, ifp->if_broot_bytes, 0);
412 82454 : new_max = cur_max + rec_diff;
413 82454 : new_size = XFS_BMAP_BROOT_SPACE_CALC(mp, new_max);
414 82454 : ifp->if_broot = krealloc(ifp->if_broot, new_size,
415 : GFP_NOFS | __GFP_NOFAIL);
416 82455 : op = (char *)XFS_BMAP_BROOT_PTR_ADDR(mp, ifp->if_broot, 1,
417 : ifp->if_broot_bytes);
418 82454 : np = (char *)XFS_BMAP_BROOT_PTR_ADDR(mp, ifp->if_broot, 1,
419 : (int)new_size);
420 82455 : ifp->if_broot_bytes = (int)new_size;
421 82455 : ASSERT(XFS_BMAP_BMDR_SPACE(ifp->if_broot) <=
422 : xfs_inode_fork_size(ip, whichfork));
423 164910 : memmove(np, op, cur_max * (uint)sizeof(xfs_fsblock_t));
424 82455 : return;
425 : }
426 :
427 : /*
428 : * rec_diff is less than 0. In this case, we are shrinking the
429 : * if_broot buffer. It must already exist. If we go to zero
430 : * records, just get rid of the root and clear the status bit.
431 : */
432 554041 : ASSERT((ifp->if_broot != NULL) && (ifp->if_broot_bytes > 0));
433 554041 : cur_max = xfs_bmbt_maxrecs(mp, ifp->if_broot_bytes, 0);
434 554041 : new_max = cur_max + rec_diff;
435 554041 : ASSERT(new_max >= 0);
436 554041 : if (new_max > 0)
437 60313 : new_size = XFS_BMAP_BROOT_SPACE_CALC(mp, new_max);
438 : else
439 : new_size = 0;
440 60313 : if (new_size > 0) {
441 60313 : new_broot = kmem_alloc(new_size, KM_NOFS);
442 : /*
443 : * First copy over the btree block header.
444 : */
445 120626 : memcpy(new_broot, ifp->if_broot,
446 : XFS_BMBT_BLOCK_LEN(ip->i_mount));
447 : } else {
448 : new_broot = NULL;
449 : }
450 :
451 : /*
452 : * Only copy the records and pointers if there are any.
453 : */
454 554041 : if (new_max > 0) {
455 : /*
456 : * First copy the records.
457 : */
458 60313 : op = (char *)XFS_BMBT_REC_ADDR(mp, ifp->if_broot, 1);
459 60313 : np = (char *)XFS_BMBT_REC_ADDR(mp, new_broot, 1);
460 120626 : memcpy(np, op, new_max * (uint)sizeof(xfs_bmbt_rec_t));
461 :
462 : /*
463 : * Then copy the pointers.
464 : */
465 60313 : op = (char *)XFS_BMAP_BROOT_PTR_ADDR(mp, ifp->if_broot, 1,
466 : ifp->if_broot_bytes);
467 60313 : np = (char *)XFS_BMAP_BROOT_PTR_ADDR(mp, new_broot, 1,
468 : (int)new_size);
469 120626 : memcpy(np, op, new_max * (uint)sizeof(xfs_fsblock_t));
470 : }
471 554041 : kmem_free(ifp->if_broot);
472 554042 : ifp->if_broot = new_broot;
473 554042 : ifp->if_broot_bytes = (int)new_size;
474 554042 : if (ifp->if_broot)
475 60313 : ASSERT(XFS_BMAP_BMDR_SPACE(ifp->if_broot) <=
476 : xfs_inode_fork_size(ip, whichfork));
477 : return;
478 : }
479 :
480 :
481 : /*
482 : * This is called when the amount of space needed for if_data
483 : * is increased or decreased. The change in size is indicated by
484 : * the number of bytes that need to be added or deleted in the
485 : * byte_diff parameter.
486 : *
487 : * If the amount of space needed has decreased below the size of the
488 : * inline buffer, then switch to using the inline buffer. Otherwise,
489 : * use kmem_realloc() or kmem_alloc() to adjust the size of the buffer
490 : * to what is needed.
491 : *
492 : * ip -- the inode whose if_data area is changing
493 : * byte_diff -- the change in the number of bytes, positive or negative,
494 : * requested for the if_data array.
495 : */
496 : void
497 145412865 : xfs_idata_realloc(
498 : struct xfs_inode *ip,
499 : int64_t byte_diff,
500 : int whichfork)
501 : {
502 145412865 : struct xfs_ifork *ifp = xfs_ifork_ptr(ip, whichfork);
503 145384953 : int64_t new_size = ifp->if_bytes + byte_diff;
504 :
505 145384953 : ASSERT(new_size >= 0);
506 145384953 : ASSERT(new_size <= xfs_inode_fork_size(ip, whichfork));
507 :
508 145384953 : if (byte_diff == 0)
509 : return;
510 :
511 145384953 : if (new_size == 0) {
512 3041396 : kmem_free(ifp->if_u1.if_data);
513 3041545 : ifp->if_u1.if_data = NULL;
514 3041545 : ifp->if_bytes = 0;
515 3041545 : return;
516 : }
517 :
518 142343557 : ifp->if_u1.if_data = krealloc(ifp->if_u1.if_data, new_size,
519 : GFP_NOFS | __GFP_NOFAIL);
520 142386331 : ifp->if_bytes = new_size;
521 : }
522 :
523 : void
524 819946671 : xfs_idestroy_fork(
525 : struct xfs_ifork *ifp)
526 : {
527 819946671 : if (ifp->if_broot != NULL) {
528 6248341 : kmem_free(ifp->if_broot);
529 6248392 : ifp->if_broot = NULL;
530 : }
531 :
532 819946722 : switch (ifp->if_format) {
533 121815467 : case XFS_DINODE_FMT_LOCAL:
534 121815467 : kmem_free(ifp->if_u1.if_data);
535 121839258 : ifp->if_u1.if_data = NULL;
536 121839258 : break;
537 698131255 : case XFS_DINODE_FMT_EXTENTS:
538 : case XFS_DINODE_FMT_BTREE:
539 698131255 : if (ifp->if_height)
540 128478376 : xfs_iext_destroy(ifp);
541 : break;
542 : }
543 819962848 : }
544 :
545 : /*
546 : * Convert in-core extents to on-disk form
547 : *
548 : * In the case of the data fork, the in-core and on-disk fork sizes can be
549 : * different due to delayed allocation extents. We only copy on-disk extents
550 : * here, so callers must always use the physical fork size to determine the
551 : * size of the buffer passed to this routine. We will return the size actually
552 : * used.
553 : */
554 : int
555 498277719 : xfs_iextents_copy(
556 : struct xfs_inode *ip,
557 : struct xfs_bmbt_rec *dp,
558 : int whichfork)
559 : {
560 498277719 : int state = xfs_bmap_fork_to_state(whichfork);
561 498277719 : struct xfs_ifork *ifp = xfs_ifork_ptr(ip, whichfork);
562 498124534 : struct xfs_iext_cursor icur;
563 498124534 : struct xfs_bmbt_irec rec;
564 498124534 : int64_t copied = 0;
565 :
566 498124534 : ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL | XFS_ILOCK_SHARED));
567 498161245 : ASSERT(ifp->if_bytes > 0);
568 :
569 3545642388 : for_each_xfs_iext(ifp, &icur, &rec) {
570 3047549223 : if (isnullstartblock(rec.br_startblock))
571 51830772 : continue;
572 2995718451 : ASSERT(xfs_bmap_validate_extent(ip, whichfork, &rec) == NULL);
573 2995672366 : xfs_bmbt_disk_set_all(dp, &rec);
574 2995641761 : trace_xfs_write_extent(ip, &icur, state, _RET_IP_);
575 2995650371 : copied += sizeof(struct xfs_bmbt_rec);
576 2995650371 : dp++;
577 : }
578 :
579 498194247 : ASSERT(copied > 0);
580 498194247 : ASSERT(copied <= ifp->if_bytes);
581 498194247 : return copied;
582 : }
583 :
584 : /*
585 : * Each of the following cases stores data into the same region
586 : * of the on-disk inode, so only one of them can be valid at
587 : * any given time. While it is possible to have conflicting formats
588 : * and log flags, e.g. having XFS_ILOG_?DATA set when the fork is
589 : * in EXTENTS format, this can only happen when the fork has
590 : * changed formats after being modified but before being flushed.
591 : * In these cases, the format always takes precedence, because the
592 : * format indicates the current state of the fork.
593 : */
594 : void
595 222245326 : xfs_iflush_fork(
596 : struct xfs_inode *ip,
597 : struct xfs_dinode *dip,
598 : struct xfs_inode_log_item *iip,
599 : int whichfork)
600 : {
601 222245326 : char *cp;
602 222245326 : struct xfs_ifork *ifp;
603 222245326 : xfs_mount_t *mp;
604 222245326 : static const short brootflag[2] =
605 : { XFS_ILOG_DBROOT, XFS_ILOG_ABROOT };
606 222245326 : static const short dataflag[2] =
607 : { XFS_ILOG_DDATA, XFS_ILOG_ADATA };
608 222245326 : static const short extflag[2] =
609 : { XFS_ILOG_DEXT, XFS_ILOG_AEXT };
610 :
611 222245326 : if (!iip)
612 : return;
613 222245326 : ifp = xfs_ifork_ptr(ip, whichfork);
614 : /*
615 : * This can happen if we gave up in iformat in an error path,
616 : * for the attribute fork.
617 : */
618 222245326 : if (!ifp) {
619 0 : ASSERT(whichfork == XFS_ATTR_FORK);
620 0 : return;
621 : }
622 444489356 : cp = XFS_DFORK_PTR(dip, whichfork);
623 222245326 : mp = ip->i_mount;
624 222245326 : switch (ifp->if_format) {
625 64370532 : case XFS_DINODE_FMT_LOCAL:
626 64370532 : if ((iip->ili_fields & dataflag[whichfork]) &&
627 51165980 : (ifp->if_bytes > 0)) {
628 51165980 : ASSERT(ifp->if_u1.if_data != NULL);
629 51165980 : ASSERT(ifp->if_bytes <= xfs_inode_fork_size(ip, whichfork));
630 102331960 : memcpy(cp, ifp->if_u1.if_data, ifp->if_bytes);
631 : }
632 : break;
633 :
634 142042007 : case XFS_DINODE_FMT_EXTENTS:
635 142042007 : if ((iip->ili_fields & extflag[whichfork]) &&
636 31847972 : (ifp->if_bytes > 0)) {
637 31847972 : ASSERT(ifp->if_nextents > 0);
638 31847972 : (void)xfs_iextents_copy(ip, (xfs_bmbt_rec_t *)cp,
639 : whichfork);
640 : }
641 : break;
642 :
643 3873897 : case XFS_DINODE_FMT_BTREE:
644 3873897 : if ((iip->ili_fields & brootflag[whichfork]) &&
645 621941 : (ifp->if_broot_bytes > 0)) {
646 621941 : ASSERT(ifp->if_broot != NULL);
647 621941 : ASSERT(XFS_BMAP_BMDR_SPACE(ifp->if_broot) <=
648 : xfs_inode_fork_size(ip, whichfork));
649 1243882 : xfs_bmbt_to_bmdr(mp, ifp->if_broot, ifp->if_broot_bytes,
650 : (xfs_bmdr_block_t *)cp,
651 621941 : XFS_DFORK_SIZE(dip, mp, whichfork));
652 : }
653 : break;
654 :
655 11958890 : case XFS_DINODE_FMT_DEV:
656 11958890 : if (iip->ili_fields & XFS_ILOG_DEV) {
657 6883891 : ASSERT(whichfork == XFS_DATA_FORK);
658 6883891 : xfs_dinode_put_rdev(dip,
659 : linux_to_xfs_dev_t(VFS_I(ip)->i_rdev));
660 : }
661 : break;
662 :
663 0 : default:
664 0 : ASSERT(0);
665 0 : break;
666 : }
667 : }
668 :
669 : /* Convert bmap state flags to an inode fork. */
670 : struct xfs_ifork *
671 2163822195 : xfs_iext_state_to_fork(
672 : struct xfs_inode *ip,
673 : int state)
674 : {
675 2163822195 : if (state & BMAP_COWFORK)
676 41878109 : return ip->i_cowfp;
677 2121944086 : else if (state & BMAP_ATTRFORK)
678 6876090 : return &ip->i_af;
679 2115067996 : return &ip->i_df;
680 : }
681 :
682 : /*
683 : * Initialize an inode's copy-on-write fork.
684 : */
685 : void
686 97767897 : xfs_ifork_init_cow(
687 : struct xfs_inode *ip)
688 : {
689 97767897 : if (ip->i_cowfp)
690 : return;
691 :
692 97148155 : ip->i_cowfp = kmem_cache_zalloc(xfs_ifork_cache,
693 : GFP_NOFS | __GFP_NOFAIL);
694 97148279 : ip->i_cowfp->if_format = XFS_DINODE_FMT_EXTENTS;
695 : }
696 :
697 : /* Verify the inline contents of the data fork of an inode. */
698 : int
699 112355177 : xfs_ifork_verify_local_data(
700 : struct xfs_inode *ip)
701 : {
702 112355177 : xfs_failaddr_t fa = NULL;
703 :
704 112355177 : switch (VFS_I(ip)->i_mode & S_IFMT) {
705 103235007 : case S_IFDIR:
706 103235007 : fa = xfs_dir2_sf_verify(ip);
707 103235007 : break;
708 9120170 : case S_IFLNK:
709 9120170 : fa = xfs_symlink_shortform_verify(ip);
710 9120170 : break;
711 : default:
712 : break;
713 : }
714 :
715 112356718 : if (fa) {
716 22 : xfs_inode_verifier_error(ip, -EFSCORRUPTED, "data fork",
717 22 : ip->i_df.if_u1.if_data, ip->i_df.if_bytes, fa);
718 22 : return -EFSCORRUPTED;
719 : }
720 :
721 : return 0;
722 : }
723 :
724 : /* Verify the inline contents of the attr fork of an inode. */
725 : int
726 64453099 : xfs_ifork_verify_local_attr(
727 : struct xfs_inode *ip)
728 : {
729 64453099 : struct xfs_ifork *ifp = &ip->i_af;
730 64453099 : xfs_failaddr_t fa;
731 :
732 64453099 : if (!xfs_inode_has_attr_fork(ip))
733 0 : fa = __this_address;
734 : else
735 64453099 : fa = xfs_attr_shortform_verify(ip);
736 :
737 64453084 : if (fa) {
738 0 : xfs_inode_verifier_error(ip, -EFSCORRUPTED, "attr fork",
739 0 : ifp->if_u1.if_data, ifp->if_bytes, fa);
740 0 : return -EFSCORRUPTED;
741 : }
742 :
743 : return 0;
744 : }
745 :
746 : int
747 416320828 : xfs_iext_count_may_overflow(
748 : struct xfs_inode *ip,
749 : int whichfork,
750 : int nr_to_add)
751 : {
752 416320828 : struct xfs_ifork *ifp = xfs_ifork_ptr(ip, whichfork);
753 416191229 : uint64_t max_exts;
754 416191229 : uint64_t nr_exts;
755 :
756 416191229 : if (whichfork == XFS_COW_FORK)
757 : return 0;
758 :
759 411935940 : max_exts = xfs_iext_max_nextents(xfs_inode_has_large_extent_counts(ip),
760 : whichfork);
761 :
762 411906790 : if (XFS_TEST_ERROR(false, ip->i_mount, XFS_ERRTAG_REDUCE_MAX_IEXTENTS))
763 1823 : max_exts = 10;
764 :
765 411859761 : nr_exts = ifp->if_nextents + nr_to_add;
766 411859761 : if (nr_exts < ifp->if_nextents || nr_exts > max_exts)
767 255 : return -EFBIG;
768 :
769 : return 0;
770 : }
771 :
772 : /*
773 : * Upgrade this inode's extent counter fields to be able to handle a potential
774 : * increase in the extent count by nr_to_add. Normally this is the same
775 : * quantity that caused xfs_iext_count_may_overflow() to return -EFBIG.
776 : */
777 : int
778 255 : xfs_iext_count_upgrade(
779 : struct xfs_trans *tp,
780 : struct xfs_inode *ip,
781 : uint nr_to_add)
782 : {
783 255 : ASSERT(nr_to_add <= XFS_MAX_EXTCNT_UPGRADE_NR);
784 :
785 255 : if (!xfs_has_large_extent_counts(ip->i_mount) ||
786 0 : xfs_inode_has_large_extent_counts(ip) ||
787 0 : XFS_TEST_ERROR(false, ip->i_mount, XFS_ERRTAG_REDUCE_MAX_IEXTENTS))
788 255 : return -EFBIG;
789 :
790 0 : ip->i_diflags2 |= XFS_DIFLAG2_NREXT64;
791 0 : xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
792 :
793 0 : return 0;
794 : }
|