Skip to content

Commit d1dd461

Browse files
committed
Merge tag 'gfs2-v5.10-rc1-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/gfs2/linux-gfs2
Pull gfs2 fixes from Andreas Gruenbacher: "Various gfs2 fixes" * tag 'gfs2-v5.10-rc1-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/gfs2/linux-gfs2: gfs2: Wake up when sd_glock_disposal becomes zero gfs2: Don't call cancel_delayed_work_sync from within delete work function gfs2: check for live vs. read-only file system in gfs2_fitrim gfs2: don't initialize statfs_change inodes in spectator mode gfs2: Split up gfs2_meta_sync into inode and rgrp versions gfs2: init_journal's undo directive should also undo the statfs inodes gfs2: Add missing truncate_inode_pages_final for sd_aspace gfs2: Free rd_bits later in gfs2_clear_rgrpd to fix use-after-free
2 parents e2557a2 + da7d554 commit d1dd461

10 files changed

Lines changed: 70 additions & 48 deletions

File tree

fs/gfs2/glock.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1078,7 +1078,8 @@ int gfs2_glock_get(struct gfs2_sbd *sdp, u64 number,
10781078
out_free:
10791079
kfree(gl->gl_lksb.sb_lvbptr);
10801080
kmem_cache_free(cachep, gl);
1081-
atomic_dec(&sdp->sd_glock_disposal);
1081+
if (atomic_dec_and_test(&sdp->sd_glock_disposal))
1082+
wake_up(&sdp->sd_glock_wait);
10821083

10831084
out:
10841085
return ret;

fs/gfs2/glops.c

Lines changed: 45 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,31 @@ void gfs2_ail_flush(struct gfs2_glock *gl, bool fsync)
164164
GFS2_LFC_AIL_FLUSH);
165165
}
166166

167+
/**
168+
* gfs2_rgrp_metasync - sync out the metadata of a resource group
169+
* @gl: the glock protecting the resource group
170+
*
171+
*/
172+
173+
static int gfs2_rgrp_metasync(struct gfs2_glock *gl)
174+
{
175+
struct gfs2_sbd *sdp = gl->gl_name.ln_sbd;
176+
struct address_space *metamapping = &sdp->sd_aspace;
177+
struct gfs2_rgrpd *rgd = gfs2_glock2rgrp(gl);
178+
const unsigned bsize = sdp->sd_sb.sb_bsize;
179+
loff_t start = (rgd->rd_addr * bsize) & PAGE_MASK;
180+
loff_t end = PAGE_ALIGN((rgd->rd_addr + rgd->rd_length) * bsize) - 1;
181+
int error;
182+
183+
filemap_fdatawrite_range(metamapping, start, end);
184+
error = filemap_fdatawait_range(metamapping, start, end);
185+
WARN_ON_ONCE(error && !gfs2_withdrawn(sdp));
186+
mapping_set_error(metamapping, error);
187+
if (error)
188+
gfs2_io_error(sdp);
189+
return error;
190+
}
191+
167192
/**
168193
* rgrp_go_sync - sync out the metadata for this glock
169194
* @gl: the glock
@@ -176,11 +201,7 @@ void gfs2_ail_flush(struct gfs2_glock *gl, bool fsync)
176201
static int rgrp_go_sync(struct gfs2_glock *gl)
177202
{
178203
struct gfs2_sbd *sdp = gl->gl_name.ln_sbd;
179-
struct address_space *mapping = &sdp->sd_aspace;
180204
struct gfs2_rgrpd *rgd = gfs2_glock2rgrp(gl);
181-
const unsigned bsize = sdp->sd_sb.sb_bsize;
182-
loff_t start = (rgd->rd_addr * bsize) & PAGE_MASK;
183-
loff_t end = PAGE_ALIGN((rgd->rd_addr + rgd->rd_length) * bsize) - 1;
184205
int error;
185206

186207
if (!test_and_clear_bit(GLF_DIRTY, &gl->gl_flags))
@@ -189,10 +210,7 @@ static int rgrp_go_sync(struct gfs2_glock *gl)
189210

190211
gfs2_log_flush(sdp, gl, GFS2_LOG_HEAD_FLUSH_NORMAL |
191212
GFS2_LFC_RGRP_GO_SYNC);
192-
filemap_fdatawrite_range(mapping, start, end);
193-
error = filemap_fdatawait_range(mapping, start, end);
194-
WARN_ON_ONCE(error && !gfs2_withdrawn(sdp));
195-
mapping_set_error(mapping, error);
213+
error = gfs2_rgrp_metasync(gl);
196214
if (!error)
197215
error = gfs2_ail_empty_gl(gl);
198216
gfs2_free_clones(rgd);
@@ -266,7 +284,24 @@ static void gfs2_clear_glop_pending(struct gfs2_inode *ip)
266284
}
267285

268286
/**
269-
* inode_go_sync - Sync the dirty data and/or metadata for an inode glock
287+
* gfs2_inode_metasync - sync out the metadata of an inode
288+
* @gl: the glock protecting the inode
289+
*
290+
*/
291+
int gfs2_inode_metasync(struct gfs2_glock *gl)
292+
{
293+
struct address_space *metamapping = gfs2_glock2aspace(gl);
294+
int error;
295+
296+
filemap_fdatawrite(metamapping);
297+
error = filemap_fdatawait(metamapping);
298+
if (error)
299+
gfs2_io_error(gl->gl_name.ln_sbd);
300+
return error;
301+
}
302+
303+
/**
304+
* inode_go_sync - Sync the dirty metadata of an inode
270305
* @gl: the glock protecting the inode
271306
*
272307
*/
@@ -297,8 +332,7 @@ static int inode_go_sync(struct gfs2_glock *gl)
297332
error = filemap_fdatawait(mapping);
298333
mapping_set_error(mapping, error);
299334
}
300-
ret = filemap_fdatawait(metamapping);
301-
mapping_set_error(metamapping, ret);
335+
ret = gfs2_inode_metasync(gl);
302336
if (!error)
303337
error = ret;
304338
gfs2_ail_empty_gl(gl);

fs/gfs2/glops.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ extern const struct gfs2_glock_operations gfs2_quota_glops;
2222
extern const struct gfs2_glock_operations gfs2_journal_glops;
2323
extern const struct gfs2_glock_operations *gfs2_glops_list[];
2424

25+
extern int gfs2_inode_metasync(struct gfs2_glock *gl);
2526
extern void gfs2_ail_flush(struct gfs2_glock *gl, bool fsync);
2627

2728
#endif /* __GLOPS_DOT_H__ */

fs/gfs2/inode.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,8 @@ struct inode *gfs2_inode_lookup(struct super_block *sb, unsigned int type,
180180
error = gfs2_glock_nq_init(io_gl, LM_ST_SHARED, GL_EXACT, &ip->i_iopen_gh);
181181
if (unlikely(error))
182182
goto fail;
183-
gfs2_cancel_delete_work(ip->i_iopen_gh.gh_gl);
183+
if (blktype != GFS2_BLKST_UNLINKED)
184+
gfs2_cancel_delete_work(ip->i_iopen_gh.gh_gl);
184185
glock_set_object(ip->i_iopen_gh.gh_gl, ip);
185186
gfs2_glock_put(io_gl);
186187
io_gl = NULL;

fs/gfs2/lops.c

Lines changed: 5 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include "incore.h"
2323
#include "inode.h"
2424
#include "glock.h"
25+
#include "glops.h"
2526
#include "log.h"
2627
#include "lops.h"
2728
#include "meta_io.h"
@@ -817,41 +818,19 @@ static int buf_lo_scan_elements(struct gfs2_jdesc *jd, u32 start,
817818
return error;
818819
}
819820

820-
/**
821-
* gfs2_meta_sync - Sync all buffers associated with a glock
822-
* @gl: The glock
823-
*
824-
*/
825-
826-
void gfs2_meta_sync(struct gfs2_glock *gl)
827-
{
828-
struct address_space *mapping = gfs2_glock2aspace(gl);
829-
struct gfs2_sbd *sdp = gl->gl_name.ln_sbd;
830-
int error;
831-
832-
if (mapping == NULL)
833-
mapping = &sdp->sd_aspace;
834-
835-
filemap_fdatawrite(mapping);
836-
error = filemap_fdatawait(mapping);
837-
838-
if (error)
839-
gfs2_io_error(gl->gl_name.ln_sbd);
840-
}
841-
842821
static void buf_lo_after_scan(struct gfs2_jdesc *jd, int error, int pass)
843822
{
844823
struct gfs2_inode *ip = GFS2_I(jd->jd_inode);
845824
struct gfs2_sbd *sdp = GFS2_SB(jd->jd_inode);
846825

847826
if (error) {
848-
gfs2_meta_sync(ip->i_gl);
827+
gfs2_inode_metasync(ip->i_gl);
849828
return;
850829
}
851830
if (pass != 1)
852831
return;
853832

854-
gfs2_meta_sync(ip->i_gl);
833+
gfs2_inode_metasync(ip->i_gl);
855834

856835
fs_info(sdp, "jid=%u: Replayed %u of %u blocks\n",
857836
jd->jd_jid, jd->jd_replayed_blocks, jd->jd_found_blocks);
@@ -1060,14 +1039,14 @@ static void databuf_lo_after_scan(struct gfs2_jdesc *jd, int error, int pass)
10601039
struct gfs2_sbd *sdp = GFS2_SB(jd->jd_inode);
10611040

10621041
if (error) {
1063-
gfs2_meta_sync(ip->i_gl);
1042+
gfs2_inode_metasync(ip->i_gl);
10641043
return;
10651044
}
10661045
if (pass != 1)
10671046
return;
10681047

10691048
/* data sync? */
1070-
gfs2_meta_sync(ip->i_gl);
1049+
gfs2_inode_metasync(ip->i_gl);
10711050

10721051
fs_info(sdp, "jid=%u: Replayed %u of %u data blocks\n",
10731052
jd->jd_jid, jd->jd_replayed_blocks, jd->jd_found_blocks);

fs/gfs2/lops.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,6 @@ extern void gfs2_log_submit_bio(struct bio **biop, int opf);
2727
extern void gfs2_pin(struct gfs2_sbd *sdp, struct buffer_head *bh);
2828
extern int gfs2_find_jhead(struct gfs2_jdesc *jd,
2929
struct gfs2_log_header_host *head, bool keep_cache);
30-
extern void gfs2_meta_sync(struct gfs2_glock *gl);
31-
3230
static inline unsigned int buf_limit(struct gfs2_sbd *sdp)
3331
{
3432
unsigned int limit;

fs/gfs2/ops_fstype.c

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -633,8 +633,10 @@ static int init_statfs(struct gfs2_sbd *sdp)
633633
if (IS_ERR(sdp->sd_statfs_inode)) {
634634
error = PTR_ERR(sdp->sd_statfs_inode);
635635
fs_err(sdp, "can't read in statfs inode: %d\n", error);
636-
goto fail;
636+
goto out;
637637
}
638+
if (sdp->sd_args.ar_spectator)
639+
goto out;
638640

639641
pn = gfs2_lookup_simple(master, "per_node");
640642
if (IS_ERR(pn)) {
@@ -682,15 +684,17 @@ static int init_statfs(struct gfs2_sbd *sdp)
682684
iput(pn);
683685
put_statfs:
684686
iput(sdp->sd_statfs_inode);
685-
fail:
687+
out:
686688
return error;
687689
}
688690

689691
/* Uninitialize and free up memory used by the list of statfs inodes */
690692
static void uninit_statfs(struct gfs2_sbd *sdp)
691693
{
692-
gfs2_glock_dq_uninit(&sdp->sd_sc_gh);
693-
free_local_statfs_inodes(sdp);
694+
if (!sdp->sd_args.ar_spectator) {
695+
gfs2_glock_dq_uninit(&sdp->sd_sc_gh);
696+
free_local_statfs_inodes(sdp);
697+
}
694698
iput(sdp->sd_statfs_inode);
695699
}
696700

@@ -704,7 +708,7 @@ static int init_journal(struct gfs2_sbd *sdp, int undo)
704708

705709
if (undo) {
706710
jindex = 0;
707-
goto fail_jinode_gh;
711+
goto fail_statfs;
708712
}
709713

710714
sdp->sd_jindex = gfs2_lookup_simple(master, "jindex");

fs/gfs2/recovery.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -349,7 +349,7 @@ static int update_statfs_inode(struct gfs2_jdesc *jd,
349349

350350
mark_buffer_dirty(bh);
351351
brelse(bh);
352-
gfs2_meta_sync(ip->i_gl);
352+
gfs2_inode_metasync(ip->i_gl);
353353

354354
out:
355355
return error;

fs/gfs2/rgrp.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -719,9 +719,9 @@ void gfs2_clear_rgrpd(struct gfs2_sbd *sdp)
719719
}
720720

721721
gfs2_free_clones(rgd);
722+
return_all_reservations(rgd);
722723
kfree(rgd->rd_bits);
723724
rgd->rd_bits = NULL;
724-
return_all_reservations(rgd);
725725
kmem_cache_free(gfs2_rgrpd_cachep, rgd);
726726
}
727727
}
@@ -1370,6 +1370,9 @@ int gfs2_fitrim(struct file *filp, void __user *argp)
13701370
if (!capable(CAP_SYS_ADMIN))
13711371
return -EPERM;
13721372

1373+
if (!test_bit(SDF_JOURNAL_LIVE, &sdp->sd_flags))
1374+
return -EROFS;
1375+
13731376
if (!blk_queue_discard(q))
13741377
return -EOPNOTSUPP;
13751378

fs/gfs2/super.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -738,6 +738,7 @@ static void gfs2_put_super(struct super_block *sb)
738738
gfs2_jindex_free(sdp);
739739
/* Take apart glock structures and buffer lists */
740740
gfs2_gl_hash_clear(sdp);
741+
truncate_inode_pages_final(&sdp->sd_aspace);
741742
gfs2_delete_debugfs_file(sdp);
742743
/* Unmount the locking protocol */
743744
gfs2_lm_unmount(sdp);

0 commit comments

Comments
 (0)