Skip to content

Commit b924bda

Browse files
author
Andreas Gruenbacher
committed
gfs2: Move the inode glock locking to gfs2_file_buffered_write
So far, for buffered writes, we were taking the inode glock in gfs2_iomap_begin and dropping it in gfs2_iomap_end with the intention of not holding the inode glock while iomap_write_actor faults in user pages. It turns out that iomap_write_actor is called inside iomap_begin ... iomap_end, so the user pages were still faulted in while holding the inode glock and the locking code in iomap_begin / iomap_end was completely pointless. Move the locking into gfs2_file_buffered_write instead. We'll take care of the potential deadlocks due to faulting in user pages while holding a glock in a subsequent patch. Signed-off-by: Andreas Gruenbacher <[email protected]>
1 parent dc73290 commit b924bda

File tree

2 files changed

+28
-59
lines changed

2 files changed

+28
-59
lines changed

fs/gfs2/bmap.c

Lines changed: 1 addition & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -961,46 +961,6 @@ static int __gfs2_iomap_get(struct inode *inode, loff_t pos, loff_t length,
961961
goto out;
962962
}
963963

964-
static int gfs2_write_lock(struct inode *inode)
965-
{
966-
struct gfs2_inode *ip = GFS2_I(inode);
967-
struct gfs2_sbd *sdp = GFS2_SB(inode);
968-
int error;
969-
970-
gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &ip->i_gh);
971-
error = gfs2_glock_nq(&ip->i_gh);
972-
if (error)
973-
goto out_uninit;
974-
if (&ip->i_inode == sdp->sd_rindex) {
975-
struct gfs2_inode *m_ip = GFS2_I(sdp->sd_statfs_inode);
976-
977-
error = gfs2_glock_nq_init(m_ip->i_gl, LM_ST_EXCLUSIVE,
978-
GL_NOCACHE, &m_ip->i_gh);
979-
if (error)
980-
goto out_unlock;
981-
}
982-
return 0;
983-
984-
out_unlock:
985-
gfs2_glock_dq(&ip->i_gh);
986-
out_uninit:
987-
gfs2_holder_uninit(&ip->i_gh);
988-
return error;
989-
}
990-
991-
static void gfs2_write_unlock(struct inode *inode)
992-
{
993-
struct gfs2_inode *ip = GFS2_I(inode);
994-
struct gfs2_sbd *sdp = GFS2_SB(inode);
995-
996-
if (&ip->i_inode == sdp->sd_rindex) {
997-
struct gfs2_inode *m_ip = GFS2_I(sdp->sd_statfs_inode);
998-
999-
gfs2_glock_dq_uninit(&m_ip->i_gh);
1000-
}
1001-
gfs2_glock_dq_uninit(&ip->i_gh);
1002-
}
1003-
1004964
static int gfs2_iomap_page_prepare(struct inode *inode, loff_t pos,
1005965
unsigned len)
1006966
{
@@ -1118,11 +1078,6 @@ static int gfs2_iomap_begin_write(struct inode *inode, loff_t pos,
11181078
return ret;
11191079
}
11201080

1121-
static inline bool gfs2_iomap_need_write_lock(unsigned flags)
1122-
{
1123-
return (flags & IOMAP_WRITE) && !(flags & IOMAP_DIRECT);
1124-
}
1125-
11261081
static int gfs2_iomap_begin(struct inode *inode, loff_t pos, loff_t length,
11271082
unsigned flags, struct iomap *iomap,
11281083
struct iomap *srcmap)
@@ -1135,12 +1090,6 @@ static int gfs2_iomap_begin(struct inode *inode, loff_t pos, loff_t length,
11351090
iomap->flags |= IOMAP_F_BUFFER_HEAD;
11361091

11371092
trace_gfs2_iomap_start(ip, pos, length, flags);
1138-
if (gfs2_iomap_need_write_lock(flags)) {
1139-
ret = gfs2_write_lock(inode);
1140-
if (ret)
1141-
goto out;
1142-
}
1143-
11441093
ret = __gfs2_iomap_get(inode, pos, length, flags, iomap, &mp);
11451094
if (ret)
11461095
goto out_unlock;
@@ -1168,10 +1117,7 @@ static int gfs2_iomap_begin(struct inode *inode, loff_t pos, loff_t length,
11681117
ret = gfs2_iomap_begin_write(inode, pos, length, flags, iomap, &mp);
11691118

11701119
out_unlock:
1171-
if (ret && gfs2_iomap_need_write_lock(flags))
1172-
gfs2_write_unlock(inode);
11731120
release_metapath(&mp);
1174-
out:
11751121
trace_gfs2_iomap_end(ip, iomap, ret);
11761122
return ret;
11771123
}
@@ -1219,15 +1165,11 @@ static int gfs2_iomap_end(struct inode *inode, loff_t pos, loff_t length,
12191165
}
12201166

12211167
if (unlikely(!written))
1222-
goto out_unlock;
1168+
return 0;
12231169

12241170
if (iomap->flags & IOMAP_F_SIZE_CHANGED)
12251171
mark_inode_dirty(inode);
12261172
set_bit(GLF_DIRTY, &ip->i_gl->gl_flags);
1227-
1228-
out_unlock:
1229-
if (gfs2_iomap_need_write_lock(flags))
1230-
gfs2_write_unlock(inode);
12311173
return 0;
12321174
}
12331175

fs/gfs2/file.c

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -880,13 +880,40 @@ static ssize_t gfs2_file_buffered_write(struct kiocb *iocb, struct iov_iter *fro
880880
{
881881
struct file *file = iocb->ki_filp;
882882
struct inode *inode = file_inode(file);
883+
struct gfs2_inode *ip = GFS2_I(inode);
884+
struct gfs2_sbd *sdp = GFS2_SB(inode);
883885
ssize_t ret;
884886

887+
gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &ip->i_gh);
888+
ret = gfs2_glock_nq(&ip->i_gh);
889+
if (ret)
890+
goto out_uninit;
891+
892+
if (inode == sdp->sd_rindex) {
893+
struct gfs2_inode *m_ip = GFS2_I(sdp->sd_statfs_inode);
894+
895+
ret = gfs2_glock_nq_init(m_ip->i_gl, LM_ST_EXCLUSIVE,
896+
GL_NOCACHE, &m_ip->i_gh);
897+
if (ret)
898+
goto out_unlock;
899+
}
900+
885901
current->backing_dev_info = inode_to_bdi(inode);
886902
ret = iomap_file_buffered_write(iocb, from, &gfs2_iomap_ops);
887903
current->backing_dev_info = NULL;
888904
if (ret > 0)
889905
iocb->ki_pos += ret;
906+
907+
if (inode == sdp->sd_rindex) {
908+
struct gfs2_inode *m_ip = GFS2_I(sdp->sd_statfs_inode);
909+
910+
gfs2_glock_dq_uninit(&m_ip->i_gh);
911+
}
912+
913+
out_unlock:
914+
gfs2_glock_dq(&ip->i_gh);
915+
out_uninit:
916+
gfs2_holder_uninit(&ip->i_gh);
890917
return ret;
891918
}
892919

0 commit comments

Comments
 (0)