hc
2024-05-13 9d77db3c730780c8ef5ccd4b66403ff5675cfe4e
kernel/fs/xfs/libxfs/xfs_inode_fork.c
....@@ -3,10 +3,10 @@
33 * Copyright (c) 2000-2006 Silicon Graphics, Inc.
44 * All Rights Reserved.
55 */
6
-#include <linux/log2.h>
76
87 #include "xfs.h"
98 #include "xfs_fs.h"
9
+#include "xfs_shared.h"
1010 #include "xfs_format.h"
1111 #include "xfs_log_format.h"
1212 #include "xfs_trans_resv.h"
....@@ -19,119 +19,19 @@
1919 #include "xfs_bmap.h"
2020 #include "xfs_error.h"
2121 #include "xfs_trace.h"
22
-#include "xfs_attr_sf.h"
2322 #include "xfs_da_format.h"
2423 #include "xfs_da_btree.h"
2524 #include "xfs_dir2_priv.h"
2625 #include "xfs_attr_leaf.h"
27
-#include "xfs_shared.h"
2826
2927 kmem_zone_t *xfs_ifork_zone;
30
-
31
-STATIC int xfs_iformat_local(xfs_inode_t *, xfs_dinode_t *, int, int);
32
-STATIC int xfs_iformat_extents(xfs_inode_t *, xfs_dinode_t *, int);
33
-STATIC int xfs_iformat_btree(xfs_inode_t *, xfs_dinode_t *, int);
34
-
35
-/*
36
- * Copy inode type and data and attr format specific information from the
37
- * on-disk inode to the in-core inode and fork structures. For fifos, devices,
38
- * and sockets this means set i_rdev to the proper value. For files,
39
- * directories, and symlinks this means to bring in the in-line data or extent
40
- * pointers as well as the attribute fork. For a fork in B-tree format, only
41
- * the root is immediately brought in-core. The rest will be read in later when
42
- * first referenced (see xfs_iread_extents()).
43
- */
44
-int
45
-xfs_iformat_fork(
46
- struct xfs_inode *ip,
47
- struct xfs_dinode *dip)
48
-{
49
- struct inode *inode = VFS_I(ip);
50
- struct xfs_attr_shortform *atp;
51
- int size;
52
- int error = 0;
53
- xfs_fsize_t di_size;
54
-
55
- switch (inode->i_mode & S_IFMT) {
56
- case S_IFIFO:
57
- case S_IFCHR:
58
- case S_IFBLK:
59
- case S_IFSOCK:
60
- ip->i_d.di_size = 0;
61
- inode->i_rdev = xfs_to_linux_dev_t(xfs_dinode_get_rdev(dip));
62
- break;
63
-
64
- case S_IFREG:
65
- case S_IFLNK:
66
- case S_IFDIR:
67
- switch (dip->di_format) {
68
- case XFS_DINODE_FMT_LOCAL:
69
- di_size = be64_to_cpu(dip->di_size);
70
- size = (int)di_size;
71
- error = xfs_iformat_local(ip, dip, XFS_DATA_FORK, size);
72
- break;
73
- case XFS_DINODE_FMT_EXTENTS:
74
- error = xfs_iformat_extents(ip, dip, XFS_DATA_FORK);
75
- break;
76
- case XFS_DINODE_FMT_BTREE:
77
- error = xfs_iformat_btree(ip, dip, XFS_DATA_FORK);
78
- break;
79
- default:
80
- return -EFSCORRUPTED;
81
- }
82
- break;
83
-
84
- default:
85
- return -EFSCORRUPTED;
86
- }
87
- if (error)
88
- return error;
89
-
90
- if (xfs_is_reflink_inode(ip)) {
91
- ASSERT(ip->i_cowfp == NULL);
92
- xfs_ifork_init_cow(ip);
93
- }
94
-
95
- if (!XFS_DFORK_Q(dip))
96
- return 0;
97
-
98
- ASSERT(ip->i_afp == NULL);
99
- ip->i_afp = kmem_zone_zalloc(xfs_ifork_zone, KM_SLEEP | KM_NOFS);
100
-
101
- switch (dip->di_aformat) {
102
- case XFS_DINODE_FMT_LOCAL:
103
- atp = (xfs_attr_shortform_t *)XFS_DFORK_APTR(dip);
104
- size = be16_to_cpu(atp->hdr.totsize);
105
-
106
- error = xfs_iformat_local(ip, dip, XFS_ATTR_FORK, size);
107
- break;
108
- case XFS_DINODE_FMT_EXTENTS:
109
- error = xfs_iformat_extents(ip, dip, XFS_ATTR_FORK);
110
- break;
111
- case XFS_DINODE_FMT_BTREE:
112
- error = xfs_iformat_btree(ip, dip, XFS_ATTR_FORK);
113
- break;
114
- default:
115
- error = -EFSCORRUPTED;
116
- break;
117
- }
118
- if (error) {
119
- kmem_zone_free(xfs_ifork_zone, ip->i_afp);
120
- ip->i_afp = NULL;
121
- if (ip->i_cowfp)
122
- kmem_zone_free(xfs_ifork_zone, ip->i_cowfp);
123
- ip->i_cowfp = NULL;
124
- xfs_idestroy_fork(ip, XFS_DATA_FORK);
125
- }
126
- return error;
127
-}
12828
12929 void
13030 xfs_init_local_fork(
13131 struct xfs_inode *ip,
13232 int whichfork,
13333 const void *data,
134
- int size)
34
+ int64_t size)
13535 {
13636 struct xfs_ifork *ifp = XFS_IFORK_PTR(ip, whichfork);
13737 int mem_size = size, real_size = 0;
....@@ -149,7 +49,7 @@
14949
15050 if (size) {
15151 real_size = roundup(mem_size, 4);
152
- ifp->if_u1.if_data = kmem_alloc(real_size, KM_SLEEP | KM_NOFS);
52
+ ifp->if_u1.if_data = kmem_alloc(real_size, KM_NOFS);
15353 memcpy(ifp->if_u1.if_data, data, size);
15454 if (zero_terminate)
15555 ifp->if_u1.if_data[size] = '\0';
....@@ -179,7 +79,7 @@
17979 */
18080 if (unlikely(size > XFS_DFORK_SIZE(dip, ip->i_mount, whichfork))) {
18181 xfs_warn(ip->i_mount,
182
- "corrupt inode %Lu (bad size %d for local fork, size = %d).",
82
+ "corrupt inode %Lu (bad size %d for local fork, size = %zd).",
18383 (unsigned long long) ip->i_ino, size,
18484 XFS_DFORK_SIZE(dip, ip->i_mount, whichfork));
18585 xfs_inode_verifier_error(ip, -EFSCORRUPTED,
....@@ -288,12 +188,11 @@
288188 * or the number of extents is greater than the number of
289189 * blocks.
290190 */
291
- if (unlikely(XFS_IFORK_NEXTENTS(ip, whichfork) <=
292
- XFS_IFORK_MAXEXT(ip, whichfork) ||
191
+ if (unlikely(ifp->if_nextents <= XFS_IFORK_MAXEXT(ip, whichfork) ||
293192 nrecs == 0 ||
294193 XFS_BMDR_SPACE_CALC(nrecs) >
295194 XFS_DFORK_SIZE(dip, mp, whichfork) ||
296
- XFS_IFORK_NEXTENTS(ip, whichfork) > ip->i_d.di_nblocks) ||
195
+ ifp->if_nextents > ip->i_d.di_nblocks) ||
297196 level == 0 || level > XFS_BTREE_MAXLEVELS) {
298197 xfs_warn(mp, "corrupt inode %Lu (btree).",
299198 (unsigned long long) ip->i_ino);
....@@ -304,7 +203,7 @@
304203 }
305204
306205 ifp->if_broot_bytes = size;
307
- ifp->if_broot = kmem_alloc(size, KM_SLEEP | KM_NOFS);
206
+ ifp->if_broot = kmem_alloc(size, KM_NOFS);
308207 ASSERT(ifp->if_broot != NULL);
309208 /*
310209 * Copy and convert from the on-disk structure
....@@ -319,6 +218,110 @@
319218 ifp->if_u1.if_root = NULL;
320219 ifp->if_height = 0;
321220 return 0;
221
+}
222
+
223
+int
224
+xfs_iformat_data_fork(
225
+ struct xfs_inode *ip,
226
+ struct xfs_dinode *dip)
227
+{
228
+ struct inode *inode = VFS_I(ip);
229
+ int error;
230
+
231
+ /*
232
+ * Initialize the extent count early, as the per-format routines may
233
+ * depend on it.
234
+ */
235
+ ip->i_df.if_format = dip->di_format;
236
+ ip->i_df.if_nextents = be32_to_cpu(dip->di_nextents);
237
+
238
+ switch (inode->i_mode & S_IFMT) {
239
+ case S_IFIFO:
240
+ case S_IFCHR:
241
+ case S_IFBLK:
242
+ case S_IFSOCK:
243
+ ip->i_d.di_size = 0;
244
+ inode->i_rdev = xfs_to_linux_dev_t(xfs_dinode_get_rdev(dip));
245
+ return 0;
246
+ case S_IFREG:
247
+ case S_IFLNK:
248
+ case S_IFDIR:
249
+ switch (ip->i_df.if_format) {
250
+ case XFS_DINODE_FMT_LOCAL:
251
+ error = xfs_iformat_local(ip, dip, XFS_DATA_FORK,
252
+ be64_to_cpu(dip->di_size));
253
+ if (!error)
254
+ error = xfs_ifork_verify_local_data(ip);
255
+ return error;
256
+ case XFS_DINODE_FMT_EXTENTS:
257
+ return xfs_iformat_extents(ip, dip, XFS_DATA_FORK);
258
+ case XFS_DINODE_FMT_BTREE:
259
+ return xfs_iformat_btree(ip, dip, XFS_DATA_FORK);
260
+ default:
261
+ xfs_inode_verifier_error(ip, -EFSCORRUPTED, __func__,
262
+ dip, sizeof(*dip), __this_address);
263
+ return -EFSCORRUPTED;
264
+ }
265
+ break;
266
+ default:
267
+ xfs_inode_verifier_error(ip, -EFSCORRUPTED, __func__, dip,
268
+ sizeof(*dip), __this_address);
269
+ return -EFSCORRUPTED;
270
+ }
271
+}
272
+
273
+static uint16_t
274
+xfs_dfork_attr_shortform_size(
275
+ struct xfs_dinode *dip)
276
+{
277
+ struct xfs_attr_shortform *atp =
278
+ (struct xfs_attr_shortform *)XFS_DFORK_APTR(dip);
279
+
280
+ return be16_to_cpu(atp->hdr.totsize);
281
+}
282
+
283
+int
284
+xfs_iformat_attr_fork(
285
+ struct xfs_inode *ip,
286
+ struct xfs_dinode *dip)
287
+{
288
+ int error = 0;
289
+
290
+ /*
291
+ * Initialize the extent count early, as the per-format routines may
292
+ * depend on it.
293
+ */
294
+ ip->i_afp = kmem_cache_zalloc(xfs_ifork_zone, GFP_NOFS | __GFP_NOFAIL);
295
+ ip->i_afp->if_format = dip->di_aformat;
296
+ if (unlikely(ip->i_afp->if_format == 0)) /* pre IRIX 6.2 file system */
297
+ ip->i_afp->if_format = XFS_DINODE_FMT_EXTENTS;
298
+ ip->i_afp->if_nextents = be16_to_cpu(dip->di_anextents);
299
+
300
+ switch (ip->i_afp->if_format) {
301
+ case XFS_DINODE_FMT_LOCAL:
302
+ error = xfs_iformat_local(ip, dip, XFS_ATTR_FORK,
303
+ xfs_dfork_attr_shortform_size(dip));
304
+ if (!error)
305
+ error = xfs_ifork_verify_local_attr(ip);
306
+ break;
307
+ case XFS_DINODE_FMT_EXTENTS:
308
+ error = xfs_iformat_extents(ip, dip, XFS_ATTR_FORK);
309
+ break;
310
+ case XFS_DINODE_FMT_BTREE:
311
+ error = xfs_iformat_btree(ip, dip, XFS_ATTR_FORK);
312
+ break;
313
+ default:
314
+ xfs_inode_verifier_error(ip, error, __func__, dip,
315
+ sizeof(*dip), __this_address);
316
+ error = -EFSCORRUPTED;
317
+ break;
318
+ }
319
+
320
+ if (error) {
321
+ kmem_cache_free(xfs_ifork_zone, ip->i_afp);
322
+ ip->i_afp = NULL;
323
+ }
324
+ return error;
322325 }
323326
324327 /*
....@@ -369,7 +372,7 @@
369372 */
370373 if (ifp->if_broot_bytes == 0) {
371374 new_size = XFS_BMAP_BROOT_SPACE_CALC(mp, rec_diff);
372
- ifp->if_broot = kmem_alloc(new_size, KM_SLEEP | KM_NOFS);
375
+ ifp->if_broot = kmem_alloc(new_size, KM_NOFS);
373376 ifp->if_broot_bytes = (int)new_size;
374377 return;
375378 }
....@@ -383,8 +386,8 @@
383386 cur_max = xfs_bmbt_maxrecs(mp, ifp->if_broot_bytes, 0);
384387 new_max = cur_max + rec_diff;
385388 new_size = XFS_BMAP_BROOT_SPACE_CALC(mp, new_max);
386
- ifp->if_broot = kmem_realloc(ifp->if_broot, new_size,
387
- KM_SLEEP | KM_NOFS);
389
+ ifp->if_broot = krealloc(ifp->if_broot, new_size,
390
+ GFP_NOFS | __GFP_NOFAIL);
388391 op = (char *)XFS_BMAP_BROOT_PTR_ADDR(mp, ifp->if_broot, 1,
389392 ifp->if_broot_bytes);
390393 np = (char *)XFS_BMAP_BROOT_PTR_ADDR(mp, ifp->if_broot, 1,
....@@ -410,7 +413,7 @@
410413 else
411414 new_size = 0;
412415 if (new_size > 0) {
413
- new_broot = kmem_alloc(new_size, KM_SLEEP | KM_NOFS);
416
+ new_broot = kmem_alloc(new_size, KM_NOFS);
414417 /*
415418 * First copy over the btree block header.
416419 */
....@@ -469,11 +472,11 @@
469472 void
470473 xfs_idata_realloc(
471474 struct xfs_inode *ip,
472
- int byte_diff,
475
+ int64_t byte_diff,
473476 int whichfork)
474477 {
475478 struct xfs_ifork *ifp = XFS_IFORK_PTR(ip, whichfork);
476
- int new_size = (int)ifp->if_bytes + byte_diff;
479
+ int64_t new_size = ifp->if_bytes + byte_diff;
477480
478481 ASSERT(new_size >= 0);
479482 ASSERT(new_size <= XFS_IFORK_SIZE(ip, whichfork));
....@@ -493,45 +496,31 @@
493496 * in size so that it can be logged and stay on word boundaries.
494497 * We enforce that here.
495498 */
496
- ifp->if_u1.if_data = kmem_realloc(ifp->if_u1.if_data,
497
- roundup(new_size, 4), KM_SLEEP | KM_NOFS);
499
+ ifp->if_u1.if_data = krealloc(ifp->if_u1.if_data, roundup(new_size, 4),
500
+ GFP_NOFS | __GFP_NOFAIL);
498501 ifp->if_bytes = new_size;
499502 }
500503
501504 void
502505 xfs_idestroy_fork(
503
- xfs_inode_t *ip,
504
- int whichfork)
506
+ struct xfs_ifork *ifp)
505507 {
506
- struct xfs_ifork *ifp;
507
-
508
- ifp = XFS_IFORK_PTR(ip, whichfork);
509508 if (ifp->if_broot != NULL) {
510509 kmem_free(ifp->if_broot);
511510 ifp->if_broot = NULL;
512511 }
513512
514513 /*
515
- * If the format is local, then we can't have an extents
516
- * array so just look for an inline data array. If we're
517
- * not local then we may or may not have an extents list,
518
- * so check and free it up if we do.
514
+ * If the format is local, then we can't have an extents array so just
515
+ * look for an inline data array. If we're not local then we may or may
516
+ * not have an extents list, so check and free it up if we do.
519517 */
520
- if (XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_LOCAL) {
521
- if (ifp->if_u1.if_data != NULL) {
522
- kmem_free(ifp->if_u1.if_data);
523
- ifp->if_u1.if_data = NULL;
524
- }
525
- } else if ((ifp->if_flags & XFS_IFEXTENTS) && ifp->if_height) {
526
- xfs_iext_destroy(ifp);
527
- }
528
-
529
- if (whichfork == XFS_ATTR_FORK) {
530
- kmem_zone_free(xfs_ifork_zone, ip->i_afp);
531
- ip->i_afp = NULL;
532
- } else if (whichfork == XFS_COW_FORK) {
533
- kmem_zone_free(xfs_ifork_zone, ip->i_cowfp);
534
- ip->i_cowfp = NULL;
518
+ if (ifp->if_format == XFS_DINODE_FMT_LOCAL) {
519
+ kmem_free(ifp->if_u1.if_data);
520
+ ifp->if_u1.if_data = NULL;
521
+ } else if (ifp->if_flags & XFS_IFEXTENTS) {
522
+ if (ifp->if_height)
523
+ xfs_iext_destroy(ifp);
535524 }
536525 }
537526
....@@ -554,7 +543,7 @@
554543 struct xfs_ifork *ifp = XFS_IFORK_PTR(ip, whichfork);
555544 struct xfs_iext_cursor icur;
556545 struct xfs_bmbt_irec rec;
557
- int copied = 0;
546
+ int64_t copied = 0;
558547
559548 ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL | XFS_ILOCK_SHARED));
560549 ASSERT(ifp->if_bytes > 0);
....@@ -588,7 +577,7 @@
588577 xfs_iflush_fork(
589578 xfs_inode_t *ip,
590579 xfs_dinode_t *dip,
591
- xfs_inode_log_item_t *iip,
580
+ struct xfs_inode_log_item *iip,
592581 int whichfork)
593582 {
594583 char *cp;
....@@ -614,7 +603,7 @@
614603 }
615604 cp = XFS_DFORK_PTR(dip, whichfork);
616605 mp = ip->i_mount;
617
- switch (XFS_IFORK_FORMAT(ip, whichfork)) {
606
+ switch (ifp->if_format) {
618607 case XFS_DINODE_FMT_LOCAL:
619608 if ((iip->ili_fields & dataflag[whichfork]) &&
620609 (ifp->if_bytes > 0)) {
....@@ -629,7 +618,7 @@
629618 !(iip->ili_fields & extflag[whichfork]));
630619 if ((iip->ili_fields & extflag[whichfork]) &&
631620 (ifp->if_bytes > 0)) {
632
- ASSERT(XFS_IFORK_NEXTENTS(ip, whichfork) > 0);
621
+ ASSERT(ifp->if_nextents > 0);
633622 (void)xfs_iextents_copy(ip, (xfs_bmbt_rec_t *)cp,
634623 whichfork);
635624 }
....@@ -684,51 +673,58 @@
684673 if (ip->i_cowfp)
685674 return;
686675
687
- ip->i_cowfp = kmem_zone_zalloc(xfs_ifork_zone,
688
- KM_SLEEP | KM_NOFS);
676
+ ip->i_cowfp = kmem_cache_zalloc(xfs_ifork_zone,
677
+ GFP_NOFS | __GFP_NOFAIL);
689678 ip->i_cowfp->if_flags = XFS_IFEXTENTS;
690
- ip->i_cformat = XFS_DINODE_FMT_EXTENTS;
691
- ip->i_cnextents = 0;
679
+ ip->i_cowfp->if_format = XFS_DINODE_FMT_EXTENTS;
692680 }
693681
694
-/* Default fork content verifiers. */
695
-struct xfs_ifork_ops xfs_default_ifork_ops = {
696
- .verify_attr = xfs_attr_shortform_verify,
697
- .verify_dir = xfs_dir2_sf_verify,
698
- .verify_symlink = xfs_symlink_shortform_verify,
699
-};
700
-
701682 /* Verify the inline contents of the data fork of an inode. */
702
-xfs_failaddr_t
703
-xfs_ifork_verify_data(
704
- struct xfs_inode *ip,
705
- struct xfs_ifork_ops *ops)
683
+int
684
+xfs_ifork_verify_local_data(
685
+ struct xfs_inode *ip)
706686 {
707
- /* Non-local data fork, we're done. */
708
- if (ip->i_d.di_format != XFS_DINODE_FMT_LOCAL)
709
- return NULL;
687
+ xfs_failaddr_t fa = NULL;
710688
711
- /* Check the inline data fork if there is one. */
712689 switch (VFS_I(ip)->i_mode & S_IFMT) {
713690 case S_IFDIR:
714
- return ops->verify_dir(ip);
691
+ fa = xfs_dir2_sf_verify(ip);
692
+ break;
715693 case S_IFLNK:
716
- return ops->verify_symlink(ip);
694
+ fa = xfs_symlink_shortform_verify(ip);
695
+ break;
717696 default:
718
- return NULL;
697
+ break;
719698 }
699
+
700
+ if (fa) {
701
+ xfs_inode_verifier_error(ip, -EFSCORRUPTED, "data fork",
702
+ ip->i_df.if_u1.if_data, ip->i_df.if_bytes, fa);
703
+ return -EFSCORRUPTED;
704
+ }
705
+
706
+ return 0;
720707 }
721708
722709 /* Verify the inline contents of the attr fork of an inode. */
723
-xfs_failaddr_t
724
-xfs_ifork_verify_attr(
725
- struct xfs_inode *ip,
726
- struct xfs_ifork_ops *ops)
710
+int
711
+xfs_ifork_verify_local_attr(
712
+ struct xfs_inode *ip)
727713 {
728
- /* There has to be an attr fork allocated if aformat is local. */
729
- if (ip->i_d.di_aformat != XFS_DINODE_FMT_LOCAL)
730
- return NULL;
731
- if (!XFS_IFORK_PTR(ip, XFS_ATTR_FORK))
732
- return __this_address;
733
- return ops->verify_attr(ip);
714
+ struct xfs_ifork *ifp = ip->i_afp;
715
+ xfs_failaddr_t fa;
716
+
717
+ if (!ifp)
718
+ fa = __this_address;
719
+ else
720
+ fa = xfs_attr_shortform_verify(ip);
721
+
722
+ if (fa) {
723
+ xfs_inode_verifier_error(ip, -EFSCORRUPTED, "attr fork",
724
+ ifp ? ifp->if_u1.if_data : NULL,
725
+ ifp ? ifp->if_bytes : 0, fa);
726
+ return -EFSCORRUPTED;
727
+ }
728
+
729
+ return 0;
734730 }