Merge tag 'selinux-pr-20190115' of git://git.kernel.org/pub/scm/linux/kernel/git...
[sfrench/cifs-2.6.git] / fs / xfs / xfs_trans_extfree.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright (c) 2000,2005 Silicon Graphics, Inc.
4  * All Rights Reserved.
5  */
6 #include "xfs.h"
7 #include "xfs_fs.h"
8 #include "xfs_shared.h"
9 #include "xfs_format.h"
10 #include "xfs_log_format.h"
11 #include "xfs_trans_resv.h"
12 #include "xfs_bit.h"
13 #include "xfs_mount.h"
14 #include "xfs_defer.h"
15 #include "xfs_trans.h"
16 #include "xfs_trans_priv.h"
17 #include "xfs_extfree_item.h"
18 #include "xfs_alloc.h"
19 #include "xfs_bmap.h"
20 #include "xfs_trace.h"
21 #include "xfs_defer.h"
22
23 /*
24  * This routine is called to allocate an "extent free done"
25  * log item that will hold nextents worth of extents.  The
26  * caller must use all nextents extents, because we are not
27  * flexible about this at all.
28  */
29 struct xfs_efd_log_item *
30 xfs_trans_get_efd(struct xfs_trans              *tp,
31                   struct xfs_efi_log_item       *efip,
32                   uint                          nextents)
33 {
34         struct xfs_efd_log_item                 *efdp;
35
36         ASSERT(tp != NULL);
37         ASSERT(nextents > 0);
38
39         efdp = xfs_efd_init(tp->t_mountp, efip, nextents);
40         ASSERT(efdp != NULL);
41
42         /*
43          * Get a log_item_desc to point at the new item.
44          */
45         xfs_trans_add_item(tp, &efdp->efd_item);
46         return efdp;
47 }
48
49 /*
50  * Free an extent and log it to the EFD. Note that the transaction is marked
51  * dirty regardless of whether the extent free succeeds or fails to support the
52  * EFI/EFD lifecycle rules.
53  */
54 int
55 xfs_trans_free_extent(
56         struct xfs_trans                *tp,
57         struct xfs_efd_log_item         *efdp,
58         xfs_fsblock_t                   start_block,
59         xfs_extlen_t                    ext_len,
60         const struct xfs_owner_info     *oinfo,
61         bool                            skip_discard)
62 {
63         struct xfs_mount                *mp = tp->t_mountp;
64         struct xfs_extent               *extp;
65         uint                            next_extent;
66         xfs_agnumber_t                  agno = XFS_FSB_TO_AGNO(mp, start_block);
67         xfs_agblock_t                   agbno = XFS_FSB_TO_AGBNO(mp,
68                                                                 start_block);
69         int                             error;
70
71         trace_xfs_bmap_free_deferred(tp->t_mountp, agno, 0, agbno, ext_len);
72
73         error = __xfs_free_extent(tp, start_block, ext_len,
74                                   oinfo, XFS_AG_RESV_NONE, skip_discard);
75         /*
76          * Mark the transaction dirty, even on error. This ensures the
77          * transaction is aborted, which:
78          *
79          * 1.) releases the EFI and frees the EFD
80          * 2.) shuts down the filesystem
81          */
82         tp->t_flags |= XFS_TRANS_DIRTY;
83         set_bit(XFS_LI_DIRTY, &efdp->efd_item.li_flags);
84
85         next_extent = efdp->efd_next_extent;
86         ASSERT(next_extent < efdp->efd_format.efd_nextents);
87         extp = &(efdp->efd_format.efd_extents[next_extent]);
88         extp->ext_start = start_block;
89         extp->ext_len = ext_len;
90         efdp->efd_next_extent++;
91
92         return error;
93 }
94
95 /* Sort bmap items by AG. */
96 static int
97 xfs_extent_free_diff_items(
98         void                            *priv,
99         struct list_head                *a,
100         struct list_head                *b)
101 {
102         struct xfs_mount                *mp = priv;
103         struct xfs_extent_free_item     *ra;
104         struct xfs_extent_free_item     *rb;
105
106         ra = container_of(a, struct xfs_extent_free_item, xefi_list);
107         rb = container_of(b, struct xfs_extent_free_item, xefi_list);
108         return  XFS_FSB_TO_AGNO(mp, ra->xefi_startblock) -
109                 XFS_FSB_TO_AGNO(mp, rb->xefi_startblock);
110 }
111
112 /* Get an EFI. */
113 STATIC void *
114 xfs_extent_free_create_intent(
115         struct xfs_trans                *tp,
116         unsigned int                    count)
117 {
118         struct xfs_efi_log_item         *efip;
119
120         ASSERT(tp != NULL);
121         ASSERT(count > 0);
122
123         efip = xfs_efi_init(tp->t_mountp, count);
124         ASSERT(efip != NULL);
125
126         /*
127          * Get a log_item_desc to point at the new item.
128          */
129         xfs_trans_add_item(tp, &efip->efi_item);
130         return efip;
131 }
132
133 /* Log a free extent to the intent item. */
134 STATIC void
135 xfs_extent_free_log_item(
136         struct xfs_trans                *tp,
137         void                            *intent,
138         struct list_head                *item)
139 {
140         struct xfs_efi_log_item         *efip = intent;
141         struct xfs_extent_free_item     *free;
142         uint                            next_extent;
143         struct xfs_extent               *extp;
144
145         free = container_of(item, struct xfs_extent_free_item, xefi_list);
146
147         tp->t_flags |= XFS_TRANS_DIRTY;
148         set_bit(XFS_LI_DIRTY, &efip->efi_item.li_flags);
149
150         /*
151          * atomic_inc_return gives us the value after the increment;
152          * we want to use it as an array index so we need to subtract 1 from
153          * it.
154          */
155         next_extent = atomic_inc_return(&efip->efi_next_extent) - 1;
156         ASSERT(next_extent < efip->efi_format.efi_nextents);
157         extp = &efip->efi_format.efi_extents[next_extent];
158         extp->ext_start = free->xefi_startblock;
159         extp->ext_len = free->xefi_blockcount;
160 }
161
162 /* Get an EFD so we can process all the free extents. */
163 STATIC void *
164 xfs_extent_free_create_done(
165         struct xfs_trans                *tp,
166         void                            *intent,
167         unsigned int                    count)
168 {
169         return xfs_trans_get_efd(tp, intent, count);
170 }
171
172 /* Process a free extent. */
173 STATIC int
174 xfs_extent_free_finish_item(
175         struct xfs_trans                *tp,
176         struct list_head                *item,
177         void                            *done_item,
178         void                            **state)
179 {
180         struct xfs_extent_free_item     *free;
181         int                             error;
182
183         free = container_of(item, struct xfs_extent_free_item, xefi_list);
184         error = xfs_trans_free_extent(tp, done_item,
185                         free->xefi_startblock,
186                         free->xefi_blockcount,
187                         &free->xefi_oinfo, free->xefi_skip_discard);
188         kmem_free(free);
189         return error;
190 }
191
192 /* Abort all pending EFIs. */
193 STATIC void
194 xfs_extent_free_abort_intent(
195         void                            *intent)
196 {
197         xfs_efi_release(intent);
198 }
199
200 /* Cancel a free extent. */
201 STATIC void
202 xfs_extent_free_cancel_item(
203         struct list_head                *item)
204 {
205         struct xfs_extent_free_item     *free;
206
207         free = container_of(item, struct xfs_extent_free_item, xefi_list);
208         kmem_free(free);
209 }
210
211 const struct xfs_defer_op_type xfs_extent_free_defer_type = {
212         .max_items      = XFS_EFI_MAX_FAST_EXTENTS,
213         .diff_items     = xfs_extent_free_diff_items,
214         .create_intent  = xfs_extent_free_create_intent,
215         .abort_intent   = xfs_extent_free_abort_intent,
216         .log_item       = xfs_extent_free_log_item,
217         .create_done    = xfs_extent_free_create_done,
218         .finish_item    = xfs_extent_free_finish_item,
219         .cancel_item    = xfs_extent_free_cancel_item,
220 };
221
222 /*
223  * AGFL blocks are accounted differently in the reserve pools and are not
224  * inserted into the busy extent list.
225  */
226 STATIC int
227 xfs_agfl_free_finish_item(
228         struct xfs_trans                *tp,
229         struct list_head                *item,
230         void                            *done_item,
231         void                            **state)
232 {
233         struct xfs_mount                *mp = tp->t_mountp;
234         struct xfs_efd_log_item         *efdp = done_item;
235         struct xfs_extent_free_item     *free;
236         struct xfs_extent               *extp;
237         struct xfs_buf                  *agbp;
238         int                             error;
239         xfs_agnumber_t                  agno;
240         xfs_agblock_t                   agbno;
241         uint                            next_extent;
242
243         free = container_of(item, struct xfs_extent_free_item, xefi_list);
244         ASSERT(free->xefi_blockcount == 1);
245         agno = XFS_FSB_TO_AGNO(mp, free->xefi_startblock);
246         agbno = XFS_FSB_TO_AGBNO(mp, free->xefi_startblock);
247
248         trace_xfs_agfl_free_deferred(mp, agno, 0, agbno, free->xefi_blockcount);
249
250         error = xfs_alloc_read_agf(mp, tp, agno, 0, &agbp);
251         if (!error)
252                 error = xfs_free_agfl_block(tp, agno, agbno, agbp,
253                                             &free->xefi_oinfo);
254
255         /*
256          * Mark the transaction dirty, even on error. This ensures the
257          * transaction is aborted, which:
258          *
259          * 1.) releases the EFI and frees the EFD
260          * 2.) shuts down the filesystem
261          */
262         tp->t_flags |= XFS_TRANS_DIRTY;
263         set_bit(XFS_LI_DIRTY, &efdp->efd_item.li_flags);
264
265         next_extent = efdp->efd_next_extent;
266         ASSERT(next_extent < efdp->efd_format.efd_nextents);
267         extp = &(efdp->efd_format.efd_extents[next_extent]);
268         extp->ext_start = free->xefi_startblock;
269         extp->ext_len = free->xefi_blockcount;
270         efdp->efd_next_extent++;
271
272         kmem_free(free);
273         return error;
274 }
275
276
277 /* sub-type with special handling for AGFL deferred frees */
278 const struct xfs_defer_op_type xfs_agfl_free_defer_type = {
279         .max_items      = XFS_EFI_MAX_FAST_EXTENTS,
280         .diff_items     = xfs_extent_free_diff_items,
281         .create_intent  = xfs_extent_free_create_intent,
282         .abort_intent   = xfs_extent_free_abort_intent,
283         .log_item       = xfs_extent_free_log_item,
284         .create_done    = xfs_extent_free_create_done,
285         .finish_item    = xfs_agfl_free_finish_item,
286         .cancel_item    = xfs_extent_free_cancel_item,
287 };