Skip to content

Commit 7208c98

Browse files
committed
Merge tag 'gfs2-v5.18-rc6-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/gfs2/linux-gfs2
Pull gfs2 updates from Andreas Gruenbacher: - Clean up the allocation of glocks that have an address space attached - Quota locking fix and quota iomap conversion - Fix the FITRIM error reporting - Some list iterator cleanups * tag 'gfs2-v5.18-rc6-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/gfs2/linux-gfs2: gfs2: Convert function bh_get to use iomap gfs2: use i_lock spin_lock for inode qadata gfs2: Return more useful errors from gfs2_rgrp_send_discards() gfs2: Use container_of() for gfs2_glock(aspace) gfs2: Explain some direct I/O oddities gfs2: replace 'found' with dedicated list iterator variable
2 parents bd1b7c1 + c360abb commit 7208c98

File tree

8 files changed

+91
-66
lines changed

8 files changed

+91
-66
lines changed

fs/gfs2/file.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -840,6 +840,7 @@ static ssize_t gfs2_file_direct_read(struct kiocb *iocb, struct iov_iter *to,
840840
pagefault_enable();
841841
if (ret <= 0 && ret != -EFAULT)
842842
goto out_unlock;
843+
/* No increment (+=) because iomap_dio_rw returns a cumulative value. */
843844
if (ret > 0)
844845
read = ret;
845846

@@ -854,6 +855,7 @@ static ssize_t gfs2_file_direct_read(struct kiocb *iocb, struct iov_iter *to,
854855
gfs2_glock_dq(gh);
855856
out_uninit:
856857
gfs2_holder_uninit(gh);
858+
/* User space doesn't expect partial success. */
857859
if (ret < 0)
858860
return ret;
859861
return read;
@@ -906,6 +908,7 @@ static ssize_t gfs2_file_direct_write(struct kiocb *iocb, struct iov_iter *from,
906908
if (ret != -EFAULT)
907909
goto out_unlock;
908910
}
911+
/* No increment (+=) because iomap_dio_rw returns a cumulative value. */
909912
if (ret > 0)
910913
written = ret;
911914

@@ -920,6 +923,7 @@ static ssize_t gfs2_file_direct_write(struct kiocb *iocb, struct iov_iter *from,
920923
gfs2_glock_dq(gh);
921924
out_uninit:
922925
gfs2_holder_uninit(gh);
926+
/* User space doesn't expect partial success. */
923927
if (ret < 0)
924928
return ret;
925929
return written;

fs/gfs2/glock.c

Lines changed: 19 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -127,9 +127,11 @@ static void gfs2_glock_dealloc(struct rcu_head *rcu)
127127
struct gfs2_glock *gl = container_of(rcu, struct gfs2_glock, gl_rcu);
128128

129129
kfree(gl->gl_lksb.sb_lvbptr);
130-
if (gl->gl_ops->go_flags & GLOF_ASPACE)
131-
kmem_cache_free(gfs2_glock_aspace_cachep, gl);
132-
else
130+
if (gl->gl_ops->go_flags & GLOF_ASPACE) {
131+
struct gfs2_glock_aspace *gla =
132+
container_of(gl, struct gfs2_glock_aspace, glock);
133+
kmem_cache_free(gfs2_glock_aspace_cachep, gla);
134+
} else
133135
kmem_cache_free(gfs2_glock_cachep, gl);
134136
}
135137

@@ -1159,7 +1161,6 @@ int gfs2_glock_get(struct gfs2_sbd *sdp, u64 number,
11591161
.ln_sbd = sdp };
11601162
struct gfs2_glock *gl, *tmp;
11611163
struct address_space *mapping;
1162-
struct kmem_cache *cachep;
11631164
int ret = 0;
11641165

11651166
gl = find_insert_glock(&name, NULL);
@@ -1170,20 +1171,24 @@ int gfs2_glock_get(struct gfs2_sbd *sdp, u64 number,
11701171
if (!create)
11711172
return -ENOENT;
11721173

1173-
if (glops->go_flags & GLOF_ASPACE)
1174-
cachep = gfs2_glock_aspace_cachep;
1175-
else
1176-
cachep = gfs2_glock_cachep;
1177-
gl = kmem_cache_alloc(cachep, GFP_NOFS);
1178-
if (!gl)
1179-
return -ENOMEM;
1180-
1174+
if (glops->go_flags & GLOF_ASPACE) {
1175+
struct gfs2_glock_aspace *gla =
1176+
kmem_cache_alloc(gfs2_glock_aspace_cachep, GFP_NOFS);
1177+
if (!gla)
1178+
return -ENOMEM;
1179+
gl = &gla->glock;
1180+
} else {
1181+
gl = kmem_cache_alloc(gfs2_glock_cachep, GFP_NOFS);
1182+
if (!gl)
1183+
return -ENOMEM;
1184+
}
11811185
memset(&gl->gl_lksb, 0, sizeof(struct dlm_lksb));
1186+
gl->gl_ops = glops;
11821187

11831188
if (glops->go_flags & GLOF_LVB) {
11841189
gl->gl_lksb.sb_lvbptr = kzalloc(GDLM_LVB_SIZE, GFP_NOFS);
11851190
if (!gl->gl_lksb.sb_lvbptr) {
1186-
kmem_cache_free(cachep, gl);
1191+
gfs2_glock_dealloc(&gl->gl_rcu);
11871192
return -ENOMEM;
11881193
}
11891194
}
@@ -1197,7 +1202,6 @@ int gfs2_glock_get(struct gfs2_sbd *sdp, u64 number,
11971202
gl->gl_state = LM_ST_UNLOCKED;
11981203
gl->gl_target = LM_ST_UNLOCKED;
11991204
gl->gl_demote_state = LM_ST_EXCLUSIVE;
1200-
gl->gl_ops = glops;
12011205
gl->gl_dstamp = 0;
12021206
preempt_disable();
12031207
/* We use the global stats to estimate the initial per-glock stats */
@@ -1234,8 +1238,7 @@ int gfs2_glock_get(struct gfs2_sbd *sdp, u64 number,
12341238
*glp = tmp;
12351239

12361240
out_free:
1237-
kfree(gl->gl_lksb.sb_lvbptr);
1238-
kmem_cache_free(cachep, gl);
1241+
gfs2_glock_dealloc(&gl->gl_rcu);
12391242
if (atomic_dec_and_test(&sdp->sd_glock_disposal))
12401243
wake_up(&sdp->sd_glock_wait);
12411244

fs/gfs2/glock.h

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,11 @@ struct lm_lockops {
138138
const match_table_t *lm_tokens;
139139
};
140140

141+
struct gfs2_glock_aspace {
142+
struct gfs2_glock glock;
143+
struct address_space mapping;
144+
};
145+
141146
extern struct workqueue_struct *gfs2_delete_workqueue;
142147
static inline struct gfs2_holder *gfs2_glock_is_locked_by_me(struct gfs2_glock *gl)
143148
{
@@ -179,8 +184,11 @@ static inline int gfs2_glock_is_held_shrd(struct gfs2_glock *gl)
179184

180185
static inline struct address_space *gfs2_glock2aspace(struct gfs2_glock *gl)
181186
{
182-
if (gl->gl_ops->go_flags & GLOF_ASPACE)
183-
return (struct address_space *)(gl + 1);
187+
if (gl->gl_ops->go_flags & GLOF_ASPACE) {
188+
struct gfs2_glock_aspace *gla =
189+
container_of(gl, struct gfs2_glock_aspace, glock);
190+
return &gla->mapping;
191+
}
184192
return NULL;
185193
}
186194

fs/gfs2/main.c

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -62,11 +62,10 @@ static void gfs2_init_glock_once(void *foo)
6262

6363
static void gfs2_init_gl_aspace_once(void *foo)
6464
{
65-
struct gfs2_glock *gl = foo;
66-
struct address_space *mapping = (struct address_space *)(gl + 1);
65+
struct gfs2_glock_aspace *gla = foo;
6766

68-
gfs2_init_glock_once(gl);
69-
address_space_init_once(mapping);
67+
gfs2_init_glock_once(&gla->glock);
68+
address_space_init_once(&gla->mapping);
7069
}
7170

7271
/**
@@ -104,8 +103,7 @@ static int __init init_gfs2_fs(void)
104103
goto fail_cachep1;
105104

106105
gfs2_glock_aspace_cachep = kmem_cache_create("gfs2_glock(aspace)",
107-
sizeof(struct gfs2_glock) +
108-
sizeof(struct address_space),
106+
sizeof(struct gfs2_glock_aspace),
109107
0, 0, gfs2_init_gl_aspace_once);
110108

111109
if (!gfs2_glock_aspace_cachep)

fs/gfs2/meta_io.h

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,9 +40,11 @@ extern const struct address_space_operations gfs2_rgrp_aops;
4040
static inline struct gfs2_sbd *gfs2_mapping2sbd(struct address_space *mapping)
4141
{
4242
struct inode *inode = mapping->host;
43-
if (mapping->a_ops == &gfs2_meta_aops)
44-
return (((struct gfs2_glock *)mapping) - 1)->gl_name.ln_sbd;
45-
else if (mapping->a_ops == &gfs2_rgrp_aops)
43+
if (mapping->a_ops == &gfs2_meta_aops) {
44+
struct gfs2_glock_aspace *gla =
45+
container_of(mapping, struct gfs2_glock_aspace, mapping);
46+
return gla->glock.gl_name.ln_sbd;
47+
} else if (mapping->a_ops == &gfs2_rgrp_aops)
4648
return container_of(mapping, struct gfs2_sbd, sd_aspace);
4749
else
4850
return inode->i_sb->s_fs_info;

fs/gfs2/quota.c

Lines changed: 37 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -365,11 +365,12 @@ static void slot_put(struct gfs2_quota_data *qd)
365365
static int bh_get(struct gfs2_quota_data *qd)
366366
{
367367
struct gfs2_sbd *sdp = qd->qd_gl->gl_name.ln_sbd;
368-
struct gfs2_inode *ip = GFS2_I(sdp->sd_qc_inode);
368+
struct inode *inode = sdp->sd_qc_inode;
369+
struct gfs2_inode *ip = GFS2_I(inode);
369370
unsigned int block, offset;
370371
struct buffer_head *bh;
372+
struct iomap iomap = { };
371373
int error;
372-
struct buffer_head bh_map = { .b_state = 0, .b_blocknr = 0 };
373374

374375
mutex_lock(&sdp->sd_quota_mutex);
375376

@@ -381,11 +382,17 @@ static int bh_get(struct gfs2_quota_data *qd)
381382
block = qd->qd_slot / sdp->sd_qc_per_block;
382383
offset = qd->qd_slot % sdp->sd_qc_per_block;
383384

384-
bh_map.b_size = BIT(ip->i_inode.i_blkbits);
385-
error = gfs2_block_map(&ip->i_inode, block, &bh_map, 0);
385+
error = gfs2_iomap_get(inode,
386+
(loff_t)block << inode->i_blkbits,
387+
i_blocksize(inode), &iomap);
386388
if (error)
387389
goto fail;
388-
error = gfs2_meta_read(ip->i_gl, bh_map.b_blocknr, DIO_WAIT, 0, &bh);
390+
error = -ENOENT;
391+
if (iomap.type != IOMAP_MAPPED)
392+
goto fail;
393+
394+
error = gfs2_meta_read(ip->i_gl, iomap.addr >> inode->i_blkbits,
395+
DIO_WAIT, 0, &bh);
389396
if (error)
390397
goto fail;
391398
error = -EIO;
@@ -443,9 +450,8 @@ static int qd_check_sync(struct gfs2_sbd *sdp, struct gfs2_quota_data *qd,
443450

444451
static int qd_fish(struct gfs2_sbd *sdp, struct gfs2_quota_data **qdp)
445452
{
446-
struct gfs2_quota_data *qd = NULL;
453+
struct gfs2_quota_data *qd = NULL, *iter;
447454
int error;
448-
int found = 0;
449455

450456
*qdp = NULL;
451457

@@ -454,15 +460,13 @@ static int qd_fish(struct gfs2_sbd *sdp, struct gfs2_quota_data **qdp)
454460

455461
spin_lock(&qd_lock);
456462

457-
list_for_each_entry(qd, &sdp->sd_quota_list, qd_list) {
458-
found = qd_check_sync(sdp, qd, &sdp->sd_quota_sync_gen);
459-
if (found)
463+
list_for_each_entry(iter, &sdp->sd_quota_list, qd_list) {
464+
if (qd_check_sync(sdp, iter, &sdp->sd_quota_sync_gen)) {
465+
qd = iter;
460466
break;
467+
}
461468
}
462469

463-
if (!found)
464-
qd = NULL;
465-
466470
spin_unlock(&qd_lock);
467471

468472
if (qd) {
@@ -531,34 +535,42 @@ static void qdsb_put(struct gfs2_quota_data *qd)
531535
*/
532536
int gfs2_qa_get(struct gfs2_inode *ip)
533537
{
534-
int error = 0;
535538
struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
539+
struct inode *inode = &ip->i_inode;
536540

537541
if (sdp->sd_args.ar_quota == GFS2_QUOTA_OFF)
538542
return 0;
539543

540-
down_write(&ip->i_rw_mutex);
544+
spin_lock(&inode->i_lock);
541545
if (ip->i_qadata == NULL) {
542-
ip->i_qadata = kmem_cache_zalloc(gfs2_qadata_cachep, GFP_NOFS);
543-
if (!ip->i_qadata) {
544-
error = -ENOMEM;
545-
goto out;
546-
}
546+
struct gfs2_qadata *tmp;
547+
548+
spin_unlock(&inode->i_lock);
549+
tmp = kmem_cache_zalloc(gfs2_qadata_cachep, GFP_NOFS);
550+
if (!tmp)
551+
return -ENOMEM;
552+
553+
spin_lock(&inode->i_lock);
554+
if (ip->i_qadata == NULL)
555+
ip->i_qadata = tmp;
556+
else
557+
kmem_cache_free(gfs2_qadata_cachep, tmp);
547558
}
548559
ip->i_qadata->qa_ref++;
549-
out:
550-
up_write(&ip->i_rw_mutex);
551-
return error;
560+
spin_unlock(&inode->i_lock);
561+
return 0;
552562
}
553563

554564
void gfs2_qa_put(struct gfs2_inode *ip)
555565
{
556-
down_write(&ip->i_rw_mutex);
566+
struct inode *inode = &ip->i_inode;
567+
568+
spin_lock(&inode->i_lock);
557569
if (ip->i_qadata && --ip->i_qadata->qa_ref == 0) {
558570
kmem_cache_free(gfs2_qadata_cachep, ip->i_qadata);
559571
ip->i_qadata = NULL;
560572
}
561-
up_write(&ip->i_rw_mutex);
573+
spin_unlock(&inode->i_lock);
562574
}
563575

564576
int gfs2_quota_hold(struct gfs2_inode *ip, kuid_t uid, kgid_t gid)

fs/gfs2/recovery.c

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -55,17 +55,16 @@ int gfs2_replay_read_block(struct gfs2_jdesc *jd, unsigned int blk,
5555
int gfs2_revoke_add(struct gfs2_jdesc *jd, u64 blkno, unsigned int where)
5656
{
5757
struct list_head *head = &jd->jd_revoke_list;
58-
struct gfs2_revoke_replay *rr;
59-
int found = 0;
58+
struct gfs2_revoke_replay *rr = NULL, *iter;
6059

61-
list_for_each_entry(rr, head, rr_list) {
62-
if (rr->rr_blkno == blkno) {
63-
found = 1;
60+
list_for_each_entry(iter, head, rr_list) {
61+
if (iter->rr_blkno == blkno) {
62+
rr = iter;
6463
break;
6564
}
6665
}
6766

68-
if (found) {
67+
if (rr) {
6968
rr->rr_where = where;
7069
return 0;
7170
}
@@ -83,18 +82,17 @@ int gfs2_revoke_add(struct gfs2_jdesc *jd, u64 blkno, unsigned int where)
8382

8483
int gfs2_revoke_check(struct gfs2_jdesc *jd, u64 blkno, unsigned int where)
8584
{
86-
struct gfs2_revoke_replay *rr;
85+
struct gfs2_revoke_replay *rr = NULL, *iter;
8786
int wrap, a, b, revoke;
88-
int found = 0;
8987

90-
list_for_each_entry(rr, &jd->jd_revoke_list, rr_list) {
91-
if (rr->rr_blkno == blkno) {
92-
found = 1;
88+
list_for_each_entry(iter, &jd->jd_revoke_list, rr_list) {
89+
if (iter->rr_blkno == blkno) {
90+
rr = iter;
9391
break;
9492
}
9593
}
9694

97-
if (!found)
95+
if (!rr)
9896
return 0;
9997

10098
wrap = (rr->rr_where < jd->jd_replay_tail);

fs/gfs2/rgrp.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1315,7 +1315,7 @@ int gfs2_rgrp_send_discards(struct gfs2_sbd *sdp, u64 offset,
13151315
u64 blk;
13161316
sector_t start = 0;
13171317
sector_t nr_blks = 0;
1318-
int rv;
1318+
int rv = -EIO;
13191319
unsigned int x;
13201320
u32 trimmed = 0;
13211321
u8 diff;
@@ -1371,7 +1371,7 @@ int gfs2_rgrp_send_discards(struct gfs2_sbd *sdp, u64 offset,
13711371
if (sdp->sd_args.ar_discard)
13721372
fs_warn(sdp, "error %d on discard request, turning discards off for this filesystem\n", rv);
13731373
sdp->sd_args.ar_discard = 0;
1374-
return -EIO;
1374+
return rv;
13751375
}
13761376

13771377
/**

0 commit comments

Comments
 (0)