Skip to content

Commit 78805cb

Browse files
committed
Merge tag 'gfs2-v5.15-rc5-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/gfs2/linux-gfs2
Pull gfs2 updates from Andreas Gruenbacher: - Fix a locking order inversion between the inode and iopen glocks in gfs2_inode_lookup. - Implement proper queuing of glock holders for glocks that require instantiation (like reading an inode or bitmap blocks from disk). Before, multiple glock holders could race with each other and half-initialized objects could be exposed; the GL_SKIP flag further exacerbated this problem. - Fix a rare deadlock between inode lookup / creation and remote delete work. - Fix a rare scheduling-while-atomic bug in dlm during glock hash table walks. - Various other minor fixes and cleanups. * tag 'gfs2-v5.15-rc5-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/gfs2/linux-gfs2: (21 commits) gfs2: Fix unused value warning in do_gfs2_set_flags() gfs2: check context in gfs2_glock_put gfs2: Fix glock_hash_walk bugs gfs2: Cancel remote delete work asynchronously gfs2: set glock object after nq gfs2: remove RDF_UPTODATE flag gfs2: Eliminate GIF_INVALID flag gfs2: fix GL_SKIP node_scope problems gfs2: split glock instantiation off from do_promote gfs2: further simplify do_promote gfs2: re-factor function do_promote gfs2: Remove 'first' trace_gfs2_promote argument gfs2: change go_lock to go_instantiate gfs2: dump glocks from gfs2_consist_OBJ_i gfs2: dequeue iopen holder in gfs2_inode_lookup error gfs2: Save ip from gfs2_glock_nq_init gfs2: Allow append and immutable bits to coexist gfs2: Switch some BUG_ON to GLOCK_BUG_ON for debug gfs2: move GL_SKIP check from glops to do_promote gfs2: Add GL_SKIP holder flag to dump_holder ...
2 parents c03098d + e34e6f8 commit 78805cb

11 files changed

Lines changed: 186 additions & 136 deletions

File tree

fs/gfs2/file.c

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -213,11 +213,9 @@ void gfs2_set_inode_flags(struct inode *inode)
213213
* @inode: The inode
214214
* @reqflags: The flags to set
215215
* @mask: Indicates which flags are valid
216-
* @fsflags: The FS_* inode flags passed in
217216
*
218217
*/
219-
static int do_gfs2_set_flags(struct inode *inode, u32 reqflags, u32 mask,
220-
const u32 fsflags)
218+
static int do_gfs2_set_flags(struct inode *inode, u32 reqflags, u32 mask)
221219
{
222220
struct gfs2_inode *ip = GFS2_I(inode);
223221
struct gfs2_sbd *sdp = GFS2_SB(inode);
@@ -236,11 +234,6 @@ static int do_gfs2_set_flags(struct inode *inode, u32 reqflags, u32 mask,
236234
if ((new_flags ^ flags) == 0)
237235
goto out;
238236

239-
error = -EPERM;
240-
if (IS_IMMUTABLE(inode) && (new_flags & GFS2_DIF_IMMUTABLE))
241-
goto out;
242-
if (IS_APPEND(inode) && (new_flags & GFS2_DIF_APPENDONLY))
243-
goto out;
244237
if (!IS_IMMUTABLE(inode)) {
245238
error = gfs2_permission(&init_user_ns, inode, MAY_WRITE);
246239
if (error)
@@ -313,7 +306,7 @@ int gfs2_fileattr_set(struct user_namespace *mnt_userns,
313306
mask &= ~(GFS2_DIF_TOPDIR | GFS2_DIF_INHERIT_JDATA);
314307
}
315308

316-
return do_gfs2_set_flags(inode, gfsflags, mask, fsflags);
309+
return do_gfs2_set_flags(inode, gfsflags, mask);
317310
}
318311

319312
static int gfs2_getlabel(struct file *filp, char __user *label)

fs/gfs2/glock.c

Lines changed: 111 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -301,6 +301,9 @@ void gfs2_glock_queue_put(struct gfs2_glock *gl)
301301

302302
void gfs2_glock_put(struct gfs2_glock *gl)
303303
{
304+
/* last put could call sleepable dlm api */
305+
might_sleep();
306+
304307
if (lockref_put_or_lock(&gl->gl_lockref))
305308
return;
306309

@@ -472,6 +475,51 @@ find_first_strong_holder(struct gfs2_glock *gl)
472475
return NULL;
473476
}
474477

478+
/*
479+
* gfs2_instantiate - Call the glops instantiate function
480+
* @gl: The glock
481+
*
482+
* Returns: 0 if instantiate was successful, 2 if type specific operation is
483+
* underway, or error.
484+
*/
485+
int gfs2_instantiate(struct gfs2_holder *gh)
486+
{
487+
struct gfs2_glock *gl = gh->gh_gl;
488+
const struct gfs2_glock_operations *glops = gl->gl_ops;
489+
int ret;
490+
491+
again:
492+
if (!test_bit(GLF_INSTANTIATE_NEEDED, &gl->gl_flags))
493+
return 0;
494+
495+
/*
496+
* Since we unlock the lockref lock, we set a flag to indicate
497+
* instantiate is in progress.
498+
*/
499+
if (test_bit(GLF_INSTANTIATE_IN_PROG, &gl->gl_flags)) {
500+
wait_on_bit(&gl->gl_flags, GLF_INSTANTIATE_IN_PROG,
501+
TASK_UNINTERRUPTIBLE);
502+
/*
503+
* Here we just waited for a different instantiate to finish.
504+
* But that may not have been successful, as when a process
505+
* locks an inode glock _before_ it has an actual inode to
506+
* instantiate into. So we check again. This process might
507+
* have an inode to instantiate, so might be successful.
508+
*/
509+
goto again;
510+
}
511+
512+
set_bit(GLF_INSTANTIATE_IN_PROG, &gl->gl_flags);
513+
514+
ret = glops->go_instantiate(gh);
515+
if (!ret)
516+
clear_bit(GLF_INSTANTIATE_NEEDED, &gl->gl_flags);
517+
clear_bit(GLF_INSTANTIATE_IN_PROG, &gl->gl_flags);
518+
smp_mb__after_atomic();
519+
wake_up_bit(&gl->gl_flags, GLF_INSTANTIATE_IN_PROG);
520+
return ret;
521+
}
522+
475523
/**
476524
* do_promote - promote as many requests as possible on the current queue
477525
* @gl: The glock
@@ -484,56 +532,59 @@ static int do_promote(struct gfs2_glock *gl)
484532
__releases(&gl->gl_lockref.lock)
485533
__acquires(&gl->gl_lockref.lock)
486534
{
487-
const struct gfs2_glock_operations *glops = gl->gl_ops;
488535
struct gfs2_holder *gh, *tmp, *first_gh;
489536
bool incompat_holders_demoted = false;
537+
bool lock_released;
490538
int ret;
491539

492540
restart:
493541
first_gh = find_first_strong_holder(gl);
494542
list_for_each_entry_safe(gh, tmp, &gl->gl_holders, gh_list) {
495-
if (!test_bit(HIF_WAIT, &gh->gh_iflags))
543+
lock_released = false;
544+
if (test_bit(HIF_HOLDER, &gh->gh_iflags))
496545
continue;
497-
if (may_grant(gl, first_gh, gh)) {
498-
if (!incompat_holders_demoted) {
499-
demote_incompat_holders(gl, first_gh);
500-
incompat_holders_demoted = true;
501-
first_gh = gh;
502-
}
503-
if (gh->gh_list.prev == &gl->gl_holders &&
504-
glops->go_lock) {
505-
spin_unlock(&gl->gl_lockref.lock);
506-
/* FIXME: eliminate this eventually */
507-
ret = glops->go_lock(gh);
508-
spin_lock(&gl->gl_lockref.lock);
509-
if (ret) {
510-
if (ret == 1)
511-
return 2;
512-
gh->gh_error = ret;
513-
list_del_init(&gh->gh_list);
514-
trace_gfs2_glock_queue(gh, 0);
515-
gfs2_holder_wake(gh);
516-
goto restart;
517-
}
518-
set_bit(HIF_HOLDER, &gh->gh_iflags);
519-
trace_gfs2_promote(gh, 1);
546+
if (!may_grant(gl, first_gh, gh)) {
547+
/*
548+
* If we get here, it means we may not grant this holder for
549+
* some reason. If this holder is the head of the list, it
550+
* means we have a blocked holder at the head, so return 1.
551+
*/
552+
if (gh->gh_list.prev == &gl->gl_holders)
553+
return 1;
554+
do_error(gl, 0);
555+
break;
556+
}
557+
if (!incompat_holders_demoted) {
558+
demote_incompat_holders(gl, first_gh);
559+
incompat_holders_demoted = true;
560+
first_gh = gh;
561+
}
562+
if (test_bit(GLF_INSTANTIATE_NEEDED, &gl->gl_flags) &&
563+
!(gh->gh_flags & GL_SKIP) && gl->gl_ops->go_instantiate) {
564+
lock_released = true;
565+
spin_unlock(&gl->gl_lockref.lock);
566+
ret = gfs2_instantiate(gh);
567+
spin_lock(&gl->gl_lockref.lock);
568+
if (ret) {
569+
if (ret == 1)
570+
return 2;
571+
gh->gh_error = ret;
572+
list_del_init(&gh->gh_list);
573+
trace_gfs2_glock_queue(gh, 0);
520574
gfs2_holder_wake(gh);
521575
goto restart;
522576
}
523-
set_bit(HIF_HOLDER, &gh->gh_iflags);
524-
trace_gfs2_promote(gh, 0);
525-
gfs2_holder_wake(gh);
526-
continue;
527577
}
578+
set_bit(HIF_HOLDER, &gh->gh_iflags);
579+
trace_gfs2_promote(gh);
580+
gfs2_holder_wake(gh);
528581
/*
529-
* If we get here, it means we may not grant this holder for
530-
* some reason. If this holder is the head of the list, it
531-
* means we have a blocked holder at the head, so return 1.
582+
* If we released the gl_lockref.lock the holders list may have
583+
* changed. For that reason, we start again at the start of
584+
* the holders queue.
532585
*/
533-
if (gh->gh_list.prev == &gl->gl_holders)
534-
return 1;
535-
do_error(gl, 0);
536-
break;
586+
if (lock_released)
587+
goto restart;
537588
}
538589
return 0;
539590
}
@@ -909,7 +960,7 @@ static void gfs2_glock_poke(struct gfs2_glock *gl)
909960
struct gfs2_holder gh;
910961
int error;
911962

912-
gfs2_holder_init(gl, LM_ST_SHARED, flags, &gh);
963+
__gfs2_holder_init(gl, LM_ST_SHARED, flags, &gh, _RET_IP_);
913964
error = gfs2_glock_nq(&gh);
914965
if (!error)
915966
gfs2_glock_dq(&gh);
@@ -1144,7 +1195,7 @@ int gfs2_glock_get(struct gfs2_sbd *sdp, u64 number,
11441195

11451196
atomic_inc(&sdp->sd_glock_disposal);
11461197
gl->gl_node.next = NULL;
1147-
gl->gl_flags = 0;
1198+
gl->gl_flags = glops->go_instantiate ? BIT(GLF_INSTANTIATE_NEEDED) : 0;
11481199
gl->gl_name = name;
11491200
lockdep_set_subclass(&gl->gl_lockref.lock, glops->go_subclass);
11501201
gl->gl_lockref.count = 1;
@@ -1206,12 +1257,12 @@ int gfs2_glock_get(struct gfs2_sbd *sdp, u64 number,
12061257
*
12071258
*/
12081259

1209-
void gfs2_holder_init(struct gfs2_glock *gl, unsigned int state, u16 flags,
1210-
struct gfs2_holder *gh)
1260+
void __gfs2_holder_init(struct gfs2_glock *gl, unsigned int state, u16 flags,
1261+
struct gfs2_holder *gh, unsigned long ip)
12111262
{
12121263
INIT_LIST_HEAD(&gh->gh_list);
12131264
gh->gh_gl = gl;
1214-
gh->gh_ip = _RET_IP_;
1265+
gh->gh_ip = ip;
12151266
gh->gh_owner_pid = get_pid(task_pid(current));
12161267
gh->gh_state = state;
12171268
gh->gh_flags = flags;
@@ -2053,10 +2104,10 @@ static void glock_hash_walk(glock_examiner examiner, const struct gfs2_sbd *sdp)
20532104
do {
20542105
rhashtable_walk_start(&iter);
20552106

2056-
while ((gl = rhashtable_walk_next(&iter)) && !IS_ERR(gl))
2057-
if (gl->gl_name.ln_sbd == sdp &&
2058-
lockref_get_not_dead(&gl->gl_lockref))
2107+
while ((gl = rhashtable_walk_next(&iter)) && !IS_ERR(gl)) {
2108+
if (gl->gl_name.ln_sbd == sdp)
20592109
examiner(gl);
2110+
}
20602111

20612112
rhashtable_walk_stop(&iter);
20622113
} while (cond_resched(), gl == ERR_PTR(-EAGAIN));
@@ -2079,7 +2130,7 @@ bool gfs2_queue_delete_work(struct gfs2_glock *gl, unsigned long delay)
20792130

20802131
void gfs2_cancel_delete_work(struct gfs2_glock *gl)
20812132
{
2082-
if (cancel_delayed_work_sync(&gl->gl_delete)) {
2133+
if (cancel_delayed_work(&gl->gl_delete)) {
20832134
clear_bit(GLF_PENDING_DELETE, &gl->gl_flags);
20842135
gfs2_glock_put(gl);
20852136
}
@@ -2098,7 +2149,6 @@ static void flush_delete_work(struct gfs2_glock *gl)
20982149
&gl->gl_delete, 0);
20992150
}
21002151
}
2101-
gfs2_glock_queue_work(gl, 0);
21022152
}
21032153

21042154
void gfs2_flush_delete_work(struct gfs2_sbd *sdp)
@@ -2115,10 +2165,10 @@ void gfs2_flush_delete_work(struct gfs2_sbd *sdp)
21152165

21162166
static void thaw_glock(struct gfs2_glock *gl)
21172167
{
2118-
if (!test_and_clear_bit(GLF_FROZEN, &gl->gl_flags)) {
2119-
gfs2_glock_put(gl);
2168+
if (!test_and_clear_bit(GLF_FROZEN, &gl->gl_flags))
2169+
return;
2170+
if (!lockref_get_not_dead(&gl->gl_lockref))
21202171
return;
2121-
}
21222172
set_bit(GLF_REPLY_PENDING, &gl->gl_flags);
21232173
gfs2_glock_queue_work(gl, 0);
21242174
}
@@ -2134,9 +2184,12 @@ static void clear_glock(struct gfs2_glock *gl)
21342184
gfs2_glock_remove_from_lru(gl);
21352185

21362186
spin_lock(&gl->gl_lockref.lock);
2137-
if (gl->gl_state != LM_ST_UNLOCKED)
2138-
handle_callback(gl, LM_ST_UNLOCKED, 0, false);
2139-
__gfs2_glock_queue_work(gl, 0);
2187+
if (!__lockref_is_dead(&gl->gl_lockref)) {
2188+
gl->gl_lockref.count++;
2189+
if (gl->gl_state != LM_ST_UNLOCKED)
2190+
handle_callback(gl, LM_ST_UNLOCKED, 0, false);
2191+
__gfs2_glock_queue_work(gl, 0);
2192+
}
21402193
spin_unlock(&gl->gl_lockref.lock);
21412194
}
21422195

@@ -2238,6 +2291,8 @@ static const char *hflags2str(char *buf, u16 flags, unsigned long iflags)
22382291
*p++ = 'W';
22392292
if (test_bit(HIF_MAY_DEMOTE, &iflags))
22402293
*p++ = 'D';
2294+
if (flags & GL_SKIP)
2295+
*p++ = 's';
22412296
*p = 0;
22422297
return buf;
22432298
}
@@ -2306,6 +2361,10 @@ static const char *gflags2str(char *buf, const struct gfs2_glock *gl)
23062361
*p++ = 'P';
23072362
if (test_bit(GLF_FREEING, gflags))
23082363
*p++ = 'x';
2364+
if (test_bit(GLF_INSTANTIATE_NEEDED, gflags))
2365+
*p++ = 'n';
2366+
if (test_bit(GLF_INSTANTIATE_IN_PROG, gflags))
2367+
*p++ = 'N';
23092368
*p = 0;
23102369
return buf;
23112370
}

fs/gfs2/glock.h

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -190,13 +190,21 @@ extern int gfs2_glock_get(struct gfs2_sbd *sdp, u64 number,
190190
extern void gfs2_glock_hold(struct gfs2_glock *gl);
191191
extern void gfs2_glock_put(struct gfs2_glock *gl);
192192
extern void gfs2_glock_queue_put(struct gfs2_glock *gl);
193-
extern void gfs2_holder_init(struct gfs2_glock *gl, unsigned int state,
194-
u16 flags, struct gfs2_holder *gh);
193+
194+
extern void __gfs2_holder_init(struct gfs2_glock *gl, unsigned int state,
195+
u16 flags, struct gfs2_holder *gh,
196+
unsigned long ip);
197+
static inline void gfs2_holder_init(struct gfs2_glock *gl, unsigned int state,
198+
u16 flags, struct gfs2_holder *gh) {
199+
__gfs2_holder_init(gl, state, flags, gh, _RET_IP_);
200+
}
201+
195202
extern void gfs2_holder_reinit(unsigned int state, u16 flags,
196203
struct gfs2_holder *gh);
197204
extern void gfs2_holder_uninit(struct gfs2_holder *gh);
198205
extern int gfs2_glock_nq(struct gfs2_holder *gh);
199206
extern int gfs2_glock_poll(struct gfs2_holder *gh);
207+
extern int gfs2_instantiate(struct gfs2_holder *gh);
200208
extern int gfs2_glock_wait(struct gfs2_holder *gh);
201209
extern int gfs2_glock_async_wait(unsigned int num_gh, struct gfs2_holder *ghs);
202210
extern void gfs2_glock_dq(struct gfs2_holder *gh);
@@ -241,7 +249,7 @@ static inline int gfs2_glock_nq_init(struct gfs2_glock *gl,
241249
{
242250
int error;
243251

244-
gfs2_holder_init(gl, state, flags, gh);
252+
__gfs2_holder_init(gl, state, flags, gh, _RET_IP_);
245253

246254
error = gfs2_glock_nq(gh);
247255
if (error)

0 commit comments

Comments
 (0)