Skip to content

Commit 42eb8fd

Browse files
committed
Merge tag 'gfs2-v5.16-rc2-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/gfs2/linux-gfs2
Pull gfs2 fixes from Andreas Gruenbacher: - The current iomap_file_buffered_write behavior of failing the entire write when part of the user buffer cannot be faulted in leads to an endless loop in gfs2. Work around that in gfs2 for now. - Various other bugs all over the place. * tag 'gfs2-v5.16-rc2-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/gfs2/linux-gfs2: gfs2: Prevent endless loops in gfs2_file_buffered_write gfs2: Fix "Introduce flag for glock holder auto-demotion" gfs2: Fix length of holes reported at end-of-file gfs2: release iopen glock early in evict gfs2: Fix atomic bug in gfs2_instantiate gfs2: Only dereference i->iov when iter_is_iovec(i)
2 parents 3fa5954 + 554c577 commit 42eb8fd

File tree

4 files changed

+18
-19
lines changed

4 files changed

+18
-19
lines changed

fs/gfs2/bmap.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -940,7 +940,7 @@ static int __gfs2_iomap_get(struct inode *inode, loff_t pos, loff_t length,
940940
else if (height == ip->i_height)
941941
ret = gfs2_hole_size(inode, lblock, len, mp, iomap);
942942
else
943-
iomap->length = size - pos;
943+
iomap->length = size - iomap->offset;
944944
} else if (flags & IOMAP_WRITE) {
945945
u64 alloc_size;
946946

fs/gfs2/file.c

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -773,8 +773,8 @@ static inline bool should_fault_in_pages(ssize_t ret, struct iov_iter *i,
773773
size_t *prev_count,
774774
size_t *window_size)
775775
{
776-
char __user *p = i->iov[0].iov_base + i->iov_offset;
777776
size_t count = iov_iter_count(i);
777+
char __user *p;
778778
int pages = 1;
779779

780780
if (likely(!count))
@@ -787,14 +787,14 @@ static inline bool should_fault_in_pages(ssize_t ret, struct iov_iter *i,
787787
if (*prev_count != count || !*window_size) {
788788
int pages, nr_dirtied;
789789

790-
pages = min_t(int, BIO_MAX_VECS,
791-
DIV_ROUND_UP(iov_iter_count(i), PAGE_SIZE));
790+
pages = min_t(int, BIO_MAX_VECS, DIV_ROUND_UP(count, PAGE_SIZE));
792791
nr_dirtied = max(current->nr_dirtied_pause -
793792
current->nr_dirtied, 1);
794793
pages = min(pages, nr_dirtied);
795794
}
796795

797796
*prev_count = count;
797+
p = i->iov[0].iov_base + i->iov_offset;
798798
*window_size = (size_t)PAGE_SIZE * pages - offset_in_page(p);
799799
return true;
800800
}
@@ -1013,6 +1013,7 @@ static ssize_t gfs2_file_buffered_write(struct kiocb *iocb,
10131013
struct gfs2_sbd *sdp = GFS2_SB(inode);
10141014
struct gfs2_holder *statfs_gh = NULL;
10151015
size_t prev_count = 0, window_size = 0;
1016+
size_t orig_count = iov_iter_count(from);
10161017
size_t read = 0;
10171018
ssize_t ret;
10181019

@@ -1057,13 +1058,15 @@ static ssize_t gfs2_file_buffered_write(struct kiocb *iocb,
10571058
if (inode == sdp->sd_rindex)
10581059
gfs2_glock_dq_uninit(statfs_gh);
10591060

1061+
from->count = orig_count - read;
10601062
if (should_fault_in_pages(ret, from, &prev_count, &window_size)) {
10611063
size_t leftover;
10621064

10631065
gfs2_holder_allow_demote(gh);
10641066
leftover = fault_in_iov_iter_readable(from, window_size);
10651067
gfs2_holder_disallow_demote(gh);
10661068
if (leftover != window_size) {
1069+
from->count = min(from->count, window_size - leftover);
10671070
if (!gfs2_holder_queued(gh)) {
10681071
if (read)
10691072
goto out_uninit;

fs/gfs2/glock.c

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -411,14 +411,14 @@ static void do_error(struct gfs2_glock *gl, const int ret)
411411
static void demote_incompat_holders(struct gfs2_glock *gl,
412412
struct gfs2_holder *new_gh)
413413
{
414-
struct gfs2_holder *gh;
414+
struct gfs2_holder *gh, *tmp;
415415

416416
/*
417417
* Demote incompatible holders before we make ourselves eligible.
418418
* (This holder may or may not allow auto-demoting, but we don't want
419419
* to demote the new holder before it's even granted.)
420420
*/
421-
list_for_each_entry(gh, &gl->gl_holders, gh_list) {
421+
list_for_each_entry_safe(gh, tmp, &gl->gl_holders, gh_list) {
422422
/*
423423
* Since holders are at the front of the list, we stop when we
424424
* find the first non-holder.
@@ -496,7 +496,7 @@ int gfs2_instantiate(struct gfs2_holder *gh)
496496
* Since we unlock the lockref lock, we set a flag to indicate
497497
* instantiate is in progress.
498498
*/
499-
if (test_bit(GLF_INSTANTIATE_IN_PROG, &gl->gl_flags)) {
499+
if (test_and_set_bit(GLF_INSTANTIATE_IN_PROG, &gl->gl_flags)) {
500500
wait_on_bit(&gl->gl_flags, GLF_INSTANTIATE_IN_PROG,
501501
TASK_UNINTERRUPTIBLE);
502502
/*
@@ -509,14 +509,10 @@ int gfs2_instantiate(struct gfs2_holder *gh)
509509
goto again;
510510
}
511511

512-
set_bit(GLF_INSTANTIATE_IN_PROG, &gl->gl_flags);
513-
514512
ret = glops->go_instantiate(gh);
515513
if (!ret)
516514
clear_bit(GLF_INSTANTIATE_NEEDED, &gl->gl_flags);
517-
clear_bit(GLF_INSTANTIATE_IN_PROG, &gl->gl_flags);
518-
smp_mb__after_atomic();
519-
wake_up_bit(&gl->gl_flags, GLF_INSTANTIATE_IN_PROG);
515+
clear_and_wake_up_bit(GLF_INSTANTIATE_IN_PROG, &gl->gl_flags);
520516
return ret;
521517
}
522518

fs/gfs2/super.c

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1402,13 +1402,6 @@ static void gfs2_evict_inode(struct inode *inode)
14021402
gfs2_ordered_del_inode(ip);
14031403
clear_inode(inode);
14041404
gfs2_dir_hash_inval(ip);
1405-
if (ip->i_gl) {
1406-
glock_clear_object(ip->i_gl, ip);
1407-
wait_on_bit_io(&ip->i_flags, GIF_GLOP_PENDING, TASK_UNINTERRUPTIBLE);
1408-
gfs2_glock_add_to_lru(ip->i_gl);
1409-
gfs2_glock_put_eventually(ip->i_gl);
1410-
ip->i_gl = NULL;
1411-
}
14121405
if (gfs2_holder_initialized(&ip->i_iopen_gh)) {
14131406
struct gfs2_glock *gl = ip->i_iopen_gh.gh_gl;
14141407

@@ -1421,6 +1414,13 @@ static void gfs2_evict_inode(struct inode *inode)
14211414
gfs2_holder_uninit(&ip->i_iopen_gh);
14221415
gfs2_glock_put_eventually(gl);
14231416
}
1417+
if (ip->i_gl) {
1418+
glock_clear_object(ip->i_gl, ip);
1419+
wait_on_bit_io(&ip->i_flags, GIF_GLOP_PENDING, TASK_UNINTERRUPTIBLE);
1420+
gfs2_glock_add_to_lru(ip->i_gl);
1421+
gfs2_glock_put_eventually(ip->i_gl);
1422+
ip->i_gl = NULL;
1423+
}
14241424
}
14251425

14261426
static struct inode *gfs2_alloc_inode(struct super_block *sb)

0 commit comments

Comments
 (0)