]> git.karo-electronics.de Git - karo-tx-linux.git/blob - fs/xfs/xfs_trans_item.c
[XFS] Remove xfs_macros.c, xfs_macros.h, rework headers a whole lot.
[karo-tx-linux.git] / fs / xfs / xfs_trans_item.c
1 /*
2  * Copyright (c) 2000-2002 Silicon Graphics, Inc.  All Rights Reserved.
3  *
4  * This program is free software; you can redistribute it and/or modify it
5  * under the terms of version 2 of the GNU General Public License as
6  * published by the Free Software Foundation.
7  *
8  * This program is distributed in the hope that it would be useful, but
9  * WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11  *
12  * Further, this software is distributed without any warranty that it is
13  * free of the rightful claim of any third person regarding infringement
14  * or the like.  Any license provided herein, whether implied or
15  * otherwise, applies only to this software file.  Patent licenses, if
16  * any, provided herein do not apply to combinations of this program with
17  * other software, or any other product whatsoever.
18  *
19  * You should have received a copy of the GNU General Public License along
20  * with this program; if not, write the Free Software Foundation, Inc., 59
21  * Temple Place - Suite 330, Boston MA 02111-1307, USA.
22  *
23  * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
24  * Mountain View, CA  94043, or:
25  *
26  * http://www.sgi.com
27  *
28  * For further information regarding this notice, see:
29  *
30  * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
31  */
32 #include "xfs.h"
33 #include "xfs_fs.h"
34 #include "xfs_types.h"
35 #include "xfs_log.h"
36 #include "xfs_inum.h"
37 #include "xfs_trans.h"
38
39 STATIC int      xfs_trans_unlock_chunk(xfs_log_item_chunk_t *,
40                                         int, int, xfs_lsn_t);
41
42 /*
43  * This is called to add the given log item to the transaction's
44  * list of log items.  It must find a free log item descriptor
45  * or allocate a new one and add the item to that descriptor.
46  * The function returns a pointer to item descriptor used to point
47  * to the new item.  The log item will now point to its new descriptor
48  * with its li_desc field.
49  */
50 xfs_log_item_desc_t *
51 xfs_trans_add_item(xfs_trans_t *tp, xfs_log_item_t *lip)
52 {
53         xfs_log_item_desc_t     *lidp;
54         xfs_log_item_chunk_t    *licp;
55         int                     i=0;
56
57         /*
58          * If there are no free descriptors, allocate a new chunk
59          * of them and put it at the front of the chunk list.
60          */
61         if (tp->t_items_free == 0) {
62                 licp = (xfs_log_item_chunk_t*)
63                        kmem_alloc(sizeof(xfs_log_item_chunk_t), KM_SLEEP);
64                 ASSERT(licp != NULL);
65                 /*
66                  * Initialize the chunk, and then
67                  * claim the first slot in the newly allocated chunk.
68                  */
69                 XFS_LIC_INIT(licp);
70                 XFS_LIC_CLAIM(licp, 0);
71                 licp->lic_unused = 1;
72                 XFS_LIC_INIT_SLOT(licp, 0);
73                 lidp = XFS_LIC_SLOT(licp, 0);
74
75                 /*
76                  * Link in the new chunk and update the free count.
77                  */
78                 licp->lic_next = tp->t_items.lic_next;
79                 tp->t_items.lic_next = licp;
80                 tp->t_items_free = XFS_LIC_NUM_SLOTS - 1;
81
82                 /*
83                  * Initialize the descriptor and the generic portion
84                  * of the log item.
85                  *
86                  * Point the new slot at this item and return it.
87                  * Also point the log item at its currently active
88                  * descriptor and set the item's mount pointer.
89                  */
90                 lidp->lid_item = lip;
91                 lidp->lid_flags = 0;
92                 lidp->lid_size = 0;
93                 lip->li_desc = lidp;
94                 lip->li_mountp = tp->t_mountp;
95                 return (lidp);
96         }
97
98         /*
99          * Find the free descriptor. It is somewhere in the chunklist
100          * of descriptors.
101          */
102         licp = &tp->t_items;
103         while (licp != NULL) {
104                 if (XFS_LIC_VACANCY(licp)) {
105                         if (licp->lic_unused <= XFS_LIC_MAX_SLOT) {
106                                 i = licp->lic_unused;
107                                 ASSERT(XFS_LIC_ISFREE(licp, i));
108                                 break;
109                         }
110                         for (i = 0; i <= XFS_LIC_MAX_SLOT; i++) {
111                                 if (XFS_LIC_ISFREE(licp, i))
112                                         break;
113                         }
114                         ASSERT(i <= XFS_LIC_MAX_SLOT);
115                         break;
116                 }
117                 licp = licp->lic_next;
118         }
119         ASSERT(licp != NULL);
120         /*
121          * If we find a free descriptor, claim it,
122          * initialize it, and return it.
123          */
124         XFS_LIC_CLAIM(licp, i);
125         if (licp->lic_unused <= i) {
126                 licp->lic_unused = i + 1;
127                 XFS_LIC_INIT_SLOT(licp, i);
128         }
129         lidp = XFS_LIC_SLOT(licp, i);
130         tp->t_items_free--;
131         lidp->lid_item = lip;
132         lidp->lid_flags = 0;
133         lidp->lid_size = 0;
134         lip->li_desc = lidp;
135         lip->li_mountp = tp->t_mountp;
136         return (lidp);
137 }
138
139 /*
140  * Free the given descriptor.
141  *
142  * This requires setting the bit in the chunk's free mask corresponding
143  * to the given slot.
144  */
145 void
146 xfs_trans_free_item(xfs_trans_t *tp, xfs_log_item_desc_t *lidp)
147 {
148         uint                    slot;
149         xfs_log_item_chunk_t    *licp;
150         xfs_log_item_chunk_t    **licpp;
151
152         slot = XFS_LIC_DESC_TO_SLOT(lidp);
153         licp = XFS_LIC_DESC_TO_CHUNK(lidp);
154         XFS_LIC_RELSE(licp, slot);
155         lidp->lid_item->li_desc = NULL;
156         tp->t_items_free++;
157
158         /*
159          * If there are no more used items in the chunk and this is not
160          * the chunk embedded in the transaction structure, then free
161          * the chunk. First pull it from the chunk list and then
162          * free it back to the heap.  We didn't bother with a doubly
163          * linked list here because the lists should be very short
164          * and this is not a performance path.  It's better to save
165          * the memory of the extra pointer.
166          *
167          * Also decrement the transaction structure's count of free items
168          * by the number in a chunk since we are freeing an empty chunk.
169          */
170         if (XFS_LIC_ARE_ALL_FREE(licp) && (licp != &(tp->t_items))) {
171                 licpp = &(tp->t_items.lic_next);
172                 while (*licpp != licp) {
173                         ASSERT(*licpp != NULL);
174                         licpp = &((*licpp)->lic_next);
175                 }
176                 *licpp = licp->lic_next;
177                 kmem_free(licp, sizeof(xfs_log_item_chunk_t));
178                 tp->t_items_free -= XFS_LIC_NUM_SLOTS;
179         }
180 }
181
182 /*
183  * This is called to find the descriptor corresponding to the given
184  * log item.  It returns a pointer to the descriptor.
185  * The log item MUST have a corresponding descriptor in the given
186  * transaction.  This routine does not return NULL, it panics.
187  *
188  * The descriptor pointer is kept in the log item's li_desc field.
189  * Just return it.
190  */
191 /*ARGSUSED*/
192 xfs_log_item_desc_t *
193 xfs_trans_find_item(xfs_trans_t *tp, xfs_log_item_t *lip)
194 {
195         ASSERT(lip->li_desc != NULL);
196
197         return (lip->li_desc);
198 }
199
200
201 /*
202  * Return a pointer to the first descriptor in the chunk list.
203  * This does not return NULL if there are none, it panics.
204  *
205  * The first descriptor must be in either the first or second chunk.
206  * This is because the only chunk allowed to be empty is the first.
207  * All others are freed when they become empty.
208  *
209  * At some point this and xfs_trans_next_item() should be optimized
210  * to quickly look at the mask to determine if there is anything to
211  * look at.
212  */
213 xfs_log_item_desc_t *
214 xfs_trans_first_item(xfs_trans_t *tp)
215 {
216         xfs_log_item_chunk_t    *licp;
217         int                     i;
218
219         licp = &tp->t_items;
220         /*
221          * If it's not in the first chunk, skip to the second.
222          */
223         if (XFS_LIC_ARE_ALL_FREE(licp)) {
224                 licp = licp->lic_next;
225         }
226
227         /*
228          * Return the first non-free descriptor in the chunk.
229          */
230         ASSERT(!XFS_LIC_ARE_ALL_FREE(licp));
231         for (i = 0; i < licp->lic_unused; i++) {
232                 if (XFS_LIC_ISFREE(licp, i)) {
233                         continue;
234                 }
235
236                 return (XFS_LIC_SLOT(licp, i));
237         }
238         cmn_err(CE_WARN, "xfs_trans_first_item() -- no first item");
239         return(NULL);
240 }
241
242
243 /*
244  * Given a descriptor, return the next descriptor in the chunk list.
245  * This returns NULL if there are no more used descriptors in the list.
246  *
247  * We do this by first locating the chunk in which the descriptor resides,
248  * and then scanning forward in the chunk and the list for the next
249  * used descriptor.
250  */
251 /*ARGSUSED*/
252 xfs_log_item_desc_t *
253 xfs_trans_next_item(xfs_trans_t *tp, xfs_log_item_desc_t *lidp)
254 {
255         xfs_log_item_chunk_t    *licp;
256         int                     i;
257
258         licp = XFS_LIC_DESC_TO_CHUNK(lidp);
259
260         /*
261          * First search the rest of the chunk. The for loop keeps us
262          * from referencing things beyond the end of the chunk.
263          */
264         for (i = (int)XFS_LIC_DESC_TO_SLOT(lidp) + 1; i < licp->lic_unused; i++) {
265                 if (XFS_LIC_ISFREE(licp, i)) {
266                         continue;
267                 }
268
269                 return (XFS_LIC_SLOT(licp, i));
270         }
271
272         /*
273          * Now search the next chunk.  It must be there, because the
274          * next chunk would have been freed if it were empty.
275          * If there is no next chunk, return NULL.
276          */
277         if (licp->lic_next == NULL) {
278                 return (NULL);
279         }
280
281         licp = licp->lic_next;
282         ASSERT(!XFS_LIC_ARE_ALL_FREE(licp));
283         for (i = 0; i < licp->lic_unused; i++) {
284                 if (XFS_LIC_ISFREE(licp, i)) {
285                         continue;
286                 }
287
288                 return (XFS_LIC_SLOT(licp, i));
289         }
290         ASSERT(0);
291         /* NOTREACHED */
292         return NULL; /* keep gcc quite */
293 }
294
295 /*
296  * This is called to unlock all of the items of a transaction and to free
297  * all the descriptors of that transaction.
298  *
299  * It walks the list of descriptors and unlocks each item.  It frees
300  * each chunk except that embedded in the transaction as it goes along.
301  */
302 void
303 xfs_trans_free_items(
304         xfs_trans_t     *tp,
305         int             flags)
306 {
307         xfs_log_item_chunk_t    *licp;
308         xfs_log_item_chunk_t    *next_licp;
309         int                     abort;
310
311         abort = flags & XFS_TRANS_ABORT;
312         licp = &tp->t_items;
313         /*
314          * Special case the embedded chunk so we don't free it below.
315          */
316         if (!XFS_LIC_ARE_ALL_FREE(licp)) {
317                 (void) xfs_trans_unlock_chunk(licp, 1, abort, NULLCOMMITLSN);
318                 XFS_LIC_ALL_FREE(licp);
319                 licp->lic_unused = 0;
320         }
321         licp = licp->lic_next;
322
323         /*
324          * Unlock each item in each chunk and free the chunks.
325          */
326         while (licp != NULL) {
327                 ASSERT(!XFS_LIC_ARE_ALL_FREE(licp));
328                 (void) xfs_trans_unlock_chunk(licp, 1, abort, NULLCOMMITLSN);
329                 next_licp = licp->lic_next;
330                 kmem_free(licp, sizeof(xfs_log_item_chunk_t));
331                 licp = next_licp;
332         }
333
334         /*
335          * Reset the transaction structure's free item count.
336          */
337         tp->t_items_free = XFS_LIC_NUM_SLOTS;
338         tp->t_items.lic_next = NULL;
339 }
340
341
342
343 /*
344  * This is called to unlock the items associated with a transaction.
345  * Items which were not logged should be freed.
346  * Those which were logged must still be tracked so they can be unpinned
347  * when the transaction commits.
348  */
349 void
350 xfs_trans_unlock_items(xfs_trans_t *tp, xfs_lsn_t commit_lsn)
351 {
352         xfs_log_item_chunk_t    *licp;
353         xfs_log_item_chunk_t    *next_licp;
354         xfs_log_item_chunk_t    **licpp;
355         int                     freed;
356
357         freed = 0;
358         licp = &tp->t_items;
359
360         /*
361          * Special case the embedded chunk so we don't free.
362          */
363         if (!XFS_LIC_ARE_ALL_FREE(licp)) {
364                 freed = xfs_trans_unlock_chunk(licp, 0, 0, commit_lsn);
365         }
366         licpp = &(tp->t_items.lic_next);
367         licp = licp->lic_next;
368
369         /*
370          * Unlock each item in each chunk, free non-dirty descriptors,
371          * and free empty chunks.
372          */
373         while (licp != NULL) {
374                 ASSERT(!XFS_LIC_ARE_ALL_FREE(licp));
375                 freed += xfs_trans_unlock_chunk(licp, 0, 0, commit_lsn);
376                 next_licp = licp->lic_next;
377                 if (XFS_LIC_ARE_ALL_FREE(licp)) {
378                         *licpp = next_licp;
379                         kmem_free(licp, sizeof(xfs_log_item_chunk_t));
380                         freed -= XFS_LIC_NUM_SLOTS;
381                 } else {
382                         licpp = &(licp->lic_next);
383                 }
384                 ASSERT(*licpp == next_licp);
385                 licp = next_licp;
386         }
387
388         /*
389          * Fix the free descriptor count in the transaction.
390          */
391         tp->t_items_free += freed;
392 }
393
394 /*
395  * Unlock each item pointed to by a descriptor in the given chunk.
396  * Stamp the commit lsn into each item if necessary.
397  * Free descriptors pointing to items which are not dirty if freeing_chunk
398  * is zero. If freeing_chunk is non-zero, then we need to unlock all
399  * items in the chunk.
400  * 
401  * Return the number of descriptors freed.
402  */
403 STATIC int
404 xfs_trans_unlock_chunk(
405         xfs_log_item_chunk_t    *licp,
406         int                     freeing_chunk,
407         int                     abort,
408         xfs_lsn_t               commit_lsn)
409 {
410         xfs_log_item_desc_t     *lidp;
411         xfs_log_item_t          *lip;
412         int                     i;
413         int                     freed;
414
415         freed = 0;
416         lidp = licp->lic_descs;
417         for (i = 0; i < licp->lic_unused; i++, lidp++) {
418                 if (XFS_LIC_ISFREE(licp, i)) {
419                         continue;
420                 }
421                 lip = lidp->lid_item;
422                 lip->li_desc = NULL;
423
424                 if (commit_lsn != NULLCOMMITLSN)
425                         IOP_COMMITTING(lip, commit_lsn);
426                 if (abort)
427                         lip->li_flags |= XFS_LI_ABORTED;
428                 IOP_UNLOCK(lip);
429
430                 /*
431                  * Free the descriptor if the item is not dirty
432                  * within this transaction and the caller is not
433                  * going to just free the entire thing regardless.
434                  */
435                 if (!(freeing_chunk) &&
436                     (!(lidp->lid_flags & XFS_LID_DIRTY) || abort)) {
437                         XFS_LIC_RELSE(licp, i);
438                         freed++;
439                 }
440         }
441
442         return (freed);
443 }
444
445
446 /*
447  * This is called to add the given busy item to the transaction's
448  * list of busy items.  It must find a free busy item descriptor
449  * or allocate a new one and add the item to that descriptor.
450  * The function returns a pointer to busy descriptor used to point
451  * to the new busy entry.  The log busy entry will now point to its new
452  * descriptor with its ???? field.
453  */
454 xfs_log_busy_slot_t *
455 xfs_trans_add_busy(xfs_trans_t *tp, xfs_agnumber_t ag, xfs_extlen_t idx)
456 {
457         xfs_log_busy_chunk_t    *lbcp;
458         xfs_log_busy_slot_t     *lbsp;
459         int                     i=0;
460
461         /*
462          * If there are no free descriptors, allocate a new chunk
463          * of them and put it at the front of the chunk list.
464          */
465         if (tp->t_busy_free == 0) {
466                 lbcp = (xfs_log_busy_chunk_t*)
467                        kmem_alloc(sizeof(xfs_log_busy_chunk_t), KM_SLEEP);
468                 ASSERT(lbcp != NULL);
469                 /*
470                  * Initialize the chunk, and then
471                  * claim the first slot in the newly allocated chunk.
472                  */
473                 XFS_LBC_INIT(lbcp);
474                 XFS_LBC_CLAIM(lbcp, 0);
475                 lbcp->lbc_unused = 1;
476                 lbsp = XFS_LBC_SLOT(lbcp, 0);
477
478                 /*
479                  * Link in the new chunk and update the free count.
480                  */
481                 lbcp->lbc_next = tp->t_busy.lbc_next;
482                 tp->t_busy.lbc_next = lbcp;
483                 tp->t_busy_free = XFS_LIC_NUM_SLOTS - 1;
484
485                 /*
486                  * Initialize the descriptor and the generic portion
487                  * of the log item.
488                  *
489                  * Point the new slot at this item and return it.
490                  * Also point the log item at its currently active
491                  * descriptor and set the item's mount pointer.
492                  */
493                 lbsp->lbc_ag = ag;
494                 lbsp->lbc_idx = idx;
495                 return (lbsp);
496         }
497
498         /*
499          * Find the free descriptor. It is somewhere in the chunklist
500          * of descriptors.
501          */
502         lbcp = &tp->t_busy;
503         while (lbcp != NULL) {
504                 if (XFS_LBC_VACANCY(lbcp)) {
505                         if (lbcp->lbc_unused <= XFS_LBC_MAX_SLOT) {
506                                 i = lbcp->lbc_unused;
507                                 break;
508                         } else {
509                                 /* out-of-order vacancy */
510                                 printk("OOO vacancy lbcp 0x%p\n", lbcp);
511                                 ASSERT(0);
512                         }
513                 }
514                 lbcp = lbcp->lbc_next;
515         }
516         ASSERT(lbcp != NULL);
517         /*
518          * If we find a free descriptor, claim it,
519          * initialize it, and return it.
520          */
521         XFS_LBC_CLAIM(lbcp, i);
522         if (lbcp->lbc_unused <= i) {
523                 lbcp->lbc_unused = i + 1;
524         }
525         lbsp = XFS_LBC_SLOT(lbcp, i);
526         tp->t_busy_free--;
527         lbsp->lbc_ag = ag;
528         lbsp->lbc_idx = idx;
529         return (lbsp);
530 }
531
532
533 /*
534  * xfs_trans_free_busy
535  * Free all of the busy lists from a transaction
536  */
537 void
538 xfs_trans_free_busy(xfs_trans_t *tp)
539 {
540         xfs_log_busy_chunk_t    *lbcp;
541         xfs_log_busy_chunk_t    *lbcq;
542
543         lbcp = tp->t_busy.lbc_next;
544         while (lbcp != NULL) {
545                 lbcq = lbcp->lbc_next;
546                 kmem_free(lbcp, sizeof(xfs_log_busy_chunk_t));
547                 lbcp = lbcq;
548         }
549
550         XFS_LBC_INIT(&tp->t_busy);
551         tp->t_busy.lbc_unused = 0;
552 }