xfs_trans_item.c 13 KB

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