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> 214667a0ecSSteven Whitehouse #include <linux/writeback.h> 224a36d08dSBob Peterson #include <linux/list_sort.h> 23b3b94faaSDavid Teigland 24b3b94faaSDavid Teigland #include "gfs2.h" 255c676f6dSSteven Whitehouse #include "incore.h" 26b3b94faaSDavid Teigland #include "bmap.h" 27b3b94faaSDavid Teigland #include "glock.h" 28b3b94faaSDavid Teigland #include "log.h" 29b3b94faaSDavid Teigland #include "lops.h" 30b3b94faaSDavid Teigland #include "meta_io.h" 315c676f6dSSteven Whitehouse #include "util.h" 3271b86f56SSteven Whitehouse #include "dir.h" 3363997775SSteven Whitehouse #include "trace_gfs2.h" 34b3b94faaSDavid Teigland 35b3b94faaSDavid Teigland /** 36b3b94faaSDavid Teigland * gfs2_struct2blk - compute stuff 37b3b94faaSDavid Teigland * @sdp: the filesystem 38b3b94faaSDavid Teigland * @nstruct: the number of structures 39b3b94faaSDavid Teigland * @ssize: the size of the structures 40b3b94faaSDavid Teigland * 41b3b94faaSDavid Teigland * Compute the number of log descriptor blocks needed to hold a certain number 42b3b94faaSDavid Teigland * of structures of a certain size. 43b3b94faaSDavid Teigland * 44b3b94faaSDavid Teigland * Returns: the number of blocks needed (minimum is always 1) 45b3b94faaSDavid Teigland */ 46b3b94faaSDavid Teigland 47b3b94faaSDavid Teigland unsigned int gfs2_struct2blk(struct gfs2_sbd *sdp, unsigned int nstruct, 48b3b94faaSDavid Teigland unsigned int ssize) 49b3b94faaSDavid Teigland { 50b3b94faaSDavid Teigland unsigned int blks; 51b3b94faaSDavid Teigland unsigned int first, second; 52b3b94faaSDavid Teigland 53b3b94faaSDavid Teigland blks = 1; 54faa31ce8SSteven Whitehouse first = (sdp->sd_sb.sb_bsize - sizeof(struct gfs2_log_descriptor)) / ssize; 55b3b94faaSDavid Teigland 56b3b94faaSDavid Teigland if (nstruct > first) { 57568f4c96SSteven Whitehouse second = (sdp->sd_sb.sb_bsize - 58568f4c96SSteven Whitehouse sizeof(struct gfs2_meta_header)) / ssize; 595c676f6dSSteven Whitehouse blks += DIV_ROUND_UP(nstruct - first, second); 60b3b94faaSDavid Teigland } 61b3b94faaSDavid Teigland 62b3b94faaSDavid Teigland return blks; 63b3b94faaSDavid Teigland } 64b3b94faaSDavid Teigland 65ddacfaf7SSteven Whitehouse /** 661e1a3d03SSteven Whitehouse * gfs2_remove_from_ail - Remove an entry from the ail lists, updating counters 671e1a3d03SSteven Whitehouse * @mapping: The associated mapping (maybe NULL) 681e1a3d03SSteven Whitehouse * @bd: The gfs2_bufdata to remove 691e1a3d03SSteven Whitehouse * 70c618e87aSSteven Whitehouse * The ail lock _must_ be held when calling this function 711e1a3d03SSteven Whitehouse * 721e1a3d03SSteven Whitehouse */ 731e1a3d03SSteven Whitehouse 74f91a0d3eSSteven Whitehouse void gfs2_remove_from_ail(struct gfs2_bufdata *bd) 751e1a3d03SSteven Whitehouse { 76*16ca9412SBenjamin Marzinski bd->bd_tr = NULL; 771ad38c43SSteven Whitehouse list_del_init(&bd->bd_ail_st_list); 781ad38c43SSteven Whitehouse list_del_init(&bd->bd_ail_gl_list); 791e1a3d03SSteven Whitehouse atomic_dec(&bd->bd_gl->gl_ail_count); 801e1a3d03SSteven Whitehouse brelse(bd->bd_bh); 811e1a3d03SSteven Whitehouse } 821e1a3d03SSteven Whitehouse 831e1a3d03SSteven Whitehouse /** 84ddacfaf7SSteven Whitehouse * gfs2_ail1_start_one - Start I/O on a part of the AIL 85ddacfaf7SSteven Whitehouse * @sdp: the filesystem 864667a0ecSSteven Whitehouse * @wbc: The writeback control structure 874667a0ecSSteven Whitehouse * @ai: The ail structure 88ddacfaf7SSteven Whitehouse * 89ddacfaf7SSteven Whitehouse */ 90ddacfaf7SSteven Whitehouse 914f1de018SSteven Whitehouse static int gfs2_ail1_start_one(struct gfs2_sbd *sdp, 924667a0ecSSteven Whitehouse struct writeback_control *wbc, 93*16ca9412SBenjamin Marzinski struct gfs2_trans *tr) 94d6a079e8SDave Chinner __releases(&sdp->sd_ail_lock) 95d6a079e8SDave Chinner __acquires(&sdp->sd_ail_lock) 96ddacfaf7SSteven Whitehouse { 975ac048bbSSteven Whitehouse struct gfs2_glock *gl = NULL; 984667a0ecSSteven Whitehouse struct address_space *mapping; 99ddacfaf7SSteven Whitehouse struct gfs2_bufdata *bd, *s; 100ddacfaf7SSteven Whitehouse struct buffer_head *bh; 101ddacfaf7SSteven Whitehouse 102*16ca9412SBenjamin Marzinski list_for_each_entry_safe_reverse(bd, s, &tr->tr_ail1_list, bd_ail_st_list) { 103ddacfaf7SSteven Whitehouse bh = bd->bd_bh; 104ddacfaf7SSteven Whitehouse 105*16ca9412SBenjamin Marzinski gfs2_assert(sdp, bd->bd_tr == tr); 106ddacfaf7SSteven Whitehouse 107ddacfaf7SSteven Whitehouse if (!buffer_busy(bh)) { 10816615be1SSteven Whitehouse if (!buffer_uptodate(bh)) 109ddacfaf7SSteven Whitehouse gfs2_io_error_bh(sdp, bh); 110*16ca9412SBenjamin Marzinski list_move(&bd->bd_ail_st_list, &tr->tr_ail2_list); 111ddacfaf7SSteven Whitehouse continue; 112ddacfaf7SSteven Whitehouse } 113ddacfaf7SSteven Whitehouse 114ddacfaf7SSteven Whitehouse if (!buffer_dirty(bh)) 115ddacfaf7SSteven Whitehouse continue; 1165ac048bbSSteven Whitehouse if (gl == bd->bd_gl) 1175ac048bbSSteven Whitehouse continue; 1185ac048bbSSteven Whitehouse gl = bd->bd_gl; 119*16ca9412SBenjamin Marzinski list_move(&bd->bd_ail_st_list, &tr->tr_ail1_list); 1204667a0ecSSteven Whitehouse mapping = bh->b_page->mapping; 1214f1de018SSteven Whitehouse if (!mapping) 1224f1de018SSteven Whitehouse continue; 123d6a079e8SDave Chinner spin_unlock(&sdp->sd_ail_lock); 1244667a0ecSSteven Whitehouse generic_writepages(mapping, wbc); 125d6a079e8SDave Chinner spin_lock(&sdp->sd_ail_lock); 1264667a0ecSSteven Whitehouse if (wbc->nr_to_write <= 0) 127ddacfaf7SSteven Whitehouse break; 1284f1de018SSteven Whitehouse return 1; 129ddacfaf7SSteven Whitehouse } 1304f1de018SSteven Whitehouse 1314f1de018SSteven Whitehouse return 0; 1324667a0ecSSteven Whitehouse } 1334667a0ecSSteven Whitehouse 1344667a0ecSSteven Whitehouse 1354667a0ecSSteven Whitehouse /** 1364667a0ecSSteven Whitehouse * gfs2_ail1_flush - start writeback of some ail1 entries 1374667a0ecSSteven Whitehouse * @sdp: The super block 1384667a0ecSSteven Whitehouse * @wbc: The writeback control structure 1394667a0ecSSteven Whitehouse * 1404667a0ecSSteven Whitehouse * Writes back some ail1 entries, according to the limits in the 1414667a0ecSSteven Whitehouse * writeback control structure 1424667a0ecSSteven Whitehouse */ 1434667a0ecSSteven Whitehouse 1444667a0ecSSteven Whitehouse void gfs2_ail1_flush(struct gfs2_sbd *sdp, struct writeback_control *wbc) 1454667a0ecSSteven Whitehouse { 1464667a0ecSSteven Whitehouse struct list_head *head = &sdp->sd_ail1_list; 147*16ca9412SBenjamin Marzinski struct gfs2_trans *tr; 1484667a0ecSSteven Whitehouse 149c83ae9caSSteven Whitehouse trace_gfs2_ail_flush(sdp, wbc, 1); 1504667a0ecSSteven Whitehouse spin_lock(&sdp->sd_ail_lock); 1514f1de018SSteven Whitehouse restart: 152*16ca9412SBenjamin Marzinski list_for_each_entry_reverse(tr, head, tr_list) { 1534667a0ecSSteven Whitehouse if (wbc->nr_to_write <= 0) 1544667a0ecSSteven Whitehouse break; 155*16ca9412SBenjamin Marzinski if (gfs2_ail1_start_one(sdp, wbc, tr)) 1564f1de018SSteven Whitehouse goto restart; 1574667a0ecSSteven Whitehouse } 1584667a0ecSSteven Whitehouse spin_unlock(&sdp->sd_ail_lock); 159c83ae9caSSteven Whitehouse trace_gfs2_ail_flush(sdp, wbc, 0); 1604667a0ecSSteven Whitehouse } 1614667a0ecSSteven Whitehouse 1624667a0ecSSteven Whitehouse /** 1634667a0ecSSteven Whitehouse * gfs2_ail1_start - start writeback of all ail1 entries 1644667a0ecSSteven Whitehouse * @sdp: The superblock 1654667a0ecSSteven Whitehouse */ 1664667a0ecSSteven Whitehouse 1674667a0ecSSteven Whitehouse static void gfs2_ail1_start(struct gfs2_sbd *sdp) 1684667a0ecSSteven Whitehouse { 1694667a0ecSSteven Whitehouse struct writeback_control wbc = { 1704667a0ecSSteven Whitehouse .sync_mode = WB_SYNC_NONE, 1714667a0ecSSteven Whitehouse .nr_to_write = LONG_MAX, 1724667a0ecSSteven Whitehouse .range_start = 0, 1734667a0ecSSteven Whitehouse .range_end = LLONG_MAX, 1744667a0ecSSteven Whitehouse }; 1754667a0ecSSteven Whitehouse 1764667a0ecSSteven Whitehouse return gfs2_ail1_flush(sdp, &wbc); 177ddacfaf7SSteven Whitehouse } 178ddacfaf7SSteven Whitehouse 179ddacfaf7SSteven Whitehouse /** 180ddacfaf7SSteven Whitehouse * gfs2_ail1_empty_one - Check whether or not a trans in the AIL has been synced 181ddacfaf7SSteven Whitehouse * @sdp: the filesystem 182ddacfaf7SSteven Whitehouse * @ai: the AIL entry 183ddacfaf7SSteven Whitehouse * 184ddacfaf7SSteven Whitehouse */ 185ddacfaf7SSteven Whitehouse 186*16ca9412SBenjamin Marzinski static void gfs2_ail1_empty_one(struct gfs2_sbd *sdp, struct gfs2_trans *tr) 187ddacfaf7SSteven Whitehouse { 188ddacfaf7SSteven Whitehouse struct gfs2_bufdata *bd, *s; 189ddacfaf7SSteven Whitehouse struct buffer_head *bh; 190ddacfaf7SSteven Whitehouse 191*16ca9412SBenjamin Marzinski list_for_each_entry_safe_reverse(bd, s, &tr->tr_ail1_list, 192ddacfaf7SSteven Whitehouse bd_ail_st_list) { 193ddacfaf7SSteven Whitehouse bh = bd->bd_bh; 194*16ca9412SBenjamin Marzinski gfs2_assert(sdp, bd->bd_tr == tr); 1954667a0ecSSteven Whitehouse if (buffer_busy(bh)) 196ddacfaf7SSteven Whitehouse continue; 197ddacfaf7SSteven Whitehouse if (!buffer_uptodate(bh)) 198ddacfaf7SSteven Whitehouse gfs2_io_error_bh(sdp, bh); 199*16ca9412SBenjamin Marzinski list_move(&bd->bd_ail_st_list, &tr->tr_ail2_list); 200ddacfaf7SSteven Whitehouse } 201ddacfaf7SSteven Whitehouse 202ddacfaf7SSteven Whitehouse } 203ddacfaf7SSteven Whitehouse 2044667a0ecSSteven Whitehouse /** 2054667a0ecSSteven Whitehouse * gfs2_ail1_empty - Try to empty the ail1 lists 2064667a0ecSSteven Whitehouse * @sdp: The superblock 2074667a0ecSSteven Whitehouse * 2084667a0ecSSteven Whitehouse * Tries to empty the ail1 lists, starting with the oldest first 2094667a0ecSSteven Whitehouse */ 210b3b94faaSDavid Teigland 2114667a0ecSSteven Whitehouse static int gfs2_ail1_empty(struct gfs2_sbd *sdp) 212b3b94faaSDavid Teigland { 213*16ca9412SBenjamin Marzinski struct gfs2_trans *tr, *s; 214b3b94faaSDavid Teigland int ret; 215b3b94faaSDavid Teigland 216d6a079e8SDave Chinner spin_lock(&sdp->sd_ail_lock); 217*16ca9412SBenjamin Marzinski list_for_each_entry_safe_reverse(tr, s, &sdp->sd_ail1_list, tr_list) { 218*16ca9412SBenjamin Marzinski gfs2_ail1_empty_one(sdp, tr); 219*16ca9412SBenjamin Marzinski if (list_empty(&tr->tr_ail1_list)) 220*16ca9412SBenjamin Marzinski list_move(&tr->tr_list, &sdp->sd_ail2_list); 2214667a0ecSSteven Whitehouse else 222b3b94faaSDavid Teigland break; 223b3b94faaSDavid Teigland } 224b3b94faaSDavid Teigland ret = list_empty(&sdp->sd_ail1_list); 225d6a079e8SDave Chinner spin_unlock(&sdp->sd_ail_lock); 226b3b94faaSDavid Teigland 227b3b94faaSDavid Teigland return ret; 228b3b94faaSDavid Teigland } 229b3b94faaSDavid Teigland 23026b06a69SSteven Whitehouse static void gfs2_ail1_wait(struct gfs2_sbd *sdp) 23126b06a69SSteven Whitehouse { 232*16ca9412SBenjamin Marzinski struct gfs2_trans *tr; 23326b06a69SSteven Whitehouse struct gfs2_bufdata *bd; 23426b06a69SSteven Whitehouse struct buffer_head *bh; 23526b06a69SSteven Whitehouse 23626b06a69SSteven Whitehouse spin_lock(&sdp->sd_ail_lock); 237*16ca9412SBenjamin Marzinski list_for_each_entry_reverse(tr, &sdp->sd_ail1_list, tr_list) { 238*16ca9412SBenjamin Marzinski list_for_each_entry(bd, &tr->tr_ail1_list, bd_ail_st_list) { 23926b06a69SSteven Whitehouse bh = bd->bd_bh; 24026b06a69SSteven Whitehouse if (!buffer_locked(bh)) 24126b06a69SSteven Whitehouse continue; 24226b06a69SSteven Whitehouse get_bh(bh); 24326b06a69SSteven Whitehouse spin_unlock(&sdp->sd_ail_lock); 24426b06a69SSteven Whitehouse wait_on_buffer(bh); 24526b06a69SSteven Whitehouse brelse(bh); 24626b06a69SSteven Whitehouse return; 24726b06a69SSteven Whitehouse } 24826b06a69SSteven Whitehouse } 24926b06a69SSteven Whitehouse spin_unlock(&sdp->sd_ail_lock); 25026b06a69SSteven Whitehouse } 251ddacfaf7SSteven Whitehouse 252ddacfaf7SSteven Whitehouse /** 253ddacfaf7SSteven Whitehouse * gfs2_ail2_empty_one - Check whether or not a trans in the AIL has been synced 254ddacfaf7SSteven Whitehouse * @sdp: the filesystem 255ddacfaf7SSteven Whitehouse * @ai: the AIL entry 256ddacfaf7SSteven Whitehouse * 257ddacfaf7SSteven Whitehouse */ 258ddacfaf7SSteven Whitehouse 259*16ca9412SBenjamin Marzinski static void gfs2_ail2_empty_one(struct gfs2_sbd *sdp, struct gfs2_trans *tr) 260ddacfaf7SSteven Whitehouse { 261*16ca9412SBenjamin Marzinski struct list_head *head = &tr->tr_ail2_list; 262ddacfaf7SSteven Whitehouse struct gfs2_bufdata *bd; 263ddacfaf7SSteven Whitehouse 264ddacfaf7SSteven Whitehouse while (!list_empty(head)) { 265ddacfaf7SSteven Whitehouse bd = list_entry(head->prev, struct gfs2_bufdata, 266ddacfaf7SSteven Whitehouse bd_ail_st_list); 267*16ca9412SBenjamin Marzinski gfs2_assert(sdp, bd->bd_tr == tr); 268f91a0d3eSSteven Whitehouse gfs2_remove_from_ail(bd); 269ddacfaf7SSteven Whitehouse } 270ddacfaf7SSteven Whitehouse } 271ddacfaf7SSteven Whitehouse 272b3b94faaSDavid Teigland static void ail2_empty(struct gfs2_sbd *sdp, unsigned int new_tail) 273b3b94faaSDavid Teigland { 274*16ca9412SBenjamin Marzinski struct gfs2_trans *tr, *safe; 275b3b94faaSDavid Teigland unsigned int old_tail = sdp->sd_log_tail; 276b3b94faaSDavid Teigland int wrap = (new_tail < old_tail); 277b3b94faaSDavid Teigland int a, b, rm; 278b3b94faaSDavid Teigland 279d6a079e8SDave Chinner spin_lock(&sdp->sd_ail_lock); 280b3b94faaSDavid Teigland 281*16ca9412SBenjamin Marzinski list_for_each_entry_safe(tr, safe, &sdp->sd_ail2_list, tr_list) { 282*16ca9412SBenjamin Marzinski a = (old_tail <= tr->tr_first); 283*16ca9412SBenjamin Marzinski b = (tr->tr_first < new_tail); 284b3b94faaSDavid Teigland rm = (wrap) ? (a || b) : (a && b); 285b3b94faaSDavid Teigland if (!rm) 286b3b94faaSDavid Teigland continue; 287b3b94faaSDavid Teigland 288*16ca9412SBenjamin Marzinski gfs2_ail2_empty_one(sdp, tr); 289*16ca9412SBenjamin Marzinski list_del(&tr->tr_list); 290*16ca9412SBenjamin Marzinski gfs2_assert_warn(sdp, list_empty(&tr->tr_ail1_list)); 291*16ca9412SBenjamin Marzinski gfs2_assert_warn(sdp, list_empty(&tr->tr_ail2_list)); 292*16ca9412SBenjamin Marzinski kfree(tr); 293b3b94faaSDavid Teigland } 294b3b94faaSDavid Teigland 295d6a079e8SDave Chinner spin_unlock(&sdp->sd_ail_lock); 296b3b94faaSDavid Teigland } 297b3b94faaSDavid Teigland 298b3b94faaSDavid Teigland /** 299b3b94faaSDavid Teigland * gfs2_log_reserve - Make a log reservation 300b3b94faaSDavid Teigland * @sdp: The GFS2 superblock 301b3b94faaSDavid Teigland * @blks: The number of blocks to reserve 302b3b94faaSDavid Teigland * 30389918647SSteven Whitehouse * Note that we never give out the last few blocks of the journal. Thats 3042332c443SRobert Peterson * due to the fact that there is a small number of header blocks 305b004157aSSteven Whitehouse * associated with each log flush. The exact number can't be known until 306b004157aSSteven Whitehouse * flush time, so we ensure that we have just enough free blocks at all 307b004157aSSteven Whitehouse * times to avoid running out during a log flush. 308b004157aSSteven Whitehouse * 3095e687eacSBenjamin Marzinski * We no longer flush the log here, instead we wake up logd to do that 3105e687eacSBenjamin Marzinski * for us. To avoid the thundering herd and to ensure that we deal fairly 3115e687eacSBenjamin Marzinski * with queued waiters, we use an exclusive wait. This means that when we 3125e687eacSBenjamin Marzinski * get woken with enough journal space to get our reservation, we need to 3135e687eacSBenjamin Marzinski * wake the next waiter on the list. 3145e687eacSBenjamin Marzinski * 315b3b94faaSDavid Teigland * Returns: errno 316b3b94faaSDavid Teigland */ 317b3b94faaSDavid Teigland 318b3b94faaSDavid Teigland int gfs2_log_reserve(struct gfs2_sbd *sdp, unsigned int blks) 319b3b94faaSDavid Teigland { 32089918647SSteven Whitehouse unsigned reserved_blks = 6 * (4096 / sdp->sd_vfs->s_blocksize); 3215e687eacSBenjamin Marzinski unsigned wanted = blks + reserved_blks; 3225e687eacSBenjamin Marzinski DEFINE_WAIT(wait); 3235e687eacSBenjamin Marzinski int did_wait = 0; 3245e687eacSBenjamin Marzinski unsigned int free_blocks; 325b3b94faaSDavid Teigland 326b3b94faaSDavid Teigland if (gfs2_assert_warn(sdp, blks) || 327b3b94faaSDavid Teigland gfs2_assert_warn(sdp, blks <= sdp->sd_jdesc->jd_blocks)) 328b3b94faaSDavid Teigland return -EINVAL; 3295e687eacSBenjamin Marzinski retry: 3305e687eacSBenjamin Marzinski free_blocks = atomic_read(&sdp->sd_log_blks_free); 3315e687eacSBenjamin Marzinski if (unlikely(free_blocks <= wanted)) { 3325e687eacSBenjamin Marzinski do { 3335e687eacSBenjamin Marzinski prepare_to_wait_exclusive(&sdp->sd_log_waitq, &wait, 3345e687eacSBenjamin Marzinski TASK_UNINTERRUPTIBLE); 3355e687eacSBenjamin Marzinski wake_up(&sdp->sd_logd_waitq); 3365e687eacSBenjamin Marzinski did_wait = 1; 3375e687eacSBenjamin Marzinski if (atomic_read(&sdp->sd_log_blks_free) <= wanted) 3385e687eacSBenjamin Marzinski io_schedule(); 3395e687eacSBenjamin Marzinski free_blocks = atomic_read(&sdp->sd_log_blks_free); 3405e687eacSBenjamin Marzinski } while(free_blocks <= wanted); 3415e687eacSBenjamin Marzinski finish_wait(&sdp->sd_log_waitq, &wait); 342b3b94faaSDavid Teigland } 3435e687eacSBenjamin Marzinski if (atomic_cmpxchg(&sdp->sd_log_blks_free, free_blocks, 3445e687eacSBenjamin Marzinski free_blocks - blks) != free_blocks) 3455e687eacSBenjamin Marzinski goto retry; 34663997775SSteven Whitehouse trace_gfs2_log_blocks(sdp, -blks); 3475e687eacSBenjamin Marzinski 3485e687eacSBenjamin Marzinski /* 3495e687eacSBenjamin Marzinski * If we waited, then so might others, wake them up _after_ we get 3505e687eacSBenjamin Marzinski * our share of the log. 3515e687eacSBenjamin Marzinski */ 3525e687eacSBenjamin Marzinski if (unlikely(did_wait)) 3535e687eacSBenjamin Marzinski wake_up(&sdp->sd_log_waitq); 354484adff8SSteven Whitehouse 355484adff8SSteven Whitehouse down_read(&sdp->sd_log_flush_lock); 356b3b94faaSDavid Teigland 357b3b94faaSDavid Teigland return 0; 358b3b94faaSDavid Teigland } 359b3b94faaSDavid Teigland 360b3b94faaSDavid Teigland /** 361b3b94faaSDavid Teigland * log_distance - Compute distance between two journal blocks 362b3b94faaSDavid Teigland * @sdp: The GFS2 superblock 363b3b94faaSDavid Teigland * @newer: The most recent journal block of the pair 364b3b94faaSDavid Teigland * @older: The older journal block of the pair 365b3b94faaSDavid Teigland * 366b3b94faaSDavid Teigland * Compute the distance (in the journal direction) between two 367b3b94faaSDavid Teigland * blocks in the journal 368b3b94faaSDavid Teigland * 369b3b94faaSDavid Teigland * Returns: the distance in blocks 370b3b94faaSDavid Teigland */ 371b3b94faaSDavid Teigland 372faa31ce8SSteven Whitehouse static inline unsigned int log_distance(struct gfs2_sbd *sdp, unsigned int newer, 373b3b94faaSDavid Teigland unsigned int older) 374b3b94faaSDavid Teigland { 375b3b94faaSDavid Teigland int dist; 376b3b94faaSDavid Teigland 377b3b94faaSDavid Teigland dist = newer - older; 378b3b94faaSDavid Teigland if (dist < 0) 379b3b94faaSDavid Teigland dist += sdp->sd_jdesc->jd_blocks; 380b3b94faaSDavid Teigland 381b3b94faaSDavid Teigland return dist; 382b3b94faaSDavid Teigland } 383b3b94faaSDavid Teigland 3842332c443SRobert Peterson /** 3852332c443SRobert Peterson * calc_reserved - Calculate the number of blocks to reserve when 3862332c443SRobert Peterson * refunding a transaction's unused buffers. 3872332c443SRobert Peterson * @sdp: The GFS2 superblock 3882332c443SRobert Peterson * 3892332c443SRobert Peterson * This is complex. We need to reserve room for all our currently used 3902332c443SRobert Peterson * metadata buffers (e.g. normal file I/O rewriting file time stamps) and 3912332c443SRobert Peterson * all our journaled data buffers for journaled files (e.g. files in the 3922332c443SRobert Peterson * meta_fs like rindex, or files for which chattr +j was done.) 3932332c443SRobert Peterson * If we don't reserve enough space, gfs2_log_refund and gfs2_log_flush 3942332c443SRobert Peterson * will count it as free space (sd_log_blks_free) and corruption will follow. 3952332c443SRobert Peterson * 3962332c443SRobert Peterson * We can have metadata bufs and jdata bufs in the same journal. So each 3972332c443SRobert Peterson * type gets its own log header, for which we need to reserve a block. 3982332c443SRobert Peterson * In fact, each type has the potential for needing more than one header 3992332c443SRobert Peterson * in cases where we have more buffers than will fit on a journal page. 4002332c443SRobert Peterson * Metadata journal entries take up half the space of journaled buffer entries. 4012332c443SRobert Peterson * Thus, metadata entries have buf_limit (502) and journaled buffers have 4022332c443SRobert Peterson * databuf_limit (251) before they cause a wrap around. 4032332c443SRobert Peterson * 4042332c443SRobert Peterson * Also, we need to reserve blocks for revoke journal entries and one for an 4052332c443SRobert Peterson * overall header for the lot. 4062332c443SRobert Peterson * 4072332c443SRobert Peterson * Returns: the number of blocks reserved 4082332c443SRobert Peterson */ 4092332c443SRobert Peterson static unsigned int calc_reserved(struct gfs2_sbd *sdp) 4102332c443SRobert Peterson { 4112332c443SRobert Peterson unsigned int reserved = 0; 4122332c443SRobert Peterson unsigned int mbuf_limit, metabufhdrs_needed; 4132332c443SRobert Peterson unsigned int dbuf_limit, databufhdrs_needed; 4142332c443SRobert Peterson unsigned int revokes = 0; 4152332c443SRobert Peterson 4162332c443SRobert Peterson mbuf_limit = buf_limit(sdp); 4172332c443SRobert Peterson metabufhdrs_needed = (sdp->sd_log_commited_buf + 4182332c443SRobert Peterson (mbuf_limit - 1)) / mbuf_limit; 4192332c443SRobert Peterson dbuf_limit = databuf_limit(sdp); 4202332c443SRobert Peterson databufhdrs_needed = (sdp->sd_log_commited_databuf + 4212332c443SRobert Peterson (dbuf_limit - 1)) / dbuf_limit; 4222332c443SRobert Peterson 4232e95e3f6SBenjamin Marzinski if (sdp->sd_log_commited_revoke > 0) 4242332c443SRobert Peterson revokes = gfs2_struct2blk(sdp, sdp->sd_log_commited_revoke, 4252332c443SRobert Peterson sizeof(u64)); 4262332c443SRobert Peterson 4272332c443SRobert Peterson reserved = sdp->sd_log_commited_buf + metabufhdrs_needed + 4282332c443SRobert Peterson sdp->sd_log_commited_databuf + databufhdrs_needed + 4292332c443SRobert Peterson revokes; 4302332c443SRobert Peterson /* One for the overall header */ 4312332c443SRobert Peterson if (reserved) 4322332c443SRobert Peterson reserved++; 4332332c443SRobert Peterson return reserved; 4342332c443SRobert Peterson } 4352332c443SRobert Peterson 436b3b94faaSDavid Teigland static unsigned int current_tail(struct gfs2_sbd *sdp) 437b3b94faaSDavid Teigland { 438*16ca9412SBenjamin Marzinski struct gfs2_trans *tr; 439b3b94faaSDavid Teigland unsigned int tail; 440b3b94faaSDavid Teigland 441d6a079e8SDave Chinner spin_lock(&sdp->sd_ail_lock); 442b3b94faaSDavid Teigland 443faa31ce8SSteven Whitehouse if (list_empty(&sdp->sd_ail1_list)) { 444b3b94faaSDavid Teigland tail = sdp->sd_log_head; 445faa31ce8SSteven Whitehouse } else { 446*16ca9412SBenjamin Marzinski tr = list_entry(sdp->sd_ail1_list.prev, struct gfs2_trans, 447*16ca9412SBenjamin Marzinski tr_list); 448*16ca9412SBenjamin Marzinski tail = tr->tr_first; 449b3b94faaSDavid Teigland } 450b3b94faaSDavid Teigland 451d6a079e8SDave Chinner spin_unlock(&sdp->sd_ail_lock); 452b3b94faaSDavid Teigland 453b3b94faaSDavid Teigland return tail; 454b3b94faaSDavid Teigland } 455b3b94faaSDavid Teigland 4562332c443SRobert Peterson static void log_pull_tail(struct gfs2_sbd *sdp, unsigned int new_tail) 457b3b94faaSDavid Teigland { 458b3b94faaSDavid Teigland unsigned int dist = log_distance(sdp, new_tail, sdp->sd_log_tail); 459b3b94faaSDavid Teigland 460b3b94faaSDavid Teigland ail2_empty(sdp, new_tail); 461b3b94faaSDavid Teigland 462fd041f0bSSteven Whitehouse atomic_add(dist, &sdp->sd_log_blks_free); 46363997775SSteven Whitehouse trace_gfs2_log_blocks(sdp, dist); 4645e687eacSBenjamin Marzinski gfs2_assert_withdraw(sdp, atomic_read(&sdp->sd_log_blks_free) <= 4655e687eacSBenjamin Marzinski sdp->sd_jdesc->jd_blocks); 466b3b94faaSDavid Teigland 467b3b94faaSDavid Teigland sdp->sd_log_tail = new_tail; 468b3b94faaSDavid Teigland } 469b3b94faaSDavid Teigland 470b3b94faaSDavid Teigland 47134cc1781SSteven Whitehouse static void log_flush_wait(struct gfs2_sbd *sdp) 472b3b94faaSDavid Teigland { 47316615be1SSteven Whitehouse DEFINE_WAIT(wait); 474b3b94faaSDavid Teigland 47516615be1SSteven Whitehouse if (atomic_read(&sdp->sd_log_in_flight)) { 47616615be1SSteven Whitehouse do { 47716615be1SSteven Whitehouse prepare_to_wait(&sdp->sd_log_flush_wait, &wait, 47816615be1SSteven Whitehouse TASK_UNINTERRUPTIBLE); 47916615be1SSteven Whitehouse if (atomic_read(&sdp->sd_log_in_flight)) 48016615be1SSteven Whitehouse io_schedule(); 48116615be1SSteven Whitehouse } while(atomic_read(&sdp->sd_log_in_flight)); 48216615be1SSteven Whitehouse finish_wait(&sdp->sd_log_flush_wait, &wait); 483b3b94faaSDavid Teigland } 484b3b94faaSDavid Teigland } 485b3b94faaSDavid Teigland 48645138990SSteven Whitehouse static int ip_cmp(void *priv, struct list_head *a, struct list_head *b) 4874a36d08dSBob Peterson { 48845138990SSteven Whitehouse struct gfs2_inode *ipa, *ipb; 4894a36d08dSBob Peterson 49045138990SSteven Whitehouse ipa = list_entry(a, struct gfs2_inode, i_ordered); 49145138990SSteven Whitehouse ipb = list_entry(b, struct gfs2_inode, i_ordered); 4924a36d08dSBob Peterson 49345138990SSteven Whitehouse if (ipa->i_no_addr < ipb->i_no_addr) 4944a36d08dSBob Peterson return -1; 49545138990SSteven Whitehouse if (ipa->i_no_addr > ipb->i_no_addr) 4964a36d08dSBob Peterson return 1; 4974a36d08dSBob Peterson return 0; 4984a36d08dSBob Peterson } 4994a36d08dSBob Peterson 500d7b616e2SSteven Whitehouse static void gfs2_ordered_write(struct gfs2_sbd *sdp) 501d7b616e2SSteven Whitehouse { 50245138990SSteven Whitehouse struct gfs2_inode *ip; 503d7b616e2SSteven Whitehouse LIST_HEAD(written); 504d7b616e2SSteven Whitehouse 50545138990SSteven Whitehouse spin_lock(&sdp->sd_ordered_lock); 50645138990SSteven Whitehouse list_sort(NULL, &sdp->sd_log_le_ordered, &ip_cmp); 507d7b616e2SSteven Whitehouse while (!list_empty(&sdp->sd_log_le_ordered)) { 50845138990SSteven Whitehouse ip = list_entry(sdp->sd_log_le_ordered.next, struct gfs2_inode, i_ordered); 50945138990SSteven Whitehouse list_move(&ip->i_ordered, &written); 51045138990SSteven Whitehouse if (ip->i_inode.i_mapping->nrpages == 0) 511d7b616e2SSteven Whitehouse continue; 51245138990SSteven Whitehouse spin_unlock(&sdp->sd_ordered_lock); 51345138990SSteven Whitehouse filemap_fdatawrite(ip->i_inode.i_mapping); 51445138990SSteven Whitehouse spin_lock(&sdp->sd_ordered_lock); 515d7b616e2SSteven Whitehouse } 516d7b616e2SSteven Whitehouse list_splice(&written, &sdp->sd_log_le_ordered); 51745138990SSteven Whitehouse spin_unlock(&sdp->sd_ordered_lock); 518d7b616e2SSteven Whitehouse } 519d7b616e2SSteven Whitehouse 520d7b616e2SSteven Whitehouse static void gfs2_ordered_wait(struct gfs2_sbd *sdp) 521d7b616e2SSteven Whitehouse { 52245138990SSteven Whitehouse struct gfs2_inode *ip; 523d7b616e2SSteven Whitehouse 52445138990SSteven Whitehouse spin_lock(&sdp->sd_ordered_lock); 525d7b616e2SSteven Whitehouse while (!list_empty(&sdp->sd_log_le_ordered)) { 52645138990SSteven Whitehouse ip = list_entry(sdp->sd_log_le_ordered.next, struct gfs2_inode, i_ordered); 52745138990SSteven Whitehouse list_del(&ip->i_ordered); 52845138990SSteven Whitehouse WARN_ON(!test_and_clear_bit(GIF_ORDERED, &ip->i_flags)); 52945138990SSteven Whitehouse if (ip->i_inode.i_mapping->nrpages == 0) 530d7b616e2SSteven Whitehouse continue; 53145138990SSteven Whitehouse spin_unlock(&sdp->sd_ordered_lock); 53245138990SSteven Whitehouse filemap_fdatawait(ip->i_inode.i_mapping); 53345138990SSteven Whitehouse spin_lock(&sdp->sd_ordered_lock); 534d7b616e2SSteven Whitehouse } 53545138990SSteven Whitehouse spin_unlock(&sdp->sd_ordered_lock); 536d7b616e2SSteven Whitehouse } 53745138990SSteven Whitehouse 53845138990SSteven Whitehouse void gfs2_ordered_del_inode(struct gfs2_inode *ip) 53945138990SSteven Whitehouse { 54045138990SSteven Whitehouse struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); 54145138990SSteven Whitehouse 54245138990SSteven Whitehouse spin_lock(&sdp->sd_ordered_lock); 54345138990SSteven Whitehouse if (test_and_clear_bit(GIF_ORDERED, &ip->i_flags)) 54445138990SSteven Whitehouse list_del(&ip->i_ordered); 54545138990SSteven Whitehouse spin_unlock(&sdp->sd_ordered_lock); 546d7b616e2SSteven Whitehouse } 547d7b616e2SSteven Whitehouse 548b3b94faaSDavid Teigland /** 54934cc1781SSteven Whitehouse * log_write_header - Get and initialize a journal header buffer 55034cc1781SSteven Whitehouse * @sdp: The GFS2 superblock 55134cc1781SSteven Whitehouse * 55234cc1781SSteven Whitehouse * Returns: the initialized log buffer descriptor 55334cc1781SSteven Whitehouse */ 55434cc1781SSteven Whitehouse 555fdb76a42SSteven Whitehouse static void log_write_header(struct gfs2_sbd *sdp, u32 flags) 55634cc1781SSteven Whitehouse { 55734cc1781SSteven Whitehouse struct gfs2_log_header *lh; 55834cc1781SSteven Whitehouse unsigned int tail; 55934cc1781SSteven Whitehouse u32 hash; 560e8c92ed7SSteven Whitehouse int rw = WRITE_FLUSH_FUA | REQ_META; 561e8c92ed7SSteven Whitehouse struct page *page = mempool_alloc(gfs2_page_pool, GFP_NOIO); 562e8c92ed7SSteven Whitehouse lh = page_address(page); 563e8c92ed7SSteven Whitehouse clear_page(lh); 56434cc1781SSteven Whitehouse 56534cc1781SSteven Whitehouse gfs2_ail1_empty(sdp); 56634cc1781SSteven Whitehouse tail = current_tail(sdp); 56734cc1781SSteven Whitehouse 56834cc1781SSteven Whitehouse lh->lh_header.mh_magic = cpu_to_be32(GFS2_MAGIC); 56934cc1781SSteven Whitehouse lh->lh_header.mh_type = cpu_to_be32(GFS2_METATYPE_LH); 57034cc1781SSteven Whitehouse lh->lh_header.__pad0 = cpu_to_be64(0); 57134cc1781SSteven Whitehouse lh->lh_header.mh_format = cpu_to_be32(GFS2_FORMAT_LH); 57234cc1781SSteven Whitehouse lh->lh_header.mh_jid = cpu_to_be32(sdp->sd_jdesc->jd_jid); 57334cc1781SSteven Whitehouse lh->lh_sequence = cpu_to_be64(sdp->sd_log_sequence++); 57434cc1781SSteven Whitehouse lh->lh_flags = cpu_to_be32(flags); 57534cc1781SSteven Whitehouse lh->lh_tail = cpu_to_be32(tail); 57634cc1781SSteven Whitehouse lh->lh_blkno = cpu_to_be32(sdp->sd_log_flush_head); 577e8c92ed7SSteven Whitehouse hash = gfs2_disk_hash(page_address(page), sizeof(struct gfs2_log_header)); 57834cc1781SSteven Whitehouse lh->lh_hash = cpu_to_be32(hash); 57934cc1781SSteven Whitehouse 58034cc1781SSteven Whitehouse if (test_bit(SDF_NOBARRIERS, &sdp->sd_flags)) { 58134cc1781SSteven Whitehouse gfs2_ordered_wait(sdp); 58234cc1781SSteven Whitehouse log_flush_wait(sdp); 583e8c92ed7SSteven Whitehouse rw = WRITE_SYNC | REQ_META | REQ_PRIO; 58434cc1781SSteven Whitehouse } 58534cc1781SSteven Whitehouse 586e8c92ed7SSteven Whitehouse sdp->sd_log_idle = (tail == sdp->sd_log_flush_head); 587e8c92ed7SSteven Whitehouse gfs2_log_write_page(sdp, page); 588e8c92ed7SSteven Whitehouse gfs2_log_flush_bio(sdp, rw); 589e8c92ed7SSteven Whitehouse log_flush_wait(sdp); 59034cc1781SSteven Whitehouse 59134cc1781SSteven Whitehouse if (sdp->sd_log_tail != tail) 59234cc1781SSteven Whitehouse log_pull_tail(sdp, tail); 59334cc1781SSteven Whitehouse } 59434cc1781SSteven Whitehouse 59534cc1781SSteven Whitehouse /** 596b09e593dSSteven Whitehouse * gfs2_log_flush - flush incore transaction(s) 597b3b94faaSDavid Teigland * @sdp: the filesystem 598b3b94faaSDavid Teigland * @gl: The glock structure to flush. If NULL, flush the whole incore log 599b3b94faaSDavid Teigland * 600b3b94faaSDavid Teigland */ 601b3b94faaSDavid Teigland 602ed4878e8SBob Peterson void gfs2_log_flush(struct gfs2_sbd *sdp, struct gfs2_glock *gl) 603b3b94faaSDavid Teigland { 604*16ca9412SBenjamin Marzinski struct gfs2_trans *tr; 605b3b94faaSDavid Teigland 606484adff8SSteven Whitehouse down_write(&sdp->sd_log_flush_lock); 607f55ab26aSSteven Whitehouse 6082bcd610dSSteven Whitehouse /* Log might have been flushed while we waited for the flush lock */ 6092bcd610dSSteven Whitehouse if (gl && !test_bit(GLF_LFLUSH, &gl->gl_flags)) { 610484adff8SSteven Whitehouse up_write(&sdp->sd_log_flush_lock); 611f55ab26aSSteven Whitehouse return; 612f55ab26aSSteven Whitehouse } 61363997775SSteven Whitehouse trace_gfs2_log_flush(sdp, 1); 614f55ab26aSSteven Whitehouse 615*16ca9412SBenjamin Marzinski tr = sdp->sd_log_tr; 616*16ca9412SBenjamin Marzinski if (tr) { 617*16ca9412SBenjamin Marzinski sdp->sd_log_tr = NULL; 618*16ca9412SBenjamin Marzinski INIT_LIST_HEAD(&tr->tr_ail1_list); 619*16ca9412SBenjamin Marzinski INIT_LIST_HEAD(&tr->tr_ail2_list); 620*16ca9412SBenjamin Marzinski } 621b3b94faaSDavid Teigland 62216615be1SSteven Whitehouse if (sdp->sd_log_num_buf != sdp->sd_log_commited_buf) { 62316615be1SSteven Whitehouse printk(KERN_INFO "GFS2: log buf %u %u\n", sdp->sd_log_num_buf, 62416615be1SSteven Whitehouse sdp->sd_log_commited_buf); 62516615be1SSteven Whitehouse gfs2_assert_withdraw(sdp, 0); 62616615be1SSteven Whitehouse } 62716615be1SSteven Whitehouse if (sdp->sd_log_num_databuf != sdp->sd_log_commited_databuf) { 62816615be1SSteven Whitehouse printk(KERN_INFO "GFS2: log databuf %u %u\n", 62916615be1SSteven Whitehouse sdp->sd_log_num_databuf, sdp->sd_log_commited_databuf); 63016615be1SSteven Whitehouse gfs2_assert_withdraw(sdp, 0); 63116615be1SSteven Whitehouse } 632b3b94faaSDavid Teigland gfs2_assert_withdraw(sdp, 633b3b94faaSDavid Teigland sdp->sd_log_num_revoke == sdp->sd_log_commited_revoke); 634b3b94faaSDavid Teigland 635b3b94faaSDavid Teigland sdp->sd_log_flush_head = sdp->sd_log_head; 636b3b94faaSDavid Teigland sdp->sd_log_flush_wrapped = 0; 637*16ca9412SBenjamin Marzinski if (tr) 638*16ca9412SBenjamin Marzinski tr->tr_first = sdp->sd_log_flush_head; 639b3b94faaSDavid Teigland 640d7b616e2SSteven Whitehouse gfs2_ordered_write(sdp); 641b3b94faaSDavid Teigland lops_before_commit(sdp); 642e8c92ed7SSteven Whitehouse gfs2_log_flush_bio(sdp, WRITE); 643d7b616e2SSteven Whitehouse 64434cc1781SSteven Whitehouse if (sdp->sd_log_head != sdp->sd_log_flush_head) { 645fdb76a42SSteven Whitehouse log_write_header(sdp, 0); 64634cc1781SSteven Whitehouse } else if (sdp->sd_log_tail != current_tail(sdp) && !sdp->sd_log_idle){ 647fd041f0bSSteven Whitehouse atomic_dec(&sdp->sd_log_blks_free); /* Adjust for unreserved buffer */ 64863997775SSteven Whitehouse trace_gfs2_log_blocks(sdp, -1); 649fdb76a42SSteven Whitehouse log_write_header(sdp, 0); 6502332c443SRobert Peterson } 651*16ca9412SBenjamin Marzinski lops_after_commit(sdp, tr); 652fe1a698fSSteven Whitehouse 653fe1a698fSSteven Whitehouse gfs2_log_lock(sdp); 654b3b94faaSDavid Teigland sdp->sd_log_head = sdp->sd_log_flush_head; 655faa31ce8SSteven Whitehouse sdp->sd_log_blks_reserved = 0; 656faa31ce8SSteven Whitehouse sdp->sd_log_commited_buf = 0; 6572332c443SRobert Peterson sdp->sd_log_commited_databuf = 0; 658b3b94faaSDavid Teigland sdp->sd_log_commited_revoke = 0; 659b3b94faaSDavid Teigland 660d6a079e8SDave Chinner spin_lock(&sdp->sd_ail_lock); 661*16ca9412SBenjamin Marzinski if (tr && !list_empty(&tr->tr_ail1_list)) { 662*16ca9412SBenjamin Marzinski list_add(&tr->tr_list, &sdp->sd_ail1_list); 663*16ca9412SBenjamin Marzinski tr = NULL; 664b3b94faaSDavid Teigland } 665d6a079e8SDave Chinner spin_unlock(&sdp->sd_ail_lock); 666b3b94faaSDavid Teigland gfs2_log_unlock(sdp); 66763997775SSteven Whitehouse trace_gfs2_log_flush(sdp, 0); 668484adff8SSteven Whitehouse up_write(&sdp->sd_log_flush_lock); 669b3b94faaSDavid Teigland 670*16ca9412SBenjamin Marzinski kfree(tr); 671b3b94faaSDavid Teigland } 672b3b94faaSDavid Teigland 673b3b94faaSDavid Teigland static void log_refund(struct gfs2_sbd *sdp, struct gfs2_trans *tr) 674b3b94faaSDavid Teigland { 6752332c443SRobert Peterson unsigned int reserved; 676ac39aaddSSteven Whitehouse unsigned int unused; 677b3b94faaSDavid Teigland 678b3b94faaSDavid Teigland gfs2_log_lock(sdp); 679b3b94faaSDavid Teigland 680b3b94faaSDavid Teigland sdp->sd_log_commited_buf += tr->tr_num_buf_new - tr->tr_num_buf_rm; 6812332c443SRobert Peterson sdp->sd_log_commited_databuf += tr->tr_num_databuf_new - 6822332c443SRobert Peterson tr->tr_num_databuf_rm; 6832332c443SRobert Peterson gfs2_assert_withdraw(sdp, (((int)sdp->sd_log_commited_buf) >= 0) || 6842332c443SRobert Peterson (((int)sdp->sd_log_commited_databuf) >= 0)); 685b3b94faaSDavid Teigland sdp->sd_log_commited_revoke += tr->tr_num_revoke - tr->tr_num_revoke_rm; 6862332c443SRobert Peterson reserved = calc_reserved(sdp); 68762be1f71SRoel Kluin gfs2_assert_withdraw(sdp, sdp->sd_log_blks_reserved + tr->tr_reserved >= reserved); 688ac39aaddSSteven Whitehouse unused = sdp->sd_log_blks_reserved - reserved + tr->tr_reserved; 689ac39aaddSSteven Whitehouse atomic_add(unused, &sdp->sd_log_blks_free); 69063997775SSteven Whitehouse trace_gfs2_log_blocks(sdp, unused); 691fd041f0bSSteven Whitehouse gfs2_assert_withdraw(sdp, atomic_read(&sdp->sd_log_blks_free) <= 6922332c443SRobert Peterson sdp->sd_jdesc->jd_blocks); 693b3b94faaSDavid Teigland sdp->sd_log_blks_reserved = reserved; 694b3b94faaSDavid Teigland 695*16ca9412SBenjamin Marzinski if (sdp->sd_log_tr == NULL && 696*16ca9412SBenjamin Marzinski (tr->tr_num_buf_new || tr->tr_num_databuf_new)) { 697*16ca9412SBenjamin Marzinski gfs2_assert_withdraw(sdp, tr->tr_t_gh.gh_gl); 698*16ca9412SBenjamin Marzinski sdp->sd_log_tr = tr; 699*16ca9412SBenjamin Marzinski tr->tr_attached = 1; 700*16ca9412SBenjamin Marzinski } 701b3b94faaSDavid Teigland gfs2_log_unlock(sdp); 702b3b94faaSDavid Teigland } 703b3b94faaSDavid Teigland 704b3b94faaSDavid Teigland /** 705b3b94faaSDavid Teigland * gfs2_log_commit - Commit a transaction to the log 706b3b94faaSDavid Teigland * @sdp: the filesystem 707b3b94faaSDavid Teigland * @tr: the transaction 708b3b94faaSDavid Teigland * 7095e687eacSBenjamin Marzinski * We wake up gfs2_logd if the number of pinned blocks exceed thresh1 7105e687eacSBenjamin Marzinski * or the total number of used blocks (pinned blocks plus AIL blocks) 7115e687eacSBenjamin Marzinski * is greater than thresh2. 7125e687eacSBenjamin Marzinski * 7135e687eacSBenjamin Marzinski * At mount time thresh1 is 1/3rd of journal size, thresh2 is 2/3rd of 7145e687eacSBenjamin Marzinski * journal size. 7155e687eacSBenjamin Marzinski * 716b3b94faaSDavid Teigland * Returns: errno 717b3b94faaSDavid Teigland */ 718b3b94faaSDavid Teigland 719b3b94faaSDavid Teigland void gfs2_log_commit(struct gfs2_sbd *sdp, struct gfs2_trans *tr) 720b3b94faaSDavid Teigland { 721b3b94faaSDavid Teigland log_refund(sdp, tr); 722b3b94faaSDavid Teigland 7235e687eacSBenjamin Marzinski if (atomic_read(&sdp->sd_log_pinned) > atomic_read(&sdp->sd_log_thresh1) || 7245e687eacSBenjamin Marzinski ((sdp->sd_jdesc->jd_blocks - atomic_read(&sdp->sd_log_blks_free)) > 7255e687eacSBenjamin Marzinski atomic_read(&sdp->sd_log_thresh2))) 7265e687eacSBenjamin Marzinski wake_up(&sdp->sd_logd_waitq); 727faa31ce8SSteven Whitehouse } 728b3b94faaSDavid Teigland 729b3b94faaSDavid Teigland /** 730b3b94faaSDavid Teigland * gfs2_log_shutdown - write a shutdown header into a journal 731b3b94faaSDavid Teigland * @sdp: the filesystem 732b3b94faaSDavid Teigland * 733b3b94faaSDavid Teigland */ 734b3b94faaSDavid Teigland 735b3b94faaSDavid Teigland void gfs2_log_shutdown(struct gfs2_sbd *sdp) 736b3b94faaSDavid Teigland { 737484adff8SSteven Whitehouse down_write(&sdp->sd_log_flush_lock); 738b3b94faaSDavid Teigland 739b3b94faaSDavid Teigland gfs2_assert_withdraw(sdp, !sdp->sd_log_blks_reserved); 740b3b94faaSDavid Teigland gfs2_assert_withdraw(sdp, !sdp->sd_log_num_buf); 741b3b94faaSDavid Teigland gfs2_assert_withdraw(sdp, !sdp->sd_log_num_revoke); 742b3b94faaSDavid Teigland gfs2_assert_withdraw(sdp, !sdp->sd_log_num_rg); 743b3b94faaSDavid Teigland gfs2_assert_withdraw(sdp, !sdp->sd_log_num_databuf); 744b3b94faaSDavid Teigland gfs2_assert_withdraw(sdp, list_empty(&sdp->sd_ail1_list)); 745b3b94faaSDavid Teigland 746b3b94faaSDavid Teigland sdp->sd_log_flush_head = sdp->sd_log_head; 747b3b94faaSDavid Teigland sdp->sd_log_flush_wrapped = 0; 748b3b94faaSDavid Teigland 749fdb76a42SSteven Whitehouse log_write_header(sdp, GFS2_LOG_HEAD_UNMOUNT); 750b3b94faaSDavid Teigland 751fd041f0bSSteven Whitehouse gfs2_assert_warn(sdp, atomic_read(&sdp->sd_log_blks_free) == sdp->sd_jdesc->jd_blocks); 752a74604beSSteven Whitehouse gfs2_assert_warn(sdp, sdp->sd_log_head == sdp->sd_log_tail); 753a74604beSSteven Whitehouse gfs2_assert_warn(sdp, list_empty(&sdp->sd_ail2_list)); 754b3b94faaSDavid Teigland 755b3b94faaSDavid Teigland sdp->sd_log_head = sdp->sd_log_flush_head; 756b3b94faaSDavid Teigland sdp->sd_log_tail = sdp->sd_log_head; 757b3b94faaSDavid Teigland 758484adff8SSteven Whitehouse up_write(&sdp->sd_log_flush_lock); 759b3b94faaSDavid Teigland } 760b3b94faaSDavid Teigland 761a25311c8SSteven Whitehouse 762a25311c8SSteven Whitehouse /** 763a25311c8SSteven Whitehouse * gfs2_meta_syncfs - sync all the buffers in a filesystem 764a25311c8SSteven Whitehouse * @sdp: the filesystem 765a25311c8SSteven Whitehouse * 766a25311c8SSteven Whitehouse */ 767a25311c8SSteven Whitehouse 768a25311c8SSteven Whitehouse void gfs2_meta_syncfs(struct gfs2_sbd *sdp) 769a25311c8SSteven Whitehouse { 770a25311c8SSteven Whitehouse gfs2_log_flush(sdp, NULL); 771a25311c8SSteven Whitehouse for (;;) { 7725e687eacSBenjamin Marzinski gfs2_ail1_start(sdp); 77326b06a69SSteven Whitehouse gfs2_ail1_wait(sdp); 7744667a0ecSSteven Whitehouse if (gfs2_ail1_empty(sdp)) 775a25311c8SSteven Whitehouse break; 776a25311c8SSteven Whitehouse } 777380f7c65SSteven Whitehouse gfs2_log_flush(sdp, NULL); 778a25311c8SSteven Whitehouse } 779a25311c8SSteven Whitehouse 7805e687eacSBenjamin Marzinski static inline int gfs2_jrnl_flush_reqd(struct gfs2_sbd *sdp) 7815e687eacSBenjamin Marzinski { 7825e687eacSBenjamin Marzinski return (atomic_read(&sdp->sd_log_pinned) >= atomic_read(&sdp->sd_log_thresh1)); 7835e687eacSBenjamin Marzinski } 7845e687eacSBenjamin Marzinski 7855e687eacSBenjamin Marzinski static inline int gfs2_ail_flush_reqd(struct gfs2_sbd *sdp) 7865e687eacSBenjamin Marzinski { 7875e687eacSBenjamin Marzinski unsigned int used_blocks = sdp->sd_jdesc->jd_blocks - atomic_read(&sdp->sd_log_blks_free); 7885e687eacSBenjamin Marzinski return used_blocks >= atomic_read(&sdp->sd_log_thresh2); 7895e687eacSBenjamin Marzinski } 790ec69b188SSteven Whitehouse 791ec69b188SSteven Whitehouse /** 792ec69b188SSteven Whitehouse * gfs2_logd - Update log tail as Active Items get flushed to in-place blocks 793ec69b188SSteven Whitehouse * @sdp: Pointer to GFS2 superblock 794ec69b188SSteven Whitehouse * 795ec69b188SSteven Whitehouse * Also, periodically check to make sure that we're using the most recent 796ec69b188SSteven Whitehouse * journal index. 797ec69b188SSteven Whitehouse */ 798ec69b188SSteven Whitehouse 799ec69b188SSteven Whitehouse int gfs2_logd(void *data) 800ec69b188SSteven Whitehouse { 801ec69b188SSteven Whitehouse struct gfs2_sbd *sdp = data; 8025e687eacSBenjamin Marzinski unsigned long t = 1; 8035e687eacSBenjamin Marzinski DEFINE_WAIT(wait); 804ec69b188SSteven Whitehouse 805ec69b188SSteven Whitehouse while (!kthread_should_stop()) { 806ec69b188SSteven Whitehouse 8075e687eacSBenjamin Marzinski if (gfs2_jrnl_flush_reqd(sdp) || t == 0) { 8084667a0ecSSteven Whitehouse gfs2_ail1_empty(sdp); 809ec69b188SSteven Whitehouse gfs2_log_flush(sdp, NULL); 810ec69b188SSteven Whitehouse } 811ec69b188SSteven Whitehouse 8125e687eacSBenjamin Marzinski if (gfs2_ail_flush_reqd(sdp)) { 8135e687eacSBenjamin Marzinski gfs2_ail1_start(sdp); 81426b06a69SSteven Whitehouse gfs2_ail1_wait(sdp); 8154667a0ecSSteven Whitehouse gfs2_ail1_empty(sdp); 8165e687eacSBenjamin Marzinski gfs2_log_flush(sdp, NULL); 8175e687eacSBenjamin Marzinski } 8185e687eacSBenjamin Marzinski 81926b06a69SSteven Whitehouse if (!gfs2_ail_flush_reqd(sdp)) 8205e687eacSBenjamin Marzinski wake_up(&sdp->sd_log_waitq); 82126b06a69SSteven Whitehouse 822ec69b188SSteven Whitehouse t = gfs2_tune_get(sdp, gt_logd_secs) * HZ; 823a0acae0eSTejun Heo 824a0acae0eSTejun Heo try_to_freeze(); 8255e687eacSBenjamin Marzinski 8265e687eacSBenjamin Marzinski do { 8275e687eacSBenjamin Marzinski prepare_to_wait(&sdp->sd_logd_waitq, &wait, 8285f487490SSteven Whitehouse TASK_INTERRUPTIBLE); 8295e687eacSBenjamin Marzinski if (!gfs2_ail_flush_reqd(sdp) && 8305e687eacSBenjamin Marzinski !gfs2_jrnl_flush_reqd(sdp) && 8315e687eacSBenjamin Marzinski !kthread_should_stop()) 8325e687eacSBenjamin Marzinski t = schedule_timeout(t); 8335e687eacSBenjamin Marzinski } while(t && !gfs2_ail_flush_reqd(sdp) && 8345e687eacSBenjamin Marzinski !gfs2_jrnl_flush_reqd(sdp) && 8355e687eacSBenjamin Marzinski !kthread_should_stop()); 8365e687eacSBenjamin Marzinski finish_wait(&sdp->sd_logd_waitq, &wait); 837ec69b188SSteven Whitehouse } 838ec69b188SSteven Whitehouse 839ec69b188SSteven Whitehouse return 0; 840ec69b188SSteven Whitehouse } 841ec69b188SSteven Whitehouse 842