1 |
From 82e938bd5382b322ce81e6cb8fd030987f2da022 Mon Sep 17 00:00:00 2001 |
2 |
From: Andreas Gruenbacher <agruenba@redhat.com> |
3 |
Date: Wed, 25 Nov 2020 23:37:18 +0100 |
4 |
Subject: [PATCH 117/150] gfs2: Upgrade shared glocks for atime updates |
5 |
|
6 |
Commit 20f829999c38 ("gfs2: Rework read and page fault locking") lifted |
7 |
the glock lock taking from the low-level ->readpage and ->readahead |
8 |
address space operations to the higher-level ->read_iter file and |
9 |
->fault vm operations. The glocks are still taken in LM_ST_SHARED mode |
10 |
only. On filesystems mounted without the noatime option, ->read_iter |
11 |
sometimes needs to update the atime as well, though. Right now, this |
12 |
leads to a failed locking mode assertion in gfs2_dirty_inode. |
13 |
|
14 |
Fix that by introducing a new update_time inode operation. There, if |
15 |
the glock is held non-exclusively, upgrade it to an exclusive lock. |
16 |
|
17 |
Reported-by: Alexander Aring <aahringo@redhat.com> |
18 |
Fixes: 20f829999c38 ("gfs2: Rework read and page fault locking") |
19 |
Cc: stable@vger.kernel.org # v5.8+ |
20 |
Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com> |
21 |
--- |
22 |
fs/gfs2/inode.c | 21 +++++++++++++++++++++ |
23 |
1 file changed, 21 insertions(+) |
24 |
|
25 |
diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c |
26 |
index 077ccb1b3ccc..eed1a1bac6f6 100644 |
27 |
--- a/fs/gfs2/inode.c |
28 |
+++ b/fs/gfs2/inode.c |
29 |
@@ -2116,6 +2116,25 @@ loff_t gfs2_seek_hole(struct file *file, loff_t offset) |
30 |
return vfs_setpos(file, ret, inode->i_sb->s_maxbytes); |
31 |
} |
32 |
|
33 |
+static int gfs2_update_time(struct inode *inode, struct timespec64 *time, |
34 |
+ int flags) |
35 |
+{ |
36 |
+ struct gfs2_inode *ip = GFS2_I(inode); |
37 |
+ struct gfs2_glock *gl = ip->i_gl; |
38 |
+ struct gfs2_holder *gh; |
39 |
+ int error; |
40 |
+ |
41 |
+ gh = gfs2_glock_is_locked_by_me(gl); |
42 |
+ if (gh && !gfs2_glock_is_held_excl(gl)) { |
43 |
+ gfs2_glock_dq(gh); |
44 |
+ gfs2_holder_reinit(LM_ST_EXCLUSIVE, 0, gh); |
45 |
+ error = gfs2_glock_nq(gh); |
46 |
+ if (error) |
47 |
+ return error; |
48 |
+ } |
49 |
+ return generic_update_time(inode, time, flags); |
50 |
+} |
51 |
+ |
52 |
const struct inode_operations gfs2_file_iops = { |
53 |
.permission = gfs2_permission, |
54 |
.setattr = gfs2_setattr, |
55 |
@@ -2124,6 +2143,7 @@ const struct inode_operations gfs2_file_iops = { |
56 |
.fiemap = gfs2_fiemap, |
57 |
.get_acl = gfs2_get_acl, |
58 |
.set_acl = gfs2_set_acl, |
59 |
+ .update_time = gfs2_update_time, |
60 |
}; |
61 |
|
62 |
const struct inode_operations gfs2_dir_iops = { |
63 |
@@ -2143,6 +2163,7 @@ const struct inode_operations gfs2_dir_iops = { |
64 |
.fiemap = gfs2_fiemap, |
65 |
.get_acl = gfs2_get_acl, |
66 |
.set_acl = gfs2_set_acl, |
67 |
+ .update_time = gfs2_update_time, |
68 |
.atomic_open = gfs2_atomic_open, |
69 |
}; |
70 |
|
71 |
-- |
72 |
2.29.2 |
73 |
|