[XFS] Remove xfs_macros.c, xfs_macros.h, rework headers a whole lot.
[safe/jmp/linux-2.6] / fs / xfs / xfs_trans_ail.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 #include "xfs_sb.h"
39 #include "xfs_dir.h"
40 #include "xfs_dmapi.h"
41 #include "xfs_mount.h"
42 #include "xfs_trans_priv.h"
43 #include "xfs_error.h"
44
45 STATIC void xfs_ail_insert(xfs_ail_entry_t *, xfs_log_item_t *);
46 STATIC xfs_log_item_t * xfs_ail_delete(xfs_ail_entry_t *, xfs_log_item_t *);
47 STATIC xfs_log_item_t * xfs_ail_min(xfs_ail_entry_t *);
48 STATIC xfs_log_item_t * xfs_ail_next(xfs_ail_entry_t *, xfs_log_item_t *);
49
50 #ifdef DEBUG
51 STATIC void xfs_ail_check(xfs_ail_entry_t *);
52 #else
53 #define xfs_ail_check(a)
54 #endif /* DEBUG */
55
56
57 /*
58  * This is called by the log manager code to determine the LSN
59  * of the tail of the log.  This is exactly the LSN of the first
60  * item in the AIL.  If the AIL is empty, then this function
61  * returns 0.
62  *
63  * We need the AIL lock in order to get a coherent read of the
64  * lsn of the last item in the AIL.
65  */
66 xfs_lsn_t
67 xfs_trans_tail_ail(
68         xfs_mount_t     *mp)
69 {
70         xfs_lsn_t       lsn;
71         xfs_log_item_t  *lip;
72         SPLDECL(s);
73
74         AIL_LOCK(mp,s);
75         lip = xfs_ail_min(&(mp->m_ail));
76         if (lip == NULL) {
77                 lsn = (xfs_lsn_t)0;
78         } else {
79                 lsn = lip->li_lsn;
80         }
81         AIL_UNLOCK(mp, s);
82
83         return lsn;
84 }
85
86 /*
87  * xfs_trans_push_ail
88  *
89  * This routine is called to move the tail of the AIL
90  * forward.  It does this by trying to flush items in the AIL
91  * whose lsns are below the given threshold_lsn.
92  *
93  * The routine returns the lsn of the tail of the log.
94  */
95 xfs_lsn_t
96 xfs_trans_push_ail(
97         xfs_mount_t             *mp,
98         xfs_lsn_t               threshold_lsn)
99 {
100         xfs_lsn_t               lsn;
101         xfs_log_item_t          *lip;
102         int                     gen;
103         int                     restarts;
104         int                     lock_result;
105         int                     flush_log;
106         SPLDECL(s);
107
108 #define XFS_TRANS_PUSH_AIL_RESTARTS     10
109
110         AIL_LOCK(mp,s);
111         lip = xfs_trans_first_ail(mp, &gen);
112         if (lip == NULL || XFS_FORCED_SHUTDOWN(mp)) {
113                 /*
114                  * Just return if the AIL is empty.
115                  */
116                 AIL_UNLOCK(mp, s);
117                 return (xfs_lsn_t)0;
118         }
119
120         XFS_STATS_INC(xs_push_ail);
121
122         /*
123          * While the item we are looking at is below the given threshold
124          * try to flush it out.  Make sure to limit the number of times
125          * we allow xfs_trans_next_ail() to restart scanning from the
126          * beginning of the list.  We'd like not to stop until we've at least
127          * tried to push on everything in the AIL with an LSN less than
128          * the given threshold. However, we may give up before that if
129          * we realize that we've been holding the AIL_LOCK for 'too long',
130          * blocking interrupts. Currently, too long is < 500us roughly.
131          */
132         flush_log = 0;
133         restarts = 0;
134         while (((restarts < XFS_TRANS_PUSH_AIL_RESTARTS) &&
135                 (XFS_LSN_CMP(lip->li_lsn, threshold_lsn) < 0))) {
136                 /*
137                  * If we can lock the item without sleeping, unlock
138                  * the AIL lock and flush the item.  Then re-grab the
139                  * AIL lock so we can look for the next item on the
140                  * AIL.  Since we unlock the AIL while we flush the
141                  * item, the next routine may start over again at the
142                  * the beginning of the list if anything has changed.
143                  * That is what the generation count is for.
144                  *
145                  * If we can't lock the item, either its holder will flush
146                  * it or it is already being flushed or it is being relogged.
147                  * In any of these case it is being taken care of and we
148                  * can just skip to the next item in the list.
149                  */
150                 lock_result = IOP_TRYLOCK(lip);
151                 switch (lock_result) {
152                       case XFS_ITEM_SUCCESS:
153                         AIL_UNLOCK(mp, s);
154                         XFS_STATS_INC(xs_push_ail_success);
155                         IOP_PUSH(lip);
156                         AIL_LOCK(mp,s);
157                         break;
158
159                       case XFS_ITEM_PUSHBUF:
160                         AIL_UNLOCK(mp, s);
161                         XFS_STATS_INC(xs_push_ail_pushbuf);
162 #ifdef XFSRACEDEBUG
163                         delay_for_intr();
164                         delay(300);
165 #endif
166                         ASSERT(lip->li_ops->iop_pushbuf);
167                         ASSERT(lip);
168                         IOP_PUSHBUF(lip);
169                         AIL_LOCK(mp,s);
170                         break;
171
172                       case XFS_ITEM_PINNED:
173                         XFS_STATS_INC(xs_push_ail_pinned);
174                         flush_log = 1;
175                         break;
176
177                       case XFS_ITEM_LOCKED:
178                         XFS_STATS_INC(xs_push_ail_locked);
179                         break;
180
181                       case XFS_ITEM_FLUSHING:
182                         XFS_STATS_INC(xs_push_ail_flushing);
183                         break;
184
185                       default:
186                         ASSERT(0);
187                         break;
188                 }
189
190                 lip = xfs_trans_next_ail(mp, lip, &gen, &restarts);
191                 if (lip == NULL) {
192                         break;
193                 }
194                 if (XFS_FORCED_SHUTDOWN(mp)) {
195                         /*
196                          * Just return if we shut down during the last try.
197                          */
198                         AIL_UNLOCK(mp, s);
199                         return (xfs_lsn_t)0;
200                 }
201
202         }
203
204         if (flush_log) {
205                 /*
206                  * If something we need to push out was pinned, then
207                  * push out the log so it will become unpinned and
208                  * move forward in the AIL.
209                  */
210                 AIL_UNLOCK(mp, s);
211                 XFS_STATS_INC(xs_push_ail_flush);
212                 xfs_log_force(mp, (xfs_lsn_t)0, XFS_LOG_FORCE);
213                 AIL_LOCK(mp, s);
214         }
215
216         lip = xfs_ail_min(&(mp->m_ail));
217         if (lip == NULL) {
218                 lsn = (xfs_lsn_t)0;
219         } else {
220                 lsn = lip->li_lsn;
221         }
222
223         AIL_UNLOCK(mp, s);
224         return lsn;
225 }       /* xfs_trans_push_ail */
226
227
228 /*
229  * This is to be called when an item is unlocked that may have
230  * been in the AIL.  It will wake up the first member of the AIL
231  * wait list if this item's unlocking might allow it to progress.
232  * If the item is in the AIL, then we need to get the AIL lock
233  * while doing our checking so we don't race with someone going
234  * to sleep waiting for this event in xfs_trans_push_ail().
235  */
236 void
237 xfs_trans_unlocked_item(
238         xfs_mount_t     *mp,
239         xfs_log_item_t  *lip)
240 {
241         xfs_log_item_t  *min_lip;
242
243         /*
244          * If we're forcibly shutting down, we may have
245          * unlocked log items arbitrarily. The last thing
246          * we want to do is to move the tail of the log
247          * over some potentially valid data.
248          */
249         if (!(lip->li_flags & XFS_LI_IN_AIL) ||
250             XFS_FORCED_SHUTDOWN(mp)) {
251                 return;
252         }
253
254         /*
255          * This is the one case where we can call into xfs_ail_min()
256          * without holding the AIL lock because we only care about the
257          * case where we are at the tail of the AIL.  If the object isn't
258          * at the tail, it doesn't matter what result we get back.  This
259          * is slightly racy because since we were just unlocked, we could
260          * go to sleep between the call to xfs_ail_min and the call to
261          * xfs_log_move_tail, have someone else lock us, commit to us disk,
262          * move us out of the tail of the AIL, and then we wake up.  However,
263          * the call to xfs_log_move_tail() doesn't do anything if there's
264          * not enough free space to wake people up so we're safe calling it.
265          */
266         min_lip = xfs_ail_min(&mp->m_ail);
267
268         if (min_lip == lip)
269                 xfs_log_move_tail(mp, 1);
270 }       /* xfs_trans_unlocked_item */
271
272
273 /*
274  * Update the position of the item in the AIL with the new
275  * lsn.  If it is not yet in the AIL, add it.  Otherwise, move
276  * it to its new position by removing it and re-adding it.
277  *
278  * Wakeup anyone with an lsn less than the item's lsn.  If the item
279  * we move in the AIL is the minimum one, update the tail lsn in the
280  * log manager.
281  *
282  * Increment the AIL's generation count to indicate that the tree
283  * has changed.
284  *
285  * This function must be called with the AIL lock held.  The lock
286  * is dropped before returning, so the caller must pass in the
287  * cookie returned by AIL_LOCK.
288  */
289 void
290 xfs_trans_update_ail(
291         xfs_mount_t     *mp,
292         xfs_log_item_t  *lip,
293         xfs_lsn_t       lsn,
294         unsigned long   s)
295 {
296         xfs_ail_entry_t         *ailp;
297         xfs_log_item_t          *dlip=NULL;
298         xfs_log_item_t          *mlip;  /* ptr to minimum lip */
299
300         ailp = &(mp->m_ail);
301         mlip = xfs_ail_min(ailp);
302
303         if (lip->li_flags & XFS_LI_IN_AIL) {
304                 dlip = xfs_ail_delete(ailp, lip);
305                 ASSERT(dlip == lip);
306         } else {
307                 lip->li_flags |= XFS_LI_IN_AIL;
308         }
309
310         lip->li_lsn = lsn;
311
312         xfs_ail_insert(ailp, lip);
313         mp->m_ail_gen++;
314
315         if (mlip == dlip) {
316                 mlip = xfs_ail_min(&(mp->m_ail));
317                 AIL_UNLOCK(mp, s);
318                 xfs_log_move_tail(mp, mlip->li_lsn);
319         } else {
320                 AIL_UNLOCK(mp, s);
321         }
322
323
324 }       /* xfs_trans_update_ail */
325
326 /*
327  * Delete the given item from the AIL.  It must already be in
328  * the AIL.
329  *
330  * Wakeup anyone with an lsn less than item's lsn.    If the item
331  * we delete in the AIL is the minimum one, update the tail lsn in the
332  * log manager.
333  *
334  * Clear the IN_AIL flag from the item, reset its lsn to 0, and
335  * bump the AIL's generation count to indicate that the tree
336  * has changed.
337  *
338  * This function must be called with the AIL lock held.  The lock
339  * is dropped before returning, so the caller must pass in the
340  * cookie returned by AIL_LOCK.
341  */
342 void
343 xfs_trans_delete_ail(
344         xfs_mount_t     *mp,
345         xfs_log_item_t  *lip,
346         unsigned long   s)
347 {
348         xfs_ail_entry_t         *ailp;
349         xfs_log_item_t          *dlip;
350         xfs_log_item_t          *mlip;
351
352         if (lip->li_flags & XFS_LI_IN_AIL) {
353                 ailp = &(mp->m_ail);
354                 mlip = xfs_ail_min(ailp);
355                 dlip = xfs_ail_delete(ailp, lip);
356                 ASSERT(dlip == lip);
357
358
359                 lip->li_flags &= ~XFS_LI_IN_AIL;
360                 lip->li_lsn = 0;
361                 mp->m_ail_gen++;
362
363                 if (mlip == dlip) {
364                         mlip = xfs_ail_min(&(mp->m_ail));
365                         AIL_UNLOCK(mp, s);
366                         xfs_log_move_tail(mp, (mlip ? mlip->li_lsn : 0));
367                 } else {
368                         AIL_UNLOCK(mp, s);
369                 }
370         }
371         else {
372                 /*
373                  * If the file system is not being shutdown, we are in
374                  * serious trouble if we get to this stage.
375                  */
376                 if (XFS_FORCED_SHUTDOWN(mp))
377                         AIL_UNLOCK(mp, s);
378                 else {
379                         xfs_cmn_err(XFS_PTAG_AILDELETE, CE_ALERT, mp,
380                                 "xfs_trans_delete_ail: attempting to delete a log item that is not in the AIL");
381                         AIL_UNLOCK(mp, s);
382                         xfs_force_shutdown(mp, XFS_CORRUPT_INCORE);
383                 }
384         }
385 }
386
387
388
389 /*
390  * Return the item in the AIL with the smallest lsn.
391  * Return the current tree generation number for use
392  * in calls to xfs_trans_next_ail().
393  */
394 xfs_log_item_t *
395 xfs_trans_first_ail(
396         xfs_mount_t     *mp,
397         int             *gen)
398 {
399         xfs_log_item_t  *lip;
400
401         lip = xfs_ail_min(&(mp->m_ail));
402         *gen = (int)mp->m_ail_gen;
403
404         return (lip);
405 }
406
407 /*
408  * If the generation count of the tree has not changed since the
409  * caller last took something from the AIL, then return the elmt
410  * in the tree which follows the one given.  If the count has changed,
411  * then return the minimum elmt of the AIL and bump the restarts counter
412  * if one is given.
413  */
414 xfs_log_item_t *
415 xfs_trans_next_ail(
416         xfs_mount_t     *mp,
417         xfs_log_item_t  *lip,
418         int             *gen,
419         int             *restarts)
420 {
421         xfs_log_item_t  *nlip;
422
423         ASSERT(mp && lip && gen);
424         if (mp->m_ail_gen == *gen) {
425                 nlip = xfs_ail_next(&(mp->m_ail), lip);
426         } else {
427                 nlip = xfs_ail_min(&(mp->m_ail));
428                 *gen = (int)mp->m_ail_gen;
429                 if (restarts != NULL) {
430                         XFS_STATS_INC(xs_push_ail_restarts);
431                         (*restarts)++;
432                 }
433         }
434
435         return (nlip);
436 }
437
438
439 /*
440  * The active item list (AIL) is a doubly linked list of log
441  * items sorted by ascending lsn.  The base of the list is
442  * a forw/back pointer pair embedded in the xfs mount structure.
443  * The base is initialized with both pointers pointing to the
444  * base.  This case always needs to be distinguished, because
445  * the base has no lsn to look at.  We almost always insert
446  * at the end of the list, so on inserts we search from the
447  * end of the list to find where the new item belongs.
448  */
449
450 /*
451  * Initialize the doubly linked list to point only to itself.
452  */
453 void
454 xfs_trans_ail_init(
455         xfs_mount_t     *mp)
456 {
457         mp->m_ail.ail_forw = (xfs_log_item_t*)&(mp->m_ail);
458         mp->m_ail.ail_back = (xfs_log_item_t*)&(mp->m_ail);
459 }
460
461 /*
462  * Insert the given log item into the AIL.
463  * We almost always insert at the end of the list, so on inserts
464  * we search from the end of the list to find where the
465  * new item belongs.
466  */
467 STATIC void
468 xfs_ail_insert(
469         xfs_ail_entry_t *base,
470         xfs_log_item_t  *lip)
471 /* ARGSUSED */
472 {
473         xfs_log_item_t  *next_lip;
474
475         /*
476          * If the list is empty, just insert the item.
477          */
478         if (base->ail_back == (xfs_log_item_t*)base) {
479                 base->ail_forw = lip;
480                 base->ail_back = lip;
481                 lip->li_ail.ail_forw = (xfs_log_item_t*)base;
482                 lip->li_ail.ail_back = (xfs_log_item_t*)base;
483                 return;
484         }
485
486         next_lip = base->ail_back;
487         while ((next_lip != (xfs_log_item_t*)base) &&
488                (XFS_LSN_CMP(next_lip->li_lsn, lip->li_lsn) > 0)) {
489                 next_lip = next_lip->li_ail.ail_back;
490         }
491         ASSERT((next_lip == (xfs_log_item_t*)base) ||
492                (XFS_LSN_CMP(next_lip->li_lsn, lip->li_lsn) <= 0));
493         lip->li_ail.ail_forw = next_lip->li_ail.ail_forw;
494         lip->li_ail.ail_back = next_lip;
495         next_lip->li_ail.ail_forw = lip;
496         lip->li_ail.ail_forw->li_ail.ail_back = lip;
497
498         xfs_ail_check(base);
499         return;
500 }
501
502 /*
503  * Delete the given item from the AIL.  Return a pointer to the item.
504  */
505 /*ARGSUSED*/
506 STATIC xfs_log_item_t *
507 xfs_ail_delete(
508         xfs_ail_entry_t *base,
509         xfs_log_item_t  *lip)
510 /* ARGSUSED */
511 {
512         lip->li_ail.ail_forw->li_ail.ail_back = lip->li_ail.ail_back;
513         lip->li_ail.ail_back->li_ail.ail_forw = lip->li_ail.ail_forw;
514         lip->li_ail.ail_forw = NULL;
515         lip->li_ail.ail_back = NULL;
516
517         xfs_ail_check(base);
518         return lip;
519 }
520
521 /*
522  * Return a pointer to the first item in the AIL.
523  * If the AIL is empty, then return NULL.
524  */
525 STATIC xfs_log_item_t *
526 xfs_ail_min(
527         xfs_ail_entry_t *base)
528 /* ARGSUSED */
529 {
530         register xfs_log_item_t *forw = base->ail_forw;
531         if (forw == (xfs_log_item_t*)base) {
532                 return NULL;
533         }
534         return forw;
535 }
536
537 /*
538  * Return a pointer to the item which follows
539  * the given item in the AIL.  If the given item
540  * is the last item in the list, then return NULL.
541  */
542 STATIC xfs_log_item_t *
543 xfs_ail_next(
544         xfs_ail_entry_t *base,
545         xfs_log_item_t  *lip)
546 /* ARGSUSED */
547 {
548         if (lip->li_ail.ail_forw == (xfs_log_item_t*)base) {
549                 return NULL;
550         }
551         return lip->li_ail.ail_forw;
552
553 }
554
555 #ifdef DEBUG
556 /*
557  * Check that the list is sorted as it should be.
558  */
559 STATIC void
560 xfs_ail_check(
561         xfs_ail_entry_t *base)
562 {
563         xfs_log_item_t  *lip;
564         xfs_log_item_t  *prev_lip;
565
566         lip = base->ail_forw;
567         if (lip == (xfs_log_item_t*)base) {
568                 /*
569                  * Make sure the pointers are correct when the list
570                  * is empty.
571                  */
572                 ASSERT(base->ail_back == (xfs_log_item_t*)base);
573                 return;
574         }
575
576         /*
577          * Walk the list checking forward and backward pointers,
578          * lsn ordering, and that every entry has the XFS_LI_IN_AIL
579          * flag set.
580          */
581         prev_lip = (xfs_log_item_t*)base;
582         while (lip != (xfs_log_item_t*)base) {
583                 if (prev_lip != (xfs_log_item_t*)base) {
584                         ASSERT(prev_lip->li_ail.ail_forw == lip);
585                         ASSERT(XFS_LSN_CMP(prev_lip->li_lsn, lip->li_lsn) <= 0);
586                 }
587                 ASSERT(lip->li_ail.ail_back == prev_lip);
588                 ASSERT((lip->li_flags & XFS_LI_IN_AIL) != 0);
589                 prev_lip = lip;
590                 lip = lip->li_ail.ail_forw;
591         }
592         ASSERT(lip == (xfs_log_item_t*)base);
593         ASSERT(base->ail_back == prev_lip);
594 }
595 #endif /* DEBUG */