Skip to content

Commit

Permalink
gfs2: Add flocks to glockfd debugfs file
Browse files Browse the repository at this point in the history
Include flock glocks in the "glockfd" debugfs file.  Those are similar to the
iopen glocks; while an open file is holding an flock, it is holding the file's
flock glock.

We cannot take f_fl_mutex in gfs2_glockfd_seq_show_flock() or else dumping the
"glockfd" file would block on flock operations.  Instead, use the file->f_lock
spin lock to protect the f_fl_gh.gh_gl glock pointer.

Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
  • Loading branch information
Andreas Gruenbacher committed Jun 29, 2022
1 parent 4480c27 commit 56535dc
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 2 deletions.
22 changes: 20 additions & 2 deletions fs/gfs2/file.c
Original file line number Diff line number Diff line change
Expand Up @@ -1444,6 +1444,22 @@ static int gfs2_lock(struct file *file, int cmd, struct file_lock *fl)
return dlm_posix_lock(ls->ls_dlm, ip->i_no_addr, file, cmd, fl);
}

static void __flock_holder_uninit(struct file *file, struct gfs2_holder *fl_gh)
{
struct gfs2_glock *gl = fl_gh->gh_gl;

/*
* Make sure gfs2_glock_put() won't sleep under the file->f_lock
* spinlock.
*/

gfs2_glock_hold(gl);
spin_lock(&file->f_lock);
gfs2_holder_uninit(fl_gh);
spin_unlock(&file->f_lock);
gfs2_glock_put(gl);
}

static int do_flock(struct file *file, int cmd, struct file_lock *fl)
{
struct gfs2_file *fp = file->private_data;
Expand Down Expand Up @@ -1475,7 +1491,9 @@ static int do_flock(struct file *file, int cmd, struct file_lock *fl)
&gfs2_flock_glops, CREATE, &gl);
if (error)
goto out;
spin_lock(&file->f_lock);
gfs2_holder_init(gl, state, flags, fl_gh);
spin_unlock(&file->f_lock);
gfs2_glock_put(gl);
}
for (sleeptime = 1; sleeptime <= 4; sleeptime <<= 1) {
Expand All @@ -1486,7 +1504,7 @@ static int do_flock(struct file *file, int cmd, struct file_lock *fl)
msleep(sleeptime);
}
if (error) {
gfs2_holder_uninit(fl_gh);
__flock_holder_uninit(file, fl_gh);
if (error == GLR_TRYFAILED)
error = -EAGAIN;
} else {
Expand All @@ -1508,7 +1526,7 @@ static void do_unflock(struct file *file, struct file_lock *fl)
locks_lock_file_wait(file, fl);
if (gfs2_holder_initialized(fl_gh)) {
gfs2_glock_dq(fl_gh);
gfs2_holder_uninit(fl_gh);
__flock_holder_uninit(file, fl_gh);
}
mutex_unlock(&fp->f_fl_mutex);
}
Expand Down
23 changes: 23 additions & 0 deletions fs/gfs2/glock.c
Original file line number Diff line number Diff line change
Expand Up @@ -2846,6 +2846,28 @@ static void gfs2_glockfd_seq_stop(struct seq_file *seq, void *iter_ptr)
put_task_struct(i->task);
}

static void gfs2_glockfd_seq_show_flock(struct seq_file *seq,
struct gfs2_glockfd_iter *i)
{
struct gfs2_file *fp = i->file->private_data;
struct gfs2_holder *fl_gh = &fp->f_fl_gh;
struct lm_lockname gl_name = { .ln_type = LM_TYPE_RESERVED };

if (!READ_ONCE(fl_gh->gh_gl))
return;

spin_lock(&i->file->f_lock);
if (gfs2_holder_initialized(fl_gh))
gl_name = fl_gh->gh_gl->gl_name;
spin_unlock(&i->file->f_lock);

if (gl_name.ln_type != LM_TYPE_RESERVED) {
seq_printf(seq, "%d %u %u/%llx\n",
i->tgid, i->fd, gl_name.ln_type,
(unsigned long long)gl_name.ln_number);
}
}

static int gfs2_glockfd_seq_show(struct seq_file *seq, void *iter_ptr)
{
struct gfs2_glockfd_iter *i = seq->private;
Expand All @@ -2859,6 +2881,7 @@ static int gfs2_glockfd_seq_show(struct seq_file *seq, void *iter_ptr)
i->tgid, i->fd, gl->gl_name.ln_type,
(unsigned long long)gl->gl_name.ln_number);
}
gfs2_glockfd_seq_show_flock(seq, i);
inode_unlock_shared(inode);
return 0;
}
Expand Down

0 comments on commit 56535dc

Please sign in to comment.