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