Skip to content

Commit f6e1e1d

Browse files
committed
Merge tag 'gfs2-for-5.12' of git://git.kernel.org/pub/scm/linux/kernel/git/gfs2/linux-gfs2
Pull gfs2 updates from Andreas Gruenbacher: - Log space and revoke accounting rework to fix some failed asserts. - Local resource group glock sharing for better local performance. - Add support for version 1802 filesystems: trusted xattr support and '-o rgrplvb' mounts by default. - Actually synchronize on the inode glock's FREEING bit during withdraw ("gfs2: fix glock confusion in function signal_our_withdraw"). - Fix parallel recovery of multiple journals ("gfs2: keep bios separate for each journal"). - Various other bug fixes. * tag 'gfs2-for-5.12' of git://git.kernel.org/pub/scm/linux/kernel/git/gfs2/linux-gfs2: (49 commits) gfs2: Don't get stuck with I/O plugged in gfs2_ail1_flush gfs2: Per-revoke accounting in transactions gfs2: Rework the log space allocation logic gfs2: Minor calc_reserved cleanup gfs2: Use resource group glock sharing gfs2: Allow node-wide exclusive glock sharing gfs2: Add local resource group locking gfs2: Add per-reservation reserved block accounting gfs2: Rename rs_{free -> requested} and rd_{reserved -> requested} gfs2: Check for active reservation in gfs2_release gfs2: Don't search for unreserved space twice gfs2: Only pass reservation down to gfs2_rbm_find gfs2: Also reflect single-block allocations in rgd->rd_extfail_pt gfs2: Recursive gfs2_quota_hold in gfs2_iomap_end gfs2: Add trusted xattr support gfs2: Enable rgrplvb for sb_fs_format 1802 gfs2: Don't skip dlm unlock if glock has an lvb gfs2: Lock imbalance on error path in gfs2_recover_one gfs2: Move function gfs2_ail_empty_tr gfs2: Get rid of current_tail() ...
2 parents 7d6beb7 + 17d7768 commit f6e1e1d

26 files changed

+967
-662
lines changed

fs/gfs2/bmap.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1230,6 +1230,9 @@ static int gfs2_iomap_end(struct inode *inode, loff_t pos, loff_t length,
12301230

12311231
gfs2_inplace_release(ip);
12321232

1233+
if (ip->i_qadata && ip->i_qadata->qa_qd_num)
1234+
gfs2_quota_unlock(ip);
1235+
12331236
if (length != written && (iomap->flags & IOMAP_F_NEW)) {
12341237
/* Deallocate blocks that were just allocated. */
12351238
loff_t blockmask = i_blocksize(inode) - 1;
@@ -1242,9 +1245,6 @@ static int gfs2_iomap_end(struct inode *inode, loff_t pos, loff_t length,
12421245
}
12431246
}
12441247

1245-
if (ip->i_qadata && ip->i_qadata->qa_qd_num)
1246-
gfs2_quota_unlock(ip);
1247-
12481248
if (unlikely(!written))
12491249
goto out_unlock;
12501250

@@ -1538,13 +1538,13 @@ static int sweep_bh_for_rgrps(struct gfs2_inode *ip, struct gfs2_holder *rd_gh,
15381538
goto out;
15391539
}
15401540
ret = gfs2_glock_nq_init(rgd->rd_gl, LM_ST_EXCLUSIVE,
1541-
0, rd_gh);
1541+
LM_FLAG_NODE_SCOPE, rd_gh);
15421542
if (ret)
15431543
goto out;
15441544

15451545
/* Must be done with the rgrp glock held: */
15461546
if (gfs2_rs_active(&ip->i_res) &&
1547-
rgd == ip->i_res.rs_rbm.rgd)
1547+
rgd == ip->i_res.rs_rgd)
15481548
gfs2_rs_deltree(&ip->i_res);
15491549
}
15501550

fs/gfs2/file.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -716,10 +716,10 @@ static int gfs2_release(struct inode *inode, struct file *file)
716716
kfree(file->private_data);
717717
file->private_data = NULL;
718718

719-
if (file->f_mode & FMODE_WRITE) {
719+
if (gfs2_rs_active(&ip->i_res))
720720
gfs2_rs_delete(ip, &inode->i_writecount);
721+
if (file->f_mode & FMODE_WRITE)
721722
gfs2_qa_put(ip);
722-
}
723723
return 0;
724724
}
725725

@@ -1112,8 +1112,8 @@ static long __gfs2_fallocate(struct file *file, int mode, loff_t offset, loff_t
11121112
goto out_qunlock;
11131113

11141114
/* check if the selected rgrp limits our max_blks further */
1115-
if (ap.allowed && ap.allowed < max_blks)
1116-
max_blks = ap.allowed;
1115+
if (ip->i_res.rs_reserved < max_blks)
1116+
max_blks = ip->i_res.rs_reserved;
11171117

11181118
/* Almost done. Calculate bytes that can be written using
11191119
* max_blks. We also recompute max_bytes, data_blocks and

fs/gfs2/glock.c

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -313,9 +313,23 @@ void gfs2_glock_put(struct gfs2_glock *gl)
313313
static inline int may_grant(const struct gfs2_glock *gl, const struct gfs2_holder *gh)
314314
{
315315
const struct gfs2_holder *gh_head = list_first_entry(&gl->gl_holders, const struct gfs2_holder, gh_list);
316-
if ((gh->gh_state == LM_ST_EXCLUSIVE ||
317-
gh_head->gh_state == LM_ST_EXCLUSIVE) && gh != gh_head)
318-
return 0;
316+
317+
if (gh != gh_head) {
318+
/**
319+
* Here we make a special exception to grant holders who agree
320+
* to share the EX lock with other holders who also have the
321+
* bit set. If the original holder has the LM_FLAG_NODE_SCOPE bit
322+
* is set, we grant more holders with the bit set.
323+
*/
324+
if (gh_head->gh_state == LM_ST_EXCLUSIVE &&
325+
(gh_head->gh_flags & LM_FLAG_NODE_SCOPE) &&
326+
gh->gh_state == LM_ST_EXCLUSIVE &&
327+
(gh->gh_flags & LM_FLAG_NODE_SCOPE))
328+
return 1;
329+
if ((gh->gh_state == LM_ST_EXCLUSIVE ||
330+
gh_head->gh_state == LM_ST_EXCLUSIVE))
331+
return 0;
332+
}
319333
if (gl->gl_state == gh->gh_state)
320334
return 1;
321335
if (gh->gh_flags & GL_EXACT)
@@ -2030,6 +2044,8 @@ static const char *hflags2str(char *buf, u16 flags, unsigned long iflags)
20302044
*p++ = 'A';
20312045
if (flags & LM_FLAG_PRIORITY)
20322046
*p++ = 'p';
2047+
if (flags & LM_FLAG_NODE_SCOPE)
2048+
*p++ = 'n';
20332049
if (flags & GL_ASYNC)
20342050
*p++ = 'a';
20352051
if (flags & GL_EXACT)

fs/gfs2/glock.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,13 +75,19 @@ enum {
7575
* request and directly join the other shared lock. A shared lock request
7676
* without the priority flag might be forced to wait until the deferred
7777
* requested had acquired and released the lock.
78+
*
79+
* LM_FLAG_NODE_SCOPE
80+
* This holder agrees to share the lock within this node. In other words,
81+
* the glock is held in EX mode according to DLM, but local holders on the
82+
* same node can share it.
7883
*/
7984

8085
#define LM_FLAG_TRY 0x0001
8186
#define LM_FLAG_TRY_1CB 0x0002
8287
#define LM_FLAG_NOEXP 0x0004
8388
#define LM_FLAG_ANY 0x0008
8489
#define LM_FLAG_PRIORITY 0x0010
90+
#define LM_FLAG_NODE_SCOPE 0x0020
8591
#define GL_ASYNC 0x0040
8692
#define GL_EXACT 0x0080
8793
#define GL_SKIP 0x0100

fs/gfs2/glops.c

Lines changed: 12 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -86,16 +86,12 @@ static int gfs2_ail_empty_gl(struct gfs2_glock *gl)
8686
{
8787
struct gfs2_sbd *sdp = gl->gl_name.ln_sbd;
8888
struct gfs2_trans tr;
89+
unsigned int revokes;
8990
int ret;
9091

91-
memset(&tr, 0, sizeof(tr));
92-
INIT_LIST_HEAD(&tr.tr_buf);
93-
INIT_LIST_HEAD(&tr.tr_databuf);
94-
INIT_LIST_HEAD(&tr.tr_ail1_list);
95-
INIT_LIST_HEAD(&tr.tr_ail2_list);
96-
tr.tr_revokes = atomic_read(&gl->gl_ail_count);
92+
revokes = atomic_read(&gl->gl_ail_count);
9793

98-
if (!tr.tr_revokes) {
94+
if (!revokes) {
9995
bool have_revokes;
10096
bool log_in_flight;
10197

@@ -122,20 +118,14 @@ static int gfs2_ail_empty_gl(struct gfs2_glock *gl)
122118
return 0;
123119
}
124120

125-
/* A shortened, inline version of gfs2_trans_begin()
126-
* tr->alloced is not set since the transaction structure is
127-
* on the stack */
128-
tr.tr_reserved = 1 + gfs2_struct2blk(sdp, tr.tr_revokes);
129-
tr.tr_ip = _RET_IP_;
130-
ret = gfs2_log_reserve(sdp, tr.tr_reserved);
131-
if (ret < 0)
132-
return ret;
133-
WARN_ON_ONCE(current->journal_info);
134-
current->journal_info = &tr;
135-
136-
__gfs2_ail_flush(gl, 0, tr.tr_revokes);
137-
121+
memset(&tr, 0, sizeof(tr));
122+
set_bit(TR_ONSTACK, &tr.tr_flags);
123+
ret = __gfs2_trans_begin(&tr, sdp, 0, revokes, _RET_IP_);
124+
if (ret)
125+
goto flush;
126+
__gfs2_ail_flush(gl, 0, revokes);
138127
gfs2_trans_end(sdp);
128+
139129
flush:
140130
gfs2_log_flush(sdp, NULL, GFS2_LOG_HEAD_FLUSH_NORMAL |
141131
GFS2_LFC_AIL_EMPTY_GL);
@@ -146,19 +136,15 @@ void gfs2_ail_flush(struct gfs2_glock *gl, bool fsync)
146136
{
147137
struct gfs2_sbd *sdp = gl->gl_name.ln_sbd;
148138
unsigned int revokes = atomic_read(&gl->gl_ail_count);
149-
unsigned int max_revokes = (sdp->sd_sb.sb_bsize - sizeof(struct gfs2_log_descriptor)) / sizeof(u64);
150139
int ret;
151140

152141
if (!revokes)
153142
return;
154143

155-
while (revokes > max_revokes)
156-
max_revokes += (sdp->sd_sb.sb_bsize - sizeof(struct gfs2_meta_header)) / sizeof(u64);
157-
158-
ret = gfs2_trans_begin(sdp, 0, max_revokes);
144+
ret = gfs2_trans_begin(sdp, 0, revokes);
159145
if (ret)
160146
return;
161-
__gfs2_ail_flush(gl, fsync, max_revokes);
147+
__gfs2_ail_flush(gl, fsync, revokes);
162148
gfs2_trans_end(sdp);
163149
gfs2_log_flush(sdp, NULL, GFS2_LOG_HEAD_FLUSH_NORMAL |
164150
GFS2_LFC_AIL_FLUSH);

fs/gfs2/incore.h

Lines changed: 16 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include <linux/percpu.h>
2121
#include <linux/lockref.h>
2222
#include <linux/rhashtable.h>
23+
#include <linux/mutex.h>
2324

2425
#define DIO_WAIT 0x00000010
2526
#define DIO_METADATA 0x00000020
@@ -106,7 +107,8 @@ struct gfs2_rgrpd {
106107
u32 rd_data; /* num of data blocks in rgrp */
107108
u32 rd_bitbytes; /* number of bytes in data bitmaps */
108109
u32 rd_free;
109-
u32 rd_reserved; /* number of blocks reserved */
110+
u32 rd_requested; /* number of blocks in rd_rstree */
111+
u32 rd_reserved; /* number of reserved blocks */
110112
u32 rd_free_clone;
111113
u32 rd_dinodes;
112114
u64 rd_igeneration;
@@ -122,34 +124,10 @@ struct gfs2_rgrpd {
122124
#define GFS2_RDF_PREFERRED 0x80000000 /* This rgrp is preferred */
123125
#define GFS2_RDF_MASK 0xf0000000 /* mask for internal flags */
124126
spinlock_t rd_rsspin; /* protects reservation related vars */
127+
struct mutex rd_mutex;
125128
struct rb_root rd_rstree; /* multi-block reservation tree */
126129
};
127130

128-
struct gfs2_rbm {
129-
struct gfs2_rgrpd *rgd;
130-
u32 offset; /* The offset is bitmap relative */
131-
int bii; /* Bitmap index */
132-
};
133-
134-
static inline struct gfs2_bitmap *rbm_bi(const struct gfs2_rbm *rbm)
135-
{
136-
return rbm->rgd->rd_bits + rbm->bii;
137-
}
138-
139-
static inline u64 gfs2_rbm_to_block(const struct gfs2_rbm *rbm)
140-
{
141-
BUG_ON(rbm->offset >= rbm->rgd->rd_data);
142-
return rbm->rgd->rd_data0 + (rbm_bi(rbm)->bi_start * GFS2_NBBY) +
143-
rbm->offset;
144-
}
145-
146-
static inline bool gfs2_rbm_eq(const struct gfs2_rbm *rbm1,
147-
const struct gfs2_rbm *rbm2)
148-
{
149-
return (rbm1->rgd == rbm2->rgd) && (rbm1->bii == rbm2->bii) &&
150-
(rbm1->offset == rbm2->offset);
151-
}
152-
153131
enum gfs2_state_bits {
154132
BH_Pinned = BH_PrivateStart,
155133
BH_Escaped = BH_PrivateStart + 1,
@@ -313,9 +291,11 @@ struct gfs2_qadata { /* quota allocation data */
313291
*/
314292

315293
struct gfs2_blkreserv {
316-
struct rb_node rs_node; /* link to other block reservations */
317-
struct gfs2_rbm rs_rbm; /* Start of reservation */
318-
u32 rs_free; /* how many blocks are still free */
294+
struct rb_node rs_node; /* node within rd_rstree */
295+
struct gfs2_rgrpd *rs_rgd;
296+
u64 rs_start;
297+
u32 rs_requested;
298+
u32 rs_reserved; /* number of reserved blocks */
319299
};
320300

321301
/*
@@ -490,7 +470,7 @@ struct gfs2_quota_data {
490470
enum {
491471
TR_TOUCHED = 1,
492472
TR_ATTACHED = 2,
493-
TR_ALLOCED = 3,
473+
TR_ONSTACK = 3,
494474
};
495475

496476
struct gfs2_trans {
@@ -506,7 +486,6 @@ struct gfs2_trans {
506486
unsigned int tr_num_buf_rm;
507487
unsigned int tr_num_databuf_rm;
508488
unsigned int tr_num_revoke;
509-
unsigned int tr_num_revoke_rm;
510489

511490
struct list_head tr_list;
512491
struct list_head tr_databuf;
@@ -531,6 +510,7 @@ struct gfs2_jdesc {
531510
unsigned int nr_extents;
532511
struct work_struct jd_work;
533512
struct inode *jd_inode;
513+
struct bio *jd_log_bio;
534514
unsigned long jd_flags;
535515
#define JDF_RECOVERY 1
536516
unsigned int jd_jid;
@@ -585,6 +565,7 @@ struct gfs2_args {
585565
unsigned int ar_errors:2; /* errors=withdraw | panic */
586566
unsigned int ar_nobarrier:1; /* do not send barriers */
587567
unsigned int ar_rgrplvb:1; /* use lvbs for rgrp info */
568+
unsigned int ar_got_rgrplvb:1; /* Was the rgrplvb opt given? */
588569
unsigned int ar_loccookie:1; /* use location based readdir
589570
cookies */
590571
s32 ar_commit; /* Commit interval */
@@ -821,7 +802,6 @@ struct gfs2_sbd {
821802

822803
struct gfs2_trans *sd_log_tr;
823804
unsigned int sd_log_blks_reserved;
824-
int sd_log_committed_revoke;
825805

826806
atomic_t sd_log_pinned;
827807
unsigned int sd_log_num_revoke;
@@ -834,24 +814,22 @@ struct gfs2_sbd {
834814
atomic_t sd_log_thresh2;
835815
atomic_t sd_log_blks_free;
836816
atomic_t sd_log_blks_needed;
817+
atomic_t sd_log_revokes_available;
837818
wait_queue_head_t sd_log_waitq;
838819
wait_queue_head_t sd_logd_waitq;
839820

840821
u64 sd_log_sequence;
841-
unsigned int sd_log_head;
842-
unsigned int sd_log_tail;
843822
int sd_log_idle;
844823

845824
struct rw_semaphore sd_log_flush_lock;
846825
atomic_t sd_log_in_flight;
847-
struct bio *sd_log_bio;
848826
wait_queue_head_t sd_log_flush_wait;
849827
int sd_log_error; /* First log error */
850828
wait_queue_head_t sd_withdraw_wait;
851829

852-
atomic_t sd_reserving_log;
853-
wait_queue_head_t sd_reserving_log_wait;
854-
830+
unsigned int sd_log_tail;
831+
unsigned int sd_log_flush_tail;
832+
unsigned int sd_log_head;
855833
unsigned int sd_log_flush_head;
856834

857835
spinlock_t sd_ail_lock;

fs/gfs2/inode.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1147,7 +1147,7 @@ static int gfs2_unlink(struct inode *dir, struct dentry *dentry)
11471147
if (!rgd)
11481148
goto out_inodes;
11491149

1150-
gfs2_holder_init(rgd->rd_gl, LM_ST_EXCLUSIVE, 0, ghs + 2);
1150+
gfs2_holder_init(rgd->rd_gl, LM_ST_EXCLUSIVE, LM_FLAG_NODE_SCOPE, ghs + 2);
11511151

11521152

11531153
error = gfs2_glock_nq(ghs); /* parent */
@@ -1453,8 +1453,8 @@ static int gfs2_rename(struct inode *odir, struct dentry *odentry,
14531453
error = -ENOENT;
14541454
goto out_gunlock;
14551455
}
1456-
error = gfs2_glock_nq_init(nrgd->rd_gl, LM_ST_EXCLUSIVE, 0,
1457-
&rd_gh);
1456+
error = gfs2_glock_nq_init(nrgd->rd_gl, LM_ST_EXCLUSIVE,
1457+
LM_FLAG_NODE_SCOPE, &rd_gh);
14581458
if (error)
14591459
goto out_gunlock;
14601460
}

fs/gfs2/lock_dlm.c

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -284,7 +284,6 @@ static void gdlm_put_lock(struct gfs2_glock *gl)
284284
{
285285
struct gfs2_sbd *sdp = gl->gl_name.ln_sbd;
286286
struct lm_lockstruct *ls = &sdp->sd_lockstruct;
287-
int lvb_needs_unlock = 0;
288287
int error;
289288

290289
if (gl->gl_lksb.sb_lkid == 0) {
@@ -297,13 +296,10 @@ static void gdlm_put_lock(struct gfs2_glock *gl)
297296
gfs2_sbstats_inc(gl, GFS2_LKS_DCOUNT);
298297
gfs2_update_request_times(gl);
299298

300-
/* don't want to skip dlm_unlock writing the lvb when lock is ex */
301-
302-
if (gl->gl_lksb.sb_lvbptr && (gl->gl_state == LM_ST_EXCLUSIVE))
303-
lvb_needs_unlock = 1;
299+
/* don't want to skip dlm_unlock writing the lvb when lock has one */
304300

305301
if (test_bit(SDF_SKIP_DLM_UNLOCK, &sdp->sd_flags) &&
306-
!lvb_needs_unlock) {
302+
!gl->gl_lksb.sb_lvbptr) {
307303
gfs2_glock_free(gl);
308304
return;
309305
}

0 commit comments

Comments
 (0)