1b3b94faaSDavid Teigland /* 2b3b94faaSDavid Teigland * Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. 3da6dd40dSBob Peterson * Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved. 4b3b94faaSDavid Teigland * 5b3b94faaSDavid Teigland * This copyrighted material is made available to anyone wishing to use, 6b3b94faaSDavid Teigland * modify, copy, or redistribute it subject to the terms and conditions 7e9fc2aa0SSteven Whitehouse * of the GNU General Public License version 2. 8b3b94faaSDavid Teigland */ 9b3b94faaSDavid Teigland 10b3b94faaSDavid Teigland #include <linux/sched.h> 11b3b94faaSDavid Teigland #include <linux/slab.h> 12b3b94faaSDavid Teigland #include <linux/spinlock.h> 13b3b94faaSDavid Teigland #include <linux/completion.h> 14b3b94faaSDavid Teigland #include <linux/buffer_head.h> 155c676f6dSSteven Whitehouse #include <linux/gfs2_ondisk.h> 1671b86f56SSteven Whitehouse #include <linux/crc32.h> 17a25311c8SSteven Whitehouse #include <linux/delay.h> 18ec69b188SSteven Whitehouse #include <linux/kthread.h> 19ec69b188SSteven Whitehouse #include <linux/freezer.h> 20254db57fSSteven Whitehouse #include <linux/bio.h> 21885bcecaSSteven Whitehouse #include <linux/blkdev.h> 224667a0ecSSteven Whitehouse #include <linux/writeback.h> 234a36d08dSBob Peterson #include <linux/list_sort.h> 24b3b94faaSDavid Teigland 25b3b94faaSDavid Teigland #include "gfs2.h" 265c676f6dSSteven Whitehouse #include "incore.h" 27b3b94faaSDavid Teigland #include "bmap.h" 28b3b94faaSDavid Teigland #include "glock.h" 29b3b94faaSDavid Teigland #include "log.h" 30b3b94faaSDavid Teigland #include "lops.h" 31b3b94faaSDavid Teigland #include "meta_io.h" 325c676f6dSSteven Whitehouse #include "util.h" 3371b86f56SSteven Whitehouse #include "dir.h" 3463997775SSteven Whitehouse #include "trace_gfs2.h" 35b3b94faaSDavid Teigland 36b3b94faaSDavid Teigland /** 37b3b94faaSDavid Teigland * gfs2_struct2blk - compute stuff 38b3b94faaSDavid Teigland * @sdp: the filesystem 39b3b94faaSDavid Teigland * @nstruct: the number of structures 40b3b94faaSDavid Teigland * @ssize: the size of the structures 41b3b94faaSDavid Teigland * 42b3b94faaSDavid Teigland * Compute the number of log descriptor blocks needed to hold a certain number 43b3b94faaSDavid Teigland * of structures of a certain size. 44b3b94faaSDavid Teigland * 45b3b94faaSDavid Teigland * Returns: the number of blocks needed (minimum is always 1) 46b3b94faaSDavid Teigland */ 47b3b94faaSDavid Teigland 48b3b94faaSDavid Teigland unsigned int gfs2_struct2blk(struct gfs2_sbd *sdp, unsigned int nstruct, 49b3b94faaSDavid Teigland unsigned int ssize) 50b3b94faaSDavid Teigland { 51b3b94faaSDavid Teigland unsigned int blks; 52b3b94faaSDavid Teigland unsigned int first, second; 53b3b94faaSDavid Teigland 54b3b94faaSDavid Teigland blks = 1; 55faa31ce8SSteven Whitehouse first = (sdp->sd_sb.sb_bsize - sizeof(struct gfs2_log_descriptor)) / ssize; 56b3b94faaSDavid Teigland 57b3b94faaSDavid Teigland if (nstruct > first) { 58568f4c96SSteven Whitehouse second = (sdp->sd_sb.sb_bsize - 59568f4c96SSteven Whitehouse sizeof(struct gfs2_meta_header)) / ssize; 605c676f6dSSteven Whitehouse blks += DIV_ROUND_UP(nstruct - first, second); 61b3b94faaSDavid Teigland } 62b3b94faaSDavid Teigland 63b3b94faaSDavid Teigland return blks; 64b3b94faaSDavid Teigland } 65b3b94faaSDavid Teigland 66ddacfaf7SSteven Whitehouse /** 671e1a3d03SSteven Whitehouse * gfs2_remove_from_ail - Remove an entry from the ail lists, updating counters 681e1a3d03SSteven Whitehouse * @mapping: The associated mapping (maybe NULL) 691e1a3d03SSteven Whitehouse * @bd: The gfs2_bufdata to remove 701e1a3d03SSteven Whitehouse * 71c618e87aSSteven Whitehouse * The ail lock _must_ be held when calling this function 721e1a3d03SSteven Whitehouse * 731e1a3d03SSteven Whitehouse */ 741e1a3d03SSteven Whitehouse 75f91a0d3eSSteven Whitehouse void gfs2_remove_from_ail(struct gfs2_bufdata *bd) 761e1a3d03SSteven Whitehouse { 7716ca9412SBenjamin Marzinski bd->bd_tr = NULL; 781ad38c43SSteven Whitehouse list_del_init(&bd->bd_ail_st_list); 791ad38c43SSteven Whitehouse list_del_init(&bd->bd_ail_gl_list); 801e1a3d03SSteven Whitehouse atomic_dec(&bd->bd_gl->gl_ail_count); 811e1a3d03SSteven Whitehouse brelse(bd->bd_bh); 821e1a3d03SSteven Whitehouse } 831e1a3d03SSteven Whitehouse 841e1a3d03SSteven Whitehouse /** 85ddacfaf7SSteven Whitehouse * gfs2_ail1_start_one - Start I/O on a part of the AIL 86ddacfaf7SSteven Whitehouse * @sdp: the filesystem 874667a0ecSSteven Whitehouse * @wbc: The writeback control structure 884667a0ecSSteven Whitehouse * @ai: The ail structure 89ddacfaf7SSteven Whitehouse * 90ddacfaf7SSteven Whitehouse */ 91ddacfaf7SSteven Whitehouse 924f1de018SSteven Whitehouse static int gfs2_ail1_start_one(struct gfs2_sbd *sdp, 934667a0ecSSteven Whitehouse struct writeback_control *wbc, 9416ca9412SBenjamin Marzinski struct gfs2_trans *tr) 95d6a079e8SDave Chinner __releases(&sdp->sd_ail_lock) 96d6a079e8SDave Chinner __acquires(&sdp->sd_ail_lock) 97ddacfaf7SSteven Whitehouse { 985ac048bbSSteven Whitehouse struct gfs2_glock *gl = NULL; 994667a0ecSSteven Whitehouse struct address_space *mapping; 100ddacfaf7SSteven Whitehouse struct gfs2_bufdata *bd, *s; 101ddacfaf7SSteven Whitehouse struct buffer_head *bh; 102ddacfaf7SSteven Whitehouse 10316ca9412SBenjamin Marzinski list_for_each_entry_safe_reverse(bd, s, &tr->tr_ail1_list, bd_ail_st_list) { 104ddacfaf7SSteven Whitehouse bh = bd->bd_bh; 105ddacfaf7SSteven Whitehouse 10616ca9412SBenjamin Marzinski gfs2_assert(sdp, bd->bd_tr == tr); 107ddacfaf7SSteven Whitehouse 108ddacfaf7SSteven Whitehouse if (!buffer_busy(bh)) { 10916615be1SSteven Whitehouse if (!buffer_uptodate(bh)) 110ddacfaf7SSteven Whitehouse gfs2_io_error_bh(sdp, bh); 11116ca9412SBenjamin Marzinski list_move(&bd->bd_ail_st_list, &tr->tr_ail2_list); 112ddacfaf7SSteven Whitehouse continue; 113ddacfaf7SSteven Whitehouse } 114ddacfaf7SSteven Whitehouse 115ddacfaf7SSteven Whitehouse if (!buffer_dirty(bh)) 116ddacfaf7SSteven Whitehouse continue; 1175ac048bbSSteven Whitehouse if (gl == bd->bd_gl) 1185ac048bbSSteven Whitehouse continue; 1195ac048bbSSteven Whitehouse gl = bd->bd_gl; 12016ca9412SBenjamin Marzinski list_move(&bd->bd_ail_st_list, &tr->tr_ail1_list); 1214667a0ecSSteven Whitehouse mapping = bh->b_page->mapping; 1224f1de018SSteven Whitehouse if (!mapping) 1234f1de018SSteven Whitehouse continue; 124d6a079e8SDave Chinner spin_unlock(&sdp->sd_ail_lock); 1254667a0ecSSteven Whitehouse generic_writepages(mapping, wbc); 126d6a079e8SDave Chinner spin_lock(&sdp->sd_ail_lock); 1274667a0ecSSteven Whitehouse if (wbc->nr_to_write <= 0) 128ddacfaf7SSteven Whitehouse break; 1294f1de018SSteven Whitehouse return 1; 130ddacfaf7SSteven Whitehouse } 1314f1de018SSteven Whitehouse 1324f1de018SSteven Whitehouse return 0; 1334667a0ecSSteven Whitehouse } 1344667a0ecSSteven Whitehouse 1354667a0ecSSteven Whitehouse 1364667a0ecSSteven Whitehouse /** 1374667a0ecSSteven Whitehouse * gfs2_ail1_flush - start writeback of some ail1 entries 1384667a0ecSSteven Whitehouse * @sdp: The super block 1394667a0ecSSteven Whitehouse * @wbc: The writeback control structure 1404667a0ecSSteven Whitehouse * 1414667a0ecSSteven Whitehouse * Writes back some ail1 entries, according to the limits in the 1424667a0ecSSteven Whitehouse * writeback control structure 1434667a0ecSSteven Whitehouse */ 1444667a0ecSSteven Whitehouse 1454667a0ecSSteven Whitehouse void gfs2_ail1_flush(struct gfs2_sbd *sdp, struct writeback_control *wbc) 1464667a0ecSSteven Whitehouse { 1474667a0ecSSteven Whitehouse struct list_head *head = &sdp->sd_ail1_list; 14816ca9412SBenjamin Marzinski struct gfs2_trans *tr; 149885bcecaSSteven Whitehouse struct blk_plug plug; 1504667a0ecSSteven Whitehouse 151c83ae9caSSteven Whitehouse trace_gfs2_ail_flush(sdp, wbc, 1); 152885bcecaSSteven Whitehouse blk_start_plug(&plug); 1534667a0ecSSteven Whitehouse spin_lock(&sdp->sd_ail_lock); 1544f1de018SSteven Whitehouse restart: 15516ca9412SBenjamin Marzinski list_for_each_entry_reverse(tr, head, tr_list) { 1564667a0ecSSteven Whitehouse if (wbc->nr_to_write <= 0) 1574667a0ecSSteven Whitehouse break; 15816ca9412SBenjamin Marzinski if (gfs2_ail1_start_one(sdp, wbc, tr)) 1594f1de018SSteven Whitehouse goto restart; 1604667a0ecSSteven Whitehouse } 1614667a0ecSSteven Whitehouse spin_unlock(&sdp->sd_ail_lock); 162885bcecaSSteven Whitehouse blk_finish_plug(&plug); 163c83ae9caSSteven Whitehouse trace_gfs2_ail_flush(sdp, wbc, 0); 1644667a0ecSSteven Whitehouse } 1654667a0ecSSteven Whitehouse 1664667a0ecSSteven Whitehouse /** 1674667a0ecSSteven Whitehouse * gfs2_ail1_start - start writeback of all ail1 entries 1684667a0ecSSteven Whitehouse * @sdp: The superblock 1694667a0ecSSteven Whitehouse */ 1704667a0ecSSteven Whitehouse 1714667a0ecSSteven Whitehouse static void gfs2_ail1_start(struct gfs2_sbd *sdp) 1724667a0ecSSteven Whitehouse { 1734667a0ecSSteven Whitehouse struct writeback_control wbc = { 1744667a0ecSSteven Whitehouse .sync_mode = WB_SYNC_NONE, 1754667a0ecSSteven Whitehouse .nr_to_write = LONG_MAX, 1764667a0ecSSteven Whitehouse .range_start = 0, 1774667a0ecSSteven Whitehouse .range_end = LLONG_MAX, 1784667a0ecSSteven Whitehouse }; 1794667a0ecSSteven Whitehouse 1804667a0ecSSteven Whitehouse return gfs2_ail1_flush(sdp, &wbc); 181ddacfaf7SSteven Whitehouse } 182ddacfaf7SSteven Whitehouse 183ddacfaf7SSteven Whitehouse /** 184ddacfaf7SSteven Whitehouse * gfs2_ail1_empty_one - Check whether or not a trans in the AIL has been synced 185ddacfaf7SSteven Whitehouse * @sdp: the filesystem 186ddacfaf7SSteven Whitehouse * @ai: the AIL entry 187ddacfaf7SSteven Whitehouse * 188ddacfaf7SSteven Whitehouse */ 189ddacfaf7SSteven Whitehouse 19016ca9412SBenjamin Marzinski static void gfs2_ail1_empty_one(struct gfs2_sbd *sdp, struct gfs2_trans *tr) 191ddacfaf7SSteven Whitehouse { 192ddacfaf7SSteven Whitehouse struct gfs2_bufdata *bd, *s; 193ddacfaf7SSteven Whitehouse struct buffer_head *bh; 194ddacfaf7SSteven Whitehouse 19516ca9412SBenjamin Marzinski list_for_each_entry_safe_reverse(bd, s, &tr->tr_ail1_list, 196ddacfaf7SSteven Whitehouse bd_ail_st_list) { 197ddacfaf7SSteven Whitehouse bh = bd->bd_bh; 19816ca9412SBenjamin Marzinski gfs2_assert(sdp, bd->bd_tr == tr); 1994667a0ecSSteven Whitehouse if (buffer_busy(bh)) 200ddacfaf7SSteven Whitehouse continue; 201ddacfaf7SSteven Whitehouse if (!buffer_uptodate(bh)) 202ddacfaf7SSteven Whitehouse gfs2_io_error_bh(sdp, bh); 20316ca9412SBenjamin Marzinski list_move(&bd->bd_ail_st_list, &tr->tr_ail2_list); 204ddacfaf7SSteven Whitehouse } 205ddacfaf7SSteven Whitehouse 206ddacfaf7SSteven Whitehouse } 207ddacfaf7SSteven Whitehouse 2084667a0ecSSteven Whitehouse /** 2094667a0ecSSteven Whitehouse * gfs2_ail1_empty - Try to empty the ail1 lists 2104667a0ecSSteven Whitehouse * @sdp: The superblock 2114667a0ecSSteven Whitehouse * 2124667a0ecSSteven Whitehouse * Tries to empty the ail1 lists, starting with the oldest first 2134667a0ecSSteven Whitehouse */ 214b3b94faaSDavid Teigland 2154667a0ecSSteven Whitehouse static int gfs2_ail1_empty(struct gfs2_sbd *sdp) 216b3b94faaSDavid Teigland { 21716ca9412SBenjamin Marzinski struct gfs2_trans *tr, *s; 2185d054964SBenjamin Marzinski int oldest_tr = 1; 219b3b94faaSDavid Teigland int ret; 220b3b94faaSDavid Teigland 221d6a079e8SDave Chinner spin_lock(&sdp->sd_ail_lock); 22216ca9412SBenjamin Marzinski list_for_each_entry_safe_reverse(tr, s, &sdp->sd_ail1_list, tr_list) { 22316ca9412SBenjamin Marzinski gfs2_ail1_empty_one(sdp, tr); 2245d054964SBenjamin Marzinski if (list_empty(&tr->tr_ail1_list) && oldest_tr) 22516ca9412SBenjamin Marzinski list_move(&tr->tr_list, &sdp->sd_ail2_list); 2264667a0ecSSteven Whitehouse else 2275d054964SBenjamin Marzinski oldest_tr = 0; 228b3b94faaSDavid Teigland } 229b3b94faaSDavid Teigland ret = list_empty(&sdp->sd_ail1_list); 230d6a079e8SDave Chinner spin_unlock(&sdp->sd_ail_lock); 231b3b94faaSDavid Teigland 232b3b94faaSDavid Teigland return ret; 233b3b94faaSDavid Teigland } 234b3b94faaSDavid Teigland 23526b06a69SSteven Whitehouse static void gfs2_ail1_wait(struct gfs2_sbd *sdp) 23626b06a69SSteven Whitehouse { 23716ca9412SBenjamin Marzinski struct gfs2_trans *tr; 23826b06a69SSteven Whitehouse struct gfs2_bufdata *bd; 23926b06a69SSteven Whitehouse struct buffer_head *bh; 24026b06a69SSteven Whitehouse 24126b06a69SSteven Whitehouse spin_lock(&sdp->sd_ail_lock); 24216ca9412SBenjamin Marzinski list_for_each_entry_reverse(tr, &sdp->sd_ail1_list, tr_list) { 24316ca9412SBenjamin Marzinski list_for_each_entry(bd, &tr->tr_ail1_list, bd_ail_st_list) { 24426b06a69SSteven Whitehouse bh = bd->bd_bh; 24526b06a69SSteven Whitehouse if (!buffer_locked(bh)) 24626b06a69SSteven Whitehouse continue; 24726b06a69SSteven Whitehouse get_bh(bh); 24826b06a69SSteven Whitehouse spin_unlock(&sdp->sd_ail_lock); 24926b06a69SSteven Whitehouse wait_on_buffer(bh); 25026b06a69SSteven Whitehouse brelse(bh); 25126b06a69SSteven Whitehouse return; 25226b06a69SSteven Whitehouse } 25326b06a69SSteven Whitehouse } 25426b06a69SSteven Whitehouse spin_unlock(&sdp->sd_ail_lock); 25526b06a69SSteven Whitehouse } 256ddacfaf7SSteven Whitehouse 257ddacfaf7SSteven Whitehouse /** 258ddacfaf7SSteven Whitehouse * gfs2_ail2_empty_one - Check whether or not a trans in the AIL has been synced 259ddacfaf7SSteven Whitehouse * @sdp: the filesystem 260ddacfaf7SSteven Whitehouse * @ai: the AIL entry 261ddacfaf7SSteven Whitehouse * 262ddacfaf7SSteven Whitehouse */ 263ddacfaf7SSteven Whitehouse 26416ca9412SBenjamin Marzinski static void gfs2_ail2_empty_one(struct gfs2_sbd *sdp, struct gfs2_trans *tr) 265ddacfaf7SSteven Whitehouse { 26616ca9412SBenjamin Marzinski struct list_head *head = &tr->tr_ail2_list; 267ddacfaf7SSteven Whitehouse struct gfs2_bufdata *bd; 268ddacfaf7SSteven Whitehouse 269ddacfaf7SSteven Whitehouse while (!list_empty(head)) { 270ddacfaf7SSteven Whitehouse bd = list_entry(head->prev, struct gfs2_bufdata, 271ddacfaf7SSteven Whitehouse bd_ail_st_list); 27216ca9412SBenjamin Marzinski gfs2_assert(sdp, bd->bd_tr == tr); 273f91a0d3eSSteven Whitehouse gfs2_remove_from_ail(bd); 274ddacfaf7SSteven Whitehouse } 275ddacfaf7SSteven Whitehouse } 276ddacfaf7SSteven Whitehouse 277b3b94faaSDavid Teigland static void ail2_empty(struct gfs2_sbd *sdp, unsigned int new_tail) 278b3b94faaSDavid Teigland { 27916ca9412SBenjamin Marzinski struct gfs2_trans *tr, *safe; 280b3b94faaSDavid Teigland unsigned int old_tail = sdp->sd_log_tail; 281b3b94faaSDavid Teigland int wrap = (new_tail < old_tail); 282b3b94faaSDavid Teigland int a, b, rm; 283b3b94faaSDavid Teigland 284d6a079e8SDave Chinner spin_lock(&sdp->sd_ail_lock); 285b3b94faaSDavid Teigland 28616ca9412SBenjamin Marzinski list_for_each_entry_safe(tr, safe, &sdp->sd_ail2_list, tr_list) { 28716ca9412SBenjamin Marzinski a = (old_tail <= tr->tr_first); 28816ca9412SBenjamin Marzinski b = (tr->tr_first < new_tail); 289b3b94faaSDavid Teigland rm = (wrap) ? (a || b) : (a && b); 290b3b94faaSDavid Teigland if (!rm) 291b3b94faaSDavid Teigland continue; 292b3b94faaSDavid Teigland 29316ca9412SBenjamin Marzinski gfs2_ail2_empty_one(sdp, tr); 29416ca9412SBenjamin Marzinski list_del(&tr->tr_list); 29516ca9412SBenjamin Marzinski gfs2_assert_warn(sdp, list_empty(&tr->tr_ail1_list)); 29616ca9412SBenjamin Marzinski gfs2_assert_warn(sdp, list_empty(&tr->tr_ail2_list)); 29716ca9412SBenjamin Marzinski kfree(tr); 298b3b94faaSDavid Teigland } 299b3b94faaSDavid Teigland 300d6a079e8SDave Chinner spin_unlock(&sdp->sd_ail_lock); 301b3b94faaSDavid Teigland } 302b3b94faaSDavid Teigland 303b3b94faaSDavid Teigland /** 304b3b94faaSDavid Teigland * gfs2_log_reserve - Make a log reservation 305b3b94faaSDavid Teigland * @sdp: The GFS2 superblock 306b3b94faaSDavid Teigland * @blks: The number of blocks to reserve 307b3b94faaSDavid Teigland * 30889918647SSteven Whitehouse * Note that we never give out the last few blocks of the journal. Thats 3092332c443SRobert Peterson * due to the fact that there is a small number of header blocks 310b004157aSSteven Whitehouse * associated with each log flush. The exact number can't be known until 311b004157aSSteven Whitehouse * flush time, so we ensure that we have just enough free blocks at all 312b004157aSSteven Whitehouse * times to avoid running out during a log flush. 313b004157aSSteven Whitehouse * 3145e687eacSBenjamin Marzinski * We no longer flush the log here, instead we wake up logd to do that 3155e687eacSBenjamin Marzinski * for us. To avoid the thundering herd and to ensure that we deal fairly 3165e687eacSBenjamin Marzinski * with queued waiters, we use an exclusive wait. This means that when we 3175e687eacSBenjamin Marzinski * get woken with enough journal space to get our reservation, we need to 3185e687eacSBenjamin Marzinski * wake the next waiter on the list. 3195e687eacSBenjamin Marzinski * 320b3b94faaSDavid Teigland * Returns: errno 321b3b94faaSDavid Teigland */ 322b3b94faaSDavid Teigland 323b3b94faaSDavid Teigland int gfs2_log_reserve(struct gfs2_sbd *sdp, unsigned int blks) 324b3b94faaSDavid Teigland { 3255d054964SBenjamin Marzinski unsigned reserved_blks = 7 * (4096 / sdp->sd_vfs->s_blocksize); 3265e687eacSBenjamin Marzinski unsigned wanted = blks + reserved_blks; 3275e687eacSBenjamin Marzinski DEFINE_WAIT(wait); 3285e687eacSBenjamin Marzinski int did_wait = 0; 3295e687eacSBenjamin Marzinski unsigned int free_blocks; 330b3b94faaSDavid Teigland 331b3b94faaSDavid Teigland if (gfs2_assert_warn(sdp, blks) || 332b3b94faaSDavid Teigland gfs2_assert_warn(sdp, blks <= sdp->sd_jdesc->jd_blocks)) 333b3b94faaSDavid Teigland return -EINVAL; 3345e687eacSBenjamin Marzinski retry: 3355e687eacSBenjamin Marzinski free_blocks = atomic_read(&sdp->sd_log_blks_free); 3365e687eacSBenjamin Marzinski if (unlikely(free_blocks <= wanted)) { 3375e687eacSBenjamin Marzinski do { 3385e687eacSBenjamin Marzinski prepare_to_wait_exclusive(&sdp->sd_log_waitq, &wait, 3395e687eacSBenjamin Marzinski TASK_UNINTERRUPTIBLE); 3405e687eacSBenjamin Marzinski wake_up(&sdp->sd_logd_waitq); 3415e687eacSBenjamin Marzinski did_wait = 1; 3425e687eacSBenjamin Marzinski if (atomic_read(&sdp->sd_log_blks_free) <= wanted) 3435e687eacSBenjamin Marzinski io_schedule(); 3445e687eacSBenjamin Marzinski free_blocks = atomic_read(&sdp->sd_log_blks_free); 3455e687eacSBenjamin Marzinski } while(free_blocks <= wanted); 3465e687eacSBenjamin Marzinski finish_wait(&sdp->sd_log_waitq, &wait); 347b3b94faaSDavid Teigland } 3485e687eacSBenjamin Marzinski if (atomic_cmpxchg(&sdp->sd_log_blks_free, free_blocks, 3495e687eacSBenjamin Marzinski free_blocks - blks) != free_blocks) 3505e687eacSBenjamin Marzinski goto retry; 35163997775SSteven Whitehouse trace_gfs2_log_blocks(sdp, -blks); 3525e687eacSBenjamin Marzinski 3535e687eacSBenjamin Marzinski /* 3545e687eacSBenjamin Marzinski * If we waited, then so might others, wake them up _after_ we get 3555e687eacSBenjamin Marzinski * our share of the log. 3565e687eacSBenjamin Marzinski */ 3575e687eacSBenjamin Marzinski if (unlikely(did_wait)) 3585e687eacSBenjamin Marzinski wake_up(&sdp->sd_log_waitq); 359484adff8SSteven Whitehouse 360484adff8SSteven Whitehouse down_read(&sdp->sd_log_flush_lock); 361b3b94faaSDavid Teigland 362b3b94faaSDavid Teigland return 0; 363b3b94faaSDavid Teigland } 364b3b94faaSDavid Teigland 365b3b94faaSDavid Teigland /** 366b3b94faaSDavid Teigland * log_distance - Compute distance between two journal blocks 367b3b94faaSDavid Teigland * @sdp: The GFS2 superblock 368b3b94faaSDavid Teigland * @newer: The most recent journal block of the pair 369b3b94faaSDavid Teigland * @older: The older journal block of the pair 370b3b94faaSDavid Teigland * 371b3b94faaSDavid Teigland * Compute the distance (in the journal direction) between two 372b3b94faaSDavid Teigland * blocks in the journal 373b3b94faaSDavid Teigland * 374b3b94faaSDavid Teigland * Returns: the distance in blocks 375b3b94faaSDavid Teigland */ 376b3b94faaSDavid Teigland 377faa31ce8SSteven Whitehouse static inline unsigned int log_distance(struct gfs2_sbd *sdp, unsigned int newer, 378b3b94faaSDavid Teigland unsigned int older) 379b3b94faaSDavid Teigland { 380b3b94faaSDavid Teigland int dist; 381b3b94faaSDavid Teigland 382b3b94faaSDavid Teigland dist = newer - older; 383b3b94faaSDavid Teigland if (dist < 0) 384b3b94faaSDavid Teigland dist += sdp->sd_jdesc->jd_blocks; 385b3b94faaSDavid Teigland 386b3b94faaSDavid Teigland return dist; 387b3b94faaSDavid Teigland } 388b3b94faaSDavid Teigland 3892332c443SRobert Peterson /** 3902332c443SRobert Peterson * calc_reserved - Calculate the number of blocks to reserve when 3912332c443SRobert Peterson * refunding a transaction's unused buffers. 3922332c443SRobert Peterson * @sdp: The GFS2 superblock 3932332c443SRobert Peterson * 3942332c443SRobert Peterson * This is complex. We need to reserve room for all our currently used 3952332c443SRobert Peterson * metadata buffers (e.g. normal file I/O rewriting file time stamps) and 3962332c443SRobert Peterson * all our journaled data buffers for journaled files (e.g. files in the 3972332c443SRobert Peterson * meta_fs like rindex, or files for which chattr +j was done.) 3982332c443SRobert Peterson * If we don't reserve enough space, gfs2_log_refund and gfs2_log_flush 3992332c443SRobert Peterson * will count it as free space (sd_log_blks_free) and corruption will follow. 4002332c443SRobert Peterson * 4012332c443SRobert Peterson * We can have metadata bufs and jdata bufs in the same journal. So each 4022332c443SRobert Peterson * type gets its own log header, for which we need to reserve a block. 4032332c443SRobert Peterson * In fact, each type has the potential for needing more than one header 4042332c443SRobert Peterson * in cases where we have more buffers than will fit on a journal page. 4052332c443SRobert Peterson * Metadata journal entries take up half the space of journaled buffer entries. 4062332c443SRobert Peterson * Thus, metadata entries have buf_limit (502) and journaled buffers have 4072332c443SRobert Peterson * databuf_limit (251) before they cause a wrap around. 4082332c443SRobert Peterson * 4092332c443SRobert Peterson * Also, we need to reserve blocks for revoke journal entries and one for an 4102332c443SRobert Peterson * overall header for the lot. 4112332c443SRobert Peterson * 4122332c443SRobert Peterson * Returns: the number of blocks reserved 4132332c443SRobert Peterson */ 4142332c443SRobert Peterson static unsigned int calc_reserved(struct gfs2_sbd *sdp) 4152332c443SRobert Peterson { 4162332c443SRobert Peterson unsigned int reserved = 0; 417022ef4feSSteven Whitehouse unsigned int mbuf; 418022ef4feSSteven Whitehouse unsigned int dbuf; 419022ef4feSSteven Whitehouse struct gfs2_trans *tr = sdp->sd_log_tr; 4202332c443SRobert Peterson 421022ef4feSSteven Whitehouse if (tr) { 422022ef4feSSteven Whitehouse mbuf = tr->tr_num_buf_new - tr->tr_num_buf_rm; 423022ef4feSSteven Whitehouse dbuf = tr->tr_num_databuf_new - tr->tr_num_databuf_rm; 424022ef4feSSteven Whitehouse reserved = mbuf + dbuf; 425022ef4feSSteven Whitehouse /* Account for header blocks */ 426022ef4feSSteven Whitehouse reserved += DIV_ROUND_UP(mbuf, buf_limit(sdp)); 427022ef4feSSteven Whitehouse reserved += DIV_ROUND_UP(dbuf, databuf_limit(sdp)); 428022ef4feSSteven Whitehouse } 4292332c443SRobert Peterson 4302e95e3f6SBenjamin Marzinski if (sdp->sd_log_commited_revoke > 0) 431022ef4feSSteven Whitehouse reserved += gfs2_struct2blk(sdp, sdp->sd_log_commited_revoke, 4322332c443SRobert Peterson sizeof(u64)); 4332332c443SRobert Peterson /* One for the overall header */ 4342332c443SRobert Peterson if (reserved) 4352332c443SRobert Peterson reserved++; 4362332c443SRobert Peterson return reserved; 4372332c443SRobert Peterson } 4382332c443SRobert Peterson 439b3b94faaSDavid Teigland static unsigned int current_tail(struct gfs2_sbd *sdp) 440b3b94faaSDavid Teigland { 44116ca9412SBenjamin Marzinski struct gfs2_trans *tr; 442b3b94faaSDavid Teigland unsigned int tail; 443b3b94faaSDavid Teigland 444d6a079e8SDave Chinner spin_lock(&sdp->sd_ail_lock); 445b3b94faaSDavid Teigland 446faa31ce8SSteven Whitehouse if (list_empty(&sdp->sd_ail1_list)) { 447b3b94faaSDavid Teigland tail = sdp->sd_log_head; 448faa31ce8SSteven Whitehouse } else { 44916ca9412SBenjamin Marzinski tr = list_entry(sdp->sd_ail1_list.prev, struct gfs2_trans, 45016ca9412SBenjamin Marzinski tr_list); 45116ca9412SBenjamin Marzinski tail = tr->tr_first; 452b3b94faaSDavid Teigland } 453b3b94faaSDavid Teigland 454d6a079e8SDave Chinner spin_unlock(&sdp->sd_ail_lock); 455b3b94faaSDavid Teigland 456b3b94faaSDavid Teigland return tail; 457b3b94faaSDavid Teigland } 458b3b94faaSDavid Teigland 4592332c443SRobert Peterson static void log_pull_tail(struct gfs2_sbd *sdp, unsigned int new_tail) 460b3b94faaSDavid Teigland { 461b3b94faaSDavid Teigland unsigned int dist = log_distance(sdp, new_tail, sdp->sd_log_tail); 462b3b94faaSDavid Teigland 463b3b94faaSDavid Teigland ail2_empty(sdp, new_tail); 464b3b94faaSDavid Teigland 465fd041f0bSSteven Whitehouse atomic_add(dist, &sdp->sd_log_blks_free); 46663997775SSteven Whitehouse trace_gfs2_log_blocks(sdp, dist); 4675e687eacSBenjamin Marzinski gfs2_assert_withdraw(sdp, atomic_read(&sdp->sd_log_blks_free) <= 4685e687eacSBenjamin Marzinski sdp->sd_jdesc->jd_blocks); 469b3b94faaSDavid Teigland 470b3b94faaSDavid Teigland sdp->sd_log_tail = new_tail; 471b3b94faaSDavid Teigland } 472b3b94faaSDavid Teigland 473b3b94faaSDavid Teigland 47434cc1781SSteven Whitehouse static void log_flush_wait(struct gfs2_sbd *sdp) 475b3b94faaSDavid Teigland { 47616615be1SSteven Whitehouse DEFINE_WAIT(wait); 477b3b94faaSDavid Teigland 47816615be1SSteven Whitehouse if (atomic_read(&sdp->sd_log_in_flight)) { 47916615be1SSteven Whitehouse do { 48016615be1SSteven Whitehouse prepare_to_wait(&sdp->sd_log_flush_wait, &wait, 48116615be1SSteven Whitehouse TASK_UNINTERRUPTIBLE); 48216615be1SSteven Whitehouse if (atomic_read(&sdp->sd_log_in_flight)) 48316615be1SSteven Whitehouse io_schedule(); 48416615be1SSteven Whitehouse } while(atomic_read(&sdp->sd_log_in_flight)); 48516615be1SSteven Whitehouse finish_wait(&sdp->sd_log_flush_wait, &wait); 486b3b94faaSDavid Teigland } 487b3b94faaSDavid Teigland } 488b3b94faaSDavid Teigland 48945138990SSteven Whitehouse static int ip_cmp(void *priv, struct list_head *a, struct list_head *b) 4904a36d08dSBob Peterson { 49145138990SSteven Whitehouse struct gfs2_inode *ipa, *ipb; 4924a36d08dSBob Peterson 49345138990SSteven Whitehouse ipa = list_entry(a, struct gfs2_inode, i_ordered); 49445138990SSteven Whitehouse ipb = list_entry(b, struct gfs2_inode, i_ordered); 4954a36d08dSBob Peterson 49645138990SSteven Whitehouse if (ipa->i_no_addr < ipb->i_no_addr) 4974a36d08dSBob Peterson return -1; 49845138990SSteven Whitehouse if (ipa->i_no_addr > ipb->i_no_addr) 4994a36d08dSBob Peterson return 1; 5004a36d08dSBob Peterson return 0; 5014a36d08dSBob Peterson } 5024a36d08dSBob Peterson 503d7b616e2SSteven Whitehouse static void gfs2_ordered_write(struct gfs2_sbd *sdp) 504d7b616e2SSteven Whitehouse { 50545138990SSteven Whitehouse struct gfs2_inode *ip; 506d7b616e2SSteven Whitehouse LIST_HEAD(written); 507d7b616e2SSteven Whitehouse 50845138990SSteven Whitehouse spin_lock(&sdp->sd_ordered_lock); 50945138990SSteven Whitehouse list_sort(NULL, &sdp->sd_log_le_ordered, &ip_cmp); 510d7b616e2SSteven Whitehouse while (!list_empty(&sdp->sd_log_le_ordered)) { 51145138990SSteven Whitehouse ip = list_entry(sdp->sd_log_le_ordered.next, struct gfs2_inode, i_ordered); 51245138990SSteven Whitehouse list_move(&ip->i_ordered, &written); 51345138990SSteven Whitehouse if (ip->i_inode.i_mapping->nrpages == 0) 514d7b616e2SSteven Whitehouse continue; 51545138990SSteven Whitehouse spin_unlock(&sdp->sd_ordered_lock); 51645138990SSteven Whitehouse filemap_fdatawrite(ip->i_inode.i_mapping); 51745138990SSteven Whitehouse spin_lock(&sdp->sd_ordered_lock); 518d7b616e2SSteven Whitehouse } 519d7b616e2SSteven Whitehouse list_splice(&written, &sdp->sd_log_le_ordered); 52045138990SSteven Whitehouse spin_unlock(&sdp->sd_ordered_lock); 521d7b616e2SSteven Whitehouse } 522d7b616e2SSteven Whitehouse 523d7b616e2SSteven Whitehouse static void gfs2_ordered_wait(struct gfs2_sbd *sdp) 524d7b616e2SSteven Whitehouse { 52545138990SSteven Whitehouse struct gfs2_inode *ip; 526d7b616e2SSteven Whitehouse 52745138990SSteven Whitehouse spin_lock(&sdp->sd_ordered_lock); 528d7b616e2SSteven Whitehouse while (!list_empty(&sdp->sd_log_le_ordered)) { 52945138990SSteven Whitehouse ip = list_entry(sdp->sd_log_le_ordered.next, struct gfs2_inode, i_ordered); 53045138990SSteven Whitehouse list_del(&ip->i_ordered); 53145138990SSteven Whitehouse WARN_ON(!test_and_clear_bit(GIF_ORDERED, &ip->i_flags)); 53245138990SSteven Whitehouse if (ip->i_inode.i_mapping->nrpages == 0) 533d7b616e2SSteven Whitehouse continue; 53445138990SSteven Whitehouse spin_unlock(&sdp->sd_ordered_lock); 53545138990SSteven Whitehouse filemap_fdatawait(ip->i_inode.i_mapping); 53645138990SSteven Whitehouse spin_lock(&sdp->sd_ordered_lock); 537d7b616e2SSteven Whitehouse } 53845138990SSteven Whitehouse spin_unlock(&sdp->sd_ordered_lock); 539d7b616e2SSteven Whitehouse } 54045138990SSteven Whitehouse 54145138990SSteven Whitehouse void gfs2_ordered_del_inode(struct gfs2_inode *ip) 54245138990SSteven Whitehouse { 54345138990SSteven Whitehouse struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); 54445138990SSteven Whitehouse 54545138990SSteven Whitehouse spin_lock(&sdp->sd_ordered_lock); 54645138990SSteven Whitehouse if (test_and_clear_bit(GIF_ORDERED, &ip->i_flags)) 54745138990SSteven Whitehouse list_del(&ip->i_ordered); 54845138990SSteven Whitehouse spin_unlock(&sdp->sd_ordered_lock); 549d7b616e2SSteven Whitehouse } 550d7b616e2SSteven Whitehouse 5515d054964SBenjamin Marzinski void gfs2_add_revoke(struct gfs2_sbd *sdp, struct gfs2_bufdata *bd) 5525d054964SBenjamin Marzinski { 5535d054964SBenjamin Marzinski struct buffer_head *bh = bd->bd_bh; 5545d054964SBenjamin Marzinski struct gfs2_glock *gl = bd->bd_gl; 5555d054964SBenjamin Marzinski 5565d054964SBenjamin Marzinski bh->b_private = NULL; 5575d054964SBenjamin Marzinski bd->bd_blkno = bh->b_blocknr; 5589290a9a7SBob Peterson gfs2_remove_from_ail(bd); /* drops ref on bh */ 5599290a9a7SBob Peterson bd->bd_bh = NULL; 5605d054964SBenjamin Marzinski bd->bd_ops = &gfs2_revoke_lops; 5615d054964SBenjamin Marzinski sdp->sd_log_num_revoke++; 5625d054964SBenjamin Marzinski atomic_inc(&gl->gl_revokes); 5635d054964SBenjamin Marzinski set_bit(GLF_LFLUSH, &gl->gl_flags); 5645d054964SBenjamin Marzinski list_add(&bd->bd_list, &sdp->sd_log_le_revoke); 5655d054964SBenjamin Marzinski } 5665d054964SBenjamin Marzinski 5675d054964SBenjamin Marzinski void gfs2_write_revokes(struct gfs2_sbd *sdp) 5685d054964SBenjamin Marzinski { 5695d054964SBenjamin Marzinski struct gfs2_trans *tr; 5705d054964SBenjamin Marzinski struct gfs2_bufdata *bd, *tmp; 5715d054964SBenjamin Marzinski int have_revokes = 0; 5725d054964SBenjamin Marzinski int max_revokes = (sdp->sd_sb.sb_bsize - sizeof(struct gfs2_log_descriptor)) / sizeof(u64); 5735d054964SBenjamin Marzinski 5745d054964SBenjamin Marzinski gfs2_ail1_empty(sdp); 5755d054964SBenjamin Marzinski spin_lock(&sdp->sd_ail_lock); 5765d054964SBenjamin Marzinski list_for_each_entry(tr, &sdp->sd_ail1_list, tr_list) { 5775d054964SBenjamin Marzinski list_for_each_entry(bd, &tr->tr_ail2_list, bd_ail_st_list) { 5785d054964SBenjamin Marzinski if (list_empty(&bd->bd_list)) { 5795d054964SBenjamin Marzinski have_revokes = 1; 5805d054964SBenjamin Marzinski goto done; 5815d054964SBenjamin Marzinski } 5825d054964SBenjamin Marzinski } 5835d054964SBenjamin Marzinski } 5845d054964SBenjamin Marzinski done: 5855d054964SBenjamin Marzinski spin_unlock(&sdp->sd_ail_lock); 5865d054964SBenjamin Marzinski if (have_revokes == 0) 5875d054964SBenjamin Marzinski return; 5885d054964SBenjamin Marzinski while (sdp->sd_log_num_revoke > max_revokes) 5895d054964SBenjamin Marzinski max_revokes += (sdp->sd_sb.sb_bsize - sizeof(struct gfs2_meta_header)) / sizeof(u64); 5905d054964SBenjamin Marzinski max_revokes -= sdp->sd_log_num_revoke; 5915d054964SBenjamin Marzinski if (!sdp->sd_log_num_revoke) { 5925d054964SBenjamin Marzinski atomic_dec(&sdp->sd_log_blks_free); 5935d054964SBenjamin Marzinski /* If no blocks have been reserved, we need to also 5945d054964SBenjamin Marzinski * reserve a block for the header */ 5955d054964SBenjamin Marzinski if (!sdp->sd_log_blks_reserved) 5965d054964SBenjamin Marzinski atomic_dec(&sdp->sd_log_blks_free); 5975d054964SBenjamin Marzinski } 5985d054964SBenjamin Marzinski gfs2_log_lock(sdp); 5995d054964SBenjamin Marzinski spin_lock(&sdp->sd_ail_lock); 6005d054964SBenjamin Marzinski list_for_each_entry(tr, &sdp->sd_ail1_list, tr_list) { 6015d054964SBenjamin Marzinski list_for_each_entry_safe(bd, tmp, &tr->tr_ail2_list, bd_ail_st_list) { 6025d054964SBenjamin Marzinski if (max_revokes == 0) 6035d054964SBenjamin Marzinski goto out_of_blocks; 6045d054964SBenjamin Marzinski if (!list_empty(&bd->bd_list)) 6055d054964SBenjamin Marzinski continue; 6065d054964SBenjamin Marzinski gfs2_add_revoke(sdp, bd); 6075d054964SBenjamin Marzinski max_revokes--; 6085d054964SBenjamin Marzinski } 6095d054964SBenjamin Marzinski } 6105d054964SBenjamin Marzinski out_of_blocks: 6115d054964SBenjamin Marzinski spin_unlock(&sdp->sd_ail_lock); 6125d054964SBenjamin Marzinski gfs2_log_unlock(sdp); 6135d054964SBenjamin Marzinski 6145d054964SBenjamin Marzinski if (!sdp->sd_log_num_revoke) { 6155d054964SBenjamin Marzinski atomic_inc(&sdp->sd_log_blks_free); 6165d054964SBenjamin Marzinski if (!sdp->sd_log_blks_reserved) 6175d054964SBenjamin Marzinski atomic_inc(&sdp->sd_log_blks_free); 6185d054964SBenjamin Marzinski } 6195d054964SBenjamin Marzinski } 6205d054964SBenjamin Marzinski 621b3b94faaSDavid Teigland /** 62234cc1781SSteven Whitehouse * log_write_header - Get and initialize a journal header buffer 62334cc1781SSteven Whitehouse * @sdp: The GFS2 superblock 62434cc1781SSteven Whitehouse * 62534cc1781SSteven Whitehouse * Returns: the initialized log buffer descriptor 62634cc1781SSteven Whitehouse */ 62734cc1781SSteven Whitehouse 628fdb76a42SSteven Whitehouse static void log_write_header(struct gfs2_sbd *sdp, u32 flags) 62934cc1781SSteven Whitehouse { 63034cc1781SSteven Whitehouse struct gfs2_log_header *lh; 63134cc1781SSteven Whitehouse unsigned int tail; 63234cc1781SSteven Whitehouse u32 hash; 633e8c92ed7SSteven Whitehouse int rw = WRITE_FLUSH_FUA | REQ_META; 634e8c92ed7SSteven Whitehouse struct page *page = mempool_alloc(gfs2_page_pool, GFP_NOIO); 635e8c92ed7SSteven Whitehouse lh = page_address(page); 636e8c92ed7SSteven Whitehouse clear_page(lh); 63734cc1781SSteven Whitehouse 63834cc1781SSteven Whitehouse tail = current_tail(sdp); 63934cc1781SSteven Whitehouse 64034cc1781SSteven Whitehouse lh->lh_header.mh_magic = cpu_to_be32(GFS2_MAGIC); 64134cc1781SSteven Whitehouse lh->lh_header.mh_type = cpu_to_be32(GFS2_METATYPE_LH); 64234cc1781SSteven Whitehouse lh->lh_header.__pad0 = cpu_to_be64(0); 64334cc1781SSteven Whitehouse lh->lh_header.mh_format = cpu_to_be32(GFS2_FORMAT_LH); 64434cc1781SSteven Whitehouse lh->lh_header.mh_jid = cpu_to_be32(sdp->sd_jdesc->jd_jid); 64534cc1781SSteven Whitehouse lh->lh_sequence = cpu_to_be64(sdp->sd_log_sequence++); 64634cc1781SSteven Whitehouse lh->lh_flags = cpu_to_be32(flags); 64734cc1781SSteven Whitehouse lh->lh_tail = cpu_to_be32(tail); 64834cc1781SSteven Whitehouse lh->lh_blkno = cpu_to_be32(sdp->sd_log_flush_head); 649e8c92ed7SSteven Whitehouse hash = gfs2_disk_hash(page_address(page), sizeof(struct gfs2_log_header)); 65034cc1781SSteven Whitehouse lh->lh_hash = cpu_to_be32(hash); 65134cc1781SSteven Whitehouse 65234cc1781SSteven Whitehouse if (test_bit(SDF_NOBARRIERS, &sdp->sd_flags)) { 65334cc1781SSteven Whitehouse gfs2_ordered_wait(sdp); 65434cc1781SSteven Whitehouse log_flush_wait(sdp); 655e8c92ed7SSteven Whitehouse rw = WRITE_SYNC | REQ_META | REQ_PRIO; 65634cc1781SSteven Whitehouse } 65734cc1781SSteven Whitehouse 658e8c92ed7SSteven Whitehouse sdp->sd_log_idle = (tail == sdp->sd_log_flush_head); 659e8c92ed7SSteven Whitehouse gfs2_log_write_page(sdp, page); 660e8c92ed7SSteven Whitehouse gfs2_log_flush_bio(sdp, rw); 661e8c92ed7SSteven Whitehouse log_flush_wait(sdp); 66234cc1781SSteven Whitehouse 66334cc1781SSteven Whitehouse if (sdp->sd_log_tail != tail) 66434cc1781SSteven Whitehouse log_pull_tail(sdp, tail); 66534cc1781SSteven Whitehouse } 66634cc1781SSteven Whitehouse 66734cc1781SSteven Whitehouse /** 668b09e593dSSteven Whitehouse * gfs2_log_flush - flush incore transaction(s) 669b3b94faaSDavid Teigland * @sdp: the filesystem 670b3b94faaSDavid Teigland * @gl: The glock structure to flush. If NULL, flush the whole incore log 671b3b94faaSDavid Teigland * 672b3b94faaSDavid Teigland */ 673b3b94faaSDavid Teigland 674ed4878e8SBob Peterson void gfs2_log_flush(struct gfs2_sbd *sdp, struct gfs2_glock *gl) 675b3b94faaSDavid Teigland { 67616ca9412SBenjamin Marzinski struct gfs2_trans *tr; 677b3b94faaSDavid Teigland 678484adff8SSteven Whitehouse down_write(&sdp->sd_log_flush_lock); 679f55ab26aSSteven Whitehouse 6802bcd610dSSteven Whitehouse /* Log might have been flushed while we waited for the flush lock */ 6812bcd610dSSteven Whitehouse if (gl && !test_bit(GLF_LFLUSH, &gl->gl_flags)) { 682484adff8SSteven Whitehouse up_write(&sdp->sd_log_flush_lock); 683f55ab26aSSteven Whitehouse return; 684f55ab26aSSteven Whitehouse } 68563997775SSteven Whitehouse trace_gfs2_log_flush(sdp, 1); 686f55ab26aSSteven Whitehouse 687*b1ab1e44SSteven Whitehouse sdp->sd_log_flush_head = sdp->sd_log_head; 688*b1ab1e44SSteven Whitehouse sdp->sd_log_flush_wrapped = 0; 68916ca9412SBenjamin Marzinski tr = sdp->sd_log_tr; 69016ca9412SBenjamin Marzinski if (tr) { 69116ca9412SBenjamin Marzinski sdp->sd_log_tr = NULL; 69216ca9412SBenjamin Marzinski INIT_LIST_HEAD(&tr->tr_ail1_list); 69316ca9412SBenjamin Marzinski INIT_LIST_HEAD(&tr->tr_ail2_list); 694*b1ab1e44SSteven Whitehouse tr->tr_first = sdp->sd_log_flush_head; 69516ca9412SBenjamin Marzinski } 696b3b94faaSDavid Teigland 697b3b94faaSDavid Teigland gfs2_assert_withdraw(sdp, 698b3b94faaSDavid Teigland sdp->sd_log_num_revoke == sdp->sd_log_commited_revoke); 699b3b94faaSDavid Teigland 700d7b616e2SSteven Whitehouse gfs2_ordered_write(sdp); 701d69a3c65SSteven Whitehouse lops_before_commit(sdp, tr); 702e8c92ed7SSteven Whitehouse gfs2_log_flush_bio(sdp, WRITE); 703d7b616e2SSteven Whitehouse 70434cc1781SSteven Whitehouse if (sdp->sd_log_head != sdp->sd_log_flush_head) { 705fdb76a42SSteven Whitehouse log_write_header(sdp, 0); 70634cc1781SSteven Whitehouse } else if (sdp->sd_log_tail != current_tail(sdp) && !sdp->sd_log_idle){ 707fd041f0bSSteven Whitehouse atomic_dec(&sdp->sd_log_blks_free); /* Adjust for unreserved buffer */ 70863997775SSteven Whitehouse trace_gfs2_log_blocks(sdp, -1); 709fdb76a42SSteven Whitehouse log_write_header(sdp, 0); 7102332c443SRobert Peterson } 71116ca9412SBenjamin Marzinski lops_after_commit(sdp, tr); 712fe1a698fSSteven Whitehouse 713fe1a698fSSteven Whitehouse gfs2_log_lock(sdp); 714b3b94faaSDavid Teigland sdp->sd_log_head = sdp->sd_log_flush_head; 715faa31ce8SSteven Whitehouse sdp->sd_log_blks_reserved = 0; 716b3b94faaSDavid Teigland sdp->sd_log_commited_revoke = 0; 717b3b94faaSDavid Teigland 718d6a079e8SDave Chinner spin_lock(&sdp->sd_ail_lock); 71916ca9412SBenjamin Marzinski if (tr && !list_empty(&tr->tr_ail1_list)) { 72016ca9412SBenjamin Marzinski list_add(&tr->tr_list, &sdp->sd_ail1_list); 72116ca9412SBenjamin Marzinski tr = NULL; 722b3b94faaSDavid Teigland } 723d6a079e8SDave Chinner spin_unlock(&sdp->sd_ail_lock); 724b3b94faaSDavid Teigland gfs2_log_unlock(sdp); 72563997775SSteven Whitehouse trace_gfs2_log_flush(sdp, 0); 726484adff8SSteven Whitehouse up_write(&sdp->sd_log_flush_lock); 727b3b94faaSDavid Teigland 72816ca9412SBenjamin Marzinski kfree(tr); 729b3b94faaSDavid Teigland } 730b3b94faaSDavid Teigland 731d69a3c65SSteven Whitehouse /** 732d69a3c65SSteven Whitehouse * gfs2_merge_trans - Merge a new transaction into a cached transaction 733d69a3c65SSteven Whitehouse * @old: Original transaction to be expanded 734d69a3c65SSteven Whitehouse * @new: New transaction to be merged 735d69a3c65SSteven Whitehouse */ 736d69a3c65SSteven Whitehouse 737d69a3c65SSteven Whitehouse static void gfs2_merge_trans(struct gfs2_trans *old, struct gfs2_trans *new) 738d69a3c65SSteven Whitehouse { 739d69a3c65SSteven Whitehouse WARN_ON_ONCE(old->tr_attached != 1); 740d69a3c65SSteven Whitehouse 741d69a3c65SSteven Whitehouse old->tr_num_buf_new += new->tr_num_buf_new; 742d69a3c65SSteven Whitehouse old->tr_num_databuf_new += new->tr_num_databuf_new; 743d69a3c65SSteven Whitehouse old->tr_num_buf_rm += new->tr_num_buf_rm; 744d69a3c65SSteven Whitehouse old->tr_num_databuf_rm += new->tr_num_databuf_rm; 745d69a3c65SSteven Whitehouse old->tr_num_revoke += new->tr_num_revoke; 746d69a3c65SSteven Whitehouse old->tr_num_revoke_rm += new->tr_num_revoke_rm; 747d69a3c65SSteven Whitehouse 748d69a3c65SSteven Whitehouse list_splice_tail_init(&new->tr_databuf, &old->tr_databuf); 749d69a3c65SSteven Whitehouse list_splice_tail_init(&new->tr_buf, &old->tr_buf); 750d69a3c65SSteven Whitehouse } 751d69a3c65SSteven Whitehouse 752b3b94faaSDavid Teigland static void log_refund(struct gfs2_sbd *sdp, struct gfs2_trans *tr) 753b3b94faaSDavid Teigland { 7542332c443SRobert Peterson unsigned int reserved; 755ac39aaddSSteven Whitehouse unsigned int unused; 756022ef4feSSteven Whitehouse unsigned int maxres; 757b3b94faaSDavid Teigland 758b3b94faaSDavid Teigland gfs2_log_lock(sdp); 759b3b94faaSDavid Teigland 760d69a3c65SSteven Whitehouse if (sdp->sd_log_tr) { 761d69a3c65SSteven Whitehouse gfs2_merge_trans(sdp->sd_log_tr, tr); 762d69a3c65SSteven Whitehouse } else if (tr->tr_num_buf_new || tr->tr_num_databuf_new) { 76316ca9412SBenjamin Marzinski gfs2_assert_withdraw(sdp, tr->tr_t_gh.gh_gl); 76416ca9412SBenjamin Marzinski sdp->sd_log_tr = tr; 76516ca9412SBenjamin Marzinski tr->tr_attached = 1; 76616ca9412SBenjamin Marzinski } 767022ef4feSSteven Whitehouse 768022ef4feSSteven Whitehouse sdp->sd_log_commited_revoke += tr->tr_num_revoke - tr->tr_num_revoke_rm; 769022ef4feSSteven Whitehouse reserved = calc_reserved(sdp); 770022ef4feSSteven Whitehouse maxres = sdp->sd_log_blks_reserved + tr->tr_reserved; 771022ef4feSSteven Whitehouse gfs2_assert_withdraw(sdp, maxres >= reserved); 772022ef4feSSteven Whitehouse unused = maxres - reserved; 773022ef4feSSteven Whitehouse atomic_add(unused, &sdp->sd_log_blks_free); 774022ef4feSSteven Whitehouse trace_gfs2_log_blocks(sdp, unused); 775022ef4feSSteven Whitehouse gfs2_assert_withdraw(sdp, atomic_read(&sdp->sd_log_blks_free) <= 776022ef4feSSteven Whitehouse sdp->sd_jdesc->jd_blocks); 777022ef4feSSteven Whitehouse sdp->sd_log_blks_reserved = reserved; 778022ef4feSSteven Whitehouse 779b3b94faaSDavid Teigland gfs2_log_unlock(sdp); 780b3b94faaSDavid Teigland } 781b3b94faaSDavid Teigland 782b3b94faaSDavid Teigland /** 783b3b94faaSDavid Teigland * gfs2_log_commit - Commit a transaction to the log 784b3b94faaSDavid Teigland * @sdp: the filesystem 785b3b94faaSDavid Teigland * @tr: the transaction 786b3b94faaSDavid Teigland * 7875e687eacSBenjamin Marzinski * We wake up gfs2_logd if the number of pinned blocks exceed thresh1 7885e687eacSBenjamin Marzinski * or the total number of used blocks (pinned blocks plus AIL blocks) 7895e687eacSBenjamin Marzinski * is greater than thresh2. 7905e687eacSBenjamin Marzinski * 7915e687eacSBenjamin Marzinski * At mount time thresh1 is 1/3rd of journal size, thresh2 is 2/3rd of 7925e687eacSBenjamin Marzinski * journal size. 7935e687eacSBenjamin Marzinski * 794b3b94faaSDavid Teigland * Returns: errno 795b3b94faaSDavid Teigland */ 796b3b94faaSDavid Teigland 797b3b94faaSDavid Teigland void gfs2_log_commit(struct gfs2_sbd *sdp, struct gfs2_trans *tr) 798b3b94faaSDavid Teigland { 799b3b94faaSDavid Teigland log_refund(sdp, tr); 800b3b94faaSDavid Teigland 8015e687eacSBenjamin Marzinski if (atomic_read(&sdp->sd_log_pinned) > atomic_read(&sdp->sd_log_thresh1) || 8025e687eacSBenjamin Marzinski ((sdp->sd_jdesc->jd_blocks - atomic_read(&sdp->sd_log_blks_free)) > 8035e687eacSBenjamin Marzinski atomic_read(&sdp->sd_log_thresh2))) 8045e687eacSBenjamin Marzinski wake_up(&sdp->sd_logd_waitq); 805faa31ce8SSteven Whitehouse } 806b3b94faaSDavid Teigland 807b3b94faaSDavid Teigland /** 808b3b94faaSDavid Teigland * gfs2_log_shutdown - write a shutdown header into a journal 809b3b94faaSDavid Teigland * @sdp: the filesystem 810b3b94faaSDavid Teigland * 811b3b94faaSDavid Teigland */ 812b3b94faaSDavid Teigland 813b3b94faaSDavid Teigland void gfs2_log_shutdown(struct gfs2_sbd *sdp) 814b3b94faaSDavid Teigland { 815484adff8SSteven Whitehouse down_write(&sdp->sd_log_flush_lock); 816b3b94faaSDavid Teigland 817b3b94faaSDavid Teigland gfs2_assert_withdraw(sdp, !sdp->sd_log_blks_reserved); 818b3b94faaSDavid Teigland gfs2_assert_withdraw(sdp, !sdp->sd_log_num_revoke); 819b3b94faaSDavid Teigland gfs2_assert_withdraw(sdp, list_empty(&sdp->sd_ail1_list)); 820b3b94faaSDavid Teigland 821b3b94faaSDavid Teigland sdp->sd_log_flush_head = sdp->sd_log_head; 822b3b94faaSDavid Teigland sdp->sd_log_flush_wrapped = 0; 823b3b94faaSDavid Teigland 824fdb76a42SSteven Whitehouse log_write_header(sdp, GFS2_LOG_HEAD_UNMOUNT); 825b3b94faaSDavid Teigland 826fd041f0bSSteven Whitehouse gfs2_assert_warn(sdp, atomic_read(&sdp->sd_log_blks_free) == sdp->sd_jdesc->jd_blocks); 827a74604beSSteven Whitehouse gfs2_assert_warn(sdp, sdp->sd_log_head == sdp->sd_log_tail); 828a74604beSSteven Whitehouse gfs2_assert_warn(sdp, list_empty(&sdp->sd_ail2_list)); 829b3b94faaSDavid Teigland 830b3b94faaSDavid Teigland sdp->sd_log_head = sdp->sd_log_flush_head; 831b3b94faaSDavid Teigland sdp->sd_log_tail = sdp->sd_log_head; 832b3b94faaSDavid Teigland 833484adff8SSteven Whitehouse up_write(&sdp->sd_log_flush_lock); 834b3b94faaSDavid Teigland } 835b3b94faaSDavid Teigland 836a25311c8SSteven Whitehouse 837a25311c8SSteven Whitehouse /** 838a25311c8SSteven Whitehouse * gfs2_meta_syncfs - sync all the buffers in a filesystem 839a25311c8SSteven Whitehouse * @sdp: the filesystem 840a25311c8SSteven Whitehouse * 841a25311c8SSteven Whitehouse */ 842a25311c8SSteven Whitehouse 843a25311c8SSteven Whitehouse void gfs2_meta_syncfs(struct gfs2_sbd *sdp) 844a25311c8SSteven Whitehouse { 845a25311c8SSteven Whitehouse gfs2_log_flush(sdp, NULL); 846a25311c8SSteven Whitehouse for (;;) { 8475e687eacSBenjamin Marzinski gfs2_ail1_start(sdp); 84826b06a69SSteven Whitehouse gfs2_ail1_wait(sdp); 8494667a0ecSSteven Whitehouse if (gfs2_ail1_empty(sdp)) 850a25311c8SSteven Whitehouse break; 851a25311c8SSteven Whitehouse } 852380f7c65SSteven Whitehouse gfs2_log_flush(sdp, NULL); 853a25311c8SSteven Whitehouse } 854a25311c8SSteven Whitehouse 8555e687eacSBenjamin Marzinski static inline int gfs2_jrnl_flush_reqd(struct gfs2_sbd *sdp) 8565e687eacSBenjamin Marzinski { 8575e687eacSBenjamin Marzinski return (atomic_read(&sdp->sd_log_pinned) >= atomic_read(&sdp->sd_log_thresh1)); 8585e687eacSBenjamin Marzinski } 8595e687eacSBenjamin Marzinski 8605e687eacSBenjamin Marzinski static inline int gfs2_ail_flush_reqd(struct gfs2_sbd *sdp) 8615e687eacSBenjamin Marzinski { 8625e687eacSBenjamin Marzinski unsigned int used_blocks = sdp->sd_jdesc->jd_blocks - atomic_read(&sdp->sd_log_blks_free); 8635e687eacSBenjamin Marzinski return used_blocks >= atomic_read(&sdp->sd_log_thresh2); 8645e687eacSBenjamin Marzinski } 865ec69b188SSteven Whitehouse 866ec69b188SSteven Whitehouse /** 867ec69b188SSteven Whitehouse * gfs2_logd - Update log tail as Active Items get flushed to in-place blocks 868ec69b188SSteven Whitehouse * @sdp: Pointer to GFS2 superblock 869ec69b188SSteven Whitehouse * 870ec69b188SSteven Whitehouse * Also, periodically check to make sure that we're using the most recent 871ec69b188SSteven Whitehouse * journal index. 872ec69b188SSteven Whitehouse */ 873ec69b188SSteven Whitehouse 874ec69b188SSteven Whitehouse int gfs2_logd(void *data) 875ec69b188SSteven Whitehouse { 876ec69b188SSteven Whitehouse struct gfs2_sbd *sdp = data; 8775e687eacSBenjamin Marzinski unsigned long t = 1; 8785e687eacSBenjamin Marzinski DEFINE_WAIT(wait); 879ec69b188SSteven Whitehouse 880ec69b188SSteven Whitehouse while (!kthread_should_stop()) { 881ec69b188SSteven Whitehouse 8825e687eacSBenjamin Marzinski if (gfs2_jrnl_flush_reqd(sdp) || t == 0) { 8834667a0ecSSteven Whitehouse gfs2_ail1_empty(sdp); 884ec69b188SSteven Whitehouse gfs2_log_flush(sdp, NULL); 885ec69b188SSteven Whitehouse } 886ec69b188SSteven Whitehouse 8875e687eacSBenjamin Marzinski if (gfs2_ail_flush_reqd(sdp)) { 8885e687eacSBenjamin Marzinski gfs2_ail1_start(sdp); 88926b06a69SSteven Whitehouse gfs2_ail1_wait(sdp); 8904667a0ecSSteven Whitehouse gfs2_ail1_empty(sdp); 8915e687eacSBenjamin Marzinski gfs2_log_flush(sdp, NULL); 8925e687eacSBenjamin Marzinski } 8935e687eacSBenjamin Marzinski 89426b06a69SSteven Whitehouse if (!gfs2_ail_flush_reqd(sdp)) 8955e687eacSBenjamin Marzinski wake_up(&sdp->sd_log_waitq); 89626b06a69SSteven Whitehouse 897ec69b188SSteven Whitehouse t = gfs2_tune_get(sdp, gt_logd_secs) * HZ; 898a0acae0eSTejun Heo 899a0acae0eSTejun Heo try_to_freeze(); 9005e687eacSBenjamin Marzinski 9015e687eacSBenjamin Marzinski do { 9025e687eacSBenjamin Marzinski prepare_to_wait(&sdp->sd_logd_waitq, &wait, 9035f487490SSteven Whitehouse TASK_INTERRUPTIBLE); 9045e687eacSBenjamin Marzinski if (!gfs2_ail_flush_reqd(sdp) && 9055e687eacSBenjamin Marzinski !gfs2_jrnl_flush_reqd(sdp) && 9065e687eacSBenjamin Marzinski !kthread_should_stop()) 9075e687eacSBenjamin Marzinski t = schedule_timeout(t); 9085e687eacSBenjamin Marzinski } while(t && !gfs2_ail_flush_reqd(sdp) && 9095e687eacSBenjamin Marzinski !gfs2_jrnl_flush_reqd(sdp) && 9105e687eacSBenjamin Marzinski !kthread_should_stop()); 9115e687eacSBenjamin Marzinski finish_wait(&sdp->sd_logd_waitq, &wait); 912ec69b188SSteven Whitehouse } 913ec69b188SSteven Whitehouse 914ec69b188SSteven Whitehouse return 0; 915ec69b188SSteven Whitehouse } 916ec69b188SSteven Whitehouse 917