xfs_trans_item.c 13 KB

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