Commit Graph

497 Commits (09cfd3c52ea76f43b3cb15e570aeddf633d65e80)

Author SHA1 Message Date
Andreas Gruenbacher 6ab26555c9 gfs2: Add proper lockspace locking
GFS2 has been calling functions like dlm_lock() even after the lockspace
that these functions operate on has been released with
dlm_release_lockspace().  It has always assumed that those functions
would return -EINVAL in that case, but that was never guaranteed, and it
certainly is no longer the case since commit 4db41bf4f0 ("dlm: remove
ls_local_handle from struct dlm_ls").

To fix that, add proper lockspace locking.

Fixes: 3e11e53041 ("GFS2: ignore unlock failures after withdraw")
Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
Reviewed-by: Andrew Price <anprice@redhat.com>
2025-09-12 12:02:57 +02:00
Andreas Gruenbacher 47faf937da gfs2: Minor run_queue fixes
Provide a better description of why the GLF_DEMOTE_IN_PROGRESS flag
cannot be set.

Function do_xmote() may block, so make sure it isn't called when
nonblock is true.

Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
Reviewed-by: Andrew Price <anprice@redhat.com>
2025-09-12 12:02:53 +02:00
Andreas Gruenbacher cd493dcf4f gfs2: run_queue cleanup
Transform the code in run_queue() to make it more readable.  No change
in functionality.

Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
Reviewed-by: Andrew Price <anprice@redhat.com>
2025-09-12 12:02:50 +02:00
Andreas Gruenbacher 2045364497 gfs2: Simplify do_promote
While not immediately obvious, do_promote() returns whether or not there
are any active holders in the queue.  But the function description is
confusing, and this information is easy to come by for callers anyway,
so turn do_promote() into a void function.

Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
Reviewed-by: Andrew Price <anprice@redhat.com>
2025-09-12 12:02:45 +02:00
Andreas Gruenbacher bddb53b776 gfs2: Get rid of GLF_INVALIDATE_IN_PROGRESS
Get rid of the GLF_INVALIDATE_IN_PROGRESS flag: it was originally used
to indicate to add_to_queue() that the ->go_sync() and ->go_invalid()
operations were in progress, but as we have established in commit "gfs2:
Fix LM_FLAG_TRY* logic in add_to_queue", add_to_queue() has no need to
know.

Commit d99724c3c3 describes a race in which GLF_INVALIDATE_IN_PROGRESS
is used to serialize two processes which are both in do_xmote() at the
same time.  That analysis is wrong: the serialization happens via the
GLF_LOCK flag, which ensures that at most one glock operation can be
active at any time.

Fixes: d99724c3c3 ("gfs2: Close timing window with GLF_INVALIDATE_IN_PROGRESS")
Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
Reviewed-by: Andrew Price <anprice@redhat.com>
2025-09-12 12:02:41 +02:00
Andreas Gruenbacher 061df28b82 gfs2: Fix GLF_INVALIDATE_IN_PROGRESS flag clearing in do_xmote
Commit 865cc3e9cc ("gfs2: fix a deadlock on withdraw-during-mount")
added a statement to do_xmote() to clear the GLF_INVALIDATE_IN_PROGRESS
flag a second time after it has already been cleared.  Fix that.

Fixes: 865cc3e9cc ("gfs2: fix a deadlock on withdraw-during-mount")
Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
Reviewed-by: Andrew Price <anprice@redhat.com>
2025-09-12 12:02:38 +02:00
Andreas Gruenbacher 9b54770b68 gfs2: Remove duplicate check in do_xmote
In do_xmote(), remove the duplicate check for the ->go_sync and
->go_inval glock operations.  They are either both defined, or none of
them are.

Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
Reviewed-by: Andrew Price <anprice@redhat.com>
2025-09-12 12:02:31 +02:00
Andreas Gruenbacher 0c23e24164 gfs2: Fix LM_FLAG_TRY* logic in add_to_queue
The logic in add_to_queue() for determining whether a LM_FLAG_TRY or
LM_FLAG_TRY_1CB holder should be queued does not make any sense: we are
interested in wether or not the new operation will block behind an
existing or future holder in the queue, but the current code checks for
ongoing locking or ->go_inval() operations, which has little to do with
that.

Replace that code with something more sensible, remove the incorrect
add_to_queue() function annotations, remove the similarly misguided
do_error(gl, 0) call in do_xmote(), and add a missing comment to the
same call in do_promote().

Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
Reviewed-by: Andrew Price <anprice@redhat.com>
2025-09-12 12:02:28 +02:00
Andreas Gruenbacher 2b813a7288 gfs2: Remove DLM_LKF_ALTCW / DLM_LKF_ALTPR code
Commit 6802e3400f ("[GFS2] Clean up the glock core") stopped passing
the LM_FLAG_ANY flag down to gdlm_lock() (then gfs2_lm_lock()).  Since
then, gfs2 effectively hasn't been using dlm's DLM_LKF_ALTCW /
DLM_LKF_ALTPR flags, but the code still suggests that it does.  Recent
testing shows that those flags don't even work reliably anymore, so
instead of fixing code that hasn't been used since 2008, remove it.

In addition, clean up how the flags are passed to [gd]lm_lock().

Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
Reviewed-by: Andrew Price <anprice@redhat.com>
2025-09-12 12:02:25 +02:00
Andreas Gruenbacher fd70ab7155 gfs2: Further sanitize lock_dlm.c
The gl_req field and GLF_BLOCKING flag are only relevant to gdlm_lock(),
its callback gdlm_ast(), and their helpers, so set and clear them inside
lock_dlm.c.

Also, the LM_FLAG_ANY flag is relevant to gdlm_lock(), but do_xmote()
doesn't pass that flag down to gdlm_lock() as it should.  Fix that by
passing down all the flags.

In addition, document the effect of the LM_FLAG_ANY flag on locks held
in EX mode locally.

Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
Reviewed-by: Andrew Price <anprice@redhat.com>
2025-09-12 12:02:20 +02:00
Andreas Gruenbacher cd71804664 gfs2: Do not use atomic operations unnecessarily
The GLF_DEMOTE_IN_PROGRESS and GLF_LOCK flags and the glock refcount are
all protected by the glock spin lock, so there is no need for atomic
operations / barriers here.

Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
Reviewed-by: Andrew Price <anprice@redhat.com>
2025-09-12 12:02:18 +02:00
Andreas Gruenbacher 418c854759 gfs2: Partially revert "gfs2: do_xmote fixes"
When the lm_lock hook which calls dlm_lock() returns an error,
do_xmote() previously reported the error to the syslog ("lm_lock ret
%d\n") but otherwise ignored it during withdraws.  Commit 9947a06d29
("gfs2: do_xmote fixes") changed that to pass the error on to the glock
layer, but the error would then only result in an unconditional BUG() in
finish_xmote(), which doesn't help.  Instead, revert to the previous
behavior.

Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
Reviewed-by: Andrew Price <anprice@redhat.com>
2025-09-12 12:02:08 +02:00
Andreas Gruenbacher 4250e683de gfs2: Simplify refcounting in do_xmote
In do_xmote(), take the additional glock references close to where those
references are needed.  This will simplify the next commit.

Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
Reviewed-by: Andrew Price <anprice@redhat.com>
2025-09-12 12:02:06 +02:00
Andreas Gruenbacher 2309a01351 gfs2: do_xmote cleanup
Check for asynchronous completion and clear the GLF_PENDING_REPLY flag
earlier in do_xmote().  This will make future changes more readable.

Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
Reviewed-by: Andrew Price <anprice@redhat.com>
2025-09-12 12:02:02 +02:00
Colin Ian King aa94ad9ab2 gfs2: Remove space before newline
There is an extraneous space before a newline in a fs_err message.
Remove it

Signed-off-by: Colin Ian King <colin.i.king@gmail.com>
Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
Reviewed-by: Andrew Price <anprice@redhat.com>
2025-09-12 12:01:58 +02:00
Andreas Gruenbacher e7ffc0af0e gfs2: a minor finish_xmote cleanup
As a minor clean-up to commit 1fc05c8d84 ("gfs2: cancel timed-out
glock requests"), when a demote request is in progress in
finish_xmote(), there is no point in waking up the glock holder at the
head of the queue because the reply from dlm cannot be on behalf of that
glock holder.

Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
Reviewed-by: Andrew Price <anprice@redhat.com>
2025-07-15 04:20:40 +02:00
Andreas Gruenbacher 92cef39bb3 gfs2: simplify finish_xmote
As a follow-up to commit a431d49243 ("gfs2: Fix request cancelation
bug"), it turns out that any call to finish_xmote() is always followed
by a call to run_queue(), either

 * directly when glock_work_func() calls finish_xmote() before calling
   run_queue(), or

 * indirectly when do_xmote() calls finish_xmote() before calling
   gfs2_glock_queue_work(), which queues a call to glock_work_func() in
   work queue context,

so remove the code in finish_xmote() that duplicates the functionality
of run_queue().

In addition, the code this commit removes is missing a check for the
GLF_DEMOTE flag which indicates that no further promotes should be
performed, so if that code didn't get removed, that check would have to
be added.

Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
Reviewed-by: Andrew Price <anprice@redhat.com>
2025-07-15 04:20:40 +02:00
Andreas Gruenbacher 6e417b3eb8 gfs2: sanitize the gdlm_ast -> finish_xmote interface
When gdlm_ast() is called with a non-zero status code, this means that
the requested operation did not succeed and the current lock state
didn't change.  Turn that into a non-zero LM_OUT_* status code (with ret
& ~LM_OUT_ST_MASK != 0) instead of pretending that dlm returned the
current lock state.

That way, we can easily change finish_xmote() to only update
gl->gl_state when the state has actually changed.

Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
Reviewed-by: Andrew Price <anprice@redhat.com>
2025-07-15 04:20:40 +02:00
Andreas Gruenbacher 75bb2ddea9 gfs2: Minor do_xmote cancelation fix
Commit 6cb3b1c2df changed how finish_xmote() clears the GLF_LOCK flag,
but it failed to adjust the equivalent code in do_xmote().  Fix that.

Fixes: 6cb3b1c2df ("gfs2: Fix additional unlikely request cancelation race")
Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
2025-07-09 20:04:14 +02:00
Andreas Gruenbacher ae9f3bd825 gfs2: replace sd_aspace with sd_inode
Currently, sdp->sd_aspace and the per-inode metadata address spaces use
sb->s_bdev->bd_mapping->host as their ->host; folios in those address
spaces will thus appear to be on bdev rather than on gfs2 filesystems.
This is a problem because gfs2 doesn't support cgroup writeback
(SB_I_CGROUPWB), but bdev does.

Fix that by using a "dummy" gfs2 inode as ->host in those address
spaces.  When coming from a folio, folio->mapping->host->i_sb will then
be a gfs2 super block and the SB_I_CGROUPWB flag will not be set in
sb->s_iflags.

Based on a previous version from Bob Peterson from several years ago.
Thanks to Tetsuo Handa, Jan Kara, and Rafael Aquini for helping figure
this out.

Fixes: aaa2cacf81 ("writeback: add lockdep annotation to inode_to_wb()")
Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
2025-04-21 18:20:36 +02:00
Linus Torvalds ef479de65a gfs2 changes
- Fix two bugs related to locking request cancelation (locking request
   being retried instead of canceled; canceling the wrong locking
   request).
 
 - Prevent a race between inode creation and deferred delete analogous
   to commit ffd1cf0443 from 6.13.  This now allows to further simplify
   gfs2_evict_inode() without introducing mysterious problems.
 
 - When in inode delete should be verified / retried "later" but that
   isn't possible, skip the delete instead of carrying it out
   immediately.  This broke in 6.13.
 
 - More folio conversions from Matthew Wilcox (plus a fix from Dan
   Carpenter).
 
 - Various minor fixes and cleanups.
 -----BEGIN PGP SIGNATURE-----
 
 iQJIBAABCAAyFiEEJZs3krPW0xkhLMTc1b+f6wMTZToFAmfcehcUHGFncnVlbmJh
 QHJlZGhhdC5jb20ACgkQ1b+f6wMTZTqfZA//XPqzf4fuS3E/SAouuHb4/MX8vmsL
 kQozDnCdJqYokU/AUjpwsCTIROURi4Xjfwuj6rd1u/IFDruioX93X/m9iCGH9TeE
 owI+qs+qQ5ZJom+KpoNuGPUw+40qlCOfIx87P3bW6xagerMiyzCdTBc7cTB6lKBi
 NsSShK71uMMLNYEAXJKl7koc9fD9bn143uElH8CLXlomuQkY9QPOD5r4jCJIaPu2
 +RvlfF9zRYc2hYEjSh0daC4Arm1Y3B9Sin6YEIfXi/t53c5eQ1+Ttcw51t4RVBxx
 CSRVUUcDhCF6pof8YkJbPQVrCZqFzorisyUqMP+qE/VW8toFc6qJ9MzcMJwK0DNH
 aNjEK2s3qPCPU4/qM2V7J3dZMD3poJ8cHdAHFU6J5OVFems0kt8jHn8C/RV1KXm9
 Cy/IWupKCMaiMIaoANrAC3xED0KOT11dHBKpYVOQhSJIRJZ+kbjdqKik13HmUAUp
 2r/tlzZNG8hhfBLPCjA0Pz+pph6x/tJO1H24ooC5D24Gn83BKkS3QC/oBVok/I3Q
 /2g61gtVNUwIAxPDnl4IdSvvWHZeSTJRFYGRA13wGbG6I4SV9M4nS+4xrgb6D5DE
 dTRZiU22J+9OJQApnGi9ehOi/49yvySAyqAjVFx+LP+2tLCzj0mcvvLerkEG+V2c
 3WkiUVkLpph+8BA=
 =yUe1
 -----END PGP SIGNATURE-----

Merge tag 'gfs2-for-6.15' of git://git.kernel.org/pub/scm/linux/kernel/git/gfs2/linux-gfs2

Pull gfs2 updates from Andreas Gruenbacher:

 - Fix two bugs related to locking request cancelation (locking request
   being retried instead of canceled; canceling the wrong locking
   request)

 - Prevent a race between inode creation and deferred delete analogous
   to commit ffd1cf0443 from 6.13. This now allows to further simplify
   gfs2_evict_inode() without introducing mysterious problems

 - When in inode delete should be verified / retried "later" but that
   isn't possible, skip the delete instead of carrying it out
   immediately. This broke in 6.13

 - More folio conversions from Matthew Wilcox (plus a fix from Dan
   Carpenter)

 - Various minor fixes and cleanups

* tag 'gfs2-for-6.15' of git://git.kernel.org/pub/scm/linux/kernel/git/gfs2/linux-gfs2: (22 commits)
  gfs2: some comment clarifications
  gfs2: Fix a NULL vs IS_ERR() bug in gfs2_find_jhead()
  gfs2: Convert gfs2_meta_read_endio() to use a folio
  gfs2: Convert gfs2_end_log_write_bh() to work on a folio
  gfs2: Convert gfs2_find_jhead() to use a folio
  gfs2: Convert gfs2_jhead_pg_srch() to gfs2_jhead_folio_search()
  gfs2: Use b_folio in gfs2_check_magic()
  gfs2: Use b_folio in gfs2_submit_bhs()
  gfs2: Use b_folio in gfs2_trans_add_meta()
  gfs2: Use b_folio in gfs2_log_write_bh()
  gfs2: skip if we cannot defer delete
  gfs2: remove redundant warnings
  gfs2: minor evict fix
  gfs2: Prevent inode creation race (2)
  gfs2: Fix additional unlikely request cancelation race
  gfs2: Fix request cancelation bug
  gfs2: Check for empty queue in run_queue
  gfs2: Remove more dead code in add_to_queue
  gfs2: Replace GIF_DEFER_DELETE with GLF_DEFER_DELETE
  gfs2: glock holder GL_NOPID fix
  ...
2025-03-27 12:09:25 -07:00
Andreas Gruenbacher 79fe790a32 gfs2: remove redundant warnings
In glock_set_object() and glock_clear_object(), there is no need to
print the glock type and number when we dump the entire glock, anyway.

Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
2025-03-10 18:15:38 +01:00
Andreas Gruenbacher 9136cad723 gfs2: Prevent inode creation race (2)
In gfs2_try_evict(), we try grabbing the inode to evict, we try to evict
it, and then we try grabbing it again to see if it still exists.  There
is no guarantee that we will end up with the same inode both times; the
inode validity check that commit ffd1cf0443 ("gfs2: Prevent inode
creation race") added to the first grab is actually needed both times.

(To avoid code duplication, add a grab_existing_inode() helper.)

Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
2025-03-10 18:15:38 +01:00
Andreas Gruenbacher 6cb3b1c2df gfs2: Fix additional unlikely request cancelation race
In gfs2_glock_dq(), we must drop the glock spin lock before calling
->lm_cancel, but this means that in the meantime, the operation we are
trying to cancel could complete.  If the operation completes
unsuccessfully, another holder can end up at the head of the queue and
another ->lm_lock operation can get started.  In this case, we would end
up canceling that second operation by accident.

To prevent that, introduce a new GLF_CANCELING flag.  Set that flag in
gfs2_glock_dq() when trying to cancel an operation.  When seeing that
flag, finish_xmote() will then keep the GLF_LOCK flag set to prevent
other glock operations from taking place.  gfs2_glock_dq() then
completes the cancelation attempt by clearing GLF_LOCK and
GLF_CANCELING.

In addition, add a missing GLF_DEMOTE_IN_PROGRESS check in
gfs2_glock_dq() to make sure that we won't accidentally cancel a demote
request.

Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
2025-03-10 18:15:38 +01:00
Andreas Gruenbacher a431d49243 gfs2: Fix request cancelation bug
In finish_xmote(), when a locking request is canceled, the corresponding
holder is moved to the tail of the holders list instead of being
dequeued immediately.  When there is only a single holder, the canceled
locking request is then immediately repeated.  This makes no sense; it
looks like another remnant of LM_FLAG_PRIORITY support.

Instead, dequeue canceled holders and proceed with the next holder in
finish_xmote().  We can then easily detect in gfs2_glock_dq() when a
holder has been canceled.

Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
2025-03-10 18:15:38 +01:00
Andreas Gruenbacher d838605fea gfs2: Check for empty queue in run_queue
In run_queue(), check if the queue of pending requests is empty instead
of blindly assuming that it won't be.

Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
2025-03-10 18:15:38 +01:00
Andreas Gruenbacher 0360faca5d gfs2: Remove more dead code in add_to_queue
Remove some more dead code in add_to_queue() that commit 0b93bac227
("gfs2: Remove LM_FLAG_PRIORITY flag") has rendered obsolete.  This is a
continuation of commit 3302764610057 ("gfs2: remove dead code in
add_to_queue"); no functional change.

Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
2025-03-10 18:15:38 +01:00
Andreas Gruenbacher 3774f53d7f gfs2: Replace GIF_DEFER_DELETE with GLF_DEFER_DELETE
Having this flag attached to the iopen glock instead of the inode is
much simpler; it eliminates a protential weird race in gfs2_try_evict().

Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
2025-03-10 18:15:38 +01:00
Andreas Gruenbacher f83f897614 gfs2: glock holder GL_NOPID fix
Glocks are always actively acquired by processes, but as indicated by
the GL_NOPID holder flag, some of them are then associated with objects
like cached inodes rather than the process that acquired them.  As such,
for those glock holders, it makes little sense to dump which processes
originally acquired them.

Therefore, gfs2 is trying to hide the identity of the processes that
acquired those glocks.  The code for doing that is incorrect though, so
fix it.

Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
2025-03-10 18:15:38 +01:00
Andreas Gruenbacher 8bbfde0875 gfs2: Add GLF_PENDING_REPLY flag
Introduce a new GLF_PENDING_REPLY flag to indicate that a reply from DLM
is expected.  Include that flag in glock dumps to show more clearly
what's going on.  (When the GLF_PENDING_REPLY flag is set, the GLF_LOCK
flag will also be set but the GLF_LOCK flag alone isn't sufficient to
tell that we are waiting for a DLM reply.)

Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
2025-03-10 18:15:38 +01:00
Andreas Gruenbacher bb504b4d64
lockref: remove count argument of lockref_init
All users of lockref_init() now initialize the count to 1, so hardcode
that and remove the count argument.

Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
Link: https://lore.kernel.org/r/20250130135624.1899988-4-agruenba@redhat.com
Signed-off-by: Christian Brauner <brauner@kernel.org>
2025-02-07 10:27:25 +01:00
Andreas Gruenbacher d9b3a3c70d
gfs2: use lockref_init for gl_lockref
Move the initialization of gl_lockref from gfs2_init_glock_once() to
gfs2_glock_get().  This allows to use lockref_init() there.

Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
Link: https://lore.kernel.org/r/20250130135624.1899988-2-agruenba@redhat.com
Signed-off-by: Christian Brauner <brauner@kernel.org>
2025-02-07 10:27:25 +01:00
Linus Torvalds ff2a7a064a gfs2 changes
- Fix the code that cleans up left-over unlinked files.  Various fixes
   and minor improvements in deleting files cached or held open remotely.
 
 - Simplify the use of dlm's DLM_LKF_QUECVT flag.
 
 - A few other minor cleanups.
 -----BEGIN PGP SIGNATURE-----
 
 iQJIBAABCAAyFiEEJZs3krPW0xkhLMTc1b+f6wMTZToFAmdESTYUHGFncnVlbmJh
 QHJlZGhhdC5jb20ACgkQ1b+f6wMTZTpdyA/9EWDxx2Y6JeVeAC+J138pSOYqHtwn
 wLtMeTdwbycW6M8V5kyW3vCh+lLLS6s0dZuwn2Xv8jx5QytrD4c51Wj3bRYjuidM
 Zt0L+wohOQISvL1+AViYuIns2pzQQvNZUC2aAVr9J3KGhdIFonbU6PdLOeEN0cZe
 R08Nseux9oJ/geaKJ3jh/ReX2VZehp2WAaQ4I+PoQkkNflBULPkyysxjkv9sc8tW
 9hN1sK7dk/U5OLKr4H6SSi1Uu6N6Wek0x2zo4NxTRqyfBiRXYtZYnXPkdftuB+6N
 M7N2dAIuhnXiAhQdo7OOe9hZZVXTFhmeQK1tyTsw/FZkQJNMX+bdBn4g7NV94drz
 CpTliqm+Z5dTnkSdS4cIozkQZ7zID1eibX8uF7QsnozBWm7bjbW6fi7a+z+u5ykN
 hsWanoMKhH1524oNKaiSjIxT0b1oda114DJQVpdU68HjkyHf5l0GXUTcVpg0dxs3
 peXhpZ+CjHbaTMXl5xqGOucD+ACPhMOGXPAX1lF2bIcfbLqgbTVn0fMMUYWeb8j1
 medJtQ0itwpiCHZTl62xUOLEOCqCiS5J1/TjrwNuJ1HLJ5JP1UePNl5kjT9nDfsA
 KXB31sKFfPX99rPVYJgjLXPgRLwslcniSHOg9p+bWwq7ZI1PSxPSauUgtKZpSe6A
 E3YfnIxjPxRMKks=
 =BP41
 -----END PGP SIGNATURE-----

Merge tag 'gfs2-for-6.13' of git://git.kernel.org/pub/scm/linux/kernel/git/gfs2/linux-gfs2

Pull gfs2 updates from Andreas Gruenbacher:

 - Fix the code that cleans up left-over unlinked files.

   Various fixes and minor improvements in deleting files cached or held
   open remotely.

 - Simplify the use of dlm's DLM_LKF_QUECVT flag.

 - A few other minor cleanups.

* tag 'gfs2-for-6.13' of git://git.kernel.org/pub/scm/linux/kernel/git/gfs2/linux-gfs2: (21 commits)
  gfs2: Prevent inode creation race
  gfs2: Only defer deletes when we have an iopen glock
  gfs2: Simplify DLM_LKF_QUECVT use
  gfs2: gfs2_evict_inode clarification
  gfs2: Make gfs2_inode_refresh static
  gfs2: Use get_random_u32 in gfs2_orlov_skip
  gfs2: Randomize GLF_VERIFY_DELETE work delay
  gfs2: Use mod_delayed_work in gfs2_queue_try_to_evict
  gfs2: Update to the evict / remote delete documentation
  gfs2: Call gfs2_queue_verify_delete from gfs2_evict_inode
  gfs2: Clean up delete work processing
  gfs2: Minor delete_work_func cleanup
  gfs2: Return enum evict_behavior from gfs2_upgrade_iopen_glock
  gfs2: Rename dinode_demise to evict_behavior
  gfs2: Rename GIF_{DEFERRED -> DEFER}_DELETE
  gfs2: Faster gfs2_upgrade_iopen_glock wakeups
  KMSAN: uninit-value in inode_go_dump (5)
  gfs2: Fix unlinked inode cleanup
  gfs2: Allow immediate GLF_VERIFY_DELETE work
  gfs2: Initialize gl_no_formal_ino earlier
  ...
2024-11-26 12:34:50 -08:00
Andreas Gruenbacher ffd1cf0443 gfs2: Prevent inode creation race
When a request to evict an inode comes in over the network, we are
trying to grab an inode reference via the iopen glock's gl_object
pointer.  There is a very small probability that by the time such a
request comes in, inode creation hasn't completed and the I_NEW flag is
still set.  To deal with that, wait for the inode and then check if
inode creation was successful.

Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
2024-11-19 13:05:41 +01:00
Andreas Gruenbacher 085e423b4d gfs2: Randomize GLF_VERIFY_DELETE work delay
Randomize the delay of GLF_VERIFY_DELETE work.  This avoids thundering
herd problems when multiple nodes schedule that kind of work in response
to an inode being unlinked remotely.

Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
2024-11-05 12:39:29 +01:00
Andreas Gruenbacher f6ca45e3d2 gfs2: Use mod_delayed_work in gfs2_queue_try_to_evict
In the unlikely case that we're trying to queue GLF_TRY_TO_EVICT work
for an inode that already has GLF_VERIFY_DELETE work queued, we want to
make sure that the GLF_TRY_TO_EVICT work gets scheduled immediately
instead of waiting for the delayed work timer to expire.

Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
2024-11-05 12:39:29 +01:00
Andreas Gruenbacher a6033333cc gfs2: Update to the evict / remote delete documentation
Try to be a bit more clear and remove some duplications.  We cannot
actually get rid of the verification step eventually, so remove the
comment saying so.

Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
2024-11-05 12:39:29 +01:00
Andreas Gruenbacher 8c21c2c71e gfs2: Call gfs2_queue_verify_delete from gfs2_evict_inode
Move calls to gfs2_queue_verify_delete() into gfs2_evict_inode().

Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
2024-11-05 12:39:29 +01:00
Andreas Gruenbacher 0baa10b60c gfs2: Clean up delete work processing
Function delete_work_func() was previously assuming that the
GLF_TRY_TO_EVICT and GLF_VERIFY_DELETE flags won't both be set at the
same time, but there probably are races in which that can happen, so
handle that case correctly.

Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
2024-11-05 12:39:29 +01:00
Andreas Gruenbacher b4100457d0 gfs2: Minor delete_work_func cleanup
Move those definitions into the the scope in which they are used.

Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
2024-11-05 12:39:28 +01:00
Andreas Gruenbacher 9fb794aac6 gfs2: Rename GIF_{DEFERRED -> DEFER}_DELETE
The GIF_DEFERRED_DELETE flag indicates an action that gfs2_evict_inode()
should take, so rename the flag to GIF_DEFER_DELETE to clarify.

Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
2024-11-05 12:39:28 +01:00
Andreas Gruenbacher ee51baa817 gfs2: Faster gfs2_upgrade_iopen_glock wakeups
Move function needs_demote() to glock.h and rename it to
glock_needs_demote().  In handle_callback(), wake up the glock when
setting the GLF_PENDING_DEMOTE flag as well.  (Setting the GLF_DEMOTE
flag already triggered a wake-up.)

With that, check for glock_needs_demote() in gfs2_upgrade_iopen_glock()
to wake up when either of those flags is set for the inode glock: the
faster we can react to contention, the better.

The GLF_PENDING_DEMOTE flag is only used for inode glocks (see
gfs2_glock_cb()) so it's okay to only check for the GLF_DEMOTE flag in
gfs2_drop_inode().  Still, using glock_needs_demote() there as well
makes the code a little easier to read.

Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
2024-11-05 12:39:28 +01:00
Al Viro 8fd3395ec9 get rid of ...lookup...fdget_rcu() family
Once upon a time, predecessors of those used to do file lookup
without bumping a refcount, provided that caller held rcu_read_lock()
across the lookup and whatever it wanted to read from the struct
file found.  When struct file allocation switched to SLAB_TYPESAFE_BY_RCU,
that stopped being feasible and these primitives started to bump the
file refcount for lookup result, requiring the caller to call fput()
afterwards.

But that turned them pointless - e.g.
	rcu_read_lock();
	file = lookup_fdget_rcu(fd);
	rcu_read_unlock();
is equivalent to
	file = fget_raw(fd);
and all callers of lookup_fdget_rcu() are of that form.  Similarly,
task_lookup_fdget_rcu() calls can be replaced with calling fget_task().
task_lookup_next_fdget_rcu() doesn't have direct counterparts, but
its callers would be happier if we replaced it with an analogue that
deals with RCU internally.

Reviewed-by: Christian Brauner <brauner@kernel.org>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
2024-10-07 13:34:41 -04:00
Andreas Gruenbacher 7c6f714d88 gfs2: Fix unlinked inode cleanup
Before commit f0e56edc2e ("gfs2: Split the two kinds of glock "delete"
work"), function delete_work_func() was used to trigger the eviction of
in-memory inodes from remote as well as deleting unlinked inodes at a
later point.  These two kinds of work were then split into two kinds of
work, and the two places in the code were deferred deletion of inodes is
required accidentally ended up queuing the wrong kind of work.  This
caused unlinked inodes to be left behind, which could in the worst case
fill up filesystems and require a filesystem check to recover.

Fix that by queuing the right kind of work in try_rgrp_unlink() and
gfs2_drop_inode().

Fixes: f0e56edc2e ("gfs2: Split the two kinds of glock "delete" work")
Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
2024-09-25 17:11:49 +02:00
Andreas Gruenbacher 160bc9555d gfs2: Allow immediate GLF_VERIFY_DELETE work
Add an argument to gfs2_queue_verify_delete() that allows it to queue
GLF_VERIFY_DELETE work for immediate execution.  This is used in the
next patch.

Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
2024-09-25 17:08:23 +02:00
Andreas Gruenbacher 1072b3aa68 gfs2: Initialize gl_no_formal_ino earlier
Set gl_no_formal_ino of the iopen glock to the generation of the
associated inode (ip->i_no_formal_ino) as soon as that value is known.
This saves us from setting it later, possibly repeatedly, when queuing
GLF_VERIFY_DELETE work.

Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
2024-09-24 19:03:33 +02:00
Andreas Gruenbacher 820ce8ed53 gfs2: Rename GLF_VERIFY_EVICT to GLF_VERIFY_DELETE
Rename the GLF_VERIFY_EVICT flag to GLF_VERIFY_DELETE: that flag
indicates that we want to delete an inode / verify that it has been
deleted.

To match, rename gfs2_queue_verify_evict() to
gfs2_queue_verify_delete().

Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
2024-09-24 16:44:22 +02:00
Julian Sun 6cb9df81a2 gfs2: fix double destroy_workqueue error
When gfs2_fill_super() fails, destroy_workqueue() is called within
gfs2_gl_hash_clear(), and the subsequent code path calls
destroy_workqueue() on the same work queue again.

This issue can be fixed by setting the work queue pointer to NULL after
the first destroy_workqueue() call and checking for a NULL pointer
before attempting to destroy the work queue again.

Reported-by: syzbot+d34c2a269ed512c531b0@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=d34c2a269ed512c531b0
Fixes: 30e388d573 ("gfs2: Switch to a per-filesystem glock workqueue")
Cc: stable@vger.kernel.org
Signed-off-by: Julian Sun <sunjunchao2870@gmail.com>
Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
2024-08-20 16:27:22 +02:00
Andreas Gruenbacher 4117efd5c9 gfs2: Minor gfs2_glock_cb cleanup
In gfs2_glock_cb(), we only need to calculate the glock hold time for
inode glocks; the value is unused otherwise.

Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
2024-08-20 16:06:43 +02:00
Andreas Gruenbacher f75efefb6d gfs2: Clean up glock demote logic
The logic for determining when to demote a glock in glock_work_func(),
introduced in commit 7cf8dcd3b6 ("GFS2: Automatically adjust glock min
hold time"), doesn't make sense: inode glocks have a minimum hold time
that delays demotion, while all other glocks are expected to be demoted
immediately.  Instead of demoting non-inode glocks immediately,
glock_work_func() schedules glock work for them to be demoted, however.
Get rid of that unnecessary indirection.

Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
2024-07-09 10:40:03 +02:00