xfs_trans_item.c 14 KB

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