Skip to content

Commit b7ee881

Browse files
committed
Merge tag 'gfs2-v6.2-rc5-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/gfs2/linux-gfs2
Pull gfs2 updates from Andreas Gruenbacher: - Fix a race when disassociating inodes from their glocks after iget_failed() - On filesystems with a block size smaller than the page size, make sure that ->writepages() writes out all buffers of journaled inodes - Various improvements to the way the delete workqueue is drained to speed up unmount and prevent leftover inodes. At unmount time, evict deleted inodes cooperatively across the cluster to avoid unnecessary timeouts - Various minor cleanups and fixes * tag 'gfs2-v6.2-rc5-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/gfs2/linux-gfs2: gfs2: Convert gfs2_page_add_databufs to folios gfs2: jdata writepage fix gfs2: Improve gfs2_make_fs_rw error handling Revert "GFS2: free disk inode which is deleted by remote node -V2" gfs2: Evict inodes cooperatively gfs2: Flush delete work before shrinking inode cache gfs2: Cease delete work during unmount gfs2: Add SDF_DEACTIVATING super block flag gfs2: check gl_object in rgrp glops gfs2: Split the two kinds of glock "delete" work gfs2: Move delete workqueue into super block gfs2: Get rid of GLF_PENDING_DELETE flag gfs2: Make glock lru list scanning safer gfs2: Clean up gfs2_scan_glock_lru gfs2: Improve gfs2_upgrade_iopen_glock comment gfs2: gl_object races fix
2 parents 28e3352 + c1b0c3c commit b7ee881

File tree

13 files changed

+204
-127
lines changed

13 files changed

+204
-127
lines changed

fs/gfs2/aops.c

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -37,10 +37,10 @@
3737
#include "aops.h"
3838

3939

40-
void gfs2_page_add_databufs(struct gfs2_inode *ip, struct page *page,
41-
unsigned int from, unsigned int len)
40+
void gfs2_trans_add_databufs(struct gfs2_inode *ip, struct folio *folio,
41+
unsigned int from, unsigned int len)
4242
{
43-
struct buffer_head *head = page_buffers(page);
43+
struct buffer_head *head = folio_buffers(folio);
4444
unsigned int bsize = head->b_size;
4545
struct buffer_head *bh;
4646
unsigned int to = from + len;
@@ -127,15 +127,14 @@ static int __gfs2_jdata_writepage(struct page *page, struct writeback_control *w
127127
{
128128
struct inode *inode = page->mapping->host;
129129
struct gfs2_inode *ip = GFS2_I(inode);
130-
struct gfs2_sbd *sdp = GFS2_SB(inode);
131130

132131
if (PageChecked(page)) {
133132
ClearPageChecked(page);
134133
if (!page_has_buffers(page)) {
135134
create_empty_buffers(page, inode->i_sb->s_blocksize,
136135
BIT(BH_Dirty)|BIT(BH_Uptodate));
137136
}
138-
gfs2_page_add_databufs(ip, page, 0, sdp->sd_vfs->s_blocksize);
137+
gfs2_trans_add_databufs(ip, page_folio(page), 0, PAGE_SIZE);
139138
}
140139
return gfs2_write_jdata_page(page, wbc);
141140
}

fs/gfs2/aops.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
#include "incore.h"
1010

1111
extern void adjust_fs_space(struct inode *inode);
12-
extern void gfs2_page_add_databufs(struct gfs2_inode *ip, struct page *page,
13-
unsigned int from, unsigned int len);
12+
extern void gfs2_trans_add_databufs(struct gfs2_inode *ip, struct folio *folio,
13+
unsigned int from, unsigned int len);
1414

1515
#endif /* __AOPS_DOT_H__ */

fs/gfs2/bmap.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -985,8 +985,8 @@ static void gfs2_iomap_put_folio(struct inode *inode, loff_t pos,
985985
struct gfs2_sbd *sdp = GFS2_SB(inode);
986986

987987
if (!gfs2_is_stuffed(ip))
988-
gfs2_page_add_databufs(ip, &folio->page, offset_in_page(pos),
989-
copied);
988+
gfs2_trans_add_databufs(ip, folio, offset_in_folio(folio, pos),
989+
copied);
990990

991991
folio_unlock(folio);
992992
folio_put(folio);

fs/gfs2/dentry.c

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -83,26 +83,8 @@ static int gfs2_dhash(const struct dentry *dentry, struct qstr *str)
8383
return 0;
8484
}
8585

86-
static int gfs2_dentry_delete(const struct dentry *dentry)
87-
{
88-
struct gfs2_inode *ginode;
89-
90-
if (d_really_is_negative(dentry))
91-
return 0;
92-
93-
ginode = GFS2_I(d_inode(dentry));
94-
if (!gfs2_holder_initialized(&ginode->i_iopen_gh))
95-
return 0;
96-
97-
if (test_bit(GLF_DEMOTE, &ginode->i_iopen_gh.gh_gl->gl_flags))
98-
return 1;
99-
100-
return 0;
101-
}
102-
10386
const struct dentry_operations gfs2_dops = {
10487
.d_revalidate = gfs2_drevalidate,
10588
.d_hash = gfs2_dhash,
106-
.d_delete = gfs2_dentry_delete,
10789
};
10890

fs/gfs2/glock.c

Lines changed: 62 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,6 @@ static void handle_callback(struct gfs2_glock *gl, unsigned int state,
6767

6868
static struct dentry *gfs2_root;
6969
static struct workqueue_struct *glock_workqueue;
70-
struct workqueue_struct *gfs2_delete_workqueue;
7170
static LIST_HEAD(lru_list);
7271
static atomic_t lru_count = ATOMIC_INIT(0);
7372
static DEFINE_SPINLOCK(lru_lock);
@@ -274,9 +273,8 @@ static void __gfs2_glock_put(struct gfs2_glock *gl)
274273
struct address_space *mapping = gfs2_glock2aspace(gl);
275274

276275
lockref_mark_dead(&gl->gl_lockref);
277-
278-
gfs2_glock_remove_from_lru(gl);
279276
spin_unlock(&gl->gl_lockref.lock);
277+
gfs2_glock_remove_from_lru(gl);
280278
GLOCK_BUG_ON(gl, !list_empty(&gl->gl_holders));
281279
if (mapping) {
282280
truncate_inode_pages_final(mapping);
@@ -883,6 +881,7 @@ void glock_set_object(struct gfs2_glock *gl, void *object)
883881
/**
884882
* glock_clear_object - clear the gl_object field of a glock
885883
* @gl: the glock
884+
* @object: object the glock currently points at
886885
*/
887886
void glock_clear_object(struct gfs2_glock *gl, void *object)
888887
{
@@ -892,8 +891,7 @@ void glock_clear_object(struct gfs2_glock *gl, void *object)
892891
prev_object = gl->gl_object;
893892
gl->gl_object = NULL;
894893
spin_unlock(&gl->gl_lockref.lock);
895-
if (gfs2_assert_warn(gl->gl_name.ln_sbd,
896-
prev_object == object || prev_object == NULL)) {
894+
if (gfs2_assert_warn(gl->gl_name.ln_sbd, prev_object == object)) {
897895
pr_warn("glock=%u/%llx\n",
898896
gl->gl_name.ln_type,
899897
(unsigned long long)gl->gl_name.ln_number);
@@ -977,6 +975,26 @@ static bool gfs2_try_evict(struct gfs2_glock *gl)
977975
return evicted;
978976
}
979977

978+
bool gfs2_queue_try_to_evict(struct gfs2_glock *gl)
979+
{
980+
struct gfs2_sbd *sdp = gl->gl_name.ln_sbd;
981+
982+
if (test_and_set_bit(GLF_TRY_TO_EVICT, &gl->gl_flags))
983+
return false;
984+
return queue_delayed_work(sdp->sd_delete_wq,
985+
&gl->gl_delete, 0);
986+
}
987+
988+
static bool gfs2_queue_verify_evict(struct gfs2_glock *gl)
989+
{
990+
struct gfs2_sbd *sdp = gl->gl_name.ln_sbd;
991+
992+
if (test_and_set_bit(GLF_VERIFY_EVICT, &gl->gl_flags))
993+
return false;
994+
return queue_delayed_work(sdp->sd_delete_wq,
995+
&gl->gl_delete, 5 * HZ);
996+
}
997+
980998
static void delete_work_func(struct work_struct *work)
981999
{
9821000
struct delayed_work *dwork = to_delayed_work(work);
@@ -985,11 +1003,7 @@ static void delete_work_func(struct work_struct *work)
9851003
struct inode *inode;
9861004
u64 no_addr = gl->gl_name.ln_number;
9871005

988-
spin_lock(&gl->gl_lockref.lock);
989-
clear_bit(GLF_PENDING_DELETE, &gl->gl_flags);
990-
spin_unlock(&gl->gl_lockref.lock);
991-
992-
if (test_bit(GLF_DEMOTE, &gl->gl_flags)) {
1006+
if (test_and_clear_bit(GLF_TRY_TO_EVICT, &gl->gl_flags)) {
9931007
/*
9941008
* If we can evict the inode, give the remote node trying to
9951009
* delete the inode some time before verifying that the delete
@@ -1008,22 +1022,28 @@ static void delete_work_func(struct work_struct *work)
10081022
* step entirely.
10091023
*/
10101024
if (gfs2_try_evict(gl)) {
1011-
if (gfs2_queue_delete_work(gl, 5 * HZ))
1025+
if (test_bit(SDF_DEACTIVATING, &sdp->sd_flags))
1026+
goto out;
1027+
if (gfs2_queue_verify_evict(gl))
10121028
return;
10131029
}
10141030
goto out;
10151031
}
10161032

1017-
inode = gfs2_lookup_by_inum(sdp, no_addr, gl->gl_no_formal_ino,
1018-
GFS2_BLKST_UNLINKED);
1019-
if (IS_ERR(inode)) {
1020-
if (PTR_ERR(inode) == -EAGAIN &&
1021-
(gfs2_queue_delete_work(gl, 5 * HZ)))
1033+
if (test_and_clear_bit(GLF_VERIFY_EVICT, &gl->gl_flags)) {
1034+
inode = gfs2_lookup_by_inum(sdp, no_addr, gl->gl_no_formal_ino,
1035+
GFS2_BLKST_UNLINKED);
1036+
if (IS_ERR(inode)) {
1037+
if (PTR_ERR(inode) == -EAGAIN &&
1038+
!test_bit(SDF_DEACTIVATING, &sdp->sd_flags) &&
1039+
gfs2_queue_verify_evict(gl))
10221040
return;
1023-
} else {
1024-
d_prune_aliases(inode);
1025-
iput(inode);
1041+
} else {
1042+
d_prune_aliases(inode);
1043+
iput(inode);
1044+
}
10261045
}
1046+
10271047
out:
10281048
gfs2_glock_put(gl);
10291049
}
@@ -1985,26 +2005,26 @@ __acquires(&lru_lock)
19852005

19862006
static long gfs2_scan_glock_lru(int nr)
19872007
{
1988-
struct gfs2_glock *gl;
1989-
LIST_HEAD(skipped);
2008+
struct gfs2_glock *gl, *next;
19902009
LIST_HEAD(dispose);
19912010
long freed = 0;
19922011

19932012
spin_lock(&lru_lock);
1994-
while ((nr-- >= 0) && !list_empty(&lru_list)) {
1995-
gl = list_first_entry(&lru_list, struct gfs2_glock, gl_lru);
1996-
2013+
list_for_each_entry_safe(gl, next, &lru_list, gl_lru) {
2014+
if (nr-- <= 0)
2015+
break;
19972016
/* Test for being demotable */
19982017
if (!test_bit(GLF_LOCK, &gl->gl_flags)) {
1999-
list_move(&gl->gl_lru, &dispose);
2000-
atomic_dec(&lru_count);
2001-
freed++;
2002-
continue;
2018+
if (!spin_trylock(&gl->gl_lockref.lock))
2019+
continue;
2020+
if (!gl->gl_lockref.count) {
2021+
list_move(&gl->gl_lru, &dispose);
2022+
atomic_dec(&lru_count);
2023+
freed++;
2024+
}
2025+
spin_unlock(&gl->gl_lockref.lock);
20032026
}
2004-
2005-
list_move(&gl->gl_lru, &skipped);
20062027
}
2007-
list_splice(&skipped, &lru_list);
20082028
if (!list_empty(&dispose))
20092029
gfs2_dispose_glock_lru(&dispose);
20102030
spin_unlock(&lru_lock);
@@ -2063,37 +2083,21 @@ static void glock_hash_walk(glock_examiner examiner, const struct gfs2_sbd *sdp)
20632083
rhashtable_walk_exit(&iter);
20642084
}
20652085

2066-
bool gfs2_queue_delete_work(struct gfs2_glock *gl, unsigned long delay)
2067-
{
2068-
bool queued;
2069-
2070-
spin_lock(&gl->gl_lockref.lock);
2071-
queued = queue_delayed_work(gfs2_delete_workqueue,
2072-
&gl->gl_delete, delay);
2073-
if (queued)
2074-
set_bit(GLF_PENDING_DELETE, &gl->gl_flags);
2075-
spin_unlock(&gl->gl_lockref.lock);
2076-
return queued;
2077-
}
2078-
20792086
void gfs2_cancel_delete_work(struct gfs2_glock *gl)
20802087
{
2081-
if (cancel_delayed_work(&gl->gl_delete)) {
2082-
clear_bit(GLF_PENDING_DELETE, &gl->gl_flags);
2088+
clear_bit(GLF_TRY_TO_EVICT, &gl->gl_flags);
2089+
clear_bit(GLF_VERIFY_EVICT, &gl->gl_flags);
2090+
if (cancel_delayed_work(&gl->gl_delete))
20832091
gfs2_glock_put(gl);
2084-
}
2085-
}
2086-
2087-
bool gfs2_delete_work_queued(const struct gfs2_glock *gl)
2088-
{
2089-
return test_bit(GLF_PENDING_DELETE, &gl->gl_flags);
20902092
}
20912093

20922094
static void flush_delete_work(struct gfs2_glock *gl)
20932095
{
20942096
if (gl->gl_name.ln_type == LM_TYPE_IOPEN) {
2097+
struct gfs2_sbd *sdp = gl->gl_name.ln_sbd;
2098+
20952099
if (cancel_delayed_work(&gl->gl_delete)) {
2096-
queue_delayed_work(gfs2_delete_workqueue,
2100+
queue_delayed_work(sdp->sd_delete_wq,
20972101
&gl->gl_delete, 0);
20982102
}
20992103
}
@@ -2102,7 +2106,7 @@ static void flush_delete_work(struct gfs2_glock *gl)
21022106
void gfs2_flush_delete_work(struct gfs2_sbd *sdp)
21032107
{
21042108
glock_hash_walk(flush_delete_work, sdp);
2105-
flush_workqueue(gfs2_delete_workqueue);
2109+
flush_workqueue(sdp->sd_delete_wq);
21062110
}
21072111

21082112
/**
@@ -2308,14 +2312,16 @@ static const char *gflags2str(char *buf, const struct gfs2_glock *gl)
23082312
*p++ = 'o';
23092313
if (test_bit(GLF_BLOCKING, gflags))
23102314
*p++ = 'b';
2311-
if (test_bit(GLF_PENDING_DELETE, gflags))
2312-
*p++ = 'P';
23132315
if (test_bit(GLF_FREEING, gflags))
23142316
*p++ = 'x';
23152317
if (test_bit(GLF_INSTANTIATE_NEEDED, gflags))
23162318
*p++ = 'n';
23172319
if (test_bit(GLF_INSTANTIATE_IN_PROG, gflags))
23182320
*p++ = 'N';
2321+
if (test_bit(GLF_TRY_TO_EVICT, gflags))
2322+
*p++ = 'e';
2323+
if (test_bit(GLF_VERIFY_EVICT, gflags))
2324+
*p++ = 'E';
23192325
*p = 0;
23202326
return buf;
23212327
}
@@ -2465,18 +2471,9 @@ int __init gfs2_glock_init(void)
24652471
rhashtable_destroy(&gl_hash_table);
24662472
return -ENOMEM;
24672473
}
2468-
gfs2_delete_workqueue = alloc_workqueue("delete_workqueue",
2469-
WQ_MEM_RECLAIM | WQ_FREEZABLE,
2470-
0);
2471-
if (!gfs2_delete_workqueue) {
2472-
destroy_workqueue(glock_workqueue);
2473-
rhashtable_destroy(&gl_hash_table);
2474-
return -ENOMEM;
2475-
}
24762474

24772475
ret = register_shrinker(&glock_shrinker, "gfs2-glock");
24782476
if (ret) {
2479-
destroy_workqueue(gfs2_delete_workqueue);
24802477
destroy_workqueue(glock_workqueue);
24812478
rhashtable_destroy(&gl_hash_table);
24822479
return ret;
@@ -2493,7 +2490,6 @@ void gfs2_glock_exit(void)
24932490
unregister_shrinker(&glock_shrinker);
24942491
rhashtable_destroy(&gl_hash_table);
24952492
destroy_workqueue(glock_workqueue);
2496-
destroy_workqueue(gfs2_delete_workqueue);
24972493
}
24982494

24992495
static void gfs2_glock_iter_next(struct gfs2_glock_iter *gi, loff_t n)

fs/gfs2/glock.h

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,6 @@ struct gfs2_glock_aspace {
144144
struct address_space mapping;
145145
};
146146

147-
extern struct workqueue_struct *gfs2_delete_workqueue;
148147
static inline struct gfs2_holder *gfs2_glock_is_locked_by_me(struct gfs2_glock *gl)
149148
{
150149
struct gfs2_holder *gh;
@@ -268,9 +267,8 @@ static inline int gfs2_glock_nq_init(struct gfs2_glock *gl,
268267

269268
extern void gfs2_glock_cb(struct gfs2_glock *gl, unsigned int state);
270269
extern void gfs2_glock_complete(struct gfs2_glock *gl, int ret);
271-
extern bool gfs2_queue_delete_work(struct gfs2_glock *gl, unsigned long delay);
270+
extern bool gfs2_queue_try_to_evict(struct gfs2_glock *gl);
272271
extern void gfs2_cancel_delete_work(struct gfs2_glock *gl);
273-
extern bool gfs2_delete_work_queued(const struct gfs2_glock *gl);
274272
extern void gfs2_flush_delete_work(struct gfs2_sbd *sdp);
275273
extern void gfs2_gl_hash_clear(struct gfs2_sbd *sdp);
276274
extern void gfs2_gl_dq_holders(struct gfs2_sbd *sdp);

0 commit comments

Comments
 (0)