xref: /openbmc/linux/fs/gfs2/glops.c (revision b181f7029bd71238ac2754ce7052dffd69432085)
17336d0e6SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only
2b3b94faaSDavid Teigland /*
3b3b94faaSDavid Teigland  * Copyright (C) Sistina Software, Inc.  1997-2003 All rights reserved.
4cf45b752SBob Peterson  * Copyright (C) 2004-2008 Red Hat, Inc.  All rights reserved.
5b3b94faaSDavid Teigland  */
6b3b94faaSDavid Teigland 
7b3b94faaSDavid Teigland #include <linux/spinlock.h>
8b3b94faaSDavid Teigland #include <linux/completion.h>
9b3b94faaSDavid Teigland #include <linux/buffer_head.h>
105c676f6dSSteven Whitehouse #include <linux/gfs2_ondisk.h>
116802e340SSteven Whitehouse #include <linux/bio.h>
12c65f7fb5SSteven Whitehouse #include <linux/posix_acl.h>
13f39814f6SAndreas Gruenbacher #include <linux/security.h>
14b3b94faaSDavid Teigland 
15b3b94faaSDavid Teigland #include "gfs2.h"
165c676f6dSSteven Whitehouse #include "incore.h"
17b3b94faaSDavid Teigland #include "bmap.h"
18b3b94faaSDavid Teigland #include "glock.h"
19b3b94faaSDavid Teigland #include "glops.h"
20b3b94faaSDavid Teigland #include "inode.h"
21b3b94faaSDavid Teigland #include "log.h"
22b3b94faaSDavid Teigland #include "meta_io.h"
23b3b94faaSDavid Teigland #include "recovery.h"
24b3b94faaSDavid Teigland #include "rgrp.h"
255c676f6dSSteven Whitehouse #include "util.h"
26ddacfaf7SSteven Whitehouse #include "trans.h"
2717d539f0SSteven Whitehouse #include "dir.h"
28f4686c26SAbhi Das #include "lops.h"
29b3b94faaSDavid Teigland 
302e60d768SBenjamin Marzinski struct workqueue_struct *gfs2_freeze_wq;
312e60d768SBenjamin Marzinski 
32601ef0d5SBob Peterson extern struct workqueue_struct *gfs2_control_wq;
33601ef0d5SBob Peterson 
gfs2_ail_error(struct gfs2_glock * gl,const struct buffer_head * bh)3475549186SSteven Whitehouse static void gfs2_ail_error(struct gfs2_glock *gl, const struct buffer_head *bh)
3575549186SSteven Whitehouse {
3669a61144SBob Peterson 	struct gfs2_sbd *sdp = gl->gl_name.ln_sbd;
3769a61144SBob Peterson 
3869a61144SBob Peterson 	fs_err(sdp,
3915562c43SBob Peterson 	       "AIL buffer %p: blocknr %llu state 0x%08lx mapping %p page "
4015562c43SBob Peterson 	       "state 0x%lx\n",
4175549186SSteven Whitehouse 	       bh, (unsigned long long)bh->b_blocknr, bh->b_state,
4211551cf1SMatthew Wilcox (Oracle) 	       bh->b_folio->mapping, bh->b_folio->flags);
4369a61144SBob Peterson 	fs_err(sdp, "AIL glock %u:%llu mapping %p\n",
4475549186SSteven Whitehouse 	       gl->gl_name.ln_type, gl->gl_name.ln_number,
4575549186SSteven Whitehouse 	       gfs2_glock2aspace(gl));
4669a61144SBob Peterson 	gfs2_lm(sdp, "AIL error\n");
47fffe9beeSBob Peterson 	gfs2_withdraw_delayed(sdp);
4875549186SSteven Whitehouse }
4975549186SSteven Whitehouse 
50ddacfaf7SSteven Whitehouse /**
51dba898b0SSteven Whitehouse  * __gfs2_ail_flush - remove all buffers for a given lock from the AIL
52ddacfaf7SSteven Whitehouse  * @gl: the glock
53b5b24d7aSSteven Whitehouse  * @fsync: set when called from fsync (not all buffers will be clean)
54c551f66cSLee Jones  * @nr_revokes: Number of buffers to revoke
55ddacfaf7SSteven Whitehouse  *
56ddacfaf7SSteven Whitehouse  * None of the buffers should be dirty, locked, or pinned.
57ddacfaf7SSteven Whitehouse  */
58ddacfaf7SSteven Whitehouse 
__gfs2_ail_flush(struct gfs2_glock * gl,bool fsync,unsigned int nr_revokes)591bc333f4SBenjamin Marzinski static void __gfs2_ail_flush(struct gfs2_glock *gl, bool fsync,
601bc333f4SBenjamin Marzinski 			     unsigned int nr_revokes)
61ddacfaf7SSteven Whitehouse {
6215562c43SBob Peterson 	struct gfs2_sbd *sdp = gl->gl_name.ln_sbd;
63ddacfaf7SSteven Whitehouse 	struct list_head *head = &gl->gl_ail_list;
64b5b24d7aSSteven Whitehouse 	struct gfs2_bufdata *bd, *tmp;
65ddacfaf7SSteven Whitehouse 	struct buffer_head *bh;
66b5b24d7aSSteven Whitehouse 	const unsigned long b_state = (1UL << BH_Dirty)|(1UL << BH_Pinned)|(1UL << BH_Lock);
67ddacfaf7SSteven Whitehouse 
68b5b24d7aSSteven Whitehouse 	gfs2_log_lock(sdp);
69d6a079e8SDave Chinner 	spin_lock(&sdp->sd_ail_lock);
701bc333f4SBenjamin Marzinski 	list_for_each_entry_safe_reverse(bd, tmp, head, bd_ail_gl_list) {
711bc333f4SBenjamin Marzinski 		if (nr_revokes == 0)
721bc333f4SBenjamin Marzinski 			break;
73ddacfaf7SSteven Whitehouse 		bh = bd->bd_bh;
74b5b24d7aSSteven Whitehouse 		if (bh->b_state & b_state) {
75b5b24d7aSSteven Whitehouse 			if (fsync)
76b5b24d7aSSteven Whitehouse 				continue;
7775549186SSteven Whitehouse 			gfs2_ail_error(gl, bh);
78b5b24d7aSSteven Whitehouse 		}
791ad38c43SSteven Whitehouse 		gfs2_trans_add_revoke(sdp, bd);
801bc333f4SBenjamin Marzinski 		nr_revokes--;
81ddacfaf7SSteven Whitehouse 	}
828eae1ca0SSteven Whitehouse 	GLOCK_BUG_ON(gl, !fsync && atomic_read(&gl->gl_ail_count));
83d6a079e8SDave Chinner 	spin_unlock(&sdp->sd_ail_lock);
84b5b24d7aSSteven Whitehouse 	gfs2_log_unlock(sdp);
8521d78e4cSAndreas Gruenbacher 
8621d78e4cSAndreas Gruenbacher 	if (gfs2_withdrawing(sdp))
8721d78e4cSAndreas Gruenbacher 		gfs2_withdraw(sdp);
88dba898b0SSteven Whitehouse }
89ddacfaf7SSteven Whitehouse 
90dba898b0SSteven Whitehouse 
gfs2_ail_empty_gl(struct gfs2_glock * gl)911c634f94SBob Peterson static int gfs2_ail_empty_gl(struct gfs2_glock *gl)
92dba898b0SSteven Whitehouse {
9315562c43SBob Peterson 	struct gfs2_sbd *sdp = gl->gl_name.ln_sbd;
94dba898b0SSteven Whitehouse 	struct gfs2_trans tr;
95c968f578SAndreas Gruenbacher 	unsigned int revokes;
9624ab1582SBob Peterson 	int ret = 0;
97dba898b0SSteven Whitehouse 
98c968f578SAndreas Gruenbacher 	revokes = atomic_read(&gl->gl_ail_count);
99dba898b0SSteven Whitehouse 
100c968f578SAndreas Gruenbacher 	if (!revokes) {
1019ff78289SBob Peterson 		bool have_revokes;
1029ff78289SBob Peterson 		bool log_in_flight;
1039ff78289SBob Peterson 
1049ff78289SBob Peterson 		/*
1059ff78289SBob Peterson 		 * We have nothing on the ail, but there could be revokes on
1069ff78289SBob Peterson 		 * the sdp revoke queue, in which case, we still want to flush
1079ff78289SBob Peterson 		 * the log and wait for it to finish.
1089ff78289SBob Peterson 		 *
1099ff78289SBob Peterson 		 * If the sdp revoke list is empty too, we might still have an
1109ff78289SBob Peterson 		 * io outstanding for writing revokes, so we should wait for
1119ff78289SBob Peterson 		 * it before returning.
1129ff78289SBob Peterson 		 *
1139ff78289SBob Peterson 		 * If none of these conditions are true, our revokes are all
1149ff78289SBob Peterson 		 * flushed and we can return.
1159ff78289SBob Peterson 		 */
1169ff78289SBob Peterson 		gfs2_log_lock(sdp);
1179ff78289SBob Peterson 		have_revokes = !list_empty(&sdp->sd_log_revokes);
1189ff78289SBob Peterson 		log_in_flight = atomic_read(&sdp->sd_log_in_flight);
1199ff78289SBob Peterson 		gfs2_log_unlock(sdp);
1209ff78289SBob Peterson 		if (have_revokes)
1219ff78289SBob Peterson 			goto flush;
1229ff78289SBob Peterson 		if (log_in_flight)
1239ff78289SBob Peterson 			log_flush_wait(sdp);
1241c634f94SBob Peterson 		return 0;
1259ff78289SBob Peterson 	}
126dba898b0SSteven Whitehouse 
127c968f578SAndreas Gruenbacher 	memset(&tr, 0, sizeof(tr));
128c968f578SAndreas Gruenbacher 	set_bit(TR_ONSTACK, &tr.tr_flags);
129c968f578SAndreas Gruenbacher 	ret = __gfs2_trans_begin(&tr, sdp, 0, revokes, _RET_IP_);
130b97e583cSBob Peterson 	if (ret) {
131b97e583cSBob Peterson 		fs_err(sdp, "Transaction error %d: Unable to write revokes.", ret);
132c968f578SAndreas Gruenbacher 		goto flush;
133b97e583cSBob Peterson 	}
134c968f578SAndreas Gruenbacher 	__gfs2_ail_flush(gl, 0, revokes);
135dba898b0SSteven Whitehouse 	gfs2_trans_end(sdp);
136c968f578SAndreas Gruenbacher 
1379ff78289SBob Peterson flush:
138644f6bf7SBob Peterson 	if (!ret)
139805c0907SBob Peterson 		gfs2_log_flush(sdp, NULL, GFS2_LOG_HEAD_FLUSH_NORMAL |
140805c0907SBob Peterson 				GFS2_LFC_AIL_EMPTY_GL);
14124ab1582SBob Peterson 	return ret;
142dba898b0SSteven Whitehouse }
143dba898b0SSteven Whitehouse 
gfs2_ail_flush(struct gfs2_glock * gl,bool fsync)144b5b24d7aSSteven Whitehouse void gfs2_ail_flush(struct gfs2_glock *gl, bool fsync)
145dba898b0SSteven Whitehouse {
14615562c43SBob Peterson 	struct gfs2_sbd *sdp = gl->gl_name.ln_sbd;
147dba898b0SSteven Whitehouse 	unsigned int revokes = atomic_read(&gl->gl_ail_count);
148dba898b0SSteven Whitehouse 	int ret;
149dba898b0SSteven Whitehouse 
150dba898b0SSteven Whitehouse 	if (!revokes)
151dba898b0SSteven Whitehouse 		return;
152dba898b0SSteven Whitehouse 
1532129b428SAndreas Gruenbacher 	ret = gfs2_trans_begin(sdp, 0, revokes);
154dba898b0SSteven Whitehouse 	if (ret)
155dba898b0SSteven Whitehouse 		return;
1562129b428SAndreas Gruenbacher 	__gfs2_ail_flush(gl, fsync, revokes);
157ddacfaf7SSteven Whitehouse 	gfs2_trans_end(sdp);
158805c0907SBob Peterson 	gfs2_log_flush(sdp, NULL, GFS2_LOG_HEAD_FLUSH_NORMAL |
159805c0907SBob Peterson 		       GFS2_LFC_AIL_FLUSH);
160ddacfaf7SSteven Whitehouse }
161ba7f7290SSteven Whitehouse 
162ba7f7290SSteven Whitehouse /**
1634a55752aSBob Peterson  * gfs2_rgrp_metasync - sync out the metadata of a resource group
1644a55752aSBob Peterson  * @gl: the glock protecting the resource group
1654a55752aSBob Peterson  *
1664a55752aSBob Peterson  */
1674a55752aSBob Peterson 
gfs2_rgrp_metasync(struct gfs2_glock * gl)1684a55752aSBob Peterson static int gfs2_rgrp_metasync(struct gfs2_glock *gl)
1694a55752aSBob Peterson {
1704a55752aSBob Peterson 	struct gfs2_sbd *sdp = gl->gl_name.ln_sbd;
1714a55752aSBob Peterson 	struct address_space *metamapping = &sdp->sd_aspace;
1724a55752aSBob Peterson 	struct gfs2_rgrpd *rgd = gfs2_glock2rgrp(gl);
1734a55752aSBob Peterson 	const unsigned bsize = sdp->sd_sb.sb_bsize;
1744a55752aSBob Peterson 	loff_t start = (rgd->rd_addr * bsize) & PAGE_MASK;
1754a55752aSBob Peterson 	loff_t end = PAGE_ALIGN((rgd->rd_addr + rgd->rd_length) * bsize) - 1;
1764a55752aSBob Peterson 	int error;
1774a55752aSBob Peterson 
1784a55752aSBob Peterson 	filemap_fdatawrite_range(metamapping, start, end);
1794a55752aSBob Peterson 	error = filemap_fdatawait_range(metamapping, start, end);
180*d6b412c5SAndreas Gruenbacher 	WARN_ON_ONCE(error && !gfs2_withdrawing_or_withdrawn(sdp));
1814a55752aSBob Peterson 	mapping_set_error(metamapping, error);
1824a55752aSBob Peterson 	if (error)
1834a55752aSBob Peterson 		gfs2_io_error(sdp);
1844a55752aSBob Peterson 	return error;
1854a55752aSBob Peterson }
1864a55752aSBob Peterson 
1874a55752aSBob Peterson /**
1886bac243fSSteven Whitehouse  * rgrp_go_sync - sync out the metadata for this glock
189b3b94faaSDavid Teigland  * @gl: the glock
190b3b94faaSDavid Teigland  *
191b3b94faaSDavid Teigland  * Called when demoting or unlocking an EX glock.  We must flush
192b3b94faaSDavid Teigland  * to disk all dirty buffers/pages relating to this glock, and must not
1936f6597baSAndreas Gruenbacher  * return to caller to demote/unlock the glock until I/O is complete.
194b3b94faaSDavid Teigland  */
195b3b94faaSDavid Teigland 
rgrp_go_sync(struct gfs2_glock * gl)1961c634f94SBob Peterson static int rgrp_go_sync(struct gfs2_glock *gl)
197b3b94faaSDavid Teigland {
19815562c43SBob Peterson 	struct gfs2_sbd *sdp = gl->gl_name.ln_sbd;
199b3422cacSBob Peterson 	struct gfs2_rgrpd *rgd = gfs2_glock2rgrp(gl);
2006bac243fSSteven Whitehouse 	int error;
201b5d32beaSSteven Whitehouse 
202fd5f446fSBob Peterson 	if (!rgd || !test_and_clear_bit(GLF_DIRTY, &gl->gl_flags))
2031c634f94SBob Peterson 		return 0;
2048eae1ca0SSteven Whitehouse 	GLOCK_BUG_ON(gl, gl->gl_state != LM_ST_EXCLUSIVE);
2056bac243fSSteven Whitehouse 
206805c0907SBob Peterson 	gfs2_log_flush(sdp, gl, GFS2_LOG_HEAD_FLUSH_NORMAL |
207805c0907SBob Peterson 		       GFS2_LFC_RGRP_GO_SYNC);
2084a55752aSBob Peterson 	error = gfs2_rgrp_metasync(gl);
2091c634f94SBob Peterson 	if (!error)
2101c634f94SBob Peterson 		error = gfs2_ail_empty_gl(gl);
2118339ee54SSteven Whitehouse 	gfs2_free_clones(rgd);
2121c634f94SBob Peterson 	return error;
213b3b94faaSDavid Teigland }
214b3b94faaSDavid Teigland 
215b3b94faaSDavid Teigland /**
2166bac243fSSteven Whitehouse  * rgrp_go_inval - invalidate the metadata for this glock
217b3b94faaSDavid Teigland  * @gl: the glock
218b3b94faaSDavid Teigland  * @flags:
219b3b94faaSDavid Teigland  *
2206bac243fSSteven Whitehouse  * We never used LM_ST_DEFERRED with resource groups, so that we
2216bac243fSSteven Whitehouse  * should always see the metadata flag set here.
2226bac243fSSteven Whitehouse  *
223b3b94faaSDavid Teigland  */
224b3b94faaSDavid Teigland 
rgrp_go_inval(struct gfs2_glock * gl,int flags)2256bac243fSSteven Whitehouse static void rgrp_go_inval(struct gfs2_glock *gl, int flags)
226b3b94faaSDavid Teigland {
22715562c43SBob Peterson 	struct gfs2_sbd *sdp = gl->gl_name.ln_sbd;
22870d4ee94SSteven Whitehouse 	struct address_space *mapping = &sdp->sd_aspace;
2296f6597baSAndreas Gruenbacher 	struct gfs2_rgrpd *rgd = gfs2_glock2rgrp(gl);
23023cfb0c3SBob Peterson 	const unsigned bsize = sdp->sd_sb.sb_bsize;
231fd5f446fSBob Peterson 	loff_t start, end;
23239b0f1e9SBob Peterson 
233fd5f446fSBob Peterson 	if (!rgd)
234fd5f446fSBob Peterson 		return;
235fd5f446fSBob Peterson 	start = (rgd->rd_addr * bsize) & PAGE_MASK;
236fd5f446fSBob Peterson 	end = PAGE_ALIGN((rgd->rd_addr + rgd->rd_length) * bsize) - 1;
23739b0f1e9SBob Peterson 	gfs2_rgrp_brelse(rgd);
2388eae1ca0SSteven Whitehouse 	WARN_ON_ONCE(!(flags & DIO_METADATA));
23923cfb0c3SBob Peterson 	truncate_inode_pages_range(mapping, start, end);
240cf45b752SBob Peterson }
241b3b94faaSDavid Teigland 
gfs2_rgrp_go_dump(struct seq_file * seq,const struct gfs2_glock * gl,const char * fs_id_buf)242f246dd4bSAndreas Gruenbacher static void gfs2_rgrp_go_dump(struct seq_file *seq, const struct gfs2_glock *gl,
2430e539ca1SAndrew Price 			      const char *fs_id_buf)
2440e539ca1SAndrew Price {
24516e6281bSAlexander Aring 	struct gfs2_rgrpd *rgd = gl->gl_object;
2460e539ca1SAndrew Price 
2470e539ca1SAndrew Price 	if (rgd)
2480e539ca1SAndrew Price 		gfs2_rgrp_dump(seq, rgd, fs_id_buf);
2490e539ca1SAndrew Price }
2500e539ca1SAndrew Price 
gfs2_glock2inode(struct gfs2_glock * gl)2514fd1a579SAndreas Gruenbacher static struct gfs2_inode *gfs2_glock2inode(struct gfs2_glock *gl)
2524fd1a579SAndreas Gruenbacher {
2534fd1a579SAndreas Gruenbacher 	struct gfs2_inode *ip;
2544fd1a579SAndreas Gruenbacher 
2554fd1a579SAndreas Gruenbacher 	spin_lock(&gl->gl_lockref.lock);
2564fd1a579SAndreas Gruenbacher 	ip = gl->gl_object;
2574fd1a579SAndreas Gruenbacher 	if (ip)
2584fd1a579SAndreas Gruenbacher 		set_bit(GIF_GLOP_PENDING, &ip->i_flags);
2594fd1a579SAndreas Gruenbacher 	spin_unlock(&gl->gl_lockref.lock);
2604fd1a579SAndreas Gruenbacher 	return ip;
2614fd1a579SAndreas Gruenbacher }
2624fd1a579SAndreas Gruenbacher 
gfs2_glock2rgrp(struct gfs2_glock * gl)2636f6597baSAndreas Gruenbacher struct gfs2_rgrpd *gfs2_glock2rgrp(struct gfs2_glock *gl)
2646f6597baSAndreas Gruenbacher {
2656f6597baSAndreas Gruenbacher 	struct gfs2_rgrpd *rgd;
2666f6597baSAndreas Gruenbacher 
2676f6597baSAndreas Gruenbacher 	spin_lock(&gl->gl_lockref.lock);
2686f6597baSAndreas Gruenbacher 	rgd = gl->gl_object;
2696f6597baSAndreas Gruenbacher 	spin_unlock(&gl->gl_lockref.lock);
2706f6597baSAndreas Gruenbacher 
2716f6597baSAndreas Gruenbacher 	return rgd;
2726f6597baSAndreas Gruenbacher }
2736f6597baSAndreas Gruenbacher 
gfs2_clear_glop_pending(struct gfs2_inode * ip)2744fd1a579SAndreas Gruenbacher static void gfs2_clear_glop_pending(struct gfs2_inode *ip)
2754fd1a579SAndreas Gruenbacher {
2764fd1a579SAndreas Gruenbacher 	if (!ip)
2774fd1a579SAndreas Gruenbacher 		return;
2784fd1a579SAndreas Gruenbacher 
2794fd1a579SAndreas Gruenbacher 	clear_bit_unlock(GIF_GLOP_PENDING, &ip->i_flags);
2804fd1a579SAndreas Gruenbacher 	wake_up_bit(&ip->i_flags, GIF_GLOP_PENDING);
2814fd1a579SAndreas Gruenbacher }
2824fd1a579SAndreas Gruenbacher 
283b3b94faaSDavid Teigland /**
2844a55752aSBob Peterson  * gfs2_inode_metasync - sync out the metadata of an inode
2854a55752aSBob Peterson  * @gl: the glock protecting the inode
2864a55752aSBob Peterson  *
2874a55752aSBob Peterson  */
gfs2_inode_metasync(struct gfs2_glock * gl)2884a55752aSBob Peterson int gfs2_inode_metasync(struct gfs2_glock *gl)
2894a55752aSBob Peterson {
2904a55752aSBob Peterson 	struct address_space *metamapping = gfs2_glock2aspace(gl);
2914a55752aSBob Peterson 	int error;
2924a55752aSBob Peterson 
2934a55752aSBob Peterson 	filemap_fdatawrite(metamapping);
2944a55752aSBob Peterson 	error = filemap_fdatawait(metamapping);
2954a55752aSBob Peterson 	if (error)
2964a55752aSBob Peterson 		gfs2_io_error(gl->gl_name.ln_sbd);
2974a55752aSBob Peterson 	return error;
2984a55752aSBob Peterson }
2994a55752aSBob Peterson 
3004a55752aSBob Peterson /**
3014a55752aSBob Peterson  * inode_go_sync - Sync the dirty metadata of an inode
302b5d32beaSSteven Whitehouse  * @gl: the glock protecting the inode
303b5d32beaSSteven Whitehouse  *
304b5d32beaSSteven Whitehouse  */
305b5d32beaSSteven Whitehouse 
inode_go_sync(struct gfs2_glock * gl)3061c634f94SBob Peterson static int inode_go_sync(struct gfs2_glock *gl)
307b5d32beaSSteven Whitehouse {
3084fd1a579SAndreas Gruenbacher 	struct gfs2_inode *ip = gfs2_glock2inode(gl);
3094fd1a579SAndreas Gruenbacher 	int isreg = ip && S_ISREG(ip->i_inode.i_mode);
310009d8518SSteven Whitehouse 	struct address_space *metamapping = gfs2_glock2aspace(gl);
311bbae10faSBob Peterson 	int error = 0, ret;
3123042a2ccSSteven Whitehouse 
3134fd1a579SAndreas Gruenbacher 	if (isreg) {
314582d2f7aSSteven Whitehouse 		if (test_and_clear_bit(GIF_SW_PAGED, &ip->i_flags))
3156bac243fSSteven Whitehouse 			unmap_shared_mapping_range(ip->i_inode.i_mapping, 0, 0);
316582d2f7aSSteven Whitehouse 		inode_dio_wait(&ip->i_inode);
317582d2f7aSSteven Whitehouse 	}
3186bac243fSSteven Whitehouse 	if (!test_and_clear_bit(GLF_DIRTY, &gl->gl_flags))
3194fd1a579SAndreas Gruenbacher 		goto out;
320b5d32beaSSteven Whitehouse 
3218eae1ca0SSteven Whitehouse 	GLOCK_BUG_ON(gl, gl->gl_state != LM_ST_EXCLUSIVE);
3226bac243fSSteven Whitehouse 
323805c0907SBob Peterson 	gfs2_log_flush(gl->gl_name.ln_sbd, gl, GFS2_LOG_HEAD_FLUSH_NORMAL |
324805c0907SBob Peterson 		       GFS2_LFC_INODE_GO_SYNC);
3253042a2ccSSteven Whitehouse 	filemap_fdatawrite(metamapping);
3264fd1a579SAndreas Gruenbacher 	if (isreg) {
327b5d32beaSSteven Whitehouse 		struct address_space *mapping = ip->i_inode.i_mapping;
3283042a2ccSSteven Whitehouse 		filemap_fdatawrite(mapping);
3293042a2ccSSteven Whitehouse 		error = filemap_fdatawait(mapping);
3303e9f45bdSGuillaume Chazarain 		mapping_set_error(mapping, error);
331b5d32beaSSteven Whitehouse 	}
3324a55752aSBob Peterson 	ret = gfs2_inode_metasync(gl);
333bbae10faSBob Peterson 	if (!error)
334bbae10faSBob Peterson 		error = ret;
33524ab1582SBob Peterson 	ret = gfs2_ail_empty_gl(gl);
33624ab1582SBob Peterson 	if (!error)
33724ab1582SBob Peterson 		error = ret;
33852fcd11cSSteven Whitehouse 	/*
33952fcd11cSSteven Whitehouse 	 * Writeback of the data mapping may cause the dirty flag to be set
34052fcd11cSSteven Whitehouse 	 * so we have to clear it again here.
34152fcd11cSSteven Whitehouse 	 */
3424e857c58SPeter Zijlstra 	smp_mb__before_atomic();
34352fcd11cSSteven Whitehouse 	clear_bit(GLF_DIRTY, &gl->gl_flags);
3444fd1a579SAndreas Gruenbacher 
3454fd1a579SAndreas Gruenbacher out:
3464fd1a579SAndreas Gruenbacher 	gfs2_clear_glop_pending(ip);
3471c634f94SBob Peterson 	return error;
348b5d32beaSSteven Whitehouse }
349b5d32beaSSteven Whitehouse 
350b5d32beaSSteven Whitehouse /**
351b3b94faaSDavid Teigland  * inode_go_inval - prepare a inode glock to be released
352b3b94faaSDavid Teigland  * @gl: the glock
353b3b94faaSDavid Teigland  * @flags:
354b3b94faaSDavid Teigland  *
3556b49d1d9SGeert Uytterhoeven  * Normally we invalidate everything, but if we are moving into
3566bac243fSSteven Whitehouse  * LM_ST_DEFERRED from LM_ST_SHARED or LM_ST_EXCLUSIVE then we
3576bac243fSSteven Whitehouse  * can keep hold of the metadata, since it won't have changed.
3586bac243fSSteven Whitehouse  *
359b3b94faaSDavid Teigland  */
360b3b94faaSDavid Teigland 
inode_go_inval(struct gfs2_glock * gl,int flags)361b3b94faaSDavid Teigland static void inode_go_inval(struct gfs2_glock *gl, int flags)
362b3b94faaSDavid Teigland {
3634fd1a579SAndreas Gruenbacher 	struct gfs2_inode *ip = gfs2_glock2inode(gl);
364b3b94faaSDavid Teigland 
3656bac243fSSteven Whitehouse 	if (flags & DIO_METADATA) {
366009d8518SSteven Whitehouse 		struct address_space *mapping = gfs2_glock2aspace(gl);
3676bac243fSSteven Whitehouse 		truncate_inode_pages(mapping, 0);
368c65f7fb5SSteven Whitehouse 		if (ip) {
369f2e70d8fSBob Peterson 			set_bit(GLF_INSTANTIATE_NEEDED, &gl->gl_flags);
370c65f7fb5SSteven Whitehouse 			forget_all_cached_acls(&ip->i_inode);
371f39814f6SAndreas Gruenbacher 			security_inode_invalidate_secctx(&ip->i_inode);
37217d539f0SSteven Whitehouse 			gfs2_dir_hash_inval(ip);
373c65f7fb5SSteven Whitehouse 		}
374b3b94faaSDavid Teigland 	}
375b004157aSSteven Whitehouse 
37615562c43SBob Peterson 	if (ip == GFS2_I(gl->gl_name.ln_sbd->sd_rindex)) {
377c1696fb8SBob Peterson 		gfs2_log_flush(gl->gl_name.ln_sbd, NULL,
378805c0907SBob Peterson 			       GFS2_LOG_HEAD_FLUSH_NORMAL |
379805c0907SBob Peterson 			       GFS2_LFC_INODE_GO_INVAL);
38015562c43SBob Peterson 		gl->gl_name.ln_sbd->sd_rindex_uptodate = 0;
3811ce53368SBenjamin Marzinski 	}
3823cc3f710SSteven Whitehouse 	if (ip && S_ISREG(ip->i_inode.i_mode))
383b004157aSSteven Whitehouse 		truncate_inode_pages(ip->i_inode.i_mapping, 0);
3844fd1a579SAndreas Gruenbacher 
3854fd1a579SAndreas Gruenbacher 	gfs2_clear_glop_pending(ip);
386b3b94faaSDavid Teigland }
387b3b94faaSDavid Teigland 
388b3b94faaSDavid Teigland /**
389b3b94faaSDavid Teigland  * inode_go_demote_ok - Check to see if it's ok to unlock an inode glock
390b3b94faaSDavid Teigland  * @gl: the glock
391b3b94faaSDavid Teigland  *
392b3b94faaSDavid Teigland  * Returns: 1 if it's ok
393b3b94faaSDavid Teigland  */
394b3b94faaSDavid Teigland 
inode_go_demote_ok(const struct gfs2_glock * gl)39597cc1025SSteven Whitehouse static int inode_go_demote_ok(const struct gfs2_glock *gl)
396b3b94faaSDavid Teigland {
39715562c43SBob Peterson 	struct gfs2_sbd *sdp = gl->gl_name.ln_sbd;
398bc015cb8SSteven Whitehouse 
39997cc1025SSteven Whitehouse 	if (sdp->sd_jindex == gl->gl_object || sdp->sd_rindex == gl->gl_object)
40097cc1025SSteven Whitehouse 		return 0;
401bc015cb8SSteven Whitehouse 
40297cc1025SSteven Whitehouse 	return 1;
403b3b94faaSDavid Teigland }
404b3b94faaSDavid Teigland 
gfs2_dinode_in(struct gfs2_inode * ip,const void * buf)405d4b2cf1bSSteven Whitehouse static int gfs2_dinode_in(struct gfs2_inode *ip, const void *buf)
406d4b2cf1bSSteven Whitehouse {
407cfcdb5baSAndreas Gruenbacher 	struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
408d4b2cf1bSSteven Whitehouse 	const struct gfs2_dinode *str = buf;
40995582b00SDeepa Dinamani 	struct timespec64 atime;
410d4b2cf1bSSteven Whitehouse 	u16 height, depth;
4114a378d8aSAl Viro 	umode_t mode = be32_to_cpu(str->di_mode);
4127db35444SAndreas Gruenbacher 	struct inode *inode = &ip->i_inode;
4137db35444SAndreas Gruenbacher 	bool is_new = inode->i_state & I_NEW;
414d4b2cf1bSSteven Whitehouse 
415d4b2cf1bSSteven Whitehouse 	if (unlikely(ip->i_no_addr != be64_to_cpu(str->di_num.no_addr)))
416d4b2cf1bSSteven Whitehouse 		goto corrupt;
4177db35444SAndreas Gruenbacher 	if (unlikely(!is_new && inode_wrong_type(inode, mode)))
4184a378d8aSAl Viro 		goto corrupt;
419d4b2cf1bSSteven Whitehouse 	ip->i_no_formal_ino = be64_to_cpu(str->di_num.no_formal_ino);
4207db35444SAndreas Gruenbacher 	inode->i_mode = mode;
4214a378d8aSAl Viro 	if (is_new) {
4227db35444SAndreas Gruenbacher 		inode->i_rdev = 0;
4234a378d8aSAl Viro 		switch (mode & S_IFMT) {
424d4b2cf1bSSteven Whitehouse 		case S_IFBLK:
425d4b2cf1bSSteven Whitehouse 		case S_IFCHR:
4267db35444SAndreas Gruenbacher 			inode->i_rdev = MKDEV(be32_to_cpu(str->di_major),
427d4b2cf1bSSteven Whitehouse 					      be32_to_cpu(str->di_minor));
428d4b2cf1bSSteven Whitehouse 			break;
429098b9c14SAliasgar Surti 		}
4304a378d8aSAl Viro 	}
431d4b2cf1bSSteven Whitehouse 
4327db35444SAndreas Gruenbacher 	i_uid_write(inode, be32_to_cpu(str->di_uid));
4337db35444SAndreas Gruenbacher 	i_gid_write(inode, be32_to_cpu(str->di_gid));
4347db35444SAndreas Gruenbacher 	set_nlink(inode, be32_to_cpu(str->di_nlink));
4357db35444SAndreas Gruenbacher 	i_size_write(inode, be64_to_cpu(str->di_size));
4367db35444SAndreas Gruenbacher 	gfs2_set_inode_blocks(inode, be64_to_cpu(str->di_blocks));
437d4b2cf1bSSteven Whitehouse 	atime.tv_sec = be64_to_cpu(str->di_atime);
438d4b2cf1bSSteven Whitehouse 	atime.tv_nsec = be32_to_cpu(str->di_atime_nsec);
4397db35444SAndreas Gruenbacher 	if (timespec64_compare(&inode->i_atime, &atime) < 0)
4407db35444SAndreas Gruenbacher 		inode->i_atime = atime;
4417db35444SAndreas Gruenbacher 	inode->i_mtime.tv_sec = be64_to_cpu(str->di_mtime);
4427db35444SAndreas Gruenbacher 	inode->i_mtime.tv_nsec = be32_to_cpu(str->di_mtime_nsec);
4438a8b8d91SJeff Layton 	inode_set_ctime(inode, be64_to_cpu(str->di_ctime),
4448a8b8d91SJeff Layton 			be32_to_cpu(str->di_ctime_nsec));
445d4b2cf1bSSteven Whitehouse 
446d4b2cf1bSSteven Whitehouse 	ip->i_goal = be64_to_cpu(str->di_goal_meta);
447d4b2cf1bSSteven Whitehouse 	ip->i_generation = be64_to_cpu(str->di_generation);
448d4b2cf1bSSteven Whitehouse 
449d4b2cf1bSSteven Whitehouse 	ip->i_diskflags = be32_to_cpu(str->di_flags);
4509964afbbSSteven Whitehouse 	ip->i_eattr = be64_to_cpu(str->di_eattr);
4519964afbbSSteven Whitehouse 	/* i_diskflags and i_eattr must be set before gfs2_set_inode_flags() */
4527db35444SAndreas Gruenbacher 	gfs2_set_inode_flags(inode);
453d4b2cf1bSSteven Whitehouse 	height = be16_to_cpu(str->di_height);
454cfcdb5baSAndreas Gruenbacher 	if (unlikely(height > sdp->sd_max_height))
455d4b2cf1bSSteven Whitehouse 		goto corrupt;
456d4b2cf1bSSteven Whitehouse 	ip->i_height = (u8)height;
457d4b2cf1bSSteven Whitehouse 
458d4b2cf1bSSteven Whitehouse 	depth = be16_to_cpu(str->di_depth);
459d4b2cf1bSSteven Whitehouse 	if (unlikely(depth > GFS2_DIR_MAX_DEPTH))
460d4b2cf1bSSteven Whitehouse 		goto corrupt;
461d4b2cf1bSSteven Whitehouse 	ip->i_depth = (u8)depth;
462d4b2cf1bSSteven Whitehouse 	ip->i_entries = be32_to_cpu(str->di_entries);
463d4b2cf1bSSteven Whitehouse 
46470376c7fSAndreas Gruenbacher 	if (gfs2_is_stuffed(ip) && inode->i_size > gfs2_max_stuffed_size(ip))
46570376c7fSAndreas Gruenbacher 		goto corrupt;
46670376c7fSAndreas Gruenbacher 
4677db35444SAndreas Gruenbacher 	if (S_ISREG(inode->i_mode))
4687db35444SAndreas Gruenbacher 		gfs2_set_aops(inode);
469d4b2cf1bSSteven Whitehouse 
470d4b2cf1bSSteven Whitehouse 	return 0;
471d4b2cf1bSSteven Whitehouse corrupt:
472d4b2cf1bSSteven Whitehouse 	gfs2_consist_inode(ip);
473d4b2cf1bSSteven Whitehouse 	return -EIO;
474d4b2cf1bSSteven Whitehouse }
475d4b2cf1bSSteven Whitehouse 
476d4b2cf1bSSteven Whitehouse /**
477d4b2cf1bSSteven Whitehouse  * gfs2_inode_refresh - Refresh the incore copy of the dinode
478d4b2cf1bSSteven Whitehouse  * @ip: The GFS2 inode
479d4b2cf1bSSteven Whitehouse  *
480d4b2cf1bSSteven Whitehouse  * Returns: errno
481d4b2cf1bSSteven Whitehouse  */
482d4b2cf1bSSteven Whitehouse 
gfs2_inode_refresh(struct gfs2_inode * ip)483d4b2cf1bSSteven Whitehouse int gfs2_inode_refresh(struct gfs2_inode *ip)
484d4b2cf1bSSteven Whitehouse {
485d4b2cf1bSSteven Whitehouse 	struct buffer_head *dibh;
486d4b2cf1bSSteven Whitehouse 	int error;
487d4b2cf1bSSteven Whitehouse 
488d4b2cf1bSSteven Whitehouse 	error = gfs2_meta_inode_buffer(ip, &dibh);
489d4b2cf1bSSteven Whitehouse 	if (error)
490d4b2cf1bSSteven Whitehouse 		return error;
491d4b2cf1bSSteven Whitehouse 
492d4b2cf1bSSteven Whitehouse 	error = gfs2_dinode_in(ip, dibh->b_data);
493d4b2cf1bSSteven Whitehouse 	brelse(dibh);
494d4b2cf1bSSteven Whitehouse 	return error;
495d4b2cf1bSSteven Whitehouse }
496d4b2cf1bSSteven Whitehouse 
497d4b2cf1bSSteven Whitehouse /**
4983278b977SBob Peterson  * inode_go_instantiate - read in an inode if necessary
499c551f66cSLee Jones  * @gh: The glock holder
500b3b94faaSDavid Teigland  *
501b3b94faaSDavid Teigland  * Returns: errno
502b3b94faaSDavid Teigland  */
503b3b94faaSDavid Teigland 
inode_go_instantiate(struct gfs2_glock * gl)5045f38a4d3SAndreas Gruenbacher static int inode_go_instantiate(struct gfs2_glock *gl)
505b3b94faaSDavid Teigland {
5065c676f6dSSteven Whitehouse 	struct gfs2_inode *ip = gl->gl_object;
50786c30a01SAndreas Gruenbacher 
50886c30a01SAndreas Gruenbacher 	if (!ip) /* no inode to populate - read it in later */
50986c30a01SAndreas Gruenbacher 		return 0;
51086c30a01SAndreas Gruenbacher 
51186c30a01SAndreas Gruenbacher 	return gfs2_inode_refresh(ip);
51286c30a01SAndreas Gruenbacher }
51386c30a01SAndreas Gruenbacher 
inode_go_held(struct gfs2_holder * gh)51486c30a01SAndreas Gruenbacher static int inode_go_held(struct gfs2_holder *gh)
51586c30a01SAndreas Gruenbacher {
51686c30a01SAndreas Gruenbacher 	struct gfs2_glock *gl = gh->gh_gl;
51786c30a01SAndreas Gruenbacher 	struct gfs2_inode *ip = gl->gl_object;
518b3b94faaSDavid Teigland 	int error = 0;
519b3b94faaSDavid Teigland 
520f2e70d8fSBob Peterson 	if (!ip) /* no inode to populate - read it in later */
52186c30a01SAndreas Gruenbacher 		return 0;
522b3b94faaSDavid Teigland 
523582d2f7aSSteven Whitehouse 	if (gh->gh_state != LM_ST_DEFERRED)
524582d2f7aSSteven Whitehouse 		inode_dio_wait(&ip->i_inode);
525582d2f7aSSteven Whitehouse 
526383f01fbSSteven Whitehouse 	if ((ip->i_diskflags & GFS2_DIF_TRUNC_IN_PROG) &&
527b3b94faaSDavid Teigland 	    (gl->gl_state == LM_ST_EXCLUSIVE) &&
528de3f906fSAndreas Gruenbacher 	    (gh->gh_state == LM_ST_EXCLUSIVE))
529de3f906fSAndreas Gruenbacher 		error = gfs2_truncatei_resume(ip);
530b3b94faaSDavid Teigland 
531b3b94faaSDavid Teigland 	return error;
532b3b94faaSDavid Teigland }
533b3b94faaSDavid Teigland 
534b3b94faaSDavid Teigland /**
5356802e340SSteven Whitehouse  * inode_go_dump - print information about an inode
5366802e340SSteven Whitehouse  * @seq: The iterator
537c551f66cSLee Jones  * @gl: The glock
5383792ce97SBob Peterson  * @fs_id_buf: file system id (may be empty)
5396802e340SSteven Whitehouse  *
5406802e340SSteven Whitehouse  */
5416802e340SSteven Whitehouse 
inode_go_dump(struct seq_file * seq,const struct gfs2_glock * gl,const char * fs_id_buf)542f246dd4bSAndreas Gruenbacher static void inode_go_dump(struct seq_file *seq, const struct gfs2_glock *gl,
5433792ce97SBob Peterson 			  const char *fs_id_buf)
5446802e340SSteven Whitehouse {
54527a2660fSBob Peterson 	struct gfs2_inode *ip = gl->gl_object;
546f246dd4bSAndreas Gruenbacher 	const struct inode *inode = &ip->i_inode;
54727a2660fSBob Peterson 
5486802e340SSteven Whitehouse 	if (ip == NULL)
549ac3beb6aSSteven Whitehouse 		return;
55027a2660fSBob Peterson 
5513792ce97SBob Peterson 	gfs2_print_dbg(seq, "%s I: n:%llu/%llu t:%u f:0x%02lx d:0x%08x s:%llu "
5523792ce97SBob Peterson 		       "p:%lu\n", fs_id_buf,
5536802e340SSteven Whitehouse 		  (unsigned long long)ip->i_no_formal_ino,
5546802e340SSteven Whitehouse 		  (unsigned long long)ip->i_no_addr,
555f246dd4bSAndreas Gruenbacher 		  IF2DT(inode->i_mode), ip->i_flags,
556fa75cedcSSteven Whitehouse 		  (unsigned int)ip->i_diskflags,
557f246dd4bSAndreas Gruenbacher 		  (unsigned long long)i_size_read(inode),
558f246dd4bSAndreas Gruenbacher 		  inode->i_data.nrpages);
5596802e340SSteven Whitehouse }
5606802e340SSteven Whitehouse 
5616802e340SSteven Whitehouse /**
562b77b4a48SAndreas Gruenbacher  * freeze_go_callback - A cluster node is requesting a freeze
563b3b94faaSDavid Teigland  * @gl: the glock
564b77b4a48SAndreas Gruenbacher  * @remote: true if this came from a different cluster node
565b3b94faaSDavid Teigland  */
566b3b94faaSDavid Teigland 
freeze_go_callback(struct gfs2_glock * gl,bool remote)567b77b4a48SAndreas Gruenbacher static void freeze_go_callback(struct gfs2_glock *gl, bool remote)
568b3b94faaSDavid Teigland {
56915562c43SBob Peterson 	struct gfs2_sbd *sdp = gl->gl_name.ln_sbd;
570b77b4a48SAndreas Gruenbacher 	struct super_block *sb = sdp->sd_vfs;
571b77b4a48SAndreas Gruenbacher 
572b77b4a48SAndreas Gruenbacher 	if (!remote ||
57352954b75SAndreas Gruenbacher 	    (gl->gl_state != LM_ST_SHARED &&
57452954b75SAndreas Gruenbacher 	     gl->gl_state != LM_ST_UNLOCKED) ||
575b77b4a48SAndreas Gruenbacher 	    gl->gl_demote_state != LM_ST_UNLOCKED)
576b77b4a48SAndreas Gruenbacher 		return;
577b3b94faaSDavid Teigland 
57820b32912SBob Peterson 	/*
579b77b4a48SAndreas Gruenbacher 	 * Try to get an active super block reference to prevent racing with
58052954b75SAndreas Gruenbacher 	 * unmount (see super_trylock_shared()).  But note that unmount isn't
58152954b75SAndreas Gruenbacher 	 * the only place where a write lock on s_umount is taken, and we can
58252954b75SAndreas Gruenbacher 	 * fail here because of things like remount as well.
58320b32912SBob Peterson 	 */
584b77b4a48SAndreas Gruenbacher 	if (down_read_trylock(&sb->s_umount)) {
585b77b4a48SAndreas Gruenbacher 		atomic_inc(&sb->s_active);
586b77b4a48SAndreas Gruenbacher 		up_read(&sb->s_umount);
587b77b4a48SAndreas Gruenbacher 		if (!queue_work(gfs2_freeze_wq, &sdp->sd_freeze_work))
588b77b4a48SAndreas Gruenbacher 			deactivate_super(sb);
589601ef0d5SBob Peterson 	}
590b3b94faaSDavid Teigland }
591b3b94faaSDavid Teigland 
592b3b94faaSDavid Teigland /**
59324972557SBenjamin Marzinski  * freeze_go_xmote_bh - After promoting/demoting the freeze glock
594b3b94faaSDavid Teigland  * @gl: the glock
595b3b94faaSDavid Teigland  */
freeze_go_xmote_bh(struct gfs2_glock * gl)596f68effb3SBob Peterson static int freeze_go_xmote_bh(struct gfs2_glock *gl)
597b3b94faaSDavid Teigland {
59815562c43SBob Peterson 	struct gfs2_sbd *sdp = gl->gl_name.ln_sbd;
599feaa7bbaSSteven Whitehouse 	struct gfs2_inode *ip = GFS2_I(sdp->sd_jdesc->jd_inode);
6005c676f6dSSteven Whitehouse 	struct gfs2_glock *j_gl = ip->i_gl;
60155167622SAl Viro 	struct gfs2_log_header_host head;
602b3b94faaSDavid Teigland 	int error;
603b3b94faaSDavid Teigland 
6046802e340SSteven Whitehouse 	if (test_bit(SDF_JOURNAL_LIVE, &sdp->sd_flags)) {
6051a14d3a6SSteven Whitehouse 		j_gl->gl_ops->go_inval(j_gl, DIO_METADATA);
606b3b94faaSDavid Teigland 
607f4686c26SAbhi Das 		error = gfs2_find_jhead(sdp->sd_jdesc, &head, false);
6089d9b1605SBob Peterson 		if (gfs2_assert_withdraw_delayed(sdp, !error))
6099d9b1605SBob Peterson 			return error;
6109d9b1605SBob Peterson 		if (gfs2_assert_withdraw_delayed(sdp, head.lh_flags &
6119d9b1605SBob Peterson 						 GFS2_LOG_HEAD_UNMOUNT))
6129d9b1605SBob Peterson 			return -EIO;
613b3b94faaSDavid Teigland 		sdp->sd_log_sequence = head.lh_sequence + 1;
614b3b94faaSDavid Teigland 		gfs2_log_pointers_init(sdp, head.lh_blkno);
615b3b94faaSDavid Teigland 	}
6166802e340SSteven Whitehouse 	return 0;
617b3b94faaSDavid Teigland }
618b3b94faaSDavid Teigland 
619b3b94faaSDavid Teigland /**
620c551f66cSLee Jones  * freeze_go_demote_ok
62197cc1025SSteven Whitehouse  * @gl: the glock
62297cc1025SSteven Whitehouse  *
62397cc1025SSteven Whitehouse  * Always returns 0
62497cc1025SSteven Whitehouse  */
62597cc1025SSteven Whitehouse 
freeze_go_demote_ok(const struct gfs2_glock * gl)62624972557SBenjamin Marzinski static int freeze_go_demote_ok(const struct gfs2_glock *gl)
62797cc1025SSteven Whitehouse {
62897cc1025SSteven Whitehouse 	return 0;
62997cc1025SSteven Whitehouse }
63097cc1025SSteven Whitehouse 
631b94a170eSBenjamin Marzinski /**
632b94a170eSBenjamin Marzinski  * iopen_go_callback - schedule the dcache entry for the inode to be deleted
633b94a170eSBenjamin Marzinski  * @gl: the glock
634c551f66cSLee Jones  * @remote: true if this came from a different cluster node
635b94a170eSBenjamin Marzinski  *
636f3dd1649SAndreas Gruenbacher  * gl_lockref.lock lock is held while calling this
637b94a170eSBenjamin Marzinski  */
iopen_go_callback(struct gfs2_glock * gl,bool remote)63881ffbf65SSteven Whitehouse static void iopen_go_callback(struct gfs2_glock *gl, bool remote)
639b94a170eSBenjamin Marzinski {
6406f6597baSAndreas Gruenbacher 	struct gfs2_inode *ip = gl->gl_object;
64115562c43SBob Peterson 	struct gfs2_sbd *sdp = gl->gl_name.ln_sbd;
642001e8e8dSSteven Whitehouse 
6436c0246a9SBob Peterson 	if (!remote || sb_rdonly(sdp->sd_vfs) ||
644e7beb8b6SAndreas Gruenbacher 	    test_bit(SDF_KILL, &sdp->sd_flags))
645001e8e8dSSteven Whitehouse 		return;
646b94a170eSBenjamin Marzinski 
647b94a170eSBenjamin Marzinski 	if (gl->gl_demote_state == LM_ST_UNLOCKED &&
648009d8518SSteven Whitehouse 	    gl->gl_state == LM_ST_SHARED && ip) {
649e66cf161SSteven Whitehouse 		gl->gl_lockref.count++;
650f0e56edcSAndreas Gruenbacher 		if (!gfs2_queue_try_to_evict(gl))
651e66cf161SSteven Whitehouse 			gl->gl_lockref.count--;
652b94a170eSBenjamin Marzinski 	}
653b94a170eSBenjamin Marzinski }
654b94a170eSBenjamin Marzinski 
655601ef0d5SBob Peterson /**
656601ef0d5SBob Peterson  * inode_go_free - wake up anyone waiting for dlm's unlock ast to free it
657601ef0d5SBob Peterson  * @gl: glock being freed
658601ef0d5SBob Peterson  *
659601ef0d5SBob Peterson  * For now, this is only used for the journal inode glock. In withdraw
660601ef0d5SBob Peterson  * situations, we need to wait for the glock to be freed so that we know
661601ef0d5SBob Peterson  * other nodes may proceed with recovery / journal replay.
662601ef0d5SBob Peterson  */
inode_go_free(struct gfs2_glock * gl)663601ef0d5SBob Peterson static void inode_go_free(struct gfs2_glock *gl)
664601ef0d5SBob Peterson {
665601ef0d5SBob Peterson 	/* Note that we cannot reference gl_object because it's already set
666601ef0d5SBob Peterson 	 * to NULL by this point in its lifecycle. */
667601ef0d5SBob Peterson 	if (!test_bit(GLF_FREEING, &gl->gl_flags))
668601ef0d5SBob Peterson 		return;
669601ef0d5SBob Peterson 	clear_bit_unlock(GLF_FREEING, &gl->gl_flags);
670601ef0d5SBob Peterson 	wake_up_bit(&gl->gl_flags, GLF_FREEING);
671601ef0d5SBob Peterson }
672601ef0d5SBob Peterson 
673601ef0d5SBob Peterson /**
674601ef0d5SBob Peterson  * nondisk_go_callback - used to signal when a node did a withdraw
675601ef0d5SBob Peterson  * @gl: the nondisk glock
676601ef0d5SBob Peterson  * @remote: true if this came from a different cluster node
677601ef0d5SBob Peterson  *
678601ef0d5SBob Peterson  */
nondisk_go_callback(struct gfs2_glock * gl,bool remote)679601ef0d5SBob Peterson static void nondisk_go_callback(struct gfs2_glock *gl, bool remote)
680601ef0d5SBob Peterson {
681601ef0d5SBob Peterson 	struct gfs2_sbd *sdp = gl->gl_name.ln_sbd;
682601ef0d5SBob Peterson 
683601ef0d5SBob Peterson 	/* Ignore the callback unless it's from another node, and it's the
684601ef0d5SBob Peterson 	   live lock. */
685601ef0d5SBob Peterson 	if (!remote || gl->gl_name.ln_number != GFS2_LIVE_LOCK)
686601ef0d5SBob Peterson 		return;
687601ef0d5SBob Peterson 
688601ef0d5SBob Peterson 	/* First order of business is to cancel the demote request. We don't
689601ef0d5SBob Peterson 	 * really want to demote a nondisk glock. At best it's just to inform
690601ef0d5SBob Peterson 	 * us of another node's withdraw. We'll keep it in SH mode. */
691601ef0d5SBob Peterson 	clear_bit(GLF_DEMOTE, &gl->gl_flags);
692601ef0d5SBob Peterson 	clear_bit(GLF_PENDING_DEMOTE, &gl->gl_flags);
693601ef0d5SBob Peterson 
694601ef0d5SBob Peterson 	/* Ignore the unlock if we're withdrawn, unmounting, or in recovery. */
695601ef0d5SBob Peterson 	if (test_bit(SDF_NORECOVERY, &sdp->sd_flags) ||
696601ef0d5SBob Peterson 	    test_bit(SDF_WITHDRAWN, &sdp->sd_flags) ||
697601ef0d5SBob Peterson 	    test_bit(SDF_REMOTE_WITHDRAW, &sdp->sd_flags))
698601ef0d5SBob Peterson 		return;
699601ef0d5SBob Peterson 
700601ef0d5SBob Peterson 	/* We only care when a node wants us to unlock, because that means
701601ef0d5SBob Peterson 	 * they want a journal recovered. */
702601ef0d5SBob Peterson 	if (gl->gl_demote_state != LM_ST_UNLOCKED)
703601ef0d5SBob Peterson 		return;
704601ef0d5SBob Peterson 
705601ef0d5SBob Peterson 	if (sdp->sd_args.ar_spectator) {
706601ef0d5SBob Peterson 		fs_warn(sdp, "Spectator node cannot recover journals.\n");
707601ef0d5SBob Peterson 		return;
708601ef0d5SBob Peterson 	}
709601ef0d5SBob Peterson 
710601ef0d5SBob Peterson 	fs_warn(sdp, "Some node has withdrawn; checking for recovery.\n");
711601ef0d5SBob Peterson 	set_bit(SDF_REMOTE_WITHDRAW, &sdp->sd_flags);
712601ef0d5SBob Peterson 	/*
713601ef0d5SBob Peterson 	 * We can't call remote_withdraw directly here or gfs2_recover_journal
714601ef0d5SBob Peterson 	 * because this is called from the glock unlock function and the
715601ef0d5SBob Peterson 	 * remote_withdraw needs to enqueue and dequeue the same "live" glock
716601ef0d5SBob Peterson 	 * we were called from. So we queue it to the control work queue in
717601ef0d5SBob Peterson 	 * lock_dlm.
718601ef0d5SBob Peterson 	 */
719601ef0d5SBob Peterson 	queue_delayed_work(gfs2_control_wq, &sdp->sd_control_work, 0);
720601ef0d5SBob Peterson }
721601ef0d5SBob Peterson 
7228fb4b536SSteven Whitehouse const struct gfs2_glock_operations gfs2_meta_glops = {
723ea67eedbSSteven Whitehouse 	.go_type = LM_TYPE_META,
724a72d2401SBob Peterson 	.go_flags = GLOF_NONDISK,
725b3b94faaSDavid Teigland };
726b3b94faaSDavid Teigland 
7278fb4b536SSteven Whitehouse const struct gfs2_glock_operations gfs2_inode_glops = {
72806dfc306SBob Peterson 	.go_sync = inode_go_sync,
729b3b94faaSDavid Teigland 	.go_inval = inode_go_inval,
730b3b94faaSDavid Teigland 	.go_demote_ok = inode_go_demote_ok,
7313278b977SBob Peterson 	.go_instantiate = inode_go_instantiate,
73286c30a01SAndreas Gruenbacher 	.go_held = inode_go_held,
7336802e340SSteven Whitehouse 	.go_dump = inode_go_dump,
734ea67eedbSSteven Whitehouse 	.go_type = LM_TYPE_INODE,
735f286d627SAndreas Gruenbacher 	.go_flags = GLOF_ASPACE | GLOF_LRU | GLOF_LVB,
736601ef0d5SBob Peterson 	.go_free = inode_go_free,
737b3b94faaSDavid Teigland };
738b3b94faaSDavid Teigland 
7398fb4b536SSteven Whitehouse const struct gfs2_glock_operations gfs2_rgrp_glops = {
74006dfc306SBob Peterson 	.go_sync = rgrp_go_sync,
7416bac243fSSteven Whitehouse 	.go_inval = rgrp_go_inval,
7423278b977SBob Peterson 	.go_instantiate = gfs2_rgrp_go_instantiate,
7430e539ca1SAndrew Price 	.go_dump = gfs2_rgrp_go_dump,
744ea67eedbSSteven Whitehouse 	.go_type = LM_TYPE_RGRP,
74570d4ee94SSteven Whitehouse 	.go_flags = GLOF_LVB,
746b3b94faaSDavid Teigland };
747b3b94faaSDavid Teigland 
74824972557SBenjamin Marzinski const struct gfs2_glock_operations gfs2_freeze_glops = {
74924972557SBenjamin Marzinski 	.go_xmote_bh = freeze_go_xmote_bh,
75024972557SBenjamin Marzinski 	.go_demote_ok = freeze_go_demote_ok,
751b77b4a48SAndreas Gruenbacher 	.go_callback = freeze_go_callback,
752ea67eedbSSteven Whitehouse 	.go_type = LM_TYPE_NONDISK,
753a72d2401SBob Peterson 	.go_flags = GLOF_NONDISK,
754b3b94faaSDavid Teigland };
755b3b94faaSDavid Teigland 
7568fb4b536SSteven Whitehouse const struct gfs2_glock_operations gfs2_iopen_glops = {
757ea67eedbSSteven Whitehouse 	.go_type = LM_TYPE_IOPEN,
758b94a170eSBenjamin Marzinski 	.go_callback = iopen_go_callback,
75974382e27SBob Peterson 	.go_dump = inode_go_dump,
760a72d2401SBob Peterson 	.go_flags = GLOF_LRU | GLOF_NONDISK,
761515b269dSAlexander Aring 	.go_subclass = 1,
762b3b94faaSDavid Teigland };
763b3b94faaSDavid Teigland 
7648fb4b536SSteven Whitehouse const struct gfs2_glock_operations gfs2_flock_glops = {
765ea67eedbSSteven Whitehouse 	.go_type = LM_TYPE_FLOCK,
766a72d2401SBob Peterson 	.go_flags = GLOF_LRU | GLOF_NONDISK,
767b3b94faaSDavid Teigland };
768b3b94faaSDavid Teigland 
7698fb4b536SSteven Whitehouse const struct gfs2_glock_operations gfs2_nondisk_glops = {
770ea67eedbSSteven Whitehouse 	.go_type = LM_TYPE_NONDISK,
771a72d2401SBob Peterson 	.go_flags = GLOF_NONDISK,
772601ef0d5SBob Peterson 	.go_callback = nondisk_go_callback,
773b3b94faaSDavid Teigland };
774b3b94faaSDavid Teigland 
7758fb4b536SSteven Whitehouse const struct gfs2_glock_operations gfs2_quota_glops = {
776ea67eedbSSteven Whitehouse 	.go_type = LM_TYPE_QUOTA,
777a72d2401SBob Peterson 	.go_flags = GLOF_LVB | GLOF_LRU | GLOF_NONDISK,
778b3b94faaSDavid Teigland };
779b3b94faaSDavid Teigland 
7808fb4b536SSteven Whitehouse const struct gfs2_glock_operations gfs2_journal_glops = {
781ea67eedbSSteven Whitehouse 	.go_type = LM_TYPE_JOURNAL,
782a72d2401SBob Peterson 	.go_flags = GLOF_NONDISK,
783b3b94faaSDavid Teigland };
784b3b94faaSDavid Teigland 
78564d576baSSteven Whitehouse const struct gfs2_glock_operations *gfs2_glops_list[] = {
78664d576baSSteven Whitehouse 	[LM_TYPE_META] = &gfs2_meta_glops,
78764d576baSSteven Whitehouse 	[LM_TYPE_INODE] = &gfs2_inode_glops,
78864d576baSSteven Whitehouse 	[LM_TYPE_RGRP] = &gfs2_rgrp_glops,
78964d576baSSteven Whitehouse 	[LM_TYPE_IOPEN] = &gfs2_iopen_glops,
79064d576baSSteven Whitehouse 	[LM_TYPE_FLOCK] = &gfs2_flock_glops,
79164d576baSSteven Whitehouse 	[LM_TYPE_NONDISK] = &gfs2_nondisk_glops,
79264d576baSSteven Whitehouse 	[LM_TYPE_QUOTA] = &gfs2_quota_glops,
79364d576baSSteven Whitehouse 	[LM_TYPE_JOURNAL] = &gfs2_journal_glops,
79464d576baSSteven Whitehouse };
79564d576baSSteven Whitehouse 
796