Skip to content

Commit fa5dfa6

Browse files
author
Andreas Gruenbacher
committed
gfs2: buffered write prefaulting
In gfs2_file_buffered_write, to increase the likelihood that all the user memory we're trying to write will be resident in memory, carry out the write in chunks and fault in each chunk of user memory before trying to write it. Otherwise, some workloads will trigger frequent short "internal" writes, causing filesystem blocks to be allocated and then partially deallocated again when writing into holes, which is wasteful and breaks reservations. Neither the chunked writes nor any of the short "internal" writes are user visible. Signed-off-by: Andreas Gruenbacher <[email protected]>
1 parent 324d116 commit fa5dfa6

File tree

1 file changed

+16
-12
lines changed

1 file changed

+16
-12
lines changed

fs/gfs2/file.c

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -778,7 +778,7 @@ static inline bool should_fault_in_pages(struct iov_iter *i,
778778
size_t count = iov_iter_count(i);
779779
size_t size, offs;
780780

781-
if (likely(!count))
781+
if (!count)
782782
return false;
783783
if (!iter_is_iovec(i))
784784
return false;
@@ -1033,7 +1033,20 @@ static ssize_t gfs2_file_buffered_write(struct kiocb *iocb,
10331033
ret = gfs2_glock_nq(gh);
10341034
if (ret)
10351035
goto out_uninit;
1036+
if (should_fault_in_pages(from, iocb, &prev_count, &window_size)) {
10361037
retry_under_glock:
1038+
gfs2_holder_allow_demote(gh);
1039+
window_size -= fault_in_iov_iter_readable(from, window_size);
1040+
gfs2_holder_disallow_demote(gh);
1041+
if (!window_size) {
1042+
ret = -EFAULT;
1043+
goto out_unlock;
1044+
}
1045+
if (!gfs2_holder_queued(gh))
1046+
goto retry;
1047+
from->count = min(from->count, window_size);
1048+
}
1049+
10371050
if (inode == sdp->sd_rindex) {
10381051
struct gfs2_inode *m_ip = GFS2_I(sdp->sd_statfs_inode);
10391052

@@ -1060,17 +1073,8 @@ static ssize_t gfs2_file_buffered_write(struct kiocb *iocb,
10601073
goto out_unlock;
10611074

10621075
from->count = orig_count - written;
1063-
if (should_fault_in_pages(from, iocb, &prev_count, &window_size)) {
1064-
gfs2_holder_allow_demote(gh);
1065-
window_size -= fault_in_iov_iter_readable(from, window_size);
1066-
gfs2_holder_disallow_demote(gh);
1067-
if (window_size) {
1068-
from->count = min(from->count, window_size);
1069-
if (gfs2_holder_queued(gh))
1070-
goto retry_under_glock;
1071-
goto retry;
1072-
}
1073-
}
1076+
if (should_fault_in_pages(from, iocb, &prev_count, &window_size))
1077+
goto retry_under_glock;
10741078
out_unlock:
10751079
if (gfs2_holder_queued(gh))
10761080
gfs2_glock_dq(gh);

0 commit comments

Comments
 (0)