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