diff options
| -rw-r--r-- | fs/gfs2/glock.c | 8 | ||||
| -rw-r--r-- | fs/gfs2/glops.c | 18 | ||||
| -rw-r--r-- | fs/gfs2/inode.c | 6 | ||||
| -rw-r--r-- | fs/gfs2/main.c | 2 |
4 files changed, 23 insertions, 11 deletions
diff --git a/fs/gfs2/glock.c b/fs/gfs2/glock.c index 9435384562a2..544a809819c3 100644 --- a/fs/gfs2/glock.c +++ b/fs/gfs2/glock.c | |||
| @@ -1838,14 +1838,14 @@ int __init gfs2_glock_init(void) | |||
| 1838 | 1838 | ||
| 1839 | glock_workqueue = alloc_workqueue("glock_workqueue", WQ_MEM_RECLAIM | | 1839 | glock_workqueue = alloc_workqueue("glock_workqueue", WQ_MEM_RECLAIM | |
| 1840 | WQ_HIGHPRI | WQ_FREEZABLE, 0); | 1840 | WQ_HIGHPRI | WQ_FREEZABLE, 0); |
| 1841 | if (IS_ERR(glock_workqueue)) | 1841 | if (!glock_workqueue) |
| 1842 | return PTR_ERR(glock_workqueue); | 1842 | return -ENOMEM; |
| 1843 | gfs2_delete_workqueue = alloc_workqueue("delete_workqueue", | 1843 | gfs2_delete_workqueue = alloc_workqueue("delete_workqueue", |
| 1844 | WQ_MEM_RECLAIM | WQ_FREEZABLE, | 1844 | WQ_MEM_RECLAIM | WQ_FREEZABLE, |
| 1845 | 0); | 1845 | 0); |
| 1846 | if (IS_ERR(gfs2_delete_workqueue)) { | 1846 | if (!gfs2_delete_workqueue) { |
| 1847 | destroy_workqueue(glock_workqueue); | 1847 | destroy_workqueue(glock_workqueue); |
| 1848 | return PTR_ERR(gfs2_delete_workqueue); | 1848 | return -ENOMEM; |
| 1849 | } | 1849 | } |
| 1850 | 1850 | ||
| 1851 | register_shrinker(&glock_shrinker); | 1851 | register_shrinker(&glock_shrinker); |
diff --git a/fs/gfs2/glops.c b/fs/gfs2/glops.c index 5f2e5224c51c..e2e0a90396e7 100644 --- a/fs/gfs2/glops.c +++ b/fs/gfs2/glops.c | |||
| @@ -47,7 +47,8 @@ static void gfs2_ail_error(struct gfs2_glock *gl, const struct buffer_head *bh) | |||
| 47 | * None of the buffers should be dirty, locked, or pinned. | 47 | * None of the buffers should be dirty, locked, or pinned. |
| 48 | */ | 48 | */ |
| 49 | 49 | ||
| 50 | static void __gfs2_ail_flush(struct gfs2_glock *gl, bool fsync) | 50 | static void __gfs2_ail_flush(struct gfs2_glock *gl, bool fsync, |
| 51 | unsigned int nr_revokes) | ||
| 51 | { | 52 | { |
| 52 | struct gfs2_sbd *sdp = gl->gl_sbd; | 53 | struct gfs2_sbd *sdp = gl->gl_sbd; |
| 53 | struct list_head *head = &gl->gl_ail_list; | 54 | struct list_head *head = &gl->gl_ail_list; |
| @@ -57,7 +58,9 @@ static void __gfs2_ail_flush(struct gfs2_glock *gl, bool fsync) | |||
| 57 | 58 | ||
| 58 | gfs2_log_lock(sdp); | 59 | gfs2_log_lock(sdp); |
| 59 | spin_lock(&sdp->sd_ail_lock); | 60 | spin_lock(&sdp->sd_ail_lock); |
| 60 | list_for_each_entry_safe(bd, tmp, head, bd_ail_gl_list) { | 61 | list_for_each_entry_safe_reverse(bd, tmp, head, bd_ail_gl_list) { |
| 62 | if (nr_revokes == 0) | ||
| 63 | break; | ||
| 61 | bh = bd->bd_bh; | 64 | bh = bd->bd_bh; |
| 62 | if (bh->b_state & b_state) { | 65 | if (bh->b_state & b_state) { |
| 63 | if (fsync) | 66 | if (fsync) |
| @@ -65,6 +68,7 @@ static void __gfs2_ail_flush(struct gfs2_glock *gl, bool fsync) | |||
| 65 | gfs2_ail_error(gl, bh); | 68 | gfs2_ail_error(gl, bh); |
| 66 | } | 69 | } |
| 67 | gfs2_trans_add_revoke(sdp, bd); | 70 | gfs2_trans_add_revoke(sdp, bd); |
| 71 | nr_revokes--; | ||
| 68 | } | 72 | } |
| 69 | GLOCK_BUG_ON(gl, !fsync && atomic_read(&gl->gl_ail_count)); | 73 | GLOCK_BUG_ON(gl, !fsync && atomic_read(&gl->gl_ail_count)); |
| 70 | spin_unlock(&sdp->sd_ail_lock); | 74 | spin_unlock(&sdp->sd_ail_lock); |
| @@ -91,7 +95,7 @@ static void gfs2_ail_empty_gl(struct gfs2_glock *gl) | |||
| 91 | WARN_ON_ONCE(current->journal_info); | 95 | WARN_ON_ONCE(current->journal_info); |
| 92 | current->journal_info = &tr; | 96 | current->journal_info = &tr; |
| 93 | 97 | ||
| 94 | __gfs2_ail_flush(gl, 0); | 98 | __gfs2_ail_flush(gl, 0, tr.tr_revokes); |
| 95 | 99 | ||
| 96 | gfs2_trans_end(sdp); | 100 | gfs2_trans_end(sdp); |
| 97 | gfs2_log_flush(sdp, NULL); | 101 | gfs2_log_flush(sdp, NULL); |
| @@ -101,15 +105,19 @@ void gfs2_ail_flush(struct gfs2_glock *gl, bool fsync) | |||
| 101 | { | 105 | { |
| 102 | struct gfs2_sbd *sdp = gl->gl_sbd; | 106 | struct gfs2_sbd *sdp = gl->gl_sbd; |
| 103 | unsigned int revokes = atomic_read(&gl->gl_ail_count); | 107 | unsigned int revokes = atomic_read(&gl->gl_ail_count); |
| 108 | unsigned int max_revokes = (sdp->sd_sb.sb_bsize - sizeof(struct gfs2_log_descriptor)) / sizeof(u64); | ||
| 104 | int ret; | 109 | int ret; |
| 105 | 110 | ||
| 106 | if (!revokes) | 111 | if (!revokes) |
| 107 | return; | 112 | return; |
| 108 | 113 | ||
| 109 | ret = gfs2_trans_begin(sdp, 0, revokes); | 114 | while (revokes > max_revokes) |
| 115 | max_revokes += (sdp->sd_sb.sb_bsize - sizeof(struct gfs2_meta_header)) / sizeof(u64); | ||
| 116 | |||
| 117 | ret = gfs2_trans_begin(sdp, 0, max_revokes); | ||
| 110 | if (ret) | 118 | if (ret) |
| 111 | return; | 119 | return; |
| 112 | __gfs2_ail_flush(gl, fsync); | 120 | __gfs2_ail_flush(gl, fsync, max_revokes); |
| 113 | gfs2_trans_end(sdp); | 121 | gfs2_trans_end(sdp); |
| 114 | gfs2_log_flush(sdp, NULL); | 122 | gfs2_log_flush(sdp, NULL); |
| 115 | } | 123 | } |
diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c index bbb2715171cd..64915eeae5a7 100644 --- a/fs/gfs2/inode.c +++ b/fs/gfs2/inode.c | |||
| @@ -594,7 +594,7 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry, | |||
| 594 | } | 594 | } |
| 595 | gfs2_glock_dq_uninit(ghs); | 595 | gfs2_glock_dq_uninit(ghs); |
| 596 | if (IS_ERR(d)) | 596 | if (IS_ERR(d)) |
| 597 | return PTR_RET(d); | 597 | return PTR_ERR(d); |
| 598 | return error; | 598 | return error; |
| 599 | } else if (error != -ENOENT) { | 599 | } else if (error != -ENOENT) { |
| 600 | goto fail_gunlock; | 600 | goto fail_gunlock; |
| @@ -1750,6 +1750,10 @@ static ssize_t gfs2_getxattr(struct dentry *dentry, const char *name, | |||
| 1750 | struct gfs2_holder gh; | 1750 | struct gfs2_holder gh; |
| 1751 | int ret; | 1751 | int ret; |
| 1752 | 1752 | ||
| 1753 | /* For selinux during lookup */ | ||
| 1754 | if (gfs2_glock_is_locked_by_me(ip->i_gl)) | ||
| 1755 | return generic_getxattr(dentry, name, data, size); | ||
| 1756 | |||
| 1753 | gfs2_holder_init(ip->i_gl, LM_ST_SHARED, LM_FLAG_ANY, &gh); | 1757 | gfs2_holder_init(ip->i_gl, LM_ST_SHARED, LM_FLAG_ANY, &gh); |
| 1754 | ret = gfs2_glock_nq(&gh); | 1758 | ret = gfs2_glock_nq(&gh); |
| 1755 | if (ret == 0) { | 1759 | if (ret == 0) { |
diff --git a/fs/gfs2/main.c b/fs/gfs2/main.c index e04d0e09ee7b..7b0f5043cf24 100644 --- a/fs/gfs2/main.c +++ b/fs/gfs2/main.c | |||
| @@ -155,7 +155,7 @@ static int __init init_gfs2_fs(void) | |||
| 155 | goto fail_wq; | 155 | goto fail_wq; |
| 156 | 156 | ||
| 157 | gfs2_control_wq = alloc_workqueue("gfs2_control", | 157 | gfs2_control_wq = alloc_workqueue("gfs2_control", |
| 158 | WQ_NON_REENTRANT | WQ_UNBOUND | WQ_FREEZABLE, 0); | 158 | WQ_UNBOUND | WQ_FREEZABLE, 0); |
| 159 | if (!gfs2_control_wq) | 159 | if (!gfs2_control_wq) |
| 160 | goto fail_recovery; | 160 | goto fail_recovery; |
| 161 | 161 | ||
