forked from Minki/linux
Various gfs2 fixes
-----BEGIN PGP SIGNATURE----- iQJIBAABCAAyFiEEJZs3krPW0xkhLMTc1b+f6wMTZToFAl7/A8kUHGFncnVlbmJh QHJlZGhhdC5jb20ACgkQ1b+f6wMTZToR8A//RI5c1W9De9ST6ITDsVLVpKX7ugRl Zo9ORCRgnnBuJFGQ6VtPuren9Rd6nxIOwf8MeFHjkgapIcXVM/f81Hx7WTUS7KOP dakeOOWPw1Ue3hcnpxjT4fTgZo43u1VoKbFGMpUPK0zvGrYh8fa4euAhALGIUB0X jc12mX/FdpQY+9YurY45GJ186tC0aZp1kEK+mA5apPuIA+9pUqbPIt6tmLV1wRry 2a2fTZXI0MN0/u4ZhHSFcJVj4k6xdLLQodJHW+FAPh50vHf7W++DL6mJ5V6Svp8N vaWUdTbLh8wp/IxD+G4tnPk2BFKvGRwXZV9ZmrivxcwRKc4bgA878yjU6Ox4B0XB EzXcTPeO0zGHtXBv49Pig0dZDllgvlDL/us2rnt+APZ99yWsX8GzJ1BDP4gT4var 3IuNxyvpeAth9zth/aOzS2pE50yano64CQZq/NsuvAz4MTI8zms/o2ioH/aPbwfk DFkAQHzlNPZlbt6jF6WJxF4R0Mrs8g1oTF5eH0sIpfMUxtq0Ay9dlHDEY1yjl/Jw 2KBuKLF6P6IZN3aSolawY29dcnMp5vbRDLdbqNzz2/DzAQmqjd4IcY0gK/nHTc8i 2TLyffQ6YTdEDXKIDqfPNDxjcYLKd1XCIyogXt6Rw57C3YwIbDY/drPtFUpUCUFI Oaf4j8M9W+gamzU= =GQwd -----END PGP SIGNATURE----- Merge tag 'gfs2-v5.8-rc3.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.8-rc3.fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/gfs2/linux-gfs2: gfs2: The freeze glock should never be frozen gfs2: When freezing gfs2, use GL_EXACT and not GL_NOCACHE gfs2: read-only mounts should grab the sd_freeze_gl glock gfs2: freeze should work on read-only mounts gfs2: eliminate GIF_ORDERED in favor of list_empty gfs2: Don't sleep during glock hash walk gfs2: fix trans slab error when withdraw occurs inside log_flush gfs2: Don't return NULL from gfs2_inode_lookup
This commit is contained in:
commit
bf2d63694e
@ -1899,7 +1899,10 @@ bool gfs2_delete_work_queued(const struct gfs2_glock *gl)
|
||||
|
||||
static void flush_delete_work(struct gfs2_glock *gl)
|
||||
{
|
||||
flush_delayed_work(&gl->gl_delete);
|
||||
if (cancel_delayed_work(&gl->gl_delete)) {
|
||||
queue_delayed_work(gfs2_delete_workqueue,
|
||||
&gl->gl_delete, 0);
|
||||
}
|
||||
gfs2_glock_queue_work(gl, 0);
|
||||
}
|
||||
|
||||
|
@ -531,8 +531,7 @@ static int freeze_go_sync(struct gfs2_glock *gl)
|
||||
int error = 0;
|
||||
struct gfs2_sbd *sdp = gl->gl_name.ln_sbd;
|
||||
|
||||
if (gl->gl_state == LM_ST_SHARED && !gfs2_withdrawn(sdp) &&
|
||||
test_bit(SDF_JOURNAL_LIVE, &sdp->sd_flags)) {
|
||||
if (gl->gl_req == LM_ST_EXCLUSIVE && !gfs2_withdrawn(sdp)) {
|
||||
atomic_set(&sdp->sd_freeze_state, SFS_STARTING_FREEZE);
|
||||
error = freeze_super(sdp->sd_vfs);
|
||||
if (error) {
|
||||
@ -545,8 +544,11 @@ static int freeze_go_sync(struct gfs2_glock *gl)
|
||||
gfs2_assert_withdraw(sdp, 0);
|
||||
}
|
||||
queue_work(gfs2_freeze_wq, &sdp->sd_freeze_work);
|
||||
gfs2_log_flush(sdp, NULL, GFS2_LOG_HEAD_FLUSH_FREEZE |
|
||||
GFS2_LFC_FREEZE_GO_SYNC);
|
||||
if (test_bit(SDF_JOURNAL_LIVE, &sdp->sd_flags))
|
||||
gfs2_log_flush(sdp, NULL, GFS2_LOG_HEAD_FLUSH_FREEZE |
|
||||
GFS2_LFC_FREEZE_GO_SYNC);
|
||||
else /* read-only mounts */
|
||||
atomic_set(&sdp->sd_freeze_state, SFS_FROZEN);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -399,7 +399,6 @@ enum {
|
||||
GIF_QD_LOCKED = 1,
|
||||
GIF_ALLOC_FAILED = 2,
|
||||
GIF_SW_PAGED = 3,
|
||||
GIF_ORDERED = 4,
|
||||
GIF_FREE_VFS_INODE = 5,
|
||||
GIF_GLOP_PENDING = 6,
|
||||
GIF_DEFERRED_DELETE = 7,
|
||||
|
@ -207,10 +207,11 @@ struct inode *gfs2_inode_lookup(struct super_block *sb, unsigned int type,
|
||||
|
||||
if (no_formal_ino && ip->i_no_formal_ino &&
|
||||
no_formal_ino != ip->i_no_formal_ino) {
|
||||
error = -ESTALE;
|
||||
if (inode->i_state & I_NEW)
|
||||
goto fail;
|
||||
iput(inode);
|
||||
return ERR_PTR(-ESTALE);
|
||||
return ERR_PTR(error);
|
||||
}
|
||||
|
||||
if (inode->i_state & I_NEW)
|
||||
|
@ -613,6 +613,12 @@ static int ip_cmp(void *priv, struct list_head *a, struct list_head *b)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __ordered_del_inode(struct gfs2_inode *ip)
|
||||
{
|
||||
if (!list_empty(&ip->i_ordered))
|
||||
list_del_init(&ip->i_ordered);
|
||||
}
|
||||
|
||||
static void gfs2_ordered_write(struct gfs2_sbd *sdp)
|
||||
{
|
||||
struct gfs2_inode *ip;
|
||||
@ -623,8 +629,7 @@ static void gfs2_ordered_write(struct gfs2_sbd *sdp)
|
||||
while (!list_empty(&sdp->sd_log_ordered)) {
|
||||
ip = list_first_entry(&sdp->sd_log_ordered, struct gfs2_inode, i_ordered);
|
||||
if (ip->i_inode.i_mapping->nrpages == 0) {
|
||||
test_and_clear_bit(GIF_ORDERED, &ip->i_flags);
|
||||
list_del(&ip->i_ordered);
|
||||
__ordered_del_inode(ip);
|
||||
continue;
|
||||
}
|
||||
list_move(&ip->i_ordered, &written);
|
||||
@ -643,8 +648,7 @@ static void gfs2_ordered_wait(struct gfs2_sbd *sdp)
|
||||
spin_lock(&sdp->sd_ordered_lock);
|
||||
while (!list_empty(&sdp->sd_log_ordered)) {
|
||||
ip = list_first_entry(&sdp->sd_log_ordered, struct gfs2_inode, i_ordered);
|
||||
list_del(&ip->i_ordered);
|
||||
WARN_ON(!test_and_clear_bit(GIF_ORDERED, &ip->i_flags));
|
||||
__ordered_del_inode(ip);
|
||||
if (ip->i_inode.i_mapping->nrpages == 0)
|
||||
continue;
|
||||
spin_unlock(&sdp->sd_ordered_lock);
|
||||
@ -659,8 +663,7 @@ void gfs2_ordered_del_inode(struct gfs2_inode *ip)
|
||||
struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
|
||||
|
||||
spin_lock(&sdp->sd_ordered_lock);
|
||||
if (test_and_clear_bit(GIF_ORDERED, &ip->i_flags))
|
||||
list_del(&ip->i_ordered);
|
||||
__ordered_del_inode(ip);
|
||||
spin_unlock(&sdp->sd_ordered_lock);
|
||||
}
|
||||
|
||||
@ -1002,6 +1005,16 @@ void gfs2_log_flush(struct gfs2_sbd *sdp, struct gfs2_glock *gl, u32 flags)
|
||||
|
||||
out:
|
||||
if (gfs2_withdrawn(sdp)) {
|
||||
/**
|
||||
* If the tr_list is empty, we're withdrawing during a log
|
||||
* flush that targets a transaction, but the transaction was
|
||||
* never queued onto any of the ail lists. Here we add it to
|
||||
* ail1 just so that ail_drain() will find and free it.
|
||||
*/
|
||||
spin_lock(&sdp->sd_ail_lock);
|
||||
if (tr && list_empty(&tr->tr_list))
|
||||
list_add(&tr->tr_list, &sdp->sd_ail1_list);
|
||||
spin_unlock(&sdp->sd_ail_lock);
|
||||
ail_drain(sdp); /* frees all transactions */
|
||||
tr = NULL;
|
||||
}
|
||||
|
@ -53,9 +53,9 @@ static inline void gfs2_ordered_add_inode(struct gfs2_inode *ip)
|
||||
if (gfs2_is_jdata(ip) || !gfs2_is_ordered(sdp))
|
||||
return;
|
||||
|
||||
if (!test_bit(GIF_ORDERED, &ip->i_flags)) {
|
||||
if (list_empty(&ip->i_ordered)) {
|
||||
spin_lock(&sdp->sd_ordered_lock);
|
||||
if (!test_and_set_bit(GIF_ORDERED, &ip->i_flags))
|
||||
if (list_empty(&ip->i_ordered))
|
||||
list_add(&ip->i_ordered, &sdp->sd_log_ordered);
|
||||
spin_unlock(&sdp->sd_ordered_lock);
|
||||
}
|
||||
|
@ -39,6 +39,7 @@ static void gfs2_init_inode_once(void *foo)
|
||||
atomic_set(&ip->i_sizehint, 0);
|
||||
init_rwsem(&ip->i_rw_mutex);
|
||||
INIT_LIST_HEAD(&ip->i_trunc_list);
|
||||
INIT_LIST_HEAD(&ip->i_ordered);
|
||||
ip->i_qadata = NULL;
|
||||
gfs2_holder_mark_uninitialized(&ip->i_rgd_gh);
|
||||
memset(&ip->i_res, 0, sizeof(ip->i_res));
|
||||
|
@ -1136,7 +1136,18 @@ static int gfs2_fill_super(struct super_block *sb, struct fs_context *fc)
|
||||
goto fail_per_node;
|
||||
}
|
||||
|
||||
if (!sb_rdonly(sb)) {
|
||||
if (sb_rdonly(sb)) {
|
||||
struct gfs2_holder freeze_gh;
|
||||
|
||||
error = gfs2_glock_nq_init(sdp->sd_freeze_gl, LM_ST_SHARED,
|
||||
LM_FLAG_NOEXP | GL_EXACT,
|
||||
&freeze_gh);
|
||||
if (error) {
|
||||
fs_err(sdp, "can't make FS RO: %d\n", error);
|
||||
goto fail_per_node;
|
||||
}
|
||||
gfs2_glock_dq_uninit(&freeze_gh);
|
||||
} else {
|
||||
error = gfs2_make_fs_rw(sdp);
|
||||
if (error) {
|
||||
fs_err(sdp, "can't make FS RW: %d\n", error);
|
||||
|
@ -364,8 +364,8 @@ void gfs2_recover_func(struct work_struct *work)
|
||||
/* Acquire a shared hold on the freeze lock */
|
||||
|
||||
error = gfs2_glock_nq_init(sdp->sd_freeze_gl, LM_ST_SHARED,
|
||||
LM_FLAG_NOEXP | LM_FLAG_PRIORITY,
|
||||
&thaw_gh);
|
||||
LM_FLAG_NOEXP | LM_FLAG_PRIORITY |
|
||||
GL_EXACT, &thaw_gh);
|
||||
if (error)
|
||||
goto fail_gunlock_ji;
|
||||
|
||||
|
@ -167,7 +167,8 @@ int gfs2_make_fs_rw(struct gfs2_sbd *sdp)
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
error = gfs2_glock_nq_init(sdp->sd_freeze_gl, LM_ST_SHARED, 0,
|
||||
error = gfs2_glock_nq_init(sdp->sd_freeze_gl, LM_ST_SHARED,
|
||||
LM_FLAG_NOEXP | GL_EXACT,
|
||||
&freeze_gh);
|
||||
if (error)
|
||||
goto fail_threads;
|
||||
@ -203,7 +204,6 @@ int gfs2_make_fs_rw(struct gfs2_sbd *sdp)
|
||||
return 0;
|
||||
|
||||
fail:
|
||||
freeze_gh.gh_flags |= GL_NOCACHE;
|
||||
gfs2_glock_dq_uninit(&freeze_gh);
|
||||
fail_threads:
|
||||
if (sdp->sd_quotad_process)
|
||||
@ -430,7 +430,7 @@ static int gfs2_lock_fs_check_clean(struct gfs2_sbd *sdp)
|
||||
}
|
||||
|
||||
error = gfs2_glock_nq_init(sdp->sd_freeze_gl, LM_ST_EXCLUSIVE,
|
||||
GL_NOCACHE, &sdp->sd_freeze_gh);
|
||||
LM_FLAG_NOEXP, &sdp->sd_freeze_gh);
|
||||
if (error)
|
||||
goto out;
|
||||
|
||||
@ -613,13 +613,15 @@ int gfs2_make_fs_ro(struct gfs2_sbd *sdp)
|
||||
!gfs2_glock_is_locked_by_me(sdp->sd_freeze_gl)) {
|
||||
if (!log_write_allowed) {
|
||||
error = gfs2_glock_nq_init(sdp->sd_freeze_gl,
|
||||
LM_ST_SHARED, GL_NOCACHE |
|
||||
LM_FLAG_TRY, &freeze_gh);
|
||||
LM_ST_SHARED, LM_FLAG_TRY |
|
||||
LM_FLAG_NOEXP | GL_EXACT,
|
||||
&freeze_gh);
|
||||
if (error == GLR_TRYFAILED)
|
||||
error = 0;
|
||||
} else {
|
||||
error = gfs2_glock_nq_init(sdp->sd_freeze_gl,
|
||||
LM_ST_SHARED, GL_NOCACHE,
|
||||
LM_ST_SHARED,
|
||||
LM_FLAG_NOEXP | GL_EXACT,
|
||||
&freeze_gh);
|
||||
if (error && !gfs2_withdrawn(sdp))
|
||||
return error;
|
||||
@ -761,8 +763,8 @@ void gfs2_freeze_func(struct work_struct *work)
|
||||
struct super_block *sb = sdp->sd_vfs;
|
||||
|
||||
atomic_inc(&sb->s_active);
|
||||
error = gfs2_glock_nq_init(sdp->sd_freeze_gl, LM_ST_SHARED, 0,
|
||||
&freeze_gh);
|
||||
error = gfs2_glock_nq_init(sdp->sd_freeze_gl, LM_ST_SHARED,
|
||||
LM_FLAG_NOEXP | GL_EXACT, &freeze_gh);
|
||||
if (error) {
|
||||
fs_info(sdp, "GFS2: couldn't get freeze lock : %d\n", error);
|
||||
gfs2_assert_withdraw(sdp, 0);
|
||||
@ -774,8 +776,6 @@ void gfs2_freeze_func(struct work_struct *work)
|
||||
error);
|
||||
gfs2_assert_withdraw(sdp, 0);
|
||||
}
|
||||
if (!test_bit(SDF_JOURNAL_LIVE, &sdp->sd_flags))
|
||||
freeze_gh.gh_flags |= GL_NOCACHE;
|
||||
gfs2_glock_dq_uninit(&freeze_gh);
|
||||
}
|
||||
deactivate_super(sb);
|
||||
|
Loading…
Reference in New Issue
Block a user