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 { 7616ca9412SBenjamin 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, 9316ca9412SBenjamin 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 10216ca9412SBenjamin 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 10516ca9412SBenjamin 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); 11016ca9412SBenjamin 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; 11916ca9412SBenjamin 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; 14716ca9412SBenjamin 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: 15216ca9412SBenjamin Marzinski list_for_each_entry_reverse(tr, head, tr_list) { 1534667a0ecSSteven Whitehouse if (wbc->nr_to_write <= 0) 1544667a0ecSSteven Whitehouse break; 15516ca9412SBenjamin 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 18616ca9412SBenjamin 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 19116ca9412SBenjamin 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; 19416ca9412SBenjamin 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); 19916ca9412SBenjamin 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 { 21316ca9412SBenjamin Marzinski struct gfs2_trans *tr, *s; 214*5d054964SBenjamin Marzinski int oldest_tr = 1; 215b3b94faaSDavid Teigland int ret; 216b3b94faaSDavid Teigland 217d6a079e8SDave Chinner spin_lock(&sdp->sd_ail_lock); 21816ca9412SBenjamin Marzinski list_for_each_entry_safe_reverse(tr, s, &sdp->sd_ail1_list, tr_list) { 21916ca9412SBenjamin Marzinski gfs2_ail1_empty_one(sdp, tr); 220*5d054964SBenjamin Marzinski if (list_empty(&tr->tr_ail1_list) && oldest_tr) 22116ca9412SBenjamin Marzinski list_move(&tr->tr_list, &sdp->sd_ail2_list); 2224667a0ecSSteven Whitehouse else 223*5d054964SBenjamin Marzinski oldest_tr = 0; 224b3b94faaSDavid Teigland } 225b3b94faaSDavid Teigland ret = list_empty(&sdp->sd_ail1_list); 226d6a079e8SDave Chinner spin_unlock(&sdp->sd_ail_lock); 227b3b94faaSDavid Teigland 228b3b94faaSDavid Teigland return ret; 229b3b94faaSDavid Teigland } 230b3b94faaSDavid Teigland 23126b06a69SSteven Whitehouse static void gfs2_ail1_wait(struct gfs2_sbd *sdp) 23226b06a69SSteven Whitehouse { 23316ca9412SBenjamin Marzinski struct gfs2_trans *tr; 23426b06a69SSteven Whitehouse struct gfs2_bufdata *bd; 23526b06a69SSteven Whitehouse struct buffer_head *bh; 23626b06a69SSteven Whitehouse 23726b06a69SSteven Whitehouse spin_lock(&sdp->sd_ail_lock); 23816ca9412SBenjamin Marzinski list_for_each_entry_reverse(tr, &sdp->sd_ail1_list, tr_list) { 23916ca9412SBenjamin Marzinski list_for_each_entry(bd, &tr->tr_ail1_list, bd_ail_st_list) { 24026b06a69SSteven Whitehouse bh = bd->bd_bh; 24126b06a69SSteven Whitehouse if (!buffer_locked(bh)) 24226b06a69SSteven Whitehouse continue; 24326b06a69SSteven Whitehouse get_bh(bh); 24426b06a69SSteven Whitehouse spin_unlock(&sdp->sd_ail_lock); 24526b06a69SSteven Whitehouse wait_on_buffer(bh); 24626b06a69SSteven Whitehouse brelse(bh); 24726b06a69SSteven Whitehouse return; 24826b06a69SSteven Whitehouse } 24926b06a69SSteven Whitehouse } 25026b06a69SSteven Whitehouse spin_unlock(&sdp->sd_ail_lock); 25126b06a69SSteven Whitehouse } 252ddacfaf7SSteven Whitehouse 253ddacfaf7SSteven Whitehouse /** 254ddacfaf7SSteven Whitehouse * gfs2_ail2_empty_one - Check whether or not a trans in the AIL has been synced 255ddacfaf7SSteven Whitehouse * @sdp: the filesystem 256ddacfaf7SSteven Whitehouse * @ai: the AIL entry 257ddacfaf7SSteven Whitehouse * 258ddacfaf7SSteven Whitehouse */ 259ddacfaf7SSteven Whitehouse 26016ca9412SBenjamin Marzinski static void gfs2_ail2_empty_one(struct gfs2_sbd *sdp, struct gfs2_trans *tr) 261ddacfaf7SSteven Whitehouse { 26216ca9412SBenjamin Marzinski struct list_head *head = &tr->tr_ail2_list; 263ddacfaf7SSteven Whitehouse struct gfs2_bufdata *bd; 264ddacfaf7SSteven Whitehouse 265ddacfaf7SSteven Whitehouse while (!list_empty(head)) { 266ddacfaf7SSteven Whitehouse bd = list_entry(head->prev, struct gfs2_bufdata, 267ddacfaf7SSteven Whitehouse bd_ail_st_list); 26816ca9412SBenjamin Marzinski gfs2_assert(sdp, bd->bd_tr == tr); 269f91a0d3eSSteven Whitehouse gfs2_remove_from_ail(bd); 270ddacfaf7SSteven Whitehouse } 271ddacfaf7SSteven Whitehouse } 272ddacfaf7SSteven Whitehouse 273b3b94faaSDavid Teigland static void ail2_empty(struct gfs2_sbd *sdp, unsigned int new_tail) 274b3b94faaSDavid Teigland { 27516ca9412SBenjamin Marzinski struct gfs2_trans *tr, *safe; 276b3b94faaSDavid Teigland unsigned int old_tail = sdp->sd_log_tail; 277b3b94faaSDavid Teigland int wrap = (new_tail < old_tail); 278b3b94faaSDavid Teigland int a, b, rm; 279b3b94faaSDavid Teigland 280d6a079e8SDave Chinner spin_lock(&sdp->sd_ail_lock); 281b3b94faaSDavid Teigland 28216ca9412SBenjamin Marzinski list_for_each_entry_safe(tr, safe, &sdp->sd_ail2_list, tr_list) { 28316ca9412SBenjamin Marzinski a = (old_tail <= tr->tr_first); 28416ca9412SBenjamin Marzinski b = (tr->tr_first < new_tail); 285b3b94faaSDavid Teigland rm = (wrap) ? (a || b) : (a && b); 286b3b94faaSDavid Teigland if (!rm) 287b3b94faaSDavid Teigland continue; 288b3b94faaSDavid Teigland 28916ca9412SBenjamin Marzinski gfs2_ail2_empty_one(sdp, tr); 29016ca9412SBenjamin Marzinski list_del(&tr->tr_list); 29116ca9412SBenjamin Marzinski gfs2_assert_warn(sdp, list_empty(&tr->tr_ail1_list)); 29216ca9412SBenjamin Marzinski gfs2_assert_warn(sdp, list_empty(&tr->tr_ail2_list)); 29316ca9412SBenjamin Marzinski kfree(tr); 294b3b94faaSDavid Teigland } 295b3b94faaSDavid Teigland 296d6a079e8SDave Chinner spin_unlock(&sdp->sd_ail_lock); 297b3b94faaSDavid Teigland } 298b3b94faaSDavid Teigland 299b3b94faaSDavid Teigland /** 300b3b94faaSDavid Teigland * gfs2_log_reserve - Make a log reservation 301b3b94faaSDavid Teigland * @sdp: The GFS2 superblock 302b3b94faaSDavid Teigland * @blks: The number of blocks to reserve 303b3b94faaSDavid Teigland * 30489918647SSteven Whitehouse * Note that we never give out the last few blocks of the journal. Thats 3052332c443SRobert Peterson * due to the fact that there is a small number of header blocks 306b004157aSSteven Whitehouse * associated with each log flush. The exact number can't be known until 307b004157aSSteven Whitehouse * flush time, so we ensure that we have just enough free blocks at all 308b004157aSSteven Whitehouse * times to avoid running out during a log flush. 309b004157aSSteven Whitehouse * 3105e687eacSBenjamin Marzinski * We no longer flush the log here, instead we wake up logd to do that 3115e687eacSBenjamin Marzinski * for us. To avoid the thundering herd and to ensure that we deal fairly 3125e687eacSBenjamin Marzinski * with queued waiters, we use an exclusive wait. This means that when we 3135e687eacSBenjamin Marzinski * get woken with enough journal space to get our reservation, we need to 3145e687eacSBenjamin Marzinski * wake the next waiter on the list. 3155e687eacSBenjamin Marzinski * 316b3b94faaSDavid Teigland * Returns: errno 317b3b94faaSDavid Teigland */ 318b3b94faaSDavid Teigland 319b3b94faaSDavid Teigland int gfs2_log_reserve(struct gfs2_sbd *sdp, unsigned int blks) 320b3b94faaSDavid Teigland { 321*5d054964SBenjamin Marzinski unsigned reserved_blks = 7 * (4096 / sdp->sd_vfs->s_blocksize); 3225e687eacSBenjamin Marzinski unsigned wanted = blks + reserved_blks; 3235e687eacSBenjamin Marzinski DEFINE_WAIT(wait); 3245e687eacSBenjamin Marzinski int did_wait = 0; 3255e687eacSBenjamin Marzinski unsigned int free_blocks; 326b3b94faaSDavid Teigland 327b3b94faaSDavid Teigland if (gfs2_assert_warn(sdp, blks) || 328b3b94faaSDavid Teigland gfs2_assert_warn(sdp, blks <= sdp->sd_jdesc->jd_blocks)) 329b3b94faaSDavid Teigland return -EINVAL; 3305e687eacSBenjamin Marzinski retry: 3315e687eacSBenjamin Marzinski free_blocks = atomic_read(&sdp->sd_log_blks_free); 3325e687eacSBenjamin Marzinski if (unlikely(free_blocks <= wanted)) { 3335e687eacSBenjamin Marzinski do { 3345e687eacSBenjamin Marzinski prepare_to_wait_exclusive(&sdp->sd_log_waitq, &wait, 3355e687eacSBenjamin Marzinski TASK_UNINTERRUPTIBLE); 3365e687eacSBenjamin Marzinski wake_up(&sdp->sd_logd_waitq); 3375e687eacSBenjamin Marzinski did_wait = 1; 3385e687eacSBenjamin Marzinski if (atomic_read(&sdp->sd_log_blks_free) <= wanted) 3395e687eacSBenjamin Marzinski io_schedule(); 3405e687eacSBenjamin Marzinski free_blocks = atomic_read(&sdp->sd_log_blks_free); 3415e687eacSBenjamin Marzinski } while(free_blocks <= wanted); 3425e687eacSBenjamin Marzinski finish_wait(&sdp->sd_log_waitq, &wait); 343b3b94faaSDavid Teigland } 3445e687eacSBenjamin Marzinski if (atomic_cmpxchg(&sdp->sd_log_blks_free, free_blocks, 3455e687eacSBenjamin Marzinski free_blocks - blks) != free_blocks) 3465e687eacSBenjamin Marzinski goto retry; 34763997775SSteven Whitehouse trace_gfs2_log_blocks(sdp, -blks); 3485e687eacSBenjamin Marzinski 3495e687eacSBenjamin Marzinski /* 3505e687eacSBenjamin Marzinski * If we waited, then so might others, wake them up _after_ we get 3515e687eacSBenjamin Marzinski * our share of the log. 3525e687eacSBenjamin Marzinski */ 3535e687eacSBenjamin Marzinski if (unlikely(did_wait)) 3545e687eacSBenjamin Marzinski wake_up(&sdp->sd_log_waitq); 355484adff8SSteven Whitehouse 356484adff8SSteven Whitehouse down_read(&sdp->sd_log_flush_lock); 357b3b94faaSDavid Teigland 358b3b94faaSDavid Teigland return 0; 359b3b94faaSDavid Teigland } 360b3b94faaSDavid Teigland 361b3b94faaSDavid Teigland /** 362b3b94faaSDavid Teigland * log_distance - Compute distance between two journal blocks 363b3b94faaSDavid Teigland * @sdp: The GFS2 superblock 364b3b94faaSDavid Teigland * @newer: The most recent journal block of the pair 365b3b94faaSDavid Teigland * @older: The older journal block of the pair 366b3b94faaSDavid Teigland * 367b3b94faaSDavid Teigland * Compute the distance (in the journal direction) between two 368b3b94faaSDavid Teigland * blocks in the journal 369b3b94faaSDavid Teigland * 370b3b94faaSDavid Teigland * Returns: the distance in blocks 371b3b94faaSDavid Teigland */ 372b3b94faaSDavid Teigland 373faa31ce8SSteven Whitehouse static inline unsigned int log_distance(struct gfs2_sbd *sdp, unsigned int newer, 374b3b94faaSDavid Teigland unsigned int older) 375b3b94faaSDavid Teigland { 376b3b94faaSDavid Teigland int dist; 377b3b94faaSDavid Teigland 378b3b94faaSDavid Teigland dist = newer - older; 379b3b94faaSDavid Teigland if (dist < 0) 380b3b94faaSDavid Teigland dist += sdp->sd_jdesc->jd_blocks; 381b3b94faaSDavid Teigland 382b3b94faaSDavid Teigland return dist; 383b3b94faaSDavid Teigland } 384b3b94faaSDavid Teigland 3852332c443SRobert Peterson /** 3862332c443SRobert Peterson * calc_reserved - Calculate the number of blocks to reserve when 3872332c443SRobert Peterson * refunding a transaction's unused buffers. 3882332c443SRobert Peterson * @sdp: The GFS2 superblock 3892332c443SRobert Peterson * 3902332c443SRobert Peterson * This is complex. We need to reserve room for all our currently used 3912332c443SRobert Peterson * metadata buffers (e.g. normal file I/O rewriting file time stamps) and 3922332c443SRobert Peterson * all our journaled data buffers for journaled files (e.g. files in the 3932332c443SRobert Peterson * meta_fs like rindex, or files for which chattr +j was done.) 3942332c443SRobert Peterson * If we don't reserve enough space, gfs2_log_refund and gfs2_log_flush 3952332c443SRobert Peterson * will count it as free space (sd_log_blks_free) and corruption will follow. 3962332c443SRobert Peterson * 3972332c443SRobert Peterson * We can have metadata bufs and jdata bufs in the same journal. So each 3982332c443SRobert Peterson * type gets its own log header, for which we need to reserve a block. 3992332c443SRobert Peterson * In fact, each type has the potential for needing more than one header 4002332c443SRobert Peterson * in cases where we have more buffers than will fit on a journal page. 4012332c443SRobert Peterson * Metadata journal entries take up half the space of journaled buffer entries. 4022332c443SRobert Peterson * Thus, metadata entries have buf_limit (502) and journaled buffers have 4032332c443SRobert Peterson * databuf_limit (251) before they cause a wrap around. 4042332c443SRobert Peterson * 4052332c443SRobert Peterson * Also, we need to reserve blocks for revoke journal entries and one for an 4062332c443SRobert Peterson * overall header for the lot. 4072332c443SRobert Peterson * 4082332c443SRobert Peterson * Returns: the number of blocks reserved 4092332c443SRobert Peterson */ 4102332c443SRobert Peterson static unsigned int calc_reserved(struct gfs2_sbd *sdp) 4112332c443SRobert Peterson { 4122332c443SRobert Peterson unsigned int reserved = 0; 4132332c443SRobert Peterson unsigned int mbuf_limit, metabufhdrs_needed; 4142332c443SRobert Peterson unsigned int dbuf_limit, databufhdrs_needed; 4152332c443SRobert Peterson unsigned int revokes = 0; 4162332c443SRobert Peterson 4172332c443SRobert Peterson mbuf_limit = buf_limit(sdp); 4182332c443SRobert Peterson metabufhdrs_needed = (sdp->sd_log_commited_buf + 4192332c443SRobert Peterson (mbuf_limit - 1)) / mbuf_limit; 4202332c443SRobert Peterson dbuf_limit = databuf_limit(sdp); 4212332c443SRobert Peterson databufhdrs_needed = (sdp->sd_log_commited_databuf + 4222332c443SRobert Peterson (dbuf_limit - 1)) / dbuf_limit; 4232332c443SRobert Peterson 4242e95e3f6SBenjamin Marzinski if (sdp->sd_log_commited_revoke > 0) 4252332c443SRobert Peterson revokes = gfs2_struct2blk(sdp, sdp->sd_log_commited_revoke, 4262332c443SRobert Peterson sizeof(u64)); 4272332c443SRobert Peterson 4282332c443SRobert Peterson reserved = sdp->sd_log_commited_buf + metabufhdrs_needed + 4292332c443SRobert Peterson sdp->sd_log_commited_databuf + databufhdrs_needed + 4302332c443SRobert Peterson revokes; 4312332c443SRobert Peterson /* One for the overall header */ 4322332c443SRobert Peterson if (reserved) 4332332c443SRobert Peterson reserved++; 4342332c443SRobert Peterson return reserved; 4352332c443SRobert Peterson } 4362332c443SRobert Peterson 437b3b94faaSDavid Teigland static unsigned int current_tail(struct gfs2_sbd *sdp) 438b3b94faaSDavid Teigland { 43916ca9412SBenjamin Marzinski struct gfs2_trans *tr; 440b3b94faaSDavid Teigland unsigned int tail; 441b3b94faaSDavid Teigland 442d6a079e8SDave Chinner spin_lock(&sdp->sd_ail_lock); 443b3b94faaSDavid Teigland 444faa31ce8SSteven Whitehouse if (list_empty(&sdp->sd_ail1_list)) { 445b3b94faaSDavid Teigland tail = sdp->sd_log_head; 446faa31ce8SSteven Whitehouse } else { 44716ca9412SBenjamin Marzinski tr = list_entry(sdp->sd_ail1_list.prev, struct gfs2_trans, 44816ca9412SBenjamin Marzinski tr_list); 44916ca9412SBenjamin Marzinski tail = tr->tr_first; 450b3b94faaSDavid Teigland } 451b3b94faaSDavid Teigland 452d6a079e8SDave Chinner spin_unlock(&sdp->sd_ail_lock); 453b3b94faaSDavid Teigland 454b3b94faaSDavid Teigland return tail; 455b3b94faaSDavid Teigland } 456b3b94faaSDavid Teigland 4572332c443SRobert Peterson static void log_pull_tail(struct gfs2_sbd *sdp, unsigned int new_tail) 458b3b94faaSDavid Teigland { 459b3b94faaSDavid Teigland unsigned int dist = log_distance(sdp, new_tail, sdp->sd_log_tail); 460b3b94faaSDavid Teigland 461b3b94faaSDavid Teigland ail2_empty(sdp, new_tail); 462b3b94faaSDavid Teigland 463fd041f0bSSteven Whitehouse atomic_add(dist, &sdp->sd_log_blks_free); 46463997775SSteven Whitehouse trace_gfs2_log_blocks(sdp, dist); 4655e687eacSBenjamin Marzinski gfs2_assert_withdraw(sdp, atomic_read(&sdp->sd_log_blks_free) <= 4665e687eacSBenjamin Marzinski sdp->sd_jdesc->jd_blocks); 467b3b94faaSDavid Teigland 468b3b94faaSDavid Teigland sdp->sd_log_tail = new_tail; 469b3b94faaSDavid Teigland } 470b3b94faaSDavid Teigland 471b3b94faaSDavid Teigland 47234cc1781SSteven Whitehouse static void log_flush_wait(struct gfs2_sbd *sdp) 473b3b94faaSDavid Teigland { 47416615be1SSteven Whitehouse DEFINE_WAIT(wait); 475b3b94faaSDavid Teigland 47616615be1SSteven Whitehouse if (atomic_read(&sdp->sd_log_in_flight)) { 47716615be1SSteven Whitehouse do { 47816615be1SSteven Whitehouse prepare_to_wait(&sdp->sd_log_flush_wait, &wait, 47916615be1SSteven Whitehouse TASK_UNINTERRUPTIBLE); 48016615be1SSteven Whitehouse if (atomic_read(&sdp->sd_log_in_flight)) 48116615be1SSteven Whitehouse io_schedule(); 48216615be1SSteven Whitehouse } while(atomic_read(&sdp->sd_log_in_flight)); 48316615be1SSteven Whitehouse finish_wait(&sdp->sd_log_flush_wait, &wait); 484b3b94faaSDavid Teigland } 485b3b94faaSDavid Teigland } 486b3b94faaSDavid Teigland 48745138990SSteven Whitehouse static int ip_cmp(void *priv, struct list_head *a, struct list_head *b) 4884a36d08dSBob Peterson { 48945138990SSteven Whitehouse struct gfs2_inode *ipa, *ipb; 4904a36d08dSBob Peterson 49145138990SSteven Whitehouse ipa = list_entry(a, struct gfs2_inode, i_ordered); 49245138990SSteven Whitehouse ipb = list_entry(b, struct gfs2_inode, i_ordered); 4934a36d08dSBob Peterson 49445138990SSteven Whitehouse if (ipa->i_no_addr < ipb->i_no_addr) 4954a36d08dSBob Peterson return -1; 49645138990SSteven Whitehouse if (ipa->i_no_addr > ipb->i_no_addr) 4974a36d08dSBob Peterson return 1; 4984a36d08dSBob Peterson return 0; 4994a36d08dSBob Peterson } 5004a36d08dSBob Peterson 501d7b616e2SSteven Whitehouse static void gfs2_ordered_write(struct gfs2_sbd *sdp) 502d7b616e2SSteven Whitehouse { 50345138990SSteven Whitehouse struct gfs2_inode *ip; 504d7b616e2SSteven Whitehouse LIST_HEAD(written); 505d7b616e2SSteven Whitehouse 50645138990SSteven Whitehouse spin_lock(&sdp->sd_ordered_lock); 50745138990SSteven Whitehouse list_sort(NULL, &sdp->sd_log_le_ordered, &ip_cmp); 508d7b616e2SSteven Whitehouse while (!list_empty(&sdp->sd_log_le_ordered)) { 50945138990SSteven Whitehouse ip = list_entry(sdp->sd_log_le_ordered.next, struct gfs2_inode, i_ordered); 51045138990SSteven Whitehouse list_move(&ip->i_ordered, &written); 51145138990SSteven Whitehouse if (ip->i_inode.i_mapping->nrpages == 0) 512d7b616e2SSteven Whitehouse continue; 51345138990SSteven Whitehouse spin_unlock(&sdp->sd_ordered_lock); 51445138990SSteven Whitehouse filemap_fdatawrite(ip->i_inode.i_mapping); 51545138990SSteven Whitehouse spin_lock(&sdp->sd_ordered_lock); 516d7b616e2SSteven Whitehouse } 517d7b616e2SSteven Whitehouse list_splice(&written, &sdp->sd_log_le_ordered); 51845138990SSteven Whitehouse spin_unlock(&sdp->sd_ordered_lock); 519d7b616e2SSteven Whitehouse } 520d7b616e2SSteven Whitehouse 521d7b616e2SSteven Whitehouse static void gfs2_ordered_wait(struct gfs2_sbd *sdp) 522d7b616e2SSteven Whitehouse { 52345138990SSteven Whitehouse struct gfs2_inode *ip; 524d7b616e2SSteven Whitehouse 52545138990SSteven Whitehouse spin_lock(&sdp->sd_ordered_lock); 526d7b616e2SSteven Whitehouse while (!list_empty(&sdp->sd_log_le_ordered)) { 52745138990SSteven Whitehouse ip = list_entry(sdp->sd_log_le_ordered.next, struct gfs2_inode, i_ordered); 52845138990SSteven Whitehouse list_del(&ip->i_ordered); 52945138990SSteven Whitehouse WARN_ON(!test_and_clear_bit(GIF_ORDERED, &ip->i_flags)); 53045138990SSteven Whitehouse if (ip->i_inode.i_mapping->nrpages == 0) 531d7b616e2SSteven Whitehouse continue; 53245138990SSteven Whitehouse spin_unlock(&sdp->sd_ordered_lock); 53345138990SSteven Whitehouse filemap_fdatawait(ip->i_inode.i_mapping); 53445138990SSteven Whitehouse spin_lock(&sdp->sd_ordered_lock); 535d7b616e2SSteven Whitehouse } 53645138990SSteven Whitehouse spin_unlock(&sdp->sd_ordered_lock); 537d7b616e2SSteven Whitehouse } 53845138990SSteven Whitehouse 53945138990SSteven Whitehouse void gfs2_ordered_del_inode(struct gfs2_inode *ip) 54045138990SSteven Whitehouse { 54145138990SSteven Whitehouse struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); 54245138990SSteven Whitehouse 54345138990SSteven Whitehouse spin_lock(&sdp->sd_ordered_lock); 54445138990SSteven Whitehouse if (test_and_clear_bit(GIF_ORDERED, &ip->i_flags)) 54545138990SSteven Whitehouse list_del(&ip->i_ordered); 54645138990SSteven Whitehouse spin_unlock(&sdp->sd_ordered_lock); 547d7b616e2SSteven Whitehouse } 548d7b616e2SSteven Whitehouse 549*5d054964SBenjamin Marzinski void gfs2_add_revoke(struct gfs2_sbd *sdp, struct gfs2_bufdata *bd) 550*5d054964SBenjamin Marzinski { 551*5d054964SBenjamin Marzinski struct buffer_head *bh = bd->bd_bh; 552*5d054964SBenjamin Marzinski struct gfs2_glock *gl = bd->bd_gl; 553*5d054964SBenjamin Marzinski 554*5d054964SBenjamin Marzinski gfs2_remove_from_ail(bd); 555*5d054964SBenjamin Marzinski bd->bd_bh = NULL; 556*5d054964SBenjamin Marzinski bh->b_private = NULL; 557*5d054964SBenjamin Marzinski bd->bd_blkno = bh->b_blocknr; 558*5d054964SBenjamin Marzinski bd->bd_ops = &gfs2_revoke_lops; 559*5d054964SBenjamin Marzinski sdp->sd_log_num_revoke++; 560*5d054964SBenjamin Marzinski atomic_inc(&gl->gl_revokes); 561*5d054964SBenjamin Marzinski set_bit(GLF_LFLUSH, &gl->gl_flags); 562*5d054964SBenjamin Marzinski list_add(&bd->bd_list, &sdp->sd_log_le_revoke); 563*5d054964SBenjamin Marzinski } 564*5d054964SBenjamin Marzinski 565*5d054964SBenjamin Marzinski void gfs2_write_revokes(struct gfs2_sbd *sdp) 566*5d054964SBenjamin Marzinski { 567*5d054964SBenjamin Marzinski struct gfs2_trans *tr; 568*5d054964SBenjamin Marzinski struct gfs2_bufdata *bd, *tmp; 569*5d054964SBenjamin Marzinski int have_revokes = 0; 570*5d054964SBenjamin Marzinski int max_revokes = (sdp->sd_sb.sb_bsize - sizeof(struct gfs2_log_descriptor)) / sizeof(u64); 571*5d054964SBenjamin Marzinski 572*5d054964SBenjamin Marzinski gfs2_ail1_empty(sdp); 573*5d054964SBenjamin Marzinski spin_lock(&sdp->sd_ail_lock); 574*5d054964SBenjamin Marzinski list_for_each_entry(tr, &sdp->sd_ail1_list, tr_list) { 575*5d054964SBenjamin Marzinski list_for_each_entry(bd, &tr->tr_ail2_list, bd_ail_st_list) { 576*5d054964SBenjamin Marzinski if (list_empty(&bd->bd_list)) { 577*5d054964SBenjamin Marzinski have_revokes = 1; 578*5d054964SBenjamin Marzinski goto done; 579*5d054964SBenjamin Marzinski } 580*5d054964SBenjamin Marzinski } 581*5d054964SBenjamin Marzinski } 582*5d054964SBenjamin Marzinski done: 583*5d054964SBenjamin Marzinski spin_unlock(&sdp->sd_ail_lock); 584*5d054964SBenjamin Marzinski if (have_revokes == 0) 585*5d054964SBenjamin Marzinski return; 586*5d054964SBenjamin Marzinski while (sdp->sd_log_num_revoke > max_revokes) 587*5d054964SBenjamin Marzinski max_revokes += (sdp->sd_sb.sb_bsize - sizeof(struct gfs2_meta_header)) / sizeof(u64); 588*5d054964SBenjamin Marzinski max_revokes -= sdp->sd_log_num_revoke; 589*5d054964SBenjamin Marzinski if (!sdp->sd_log_num_revoke) { 590*5d054964SBenjamin Marzinski atomic_dec(&sdp->sd_log_blks_free); 591*5d054964SBenjamin Marzinski /* If no blocks have been reserved, we need to also 592*5d054964SBenjamin Marzinski * reserve a block for the header */ 593*5d054964SBenjamin Marzinski if (!sdp->sd_log_blks_reserved) 594*5d054964SBenjamin Marzinski atomic_dec(&sdp->sd_log_blks_free); 595*5d054964SBenjamin Marzinski } 596*5d054964SBenjamin Marzinski gfs2_log_lock(sdp); 597*5d054964SBenjamin Marzinski spin_lock(&sdp->sd_ail_lock); 598*5d054964SBenjamin Marzinski list_for_each_entry(tr, &sdp->sd_ail1_list, tr_list) { 599*5d054964SBenjamin Marzinski list_for_each_entry_safe(bd, tmp, &tr->tr_ail2_list, bd_ail_st_list) { 600*5d054964SBenjamin Marzinski if (max_revokes == 0) 601*5d054964SBenjamin Marzinski goto out_of_blocks; 602*5d054964SBenjamin Marzinski if (!list_empty(&bd->bd_list)) 603*5d054964SBenjamin Marzinski continue; 604*5d054964SBenjamin Marzinski gfs2_add_revoke(sdp, bd); 605*5d054964SBenjamin Marzinski max_revokes--; 606*5d054964SBenjamin Marzinski } 607*5d054964SBenjamin Marzinski } 608*5d054964SBenjamin Marzinski out_of_blocks: 609*5d054964SBenjamin Marzinski spin_unlock(&sdp->sd_ail_lock); 610*5d054964SBenjamin Marzinski gfs2_log_unlock(sdp); 611*5d054964SBenjamin Marzinski 612*5d054964SBenjamin Marzinski if (!sdp->sd_log_num_revoke) { 613*5d054964SBenjamin Marzinski atomic_inc(&sdp->sd_log_blks_free); 614*5d054964SBenjamin Marzinski if (!sdp->sd_log_blks_reserved) 615*5d054964SBenjamin Marzinski atomic_inc(&sdp->sd_log_blks_free); 616*5d054964SBenjamin Marzinski } 617*5d054964SBenjamin Marzinski } 618*5d054964SBenjamin Marzinski 619b3b94faaSDavid Teigland /** 62034cc1781SSteven Whitehouse * log_write_header - Get and initialize a journal header buffer 62134cc1781SSteven Whitehouse * @sdp: The GFS2 superblock 62234cc1781SSteven Whitehouse * 62334cc1781SSteven Whitehouse * Returns: the initialized log buffer descriptor 62434cc1781SSteven Whitehouse */ 62534cc1781SSteven Whitehouse 626fdb76a42SSteven Whitehouse static void log_write_header(struct gfs2_sbd *sdp, u32 flags) 62734cc1781SSteven Whitehouse { 62834cc1781SSteven Whitehouse struct gfs2_log_header *lh; 62934cc1781SSteven Whitehouse unsigned int tail; 63034cc1781SSteven Whitehouse u32 hash; 631e8c92ed7SSteven Whitehouse int rw = WRITE_FLUSH_FUA | REQ_META; 632e8c92ed7SSteven Whitehouse struct page *page = mempool_alloc(gfs2_page_pool, GFP_NOIO); 633e8c92ed7SSteven Whitehouse lh = page_address(page); 634e8c92ed7SSteven Whitehouse clear_page(lh); 63534cc1781SSteven Whitehouse 63634cc1781SSteven Whitehouse tail = current_tail(sdp); 63734cc1781SSteven Whitehouse 63834cc1781SSteven Whitehouse lh->lh_header.mh_magic = cpu_to_be32(GFS2_MAGIC); 63934cc1781SSteven Whitehouse lh->lh_header.mh_type = cpu_to_be32(GFS2_METATYPE_LH); 64034cc1781SSteven Whitehouse lh->lh_header.__pad0 = cpu_to_be64(0); 64134cc1781SSteven Whitehouse lh->lh_header.mh_format = cpu_to_be32(GFS2_FORMAT_LH); 64234cc1781SSteven Whitehouse lh->lh_header.mh_jid = cpu_to_be32(sdp->sd_jdesc->jd_jid); 64334cc1781SSteven Whitehouse lh->lh_sequence = cpu_to_be64(sdp->sd_log_sequence++); 64434cc1781SSteven Whitehouse lh->lh_flags = cpu_to_be32(flags); 64534cc1781SSteven Whitehouse lh->lh_tail = cpu_to_be32(tail); 64634cc1781SSteven Whitehouse lh->lh_blkno = cpu_to_be32(sdp->sd_log_flush_head); 647e8c92ed7SSteven Whitehouse hash = gfs2_disk_hash(page_address(page), sizeof(struct gfs2_log_header)); 64834cc1781SSteven Whitehouse lh->lh_hash = cpu_to_be32(hash); 64934cc1781SSteven Whitehouse 65034cc1781SSteven Whitehouse if (test_bit(SDF_NOBARRIERS, &sdp->sd_flags)) { 65134cc1781SSteven Whitehouse gfs2_ordered_wait(sdp); 65234cc1781SSteven Whitehouse log_flush_wait(sdp); 653e8c92ed7SSteven Whitehouse rw = WRITE_SYNC | REQ_META | REQ_PRIO; 65434cc1781SSteven Whitehouse } 65534cc1781SSteven Whitehouse 656e8c92ed7SSteven Whitehouse sdp->sd_log_idle = (tail == sdp->sd_log_flush_head); 657e8c92ed7SSteven Whitehouse gfs2_log_write_page(sdp, page); 658e8c92ed7SSteven Whitehouse gfs2_log_flush_bio(sdp, rw); 659e8c92ed7SSteven Whitehouse log_flush_wait(sdp); 66034cc1781SSteven Whitehouse 66134cc1781SSteven Whitehouse if (sdp->sd_log_tail != tail) 66234cc1781SSteven Whitehouse log_pull_tail(sdp, tail); 66334cc1781SSteven Whitehouse } 66434cc1781SSteven Whitehouse 66534cc1781SSteven Whitehouse /** 666b09e593dSSteven Whitehouse * gfs2_log_flush - flush incore transaction(s) 667b3b94faaSDavid Teigland * @sdp: the filesystem 668b3b94faaSDavid Teigland * @gl: The glock structure to flush. If NULL, flush the whole incore log 669b3b94faaSDavid Teigland * 670b3b94faaSDavid Teigland */ 671b3b94faaSDavid Teigland 672ed4878e8SBob Peterson void gfs2_log_flush(struct gfs2_sbd *sdp, struct gfs2_glock *gl) 673b3b94faaSDavid Teigland { 67416ca9412SBenjamin Marzinski struct gfs2_trans *tr; 675b3b94faaSDavid Teigland 676484adff8SSteven Whitehouse down_write(&sdp->sd_log_flush_lock); 677f55ab26aSSteven Whitehouse 6782bcd610dSSteven Whitehouse /* Log might have been flushed while we waited for the flush lock */ 6792bcd610dSSteven Whitehouse if (gl && !test_bit(GLF_LFLUSH, &gl->gl_flags)) { 680484adff8SSteven Whitehouse up_write(&sdp->sd_log_flush_lock); 681f55ab26aSSteven Whitehouse return; 682f55ab26aSSteven Whitehouse } 68363997775SSteven Whitehouse trace_gfs2_log_flush(sdp, 1); 684f55ab26aSSteven Whitehouse 68516ca9412SBenjamin Marzinski tr = sdp->sd_log_tr; 68616ca9412SBenjamin Marzinski if (tr) { 68716ca9412SBenjamin Marzinski sdp->sd_log_tr = NULL; 68816ca9412SBenjamin Marzinski INIT_LIST_HEAD(&tr->tr_ail1_list); 68916ca9412SBenjamin Marzinski INIT_LIST_HEAD(&tr->tr_ail2_list); 69016ca9412SBenjamin Marzinski } 691b3b94faaSDavid Teigland 69216615be1SSteven Whitehouse if (sdp->sd_log_num_buf != sdp->sd_log_commited_buf) { 69316615be1SSteven Whitehouse printk(KERN_INFO "GFS2: log buf %u %u\n", sdp->sd_log_num_buf, 69416615be1SSteven Whitehouse sdp->sd_log_commited_buf); 69516615be1SSteven Whitehouse gfs2_assert_withdraw(sdp, 0); 69616615be1SSteven Whitehouse } 69716615be1SSteven Whitehouse if (sdp->sd_log_num_databuf != sdp->sd_log_commited_databuf) { 69816615be1SSteven Whitehouse printk(KERN_INFO "GFS2: log databuf %u %u\n", 69916615be1SSteven Whitehouse sdp->sd_log_num_databuf, sdp->sd_log_commited_databuf); 70016615be1SSteven Whitehouse gfs2_assert_withdraw(sdp, 0); 70116615be1SSteven Whitehouse } 702b3b94faaSDavid Teigland gfs2_assert_withdraw(sdp, 703b3b94faaSDavid Teigland sdp->sd_log_num_revoke == sdp->sd_log_commited_revoke); 704b3b94faaSDavid Teigland 705b3b94faaSDavid Teigland sdp->sd_log_flush_head = sdp->sd_log_head; 706b3b94faaSDavid Teigland sdp->sd_log_flush_wrapped = 0; 70716ca9412SBenjamin Marzinski if (tr) 70816ca9412SBenjamin Marzinski tr->tr_first = sdp->sd_log_flush_head; 709b3b94faaSDavid Teigland 710d7b616e2SSteven Whitehouse gfs2_ordered_write(sdp); 711b3b94faaSDavid Teigland lops_before_commit(sdp); 712e8c92ed7SSteven Whitehouse gfs2_log_flush_bio(sdp, WRITE); 713d7b616e2SSteven Whitehouse 71434cc1781SSteven Whitehouse if (sdp->sd_log_head != sdp->sd_log_flush_head) { 715fdb76a42SSteven Whitehouse log_write_header(sdp, 0); 71634cc1781SSteven Whitehouse } else if (sdp->sd_log_tail != current_tail(sdp) && !sdp->sd_log_idle){ 717fd041f0bSSteven Whitehouse atomic_dec(&sdp->sd_log_blks_free); /* Adjust for unreserved buffer */ 71863997775SSteven Whitehouse trace_gfs2_log_blocks(sdp, -1); 719fdb76a42SSteven Whitehouse log_write_header(sdp, 0); 7202332c443SRobert Peterson } 72116ca9412SBenjamin Marzinski lops_after_commit(sdp, tr); 722fe1a698fSSteven Whitehouse 723fe1a698fSSteven Whitehouse gfs2_log_lock(sdp); 724b3b94faaSDavid Teigland sdp->sd_log_head = sdp->sd_log_flush_head; 725faa31ce8SSteven Whitehouse sdp->sd_log_blks_reserved = 0; 726faa31ce8SSteven Whitehouse sdp->sd_log_commited_buf = 0; 7272332c443SRobert Peterson sdp->sd_log_commited_databuf = 0; 728b3b94faaSDavid Teigland sdp->sd_log_commited_revoke = 0; 729b3b94faaSDavid Teigland 730d6a079e8SDave Chinner spin_lock(&sdp->sd_ail_lock); 73116ca9412SBenjamin Marzinski if (tr && !list_empty(&tr->tr_ail1_list)) { 73216ca9412SBenjamin Marzinski list_add(&tr->tr_list, &sdp->sd_ail1_list); 73316ca9412SBenjamin Marzinski tr = NULL; 734b3b94faaSDavid Teigland } 735d6a079e8SDave Chinner spin_unlock(&sdp->sd_ail_lock); 736b3b94faaSDavid Teigland gfs2_log_unlock(sdp); 73763997775SSteven Whitehouse trace_gfs2_log_flush(sdp, 0); 738484adff8SSteven Whitehouse up_write(&sdp->sd_log_flush_lock); 739b3b94faaSDavid Teigland 74016ca9412SBenjamin Marzinski kfree(tr); 741b3b94faaSDavid Teigland } 742b3b94faaSDavid Teigland 743b3b94faaSDavid Teigland static void log_refund(struct gfs2_sbd *sdp, struct gfs2_trans *tr) 744b3b94faaSDavid Teigland { 7452332c443SRobert Peterson unsigned int reserved; 746ac39aaddSSteven Whitehouse unsigned int unused; 747b3b94faaSDavid Teigland 748b3b94faaSDavid Teigland gfs2_log_lock(sdp); 749b3b94faaSDavid Teigland 750b3b94faaSDavid Teigland sdp->sd_log_commited_buf += tr->tr_num_buf_new - tr->tr_num_buf_rm; 7512332c443SRobert Peterson sdp->sd_log_commited_databuf += tr->tr_num_databuf_new - 7522332c443SRobert Peterson tr->tr_num_databuf_rm; 7532332c443SRobert Peterson gfs2_assert_withdraw(sdp, (((int)sdp->sd_log_commited_buf) >= 0) || 7542332c443SRobert Peterson (((int)sdp->sd_log_commited_databuf) >= 0)); 755b3b94faaSDavid Teigland sdp->sd_log_commited_revoke += tr->tr_num_revoke - tr->tr_num_revoke_rm; 7562332c443SRobert Peterson reserved = calc_reserved(sdp); 75762be1f71SRoel Kluin gfs2_assert_withdraw(sdp, sdp->sd_log_blks_reserved + tr->tr_reserved >= reserved); 758ac39aaddSSteven Whitehouse unused = sdp->sd_log_blks_reserved - reserved + tr->tr_reserved; 759ac39aaddSSteven Whitehouse atomic_add(unused, &sdp->sd_log_blks_free); 76063997775SSteven Whitehouse trace_gfs2_log_blocks(sdp, unused); 761fd041f0bSSteven Whitehouse gfs2_assert_withdraw(sdp, atomic_read(&sdp->sd_log_blks_free) <= 7622332c443SRobert Peterson sdp->sd_jdesc->jd_blocks); 763b3b94faaSDavid Teigland sdp->sd_log_blks_reserved = reserved; 764b3b94faaSDavid Teigland 76516ca9412SBenjamin Marzinski if (sdp->sd_log_tr == NULL && 76616ca9412SBenjamin Marzinski (tr->tr_num_buf_new || tr->tr_num_databuf_new)) { 76716ca9412SBenjamin Marzinski gfs2_assert_withdraw(sdp, tr->tr_t_gh.gh_gl); 76816ca9412SBenjamin Marzinski sdp->sd_log_tr = tr; 76916ca9412SBenjamin Marzinski tr->tr_attached = 1; 77016ca9412SBenjamin Marzinski } 771b3b94faaSDavid Teigland gfs2_log_unlock(sdp); 772b3b94faaSDavid Teigland } 773b3b94faaSDavid Teigland 774b3b94faaSDavid Teigland /** 775b3b94faaSDavid Teigland * gfs2_log_commit - Commit a transaction to the log 776b3b94faaSDavid Teigland * @sdp: the filesystem 777b3b94faaSDavid Teigland * @tr: the transaction 778b3b94faaSDavid Teigland * 7795e687eacSBenjamin Marzinski * We wake up gfs2_logd if the number of pinned blocks exceed thresh1 7805e687eacSBenjamin Marzinski * or the total number of used blocks (pinned blocks plus AIL blocks) 7815e687eacSBenjamin Marzinski * is greater than thresh2. 7825e687eacSBenjamin Marzinski * 7835e687eacSBenjamin Marzinski * At mount time thresh1 is 1/3rd of journal size, thresh2 is 2/3rd of 7845e687eacSBenjamin Marzinski * journal size. 7855e687eacSBenjamin Marzinski * 786b3b94faaSDavid Teigland * Returns: errno 787b3b94faaSDavid Teigland */ 788b3b94faaSDavid Teigland 789b3b94faaSDavid Teigland void gfs2_log_commit(struct gfs2_sbd *sdp, struct gfs2_trans *tr) 790b3b94faaSDavid Teigland { 791b3b94faaSDavid Teigland log_refund(sdp, tr); 792b3b94faaSDavid Teigland 7935e687eacSBenjamin Marzinski if (atomic_read(&sdp->sd_log_pinned) > atomic_read(&sdp->sd_log_thresh1) || 7945e687eacSBenjamin Marzinski ((sdp->sd_jdesc->jd_blocks - atomic_read(&sdp->sd_log_blks_free)) > 7955e687eacSBenjamin Marzinski atomic_read(&sdp->sd_log_thresh2))) 7965e687eacSBenjamin Marzinski wake_up(&sdp->sd_logd_waitq); 797faa31ce8SSteven Whitehouse } 798b3b94faaSDavid Teigland 799b3b94faaSDavid Teigland /** 800b3b94faaSDavid Teigland * gfs2_log_shutdown - write a shutdown header into a journal 801b3b94faaSDavid Teigland * @sdp: the filesystem 802b3b94faaSDavid Teigland * 803b3b94faaSDavid Teigland */ 804b3b94faaSDavid Teigland 805b3b94faaSDavid Teigland void gfs2_log_shutdown(struct gfs2_sbd *sdp) 806b3b94faaSDavid Teigland { 807484adff8SSteven Whitehouse down_write(&sdp->sd_log_flush_lock); 808b3b94faaSDavid Teigland 809b3b94faaSDavid Teigland gfs2_assert_withdraw(sdp, !sdp->sd_log_blks_reserved); 810b3b94faaSDavid Teigland gfs2_assert_withdraw(sdp, !sdp->sd_log_num_buf); 811b3b94faaSDavid Teigland gfs2_assert_withdraw(sdp, !sdp->sd_log_num_revoke); 812b3b94faaSDavid Teigland gfs2_assert_withdraw(sdp, !sdp->sd_log_num_rg); 813b3b94faaSDavid Teigland gfs2_assert_withdraw(sdp, !sdp->sd_log_num_databuf); 814b3b94faaSDavid Teigland gfs2_assert_withdraw(sdp, list_empty(&sdp->sd_ail1_list)); 815b3b94faaSDavid Teigland 816b3b94faaSDavid Teigland sdp->sd_log_flush_head = sdp->sd_log_head; 817b3b94faaSDavid Teigland sdp->sd_log_flush_wrapped = 0; 818b3b94faaSDavid Teigland 819fdb76a42SSteven Whitehouse log_write_header(sdp, GFS2_LOG_HEAD_UNMOUNT); 820b3b94faaSDavid Teigland 821fd041f0bSSteven Whitehouse gfs2_assert_warn(sdp, atomic_read(&sdp->sd_log_blks_free) == sdp->sd_jdesc->jd_blocks); 822a74604beSSteven Whitehouse gfs2_assert_warn(sdp, sdp->sd_log_head == sdp->sd_log_tail); 823a74604beSSteven Whitehouse gfs2_assert_warn(sdp, list_empty(&sdp->sd_ail2_list)); 824b3b94faaSDavid Teigland 825b3b94faaSDavid Teigland sdp->sd_log_head = sdp->sd_log_flush_head; 826b3b94faaSDavid Teigland sdp->sd_log_tail = sdp->sd_log_head; 827b3b94faaSDavid Teigland 828484adff8SSteven Whitehouse up_write(&sdp->sd_log_flush_lock); 829b3b94faaSDavid Teigland } 830b3b94faaSDavid Teigland 831a25311c8SSteven Whitehouse 832a25311c8SSteven Whitehouse /** 833a25311c8SSteven Whitehouse * gfs2_meta_syncfs - sync all the buffers in a filesystem 834a25311c8SSteven Whitehouse * @sdp: the filesystem 835a25311c8SSteven Whitehouse * 836a25311c8SSteven Whitehouse */ 837a25311c8SSteven Whitehouse 838a25311c8SSteven Whitehouse void gfs2_meta_syncfs(struct gfs2_sbd *sdp) 839a25311c8SSteven Whitehouse { 840a25311c8SSteven Whitehouse gfs2_log_flush(sdp, NULL); 841a25311c8SSteven Whitehouse for (;;) { 8425e687eacSBenjamin Marzinski gfs2_ail1_start(sdp); 84326b06a69SSteven Whitehouse gfs2_ail1_wait(sdp); 8444667a0ecSSteven Whitehouse if (gfs2_ail1_empty(sdp)) 845a25311c8SSteven Whitehouse break; 846a25311c8SSteven Whitehouse } 847380f7c65SSteven Whitehouse gfs2_log_flush(sdp, NULL); 848a25311c8SSteven Whitehouse } 849a25311c8SSteven Whitehouse 8505e687eacSBenjamin Marzinski static inline int gfs2_jrnl_flush_reqd(struct gfs2_sbd *sdp) 8515e687eacSBenjamin Marzinski { 8525e687eacSBenjamin Marzinski return (atomic_read(&sdp->sd_log_pinned) >= atomic_read(&sdp->sd_log_thresh1)); 8535e687eacSBenjamin Marzinski } 8545e687eacSBenjamin Marzinski 8555e687eacSBenjamin Marzinski static inline int gfs2_ail_flush_reqd(struct gfs2_sbd *sdp) 8565e687eacSBenjamin Marzinski { 8575e687eacSBenjamin Marzinski unsigned int used_blocks = sdp->sd_jdesc->jd_blocks - atomic_read(&sdp->sd_log_blks_free); 8585e687eacSBenjamin Marzinski return used_blocks >= atomic_read(&sdp->sd_log_thresh2); 8595e687eacSBenjamin Marzinski } 860ec69b188SSteven Whitehouse 861ec69b188SSteven Whitehouse /** 862ec69b188SSteven Whitehouse * gfs2_logd - Update log tail as Active Items get flushed to in-place blocks 863ec69b188SSteven Whitehouse * @sdp: Pointer to GFS2 superblock 864ec69b188SSteven Whitehouse * 865ec69b188SSteven Whitehouse * Also, periodically check to make sure that we're using the most recent 866ec69b188SSteven Whitehouse * journal index. 867ec69b188SSteven Whitehouse */ 868ec69b188SSteven Whitehouse 869ec69b188SSteven Whitehouse int gfs2_logd(void *data) 870ec69b188SSteven Whitehouse { 871ec69b188SSteven Whitehouse struct gfs2_sbd *sdp = data; 8725e687eacSBenjamin Marzinski unsigned long t = 1; 8735e687eacSBenjamin Marzinski DEFINE_WAIT(wait); 874ec69b188SSteven Whitehouse 875ec69b188SSteven Whitehouse while (!kthread_should_stop()) { 876ec69b188SSteven Whitehouse 8775e687eacSBenjamin Marzinski if (gfs2_jrnl_flush_reqd(sdp) || t == 0) { 8784667a0ecSSteven Whitehouse gfs2_ail1_empty(sdp); 879ec69b188SSteven Whitehouse gfs2_log_flush(sdp, NULL); 880ec69b188SSteven Whitehouse } 881ec69b188SSteven Whitehouse 8825e687eacSBenjamin Marzinski if (gfs2_ail_flush_reqd(sdp)) { 8835e687eacSBenjamin Marzinski gfs2_ail1_start(sdp); 88426b06a69SSteven Whitehouse gfs2_ail1_wait(sdp); 8854667a0ecSSteven Whitehouse gfs2_ail1_empty(sdp); 8865e687eacSBenjamin Marzinski gfs2_log_flush(sdp, NULL); 8875e687eacSBenjamin Marzinski } 8885e687eacSBenjamin Marzinski 88926b06a69SSteven Whitehouse if (!gfs2_ail_flush_reqd(sdp)) 8905e687eacSBenjamin Marzinski wake_up(&sdp->sd_log_waitq); 89126b06a69SSteven Whitehouse 892ec69b188SSteven Whitehouse t = gfs2_tune_get(sdp, gt_logd_secs) * HZ; 893a0acae0eSTejun Heo 894a0acae0eSTejun Heo try_to_freeze(); 8955e687eacSBenjamin Marzinski 8965e687eacSBenjamin Marzinski do { 8975e687eacSBenjamin Marzinski prepare_to_wait(&sdp->sd_logd_waitq, &wait, 8985f487490SSteven Whitehouse TASK_INTERRUPTIBLE); 8995e687eacSBenjamin Marzinski if (!gfs2_ail_flush_reqd(sdp) && 9005e687eacSBenjamin Marzinski !gfs2_jrnl_flush_reqd(sdp) && 9015e687eacSBenjamin Marzinski !kthread_should_stop()) 9025e687eacSBenjamin Marzinski t = schedule_timeout(t); 9035e687eacSBenjamin Marzinski } while(t && !gfs2_ail_flush_reqd(sdp) && 9045e687eacSBenjamin Marzinski !gfs2_jrnl_flush_reqd(sdp) && 9055e687eacSBenjamin Marzinski !kthread_should_stop()); 9065e687eacSBenjamin Marzinski finish_wait(&sdp->sd_logd_waitq, &wait); 907ec69b188SSteven Whitehouse } 908ec69b188SSteven Whitehouse 909ec69b188SSteven Whitehouse return 0; 910ec69b188SSteven Whitehouse } 911ec69b188SSteven Whitehouse 912