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