diff options
-rw-r--r-- | Documentation/filesystems/xfs.txt | 6 | ||||
-rw-r--r-- | fs/xfs/linux-2.6/xfs_discard.c | 29 | ||||
-rw-r--r-- | fs/xfs/linux-2.6/xfs_discard.h | 2 | ||||
-rw-r--r-- | fs/xfs/linux-2.6/xfs_super.c | 18 | ||||
-rw-r--r-- | fs/xfs/xfs_ag.h | 3 | ||||
-rw-r--r-- | fs/xfs/xfs_alloc.c | 35 | ||||
-rw-r--r-- | fs/xfs/xfs_alloc.h | 5 | ||||
-rw-r--r-- | fs/xfs/xfs_alloc_btree.c | 3 | ||||
-rw-r--r-- | fs/xfs/xfs_bmap.c | 549 | ||||
-rw-r--r-- | fs/xfs/xfs_bmap.h | 2 | ||||
-rw-r--r-- | fs/xfs/xfs_inode.c | 15 | ||||
-rw-r--r-- | fs/xfs/xfs_inode.h | 1 | ||||
-rw-r--r-- | fs/xfs/xfs_log_cil.c | 13 | ||||
-rw-r--r-- | fs/xfs/xfs_mount.h | 1 | ||||
-rw-r--r-- | fs/xfs/xfs_trans.c | 2 |
15 files changed, 366 insertions, 318 deletions
diff --git a/Documentation/filesystems/xfs.txt b/Documentation/filesystems/xfs.txt index 7bff3e4f35df..3fc0c31a6f5d 100644 --- a/Documentation/filesystems/xfs.txt +++ b/Documentation/filesystems/xfs.txt | |||
@@ -39,6 +39,12 @@ When mounting an XFS filesystem, the following options are accepted. | |||
39 | drive level write caching to be enabled, for devices that | 39 | drive level write caching to be enabled, for devices that |
40 | support write barriers. | 40 | support write barriers. |
41 | 41 | ||
42 | discard | ||
43 | Issue command to let the block device reclaim space freed by the | ||
44 | filesystem. This is useful for SSD devices, thinly provisioned | ||
45 | LUNs and virtual machine images, but may have a performance | ||
46 | impact. This option is incompatible with the nodelaylog option. | ||
47 | |||
42 | dmapi | 48 | dmapi |
43 | Enable the DMAPI (Data Management API) event callouts. | 49 | Enable the DMAPI (Data Management API) event callouts. |
44 | Use with the "mtpt" option. | 50 | Use with the "mtpt" option. |
diff --git a/fs/xfs/linux-2.6/xfs_discard.c b/fs/xfs/linux-2.6/xfs_discard.c index d61611c88012..244e797dae32 100644 --- a/fs/xfs/linux-2.6/xfs_discard.c +++ b/fs/xfs/linux-2.6/xfs_discard.c | |||
@@ -191,3 +191,32 @@ xfs_ioc_trim( | |||
191 | return -XFS_ERROR(EFAULT); | 191 | return -XFS_ERROR(EFAULT); |
192 | return 0; | 192 | return 0; |
193 | } | 193 | } |
194 | |||
195 | int | ||
196 | xfs_discard_extents( | ||
197 | struct xfs_mount *mp, | ||
198 | struct list_head *list) | ||
199 | { | ||
200 | struct xfs_busy_extent *busyp; | ||
201 | int error = 0; | ||
202 | |||
203 | list_for_each_entry(busyp, list, list) { | ||
204 | trace_xfs_discard_extent(mp, busyp->agno, busyp->bno, | ||
205 | busyp->length); | ||
206 | |||
207 | error = -blkdev_issue_discard(mp->m_ddev_targp->bt_bdev, | ||
208 | XFS_AGB_TO_DADDR(mp, busyp->agno, busyp->bno), | ||
209 | XFS_FSB_TO_BB(mp, busyp->length), | ||
210 | GFP_NOFS, 0); | ||
211 | if (error && error != EOPNOTSUPP) { | ||
212 | xfs_info(mp, | ||
213 | "discard failed for extent [0x%llu,%u], error %d", | ||
214 | (unsigned long long)busyp->bno, | ||
215 | busyp->length, | ||
216 | error); | ||
217 | return error; | ||
218 | } | ||
219 | } | ||
220 | |||
221 | return 0; | ||
222 | } | ||
diff --git a/fs/xfs/linux-2.6/xfs_discard.h b/fs/xfs/linux-2.6/xfs_discard.h index e82b6dd3e127..344879aea646 100644 --- a/fs/xfs/linux-2.6/xfs_discard.h +++ b/fs/xfs/linux-2.6/xfs_discard.h | |||
@@ -2,7 +2,9 @@ | |||
2 | #define XFS_DISCARD_H 1 | 2 | #define XFS_DISCARD_H 1 |
3 | 3 | ||
4 | struct fstrim_range; | 4 | struct fstrim_range; |
5 | struct list_head; | ||
5 | 6 | ||
6 | extern int xfs_ioc_trim(struct xfs_mount *, struct fstrim_range __user *); | 7 | extern int xfs_ioc_trim(struct xfs_mount *, struct fstrim_range __user *); |
8 | extern int xfs_discard_extents(struct xfs_mount *, struct list_head *); | ||
7 | 9 | ||
8 | #endif /* XFS_DISCARD_H */ | 10 | #endif /* XFS_DISCARD_H */ |
diff --git a/fs/xfs/linux-2.6/xfs_super.c b/fs/xfs/linux-2.6/xfs_super.c index b0aa59e51fd0..98b9c91fcdf1 100644 --- a/fs/xfs/linux-2.6/xfs_super.c +++ b/fs/xfs/linux-2.6/xfs_super.c | |||
@@ -110,8 +110,10 @@ mempool_t *xfs_ioend_pool; | |||
110 | #define MNTOPT_GQUOTANOENF "gqnoenforce"/* group quota limit enforcement */ | 110 | #define MNTOPT_GQUOTANOENF "gqnoenforce"/* group quota limit enforcement */ |
111 | #define MNTOPT_PQUOTANOENF "pqnoenforce"/* project quota limit enforcement */ | 111 | #define MNTOPT_PQUOTANOENF "pqnoenforce"/* project quota limit enforcement */ |
112 | #define MNTOPT_QUOTANOENF "qnoenforce" /* same as uqnoenforce */ | 112 | #define MNTOPT_QUOTANOENF "qnoenforce" /* same as uqnoenforce */ |
113 | #define MNTOPT_DELAYLOG "delaylog" /* Delayed loging enabled */ | 113 | #define MNTOPT_DELAYLOG "delaylog" /* Delayed logging enabled */ |
114 | #define MNTOPT_NODELAYLOG "nodelaylog" /* Delayed loging disabled */ | 114 | #define MNTOPT_NODELAYLOG "nodelaylog" /* Delayed logging disabled */ |
115 | #define MNTOPT_DISCARD "discard" /* Discard unused blocks */ | ||
116 | #define MNTOPT_NODISCARD "nodiscard" /* Do not discard unused blocks */ | ||
115 | 117 | ||
116 | /* | 118 | /* |
117 | * Table driven mount option parser. | 119 | * Table driven mount option parser. |
@@ -355,6 +357,10 @@ xfs_parseargs( | |||
355 | mp->m_flags |= XFS_MOUNT_DELAYLOG; | 357 | mp->m_flags |= XFS_MOUNT_DELAYLOG; |
356 | } else if (!strcmp(this_char, MNTOPT_NODELAYLOG)) { | 358 | } else if (!strcmp(this_char, MNTOPT_NODELAYLOG)) { |
357 | mp->m_flags &= ~XFS_MOUNT_DELAYLOG; | 359 | mp->m_flags &= ~XFS_MOUNT_DELAYLOG; |
360 | } else if (!strcmp(this_char, MNTOPT_DISCARD)) { | ||
361 | mp->m_flags |= XFS_MOUNT_DISCARD; | ||
362 | } else if (!strcmp(this_char, MNTOPT_NODISCARD)) { | ||
363 | mp->m_flags &= ~XFS_MOUNT_DISCARD; | ||
358 | } else if (!strcmp(this_char, "ihashsize")) { | 364 | } else if (!strcmp(this_char, "ihashsize")) { |
359 | xfs_warn(mp, | 365 | xfs_warn(mp, |
360 | "ihashsize no longer used, option is deprecated."); | 366 | "ihashsize no longer used, option is deprecated."); |
@@ -388,6 +394,13 @@ xfs_parseargs( | |||
388 | return EINVAL; | 394 | return EINVAL; |
389 | } | 395 | } |
390 | 396 | ||
397 | if ((mp->m_flags & XFS_MOUNT_DISCARD) && | ||
398 | !(mp->m_flags & XFS_MOUNT_DELAYLOG)) { | ||
399 | xfs_warn(mp, | ||
400 | "the discard option is incompatible with the nodelaylog option"); | ||
401 | return EINVAL; | ||
402 | } | ||
403 | |||
391 | #ifndef CONFIG_XFS_QUOTA | 404 | #ifndef CONFIG_XFS_QUOTA |
392 | if (XFS_IS_QUOTA_RUNNING(mp)) { | 405 | if (XFS_IS_QUOTA_RUNNING(mp)) { |
393 | xfs_warn(mp, "quota support not available in this kernel."); | 406 | xfs_warn(mp, "quota support not available in this kernel."); |
@@ -488,6 +501,7 @@ xfs_showargs( | |||
488 | { XFS_MOUNT_FILESTREAMS, "," MNTOPT_FILESTREAM }, | 501 | { XFS_MOUNT_FILESTREAMS, "," MNTOPT_FILESTREAM }, |
489 | { XFS_MOUNT_GRPID, "," MNTOPT_GRPID }, | 502 | { XFS_MOUNT_GRPID, "," MNTOPT_GRPID }, |
490 | { XFS_MOUNT_DELAYLOG, "," MNTOPT_DELAYLOG }, | 503 | { XFS_MOUNT_DELAYLOG, "," MNTOPT_DELAYLOG }, |
504 | { XFS_MOUNT_DISCARD, "," MNTOPT_DISCARD }, | ||
491 | { 0, NULL } | 505 | { 0, NULL } |
492 | }; | 506 | }; |
493 | static struct proc_xfs_info xfs_info_unset[] = { | 507 | static struct proc_xfs_info xfs_info_unset[] = { |
diff --git a/fs/xfs/xfs_ag.h b/fs/xfs/xfs_ag.h index da0a561ffba2..6530769a999b 100644 --- a/fs/xfs/xfs_ag.h +++ b/fs/xfs/xfs_ag.h | |||
@@ -187,6 +187,9 @@ struct xfs_busy_extent { | |||
187 | xfs_agnumber_t agno; | 187 | xfs_agnumber_t agno; |
188 | xfs_agblock_t bno; | 188 | xfs_agblock_t bno; |
189 | xfs_extlen_t length; | 189 | xfs_extlen_t length; |
190 | unsigned int flags; | ||
191 | #define XFS_ALLOC_BUSY_DISCARDED 0x01 /* undergoing a discard op. */ | ||
192 | #define XFS_ALLOC_BUSY_SKIP_DISCARD 0x02 /* do not discard */ | ||
190 | }; | 193 | }; |
191 | 194 | ||
192 | /* | 195 | /* |
diff --git a/fs/xfs/xfs_alloc.c b/fs/xfs/xfs_alloc.c index acdced86413c..95862bbff56b 100644 --- a/fs/xfs/xfs_alloc.c +++ b/fs/xfs/xfs_alloc.c | |||
@@ -2469,7 +2469,7 @@ xfs_free_extent( | |||
2469 | 2469 | ||
2470 | error = xfs_free_ag_extent(tp, args.agbp, args.agno, args.agbno, len, 0); | 2470 | error = xfs_free_ag_extent(tp, args.agbp, args.agno, args.agbno, len, 0); |
2471 | if (!error) | 2471 | if (!error) |
2472 | xfs_alloc_busy_insert(tp, args.agno, args.agbno, len); | 2472 | xfs_alloc_busy_insert(tp, args.agno, args.agbno, len, 0); |
2473 | error0: | 2473 | error0: |
2474 | xfs_perag_put(args.pag); | 2474 | xfs_perag_put(args.pag); |
2475 | return error; | 2475 | return error; |
@@ -2480,7 +2480,8 @@ xfs_alloc_busy_insert( | |||
2480 | struct xfs_trans *tp, | 2480 | struct xfs_trans *tp, |
2481 | xfs_agnumber_t agno, | 2481 | xfs_agnumber_t agno, |
2482 | xfs_agblock_t bno, | 2482 | xfs_agblock_t bno, |
2483 | xfs_extlen_t len) | 2483 | xfs_extlen_t len, |
2484 | unsigned int flags) | ||
2484 | { | 2485 | { |
2485 | struct xfs_busy_extent *new; | 2486 | struct xfs_busy_extent *new; |
2486 | struct xfs_busy_extent *busyp; | 2487 | struct xfs_busy_extent *busyp; |
@@ -2504,6 +2505,7 @@ xfs_alloc_busy_insert( | |||
2504 | new->bno = bno; | 2505 | new->bno = bno; |
2505 | new->length = len; | 2506 | new->length = len; |
2506 | INIT_LIST_HEAD(&new->list); | 2507 | INIT_LIST_HEAD(&new->list); |
2508 | new->flags = flags; | ||
2507 | 2509 | ||
2508 | /* trace before insert to be able to see failed inserts */ | 2510 | /* trace before insert to be able to see failed inserts */ |
2509 | trace_xfs_alloc_busy(tp->t_mountp, agno, bno, len); | 2511 | trace_xfs_alloc_busy(tp->t_mountp, agno, bno, len); |
@@ -2609,6 +2611,18 @@ xfs_alloc_busy_update_extent( | |||
2609 | xfs_agblock_t bend = bbno + busyp->length; | 2611 | xfs_agblock_t bend = bbno + busyp->length; |
2610 | 2612 | ||
2611 | /* | 2613 | /* |
2614 | * This extent is currently being discarded. Give the thread | ||
2615 | * performing the discard a chance to mark the extent unbusy | ||
2616 | * and retry. | ||
2617 | */ | ||
2618 | if (busyp->flags & XFS_ALLOC_BUSY_DISCARDED) { | ||
2619 | spin_unlock(&pag->pagb_lock); | ||
2620 | delay(1); | ||
2621 | spin_lock(&pag->pagb_lock); | ||
2622 | return false; | ||
2623 | } | ||
2624 | |||
2625 | /* | ||
2612 | * If there is a busy extent overlapping a user allocation, we have | 2626 | * If there is a busy extent overlapping a user allocation, we have |
2613 | * no choice but to force the log and retry the search. | 2627 | * no choice but to force the log and retry the search. |
2614 | * | 2628 | * |
@@ -2813,7 +2827,8 @@ restart: | |||
2813 | * If this is a metadata allocation, try to reuse the busy | 2827 | * If this is a metadata allocation, try to reuse the busy |
2814 | * extent instead of trimming the allocation. | 2828 | * extent instead of trimming the allocation. |
2815 | */ | 2829 | */ |
2816 | if (!args->userdata) { | 2830 | if (!args->userdata && |
2831 | !(busyp->flags & XFS_ALLOC_BUSY_DISCARDED)) { | ||
2817 | if (!xfs_alloc_busy_update_extent(args->mp, args->pag, | 2832 | if (!xfs_alloc_busy_update_extent(args->mp, args->pag, |
2818 | busyp, fbno, flen, | 2833 | busyp, fbno, flen, |
2819 | false)) | 2834 | false)) |
@@ -2979,10 +2994,16 @@ xfs_alloc_busy_clear_one( | |||
2979 | kmem_free(busyp); | 2994 | kmem_free(busyp); |
2980 | } | 2995 | } |
2981 | 2996 | ||
2997 | /* | ||
2998 | * Remove all extents on the passed in list from the busy extents tree. | ||
2999 | * If do_discard is set skip extents that need to be discarded, and mark | ||
3000 | * these as undergoing a discard operation instead. | ||
3001 | */ | ||
2982 | void | 3002 | void |
2983 | xfs_alloc_busy_clear( | 3003 | xfs_alloc_busy_clear( |
2984 | struct xfs_mount *mp, | 3004 | struct xfs_mount *mp, |
2985 | struct list_head *list) | 3005 | struct list_head *list, |
3006 | bool do_discard) | ||
2986 | { | 3007 | { |
2987 | struct xfs_busy_extent *busyp, *n; | 3008 | struct xfs_busy_extent *busyp, *n; |
2988 | struct xfs_perag *pag = NULL; | 3009 | struct xfs_perag *pag = NULL; |
@@ -2999,7 +3020,11 @@ xfs_alloc_busy_clear( | |||
2999 | agno = busyp->agno; | 3020 | agno = busyp->agno; |
3000 | } | 3021 | } |
3001 | 3022 | ||
3002 | xfs_alloc_busy_clear_one(mp, pag, busyp); | 3023 | if (do_discard && busyp->length && |
3024 | !(busyp->flags & XFS_ALLOC_BUSY_SKIP_DISCARD)) | ||
3025 | busyp->flags = XFS_ALLOC_BUSY_DISCARDED; | ||
3026 | else | ||
3027 | xfs_alloc_busy_clear_one(mp, pag, busyp); | ||
3003 | } | 3028 | } |
3004 | 3029 | ||
3005 | if (pag) { | 3030 | if (pag) { |
diff --git a/fs/xfs/xfs_alloc.h b/fs/xfs/xfs_alloc.h index 240ad288f2f9..2f52b924be79 100644 --- a/fs/xfs/xfs_alloc.h +++ b/fs/xfs/xfs_alloc.h | |||
@@ -137,10 +137,11 @@ xfs_alloc_longest_free_extent(struct xfs_mount *mp, | |||
137 | #ifdef __KERNEL__ | 137 | #ifdef __KERNEL__ |
138 | void | 138 | void |
139 | xfs_alloc_busy_insert(struct xfs_trans *tp, xfs_agnumber_t agno, | 139 | xfs_alloc_busy_insert(struct xfs_trans *tp, xfs_agnumber_t agno, |
140 | xfs_agblock_t bno, xfs_extlen_t len); | 140 | xfs_agblock_t bno, xfs_extlen_t len, unsigned int flags); |
141 | 141 | ||
142 | void | 142 | void |
143 | xfs_alloc_busy_clear(struct xfs_mount *mp, struct list_head *list); | 143 | xfs_alloc_busy_clear(struct xfs_mount *mp, struct list_head *list, |
144 | bool do_discard); | ||
144 | 145 | ||
145 | int | 146 | int |
146 | xfs_alloc_busy_search(struct xfs_mount *mp, xfs_agnumber_t agno, | 147 | xfs_alloc_busy_search(struct xfs_mount *mp, xfs_agnumber_t agno, |
diff --git a/fs/xfs/xfs_alloc_btree.c b/fs/xfs/xfs_alloc_btree.c index 8b469d53599f..2b3518826a69 100644 --- a/fs/xfs/xfs_alloc_btree.c +++ b/fs/xfs/xfs_alloc_btree.c | |||
@@ -120,7 +120,8 @@ xfs_allocbt_free_block( | |||
120 | if (error) | 120 | if (error) |
121 | return error; | 121 | return error; |
122 | 122 | ||
123 | xfs_alloc_busy_insert(cur->bc_tp, be32_to_cpu(agf->agf_seqno), bno, 1); | 123 | xfs_alloc_busy_insert(cur->bc_tp, be32_to_cpu(agf->agf_seqno), bno, 1, |
124 | XFS_ALLOC_BUSY_SKIP_DISCARD); | ||
124 | xfs_trans_agbtree_delta(cur->bc_tp, -1); | 125 | xfs_trans_agbtree_delta(cur->bc_tp, -1); |
125 | return 0; | 126 | return 0; |
126 | } | 127 | } |
diff --git a/fs/xfs/xfs_bmap.c b/fs/xfs/xfs_bmap.c index fa00788de2f5..e546a33214c9 100644 --- a/fs/xfs/xfs_bmap.c +++ b/fs/xfs/xfs_bmap.c | |||
@@ -89,36 +89,19 @@ xfs_bmap_add_attrfork_local( | |||
89 | int *flags); /* inode logging flags */ | 89 | int *flags); /* inode logging flags */ |
90 | 90 | ||
91 | /* | 91 | /* |
92 | * Called by xfs_bmapi to update file extent records and the btree | ||
93 | * after allocating space (or doing a delayed allocation). | ||
94 | */ | ||
95 | STATIC int /* error */ | ||
96 | xfs_bmap_add_extent( | ||
97 | xfs_inode_t *ip, /* incore inode pointer */ | ||
98 | xfs_extnum_t idx, /* extent number to update/insert */ | ||
99 | xfs_btree_cur_t **curp, /* if *curp is null, not a btree */ | ||
100 | xfs_bmbt_irec_t *new, /* new data to add to file extents */ | ||
101 | xfs_fsblock_t *first, /* pointer to firstblock variable */ | ||
102 | xfs_bmap_free_t *flist, /* list of extents to be freed */ | ||
103 | int *logflagsp, /* inode logging flags */ | ||
104 | int whichfork, /* data or attr fork */ | ||
105 | int rsvd); /* OK to allocate reserved blocks */ | ||
106 | |||
107 | /* | ||
108 | * Called by xfs_bmap_add_extent to handle cases converting a delayed | 92 | * Called by xfs_bmap_add_extent to handle cases converting a delayed |
109 | * allocation to a real allocation. | 93 | * allocation to a real allocation. |
110 | */ | 94 | */ |
111 | STATIC int /* error */ | 95 | STATIC int /* error */ |
112 | xfs_bmap_add_extent_delay_real( | 96 | xfs_bmap_add_extent_delay_real( |
113 | xfs_inode_t *ip, /* incore inode pointer */ | 97 | xfs_inode_t *ip, /* incore inode pointer */ |
114 | xfs_extnum_t idx, /* extent number to update/insert */ | 98 | xfs_extnum_t *idx, /* extent number to update/insert */ |
115 | xfs_btree_cur_t **curp, /* if *curp is null, not a btree */ | 99 | xfs_btree_cur_t **curp, /* if *curp is null, not a btree */ |
116 | xfs_bmbt_irec_t *new, /* new data to add to file extents */ | 100 | xfs_bmbt_irec_t *new, /* new data to add to file extents */ |
117 | xfs_filblks_t *dnew, /* new delayed-alloc indirect blocks */ | 101 | xfs_filblks_t *dnew, /* new delayed-alloc indirect blocks */ |
118 | xfs_fsblock_t *first, /* pointer to firstblock variable */ | 102 | xfs_fsblock_t *first, /* pointer to firstblock variable */ |
119 | xfs_bmap_free_t *flist, /* list of extents to be freed */ | 103 | xfs_bmap_free_t *flist, /* list of extents to be freed */ |
120 | int *logflagsp, /* inode logging flags */ | 104 | int *logflagsp); /* inode logging flags */ |
121 | int rsvd); /* OK to allocate reserved blocks */ | ||
122 | 105 | ||
123 | /* | 106 | /* |
124 | * Called by xfs_bmap_add_extent to handle cases converting a hole | 107 | * Called by xfs_bmap_add_extent to handle cases converting a hole |
@@ -127,10 +110,9 @@ xfs_bmap_add_extent_delay_real( | |||
127 | STATIC int /* error */ | 110 | STATIC int /* error */ |
128 | xfs_bmap_add_extent_hole_delay( | 111 | xfs_bmap_add_extent_hole_delay( |
129 | xfs_inode_t *ip, /* incore inode pointer */ | 112 | xfs_inode_t *ip, /* incore inode pointer */ |
130 | xfs_extnum_t idx, /* extent number to update/insert */ | 113 | xfs_extnum_t *idx, /* extent number to update/insert */ |
131 | xfs_bmbt_irec_t *new, /* new data to add to file extents */ | 114 | xfs_bmbt_irec_t *new, /* new data to add to file extents */ |
132 | int *logflagsp,/* inode logging flags */ | 115 | int *logflagsp); /* inode logging flags */ |
133 | int rsvd); /* OK to allocate reserved blocks */ | ||
134 | 116 | ||
135 | /* | 117 | /* |
136 | * Called by xfs_bmap_add_extent to handle cases converting a hole | 118 | * Called by xfs_bmap_add_extent to handle cases converting a hole |
@@ -139,7 +121,7 @@ xfs_bmap_add_extent_hole_delay( | |||
139 | STATIC int /* error */ | 121 | STATIC int /* error */ |
140 | xfs_bmap_add_extent_hole_real( | 122 | xfs_bmap_add_extent_hole_real( |
141 | xfs_inode_t *ip, /* incore inode pointer */ | 123 | xfs_inode_t *ip, /* incore inode pointer */ |
142 | xfs_extnum_t idx, /* extent number to update/insert */ | 124 | xfs_extnum_t *idx, /* extent number to update/insert */ |
143 | xfs_btree_cur_t *cur, /* if null, not a btree */ | 125 | xfs_btree_cur_t *cur, /* if null, not a btree */ |
144 | xfs_bmbt_irec_t *new, /* new data to add to file extents */ | 126 | xfs_bmbt_irec_t *new, /* new data to add to file extents */ |
145 | int *logflagsp, /* inode logging flags */ | 127 | int *logflagsp, /* inode logging flags */ |
@@ -152,7 +134,7 @@ xfs_bmap_add_extent_hole_real( | |||
152 | STATIC int /* error */ | 134 | STATIC int /* error */ |
153 | xfs_bmap_add_extent_unwritten_real( | 135 | xfs_bmap_add_extent_unwritten_real( |
154 | xfs_inode_t *ip, /* incore inode pointer */ | 136 | xfs_inode_t *ip, /* incore inode pointer */ |
155 | xfs_extnum_t idx, /* extent number to update/insert */ | 137 | xfs_extnum_t *idx, /* extent number to update/insert */ |
156 | xfs_btree_cur_t **curp, /* if *curp is null, not a btree */ | 138 | xfs_btree_cur_t **curp, /* if *curp is null, not a btree */ |
157 | xfs_bmbt_irec_t *new, /* new data to add to file extents */ | 139 | xfs_bmbt_irec_t *new, /* new data to add to file extents */ |
158 | int *logflagsp); /* inode logging flags */ | 140 | int *logflagsp); /* inode logging flags */ |
@@ -180,22 +162,6 @@ xfs_bmap_btree_to_extents( | |||
180 | int whichfork); /* data or attr fork */ | 162 | int whichfork); /* data or attr fork */ |
181 | 163 | ||
182 | /* | 164 | /* |
183 | * Called by xfs_bmapi to update file extent records and the btree | ||
184 | * after removing space (or undoing a delayed allocation). | ||
185 | */ | ||
186 | STATIC int /* error */ | ||
187 | xfs_bmap_del_extent( | ||
188 | xfs_inode_t *ip, /* incore inode pointer */ | ||
189 | xfs_trans_t *tp, /* current trans pointer */ | ||
190 | xfs_extnum_t idx, /* extent number to update/insert */ | ||
191 | xfs_bmap_free_t *flist, /* list of extents to be freed */ | ||
192 | xfs_btree_cur_t *cur, /* if null, not a btree */ | ||
193 | xfs_bmbt_irec_t *new, /* new data to add to file extents */ | ||
194 | int *logflagsp,/* inode logging flags */ | ||
195 | int whichfork, /* data or attr fork */ | ||
196 | int rsvd); /* OK to allocate reserved blocks */ | ||
197 | |||
198 | /* | ||
199 | * Remove the entry "free" from the free item list. Prev points to the | 165 | * Remove the entry "free" from the free item list. Prev points to the |
200 | * previous entry, unless "free" is the head of the list. | 166 | * previous entry, unless "free" is the head of the list. |
201 | */ | 167 | */ |
@@ -474,14 +440,13 @@ xfs_bmap_add_attrfork_local( | |||
474 | STATIC int /* error */ | 440 | STATIC int /* error */ |
475 | xfs_bmap_add_extent( | 441 | xfs_bmap_add_extent( |
476 | xfs_inode_t *ip, /* incore inode pointer */ | 442 | xfs_inode_t *ip, /* incore inode pointer */ |
477 | xfs_extnum_t idx, /* extent number to update/insert */ | 443 | xfs_extnum_t *idx, /* extent number to update/insert */ |
478 | xfs_btree_cur_t **curp, /* if *curp is null, not a btree */ | 444 | xfs_btree_cur_t **curp, /* if *curp is null, not a btree */ |
479 | xfs_bmbt_irec_t *new, /* new data to add to file extents */ | 445 | xfs_bmbt_irec_t *new, /* new data to add to file extents */ |
480 | xfs_fsblock_t *first, /* pointer to firstblock variable */ | 446 | xfs_fsblock_t *first, /* pointer to firstblock variable */ |
481 | xfs_bmap_free_t *flist, /* list of extents to be freed */ | 447 | xfs_bmap_free_t *flist, /* list of extents to be freed */ |
482 | int *logflagsp, /* inode logging flags */ | 448 | int *logflagsp, /* inode logging flags */ |
483 | int whichfork, /* data or attr fork */ | 449 | int whichfork) /* data or attr fork */ |
484 | int rsvd) /* OK to use reserved data blocks */ | ||
485 | { | 450 | { |
486 | xfs_btree_cur_t *cur; /* btree cursor or null */ | 451 | xfs_btree_cur_t *cur; /* btree cursor or null */ |
487 | xfs_filblks_t da_new; /* new count del alloc blocks used */ | 452 | xfs_filblks_t da_new; /* new count del alloc blocks used */ |
@@ -492,23 +457,27 @@ xfs_bmap_add_extent( | |||
492 | xfs_extnum_t nextents; /* number of extents in file now */ | 457 | xfs_extnum_t nextents; /* number of extents in file now */ |
493 | 458 | ||
494 | XFS_STATS_INC(xs_add_exlist); | 459 | XFS_STATS_INC(xs_add_exlist); |
460 | |||
495 | cur = *curp; | 461 | cur = *curp; |
496 | ifp = XFS_IFORK_PTR(ip, whichfork); | 462 | ifp = XFS_IFORK_PTR(ip, whichfork); |
497 | nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t); | 463 | nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t); |
498 | ASSERT(idx <= nextents); | ||
499 | da_old = da_new = 0; | 464 | da_old = da_new = 0; |
500 | error = 0; | 465 | error = 0; |
466 | |||
467 | ASSERT(*idx >= 0); | ||
468 | ASSERT(*idx <= nextents); | ||
469 | |||
501 | /* | 470 | /* |
502 | * This is the first extent added to a new/empty file. | 471 | * This is the first extent added to a new/empty file. |
503 | * Special case this one, so other routines get to assume there are | 472 | * Special case this one, so other routines get to assume there are |
504 | * already extents in the list. | 473 | * already extents in the list. |
505 | */ | 474 | */ |
506 | if (nextents == 0) { | 475 | if (nextents == 0) { |
507 | xfs_iext_insert(ip, 0, 1, new, | 476 | xfs_iext_insert(ip, *idx, 1, new, |
508 | whichfork == XFS_ATTR_FORK ? BMAP_ATTRFORK : 0); | 477 | whichfork == XFS_ATTR_FORK ? BMAP_ATTRFORK : 0); |
509 | 478 | ||
510 | ASSERT(cur == NULL); | 479 | ASSERT(cur == NULL); |
511 | ifp->if_lastex = 0; | 480 | |
512 | if (!isnullstartblock(new->br_startblock)) { | 481 | if (!isnullstartblock(new->br_startblock)) { |
513 | XFS_IFORK_NEXT_SET(ip, whichfork, 1); | 482 | XFS_IFORK_NEXT_SET(ip, whichfork, 1); |
514 | logflags = XFS_ILOG_CORE | xfs_ilog_fext(whichfork); | 483 | logflags = XFS_ILOG_CORE | xfs_ilog_fext(whichfork); |
@@ -522,27 +491,25 @@ xfs_bmap_add_extent( | |||
522 | if (cur) | 491 | if (cur) |
523 | ASSERT((cur->bc_private.b.flags & | 492 | ASSERT((cur->bc_private.b.flags & |
524 | XFS_BTCUR_BPRV_WASDEL) == 0); | 493 | XFS_BTCUR_BPRV_WASDEL) == 0); |
525 | if ((error = xfs_bmap_add_extent_hole_delay(ip, idx, new, | 494 | error = xfs_bmap_add_extent_hole_delay(ip, idx, new, |
526 | &logflags, rsvd))) | 495 | &logflags); |
527 | goto done; | ||
528 | } | 496 | } |
529 | /* | 497 | /* |
530 | * Real allocation off the end of the file. | 498 | * Real allocation off the end of the file. |
531 | */ | 499 | */ |
532 | else if (idx == nextents) { | 500 | else if (*idx == nextents) { |
533 | if (cur) | 501 | if (cur) |
534 | ASSERT((cur->bc_private.b.flags & | 502 | ASSERT((cur->bc_private.b.flags & |
535 | XFS_BTCUR_BPRV_WASDEL) == 0); | 503 | XFS_BTCUR_BPRV_WASDEL) == 0); |
536 | if ((error = xfs_bmap_add_extent_hole_real(ip, idx, cur, new, | 504 | error = xfs_bmap_add_extent_hole_real(ip, idx, cur, new, |
537 | &logflags, whichfork))) | 505 | &logflags, whichfork); |
538 | goto done; | ||
539 | } else { | 506 | } else { |
540 | xfs_bmbt_irec_t prev; /* old extent at offset idx */ | 507 | xfs_bmbt_irec_t prev; /* old extent at offset idx */ |
541 | 508 | ||
542 | /* | 509 | /* |
543 | * Get the record referred to by idx. | 510 | * Get the record referred to by idx. |
544 | */ | 511 | */ |
545 | xfs_bmbt_get_all(xfs_iext_get_ext(ifp, idx), &prev); | 512 | xfs_bmbt_get_all(xfs_iext_get_ext(ifp, *idx), &prev); |
546 | /* | 513 | /* |
547 | * If it's a real allocation record, and the new allocation ends | 514 | * If it's a real allocation record, and the new allocation ends |
548 | * after the start of the referred to record, then we're filling | 515 | * after the start of the referred to record, then we're filling |
@@ -557,22 +524,18 @@ xfs_bmap_add_extent( | |||
557 | if (cur) | 524 | if (cur) |
558 | ASSERT(cur->bc_private.b.flags & | 525 | ASSERT(cur->bc_private.b.flags & |
559 | XFS_BTCUR_BPRV_WASDEL); | 526 | XFS_BTCUR_BPRV_WASDEL); |
560 | if ((error = xfs_bmap_add_extent_delay_real(ip, | 527 | error = xfs_bmap_add_extent_delay_real(ip, |
561 | idx, &cur, new, &da_new, first, flist, | 528 | idx, &cur, new, &da_new, |
562 | &logflags, rsvd))) | 529 | first, flist, &logflags); |
563 | goto done; | ||
564 | } else if (new->br_state == XFS_EXT_NORM) { | ||
565 | ASSERT(new->br_state == XFS_EXT_NORM); | ||
566 | if ((error = xfs_bmap_add_extent_unwritten_real( | ||
567 | ip, idx, &cur, new, &logflags))) | ||
568 | goto done; | ||
569 | } else { | 530 | } else { |
570 | ASSERT(new->br_state == XFS_EXT_UNWRITTEN); | 531 | ASSERT(new->br_state == XFS_EXT_NORM || |
571 | if ((error = xfs_bmap_add_extent_unwritten_real( | 532 | new->br_state == XFS_EXT_UNWRITTEN); |
572 | ip, idx, &cur, new, &logflags))) | 533 | |
534 | error = xfs_bmap_add_extent_unwritten_real(ip, | ||
535 | idx, &cur, new, &logflags); | ||
536 | if (error) | ||
573 | goto done; | 537 | goto done; |
574 | } | 538 | } |
575 | ASSERT(*curp == cur || *curp == NULL); | ||
576 | } | 539 | } |
577 | /* | 540 | /* |
578 | * Otherwise we're filling in a hole with an allocation. | 541 | * Otherwise we're filling in a hole with an allocation. |
@@ -581,13 +544,15 @@ xfs_bmap_add_extent( | |||
581 | if (cur) | 544 | if (cur) |
582 | ASSERT((cur->bc_private.b.flags & | 545 | ASSERT((cur->bc_private.b.flags & |
583 | XFS_BTCUR_BPRV_WASDEL) == 0); | 546 | XFS_BTCUR_BPRV_WASDEL) == 0); |
584 | if ((error = xfs_bmap_add_extent_hole_real(ip, idx, cur, | 547 | error = xfs_bmap_add_extent_hole_real(ip, idx, cur, |
585 | new, &logflags, whichfork))) | 548 | new, &logflags, whichfork); |
586 | goto done; | ||
587 | } | 549 | } |
588 | } | 550 | } |
589 | 551 | ||
552 | if (error) | ||
553 | goto done; | ||
590 | ASSERT(*curp == cur || *curp == NULL); | 554 | ASSERT(*curp == cur || *curp == NULL); |
555 | |||
591 | /* | 556 | /* |
592 | * Convert to a btree if necessary. | 557 | * Convert to a btree if necessary. |
593 | */ | 558 | */ |
@@ -615,7 +580,7 @@ xfs_bmap_add_extent( | |||
615 | ASSERT(nblks <= da_old); | 580 | ASSERT(nblks <= da_old); |
616 | if (nblks < da_old) | 581 | if (nblks < da_old) |
617 | xfs_icsb_modify_counters(ip->i_mount, XFS_SBS_FDBLOCKS, | 582 | xfs_icsb_modify_counters(ip->i_mount, XFS_SBS_FDBLOCKS, |
618 | (int64_t)(da_old - nblks), rsvd); | 583 | (int64_t)(da_old - nblks), 0); |
619 | } | 584 | } |
620 | /* | 585 | /* |
621 | * Clear out the allocated field, done with it now in any case. | 586 | * Clear out the allocated field, done with it now in any case. |
@@ -640,14 +605,13 @@ done: | |||
640 | STATIC int /* error */ | 605 | STATIC int /* error */ |
641 | xfs_bmap_add_extent_delay_real( | 606 | xfs_bmap_add_extent_delay_real( |
642 | xfs_inode_t *ip, /* incore inode pointer */ | 607 | xfs_inode_t *ip, /* incore inode pointer */ |
643 | xfs_extnum_t idx, /* extent number to update/insert */ | 608 | xfs_extnum_t *idx, /* extent number to update/insert */ |
644 | xfs_btree_cur_t **curp, /* if *curp is null, not a btree */ | 609 | xfs_btree_cur_t **curp, /* if *curp is null, not a btree */ |
645 | xfs_bmbt_irec_t *new, /* new data to add to file extents */ | 610 | xfs_bmbt_irec_t *new, /* new data to add to file extents */ |
646 | xfs_filblks_t *dnew, /* new delayed-alloc indirect blocks */ | 611 | xfs_filblks_t *dnew, /* new delayed-alloc indirect blocks */ |
647 | xfs_fsblock_t *first, /* pointer to firstblock variable */ | 612 | xfs_fsblock_t *first, /* pointer to firstblock variable */ |
648 | xfs_bmap_free_t *flist, /* list of extents to be freed */ | 613 | xfs_bmap_free_t *flist, /* list of extents to be freed */ |
649 | int *logflagsp, /* inode logging flags */ | 614 | int *logflagsp) /* inode logging flags */ |
650 | int rsvd) /* OK to use reserved data block allocation */ | ||
651 | { | 615 | { |
652 | xfs_btree_cur_t *cur; /* btree cursor */ | 616 | xfs_btree_cur_t *cur; /* btree cursor */ |
653 | int diff; /* temp value */ | 617 | int diff; /* temp value */ |
@@ -673,7 +637,7 @@ xfs_bmap_add_extent_delay_real( | |||
673 | */ | 637 | */ |
674 | cur = *curp; | 638 | cur = *curp; |
675 | ifp = XFS_IFORK_PTR(ip, XFS_DATA_FORK); | 639 | ifp = XFS_IFORK_PTR(ip, XFS_DATA_FORK); |
676 | ep = xfs_iext_get_ext(ifp, idx); | 640 | ep = xfs_iext_get_ext(ifp, *idx); |
677 | xfs_bmbt_get_all(ep, &PREV); | 641 | xfs_bmbt_get_all(ep, &PREV); |
678 | new_endoff = new->br_startoff + new->br_blockcount; | 642 | new_endoff = new->br_startoff + new->br_blockcount; |
679 | ASSERT(PREV.br_startoff <= new->br_startoff); | 643 | ASSERT(PREV.br_startoff <= new->br_startoff); |
@@ -692,9 +656,9 @@ xfs_bmap_add_extent_delay_real( | |||
692 | * Check and set flags if this segment has a left neighbor. | 656 | * Check and set flags if this segment has a left neighbor. |
693 | * Don't set contiguous if the combined extent would be too large. | 657 | * Don't set contiguous if the combined extent would be too large. |
694 | */ | 658 | */ |
695 | if (idx > 0) { | 659 | if (*idx > 0) { |
696 | state |= BMAP_LEFT_VALID; | 660 | state |= BMAP_LEFT_VALID; |
697 | xfs_bmbt_get_all(xfs_iext_get_ext(ifp, idx - 1), &LEFT); | 661 | xfs_bmbt_get_all(xfs_iext_get_ext(ifp, *idx - 1), &LEFT); |
698 | 662 | ||
699 | if (isnullstartblock(LEFT.br_startblock)) | 663 | if (isnullstartblock(LEFT.br_startblock)) |
700 | state |= BMAP_LEFT_DELAY; | 664 | state |= BMAP_LEFT_DELAY; |
@@ -712,9 +676,9 @@ xfs_bmap_add_extent_delay_real( | |||
712 | * Don't set contiguous if the combined extent would be too large. | 676 | * Don't set contiguous if the combined extent would be too large. |
713 | * Also check for all-three-contiguous being too large. | 677 | * Also check for all-three-contiguous being too large. |
714 | */ | 678 | */ |
715 | if (idx < ip->i_df.if_bytes / (uint)sizeof(xfs_bmbt_rec_t) - 1) { | 679 | if (*idx < ip->i_df.if_bytes / (uint)sizeof(xfs_bmbt_rec_t) - 1) { |
716 | state |= BMAP_RIGHT_VALID; | 680 | state |= BMAP_RIGHT_VALID; |
717 | xfs_bmbt_get_all(xfs_iext_get_ext(ifp, idx + 1), &RIGHT); | 681 | xfs_bmbt_get_all(xfs_iext_get_ext(ifp, *idx + 1), &RIGHT); |
718 | 682 | ||
719 | if (isnullstartblock(RIGHT.br_startblock)) | 683 | if (isnullstartblock(RIGHT.br_startblock)) |
720 | state |= BMAP_RIGHT_DELAY; | 684 | state |= BMAP_RIGHT_DELAY; |
@@ -745,14 +709,14 @@ xfs_bmap_add_extent_delay_real( | |||
745 | * Filling in all of a previously delayed allocation extent. | 709 | * Filling in all of a previously delayed allocation extent. |
746 | * The left and right neighbors are both contiguous with new. | 710 | * The left and right neighbors are both contiguous with new. |
747 | */ | 711 | */ |
748 | trace_xfs_bmap_pre_update(ip, idx - 1, state, _THIS_IP_); | 712 | --*idx; |
749 | xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, idx - 1), | 713 | trace_xfs_bmap_pre_update(ip, *idx, state, _THIS_IP_); |
714 | xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, *idx), | ||
750 | LEFT.br_blockcount + PREV.br_blockcount + | 715 | LEFT.br_blockcount + PREV.br_blockcount + |
751 | RIGHT.br_blockcount); | 716 | RIGHT.br_blockcount); |
752 | trace_xfs_bmap_post_update(ip, idx - 1, state, _THIS_IP_); | 717 | trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_); |
753 | 718 | ||
754 | xfs_iext_remove(ip, idx, 2, state); | 719 | xfs_iext_remove(ip, *idx + 1, 2, state); |
755 | ip->i_df.if_lastex = idx - 1; | ||
756 | ip->i_d.di_nextents--; | 720 | ip->i_d.di_nextents--; |
757 | if (cur == NULL) | 721 | if (cur == NULL) |
758 | rval = XFS_ILOG_CORE | XFS_ILOG_DEXT; | 722 | rval = XFS_ILOG_CORE | XFS_ILOG_DEXT; |
@@ -784,13 +748,14 @@ xfs_bmap_add_extent_delay_real( | |||
784 | * Filling in all of a previously delayed allocation extent. | 748 | * Filling in all of a previously delayed allocation extent. |
785 | * The left neighbor is contiguous, the right is not. | 749 | * The left neighbor is contiguous, the right is not. |
786 | */ | 750 | */ |
787 | trace_xfs_bmap_pre_update(ip, idx - 1, state, _THIS_IP_); | 751 | --*idx; |
788 | xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, idx - 1), | 752 | |
753 | trace_xfs_bmap_pre_update(ip, *idx, state, _THIS_IP_); | ||
754 | xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, *idx), | ||
789 | LEFT.br_blockcount + PREV.br_blockcount); | 755 | LEFT.br_blockcount + PREV.br_blockcount); |
790 | trace_xfs_bmap_post_update(ip, idx - 1, state, _THIS_IP_); | 756 | trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_); |
791 | 757 | ||
792 | ip->i_df.if_lastex = idx - 1; | 758 | xfs_iext_remove(ip, *idx + 1, 1, state); |
793 | xfs_iext_remove(ip, idx, 1, state); | ||
794 | if (cur == NULL) | 759 | if (cur == NULL) |
795 | rval = XFS_ILOG_DEXT; | 760 | rval = XFS_ILOG_DEXT; |
796 | else { | 761 | else { |
@@ -814,14 +779,13 @@ xfs_bmap_add_extent_delay_real( | |||
814 | * Filling in all of a previously delayed allocation extent. | 779 | * Filling in all of a previously delayed allocation extent. |
815 | * The right neighbor is contiguous, the left is not. | 780 | * The right neighbor is contiguous, the left is not. |
816 | */ | 781 | */ |
817 | trace_xfs_bmap_pre_update(ip, idx, state, _THIS_IP_); | 782 | trace_xfs_bmap_pre_update(ip, *idx, state, _THIS_IP_); |
818 | xfs_bmbt_set_startblock(ep, new->br_startblock); | 783 | xfs_bmbt_set_startblock(ep, new->br_startblock); |
819 | xfs_bmbt_set_blockcount(ep, | 784 | xfs_bmbt_set_blockcount(ep, |
820 | PREV.br_blockcount + RIGHT.br_blockcount); | 785 | PREV.br_blockcount + RIGHT.br_blockcount); |
821 | trace_xfs_bmap_post_update(ip, idx, state, _THIS_IP_); | 786 | trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_); |
822 | 787 | ||
823 | ip->i_df.if_lastex = idx; | 788 | xfs_iext_remove(ip, *idx + 1, 1, state); |
824 | xfs_iext_remove(ip, idx + 1, 1, state); | ||
825 | if (cur == NULL) | 789 | if (cur == NULL) |
826 | rval = XFS_ILOG_DEXT; | 790 | rval = XFS_ILOG_DEXT; |
827 | else { | 791 | else { |
@@ -837,6 +801,7 @@ xfs_bmap_add_extent_delay_real( | |||
837 | RIGHT.br_blockcount, PREV.br_state))) | 801 | RIGHT.br_blockcount, PREV.br_state))) |
838 | goto done; | 802 | goto done; |
839 | } | 803 | } |
804 | |||
840 | *dnew = 0; | 805 | *dnew = 0; |
841 | break; | 806 | break; |
842 | 807 | ||
@@ -846,11 +811,10 @@ xfs_bmap_add_extent_delay_real( | |||
846 | * Neither the left nor right neighbors are contiguous with | 811 | * Neither the left nor right neighbors are contiguous with |
847 | * the new one. | 812 | * the new one. |
848 | */ | 813 | */ |
849 | trace_xfs_bmap_pre_update(ip, idx, state, _THIS_IP_); | 814 | trace_xfs_bmap_pre_update(ip, *idx, state, _THIS_IP_); |
850 | xfs_bmbt_set_startblock(ep, new->br_startblock); | 815 | xfs_bmbt_set_startblock(ep, new->br_startblock); |
851 | trace_xfs_bmap_post_update(ip, idx, state, _THIS_IP_); | 816 | trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_); |
852 | 817 | ||
853 | ip->i_df.if_lastex = idx; | ||
854 | ip->i_d.di_nextents++; | 818 | ip->i_d.di_nextents++; |
855 | if (cur == NULL) | 819 | if (cur == NULL) |
856 | rval = XFS_ILOG_CORE | XFS_ILOG_DEXT; | 820 | rval = XFS_ILOG_CORE | XFS_ILOG_DEXT; |
@@ -866,6 +830,7 @@ xfs_bmap_add_extent_delay_real( | |||
866 | goto done; | 830 | goto done; |
867 | XFS_WANT_CORRUPTED_GOTO(i == 1, done); | 831 | XFS_WANT_CORRUPTED_GOTO(i == 1, done); |
868 | } | 832 | } |
833 | |||
869 | *dnew = 0; | 834 | *dnew = 0; |
870 | break; | 835 | break; |
871 | 836 | ||
@@ -874,17 +839,16 @@ xfs_bmap_add_extent_delay_real( | |||
874 | * Filling in the first part of a previous delayed allocation. | 839 | * Filling in the first part of a previous delayed allocation. |
875 | * The left neighbor is contiguous. | 840 | * The left neighbor is contiguous. |
876 | */ | 841 | */ |
877 | trace_xfs_bmap_pre_update(ip, idx - 1, state, _THIS_IP_); | 842 | trace_xfs_bmap_pre_update(ip, *idx - 1, state, _THIS_IP_); |
878 | xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, idx - 1), | 843 | xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, *idx - 1), |
879 | LEFT.br_blockcount + new->br_blockcount); | 844 | LEFT.br_blockcount + new->br_blockcount); |
880 | xfs_bmbt_set_startoff(ep, | 845 | xfs_bmbt_set_startoff(ep, |
881 | PREV.br_startoff + new->br_blockcount); | 846 | PREV.br_startoff + new->br_blockcount); |
882 | trace_xfs_bmap_post_update(ip, idx - 1, state, _THIS_IP_); | 847 | trace_xfs_bmap_post_update(ip, *idx - 1, state, _THIS_IP_); |
883 | 848 | ||
884 | temp = PREV.br_blockcount - new->br_blockcount; | 849 | temp = PREV.br_blockcount - new->br_blockcount; |
885 | trace_xfs_bmap_pre_update(ip, idx, state, _THIS_IP_); | 850 | trace_xfs_bmap_pre_update(ip, *idx, state, _THIS_IP_); |
886 | xfs_bmbt_set_blockcount(ep, temp); | 851 | xfs_bmbt_set_blockcount(ep, temp); |
887 | ip->i_df.if_lastex = idx - 1; | ||
888 | if (cur == NULL) | 852 | if (cur == NULL) |
889 | rval = XFS_ILOG_DEXT; | 853 | rval = XFS_ILOG_DEXT; |
890 | else { | 854 | else { |
@@ -904,7 +868,9 @@ xfs_bmap_add_extent_delay_real( | |||
904 | temp = XFS_FILBLKS_MIN(xfs_bmap_worst_indlen(ip, temp), | 868 | temp = XFS_FILBLKS_MIN(xfs_bmap_worst_indlen(ip, temp), |
905 | startblockval(PREV.br_startblock)); | 869 | startblockval(PREV.br_startblock)); |
906 | xfs_bmbt_set_startblock(ep, nullstartblock((int)temp)); | 870 | xfs_bmbt_set_startblock(ep, nullstartblock((int)temp)); |
907 | trace_xfs_bmap_post_update(ip, idx, state, _THIS_IP_); | 871 | trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_); |
872 | |||
873 | --*idx; | ||
908 | *dnew = temp; | 874 | *dnew = temp; |
909 | break; | 875 | break; |
910 | 876 | ||
@@ -913,12 +879,11 @@ xfs_bmap_add_extent_delay_real( | |||
913 | * Filling in the first part of a previous delayed allocation. | 879 | * Filling in the first part of a previous delayed allocation. |
914 | * The left neighbor is not contiguous. | 880 | * The left neighbor is not contiguous. |
915 | */ | 881 | */ |
916 | trace_xfs_bmap_pre_update(ip, idx, state, _THIS_IP_); | 882 | trace_xfs_bmap_pre_update(ip, *idx, state, _THIS_IP_); |
917 | xfs_bmbt_set_startoff(ep, new_endoff); | 883 | xfs_bmbt_set_startoff(ep, new_endoff); |
918 | temp = PREV.br_blockcount - new->br_blockcount; | 884 | temp = PREV.br_blockcount - new->br_blockcount; |
919 | xfs_bmbt_set_blockcount(ep, temp); | 885 | xfs_bmbt_set_blockcount(ep, temp); |
920 | xfs_iext_insert(ip, idx, 1, new, state); | 886 | xfs_iext_insert(ip, *idx, 1, new, state); |
921 | ip->i_df.if_lastex = idx; | ||
922 | ip->i_d.di_nextents++; | 887 | ip->i_d.di_nextents++; |
923 | if (cur == NULL) | 888 | if (cur == NULL) |
924 | rval = XFS_ILOG_CORE | XFS_ILOG_DEXT; | 889 | rval = XFS_ILOG_CORE | XFS_ILOG_DEXT; |
@@ -946,9 +911,10 @@ xfs_bmap_add_extent_delay_real( | |||
946 | temp = XFS_FILBLKS_MIN(xfs_bmap_worst_indlen(ip, temp), | 911 | temp = XFS_FILBLKS_MIN(xfs_bmap_worst_indlen(ip, temp), |
947 | startblockval(PREV.br_startblock) - | 912 | startblockval(PREV.br_startblock) - |
948 | (cur ? cur->bc_private.b.allocated : 0)); | 913 | (cur ? cur->bc_private.b.allocated : 0)); |
949 | ep = xfs_iext_get_ext(ifp, idx + 1); | 914 | ep = xfs_iext_get_ext(ifp, *idx + 1); |
950 | xfs_bmbt_set_startblock(ep, nullstartblock((int)temp)); | 915 | xfs_bmbt_set_startblock(ep, nullstartblock((int)temp)); |
951 | trace_xfs_bmap_post_update(ip, idx + 1, state, _THIS_IP_); | 916 | trace_xfs_bmap_post_update(ip, *idx + 1, state, _THIS_IP_); |
917 | |||
952 | *dnew = temp; | 918 | *dnew = temp; |
953 | break; | 919 | break; |
954 | 920 | ||
@@ -958,15 +924,13 @@ xfs_bmap_add_extent_delay_real( | |||
958 | * The right neighbor is contiguous with the new allocation. | 924 | * The right neighbor is contiguous with the new allocation. |
959 | */ | 925 | */ |
960 | temp = PREV.br_blockcount - new->br_blockcount; | 926 | temp = PREV.br_blockcount - new->br_blockcount; |
961 | trace_xfs_bmap_pre_update(ip, idx, state, _THIS_IP_); | 927 | trace_xfs_bmap_pre_update(ip, *idx + 1, state, _THIS_IP_); |
962 | trace_xfs_bmap_pre_update(ip, idx + 1, state, _THIS_IP_); | ||
963 | xfs_bmbt_set_blockcount(ep, temp); | 928 | xfs_bmbt_set_blockcount(ep, temp); |
964 | xfs_bmbt_set_allf(xfs_iext_get_ext(ifp, idx + 1), | 929 | xfs_bmbt_set_allf(xfs_iext_get_ext(ifp, *idx + 1), |
965 | new->br_startoff, new->br_startblock, | 930 | new->br_startoff, new->br_startblock, |
966 | new->br_blockcount + RIGHT.br_blockcount, | 931 | new->br_blockcount + RIGHT.br_blockcount, |
967 | RIGHT.br_state); | 932 | RIGHT.br_state); |
968 | trace_xfs_bmap_post_update(ip, idx + 1, state, _THIS_IP_); | 933 | trace_xfs_bmap_post_update(ip, *idx + 1, state, _THIS_IP_); |
969 | ip->i_df.if_lastex = idx + 1; | ||
970 | if (cur == NULL) | 934 | if (cur == NULL) |
971 | rval = XFS_ILOG_DEXT; | 935 | rval = XFS_ILOG_DEXT; |
972 | else { | 936 | else { |
@@ -983,10 +947,14 @@ xfs_bmap_add_extent_delay_real( | |||
983 | RIGHT.br_state))) | 947 | RIGHT.br_state))) |
984 | goto done; | 948 | goto done; |
985 | } | 949 | } |
950 | |||
986 | temp = XFS_FILBLKS_MIN(xfs_bmap_worst_indlen(ip, temp), | 951 | temp = XFS_FILBLKS_MIN(xfs_bmap_worst_indlen(ip, temp), |
987 | startblockval(PREV.br_startblock)); | 952 | startblockval(PREV.br_startblock)); |
953 | trace_xfs_bmap_pre_update(ip, *idx, state, _THIS_IP_); | ||
988 | xfs_bmbt_set_startblock(ep, nullstartblock((int)temp)); | 954 | xfs_bmbt_set_startblock(ep, nullstartblock((int)temp)); |
989 | trace_xfs_bmap_post_update(ip, idx, state, _THIS_IP_); | 955 | trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_); |
956 | |||
957 | ++*idx; | ||
990 | *dnew = temp; | 958 | *dnew = temp; |
991 | break; | 959 | break; |
992 | 960 | ||
@@ -996,10 +964,9 @@ xfs_bmap_add_extent_delay_real( | |||
996 | * The right neighbor is not contiguous. | 964 | * The right neighbor is not contiguous. |
997 | */ | 965 | */ |
998 | temp = PREV.br_blockcount - new->br_blockcount; | 966 | temp = PREV.br_blockcount - new->br_blockcount; |
999 | trace_xfs_bmap_pre_update(ip, idx, state, _THIS_IP_); | 967 | trace_xfs_bmap_pre_update(ip, *idx, state, _THIS_IP_); |
1000 | xfs_bmbt_set_blockcount(ep, temp); | 968 | xfs_bmbt_set_blockcount(ep, temp); |
1001 | xfs_iext_insert(ip, idx + 1, 1, new, state); | 969 | xfs_iext_insert(ip, *idx + 1, 1, new, state); |
1002 | ip->i_df.if_lastex = idx + 1; | ||
1003 | ip->i_d.di_nextents++; | 970 | ip->i_d.di_nextents++; |
1004 | if (cur == NULL) | 971 | if (cur == NULL) |
1005 | rval = XFS_ILOG_CORE | XFS_ILOG_DEXT; | 972 | rval = XFS_ILOG_CORE | XFS_ILOG_DEXT; |
@@ -1027,9 +994,11 @@ xfs_bmap_add_extent_delay_real( | |||
1027 | temp = XFS_FILBLKS_MIN(xfs_bmap_worst_indlen(ip, temp), | 994 | temp = XFS_FILBLKS_MIN(xfs_bmap_worst_indlen(ip, temp), |
1028 | startblockval(PREV.br_startblock) - | 995 | startblockval(PREV.br_startblock) - |
1029 | (cur ? cur->bc_private.b.allocated : 0)); | 996 | (cur ? cur->bc_private.b.allocated : 0)); |
1030 | ep = xfs_iext_get_ext(ifp, idx); | 997 | ep = xfs_iext_get_ext(ifp, *idx); |
1031 | xfs_bmbt_set_startblock(ep, nullstartblock((int)temp)); | 998 | xfs_bmbt_set_startblock(ep, nullstartblock((int)temp)); |
1032 | trace_xfs_bmap_post_update(ip, idx, state, _THIS_IP_); | 999 | trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_); |
1000 | |||
1001 | ++*idx; | ||
1033 | *dnew = temp; | 1002 | *dnew = temp; |
1034 | break; | 1003 | break; |
1035 | 1004 | ||
@@ -1056,7 +1025,7 @@ xfs_bmap_add_extent_delay_real( | |||
1056 | */ | 1025 | */ |
1057 | temp = new->br_startoff - PREV.br_startoff; | 1026 | temp = new->br_startoff - PREV.br_startoff; |
1058 | temp2 = PREV.br_startoff + PREV.br_blockcount - new_endoff; | 1027 | temp2 = PREV.br_startoff + PREV.br_blockcount - new_endoff; |
1059 | trace_xfs_bmap_pre_update(ip, idx, 0, _THIS_IP_); | 1028 | trace_xfs_bmap_pre_update(ip, *idx, 0, _THIS_IP_); |
1060 | xfs_bmbt_set_blockcount(ep, temp); /* truncate PREV */ | 1029 | xfs_bmbt_set_blockcount(ep, temp); /* truncate PREV */ |
1061 | LEFT = *new; | 1030 | LEFT = *new; |
1062 | RIGHT.br_state = PREV.br_state; | 1031 | RIGHT.br_state = PREV.br_state; |
@@ -1065,8 +1034,7 @@ xfs_bmap_add_extent_delay_real( | |||
1065 | RIGHT.br_startoff = new_endoff; | 1034 | RIGHT.br_startoff = new_endoff; |
1066 | RIGHT.br_blockcount = temp2; | 1035 | RIGHT.br_blockcount = temp2; |
1067 | /* insert LEFT (r[0]) and RIGHT (r[1]) at the same time */ | 1036 | /* insert LEFT (r[0]) and RIGHT (r[1]) at the same time */ |
1068 | xfs_iext_insert(ip, idx + 1, 2, &LEFT, state); | 1037 | xfs_iext_insert(ip, *idx + 1, 2, &LEFT, state); |
1069 | ip->i_df.if_lastex = idx + 1; | ||
1070 | ip->i_d.di_nextents++; | 1038 | ip->i_d.di_nextents++; |
1071 | if (cur == NULL) | 1039 | if (cur == NULL) |
1072 | rval = XFS_ILOG_CORE | XFS_ILOG_DEXT; | 1040 | rval = XFS_ILOG_CORE | XFS_ILOG_DEXT; |
@@ -1097,7 +1065,7 @@ xfs_bmap_add_extent_delay_real( | |||
1097 | (cur ? cur->bc_private.b.allocated : 0)); | 1065 | (cur ? cur->bc_private.b.allocated : 0)); |
1098 | if (diff > 0 && | 1066 | if (diff > 0 && |
1099 | xfs_icsb_modify_counters(ip->i_mount, XFS_SBS_FDBLOCKS, | 1067 | xfs_icsb_modify_counters(ip->i_mount, XFS_SBS_FDBLOCKS, |
1100 | -((int64_t)diff), rsvd)) { | 1068 | -((int64_t)diff), 0)) { |
1101 | /* | 1069 | /* |
1102 | * Ick gross gag me with a spoon. | 1070 | * Ick gross gag me with a spoon. |
1103 | */ | 1071 | */ |
@@ -1109,7 +1077,7 @@ xfs_bmap_add_extent_delay_real( | |||
1109 | if (!diff || | 1077 | if (!diff || |
1110 | !xfs_icsb_modify_counters(ip->i_mount, | 1078 | !xfs_icsb_modify_counters(ip->i_mount, |
1111 | XFS_SBS_FDBLOCKS, | 1079 | XFS_SBS_FDBLOCKS, |
1112 | -((int64_t)diff), rsvd)) | 1080 | -((int64_t)diff), 0)) |
1113 | break; | 1081 | break; |
1114 | } | 1082 | } |
1115 | if (temp2) { | 1083 | if (temp2) { |
@@ -1118,18 +1086,20 @@ xfs_bmap_add_extent_delay_real( | |||
1118 | if (!diff || | 1086 | if (!diff || |
1119 | !xfs_icsb_modify_counters(ip->i_mount, | 1087 | !xfs_icsb_modify_counters(ip->i_mount, |
1120 | XFS_SBS_FDBLOCKS, | 1088 | XFS_SBS_FDBLOCKS, |
1121 | -((int64_t)diff), rsvd)) | 1089 | -((int64_t)diff), 0)) |
1122 | break; | 1090 | break; |
1123 | } | 1091 | } |
1124 | } | 1092 | } |
1125 | } | 1093 | } |
1126 | ep = xfs_iext_get_ext(ifp, idx); | 1094 | ep = xfs_iext_get_ext(ifp, *idx); |
1127 | xfs_bmbt_set_startblock(ep, nullstartblock((int)temp)); | 1095 | xfs_bmbt_set_startblock(ep, nullstartblock((int)temp)); |
1128 | trace_xfs_bmap_post_update(ip, idx, state, _THIS_IP_); | 1096 | trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_); |
1129 | trace_xfs_bmap_pre_update(ip, idx + 2, state, _THIS_IP_); | 1097 | trace_xfs_bmap_pre_update(ip, *idx + 2, state, _THIS_IP_); |
1130 | xfs_bmbt_set_startblock(xfs_iext_get_ext(ifp, idx + 2), | 1098 | xfs_bmbt_set_startblock(xfs_iext_get_ext(ifp, *idx + 2), |
1131 | nullstartblock((int)temp2)); | 1099 | nullstartblock((int)temp2)); |
1132 | trace_xfs_bmap_post_update(ip, idx + 2, state, _THIS_IP_); | 1100 | trace_xfs_bmap_post_update(ip, *idx + 2, state, _THIS_IP_); |
1101 | |||
1102 | ++*idx; | ||
1133 | *dnew = temp + temp2; | 1103 | *dnew = temp + temp2; |
1134 | break; | 1104 | break; |
1135 | 1105 | ||
@@ -1161,7 +1131,7 @@ done: | |||
1161 | STATIC int /* error */ | 1131 | STATIC int /* error */ |
1162 | xfs_bmap_add_extent_unwritten_real( | 1132 | xfs_bmap_add_extent_unwritten_real( |
1163 | xfs_inode_t *ip, /* incore inode pointer */ | 1133 | xfs_inode_t *ip, /* incore inode pointer */ |
1164 | xfs_extnum_t idx, /* extent number to update/insert */ | 1134 | xfs_extnum_t *idx, /* extent number to update/insert */ |
1165 | xfs_btree_cur_t **curp, /* if *curp is null, not a btree */ | 1135 | xfs_btree_cur_t **curp, /* if *curp is null, not a btree */ |
1166 | xfs_bmbt_irec_t *new, /* new data to add to file extents */ | 1136 | xfs_bmbt_irec_t *new, /* new data to add to file extents */ |
1167 | int *logflagsp) /* inode logging flags */ | 1137 | int *logflagsp) /* inode logging flags */ |
@@ -1188,7 +1158,7 @@ xfs_bmap_add_extent_unwritten_real( | |||
1188 | error = 0; | 1158 | error = 0; |
1189 | cur = *curp; | 1159 | cur = *curp; |
1190 | ifp = XFS_IFORK_PTR(ip, XFS_DATA_FORK); | 1160 | ifp = XFS_IFORK_PTR(ip, XFS_DATA_FORK); |
1191 | ep = xfs_iext_get_ext(ifp, idx); | 1161 | ep = xfs_iext_get_ext(ifp, *idx); |
1192 | xfs_bmbt_get_all(ep, &PREV); | 1162 | xfs_bmbt_get_all(ep, &PREV); |
1193 | newext = new->br_state; | 1163 | newext = new->br_state; |
1194 | oldext = (newext == XFS_EXT_UNWRITTEN) ? | 1164 | oldext = (newext == XFS_EXT_UNWRITTEN) ? |
@@ -1211,9 +1181,9 @@ xfs_bmap_add_extent_unwritten_real( | |||
1211 | * Check and set flags if this segment has a left neighbor. | 1181 | * Check and set flags if this segment has a left neighbor. |
1212 | * Don't set contiguous if the combined extent would be too large. | 1182 | * Don't set contiguous if the combined extent would be too large. |
1213 | */ | 1183 | */ |
1214 | if (idx > 0) { | 1184 | if (*idx > 0) { |
1215 | state |= BMAP_LEFT_VALID; | 1185 | state |= BMAP_LEFT_VALID; |
1216 | xfs_bmbt_get_all(xfs_iext_get_ext(ifp, idx - 1), &LEFT); | 1186 | xfs_bmbt_get_all(xfs_iext_get_ext(ifp, *idx - 1), &LEFT); |
1217 | 1187 | ||
1218 | if (isnullstartblock(LEFT.br_startblock)) | 1188 | if (isnullstartblock(LEFT.br_startblock)) |
1219 | state |= BMAP_LEFT_DELAY; | 1189 | state |= BMAP_LEFT_DELAY; |
@@ -1231,9 +1201,9 @@ xfs_bmap_add_extent_unwritten_real( | |||
1231 | * Don't set contiguous if the combined extent would be too large. | 1201 | * Don't set contiguous if the combined extent would be too large. |
1232 | * Also check for all-three-contiguous being too large. | 1202 | * Also check for all-three-contiguous being too large. |
1233 | */ | 1203 | */ |
1234 | if (idx < ip->i_df.if_bytes / (uint)sizeof(xfs_bmbt_rec_t) - 1) { | 1204 | if (*idx < ip->i_df.if_bytes / (uint)sizeof(xfs_bmbt_rec_t) - 1) { |
1235 | state |= BMAP_RIGHT_VALID; | 1205 | state |= BMAP_RIGHT_VALID; |
1236 | xfs_bmbt_get_all(xfs_iext_get_ext(ifp, idx + 1), &RIGHT); | 1206 | xfs_bmbt_get_all(xfs_iext_get_ext(ifp, *idx + 1), &RIGHT); |
1237 | if (isnullstartblock(RIGHT.br_startblock)) | 1207 | if (isnullstartblock(RIGHT.br_startblock)) |
1238 | state |= BMAP_RIGHT_DELAY; | 1208 | state |= BMAP_RIGHT_DELAY; |
1239 | } | 1209 | } |
@@ -1262,14 +1232,15 @@ xfs_bmap_add_extent_unwritten_real( | |||
1262 | * Setting all of a previous oldext extent to newext. | 1232 | * Setting all of a previous oldext extent to newext. |
1263 | * The left and right neighbors are both contiguous with new. | 1233 | * The left and right neighbors are both contiguous with new. |
1264 | */ | 1234 | */ |
1265 | trace_xfs_bmap_pre_update(ip, idx - 1, state, _THIS_IP_); | 1235 | --*idx; |
1266 | xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, idx - 1), | 1236 | |
1237 | trace_xfs_bmap_pre_update(ip, *idx, state, _THIS_IP_); | ||
1238 | xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, *idx), | ||
1267 | LEFT.br_blockcount + PREV.br_blockcount + | 1239 | LEFT.br_blockcount + PREV.br_blockcount + |
1268 | RIGHT.br_blockcount); | 1240 | RIGHT.br_blockcount); |
1269 | trace_xfs_bmap_post_update(ip, idx - 1, state, _THIS_IP_); | 1241 | trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_); |
1270 | 1242 | ||
1271 | xfs_iext_remove(ip, idx, 2, state); | 1243 | xfs_iext_remove(ip, *idx + 1, 2, state); |
1272 | ip->i_df.if_lastex = idx - 1; | ||
1273 | ip->i_d.di_nextents -= 2; | 1244 | ip->i_d.di_nextents -= 2; |
1274 | if (cur == NULL) | 1245 | if (cur == NULL) |
1275 | rval = XFS_ILOG_CORE | XFS_ILOG_DEXT; | 1246 | rval = XFS_ILOG_CORE | XFS_ILOG_DEXT; |
@@ -1305,13 +1276,14 @@ xfs_bmap_add_extent_unwritten_real( | |||
1305 | * Setting all of a previous oldext extent to newext. | 1276 | * Setting all of a previous oldext extent to newext. |
1306 | * The left neighbor is contiguous, the right is not. | 1277 | * The left neighbor is contiguous, the right is not. |
1307 | */ | 1278 | */ |
1308 | trace_xfs_bmap_pre_update(ip, idx - 1, state, _THIS_IP_); | 1279 | --*idx; |
1309 | xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, idx - 1), | 1280 | |
1281 | trace_xfs_bmap_pre_update(ip, *idx, state, _THIS_IP_); | ||
1282 | xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, *idx), | ||
1310 | LEFT.br_blockcount + PREV.br_blockcount); | 1283 | LEFT.br_blockcount + PREV.br_blockcount); |
1311 | trace_xfs_bmap_post_update(ip, idx - 1, state, _THIS_IP_); | 1284 | trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_); |
1312 | 1285 | ||
1313 | ip->i_df.if_lastex = idx - 1; | 1286 | xfs_iext_remove(ip, *idx + 1, 1, state); |
1314 | xfs_iext_remove(ip, idx, 1, state); | ||
1315 | ip->i_d.di_nextents--; | 1287 | ip->i_d.di_nextents--; |
1316 | if (cur == NULL) | 1288 | if (cur == NULL) |
1317 | rval = XFS_ILOG_CORE | XFS_ILOG_DEXT; | 1289 | rval = XFS_ILOG_CORE | XFS_ILOG_DEXT; |
@@ -1341,13 +1313,12 @@ xfs_bmap_add_extent_unwritten_real( | |||
1341 | * Setting all of a previous oldext extent to newext. | 1313 | * Setting all of a previous oldext extent to newext. |
1342 | * The right neighbor is contiguous, the left is not. | 1314 | * The right neighbor is contiguous, the left is not. |
1343 | */ | 1315 | */ |
1344 | trace_xfs_bmap_pre_update(ip, idx, state, _THIS_IP_); | 1316 | trace_xfs_bmap_pre_update(ip, *idx, state, _THIS_IP_); |
1345 | xfs_bmbt_set_blockcount(ep, | 1317 | xfs_bmbt_set_blockcount(ep, |
1346 | PREV.br_blockcount + RIGHT.br_blockcount); | 1318 | PREV.br_blockcount + RIGHT.br_blockcount); |
1347 | xfs_bmbt_set_state(ep, newext); | 1319 | xfs_bmbt_set_state(ep, newext); |
1348 | trace_xfs_bmap_post_update(ip, idx, state, _THIS_IP_); | 1320 | trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_); |
1349 | ip->i_df.if_lastex = idx; | 1321 | xfs_iext_remove(ip, *idx + 1, 1, state); |
1350 | xfs_iext_remove(ip, idx + 1, 1, state); | ||
1351 | ip->i_d.di_nextents--; | 1322 | ip->i_d.di_nextents--; |
1352 | if (cur == NULL) | 1323 | if (cur == NULL) |
1353 | rval = XFS_ILOG_CORE | XFS_ILOG_DEXT; | 1324 | rval = XFS_ILOG_CORE | XFS_ILOG_DEXT; |
@@ -1378,11 +1349,10 @@ xfs_bmap_add_extent_unwritten_real( | |||
1378 | * Neither the left nor right neighbors are contiguous with | 1349 | * Neither the left nor right neighbors are contiguous with |
1379 | * the new one. | 1350 | * the new one. |
1380 | */ | 1351 | */ |
1381 | trace_xfs_bmap_pre_update(ip, idx, state, _THIS_IP_); | 1352 | trace_xfs_bmap_pre_update(ip, *idx, state, _THIS_IP_); |
1382 | xfs_bmbt_set_state(ep, newext); | 1353 | xfs_bmbt_set_state(ep, newext); |
1383 | trace_xfs_bmap_post_update(ip, idx, state, _THIS_IP_); | 1354 | trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_); |
1384 | 1355 | ||
1385 | ip->i_df.if_lastex = idx; | ||
1386 | if (cur == NULL) | 1356 | if (cur == NULL) |
1387 | rval = XFS_ILOG_DEXT; | 1357 | rval = XFS_ILOG_DEXT; |
1388 | else { | 1358 | else { |
@@ -1404,21 +1374,22 @@ xfs_bmap_add_extent_unwritten_real( | |||
1404 | * Setting the first part of a previous oldext extent to newext. | 1374 | * Setting the first part of a previous oldext extent to newext. |
1405 | * The left neighbor is contiguous. | 1375 | * The left neighbor is contiguous. |
1406 | */ | 1376 | */ |
1407 | trace_xfs_bmap_pre_update(ip, idx - 1, state, _THIS_IP_); | 1377 | trace_xfs_bmap_pre_update(ip, *idx - 1, state, _THIS_IP_); |
1408 | xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, idx - 1), | 1378 | xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, *idx - 1), |
1409 | LEFT.br_blockcount + new->br_blockcount); | 1379 | LEFT.br_blockcount + new->br_blockcount); |
1410 | xfs_bmbt_set_startoff(ep, | 1380 | xfs_bmbt_set_startoff(ep, |
1411 | PREV.br_startoff + new->br_blockcount); | 1381 | PREV.br_startoff + new->br_blockcount); |
1412 | trace_xfs_bmap_post_update(ip, idx - 1, state, _THIS_IP_); | 1382 | trace_xfs_bmap_post_update(ip, *idx - 1, state, _THIS_IP_); |
1413 | 1383 | ||
1414 | trace_xfs_bmap_pre_update(ip, idx, state, _THIS_IP_); | 1384 | trace_xfs_bmap_pre_update(ip, *idx, state, _THIS_IP_); |
1415 | xfs_bmbt_set_startblock(ep, | 1385 | xfs_bmbt_set_startblock(ep, |
1416 | new->br_startblock + new->br_blockcount); | 1386 | new->br_startblock + new->br_blockcount); |
1417 | xfs_bmbt_set_blockcount(ep, | 1387 | xfs_bmbt_set_blockcount(ep, |
1418 | PREV.br_blockcount - new->br_blockcount); | 1388 | PREV.br_blockcount - new->br_blockcount); |
1419 | trace_xfs_bmap_post_update(ip, idx, state, _THIS_IP_); | 1389 | trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_); |
1390 | |||
1391 | --*idx; | ||
1420 | 1392 | ||
1421 | ip->i_df.if_lastex = idx - 1; | ||
1422 | if (cur == NULL) | 1393 | if (cur == NULL) |
1423 | rval = XFS_ILOG_DEXT; | 1394 | rval = XFS_ILOG_DEXT; |
1424 | else { | 1395 | else { |
@@ -1449,17 +1420,16 @@ xfs_bmap_add_extent_unwritten_real( | |||
1449 | * Setting the first part of a previous oldext extent to newext. | 1420 | * Setting the first part of a previous oldext extent to newext. |
1450 | * The left neighbor is not contiguous. | 1421 | * The left neighbor is not contiguous. |
1451 | */ | 1422 | */ |
1452 | trace_xfs_bmap_pre_update(ip, idx, state, _THIS_IP_); | 1423 | trace_xfs_bmap_pre_update(ip, *idx, state, _THIS_IP_); |
1453 | ASSERT(ep && xfs_bmbt_get_state(ep) == oldext); | 1424 | ASSERT(ep && xfs_bmbt_get_state(ep) == oldext); |
1454 | xfs_bmbt_set_startoff(ep, new_endoff); | 1425 | xfs_bmbt_set_startoff(ep, new_endoff); |
1455 | xfs_bmbt_set_blockcount(ep, | 1426 | xfs_bmbt_set_blockcount(ep, |
1456 | PREV.br_blockcount - new->br_blockcount); | 1427 | PREV.br_blockcount - new->br_blockcount); |
1457 | xfs_bmbt_set_startblock(ep, | 1428 | xfs_bmbt_set_startblock(ep, |
1458 | new->br_startblock + new->br_blockcount); | 1429 | new->br_startblock + new->br_blockcount); |
1459 | trace_xfs_bmap_post_update(ip, idx, state, _THIS_IP_); | 1430 | trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_); |
1460 | 1431 | ||
1461 | xfs_iext_insert(ip, idx, 1, new, state); | 1432 | xfs_iext_insert(ip, *idx, 1, new, state); |
1462 | ip->i_df.if_lastex = idx; | ||
1463 | ip->i_d.di_nextents++; | 1433 | ip->i_d.di_nextents++; |
1464 | if (cur == NULL) | 1434 | if (cur == NULL) |
1465 | rval = XFS_ILOG_CORE | XFS_ILOG_DEXT; | 1435 | rval = XFS_ILOG_CORE | XFS_ILOG_DEXT; |
@@ -1488,17 +1458,19 @@ xfs_bmap_add_extent_unwritten_real( | |||
1488 | * Setting the last part of a previous oldext extent to newext. | 1458 | * Setting the last part of a previous oldext extent to newext. |
1489 | * The right neighbor is contiguous with the new allocation. | 1459 | * The right neighbor is contiguous with the new allocation. |
1490 | */ | 1460 | */ |
1491 | trace_xfs_bmap_pre_update(ip, idx, state, _THIS_IP_); | 1461 | trace_xfs_bmap_pre_update(ip, *idx, state, _THIS_IP_); |
1492 | trace_xfs_bmap_pre_update(ip, idx + 1, state, _THIS_IP_); | ||
1493 | xfs_bmbt_set_blockcount(ep, | 1462 | xfs_bmbt_set_blockcount(ep, |
1494 | PREV.br_blockcount - new->br_blockcount); | 1463 | PREV.br_blockcount - new->br_blockcount); |
1495 | trace_xfs_bmap_post_update(ip, idx, state, _THIS_IP_); | 1464 | trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_); |
1496 | xfs_bmbt_set_allf(xfs_iext_get_ext(ifp, idx + 1), | 1465 | |
1466 | ++*idx; | ||
1467 | |||
1468 | trace_xfs_bmap_pre_update(ip, *idx, state, _THIS_IP_); | ||
1469 | xfs_bmbt_set_allf(xfs_iext_get_ext(ifp, *idx), | ||
1497 | new->br_startoff, new->br_startblock, | 1470 | new->br_startoff, new->br_startblock, |
1498 | new->br_blockcount + RIGHT.br_blockcount, newext); | 1471 | new->br_blockcount + RIGHT.br_blockcount, newext); |
1499 | trace_xfs_bmap_post_update(ip, idx + 1, state, _THIS_IP_); | 1472 | trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_); |
1500 | 1473 | ||
1501 | ip->i_df.if_lastex = idx + 1; | ||
1502 | if (cur == NULL) | 1474 | if (cur == NULL) |
1503 | rval = XFS_ILOG_DEXT; | 1475 | rval = XFS_ILOG_DEXT; |
1504 | else { | 1476 | else { |
@@ -1528,13 +1500,14 @@ xfs_bmap_add_extent_unwritten_real( | |||
1528 | * Setting the last part of a previous oldext extent to newext. | 1500 | * Setting the last part of a previous oldext extent to newext. |
1529 | * The right neighbor is not contiguous. | 1501 | * The right neighbor is not contiguous. |
1530 | */ | 1502 | */ |
1531 | trace_xfs_bmap_pre_update(ip, idx, state, _THIS_IP_); | 1503 | trace_xfs_bmap_pre_update(ip, *idx, state, _THIS_IP_); |
1532 | xfs_bmbt_set_blockcount(ep, | 1504 | xfs_bmbt_set_blockcount(ep, |
1533 | PREV.br_blockcount - new->br_blockcount); | 1505 | PREV.br_blockcount - new->br_blockcount); |
1534 | trace_xfs_bmap_post_update(ip, idx, state, _THIS_IP_); | 1506 | trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_); |
1507 | |||
1508 | ++*idx; | ||
1509 | xfs_iext_insert(ip, *idx, 1, new, state); | ||
1535 | 1510 | ||
1536 | xfs_iext_insert(ip, idx + 1, 1, new, state); | ||
1537 | ip->i_df.if_lastex = idx + 1; | ||
1538 | ip->i_d.di_nextents++; | 1511 | ip->i_d.di_nextents++; |
1539 | if (cur == NULL) | 1512 | if (cur == NULL) |
1540 | rval = XFS_ILOG_CORE | XFS_ILOG_DEXT; | 1513 | rval = XFS_ILOG_CORE | XFS_ILOG_DEXT; |
@@ -1568,10 +1541,10 @@ xfs_bmap_add_extent_unwritten_real( | |||
1568 | * newext. Contiguity is impossible here. | 1541 | * newext. Contiguity is impossible here. |
1569 | * One extent becomes three extents. | 1542 | * One extent becomes three extents. |
1570 | */ | 1543 | */ |
1571 | trace_xfs_bmap_pre_update(ip, idx, state, _THIS_IP_); | 1544 | trace_xfs_bmap_pre_update(ip, *idx, state, _THIS_IP_); |
1572 | xfs_bmbt_set_blockcount(ep, | 1545 | xfs_bmbt_set_blockcount(ep, |
1573 | new->br_startoff - PREV.br_startoff); | 1546 | new->br_startoff - PREV.br_startoff); |
1574 | trace_xfs_bmap_post_update(ip, idx, state, _THIS_IP_); | 1547 | trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_); |
1575 | 1548 | ||
1576 | r[0] = *new; | 1549 | r[0] = *new; |
1577 | r[1].br_startoff = new_endoff; | 1550 | r[1].br_startoff = new_endoff; |
@@ -1579,8 +1552,10 @@ xfs_bmap_add_extent_unwritten_real( | |||
1579 | PREV.br_startoff + PREV.br_blockcount - new_endoff; | 1552 | PREV.br_startoff + PREV.br_blockcount - new_endoff; |
1580 | r[1].br_startblock = new->br_startblock + new->br_blockcount; | 1553 | r[1].br_startblock = new->br_startblock + new->br_blockcount; |
1581 | r[1].br_state = oldext; | 1554 | r[1].br_state = oldext; |
1582 | xfs_iext_insert(ip, idx + 1, 2, &r[0], state); | 1555 | |
1583 | ip->i_df.if_lastex = idx + 1; | 1556 | ++*idx; |
1557 | xfs_iext_insert(ip, *idx, 2, &r[0], state); | ||
1558 | |||
1584 | ip->i_d.di_nextents += 2; | 1559 | ip->i_d.di_nextents += 2; |
1585 | if (cur == NULL) | 1560 | if (cur == NULL) |
1586 | rval = XFS_ILOG_CORE | XFS_ILOG_DEXT; | 1561 | rval = XFS_ILOG_CORE | XFS_ILOG_DEXT; |
@@ -1650,12 +1625,10 @@ done: | |||
1650 | STATIC int /* error */ | 1625 | STATIC int /* error */ |
1651 | xfs_bmap_add_extent_hole_delay( | 1626 | xfs_bmap_add_extent_hole_delay( |
1652 | xfs_inode_t *ip, /* incore inode pointer */ | 1627 | xfs_inode_t *ip, /* incore inode pointer */ |
1653 | xfs_extnum_t idx, /* extent number to update/insert */ | 1628 | xfs_extnum_t *idx, /* extent number to update/insert */ |
1654 | xfs_bmbt_irec_t *new, /* new data to add to file extents */ | 1629 | xfs_bmbt_irec_t *new, /* new data to add to file extents */ |
1655 | int *logflagsp, /* inode logging flags */ | 1630 | int *logflagsp) /* inode logging flags */ |
1656 | int rsvd) /* OK to allocate reserved blocks */ | ||
1657 | { | 1631 | { |
1658 | xfs_bmbt_rec_host_t *ep; /* extent record for idx */ | ||
1659 | xfs_ifork_t *ifp; /* inode fork pointer */ | 1632 | xfs_ifork_t *ifp; /* inode fork pointer */ |
1660 | xfs_bmbt_irec_t left; /* left neighbor extent entry */ | 1633 | xfs_bmbt_irec_t left; /* left neighbor extent entry */ |
1661 | xfs_filblks_t newlen=0; /* new indirect size */ | 1634 | xfs_filblks_t newlen=0; /* new indirect size */ |
@@ -1665,16 +1638,15 @@ xfs_bmap_add_extent_hole_delay( | |||
1665 | xfs_filblks_t temp=0; /* temp for indirect calculations */ | 1638 | xfs_filblks_t temp=0; /* temp for indirect calculations */ |
1666 | 1639 | ||
1667 | ifp = XFS_IFORK_PTR(ip, XFS_DATA_FORK); | 1640 | ifp = XFS_IFORK_PTR(ip, XFS_DATA_FORK); |
1668 | ep = xfs_iext_get_ext(ifp, idx); | ||
1669 | state = 0; | 1641 | state = 0; |
1670 | ASSERT(isnullstartblock(new->br_startblock)); | 1642 | ASSERT(isnullstartblock(new->br_startblock)); |
1671 | 1643 | ||
1672 | /* | 1644 | /* |
1673 | * Check and set flags if this segment has a left neighbor | 1645 | * Check and set flags if this segment has a left neighbor |
1674 | */ | 1646 | */ |
1675 | if (idx > 0) { | 1647 | if (*idx > 0) { |
1676 | state |= BMAP_LEFT_VALID; | 1648 | state |= BMAP_LEFT_VALID; |
1677 | xfs_bmbt_get_all(xfs_iext_get_ext(ifp, idx - 1), &left); | 1649 | xfs_bmbt_get_all(xfs_iext_get_ext(ifp, *idx - 1), &left); |
1678 | 1650 | ||
1679 | if (isnullstartblock(left.br_startblock)) | 1651 | if (isnullstartblock(left.br_startblock)) |
1680 | state |= BMAP_LEFT_DELAY; | 1652 | state |= BMAP_LEFT_DELAY; |
@@ -1684,9 +1656,9 @@ xfs_bmap_add_extent_hole_delay( | |||
1684 | * Check and set flags if the current (right) segment exists. | 1656 | * Check and set flags if the current (right) segment exists. |
1685 | * If it doesn't exist, we're converting the hole at end-of-file. | 1657 | * If it doesn't exist, we're converting the hole at end-of-file. |
1686 | */ | 1658 | */ |
1687 | if (idx < ip->i_df.if_bytes / (uint)sizeof(xfs_bmbt_rec_t)) { | 1659 | if (*idx < ip->i_df.if_bytes / (uint)sizeof(xfs_bmbt_rec_t)) { |
1688 | state |= BMAP_RIGHT_VALID; | 1660 | state |= BMAP_RIGHT_VALID; |
1689 | xfs_bmbt_get_all(ep, &right); | 1661 | xfs_bmbt_get_all(xfs_iext_get_ext(ifp, *idx), &right); |
1690 | 1662 | ||
1691 | if (isnullstartblock(right.br_startblock)) | 1663 | if (isnullstartblock(right.br_startblock)) |
1692 | state |= BMAP_RIGHT_DELAY; | 1664 | state |= BMAP_RIGHT_DELAY; |
@@ -1719,21 +1691,21 @@ xfs_bmap_add_extent_hole_delay( | |||
1719 | * on the left and on the right. | 1691 | * on the left and on the right. |
1720 | * Merge all three into a single extent record. | 1692 | * Merge all three into a single extent record. |
1721 | */ | 1693 | */ |
1694 | --*idx; | ||
1722 | temp = left.br_blockcount + new->br_blockcount + | 1695 | temp = left.br_blockcount + new->br_blockcount + |
1723 | right.br_blockcount; | 1696 | right.br_blockcount; |
1724 | 1697 | ||
1725 | trace_xfs_bmap_pre_update(ip, idx - 1, state, _THIS_IP_); | 1698 | trace_xfs_bmap_pre_update(ip, *idx, state, _THIS_IP_); |
1726 | xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, idx - 1), temp); | 1699 | xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, *idx), temp); |
1727 | oldlen = startblockval(left.br_startblock) + | 1700 | oldlen = startblockval(left.br_startblock) + |
1728 | startblockval(new->br_startblock) + | 1701 | startblockval(new->br_startblock) + |
1729 | startblockval(right.br_startblock); | 1702 | startblockval(right.br_startblock); |
1730 | newlen = xfs_bmap_worst_indlen(ip, temp); | 1703 | newlen = xfs_bmap_worst_indlen(ip, temp); |
1731 | xfs_bmbt_set_startblock(xfs_iext_get_ext(ifp, idx - 1), | 1704 | xfs_bmbt_set_startblock(xfs_iext_get_ext(ifp, *idx), |
1732 | nullstartblock((int)newlen)); | 1705 | nullstartblock((int)newlen)); |
1733 | trace_xfs_bmap_post_update(ip, idx - 1, state, _THIS_IP_); | 1706 | trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_); |
1734 | 1707 | ||
1735 | xfs_iext_remove(ip, idx, 1, state); | 1708 | xfs_iext_remove(ip, *idx + 1, 1, state); |
1736 | ip->i_df.if_lastex = idx - 1; | ||
1737 | break; | 1709 | break; |
1738 | 1710 | ||
1739 | case BMAP_LEFT_CONTIG: | 1711 | case BMAP_LEFT_CONTIG: |
@@ -1742,17 +1714,17 @@ xfs_bmap_add_extent_hole_delay( | |||
1742 | * on the left. | 1714 | * on the left. |
1743 | * Merge the new allocation with the left neighbor. | 1715 | * Merge the new allocation with the left neighbor. |
1744 | */ | 1716 | */ |
1717 | --*idx; | ||
1745 | temp = left.br_blockcount + new->br_blockcount; | 1718 | temp = left.br_blockcount + new->br_blockcount; |
1746 | trace_xfs_bmap_pre_update(ip, idx - 1, state, _THIS_IP_); | 1719 | |
1747 | xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, idx - 1), temp); | 1720 | trace_xfs_bmap_pre_update(ip, *idx, state, _THIS_IP_); |
1721 | xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, *idx), temp); | ||
1748 | oldlen = startblockval(left.br_startblock) + | 1722 | oldlen = startblockval(left.br_startblock) + |
1749 | startblockval(new->br_startblock); | 1723 | startblockval(new->br_startblock); |
1750 | newlen = xfs_bmap_worst_indlen(ip, temp); | 1724 | newlen = xfs_bmap_worst_indlen(ip, temp); |
1751 | xfs_bmbt_set_startblock(xfs_iext_get_ext(ifp, idx - 1), | 1725 | xfs_bmbt_set_startblock(xfs_iext_get_ext(ifp, *idx), |
1752 | nullstartblock((int)newlen)); | 1726 | nullstartblock((int)newlen)); |
1753 | trace_xfs_bmap_post_update(ip, idx - 1, state, _THIS_IP_); | 1727 | trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_); |
1754 | |||
1755 | ip->i_df.if_lastex = idx - 1; | ||
1756 | break; | 1728 | break; |
1757 | 1729 | ||
1758 | case BMAP_RIGHT_CONTIG: | 1730 | case BMAP_RIGHT_CONTIG: |
@@ -1761,16 +1733,15 @@ xfs_bmap_add_extent_hole_delay( | |||
1761 | * on the right. | 1733 | * on the right. |
1762 | * Merge the new allocation with the right neighbor. | 1734 | * Merge the new allocation with the right neighbor. |
1763 | */ | 1735 | */ |
1764 | trace_xfs_bmap_pre_update(ip, idx, state, _THIS_IP_); | 1736 | trace_xfs_bmap_pre_update(ip, *idx, state, _THIS_IP_); |
1765 | temp = new->br_blockcount + right.br_blockcount; | 1737 | temp = new->br_blockcount + right.br_blockcount; |
1766 | oldlen = startblockval(new->br_startblock) + | 1738 | oldlen = startblockval(new->br_startblock) + |
1767 | startblockval(right.br_startblock); | 1739 | startblockval(right.br_startblock); |
1768 | newlen = xfs_bmap_worst_indlen(ip, temp); | 1740 | newlen = xfs_bmap_worst_indlen(ip, temp); |
1769 | xfs_bmbt_set_allf(ep, new->br_startoff, | 1741 | xfs_bmbt_set_allf(xfs_iext_get_ext(ifp, *idx), |
1742 | new->br_startoff, | ||
1770 | nullstartblock((int)newlen), temp, right.br_state); | 1743 | nullstartblock((int)newlen), temp, right.br_state); |
1771 | trace_xfs_bmap_post_update(ip, idx, state, _THIS_IP_); | 1744 | trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_); |
1772 | |||
1773 | ip->i_df.if_lastex = idx; | ||
1774 | break; | 1745 | break; |
1775 | 1746 | ||
1776 | case 0: | 1747 | case 0: |
@@ -1780,14 +1751,13 @@ xfs_bmap_add_extent_hole_delay( | |||
1780 | * Insert a new entry. | 1751 | * Insert a new entry. |
1781 | */ | 1752 | */ |
1782 | oldlen = newlen = 0; | 1753 | oldlen = newlen = 0; |
1783 | xfs_iext_insert(ip, idx, 1, new, state); | 1754 | xfs_iext_insert(ip, *idx, 1, new, state); |
1784 | ip->i_df.if_lastex = idx; | ||
1785 | break; | 1755 | break; |
1786 | } | 1756 | } |
1787 | if (oldlen != newlen) { | 1757 | if (oldlen != newlen) { |
1788 | ASSERT(oldlen > newlen); | 1758 | ASSERT(oldlen > newlen); |
1789 | xfs_icsb_modify_counters(ip->i_mount, XFS_SBS_FDBLOCKS, | 1759 | xfs_icsb_modify_counters(ip->i_mount, XFS_SBS_FDBLOCKS, |
1790 | (int64_t)(oldlen - newlen), rsvd); | 1760 | (int64_t)(oldlen - newlen), 0); |
1791 | /* | 1761 | /* |
1792 | * Nothing to do for disk quota accounting here. | 1762 | * Nothing to do for disk quota accounting here. |
1793 | */ | 1763 | */ |
@@ -1803,13 +1773,12 @@ xfs_bmap_add_extent_hole_delay( | |||
1803 | STATIC int /* error */ | 1773 | STATIC int /* error */ |
1804 | xfs_bmap_add_extent_hole_real( | 1774 | xfs_bmap_add_extent_hole_real( |
1805 | xfs_inode_t *ip, /* incore inode pointer */ | 1775 | xfs_inode_t *ip, /* incore inode pointer */ |
1806 | xfs_extnum_t idx, /* extent number to update/insert */ | 1776 | xfs_extnum_t *idx, /* extent number to update/insert */ |
1807 | xfs_btree_cur_t *cur, /* if null, not a btree */ | 1777 | xfs_btree_cur_t *cur, /* if null, not a btree */ |
1808 | xfs_bmbt_irec_t *new, /* new data to add to file extents */ | 1778 | xfs_bmbt_irec_t *new, /* new data to add to file extents */ |
1809 | int *logflagsp, /* inode logging flags */ | 1779 | int *logflagsp, /* inode logging flags */ |
1810 | int whichfork) /* data or attr fork */ | 1780 | int whichfork) /* data or attr fork */ |
1811 | { | 1781 | { |
1812 | xfs_bmbt_rec_host_t *ep; /* pointer to extent entry ins. point */ | ||
1813 | int error; /* error return value */ | 1782 | int error; /* error return value */ |
1814 | int i; /* temp state */ | 1783 | int i; /* temp state */ |
1815 | xfs_ifork_t *ifp; /* inode fork pointer */ | 1784 | xfs_ifork_t *ifp; /* inode fork pointer */ |
@@ -1819,8 +1788,7 @@ xfs_bmap_add_extent_hole_real( | |||
1819 | int state; /* state bits, accessed thru macros */ | 1788 | int state; /* state bits, accessed thru macros */ |
1820 | 1789 | ||
1821 | ifp = XFS_IFORK_PTR(ip, whichfork); | 1790 | ifp = XFS_IFORK_PTR(ip, whichfork); |
1822 | ASSERT(idx <= ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t)); | 1791 | ASSERT(*idx <= ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t)); |
1823 | ep = xfs_iext_get_ext(ifp, idx); | ||
1824 | state = 0; | 1792 | state = 0; |
1825 | 1793 | ||
1826 | if (whichfork == XFS_ATTR_FORK) | 1794 | if (whichfork == XFS_ATTR_FORK) |
@@ -1829,9 +1797,9 @@ xfs_bmap_add_extent_hole_real( | |||
1829 | /* | 1797 | /* |
1830 | * Check and set flags if this segment has a left neighbor. | 1798 | * Check and set flags if this segment has a left neighbor. |
1831 | */ | 1799 | */ |
1832 | if (idx > 0) { | 1800 | if (*idx > 0) { |
1833 | state |= BMAP_LEFT_VALID; | 1801 | state |= BMAP_LEFT_VALID; |
1834 | xfs_bmbt_get_all(xfs_iext_get_ext(ifp, idx - 1), &left); | 1802 | xfs_bmbt_get_all(xfs_iext_get_ext(ifp, *idx - 1), &left); |
1835 | if (isnullstartblock(left.br_startblock)) | 1803 | if (isnullstartblock(left.br_startblock)) |
1836 | state |= BMAP_LEFT_DELAY; | 1804 | state |= BMAP_LEFT_DELAY; |
1837 | } | 1805 | } |
@@ -1840,9 +1808,9 @@ xfs_bmap_add_extent_hole_real( | |||
1840 | * Check and set flags if this segment has a current value. | 1808 | * Check and set flags if this segment has a current value. |
1841 | * Not true if we're inserting into the "hole" at eof. | 1809 | * Not true if we're inserting into the "hole" at eof. |
1842 | */ | 1810 | */ |
1843 | if (idx < ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t)) { | 1811 | if (*idx < ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t)) { |
1844 | state |= BMAP_RIGHT_VALID; | 1812 | state |= BMAP_RIGHT_VALID; |
1845 | xfs_bmbt_get_all(ep, &right); | 1813 | xfs_bmbt_get_all(xfs_iext_get_ext(ifp, *idx), &right); |
1846 | if (isnullstartblock(right.br_startblock)) | 1814 | if (isnullstartblock(right.br_startblock)) |
1847 | state |= BMAP_RIGHT_DELAY; | 1815 | state |= BMAP_RIGHT_DELAY; |
1848 | } | 1816 | } |
@@ -1879,14 +1847,15 @@ xfs_bmap_add_extent_hole_real( | |||
1879 | * left and on the right. | 1847 | * left and on the right. |
1880 | * Merge all three into a single extent record. | 1848 | * Merge all three into a single extent record. |
1881 | */ | 1849 | */ |
1882 | trace_xfs_bmap_pre_update(ip, idx - 1, state, _THIS_IP_); | 1850 | --*idx; |
1883 | xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, idx - 1), | 1851 | trace_xfs_bmap_pre_update(ip, *idx, state, _THIS_IP_); |
1852 | xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, *idx), | ||
1884 | left.br_blockcount + new->br_blockcount + | 1853 | left.br_blockcount + new->br_blockcount + |
1885 | right.br_blockcount); | 1854 | right.br_blockcount); |
1886 | trace_xfs_bmap_post_update(ip, idx - 1, state, _THIS_IP_); | 1855 | trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_); |
1856 | |||
1857 | xfs_iext_remove(ip, *idx + 1, 1, state); | ||
1887 | 1858 | ||
1888 | xfs_iext_remove(ip, idx, 1, state); | ||
1889 | ifp->if_lastex = idx - 1; | ||
1890 | XFS_IFORK_NEXT_SET(ip, whichfork, | 1859 | XFS_IFORK_NEXT_SET(ip, whichfork, |
1891 | XFS_IFORK_NEXTENTS(ip, whichfork) - 1); | 1860 | XFS_IFORK_NEXTENTS(ip, whichfork) - 1); |
1892 | if (cur == NULL) { | 1861 | if (cur == NULL) { |
@@ -1921,12 +1890,12 @@ xfs_bmap_add_extent_hole_real( | |||
1921 | * on the left. | 1890 | * on the left. |
1922 | * Merge the new allocation with the left neighbor. | 1891 | * Merge the new allocation with the left neighbor. |
1923 | */ | 1892 | */ |
1924 | trace_xfs_bmap_pre_update(ip, idx - 1, state, _THIS_IP_); | 1893 | --*idx; |
1925 | xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, idx - 1), | 1894 | trace_xfs_bmap_pre_update(ip, *idx, state, _THIS_IP_); |
1895 | xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, *idx), | ||
1926 | left.br_blockcount + new->br_blockcount); | 1896 | left.br_blockcount + new->br_blockcount); |
1927 | trace_xfs_bmap_post_update(ip, idx - 1, state, _THIS_IP_); | 1897 | trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_); |
1928 | 1898 | ||
1929 | ifp->if_lastex = idx - 1; | ||
1930 | if (cur == NULL) { | 1899 | if (cur == NULL) { |
1931 | rval = xfs_ilog_fext(whichfork); | 1900 | rval = xfs_ilog_fext(whichfork); |
1932 | } else { | 1901 | } else { |
@@ -1952,13 +1921,13 @@ xfs_bmap_add_extent_hole_real( | |||
1952 | * on the right. | 1921 | * on the right. |
1953 | * Merge the new allocation with the right neighbor. | 1922 | * Merge the new allocation with the right neighbor. |
1954 | */ | 1923 | */ |
1955 | trace_xfs_bmap_pre_update(ip, idx, state, _THIS_IP_); | 1924 | trace_xfs_bmap_pre_update(ip, *idx, state, _THIS_IP_); |
1956 | xfs_bmbt_set_allf(ep, new->br_startoff, new->br_startblock, | 1925 | xfs_bmbt_set_allf(xfs_iext_get_ext(ifp, *idx), |
1926 | new->br_startoff, new->br_startblock, | ||
1957 | new->br_blockcount + right.br_blockcount, | 1927 | new->br_blockcount + right.br_blockcount, |
1958 | right.br_state); | 1928 | right.br_state); |
1959 | trace_xfs_bmap_post_update(ip, idx, state, _THIS_IP_); | 1929 | trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_); |
1960 | 1930 | ||
1961 | ifp->if_lastex = idx; | ||
1962 | if (cur == NULL) { | 1931 | if (cur == NULL) { |
1963 | rval = xfs_ilog_fext(whichfork); | 1932 | rval = xfs_ilog_fext(whichfork); |
1964 | } else { | 1933 | } else { |
@@ -1984,8 +1953,7 @@ xfs_bmap_add_extent_hole_real( | |||
1984 | * real allocation. | 1953 | * real allocation. |
1985 | * Insert a new entry. | 1954 | * Insert a new entry. |
1986 | */ | 1955 | */ |
1987 | xfs_iext_insert(ip, idx, 1, new, state); | 1956 | xfs_iext_insert(ip, *idx, 1, new, state); |
1988 | ifp->if_lastex = idx; | ||
1989 | XFS_IFORK_NEXT_SET(ip, whichfork, | 1957 | XFS_IFORK_NEXT_SET(ip, whichfork, |
1990 | XFS_IFORK_NEXTENTS(ip, whichfork) + 1); | 1958 | XFS_IFORK_NEXTENTS(ip, whichfork) + 1); |
1991 | if (cur == NULL) { | 1959 | if (cur == NULL) { |
@@ -2833,13 +2801,12 @@ STATIC int /* error */ | |||
2833 | xfs_bmap_del_extent( | 2801 | xfs_bmap_del_extent( |
2834 | xfs_inode_t *ip, /* incore inode pointer */ | 2802 | xfs_inode_t *ip, /* incore inode pointer */ |
2835 | xfs_trans_t *tp, /* current transaction pointer */ | 2803 | xfs_trans_t *tp, /* current transaction pointer */ |
2836 | xfs_extnum_t idx, /* extent number to update/delete */ | 2804 | xfs_extnum_t *idx, /* extent number to update/delete */ |
2837 | xfs_bmap_free_t *flist, /* list of extents to be freed */ | 2805 | xfs_bmap_free_t *flist, /* list of extents to be freed */ |
2838 | xfs_btree_cur_t *cur, /* if null, not a btree */ | 2806 | xfs_btree_cur_t *cur, /* if null, not a btree */ |
2839 | xfs_bmbt_irec_t *del, /* data to remove from extents */ | 2807 | xfs_bmbt_irec_t *del, /* data to remove from extents */ |
2840 | int *logflagsp, /* inode logging flags */ | 2808 | int *logflagsp, /* inode logging flags */ |
2841 | int whichfork, /* data or attr fork */ | 2809 | int whichfork) /* data or attr fork */ |
2842 | int rsvd) /* OK to allocate reserved blocks */ | ||
2843 | { | 2810 | { |
2844 | xfs_filblks_t da_new; /* new delay-alloc indirect blocks */ | 2811 | xfs_filblks_t da_new; /* new delay-alloc indirect blocks */ |
2845 | xfs_filblks_t da_old; /* old delay-alloc indirect blocks */ | 2812 | xfs_filblks_t da_old; /* old delay-alloc indirect blocks */ |
@@ -2870,10 +2837,10 @@ xfs_bmap_del_extent( | |||
2870 | 2837 | ||
2871 | mp = ip->i_mount; | 2838 | mp = ip->i_mount; |
2872 | ifp = XFS_IFORK_PTR(ip, whichfork); | 2839 | ifp = XFS_IFORK_PTR(ip, whichfork); |
2873 | ASSERT((idx >= 0) && (idx < ifp->if_bytes / | 2840 | ASSERT((*idx >= 0) && (*idx < ifp->if_bytes / |
2874 | (uint)sizeof(xfs_bmbt_rec_t))); | 2841 | (uint)sizeof(xfs_bmbt_rec_t))); |
2875 | ASSERT(del->br_blockcount > 0); | 2842 | ASSERT(del->br_blockcount > 0); |
2876 | ep = xfs_iext_get_ext(ifp, idx); | 2843 | ep = xfs_iext_get_ext(ifp, *idx); |
2877 | xfs_bmbt_get_all(ep, &got); | 2844 | xfs_bmbt_get_all(ep, &got); |
2878 | ASSERT(got.br_startoff <= del->br_startoff); | 2845 | ASSERT(got.br_startoff <= del->br_startoff); |
2879 | del_endoff = del->br_startoff + del->br_blockcount; | 2846 | del_endoff = del->br_startoff + del->br_blockcount; |
@@ -2947,11 +2914,12 @@ xfs_bmap_del_extent( | |||
2947 | /* | 2914 | /* |
2948 | * Matches the whole extent. Delete the entry. | 2915 | * Matches the whole extent. Delete the entry. |
2949 | */ | 2916 | */ |
2950 | xfs_iext_remove(ip, idx, 1, | 2917 | xfs_iext_remove(ip, *idx, 1, |
2951 | whichfork == XFS_ATTR_FORK ? BMAP_ATTRFORK : 0); | 2918 | whichfork == XFS_ATTR_FORK ? BMAP_ATTRFORK : 0); |
2952 | ifp->if_lastex = idx; | 2919 | --*idx; |
2953 | if (delay) | 2920 | if (delay) |
2954 | break; | 2921 | break; |
2922 | |||
2955 | XFS_IFORK_NEXT_SET(ip, whichfork, | 2923 | XFS_IFORK_NEXT_SET(ip, whichfork, |
2956 | XFS_IFORK_NEXTENTS(ip, whichfork) - 1); | 2924 | XFS_IFORK_NEXTENTS(ip, whichfork) - 1); |
2957 | flags |= XFS_ILOG_CORE; | 2925 | flags |= XFS_ILOG_CORE; |
@@ -2968,21 +2936,20 @@ xfs_bmap_del_extent( | |||
2968 | /* | 2936 | /* |
2969 | * Deleting the first part of the extent. | 2937 | * Deleting the first part of the extent. |
2970 | */ | 2938 | */ |
2971 | trace_xfs_bmap_pre_update(ip, idx, state, _THIS_IP_); | 2939 | trace_xfs_bmap_pre_update(ip, *idx, state, _THIS_IP_); |
2972 | xfs_bmbt_set_startoff(ep, del_endoff); | 2940 | xfs_bmbt_set_startoff(ep, del_endoff); |
2973 | temp = got.br_blockcount - del->br_blockcount; | 2941 | temp = got.br_blockcount - del->br_blockcount; |
2974 | xfs_bmbt_set_blockcount(ep, temp); | 2942 | xfs_bmbt_set_blockcount(ep, temp); |
2975 | ifp->if_lastex = idx; | ||
2976 | if (delay) { | 2943 | if (delay) { |
2977 | temp = XFS_FILBLKS_MIN(xfs_bmap_worst_indlen(ip, temp), | 2944 | temp = XFS_FILBLKS_MIN(xfs_bmap_worst_indlen(ip, temp), |
2978 | da_old); | 2945 | da_old); |
2979 | xfs_bmbt_set_startblock(ep, nullstartblock((int)temp)); | 2946 | xfs_bmbt_set_startblock(ep, nullstartblock((int)temp)); |
2980 | trace_xfs_bmap_post_update(ip, idx, state, _THIS_IP_); | 2947 | trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_); |
2981 | da_new = temp; | 2948 | da_new = temp; |
2982 | break; | 2949 | break; |
2983 | } | 2950 | } |
2984 | xfs_bmbt_set_startblock(ep, del_endblock); | 2951 | xfs_bmbt_set_startblock(ep, del_endblock); |
2985 | trace_xfs_bmap_post_update(ip, idx, state, _THIS_IP_); | 2952 | trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_); |
2986 | if (!cur) { | 2953 | if (!cur) { |
2987 | flags |= xfs_ilog_fext(whichfork); | 2954 | flags |= xfs_ilog_fext(whichfork); |
2988 | break; | 2955 | break; |
@@ -2998,18 +2965,17 @@ xfs_bmap_del_extent( | |||
2998 | * Deleting the last part of the extent. | 2965 | * Deleting the last part of the extent. |
2999 | */ | 2966 | */ |
3000 | temp = got.br_blockcount - del->br_blockcount; | 2967 | temp = got.br_blockcount - del->br_blockcount; |
3001 | trace_xfs_bmap_pre_update(ip, idx, state, _THIS_IP_); | 2968 | trace_xfs_bmap_pre_update(ip, *idx, state, _THIS_IP_); |
3002 | xfs_bmbt_set_blockcount(ep, temp); | 2969 | xfs_bmbt_set_blockcount(ep, temp); |
3003 | ifp->if_lastex = idx; | ||
3004 | if (delay) { | 2970 | if (delay) { |
3005 | temp = XFS_FILBLKS_MIN(xfs_bmap_worst_indlen(ip, temp), | 2971 | temp = XFS_FILBLKS_MIN(xfs_bmap_worst_indlen(ip, temp), |
3006 | da_old); | 2972 | da_old); |
3007 | xfs_bmbt_set_startblock(ep, nullstartblock((int)temp)); | 2973 | xfs_bmbt_set_startblock(ep, nullstartblock((int)temp)); |
3008 | trace_xfs_bmap_post_update(ip, idx, state, _THIS_IP_); | 2974 | trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_); |
3009 | da_new = temp; | 2975 | da_new = temp; |
3010 | break; | 2976 | break; |
3011 | } | 2977 | } |
3012 | trace_xfs_bmap_post_update(ip, idx, state, _THIS_IP_); | 2978 | trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_); |
3013 | if (!cur) { | 2979 | if (!cur) { |
3014 | flags |= xfs_ilog_fext(whichfork); | 2980 | flags |= xfs_ilog_fext(whichfork); |
3015 | break; | 2981 | break; |
@@ -3026,7 +2992,7 @@ xfs_bmap_del_extent( | |||
3026 | * Deleting the middle of the extent. | 2992 | * Deleting the middle of the extent. |
3027 | */ | 2993 | */ |
3028 | temp = del->br_startoff - got.br_startoff; | 2994 | temp = del->br_startoff - got.br_startoff; |
3029 | trace_xfs_bmap_pre_update(ip, idx, state, _THIS_IP_); | 2995 | trace_xfs_bmap_pre_update(ip, *idx, state, _THIS_IP_); |
3030 | xfs_bmbt_set_blockcount(ep, temp); | 2996 | xfs_bmbt_set_blockcount(ep, temp); |
3031 | new.br_startoff = del_endoff; | 2997 | new.br_startoff = del_endoff; |
3032 | temp2 = got_endoff - del_endoff; | 2998 | temp2 = got_endoff - del_endoff; |
@@ -3113,9 +3079,9 @@ xfs_bmap_del_extent( | |||
3113 | } | 3079 | } |
3114 | } | 3080 | } |
3115 | } | 3081 | } |
3116 | trace_xfs_bmap_post_update(ip, idx, state, _THIS_IP_); | 3082 | trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_); |
3117 | xfs_iext_insert(ip, idx + 1, 1, &new, state); | 3083 | xfs_iext_insert(ip, *idx + 1, 1, &new, state); |
3118 | ifp->if_lastex = idx + 1; | 3084 | ++*idx; |
3119 | break; | 3085 | break; |
3120 | } | 3086 | } |
3121 | /* | 3087 | /* |
@@ -3142,7 +3108,7 @@ xfs_bmap_del_extent( | |||
3142 | ASSERT(da_old >= da_new); | 3108 | ASSERT(da_old >= da_new); |
3143 | if (da_old > da_new) { | 3109 | if (da_old > da_new) { |
3144 | xfs_icsb_modify_counters(mp, XFS_SBS_FDBLOCKS, | 3110 | xfs_icsb_modify_counters(mp, XFS_SBS_FDBLOCKS, |
3145 | (int64_t)(da_old - da_new), rsvd); | 3111 | (int64_t)(da_old - da_new), 0); |
3146 | } | 3112 | } |
3147 | done: | 3113 | done: |
3148 | *logflagsp = flags; | 3114 | *logflagsp = flags; |
@@ -4562,29 +4528,24 @@ xfs_bmapi( | |||
4562 | if (rt) { | 4528 | if (rt) { |
4563 | error = xfs_mod_incore_sb(mp, | 4529 | error = xfs_mod_incore_sb(mp, |
4564 | XFS_SBS_FREXTENTS, | 4530 | XFS_SBS_FREXTENTS, |
4565 | -((int64_t)extsz), (flags & | 4531 | -((int64_t)extsz), 0); |
4566 | XFS_BMAPI_RSVBLOCKS)); | ||
4567 | } else { | 4532 | } else { |
4568 | error = xfs_icsb_modify_counters(mp, | 4533 | error = xfs_icsb_modify_counters(mp, |
4569 | XFS_SBS_FDBLOCKS, | 4534 | XFS_SBS_FDBLOCKS, |
4570 | -((int64_t)alen), (flags & | 4535 | -((int64_t)alen), 0); |
4571 | XFS_BMAPI_RSVBLOCKS)); | ||
4572 | } | 4536 | } |
4573 | if (!error) { | 4537 | if (!error) { |
4574 | error = xfs_icsb_modify_counters(mp, | 4538 | error = xfs_icsb_modify_counters(mp, |
4575 | XFS_SBS_FDBLOCKS, | 4539 | XFS_SBS_FDBLOCKS, |
4576 | -((int64_t)indlen), (flags & | 4540 | -((int64_t)indlen), 0); |
4577 | XFS_BMAPI_RSVBLOCKS)); | ||
4578 | if (error && rt) | 4541 | if (error && rt) |
4579 | xfs_mod_incore_sb(mp, | 4542 | xfs_mod_incore_sb(mp, |
4580 | XFS_SBS_FREXTENTS, | 4543 | XFS_SBS_FREXTENTS, |
4581 | (int64_t)extsz, (flags & | 4544 | (int64_t)extsz, 0); |
4582 | XFS_BMAPI_RSVBLOCKS)); | ||
4583 | else if (error) | 4545 | else if (error) |
4584 | xfs_icsb_modify_counters(mp, | 4546 | xfs_icsb_modify_counters(mp, |
4585 | XFS_SBS_FDBLOCKS, | 4547 | XFS_SBS_FDBLOCKS, |
4586 | (int64_t)alen, (flags & | 4548 | (int64_t)alen, 0); |
4587 | XFS_BMAPI_RSVBLOCKS)); | ||
4588 | } | 4549 | } |
4589 | 4550 | ||
4590 | if (error) { | 4551 | if (error) { |
@@ -4701,13 +4662,12 @@ xfs_bmapi( | |||
4701 | if (!wasdelay && (flags & XFS_BMAPI_PREALLOC)) | 4662 | if (!wasdelay && (flags & XFS_BMAPI_PREALLOC)) |
4702 | got.br_state = XFS_EXT_UNWRITTEN; | 4663 | got.br_state = XFS_EXT_UNWRITTEN; |
4703 | } | 4664 | } |
4704 | error = xfs_bmap_add_extent(ip, lastx, &cur, &got, | 4665 | error = xfs_bmap_add_extent(ip, &lastx, &cur, &got, |
4705 | firstblock, flist, &tmp_logflags, | 4666 | firstblock, flist, &tmp_logflags, |
4706 | whichfork, (flags & XFS_BMAPI_RSVBLOCKS)); | 4667 | whichfork); |
4707 | logflags |= tmp_logflags; | 4668 | logflags |= tmp_logflags; |
4708 | if (error) | 4669 | if (error) |
4709 | goto error0; | 4670 | goto error0; |
4710 | lastx = ifp->if_lastex; | ||
4711 | ep = xfs_iext_get_ext(ifp, lastx); | 4671 | ep = xfs_iext_get_ext(ifp, lastx); |
4712 | nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t); | 4672 | nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t); |
4713 | xfs_bmbt_get_all(ep, &got); | 4673 | xfs_bmbt_get_all(ep, &got); |
@@ -4803,13 +4763,12 @@ xfs_bmapi( | |||
4803 | mval->br_state = (mval->br_state == XFS_EXT_UNWRITTEN) | 4763 | mval->br_state = (mval->br_state == XFS_EXT_UNWRITTEN) |
4804 | ? XFS_EXT_NORM | 4764 | ? XFS_EXT_NORM |
4805 | : XFS_EXT_UNWRITTEN; | 4765 | : XFS_EXT_UNWRITTEN; |
4806 | error = xfs_bmap_add_extent(ip, lastx, &cur, mval, | 4766 | error = xfs_bmap_add_extent(ip, &lastx, &cur, mval, |
4807 | firstblock, flist, &tmp_logflags, | 4767 | firstblock, flist, &tmp_logflags, |
4808 | whichfork, (flags & XFS_BMAPI_RSVBLOCKS)); | 4768 | whichfork); |
4809 | logflags |= tmp_logflags; | 4769 | logflags |= tmp_logflags; |
4810 | if (error) | 4770 | if (error) |
4811 | goto error0; | 4771 | goto error0; |
4812 | lastx = ifp->if_lastex; | ||
4813 | ep = xfs_iext_get_ext(ifp, lastx); | 4772 | ep = xfs_iext_get_ext(ifp, lastx); |
4814 | nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t); | 4773 | nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t); |
4815 | xfs_bmbt_get_all(ep, &got); | 4774 | xfs_bmbt_get_all(ep, &got); |
@@ -4868,14 +4827,14 @@ xfs_bmapi( | |||
4868 | /* | 4827 | /* |
4869 | * Else go on to the next record. | 4828 | * Else go on to the next record. |
4870 | */ | 4829 | */ |
4871 | ep = xfs_iext_get_ext(ifp, ++lastx); | ||
4872 | prev = got; | 4830 | prev = got; |
4873 | if (lastx >= nextents) | 4831 | if (++lastx < nextents) { |
4874 | eof = 1; | 4832 | ep = xfs_iext_get_ext(ifp, lastx); |
4875 | else | ||
4876 | xfs_bmbt_get_all(ep, &got); | 4833 | xfs_bmbt_get_all(ep, &got); |
4834 | } else { | ||
4835 | eof = 1; | ||
4836 | } | ||
4877 | } | 4837 | } |
4878 | ifp->if_lastex = lastx; | ||
4879 | *nmap = n; | 4838 | *nmap = n; |
4880 | /* | 4839 | /* |
4881 | * Transform from btree to extents, give it cur. | 4840 | * Transform from btree to extents, give it cur. |
@@ -4984,7 +4943,6 @@ xfs_bmapi_single( | |||
4984 | ASSERT(!isnullstartblock(got.br_startblock)); | 4943 | ASSERT(!isnullstartblock(got.br_startblock)); |
4985 | ASSERT(bno < got.br_startoff + got.br_blockcount); | 4944 | ASSERT(bno < got.br_startoff + got.br_blockcount); |
4986 | *fsb = got.br_startblock + (bno - got.br_startoff); | 4945 | *fsb = got.br_startblock + (bno - got.br_startoff); |
4987 | ifp->if_lastex = lastx; | ||
4988 | return 0; | 4946 | return 0; |
4989 | } | 4947 | } |
4990 | 4948 | ||
@@ -5026,7 +4984,6 @@ xfs_bunmapi( | |||
5026 | int tmp_logflags; /* partial logging flags */ | 4984 | int tmp_logflags; /* partial logging flags */ |
5027 | int wasdel; /* was a delayed alloc extent */ | 4985 | int wasdel; /* was a delayed alloc extent */ |
5028 | int whichfork; /* data or attribute fork */ | 4986 | int whichfork; /* data or attribute fork */ |
5029 | int rsvd; /* OK to allocate reserved blocks */ | ||
5030 | xfs_fsblock_t sum; | 4987 | xfs_fsblock_t sum; |
5031 | 4988 | ||
5032 | trace_xfs_bunmap(ip, bno, len, flags, _RET_IP_); | 4989 | trace_xfs_bunmap(ip, bno, len, flags, _RET_IP_); |
@@ -5044,7 +5001,7 @@ xfs_bunmapi( | |||
5044 | mp = ip->i_mount; | 5001 | mp = ip->i_mount; |
5045 | if (XFS_FORCED_SHUTDOWN(mp)) | 5002 | if (XFS_FORCED_SHUTDOWN(mp)) |
5046 | return XFS_ERROR(EIO); | 5003 | return XFS_ERROR(EIO); |
5047 | rsvd = (flags & XFS_BMAPI_RSVBLOCKS) != 0; | 5004 | |
5048 | ASSERT(len > 0); | 5005 | ASSERT(len > 0); |
5049 | ASSERT(nexts >= 0); | 5006 | ASSERT(nexts >= 0); |
5050 | ASSERT(ifp->if_ext_max == | 5007 | ASSERT(ifp->if_ext_max == |
@@ -5160,9 +5117,9 @@ xfs_bunmapi( | |||
5160 | del.br_blockcount = mod; | 5117 | del.br_blockcount = mod; |
5161 | } | 5118 | } |
5162 | del.br_state = XFS_EXT_UNWRITTEN; | 5119 | del.br_state = XFS_EXT_UNWRITTEN; |
5163 | error = xfs_bmap_add_extent(ip, lastx, &cur, &del, | 5120 | error = xfs_bmap_add_extent(ip, &lastx, &cur, &del, |
5164 | firstblock, flist, &logflags, | 5121 | firstblock, flist, &logflags, |
5165 | XFS_DATA_FORK, 0); | 5122 | XFS_DATA_FORK); |
5166 | if (error) | 5123 | if (error) |
5167 | goto error0; | 5124 | goto error0; |
5168 | goto nodelete; | 5125 | goto nodelete; |
@@ -5188,9 +5145,12 @@ xfs_bunmapi( | |||
5188 | */ | 5145 | */ |
5189 | ASSERT(bno >= del.br_blockcount); | 5146 | ASSERT(bno >= del.br_blockcount); |
5190 | bno -= del.br_blockcount; | 5147 | bno -= del.br_blockcount; |
5191 | if (bno < got.br_startoff) { | 5148 | if (got.br_startoff > bno) { |
5192 | if (--lastx >= 0) | 5149 | if (--lastx >= 0) { |
5193 | xfs_bmbt_get_all(--ep, &got); | 5150 | ep = xfs_iext_get_ext(ifp, |
5151 | lastx); | ||
5152 | xfs_bmbt_get_all(ep, &got); | ||
5153 | } | ||
5194 | } | 5154 | } |
5195 | continue; | 5155 | continue; |
5196 | } else if (del.br_state == XFS_EXT_UNWRITTEN) { | 5156 | } else if (del.br_state == XFS_EXT_UNWRITTEN) { |
@@ -5214,18 +5174,19 @@ xfs_bunmapi( | |||
5214 | prev.br_startoff = start; | 5174 | prev.br_startoff = start; |
5215 | } | 5175 | } |
5216 | prev.br_state = XFS_EXT_UNWRITTEN; | 5176 | prev.br_state = XFS_EXT_UNWRITTEN; |
5217 | error = xfs_bmap_add_extent(ip, lastx - 1, &cur, | 5177 | lastx--; |
5178 | error = xfs_bmap_add_extent(ip, &lastx, &cur, | ||
5218 | &prev, firstblock, flist, &logflags, | 5179 | &prev, firstblock, flist, &logflags, |
5219 | XFS_DATA_FORK, 0); | 5180 | XFS_DATA_FORK); |
5220 | if (error) | 5181 | if (error) |
5221 | goto error0; | 5182 | goto error0; |
5222 | goto nodelete; | 5183 | goto nodelete; |
5223 | } else { | 5184 | } else { |
5224 | ASSERT(del.br_state == XFS_EXT_NORM); | 5185 | ASSERT(del.br_state == XFS_EXT_NORM); |
5225 | del.br_state = XFS_EXT_UNWRITTEN; | 5186 | del.br_state = XFS_EXT_UNWRITTEN; |
5226 | error = xfs_bmap_add_extent(ip, lastx, &cur, | 5187 | error = xfs_bmap_add_extent(ip, &lastx, &cur, |
5227 | &del, firstblock, flist, &logflags, | 5188 | &del, firstblock, flist, &logflags, |
5228 | XFS_DATA_FORK, 0); | 5189 | XFS_DATA_FORK); |
5229 | if (error) | 5190 | if (error) |
5230 | goto error0; | 5191 | goto error0; |
5231 | goto nodelete; | 5192 | goto nodelete; |
@@ -5240,13 +5201,13 @@ xfs_bunmapi( | |||
5240 | rtexts = XFS_FSB_TO_B(mp, del.br_blockcount); | 5201 | rtexts = XFS_FSB_TO_B(mp, del.br_blockcount); |
5241 | do_div(rtexts, mp->m_sb.sb_rextsize); | 5202 | do_div(rtexts, mp->m_sb.sb_rextsize); |
5242 | xfs_mod_incore_sb(mp, XFS_SBS_FREXTENTS, | 5203 | xfs_mod_incore_sb(mp, XFS_SBS_FREXTENTS, |
5243 | (int64_t)rtexts, rsvd); | 5204 | (int64_t)rtexts, 0); |
5244 | (void)xfs_trans_reserve_quota_nblks(NULL, | 5205 | (void)xfs_trans_reserve_quota_nblks(NULL, |
5245 | ip, -((long)del.br_blockcount), 0, | 5206 | ip, -((long)del.br_blockcount), 0, |
5246 | XFS_QMOPT_RES_RTBLKS); | 5207 | XFS_QMOPT_RES_RTBLKS); |
5247 | } else { | 5208 | } else { |
5248 | xfs_icsb_modify_counters(mp, XFS_SBS_FDBLOCKS, | 5209 | xfs_icsb_modify_counters(mp, XFS_SBS_FDBLOCKS, |
5249 | (int64_t)del.br_blockcount, rsvd); | 5210 | (int64_t)del.br_blockcount, 0); |
5250 | (void)xfs_trans_reserve_quota_nblks(NULL, | 5211 | (void)xfs_trans_reserve_quota_nblks(NULL, |
5251 | ip, -((long)del.br_blockcount), 0, | 5212 | ip, -((long)del.br_blockcount), 0, |
5252 | XFS_QMOPT_RES_REGBLKS); | 5213 | XFS_QMOPT_RES_REGBLKS); |
@@ -5277,31 +5238,29 @@ xfs_bunmapi( | |||
5277 | error = XFS_ERROR(ENOSPC); | 5238 | error = XFS_ERROR(ENOSPC); |
5278 | goto error0; | 5239 | goto error0; |
5279 | } | 5240 | } |
5280 | error = xfs_bmap_del_extent(ip, tp, lastx, flist, cur, &del, | 5241 | error = xfs_bmap_del_extent(ip, tp, &lastx, flist, cur, &del, |
5281 | &tmp_logflags, whichfork, rsvd); | 5242 | &tmp_logflags, whichfork); |
5282 | logflags |= tmp_logflags; | 5243 | logflags |= tmp_logflags; |
5283 | if (error) | 5244 | if (error) |
5284 | goto error0; | 5245 | goto error0; |
5285 | bno = del.br_startoff - 1; | 5246 | bno = del.br_startoff - 1; |
5286 | nodelete: | 5247 | nodelete: |
5287 | lastx = ifp->if_lastex; | ||
5288 | /* | 5248 | /* |
5289 | * If not done go on to the next (previous) record. | 5249 | * If not done go on to the next (previous) record. |
5290 | * Reset ep in case the extents array was re-alloced. | ||
5291 | */ | 5250 | */ |
5292 | ep = xfs_iext_get_ext(ifp, lastx); | ||
5293 | if (bno != (xfs_fileoff_t)-1 && bno >= start) { | 5251 | if (bno != (xfs_fileoff_t)-1 && bno >= start) { |
5294 | if (lastx >= XFS_IFORK_NEXTENTS(ip, whichfork) || | 5252 | if (lastx >= 0) { |
5295 | xfs_bmbt_get_startoff(ep) > bno) { | 5253 | ep = xfs_iext_get_ext(ifp, lastx); |
5296 | if (--lastx >= 0) | 5254 | if (xfs_bmbt_get_startoff(ep) > bno) { |
5297 | ep = xfs_iext_get_ext(ifp, lastx); | 5255 | if (--lastx >= 0) |
5298 | } | 5256 | ep = xfs_iext_get_ext(ifp, |
5299 | if (lastx >= 0) | 5257 | lastx); |
5258 | } | ||
5300 | xfs_bmbt_get_all(ep, &got); | 5259 | xfs_bmbt_get_all(ep, &got); |
5260 | } | ||
5301 | extno++; | 5261 | extno++; |
5302 | } | 5262 | } |
5303 | } | 5263 | } |
5304 | ifp->if_lastex = lastx; | ||
5305 | *done = bno == (xfs_fileoff_t)-1 || bno < start || lastx < 0; | 5264 | *done = bno == (xfs_fileoff_t)-1 || bno < start || lastx < 0; |
5306 | ASSERT(ifp->if_ext_max == | 5265 | ASSERT(ifp->if_ext_max == |
5307 | XFS_IFORK_SIZE(ip, whichfork) / (uint)sizeof(xfs_bmbt_rec_t)); | 5266 | XFS_IFORK_SIZE(ip, whichfork) / (uint)sizeof(xfs_bmbt_rec_t)); |
diff --git a/fs/xfs/xfs_bmap.h b/fs/xfs/xfs_bmap.h index 3651191daea1..c62234bde053 100644 --- a/fs/xfs/xfs_bmap.h +++ b/fs/xfs/xfs_bmap.h | |||
@@ -69,7 +69,6 @@ typedef struct xfs_bmap_free | |||
69 | #define XFS_BMAPI_ENTIRE 0x004 /* return entire extent, not trimmed */ | 69 | #define XFS_BMAPI_ENTIRE 0x004 /* return entire extent, not trimmed */ |
70 | #define XFS_BMAPI_METADATA 0x008 /* mapping metadata not user data */ | 70 | #define XFS_BMAPI_METADATA 0x008 /* mapping metadata not user data */ |
71 | #define XFS_BMAPI_ATTRFORK 0x010 /* use attribute fork not data */ | 71 | #define XFS_BMAPI_ATTRFORK 0x010 /* use attribute fork not data */ |
72 | #define XFS_BMAPI_RSVBLOCKS 0x020 /* OK to alloc. reserved data blocks */ | ||
73 | #define XFS_BMAPI_PREALLOC 0x040 /* preallocation op: unwritten space */ | 72 | #define XFS_BMAPI_PREALLOC 0x040 /* preallocation op: unwritten space */ |
74 | #define XFS_BMAPI_IGSTATE 0x080 /* Ignore state - */ | 73 | #define XFS_BMAPI_IGSTATE 0x080 /* Ignore state - */ |
75 | /* combine contig. space */ | 74 | /* combine contig. space */ |
@@ -87,7 +86,6 @@ typedef struct xfs_bmap_free | |||
87 | { XFS_BMAPI_ENTIRE, "ENTIRE" }, \ | 86 | { XFS_BMAPI_ENTIRE, "ENTIRE" }, \ |
88 | { XFS_BMAPI_METADATA, "METADATA" }, \ | 87 | { XFS_BMAPI_METADATA, "METADATA" }, \ |
89 | { XFS_BMAPI_ATTRFORK, "ATTRFORK" }, \ | 88 | { XFS_BMAPI_ATTRFORK, "ATTRFORK" }, \ |
90 | { XFS_BMAPI_RSVBLOCKS, "RSVBLOCKS" }, \ | ||
91 | { XFS_BMAPI_PREALLOC, "PREALLOC" }, \ | 89 | { XFS_BMAPI_PREALLOC, "PREALLOC" }, \ |
92 | { XFS_BMAPI_IGSTATE, "IGSTATE" }, \ | 90 | { XFS_BMAPI_IGSTATE, "IGSTATE" }, \ |
93 | { XFS_BMAPI_CONTIG, "CONTIG" }, \ | 91 | { XFS_BMAPI_CONTIG, "CONTIG" }, \ |
diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c index c8e3349c287c..a098a20ca63e 100644 --- a/fs/xfs/xfs_inode.c +++ b/fs/xfs/xfs_inode.c | |||
@@ -920,7 +920,6 @@ xfs_iread_extents( | |||
920 | /* | 920 | /* |
921 | * We know that the size is valid (it's checked in iformat_btree) | 921 | * We know that the size is valid (it's checked in iformat_btree) |
922 | */ | 922 | */ |
923 | ifp->if_lastex = NULLEXTNUM; | ||
924 | ifp->if_bytes = ifp->if_real_bytes = 0; | 923 | ifp->if_bytes = ifp->if_real_bytes = 0; |
925 | ifp->if_flags |= XFS_IFEXTENTS; | 924 | ifp->if_flags |= XFS_IFEXTENTS; |
926 | xfs_iext_add(ifp, 0, nextents); | 925 | xfs_iext_add(ifp, 0, nextents); |
@@ -2558,12 +2557,9 @@ xfs_iflush_fork( | |||
2558 | case XFS_DINODE_FMT_EXTENTS: | 2557 | case XFS_DINODE_FMT_EXTENTS: |
2559 | ASSERT((ifp->if_flags & XFS_IFEXTENTS) || | 2558 | ASSERT((ifp->if_flags & XFS_IFEXTENTS) || |
2560 | !(iip->ili_format.ilf_fields & extflag[whichfork])); | 2559 | !(iip->ili_format.ilf_fields & extflag[whichfork])); |
2561 | ASSERT((xfs_iext_get_ext(ifp, 0) != NULL) || | ||
2562 | (ifp->if_bytes == 0)); | ||
2563 | ASSERT((xfs_iext_get_ext(ifp, 0) == NULL) || | ||
2564 | (ifp->if_bytes > 0)); | ||
2565 | if ((iip->ili_format.ilf_fields & extflag[whichfork]) && | 2560 | if ((iip->ili_format.ilf_fields & extflag[whichfork]) && |
2566 | (ifp->if_bytes > 0)) { | 2561 | (ifp->if_bytes > 0)) { |
2562 | ASSERT(xfs_iext_get_ext(ifp, 0)); | ||
2567 | ASSERT(XFS_IFORK_NEXTENTS(ip, whichfork) > 0); | 2563 | ASSERT(XFS_IFORK_NEXTENTS(ip, whichfork) > 0); |
2568 | (void)xfs_iextents_copy(ip, (xfs_bmbt_rec_t *)cp, | 2564 | (void)xfs_iextents_copy(ip, (xfs_bmbt_rec_t *)cp, |
2569 | whichfork); | 2565 | whichfork); |
@@ -3112,6 +3108,8 @@ xfs_iext_get_ext( | |||
3112 | xfs_extnum_t idx) /* index of target extent */ | 3108 | xfs_extnum_t idx) /* index of target extent */ |
3113 | { | 3109 | { |
3114 | ASSERT(idx >= 0); | 3110 | ASSERT(idx >= 0); |
3111 | ASSERT(idx < ifp->if_bytes / sizeof(xfs_bmbt_rec_t)); | ||
3112 | |||
3115 | if ((ifp->if_flags & XFS_IFEXTIREC) && (idx == 0)) { | 3113 | if ((ifp->if_flags & XFS_IFEXTIREC) && (idx == 0)) { |
3116 | return ifp->if_u1.if_ext_irec->er_extbuf; | 3114 | return ifp->if_u1.if_ext_irec->er_extbuf; |
3117 | } else if (ifp->if_flags & XFS_IFEXTIREC) { | 3115 | } else if (ifp->if_flags & XFS_IFEXTIREC) { |
@@ -3191,7 +3189,6 @@ xfs_iext_add( | |||
3191 | } | 3189 | } |
3192 | ifp->if_u1.if_extents = ifp->if_u2.if_inline_ext; | 3190 | ifp->if_u1.if_extents = ifp->if_u2.if_inline_ext; |
3193 | ifp->if_real_bytes = 0; | 3191 | ifp->if_real_bytes = 0; |
3194 | ifp->if_lastex = nextents + ext_diff; | ||
3195 | } | 3192 | } |
3196 | /* | 3193 | /* |
3197 | * Otherwise use a linear (direct) extent list. | 3194 | * Otherwise use a linear (direct) extent list. |
@@ -3886,8 +3883,10 @@ xfs_iext_idx_to_irec( | |||
3886 | xfs_extnum_t page_idx = *idxp; /* extent index in target list */ | 3883 | xfs_extnum_t page_idx = *idxp; /* extent index in target list */ |
3887 | 3884 | ||
3888 | ASSERT(ifp->if_flags & XFS_IFEXTIREC); | 3885 | ASSERT(ifp->if_flags & XFS_IFEXTIREC); |
3889 | ASSERT(page_idx >= 0 && page_idx <= | 3886 | ASSERT(page_idx >= 0); |
3890 | ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t)); | 3887 | ASSERT(page_idx <= ifp->if_bytes / sizeof(xfs_bmbt_rec_t)); |
3888 | ASSERT(page_idx < ifp->if_bytes / sizeof(xfs_bmbt_rec_t) || realloc); | ||
3889 | |||
3891 | nlists = ifp->if_real_bytes / XFS_IEXT_BUFSZ; | 3890 | nlists = ifp->if_real_bytes / XFS_IEXT_BUFSZ; |
3892 | erp_idx = 0; | 3891 | erp_idx = 0; |
3893 | low = 0; | 3892 | low = 0; |
diff --git a/fs/xfs/xfs_inode.h b/fs/xfs/xfs_inode.h index ff4e2a30227d..3ae6d58e5473 100644 --- a/fs/xfs/xfs_inode.h +++ b/fs/xfs/xfs_inode.h | |||
@@ -67,7 +67,6 @@ typedef struct xfs_ifork { | |||
67 | short if_broot_bytes; /* bytes allocated for root */ | 67 | short if_broot_bytes; /* bytes allocated for root */ |
68 | unsigned char if_flags; /* per-fork flags */ | 68 | unsigned char if_flags; /* per-fork flags */ |
69 | unsigned char if_ext_max; /* max # of extent records */ | 69 | unsigned char if_ext_max; /* max # of extent records */ |
70 | xfs_extnum_t if_lastex; /* last if_extents used */ | ||
71 | union { | 70 | union { |
72 | xfs_bmbt_rec_host_t *if_extents;/* linear map file exts */ | 71 | xfs_bmbt_rec_host_t *if_extents;/* linear map file exts */ |
73 | xfs_ext_irec_t *if_ext_irec; /* irec map file exts */ | 72 | xfs_ext_irec_t *if_ext_irec; /* irec map file exts */ |
diff --git a/fs/xfs/xfs_log_cil.c b/fs/xfs/xfs_log_cil.c index 7d56e88a3f0e..c7755d5a5fbe 100644 --- a/fs/xfs/xfs_log_cil.c +++ b/fs/xfs/xfs_log_cil.c | |||
@@ -29,6 +29,7 @@ | |||
29 | #include "xfs_mount.h" | 29 | #include "xfs_mount.h" |
30 | #include "xfs_error.h" | 30 | #include "xfs_error.h" |
31 | #include "xfs_alloc.h" | 31 | #include "xfs_alloc.h" |
32 | #include "xfs_discard.h" | ||
32 | 33 | ||
33 | /* | 34 | /* |
34 | * Perform initial CIL structure initialisation. If the CIL is not | 35 | * Perform initial CIL structure initialisation. If the CIL is not |
@@ -361,18 +362,28 @@ xlog_cil_committed( | |||
361 | int abort) | 362 | int abort) |
362 | { | 363 | { |
363 | struct xfs_cil_ctx *ctx = args; | 364 | struct xfs_cil_ctx *ctx = args; |
365 | struct xfs_mount *mp = ctx->cil->xc_log->l_mp; | ||
364 | 366 | ||
365 | xfs_trans_committed_bulk(ctx->cil->xc_log->l_ailp, ctx->lv_chain, | 367 | xfs_trans_committed_bulk(ctx->cil->xc_log->l_ailp, ctx->lv_chain, |
366 | ctx->start_lsn, abort); | 368 | ctx->start_lsn, abort); |
367 | 369 | ||
368 | xfs_alloc_busy_sort(&ctx->busy_extents); | 370 | xfs_alloc_busy_sort(&ctx->busy_extents); |
369 | xfs_alloc_busy_clear(ctx->cil->xc_log->l_mp, &ctx->busy_extents); | 371 | xfs_alloc_busy_clear(mp, &ctx->busy_extents, |
372 | (mp->m_flags & XFS_MOUNT_DISCARD) && !abort); | ||
370 | 373 | ||
371 | spin_lock(&ctx->cil->xc_cil_lock); | 374 | spin_lock(&ctx->cil->xc_cil_lock); |
372 | list_del(&ctx->committing); | 375 | list_del(&ctx->committing); |
373 | spin_unlock(&ctx->cil->xc_cil_lock); | 376 | spin_unlock(&ctx->cil->xc_cil_lock); |
374 | 377 | ||
375 | xlog_cil_free_logvec(ctx->lv_chain); | 378 | xlog_cil_free_logvec(ctx->lv_chain); |
379 | |||
380 | if (!list_empty(&ctx->busy_extents)) { | ||
381 | ASSERT(mp->m_flags & XFS_MOUNT_DISCARD); | ||
382 | |||
383 | xfs_discard_extents(mp, &ctx->busy_extents); | ||
384 | xfs_alloc_busy_clear(mp, &ctx->busy_extents, false); | ||
385 | } | ||
386 | |||
376 | kmem_free(ctx); | 387 | kmem_free(ctx); |
377 | } | 388 | } |
378 | 389 | ||
diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h index 19af0ab0d0c6..3d68bb267c5f 100644 --- a/fs/xfs/xfs_mount.h +++ b/fs/xfs/xfs_mount.h | |||
@@ -224,6 +224,7 @@ typedef struct xfs_mount { | |||
224 | #define XFS_MOUNT_FS_SHUTDOWN (1ULL << 4) /* atomic stop of all filesystem | 224 | #define XFS_MOUNT_FS_SHUTDOWN (1ULL << 4) /* atomic stop of all filesystem |
225 | operations, typically for | 225 | operations, typically for |
226 | disk errors in metadata */ | 226 | disk errors in metadata */ |
227 | #define XFS_MOUNT_DISCARD (1ULL << 5) /* discard unused blocks */ | ||
227 | #define XFS_MOUNT_RETERR (1ULL << 6) /* return alignment errors to | 228 | #define XFS_MOUNT_RETERR (1ULL << 6) /* return alignment errors to |
228 | user */ | 229 | user */ |
229 | #define XFS_MOUNT_NOALIGN (1ULL << 7) /* turn off stripe alignment | 230 | #define XFS_MOUNT_NOALIGN (1ULL << 7) /* turn off stripe alignment |
diff --git a/fs/xfs/xfs_trans.c b/fs/xfs/xfs_trans.c index d1f24858ccc4..7c7bc2b786bd 100644 --- a/fs/xfs/xfs_trans.c +++ b/fs/xfs/xfs_trans.c | |||
@@ -609,7 +609,7 @@ xfs_trans_free( | |||
609 | struct xfs_trans *tp) | 609 | struct xfs_trans *tp) |
610 | { | 610 | { |
611 | xfs_alloc_busy_sort(&tp->t_busy); | 611 | xfs_alloc_busy_sort(&tp->t_busy); |
612 | xfs_alloc_busy_clear(tp->t_mountp, &tp->t_busy); | 612 | xfs_alloc_busy_clear(tp->t_mountp, &tp->t_busy, false); |
613 | 613 | ||
614 | atomic_dec(&tp->t_mountp->m_active_trans); | 614 | atomic_dec(&tp->t_mountp->m_active_trans); |
615 | xfs_trans_free_dqinfo(tp); | 615 | xfs_trans_free_dqinfo(tp); |