1b3b94faaSDavid Teigland /* 2b3b94faaSDavid Teigland * Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. 3cf45b752SBob Peterson * Copyright (C) 2004-2008 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/spinlock.h> 11b3b94faaSDavid Teigland #include <linux/completion.h> 12b3b94faaSDavid Teigland #include <linux/buffer_head.h> 135c676f6dSSteven Whitehouse #include <linux/gfs2_ondisk.h> 146802e340SSteven Whitehouse #include <linux/bio.h> 15c65f7fb5SSteven Whitehouse #include <linux/posix_acl.h> 16f39814f6SAndreas Gruenbacher #include <linux/security.h> 17b3b94faaSDavid Teigland 18b3b94faaSDavid Teigland #include "gfs2.h" 195c676f6dSSteven Whitehouse #include "incore.h" 20b3b94faaSDavid Teigland #include "bmap.h" 21b3b94faaSDavid Teigland #include "glock.h" 22b3b94faaSDavid Teigland #include "glops.h" 23b3b94faaSDavid Teigland #include "inode.h" 24b3b94faaSDavid Teigland #include "log.h" 25b3b94faaSDavid Teigland #include "meta_io.h" 26b3b94faaSDavid Teigland #include "recovery.h" 27b3b94faaSDavid Teigland #include "rgrp.h" 285c676f6dSSteven Whitehouse #include "util.h" 29ddacfaf7SSteven Whitehouse #include "trans.h" 3017d539f0SSteven Whitehouse #include "dir.h" 31b3b94faaSDavid Teigland 322e60d768SBenjamin Marzinski struct workqueue_struct *gfs2_freeze_wq; 332e60d768SBenjamin Marzinski 3475549186SSteven Whitehouse static void gfs2_ail_error(struct gfs2_glock *gl, const struct buffer_head *bh) 3575549186SSteven Whitehouse { 3615562c43SBob Peterson fs_err(gl->gl_name.ln_sbd, 3715562c43SBob Peterson "AIL buffer %p: blocknr %llu state 0x%08lx mapping %p page " 3815562c43SBob Peterson "state 0x%lx\n", 3975549186SSteven Whitehouse bh, (unsigned long long)bh->b_blocknr, bh->b_state, 4075549186SSteven Whitehouse bh->b_page->mapping, bh->b_page->flags); 4115562c43SBob Peterson fs_err(gl->gl_name.ln_sbd, "AIL glock %u:%llu mapping %p\n", 4275549186SSteven Whitehouse gl->gl_name.ln_type, gl->gl_name.ln_number, 4375549186SSteven Whitehouse gfs2_glock2aspace(gl)); 4415562c43SBob Peterson gfs2_lm_withdraw(gl->gl_name.ln_sbd, "AIL error\n"); 4575549186SSteven Whitehouse } 4675549186SSteven Whitehouse 47ddacfaf7SSteven Whitehouse /** 48dba898b0SSteven Whitehouse * __gfs2_ail_flush - remove all buffers for a given lock from the AIL 49ddacfaf7SSteven Whitehouse * @gl: the glock 50b5b24d7aSSteven Whitehouse * @fsync: set when called from fsync (not all buffers will be clean) 51ddacfaf7SSteven Whitehouse * 52ddacfaf7SSteven Whitehouse * None of the buffers should be dirty, locked, or pinned. 53ddacfaf7SSteven Whitehouse */ 54ddacfaf7SSteven Whitehouse 551bc333f4SBenjamin Marzinski static void __gfs2_ail_flush(struct gfs2_glock *gl, bool fsync, 561bc333f4SBenjamin Marzinski unsigned int nr_revokes) 57ddacfaf7SSteven Whitehouse { 5815562c43SBob Peterson struct gfs2_sbd *sdp = gl->gl_name.ln_sbd; 59ddacfaf7SSteven Whitehouse struct list_head *head = &gl->gl_ail_list; 60b5b24d7aSSteven Whitehouse struct gfs2_bufdata *bd, *tmp; 61ddacfaf7SSteven Whitehouse struct buffer_head *bh; 62b5b24d7aSSteven Whitehouse const unsigned long b_state = (1UL << BH_Dirty)|(1UL << BH_Pinned)|(1UL << BH_Lock); 63ddacfaf7SSteven Whitehouse 64b5b24d7aSSteven Whitehouse gfs2_log_lock(sdp); 65d6a079e8SDave Chinner spin_lock(&sdp->sd_ail_lock); 661bc333f4SBenjamin Marzinski list_for_each_entry_safe_reverse(bd, tmp, head, bd_ail_gl_list) { 671bc333f4SBenjamin Marzinski if (nr_revokes == 0) 681bc333f4SBenjamin Marzinski break; 69ddacfaf7SSteven Whitehouse bh = bd->bd_bh; 70b5b24d7aSSteven Whitehouse if (bh->b_state & b_state) { 71b5b24d7aSSteven Whitehouse if (fsync) 72b5b24d7aSSteven Whitehouse continue; 7375549186SSteven Whitehouse gfs2_ail_error(gl, bh); 74b5b24d7aSSteven Whitehouse } 751ad38c43SSteven Whitehouse gfs2_trans_add_revoke(sdp, bd); 761bc333f4SBenjamin Marzinski nr_revokes--; 77ddacfaf7SSteven Whitehouse } 788eae1ca0SSteven Whitehouse GLOCK_BUG_ON(gl, !fsync && atomic_read(&gl->gl_ail_count)); 79d6a079e8SDave Chinner spin_unlock(&sdp->sd_ail_lock); 80b5b24d7aSSteven Whitehouse gfs2_log_unlock(sdp); 81dba898b0SSteven Whitehouse } 82ddacfaf7SSteven Whitehouse 83dba898b0SSteven Whitehouse 84dba898b0SSteven Whitehouse static void gfs2_ail_empty_gl(struct gfs2_glock *gl) 85dba898b0SSteven Whitehouse { 8615562c43SBob Peterson struct gfs2_sbd *sdp = gl->gl_name.ln_sbd; 87dba898b0SSteven Whitehouse struct gfs2_trans tr; 88dba898b0SSteven Whitehouse 89dba898b0SSteven Whitehouse memset(&tr, 0, sizeof(tr)); 90d69a3c65SSteven Whitehouse INIT_LIST_HEAD(&tr.tr_buf); 91d69a3c65SSteven Whitehouse INIT_LIST_HEAD(&tr.tr_databuf); 92dba898b0SSteven Whitehouse tr.tr_revokes = atomic_read(&gl->gl_ail_count); 93dba898b0SSteven Whitehouse 94dba898b0SSteven Whitehouse if (!tr.tr_revokes) 95dba898b0SSteven Whitehouse return; 96dba898b0SSteven Whitehouse 9724972557SBenjamin Marzinski /* A shortened, inline version of gfs2_trans_begin() 9824972557SBenjamin Marzinski * tr->alloced is not set since the transaction structure is 9924972557SBenjamin Marzinski * on the stack */ 100dba898b0SSteven Whitehouse tr.tr_reserved = 1 + gfs2_struct2blk(sdp, tr.tr_revokes, sizeof(u64)); 101d29c0afeSFabian Frederick tr.tr_ip = _RET_IP_; 1022e60d768SBenjamin Marzinski if (gfs2_log_reserve(sdp, tr.tr_reserved) < 0) 10324972557SBenjamin Marzinski return; 1048eae1ca0SSteven Whitehouse WARN_ON_ONCE(current->journal_info); 105dba898b0SSteven Whitehouse current->journal_info = &tr; 106dba898b0SSteven Whitehouse 1071bc333f4SBenjamin Marzinski __gfs2_ail_flush(gl, 0, tr.tr_revokes); 108dba898b0SSteven Whitehouse 109dba898b0SSteven Whitehouse gfs2_trans_end(sdp); 110805c0907SBob Peterson gfs2_log_flush(sdp, NULL, GFS2_LOG_HEAD_FLUSH_NORMAL | 111805c0907SBob Peterson GFS2_LFC_AIL_EMPTY_GL); 112dba898b0SSteven Whitehouse } 113dba898b0SSteven Whitehouse 114b5b24d7aSSteven Whitehouse void gfs2_ail_flush(struct gfs2_glock *gl, bool fsync) 115dba898b0SSteven Whitehouse { 11615562c43SBob Peterson struct gfs2_sbd *sdp = gl->gl_name.ln_sbd; 117dba898b0SSteven Whitehouse unsigned int revokes = atomic_read(&gl->gl_ail_count); 1181bc333f4SBenjamin Marzinski unsigned int max_revokes = (sdp->sd_sb.sb_bsize - sizeof(struct gfs2_log_descriptor)) / sizeof(u64); 119dba898b0SSteven Whitehouse int ret; 120dba898b0SSteven Whitehouse 121dba898b0SSteven Whitehouse if (!revokes) 122dba898b0SSteven Whitehouse return; 123dba898b0SSteven Whitehouse 1241bc333f4SBenjamin Marzinski while (revokes > max_revokes) 1251bc333f4SBenjamin Marzinski max_revokes += (sdp->sd_sb.sb_bsize - sizeof(struct gfs2_meta_header)) / sizeof(u64); 1261bc333f4SBenjamin Marzinski 1271bc333f4SBenjamin Marzinski ret = gfs2_trans_begin(sdp, 0, max_revokes); 128dba898b0SSteven Whitehouse if (ret) 129dba898b0SSteven Whitehouse return; 1301bc333f4SBenjamin Marzinski __gfs2_ail_flush(gl, fsync, max_revokes); 131ddacfaf7SSteven Whitehouse gfs2_trans_end(sdp); 132805c0907SBob Peterson gfs2_log_flush(sdp, NULL, GFS2_LOG_HEAD_FLUSH_NORMAL | 133805c0907SBob Peterson GFS2_LFC_AIL_FLUSH); 134ddacfaf7SSteven Whitehouse } 135ba7f7290SSteven Whitehouse 136ba7f7290SSteven Whitehouse /** 1376bac243fSSteven Whitehouse * rgrp_go_sync - sync out the metadata for this glock 138b3b94faaSDavid Teigland * @gl: the glock 139b3b94faaSDavid Teigland * 140b3b94faaSDavid Teigland * Called when demoting or unlocking an EX glock. We must flush 141b3b94faaSDavid Teigland * to disk all dirty buffers/pages relating to this glock, and must not 1426f6597baSAndreas Gruenbacher * return to caller to demote/unlock the glock until I/O is complete. 143b3b94faaSDavid Teigland */ 144b3b94faaSDavid Teigland 1456bac243fSSteven Whitehouse static void rgrp_go_sync(struct gfs2_glock *gl) 146b3b94faaSDavid Teigland { 14715562c43SBob Peterson struct gfs2_sbd *sdp = gl->gl_name.ln_sbd; 14870d4ee94SSteven Whitehouse struct address_space *mapping = &sdp->sd_aspace; 1498339ee54SSteven Whitehouse struct gfs2_rgrpd *rgd; 1506bac243fSSteven Whitehouse int error; 151b5d32beaSSteven Whitehouse 152f3dd1649SAndreas Gruenbacher spin_lock(&gl->gl_lockref.lock); 15339b0f1e9SBob Peterson rgd = gl->gl_object; 15439b0f1e9SBob Peterson if (rgd) 15539b0f1e9SBob Peterson gfs2_rgrp_brelse(rgd); 156f3dd1649SAndreas Gruenbacher spin_unlock(&gl->gl_lockref.lock); 15739b0f1e9SBob Peterson 1586bac243fSSteven Whitehouse if (!test_and_clear_bit(GLF_DIRTY, &gl->gl_flags)) 1596bac243fSSteven Whitehouse return; 1608eae1ca0SSteven Whitehouse GLOCK_BUG_ON(gl, gl->gl_state != LM_ST_EXCLUSIVE); 1616bac243fSSteven Whitehouse 162805c0907SBob Peterson gfs2_log_flush(sdp, gl, GFS2_LOG_HEAD_FLUSH_NORMAL | 163805c0907SBob Peterson GFS2_LFC_RGRP_GO_SYNC); 16470d4ee94SSteven Whitehouse filemap_fdatawrite_range(mapping, gl->gl_vm.start, gl->gl_vm.end); 16570d4ee94SSteven Whitehouse error = filemap_fdatawait_range(mapping, gl->gl_vm.start, gl->gl_vm.end); 16670d4ee94SSteven Whitehouse mapping_set_error(mapping, error); 167b3b94faaSDavid Teigland gfs2_ail_empty_gl(gl); 1687c9ca621SBob Peterson 169f3dd1649SAndreas Gruenbacher spin_lock(&gl->gl_lockref.lock); 1708339ee54SSteven Whitehouse rgd = gl->gl_object; 1718339ee54SSteven Whitehouse if (rgd) 1728339ee54SSteven Whitehouse gfs2_free_clones(rgd); 173f3dd1649SAndreas Gruenbacher spin_unlock(&gl->gl_lockref.lock); 174b3b94faaSDavid Teigland } 175b3b94faaSDavid Teigland 176b3b94faaSDavid Teigland /** 1776bac243fSSteven Whitehouse * rgrp_go_inval - invalidate the metadata for this glock 178b3b94faaSDavid Teigland * @gl: the glock 179b3b94faaSDavid Teigland * @flags: 180b3b94faaSDavid Teigland * 1816bac243fSSteven Whitehouse * We never used LM_ST_DEFERRED with resource groups, so that we 1826bac243fSSteven Whitehouse * should always see the metadata flag set here. 1836bac243fSSteven Whitehouse * 184b3b94faaSDavid Teigland */ 185b3b94faaSDavid Teigland 1866bac243fSSteven Whitehouse static void rgrp_go_inval(struct gfs2_glock *gl, int flags) 187b3b94faaSDavid Teigland { 18815562c43SBob Peterson struct gfs2_sbd *sdp = gl->gl_name.ln_sbd; 18970d4ee94SSteven Whitehouse struct address_space *mapping = &sdp->sd_aspace; 1906f6597baSAndreas Gruenbacher struct gfs2_rgrpd *rgd = gfs2_glock2rgrp(gl); 19139b0f1e9SBob Peterson 19239b0f1e9SBob Peterson if (rgd) 19339b0f1e9SBob Peterson gfs2_rgrp_brelse(rgd); 194b3b94faaSDavid Teigland 1958eae1ca0SSteven Whitehouse WARN_ON_ONCE(!(flags & DIO_METADATA)); 19670d4ee94SSteven Whitehouse gfs2_assert_withdraw(sdp, !atomic_read(&gl->gl_ail_count)); 1977005c3e4SSteven Whitehouse truncate_inode_pages_range(mapping, gl->gl_vm.start, gl->gl_vm.end); 1986bac243fSSteven Whitehouse 19939b0f1e9SBob Peterson if (rgd) 200cf45b752SBob Peterson rgd->rd_flags &= ~GFS2_RDF_UPTODATE; 201cf45b752SBob Peterson } 202b3b94faaSDavid Teigland 2034fd1a579SAndreas Gruenbacher static struct gfs2_inode *gfs2_glock2inode(struct gfs2_glock *gl) 2044fd1a579SAndreas Gruenbacher { 2054fd1a579SAndreas Gruenbacher struct gfs2_inode *ip; 2064fd1a579SAndreas Gruenbacher 2074fd1a579SAndreas Gruenbacher spin_lock(&gl->gl_lockref.lock); 2084fd1a579SAndreas Gruenbacher ip = gl->gl_object; 2094fd1a579SAndreas Gruenbacher if (ip) 2104fd1a579SAndreas Gruenbacher set_bit(GIF_GLOP_PENDING, &ip->i_flags); 2114fd1a579SAndreas Gruenbacher spin_unlock(&gl->gl_lockref.lock); 2124fd1a579SAndreas Gruenbacher return ip; 2134fd1a579SAndreas Gruenbacher } 2144fd1a579SAndreas Gruenbacher 2156f6597baSAndreas Gruenbacher struct gfs2_rgrpd *gfs2_glock2rgrp(struct gfs2_glock *gl) 2166f6597baSAndreas Gruenbacher { 2176f6597baSAndreas Gruenbacher struct gfs2_rgrpd *rgd; 2186f6597baSAndreas Gruenbacher 2196f6597baSAndreas Gruenbacher spin_lock(&gl->gl_lockref.lock); 2206f6597baSAndreas Gruenbacher rgd = gl->gl_object; 2216f6597baSAndreas Gruenbacher spin_unlock(&gl->gl_lockref.lock); 2226f6597baSAndreas Gruenbacher 2236f6597baSAndreas Gruenbacher return rgd; 2246f6597baSAndreas Gruenbacher } 2256f6597baSAndreas Gruenbacher 2264fd1a579SAndreas Gruenbacher static void gfs2_clear_glop_pending(struct gfs2_inode *ip) 2274fd1a579SAndreas Gruenbacher { 2284fd1a579SAndreas Gruenbacher if (!ip) 2294fd1a579SAndreas Gruenbacher return; 2304fd1a579SAndreas Gruenbacher 2314fd1a579SAndreas Gruenbacher clear_bit_unlock(GIF_GLOP_PENDING, &ip->i_flags); 2324fd1a579SAndreas Gruenbacher wake_up_bit(&ip->i_flags, GIF_GLOP_PENDING); 2334fd1a579SAndreas Gruenbacher } 2344fd1a579SAndreas Gruenbacher 235b3b94faaSDavid Teigland /** 236b5d32beaSSteven Whitehouse * inode_go_sync - Sync the dirty data and/or metadata for an inode glock 237b5d32beaSSteven Whitehouse * @gl: the glock protecting the inode 238b5d32beaSSteven Whitehouse * 239b5d32beaSSteven Whitehouse */ 240b5d32beaSSteven Whitehouse 241b5d32beaSSteven Whitehouse static void inode_go_sync(struct gfs2_glock *gl) 242b5d32beaSSteven Whitehouse { 2434fd1a579SAndreas Gruenbacher struct gfs2_inode *ip = gfs2_glock2inode(gl); 2444fd1a579SAndreas Gruenbacher int isreg = ip && S_ISREG(ip->i_inode.i_mode); 245009d8518SSteven Whitehouse struct address_space *metamapping = gfs2_glock2aspace(gl); 2463042a2ccSSteven Whitehouse int error; 2473042a2ccSSteven Whitehouse 2484fd1a579SAndreas Gruenbacher if (isreg) { 249582d2f7aSSteven Whitehouse if (test_and_clear_bit(GIF_SW_PAGED, &ip->i_flags)) 2506bac243fSSteven Whitehouse unmap_shared_mapping_range(ip->i_inode.i_mapping, 0, 0); 251582d2f7aSSteven Whitehouse inode_dio_wait(&ip->i_inode); 252582d2f7aSSteven Whitehouse } 2536bac243fSSteven Whitehouse if (!test_and_clear_bit(GLF_DIRTY, &gl->gl_flags)) 2544fd1a579SAndreas Gruenbacher goto out; 255b5d32beaSSteven Whitehouse 2568eae1ca0SSteven Whitehouse GLOCK_BUG_ON(gl, gl->gl_state != LM_ST_EXCLUSIVE); 2576bac243fSSteven Whitehouse 258805c0907SBob Peterson gfs2_log_flush(gl->gl_name.ln_sbd, gl, GFS2_LOG_HEAD_FLUSH_NORMAL | 259805c0907SBob Peterson GFS2_LFC_INODE_GO_SYNC); 2603042a2ccSSteven Whitehouse filemap_fdatawrite(metamapping); 2614fd1a579SAndreas Gruenbacher if (isreg) { 262b5d32beaSSteven Whitehouse struct address_space *mapping = ip->i_inode.i_mapping; 2633042a2ccSSteven Whitehouse filemap_fdatawrite(mapping); 2643042a2ccSSteven Whitehouse error = filemap_fdatawait(mapping); 2653e9f45bdSGuillaume Chazarain mapping_set_error(mapping, error); 266b5d32beaSSteven Whitehouse } 2673042a2ccSSteven Whitehouse error = filemap_fdatawait(metamapping); 2683042a2ccSSteven Whitehouse mapping_set_error(metamapping, error); 269b5d32beaSSteven Whitehouse gfs2_ail_empty_gl(gl); 27052fcd11cSSteven Whitehouse /* 27152fcd11cSSteven Whitehouse * Writeback of the data mapping may cause the dirty flag to be set 27252fcd11cSSteven Whitehouse * so we have to clear it again here. 27352fcd11cSSteven Whitehouse */ 2744e857c58SPeter Zijlstra smp_mb__before_atomic(); 27552fcd11cSSteven Whitehouse clear_bit(GLF_DIRTY, &gl->gl_flags); 2764fd1a579SAndreas Gruenbacher 2774fd1a579SAndreas Gruenbacher out: 2784fd1a579SAndreas Gruenbacher gfs2_clear_glop_pending(ip); 279b5d32beaSSteven Whitehouse } 280b5d32beaSSteven Whitehouse 281b5d32beaSSteven Whitehouse /** 282b3b94faaSDavid Teigland * inode_go_inval - prepare a inode glock to be released 283b3b94faaSDavid Teigland * @gl: the glock 284b3b94faaSDavid Teigland * @flags: 285b3b94faaSDavid Teigland * 2866b49d1d9SGeert Uytterhoeven * Normally we invalidate everything, but if we are moving into 2876bac243fSSteven Whitehouse * LM_ST_DEFERRED from LM_ST_SHARED or LM_ST_EXCLUSIVE then we 2886bac243fSSteven Whitehouse * can keep hold of the metadata, since it won't have changed. 2896bac243fSSteven Whitehouse * 290b3b94faaSDavid Teigland */ 291b3b94faaSDavid Teigland 292b3b94faaSDavid Teigland static void inode_go_inval(struct gfs2_glock *gl, int flags) 293b3b94faaSDavid Teigland { 2944fd1a579SAndreas Gruenbacher struct gfs2_inode *ip = gfs2_glock2inode(gl); 295b3b94faaSDavid Teigland 29615562c43SBob Peterson gfs2_assert_withdraw(gl->gl_name.ln_sbd, !atomic_read(&gl->gl_ail_count)); 2976bac243fSSteven Whitehouse 2986bac243fSSteven Whitehouse if (flags & DIO_METADATA) { 299009d8518SSteven Whitehouse struct address_space *mapping = gfs2_glock2aspace(gl); 3006bac243fSSteven Whitehouse truncate_inode_pages(mapping, 0); 301c65f7fb5SSteven Whitehouse if (ip) { 302bfded27bSSteven Whitehouse set_bit(GIF_INVALID, &ip->i_flags); 303c65f7fb5SSteven Whitehouse forget_all_cached_acls(&ip->i_inode); 304f39814f6SAndreas Gruenbacher security_inode_invalidate_secctx(&ip->i_inode); 30517d539f0SSteven Whitehouse gfs2_dir_hash_inval(ip); 306c65f7fb5SSteven Whitehouse } 307b3b94faaSDavid Teigland } 308b004157aSSteven Whitehouse 30915562c43SBob Peterson if (ip == GFS2_I(gl->gl_name.ln_sbd->sd_rindex)) { 310c1696fb8SBob Peterson gfs2_log_flush(gl->gl_name.ln_sbd, NULL, 311805c0907SBob Peterson GFS2_LOG_HEAD_FLUSH_NORMAL | 312805c0907SBob Peterson GFS2_LFC_INODE_GO_INVAL); 31315562c43SBob Peterson gl->gl_name.ln_sbd->sd_rindex_uptodate = 0; 3141ce53368SBenjamin Marzinski } 3153cc3f710SSteven Whitehouse if (ip && S_ISREG(ip->i_inode.i_mode)) 316b004157aSSteven Whitehouse truncate_inode_pages(ip->i_inode.i_mapping, 0); 3174fd1a579SAndreas Gruenbacher 3184fd1a579SAndreas Gruenbacher gfs2_clear_glop_pending(ip); 319b3b94faaSDavid Teigland } 320b3b94faaSDavid Teigland 321b3b94faaSDavid Teigland /** 322b3b94faaSDavid Teigland * inode_go_demote_ok - Check to see if it's ok to unlock an inode glock 323b3b94faaSDavid Teigland * @gl: the glock 324b3b94faaSDavid Teigland * 325b3b94faaSDavid Teigland * Returns: 1 if it's ok 326b3b94faaSDavid Teigland */ 327b3b94faaSDavid Teigland 32897cc1025SSteven Whitehouse static int inode_go_demote_ok(const struct gfs2_glock *gl) 329b3b94faaSDavid Teigland { 33015562c43SBob Peterson struct gfs2_sbd *sdp = gl->gl_name.ln_sbd; 331bc015cb8SSteven Whitehouse 33297cc1025SSteven Whitehouse if (sdp->sd_jindex == gl->gl_object || sdp->sd_rindex == gl->gl_object) 33397cc1025SSteven Whitehouse return 0; 334bc015cb8SSteven Whitehouse 33597cc1025SSteven Whitehouse return 1; 336b3b94faaSDavid Teigland } 337b3b94faaSDavid Teigland 338d4b2cf1bSSteven Whitehouse static int gfs2_dinode_in(struct gfs2_inode *ip, const void *buf) 339d4b2cf1bSSteven Whitehouse { 340d4b2cf1bSSteven Whitehouse const struct gfs2_dinode *str = buf; 341*95582b00SDeepa Dinamani struct timespec64 atime; 342d4b2cf1bSSteven Whitehouse u16 height, depth; 343d4b2cf1bSSteven Whitehouse 344d4b2cf1bSSteven Whitehouse if (unlikely(ip->i_no_addr != be64_to_cpu(str->di_num.no_addr))) 345d4b2cf1bSSteven Whitehouse goto corrupt; 346d4b2cf1bSSteven Whitehouse ip->i_no_formal_ino = be64_to_cpu(str->di_num.no_formal_ino); 347d4b2cf1bSSteven Whitehouse ip->i_inode.i_mode = be32_to_cpu(str->di_mode); 348d4b2cf1bSSteven Whitehouse ip->i_inode.i_rdev = 0; 349d4b2cf1bSSteven Whitehouse switch (ip->i_inode.i_mode & S_IFMT) { 350d4b2cf1bSSteven Whitehouse case S_IFBLK: 351d4b2cf1bSSteven Whitehouse case S_IFCHR: 352d4b2cf1bSSteven Whitehouse ip->i_inode.i_rdev = MKDEV(be32_to_cpu(str->di_major), 353d4b2cf1bSSteven Whitehouse be32_to_cpu(str->di_minor)); 354d4b2cf1bSSteven Whitehouse break; 355d4b2cf1bSSteven Whitehouse }; 356d4b2cf1bSSteven Whitehouse 357d0546426SEric W. Biederman i_uid_write(&ip->i_inode, be32_to_cpu(str->di_uid)); 358d0546426SEric W. Biederman i_gid_write(&ip->i_inode, be32_to_cpu(str->di_gid)); 359eebd2e81SAndreas Gruenbacher set_nlink(&ip->i_inode, be32_to_cpu(str->di_nlink)); 360d4b2cf1bSSteven Whitehouse i_size_write(&ip->i_inode, be64_to_cpu(str->di_size)); 361d4b2cf1bSSteven Whitehouse gfs2_set_inode_blocks(&ip->i_inode, be64_to_cpu(str->di_blocks)); 362d4b2cf1bSSteven Whitehouse atime.tv_sec = be64_to_cpu(str->di_atime); 363d4b2cf1bSSteven Whitehouse atime.tv_nsec = be32_to_cpu(str->di_atime_nsec); 364*95582b00SDeepa Dinamani if (timespec64_compare(&ip->i_inode.i_atime, &atime) < 0) 365d4b2cf1bSSteven Whitehouse ip->i_inode.i_atime = atime; 366d4b2cf1bSSteven Whitehouse ip->i_inode.i_mtime.tv_sec = be64_to_cpu(str->di_mtime); 367d4b2cf1bSSteven Whitehouse ip->i_inode.i_mtime.tv_nsec = be32_to_cpu(str->di_mtime_nsec); 368d4b2cf1bSSteven Whitehouse ip->i_inode.i_ctime.tv_sec = be64_to_cpu(str->di_ctime); 369d4b2cf1bSSteven Whitehouse ip->i_inode.i_ctime.tv_nsec = be32_to_cpu(str->di_ctime_nsec); 370d4b2cf1bSSteven Whitehouse 371d4b2cf1bSSteven Whitehouse ip->i_goal = be64_to_cpu(str->di_goal_meta); 372d4b2cf1bSSteven Whitehouse ip->i_generation = be64_to_cpu(str->di_generation); 373d4b2cf1bSSteven Whitehouse 374d4b2cf1bSSteven Whitehouse ip->i_diskflags = be32_to_cpu(str->di_flags); 3759964afbbSSteven Whitehouse ip->i_eattr = be64_to_cpu(str->di_eattr); 3769964afbbSSteven Whitehouse /* i_diskflags and i_eattr must be set before gfs2_set_inode_flags() */ 377d4b2cf1bSSteven Whitehouse gfs2_set_inode_flags(&ip->i_inode); 378d4b2cf1bSSteven Whitehouse height = be16_to_cpu(str->di_height); 379d4b2cf1bSSteven Whitehouse if (unlikely(height > GFS2_MAX_META_HEIGHT)) 380d4b2cf1bSSteven Whitehouse goto corrupt; 381d4b2cf1bSSteven Whitehouse ip->i_height = (u8)height; 382d4b2cf1bSSteven Whitehouse 383d4b2cf1bSSteven Whitehouse depth = be16_to_cpu(str->di_depth); 384d4b2cf1bSSteven Whitehouse if (unlikely(depth > GFS2_DIR_MAX_DEPTH)) 385d4b2cf1bSSteven Whitehouse goto corrupt; 386d4b2cf1bSSteven Whitehouse ip->i_depth = (u8)depth; 387d4b2cf1bSSteven Whitehouse ip->i_entries = be32_to_cpu(str->di_entries); 388d4b2cf1bSSteven Whitehouse 389d4b2cf1bSSteven Whitehouse if (S_ISREG(ip->i_inode.i_mode)) 390d4b2cf1bSSteven Whitehouse gfs2_set_aops(&ip->i_inode); 391d4b2cf1bSSteven Whitehouse 392d4b2cf1bSSteven Whitehouse return 0; 393d4b2cf1bSSteven Whitehouse corrupt: 394d4b2cf1bSSteven Whitehouse gfs2_consist_inode(ip); 395d4b2cf1bSSteven Whitehouse return -EIO; 396d4b2cf1bSSteven Whitehouse } 397d4b2cf1bSSteven Whitehouse 398d4b2cf1bSSteven Whitehouse /** 399d4b2cf1bSSteven Whitehouse * gfs2_inode_refresh - Refresh the incore copy of the dinode 400d4b2cf1bSSteven Whitehouse * @ip: The GFS2 inode 401d4b2cf1bSSteven Whitehouse * 402d4b2cf1bSSteven Whitehouse * Returns: errno 403d4b2cf1bSSteven Whitehouse */ 404d4b2cf1bSSteven Whitehouse 405d4b2cf1bSSteven Whitehouse int gfs2_inode_refresh(struct gfs2_inode *ip) 406d4b2cf1bSSteven Whitehouse { 407d4b2cf1bSSteven Whitehouse struct buffer_head *dibh; 408d4b2cf1bSSteven Whitehouse int error; 409d4b2cf1bSSteven Whitehouse 410d4b2cf1bSSteven Whitehouse error = gfs2_meta_inode_buffer(ip, &dibh); 411d4b2cf1bSSteven Whitehouse if (error) 412d4b2cf1bSSteven Whitehouse return error; 413d4b2cf1bSSteven Whitehouse 414d4b2cf1bSSteven Whitehouse error = gfs2_dinode_in(ip, dibh->b_data); 415d4b2cf1bSSteven Whitehouse brelse(dibh); 416d4b2cf1bSSteven Whitehouse clear_bit(GIF_INVALID, &ip->i_flags); 417d4b2cf1bSSteven Whitehouse 418d4b2cf1bSSteven Whitehouse return error; 419d4b2cf1bSSteven Whitehouse } 420d4b2cf1bSSteven Whitehouse 421d4b2cf1bSSteven Whitehouse /** 422b3b94faaSDavid Teigland * inode_go_lock - operation done after an inode lock is locked by a process 423b3b94faaSDavid Teigland * @gl: the glock 424b3b94faaSDavid Teigland * @flags: 425b3b94faaSDavid Teigland * 426b3b94faaSDavid Teigland * Returns: errno 427b3b94faaSDavid Teigland */ 428b3b94faaSDavid Teigland 429b3b94faaSDavid Teigland static int inode_go_lock(struct gfs2_holder *gh) 430b3b94faaSDavid Teigland { 431b3b94faaSDavid Teigland struct gfs2_glock *gl = gh->gh_gl; 43215562c43SBob Peterson struct gfs2_sbd *sdp = gl->gl_name.ln_sbd; 4335c676f6dSSteven Whitehouse struct gfs2_inode *ip = gl->gl_object; 434b3b94faaSDavid Teigland int error = 0; 435b3b94faaSDavid Teigland 436091806edSBob Peterson if (!ip || (gh->gh_flags & GL_SKIP)) 437b3b94faaSDavid Teigland return 0; 438b3b94faaSDavid Teigland 439bfded27bSSteven Whitehouse if (test_bit(GIF_INVALID, &ip->i_flags)) { 440b3b94faaSDavid Teigland error = gfs2_inode_refresh(ip); 441b3b94faaSDavid Teigland if (error) 442b3b94faaSDavid Teigland return error; 443b3b94faaSDavid Teigland } 444b3b94faaSDavid Teigland 445582d2f7aSSteven Whitehouse if (gh->gh_state != LM_ST_DEFERRED) 446582d2f7aSSteven Whitehouse inode_dio_wait(&ip->i_inode); 447582d2f7aSSteven Whitehouse 448383f01fbSSteven Whitehouse if ((ip->i_diskflags & GFS2_DIF_TRUNC_IN_PROG) && 449b3b94faaSDavid Teigland (gl->gl_state == LM_ST_EXCLUSIVE) && 450813e0c46SSteven Whitehouse (gh->gh_state == LM_ST_EXCLUSIVE)) { 451813e0c46SSteven Whitehouse spin_lock(&sdp->sd_trunc_lock); 452813e0c46SSteven Whitehouse if (list_empty(&ip->i_trunc_list)) 453e7cb550dSWang Xibo list_add(&ip->i_trunc_list, &sdp->sd_trunc_list); 454813e0c46SSteven Whitehouse spin_unlock(&sdp->sd_trunc_lock); 455813e0c46SSteven Whitehouse wake_up(&sdp->sd_quota_wait); 456813e0c46SSteven Whitehouse return 1; 457813e0c46SSteven Whitehouse } 458b3b94faaSDavid Teigland 459b3b94faaSDavid Teigland return error; 460b3b94faaSDavid Teigland } 461b3b94faaSDavid Teigland 462b3b94faaSDavid Teigland /** 4636802e340SSteven Whitehouse * inode_go_dump - print information about an inode 4646802e340SSteven Whitehouse * @seq: The iterator 4656802e340SSteven Whitehouse * @ip: the inode 4666802e340SSteven Whitehouse * 4676802e340SSteven Whitehouse */ 4686802e340SSteven Whitehouse 469ac3beb6aSSteven Whitehouse static void inode_go_dump(struct seq_file *seq, const struct gfs2_glock *gl) 4706802e340SSteven Whitehouse { 4716802e340SSteven Whitehouse const struct gfs2_inode *ip = gl->gl_object; 4726802e340SSteven Whitehouse if (ip == NULL) 473ac3beb6aSSteven Whitehouse return; 474a2e0f799SSteven Whitehouse gfs2_print_dbg(seq, " I: n:%llu/%llu t:%u f:0x%02lx d:0x%08x s:%llu\n", 4756802e340SSteven Whitehouse (unsigned long long)ip->i_no_formal_ino, 4766802e340SSteven Whitehouse (unsigned long long)ip->i_no_addr, 477fa75cedcSSteven Whitehouse IF2DT(ip->i_inode.i_mode), ip->i_flags, 478fa75cedcSSteven Whitehouse (unsigned int)ip->i_diskflags, 479a2e0f799SSteven Whitehouse (unsigned long long)i_size_read(&ip->i_inode)); 4806802e340SSteven Whitehouse } 4816802e340SSteven Whitehouse 4826802e340SSteven Whitehouse /** 48324972557SBenjamin Marzinski * freeze_go_sync - promote/demote the freeze glock 484b3b94faaSDavid Teigland * @gl: the glock 485b3b94faaSDavid Teigland * @state: the requested state 486b3b94faaSDavid Teigland * @flags: 487b3b94faaSDavid Teigland * 488b3b94faaSDavid Teigland */ 489b3b94faaSDavid Teigland 49024972557SBenjamin Marzinski static void freeze_go_sync(struct gfs2_glock *gl) 491b3b94faaSDavid Teigland { 4922e60d768SBenjamin Marzinski int error = 0; 49315562c43SBob Peterson struct gfs2_sbd *sdp = gl->gl_name.ln_sbd; 494b3b94faaSDavid Teigland 49524972557SBenjamin Marzinski if (gl->gl_state == LM_ST_SHARED && 496b3b94faaSDavid Teigland test_bit(SDF_JOURNAL_LIVE, &sdp->sd_flags)) { 4972e60d768SBenjamin Marzinski atomic_set(&sdp->sd_freeze_state, SFS_STARTING_FREEZE); 4982e60d768SBenjamin Marzinski error = freeze_super(sdp->sd_vfs); 4992e60d768SBenjamin Marzinski if (error) { 5002e60d768SBenjamin Marzinski printk(KERN_INFO "GFS2: couldn't freeze filesystem: %d\n", error); 5012e60d768SBenjamin Marzinski gfs2_assert_withdraw(sdp, 0); 5022e60d768SBenjamin Marzinski } 5032e60d768SBenjamin Marzinski queue_work(gfs2_freeze_wq, &sdp->sd_freeze_work); 504805c0907SBob Peterson gfs2_log_flush(sdp, NULL, GFS2_LOG_HEAD_FLUSH_FREEZE | 505805c0907SBob Peterson GFS2_LFC_FREEZE_GO_SYNC); 506b3b94faaSDavid Teigland } 507b3b94faaSDavid Teigland } 508b3b94faaSDavid Teigland 509b3b94faaSDavid Teigland /** 51024972557SBenjamin Marzinski * freeze_go_xmote_bh - After promoting/demoting the freeze glock 511b3b94faaSDavid Teigland * @gl: the glock 512b3b94faaSDavid Teigland * 513b3b94faaSDavid Teigland */ 514b3b94faaSDavid Teigland 51524972557SBenjamin Marzinski static int freeze_go_xmote_bh(struct gfs2_glock *gl, struct gfs2_holder *gh) 516b3b94faaSDavid Teigland { 51715562c43SBob Peterson struct gfs2_sbd *sdp = gl->gl_name.ln_sbd; 518feaa7bbaSSteven Whitehouse struct gfs2_inode *ip = GFS2_I(sdp->sd_jdesc->jd_inode); 5195c676f6dSSteven Whitehouse struct gfs2_glock *j_gl = ip->i_gl; 52055167622SAl Viro struct gfs2_log_header_host head; 521b3b94faaSDavid Teigland int error; 522b3b94faaSDavid Teigland 5236802e340SSteven Whitehouse if (test_bit(SDF_JOURNAL_LIVE, &sdp->sd_flags)) { 5241a14d3a6SSteven Whitehouse j_gl->gl_ops->go_inval(j_gl, DIO_METADATA); 525b3b94faaSDavid Teigland 526b3b94faaSDavid Teigland error = gfs2_find_jhead(sdp->sd_jdesc, &head); 527b3b94faaSDavid Teigland if (error) 528b3b94faaSDavid Teigland gfs2_consist(sdp); 529b3b94faaSDavid Teigland if (!(head.lh_flags & GFS2_LOG_HEAD_UNMOUNT)) 530b3b94faaSDavid Teigland gfs2_consist(sdp); 531b3b94faaSDavid Teigland 532b3b94faaSDavid Teigland /* Initialize some head of the log stuff */ 533b3b94faaSDavid Teigland if (!test_bit(SDF_SHUTDOWN, &sdp->sd_flags)) { 534b3b94faaSDavid Teigland sdp->sd_log_sequence = head.lh_sequence + 1; 535b3b94faaSDavid Teigland gfs2_log_pointers_init(sdp, head.lh_blkno); 536b3b94faaSDavid Teigland } 537b3b94faaSDavid Teigland } 5386802e340SSteven Whitehouse return 0; 539b3b94faaSDavid Teigland } 540b3b94faaSDavid Teigland 541b3b94faaSDavid Teigland /** 54297cc1025SSteven Whitehouse * trans_go_demote_ok 54397cc1025SSteven Whitehouse * @gl: the glock 54497cc1025SSteven Whitehouse * 54597cc1025SSteven Whitehouse * Always returns 0 54697cc1025SSteven Whitehouse */ 54797cc1025SSteven Whitehouse 54824972557SBenjamin Marzinski static int freeze_go_demote_ok(const struct gfs2_glock *gl) 54997cc1025SSteven Whitehouse { 55097cc1025SSteven Whitehouse return 0; 55197cc1025SSteven Whitehouse } 55297cc1025SSteven Whitehouse 553b94a170eSBenjamin Marzinski /** 554b94a170eSBenjamin Marzinski * iopen_go_callback - schedule the dcache entry for the inode to be deleted 555b94a170eSBenjamin Marzinski * @gl: the glock 556b94a170eSBenjamin Marzinski * 557f3dd1649SAndreas Gruenbacher * gl_lockref.lock lock is held while calling this 558b94a170eSBenjamin Marzinski */ 55981ffbf65SSteven Whitehouse static void iopen_go_callback(struct gfs2_glock *gl, bool remote) 560b94a170eSBenjamin Marzinski { 5616f6597baSAndreas Gruenbacher struct gfs2_inode *ip = gl->gl_object; 56215562c43SBob Peterson struct gfs2_sbd *sdp = gl->gl_name.ln_sbd; 563001e8e8dSSteven Whitehouse 564bc98a42cSDavid Howells if (!remote || sb_rdonly(sdp->sd_vfs)) 565001e8e8dSSteven Whitehouse return; 566b94a170eSBenjamin Marzinski 567b94a170eSBenjamin Marzinski if (gl->gl_demote_state == LM_ST_UNLOCKED && 568009d8518SSteven Whitehouse gl->gl_state == LM_ST_SHARED && ip) { 569e66cf161SSteven Whitehouse gl->gl_lockref.count++; 570b94a170eSBenjamin Marzinski if (queue_work(gfs2_delete_workqueue, &gl->gl_delete) == 0) 571e66cf161SSteven Whitehouse gl->gl_lockref.count--; 572b94a170eSBenjamin Marzinski } 573b94a170eSBenjamin Marzinski } 574b94a170eSBenjamin Marzinski 5758fb4b536SSteven Whitehouse const struct gfs2_glock_operations gfs2_meta_glops = { 576ea67eedbSSteven Whitehouse .go_type = LM_TYPE_META, 577b3b94faaSDavid Teigland }; 578b3b94faaSDavid Teigland 5798fb4b536SSteven Whitehouse const struct gfs2_glock_operations gfs2_inode_glops = { 58006dfc306SBob Peterson .go_sync = inode_go_sync, 581b3b94faaSDavid Teigland .go_inval = inode_go_inval, 582b3b94faaSDavid Teigland .go_demote_ok = inode_go_demote_ok, 583b3b94faaSDavid Teigland .go_lock = inode_go_lock, 5846802e340SSteven Whitehouse .go_dump = inode_go_dump, 585ea67eedbSSteven Whitehouse .go_type = LM_TYPE_INODE, 586e7ccaf5fSBob Peterson .go_flags = GLOF_ASPACE | GLOF_LRU, 587b3b94faaSDavid Teigland }; 588b3b94faaSDavid Teigland 5898fb4b536SSteven Whitehouse const struct gfs2_glock_operations gfs2_rgrp_glops = { 59006dfc306SBob Peterson .go_sync = rgrp_go_sync, 5916bac243fSSteven Whitehouse .go_inval = rgrp_go_inval, 5927c9ca621SBob Peterson .go_lock = gfs2_rgrp_go_lock, 5937c9ca621SBob Peterson .go_unlock = gfs2_rgrp_go_unlock, 59409010978SSteven Whitehouse .go_dump = gfs2_rgrp_dump, 595ea67eedbSSteven Whitehouse .go_type = LM_TYPE_RGRP, 59670d4ee94SSteven Whitehouse .go_flags = GLOF_LVB, 597b3b94faaSDavid Teigland }; 598b3b94faaSDavid Teigland 59924972557SBenjamin Marzinski const struct gfs2_glock_operations gfs2_freeze_glops = { 60024972557SBenjamin Marzinski .go_sync = freeze_go_sync, 60124972557SBenjamin Marzinski .go_xmote_bh = freeze_go_xmote_bh, 60224972557SBenjamin Marzinski .go_demote_ok = freeze_go_demote_ok, 603ea67eedbSSteven Whitehouse .go_type = LM_TYPE_NONDISK, 604b3b94faaSDavid Teigland }; 605b3b94faaSDavid Teigland 6068fb4b536SSteven Whitehouse const struct gfs2_glock_operations gfs2_iopen_glops = { 607ea67eedbSSteven Whitehouse .go_type = LM_TYPE_IOPEN, 608b94a170eSBenjamin Marzinski .go_callback = iopen_go_callback, 609e7ccaf5fSBob Peterson .go_flags = GLOF_LRU, 610b3b94faaSDavid Teigland }; 611b3b94faaSDavid Teigland 6128fb4b536SSteven Whitehouse const struct gfs2_glock_operations gfs2_flock_glops = { 613ea67eedbSSteven Whitehouse .go_type = LM_TYPE_FLOCK, 614e7ccaf5fSBob Peterson .go_flags = GLOF_LRU, 615b3b94faaSDavid Teigland }; 616b3b94faaSDavid Teigland 6178fb4b536SSteven Whitehouse const struct gfs2_glock_operations gfs2_nondisk_glops = { 618ea67eedbSSteven Whitehouse .go_type = LM_TYPE_NONDISK, 619b3b94faaSDavid Teigland }; 620b3b94faaSDavid Teigland 6218fb4b536SSteven Whitehouse const struct gfs2_glock_operations gfs2_quota_glops = { 622ea67eedbSSteven Whitehouse .go_type = LM_TYPE_QUOTA, 623e7ccaf5fSBob Peterson .go_flags = GLOF_LVB | GLOF_LRU, 624b3b94faaSDavid Teigland }; 625b3b94faaSDavid Teigland 6268fb4b536SSteven Whitehouse const struct gfs2_glock_operations gfs2_journal_glops = { 627ea67eedbSSteven Whitehouse .go_type = LM_TYPE_JOURNAL, 628b3b94faaSDavid Teigland }; 629b3b94faaSDavid Teigland 63064d576baSSteven Whitehouse const struct gfs2_glock_operations *gfs2_glops_list[] = { 63164d576baSSteven Whitehouse [LM_TYPE_META] = &gfs2_meta_glops, 63264d576baSSteven Whitehouse [LM_TYPE_INODE] = &gfs2_inode_glops, 63364d576baSSteven Whitehouse [LM_TYPE_RGRP] = &gfs2_rgrp_glops, 63464d576baSSteven Whitehouse [LM_TYPE_IOPEN] = &gfs2_iopen_glops, 63564d576baSSteven Whitehouse [LM_TYPE_FLOCK] = &gfs2_flock_glops, 63664d576baSSteven Whitehouse [LM_TYPE_NONDISK] = &gfs2_nondisk_glops, 63764d576baSSteven Whitehouse [LM_TYPE_QUOTA] = &gfs2_quota_glops, 63864d576baSSteven Whitehouse [LM_TYPE_JOURNAL] = &gfs2_journal_glops, 63964d576baSSteven Whitehouse }; 64064d576baSSteven Whitehouse 641