Skip to content

Commit d928e8f

Browse files
committed
Merge tag 'gfs2-v5.18-rc4-fix3' of git://git.kernel.org/pub/scm/linux/kernel/git/gfs2/linux-gfs2
Pull gfs2 fixes from Andreas Gruenbacher: "We've finally identified commit dc73290 ("gfs2: Introduce flag for glock holder auto-demotion") to be the other cause of the filesystem corruption we've been seeing. This feature isn't strictly necessary anymore, so we've decided to stop using it for now. With this and the gfs_iomap_end rounding fix you've already seen ("gfs2: Fix filesystem block deallocation for short writes" in this pull request), we're corruption free again now. - Fix filesystem block deallocation for short writes. - Stop using glock holder auto-demotion for now. - Get rid of buffered writes inefficiencies due to page faults being disabled. - Minor other cleanups" * tag 'gfs2-v5.18-rc4-fix3' of git://git.kernel.org/pub/scm/linux/kernel/git/gfs2/linux-gfs2: gfs2: Stop using glock holder auto-demotion for now gfs2: buffered write prefaulting gfs2: Align read and write chunks to the page cache gfs2: Pull return value test out of should_fault_in_pages gfs2: Clean up use of fault_in_iov_iter_{read,write}able gfs2: Variable rename gfs2: Fix filesystem block deallocation for short writes
2 parents f2dd007 + e1fa9ea commit d928e8f

File tree

2 files changed

+68
-82
lines changed

2 files changed

+68
-82
lines changed

fs/gfs2/bmap.c

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1153,13 +1153,12 @@ static int gfs2_iomap_end(struct inode *inode, loff_t pos, loff_t length,
11531153

11541154
if (length != written && (iomap->flags & IOMAP_F_NEW)) {
11551155
/* Deallocate blocks that were just allocated. */
1156-
loff_t blockmask = i_blocksize(inode) - 1;
1157-
loff_t end = (pos + length) & ~blockmask;
1156+
loff_t hstart = round_up(pos + written, i_blocksize(inode));
1157+
loff_t hend = iomap->offset + iomap->length;
11581158

1159-
pos = (pos + written + blockmask) & ~blockmask;
1160-
if (pos < end) {
1161-
truncate_pagecache_range(inode, pos, end - 1);
1162-
punch_hole(ip, pos, end - pos);
1159+
if (hstart < hend) {
1160+
truncate_pagecache_range(inode, hstart, hend - 1);
1161+
punch_hole(ip, hstart, hend - hstart);
11631162
}
11641163
}
11651164

fs/gfs2/file.c

Lines changed: 63 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -770,30 +770,27 @@ static int gfs2_fsync(struct file *file, loff_t start, loff_t end,
770770
return ret ? ret : ret1;
771771
}
772772

773-
static inline bool should_fault_in_pages(ssize_t ret, struct iov_iter *i,
773+
static inline bool should_fault_in_pages(struct iov_iter *i,
774+
struct kiocb *iocb,
774775
size_t *prev_count,
775776
size_t *window_size)
776777
{
777778
size_t count = iov_iter_count(i);
778779
size_t size, offs;
779780

780-
if (likely(!count))
781-
return false;
782-
if (ret <= 0 && ret != -EFAULT)
781+
if (!count)
783782
return false;
784783
if (!iter_is_iovec(i))
785784
return false;
786785

787786
size = PAGE_SIZE;
788-
offs = offset_in_page(i->iov[0].iov_base + i->iov_offset);
787+
offs = offset_in_page(iocb->ki_pos);
789788
if (*prev_count != count || !*window_size) {
790789
size_t nr_dirtied;
791790

792-
size = ALIGN(offs + count, PAGE_SIZE);
793-
size = min_t(size_t, size, SZ_1M);
794791
nr_dirtied = max(current->nr_dirtied_pause -
795792
current->nr_dirtied, 8);
796-
size = min(size, nr_dirtied << PAGE_SHIFT);
793+
size = min_t(size_t, SZ_1M, nr_dirtied << PAGE_SHIFT);
797794
}
798795

799796
*prev_count = count;
@@ -807,7 +804,7 @@ static ssize_t gfs2_file_direct_read(struct kiocb *iocb, struct iov_iter *to,
807804
struct file *file = iocb->ki_filp;
808805
struct gfs2_inode *ip = GFS2_I(file->f_mapping->host);
809806
size_t prev_count = 0, window_size = 0;
810-
size_t written = 0;
807+
size_t read = 0;
811808
ssize_t ret;
812809

813810
/*
@@ -835,35 +832,31 @@ static ssize_t gfs2_file_direct_read(struct kiocb *iocb, struct iov_iter *to,
835832
ret = gfs2_glock_nq(gh);
836833
if (ret)
837834
goto out_uninit;
838-
retry_under_glock:
839835
pagefault_disable();
840836
to->nofault = true;
841837
ret = iomap_dio_rw(iocb, to, &gfs2_iomap_ops, NULL,
842-
IOMAP_DIO_PARTIAL, written);
838+
IOMAP_DIO_PARTIAL, read);
843839
to->nofault = false;
844840
pagefault_enable();
841+
if (ret <= 0 && ret != -EFAULT)
842+
goto out_unlock;
845843
if (ret > 0)
846-
written = ret;
847-
848-
if (should_fault_in_pages(ret, to, &prev_count, &window_size)) {
849-
size_t leftover;
844+
read = ret;
850845

851-
gfs2_holder_allow_demote(gh);
852-
leftover = fault_in_iov_iter_writeable(to, window_size);
853-
gfs2_holder_disallow_demote(gh);
854-
if (leftover != window_size) {
855-
if (gfs2_holder_queued(gh))
856-
goto retry_under_glock;
846+
if (should_fault_in_pages(to, iocb, &prev_count, &window_size)) {
847+
gfs2_glock_dq(gh);
848+
window_size -= fault_in_iov_iter_writeable(to, window_size);
849+
if (window_size)
857850
goto retry;
858-
}
859851
}
852+
out_unlock:
860853
if (gfs2_holder_queued(gh))
861854
gfs2_glock_dq(gh);
862855
out_uninit:
863856
gfs2_holder_uninit(gh);
864857
if (ret < 0)
865858
return ret;
866-
return written;
859+
return read;
867860
}
868861

869862
static ssize_t gfs2_file_direct_write(struct kiocb *iocb, struct iov_iter *from,
@@ -873,7 +866,7 @@ static ssize_t gfs2_file_direct_write(struct kiocb *iocb, struct iov_iter *from,
873866
struct inode *inode = file->f_mapping->host;
874867
struct gfs2_inode *ip = GFS2_I(inode);
875868
size_t prev_count = 0, window_size = 0;
876-
size_t read = 0;
869+
size_t written = 0;
877870
ssize_t ret;
878871

879872
/*
@@ -901,47 +894,43 @@ static ssize_t gfs2_file_direct_write(struct kiocb *iocb, struct iov_iter *from,
901894
goto out_uninit;
902895
/* Silently fall back to buffered I/O when writing beyond EOF */
903896
if (iocb->ki_pos + iov_iter_count(from) > i_size_read(&ip->i_inode))
904-
goto out;
905-
retry_under_glock:
897+
goto out_unlock;
906898

907899
from->nofault = true;
908900
ret = iomap_dio_rw(iocb, from, &gfs2_iomap_ops, NULL,
909-
IOMAP_DIO_PARTIAL, read);
901+
IOMAP_DIO_PARTIAL, written);
910902
from->nofault = false;
911-
912-
if (ret == -ENOTBLK)
913-
ret = 0;
903+
if (ret <= 0) {
904+
if (ret == -ENOTBLK)
905+
ret = 0;
906+
if (ret != -EFAULT)
907+
goto out_unlock;
908+
}
914909
if (ret > 0)
915-
read = ret;
916-
917-
if (should_fault_in_pages(ret, from, &prev_count, &window_size)) {
918-
size_t leftover;
910+
written = ret;
919911

920-
gfs2_holder_allow_demote(gh);
921-
leftover = fault_in_iov_iter_readable(from, window_size);
922-
gfs2_holder_disallow_demote(gh);
923-
if (leftover != window_size) {
924-
if (gfs2_holder_queued(gh))
925-
goto retry_under_glock;
912+
if (should_fault_in_pages(from, iocb, &prev_count, &window_size)) {
913+
gfs2_glock_dq(gh);
914+
window_size -= fault_in_iov_iter_readable(from, window_size);
915+
if (window_size)
926916
goto retry;
927-
}
928917
}
929-
out:
918+
out_unlock:
930919
if (gfs2_holder_queued(gh))
931920
gfs2_glock_dq(gh);
932921
out_uninit:
933922
gfs2_holder_uninit(gh);
934923
if (ret < 0)
935924
return ret;
936-
return read;
925+
return written;
937926
}
938927

939928
static ssize_t gfs2_file_read_iter(struct kiocb *iocb, struct iov_iter *to)
940929
{
941930
struct gfs2_inode *ip;
942931
struct gfs2_holder gh;
943932
size_t prev_count = 0, window_size = 0;
944-
size_t written = 0;
933+
size_t read = 0;
945934
ssize_t ret;
946935

947936
/*
@@ -962,7 +951,7 @@ static ssize_t gfs2_file_read_iter(struct kiocb *iocb, struct iov_iter *to)
962951
if (ret >= 0) {
963952
if (!iov_iter_count(to))
964953
return ret;
965-
written = ret;
954+
read = ret;
966955
} else if (ret != -EFAULT) {
967956
if (ret != -EAGAIN)
968957
return ret;
@@ -975,30 +964,26 @@ static ssize_t gfs2_file_read_iter(struct kiocb *iocb, struct iov_iter *to)
975964
ret = gfs2_glock_nq(&gh);
976965
if (ret)
977966
goto out_uninit;
978-
retry_under_glock:
979967
pagefault_disable();
980968
ret = generic_file_read_iter(iocb, to);
981969
pagefault_enable();
970+
if (ret <= 0 && ret != -EFAULT)
971+
goto out_unlock;
982972
if (ret > 0)
983-
written += ret;
984-
985-
if (should_fault_in_pages(ret, to, &prev_count, &window_size)) {
986-
size_t leftover;
973+
read += ret;
987974

988-
gfs2_holder_allow_demote(&gh);
989-
leftover = fault_in_iov_iter_writeable(to, window_size);
990-
gfs2_holder_disallow_demote(&gh);
991-
if (leftover != window_size) {
992-
if (gfs2_holder_queued(&gh))
993-
goto retry_under_glock;
975+
if (should_fault_in_pages(to, iocb, &prev_count, &window_size)) {
976+
gfs2_glock_dq(&gh);
977+
window_size -= fault_in_iov_iter_writeable(to, window_size);
978+
if (window_size)
994979
goto retry;
995-
}
996980
}
981+
out_unlock:
997982
if (gfs2_holder_queued(&gh))
998983
gfs2_glock_dq(&gh);
999984
out_uninit:
1000985
gfs2_holder_uninit(&gh);
1001-
return written ? written : ret;
986+
return read ? read : ret;
1002987
}
1003988

1004989
static ssize_t gfs2_file_buffered_write(struct kiocb *iocb,
@@ -1012,7 +997,7 @@ static ssize_t gfs2_file_buffered_write(struct kiocb *iocb,
1012997
struct gfs2_holder *statfs_gh = NULL;
1013998
size_t prev_count = 0, window_size = 0;
1014999
size_t orig_count = iov_iter_count(from);
1015-
size_t read = 0;
1000+
size_t written = 0;
10161001
ssize_t ret;
10171002

10181003
/*
@@ -1030,10 +1015,18 @@ static ssize_t gfs2_file_buffered_write(struct kiocb *iocb,
10301015

10311016
gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, gh);
10321017
retry:
1018+
if (should_fault_in_pages(from, iocb, &prev_count, &window_size)) {
1019+
window_size -= fault_in_iov_iter_readable(from, window_size);
1020+
if (!window_size) {
1021+
ret = -EFAULT;
1022+
goto out_uninit;
1023+
}
1024+
from->count = min(from->count, window_size);
1025+
}
10331026
ret = gfs2_glock_nq(gh);
10341027
if (ret)
10351028
goto out_uninit;
1036-
retry_under_glock:
1029+
10371030
if (inode == sdp->sd_rindex) {
10381031
struct gfs2_inode *m_ip = GFS2_I(sdp->sd_statfs_inode);
10391032

@@ -1050,25 +1043,19 @@ static ssize_t gfs2_file_buffered_write(struct kiocb *iocb,
10501043
current->backing_dev_info = NULL;
10511044
if (ret > 0) {
10521045
iocb->ki_pos += ret;
1053-
read += ret;
1046+
written += ret;
10541047
}
10551048

10561049
if (inode == sdp->sd_rindex)
10571050
gfs2_glock_dq_uninit(statfs_gh);
10581051

1059-
from->count = orig_count - read;
1060-
if (should_fault_in_pages(ret, from, &prev_count, &window_size)) {
1061-
size_t leftover;
1062-
1063-
gfs2_holder_allow_demote(gh);
1064-
leftover = fault_in_iov_iter_readable(from, window_size);
1065-
gfs2_holder_disallow_demote(gh);
1066-
if (leftover != window_size) {
1067-
from->count = min(from->count, window_size - leftover);
1068-
if (gfs2_holder_queued(gh))
1069-
goto retry_under_glock;
1070-
goto retry;
1071-
}
1052+
if (ret <= 0 && ret != -EFAULT)
1053+
goto out_unlock;
1054+
1055+
from->count = orig_count - written;
1056+
if (should_fault_in_pages(from, iocb, &prev_count, &window_size)) {
1057+
gfs2_glock_dq(gh);
1058+
goto retry;
10721059
}
10731060
out_unlock:
10741061
if (gfs2_holder_queued(gh))
@@ -1077,8 +1064,8 @@ static ssize_t gfs2_file_buffered_write(struct kiocb *iocb,
10771064
gfs2_holder_uninit(gh);
10781065
if (statfs_gh)
10791066
kfree(statfs_gh);
1080-
from->count = orig_count - read;
1081-
return read ? read : ret;
1067+
from->count = orig_count - written;
1068+
return written ? written : ret;
10821069
}
10831070

10841071
/**

0 commit comments

Comments
 (0)