Commit 34816d20 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'gfs2-v5.10-rc5-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/gfs2/linux-gfs2

Pull gfs2 fixes from Andreas Gruenbacher:
 "Various gfs2 fixes"

* tag 'gfs2-v5.10-rc5-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/gfs2/linux-gfs2:
  gfs2: Fix deadlock between gfs2_{create_inode,inode_lookup} and delete_work_func
  gfs2: Upgrade shared glocks for atime updates
  gfs2: Don't freeze the file system during unmount
  gfs2: check for empty rgrp tree in gfs2_ri_update
  gfs2: set lockdep subclass for iopen glocks
  gfs2: Fix deadlock dumping resource group glocks
parents 3bb61aa6 dd0ecf54
...@@ -1035,6 +1035,7 @@ int gfs2_glock_get(struct gfs2_sbd *sdp, u64 number, ...@@ -1035,6 +1035,7 @@ int gfs2_glock_get(struct gfs2_sbd *sdp, u64 number,
gl->gl_node.next = NULL; gl->gl_node.next = NULL;
gl->gl_flags = 0; gl->gl_flags = 0;
gl->gl_name = name; gl->gl_name = name;
lockdep_set_subclass(&gl->gl_lockref.lock, glops->go_subclass);
gl->gl_lockref.count = 1; gl->gl_lockref.count = 1;
gl->gl_state = LM_ST_UNLOCKED; gl->gl_state = LM_ST_UNLOCKED;
gl->gl_target = LM_ST_UNLOCKED; gl->gl_target = LM_ST_UNLOCKED;
......
...@@ -245,7 +245,7 @@ static void rgrp_go_inval(struct gfs2_glock *gl, int flags) ...@@ -245,7 +245,7 @@ static void rgrp_go_inval(struct gfs2_glock *gl, int flags)
static void gfs2_rgrp_go_dump(struct seq_file *seq, struct gfs2_glock *gl, static void gfs2_rgrp_go_dump(struct seq_file *seq, struct gfs2_glock *gl,
const char *fs_id_buf) const char *fs_id_buf)
{ {
struct gfs2_rgrpd *rgd = gfs2_glock2rgrp(gl); struct gfs2_rgrpd *rgd = gl->gl_object;
if (rgd) if (rgd)
gfs2_rgrp_dump(seq, rgd, fs_id_buf); gfs2_rgrp_dump(seq, rgd, fs_id_buf);
...@@ -582,7 +582,8 @@ static int freeze_go_sync(struct gfs2_glock *gl) ...@@ -582,7 +582,8 @@ static int freeze_go_sync(struct gfs2_glock *gl)
* Once thawed, the work func acquires the freeze glock in * Once thawed, the work func acquires the freeze glock in
* SH and everybody goes back to thawed. * SH and everybody goes back to thawed.
*/ */
if (gl->gl_state == LM_ST_SHARED && !gfs2_withdrawn(sdp)) { if (gl->gl_state == LM_ST_SHARED && !gfs2_withdrawn(sdp) &&
!test_bit(SDF_NORECOVERY, &sdp->sd_flags)) {
atomic_set(&sdp->sd_freeze_state, SFS_STARTING_FREEZE); atomic_set(&sdp->sd_freeze_state, SFS_STARTING_FREEZE);
error = freeze_super(sdp->sd_vfs); error = freeze_super(sdp->sd_vfs);
if (error) { if (error) {
...@@ -781,6 +782,7 @@ const struct gfs2_glock_operations gfs2_iopen_glops = { ...@@ -781,6 +782,7 @@ const struct gfs2_glock_operations gfs2_iopen_glops = {
.go_callback = iopen_go_callback, .go_callback = iopen_go_callback,
.go_demote_ok = iopen_go_demote_ok, .go_demote_ok = iopen_go_demote_ok,
.go_flags = GLOF_LRU | GLOF_NONDISK, .go_flags = GLOF_LRU | GLOF_NONDISK,
.go_subclass = 1,
}; };
const struct gfs2_glock_operations gfs2_flock_glops = { const struct gfs2_glock_operations gfs2_flock_glops = {
......
...@@ -247,6 +247,7 @@ struct gfs2_glock_operations { ...@@ -247,6 +247,7 @@ struct gfs2_glock_operations {
const char *fs_id_buf); const char *fs_id_buf);
void (*go_callback)(struct gfs2_glock *gl, bool remote); void (*go_callback)(struct gfs2_glock *gl, bool remote);
void (*go_free)(struct gfs2_glock *gl); void (*go_free)(struct gfs2_glock *gl);
const int go_subclass;
const int go_type; const int go_type;
const unsigned long go_flags; const unsigned long go_flags;
#define GLOF_ASPACE 1 /* address space attached */ #define GLOF_ASPACE 1 /* address space attached */
......
...@@ -150,6 +150,8 @@ struct inode *gfs2_inode_lookup(struct super_block *sb, unsigned int type, ...@@ -150,6 +150,8 @@ struct inode *gfs2_inode_lookup(struct super_block *sb, unsigned int type,
error = gfs2_glock_get(sdp, no_addr, &gfs2_iopen_glops, CREATE, &io_gl); error = gfs2_glock_get(sdp, no_addr, &gfs2_iopen_glops, CREATE, &io_gl);
if (unlikely(error)) if (unlikely(error))
goto fail; goto fail;
if (blktype != GFS2_BLKST_UNLINKED)
gfs2_cancel_delete_work(io_gl);
if (type == DT_UNKNOWN || blktype != GFS2_BLKST_FREE) { if (type == DT_UNKNOWN || blktype != GFS2_BLKST_FREE) {
/* /*
...@@ -180,8 +182,6 @@ struct inode *gfs2_inode_lookup(struct super_block *sb, unsigned int type, ...@@ -180,8 +182,6 @@ struct inode *gfs2_inode_lookup(struct super_block *sb, unsigned int type,
error = gfs2_glock_nq_init(io_gl, LM_ST_SHARED, GL_EXACT, &ip->i_iopen_gh); error = gfs2_glock_nq_init(io_gl, LM_ST_SHARED, GL_EXACT, &ip->i_iopen_gh);
if (unlikely(error)) if (unlikely(error))
goto fail; goto fail;
if (blktype != GFS2_BLKST_UNLINKED)
gfs2_cancel_delete_work(ip->i_iopen_gh.gh_gl);
glock_set_object(ip->i_iopen_gh.gh_gl, ip); glock_set_object(ip->i_iopen_gh.gh_gl, ip);
gfs2_glock_put(io_gl); gfs2_glock_put(io_gl);
io_gl = NULL; io_gl = NULL;
...@@ -725,13 +725,19 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry, ...@@ -725,13 +725,19 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry,
flush_delayed_work(&ip->i_gl->gl_work); flush_delayed_work(&ip->i_gl->gl_work);
glock_set_object(ip->i_gl, ip); glock_set_object(ip->i_gl, ip);
error = gfs2_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, GL_SKIP, ghs + 1); error = gfs2_glock_get(sdp, ip->i_no_addr, &gfs2_iopen_glops, CREATE, &io_gl);
if (error) if (error)
goto fail_free_inode; goto fail_free_inode;
gfs2_cancel_delete_work(io_gl);
glock_set_object(io_gl, ip);
error = gfs2_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, GL_SKIP, ghs + 1);
if (error)
goto fail_gunlock2;
error = gfs2_trans_begin(sdp, blocks, 0); error = gfs2_trans_begin(sdp, blocks, 0);
if (error) if (error)
goto fail_free_inode; goto fail_gunlock2;
if (blocks > 1) { if (blocks > 1) {
ip->i_eattr = ip->i_no_addr + 1; ip->i_eattr = ip->i_no_addr + 1;
...@@ -740,18 +746,12 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry, ...@@ -740,18 +746,12 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry,
init_dinode(dip, ip, symname); init_dinode(dip, ip, symname);
gfs2_trans_end(sdp); gfs2_trans_end(sdp);
error = gfs2_glock_get(sdp, ip->i_no_addr, &gfs2_iopen_glops, CREATE, &io_gl);
if (error)
goto fail_free_inode;
BUG_ON(test_and_set_bit(GLF_INODE_CREATING, &io_gl->gl_flags)); BUG_ON(test_and_set_bit(GLF_INODE_CREATING, &io_gl->gl_flags));
error = gfs2_glock_nq_init(io_gl, LM_ST_SHARED, GL_EXACT, &ip->i_iopen_gh); error = gfs2_glock_nq_init(io_gl, LM_ST_SHARED, GL_EXACT, &ip->i_iopen_gh);
if (error) if (error)
goto fail_gunlock2; goto fail_gunlock2;
gfs2_cancel_delete_work(ip->i_iopen_gh.gh_gl);
glock_set_object(ip->i_iopen_gh.gh_gl, ip);
gfs2_set_iop(inode); gfs2_set_iop(inode);
insert_inode_hash(inode); insert_inode_hash(inode);
...@@ -803,6 +803,7 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry, ...@@ -803,6 +803,7 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry,
gfs2_glock_dq_uninit(&ip->i_iopen_gh); gfs2_glock_dq_uninit(&ip->i_iopen_gh);
fail_gunlock2: fail_gunlock2:
clear_bit(GLF_INODE_CREATING, &io_gl->gl_flags); clear_bit(GLF_INODE_CREATING, &io_gl->gl_flags);
glock_clear_object(io_gl, ip);
gfs2_glock_put(io_gl); gfs2_glock_put(io_gl);
fail_free_inode: fail_free_inode:
if (ip->i_gl) { if (ip->i_gl) {
...@@ -2116,6 +2117,25 @@ loff_t gfs2_seek_hole(struct file *file, loff_t offset) ...@@ -2116,6 +2117,25 @@ loff_t gfs2_seek_hole(struct file *file, loff_t offset)
return vfs_setpos(file, ret, inode->i_sb->s_maxbytes); return vfs_setpos(file, ret, inode->i_sb->s_maxbytes);
} }
static int gfs2_update_time(struct inode *inode, struct timespec64 *time,
int flags)
{
struct gfs2_inode *ip = GFS2_I(inode);
struct gfs2_glock *gl = ip->i_gl;
struct gfs2_holder *gh;
int error;
gh = gfs2_glock_is_locked_by_me(gl);
if (gh && !gfs2_glock_is_held_excl(gl)) {
gfs2_glock_dq(gh);
gfs2_holder_reinit(LM_ST_EXCLUSIVE, 0, gh);
error = gfs2_glock_nq(gh);
if (error)
return error;
}
return generic_update_time(inode, time, flags);
}
const struct inode_operations gfs2_file_iops = { const struct inode_operations gfs2_file_iops = {
.permission = gfs2_permission, .permission = gfs2_permission,
.setattr = gfs2_setattr, .setattr = gfs2_setattr,
...@@ -2124,6 +2144,7 @@ const struct inode_operations gfs2_file_iops = { ...@@ -2124,6 +2144,7 @@ const struct inode_operations gfs2_file_iops = {
.fiemap = gfs2_fiemap, .fiemap = gfs2_fiemap,
.get_acl = gfs2_get_acl, .get_acl = gfs2_get_acl,
.set_acl = gfs2_set_acl, .set_acl = gfs2_set_acl,
.update_time = gfs2_update_time,
}; };
const struct inode_operations gfs2_dir_iops = { const struct inode_operations gfs2_dir_iops = {
...@@ -2143,6 +2164,7 @@ const struct inode_operations gfs2_dir_iops = { ...@@ -2143,6 +2164,7 @@ const struct inode_operations gfs2_dir_iops = {
.fiemap = gfs2_fiemap, .fiemap = gfs2_fiemap,
.get_acl = gfs2_get_acl, .get_acl = gfs2_get_acl,
.set_acl = gfs2_set_acl, .set_acl = gfs2_set_acl,
.update_time = gfs2_update_time,
.atomic_open = gfs2_atomic_open, .atomic_open = gfs2_atomic_open,
}; };
......
...@@ -985,6 +985,10 @@ static int gfs2_ri_update(struct gfs2_inode *ip) ...@@ -985,6 +985,10 @@ static int gfs2_ri_update(struct gfs2_inode *ip)
if (error < 0) if (error < 0)
return error; return error;
if (RB_EMPTY_ROOT(&sdp->sd_rindex_tree)) {
fs_err(sdp, "no resource groups found in the file system.\n");
return -ENOENT;
}
set_rgrp_preferences(sdp); set_rgrp_preferences(sdp);
sdp->sd_rindex_uptodate = 1; sdp->sd_rindex_uptodate = 1;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment