Re: [Cluster-devel] [RHEL7.9.z PATCH 1/2] gfs2: Add common helper for holding and releasing the freeze glock

2020-12-14 Thread Andreas Gruenbacher
Hi Bob,

On Thu, Dec 3, 2020 at 4:23 PM Bob Peterson  wrote:
> Many places in the gfs2 code queued and dequeued the freeze glock.
> Almost all of them acquire it in SHARED mode, and need to specify the
> same LM_FLAG_NOEXP and GL_EXACT flags.
>
> This patch adds common helper functions gfs2_freeze_lock and 
> gfs2_freeze_unlock
> to make the code more readable, and to prepare for the next patch.
>
> Signed-off-by: Bob Peterson 
> ---
>  fs/gfs2/ops_fstype.c |  6 ++
>  fs/gfs2/recovery.c   |  6 ++
>  fs/gfs2/super.c  | 45 +++-
>  fs/gfs2/util.c   | 35 ++
>  fs/gfs2/util.h   |  3 +++
>  5 files changed, 57 insertions(+), 38 deletions(-)
>
> diff --git a/fs/gfs2/ops_fstype.c b/fs/gfs2/ops_fstype.c
> index 61fce59cb4d3..4ee56f5e93cb 100644
> --- a/fs/gfs2/ops_fstype.c
> +++ b/fs/gfs2/ops_fstype.c
> @@ -1198,14 +1198,12 @@ static int gfs2_fill_super(struct super_block *sb, 
> struct fs_context *fc)
> 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,
> -  _gh);
> +   error = gfs2_freeze_lock(sdp, _gh, 0);
> if (error) {
> fs_err(sdp, "can't make FS RO: %d\n", error);
> goto fail_per_node;
> }
> -   gfs2_glock_dq_uninit(_gh);
> +   gfs2_freeze_unlock(_gh);
> } else {
> error = gfs2_make_fs_rw(sdp);
> if (error) {
> diff --git a/fs/gfs2/recovery.c b/fs/gfs2/recovery.c
> index c26c68ebd29d..2208b0e2dc8c 100644
> --- a/fs/gfs2/recovery.c
> +++ b/fs/gfs2/recovery.c
> @@ -470,9 +470,7 @@ 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 |
> -  GL_EXACT, _gh);
> +   error = gfs2_freeze_lock(sdp, _gh, LM_FLAG_PRIORITY);
> if (error)
> goto fail_gunlock_ji;
>
> @@ -522,7 +520,7 @@ void gfs2_recover_func(struct work_struct *work)
> clean_journal(jd, );
> up_read(>sd_log_flush_lock);
>
> -   gfs2_glock_dq_uninit(_gh);
> +   gfs2_freeze_unlock(_gh);
> t_rep = ktime_get();
> fs_info(sdp, "jid=%u: Journal replayed in %lldms 
> [jlck:%lldms, "
> "jhead:%lldms, tlck:%lldms, replay:%lldms]\n",

The gfs2_glock_dq_uninit(_gh) at label fail_gunlock_thaw needs to
be turned into gfs2_freeze_unlock(_gh) as well.

> diff --git a/fs/gfs2/super.c b/fs/gfs2/super.c
> index 2f56acc41c04..801361a05e6f 100644
> --- a/fs/gfs2/super.c
> +++ b/fs/gfs2/super.c
> @@ -173,9 +173,7 @@ 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,
> -  LM_FLAG_NOEXP | GL_EXACT,
> -  _gh);
> +   error = gfs2_freeze_lock(sdp, _gh, 0);
> if (error)
> goto fail_threads;
>
> @@ -205,12 +203,12 @@ int gfs2_make_fs_rw(struct gfs2_sbd *sdp)
>
> set_bit(SDF_JOURNAL_LIVE, >sd_flags);
>
> -   gfs2_glock_dq_uninit(_gh);
> +   gfs2_freeze_unlock(_gh);
>
> return 0;
>
>  fail:
> -   gfs2_glock_dq_uninit(_gh);
> +   gfs2_freeze_unlock(_gh);
>  fail_threads:
> if (sdp->sd_quotad_process)
> kthread_stop(sdp->sd_quotad_process);
> @@ -452,7 +450,7 @@ static int gfs2_lock_fs_check_clean(struct gfs2_sbd *sdp)
> }
>
> if (error)
> -   gfs2_glock_dq_uninit(>sd_freeze_gh);
> +   gfs2_freeze_unlock(>sd_freeze_gh);
>
>  out:
> while (!list_empty()) {
> @@ -614,23 +612,13 @@ int gfs2_make_fs_ro(struct gfs2_sbd *sdp)
> int log_write_allowed = test_bit(SDF_JOURNAL_LIVE, >sd_flags);
>
> gfs2_holder_mark_uninitialized(_gh);
> -   if (sdp->sd_freeze_gl &&
> -   !gfs2_glock_is_locked_by_me(sdp->sd_freeze_gl)) {

Nooo, please leave the gfs2_glock_is_locked_by_me checking at the few
callers that actually need it. That check doesn't come for free, and
it also makes the code more difficult to understand.

> -   if (!log_write_allowed) {
> -   error = gfs2_glock_nq_init(sdp->sd_freeze_gl,
> -  LM_ST_SHARED, LM_FLAG_TRY |
> -  LM_FLAG_NOEXP | GL_EXACT,
> -  _gh);
> -   if (error == 

Re: [Cluster-devel] [PATCH 07/12] gfs2: Get rid of on-stack transactions

2020-12-14 Thread Steven Whitehouse

Hi,

On 14/12/2020 14:02, Bob Peterson wrote:

Hi,

- Original Message -

+   ret = __gfs2_trans_begin(sdp, 0, revokes, GFP_NOFS | __GFP_NOFAIL);

The addition of __GFP_NOFAIL means that this operation can now block.
Looking at the code, I don't think it will be a problem because it can
already block in the log_flush operations that precede it, but it
makes me nervous. Obviously, we need to test this really well.

Bob

Not sure of the context here exactly, but why are we adding an instance 
of __GFP_NOFAIL? There is already a return code there so that we can 
fail in that case if required,


Steve.




Re: [Cluster-devel] [PATCH 07/12] gfs2: Get rid of on-stack transactions

2020-12-14 Thread Bob Peterson
Hi,

- Original Message -
> + ret = __gfs2_trans_begin(sdp, 0, revokes, GFP_NOFS | __GFP_NOFAIL);

The addition of __GFP_NOFAIL means that this operation can now block.
Looking at the code, I don't think it will be a problem because it can
already block in the log_flush operations that precede it, but it
makes me nervous. Obviously, we need to test this really well.

Bob



Re: [Cluster-devel] Recording extents in GFS2

2020-12-14 Thread Steven Whitehouse

Hi,

On 11/12/2020 16:38, Abhijith Das wrote:

Hi all,

With a recent set of patches, we nearly eliminated the per_node statfs
change files by recording that info in the journal. The files and some
recovery code remain only for backward compatibility. Similarly, I'd
like to get rid of the per_node quota change files and record that
info in the journal as well.

I've been talking to Andreas and Bob a bit about this and I'm
investigating how we can record extents as we allocate and deallocate
blocks instead of writing whole blocks. I'm looking into how XFS does
this.

We could have a new journal block type that adds a list of extents to
inodes with alloc/dealloc info. We could add in quota (uid/gid) info
to this as well. If we can do this right, the representation of
alloc/dealloc becomes compact and consequently we use journal space
more efficiently. We can hopefully avoid cases where we need to zero
out blocks during allocation as well.

I'm sending this out to start a discussion and to get ideas/comments/pointers.

Cheers!
--Abhi

I think you need to propose something a bit more concrete. For example 
what will the data structures look like? How many entries will fit in a 
journal block at different block sizes? How will we ensure that this is 
backwards compatible? That will make it easier to have the discussions,


Steve.




[Cluster-devel] [PATCH 10/12] gfs2: Don't wait for journal flush in clean_journal

2020-12-14 Thread Andreas Gruenbacher
Commit 588bff95c94e added gfs2_write_log_header() and started using it in
clean_journal(), with an additional call to log_flush_wait() at the end of
gfs2_write_log_header() which is unnecessary for clean_journal().  Move
that call out of gfs2_write_log_header() to restore the previous behavior.

Signed-off-by: Andreas Gruenbacher 
---
 fs/gfs2/log.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/fs/gfs2/log.c b/fs/gfs2/log.c
index b0d4ce4992ed..a8cc71ba4852 100644
--- a/fs/gfs2/log.c
+++ b/fs/gfs2/log.c
@@ -756,7 +756,7 @@ void gfs2_write_log_header(struct gfs2_sbd *sdp, struct 
gfs2_jdesc *jd,
u64 dblock;
 
if (gfs2_withdrawn(sdp))
-   goto out;
+   return;
 
page = mempool_alloc(gfs2_page_pool, GFP_NOIO);
lh = page_address(page);
@@ -811,8 +811,6 @@ void gfs2_write_log_header(struct gfs2_sbd *sdp, struct 
gfs2_jdesc *jd,
 
gfs2_log_write(sdp, page, sb->s_blocksize, 0, dblock);
gfs2_log_submit_bio(>sd_log_bio, REQ_OP_WRITE | op_flags);
-out:
-   log_flush_wait(sdp);
 }
 
 /**
@@ -841,6 +839,7 @@ static void log_write_header(struct gfs2_sbd *sdp, u32 
flags)
gfs2_write_log_header(sdp, sdp->sd_jdesc, sdp->sd_log_sequence++, tail,
  sdp->sd_log_flush_head, flags, op_flags);
gfs2_log_incr_head(sdp);
+   log_flush_wait(sdp);
 
if (sdp->sd_log_tail != tail)
log_pull_tail(sdp, tail);
-- 
2.26.2



[Cluster-devel] [PATCH 09/12] gfs2: Move lock flush locking to gfs2_trans_{begin, end}

2020-12-14 Thread Andreas Gruenbacher
Move the read locking of sd_log_flush_lock from gfs2_log_reserve to
gfs2_trans_begin, and its unlocking from gfs2_log_release to
gfs2_trans_end.  Use gfs2_log_release in two places in which it was open
coded before.

Signed-off-by: Andreas Gruenbacher 
---
 fs/gfs2/log.c   | 28 +++-
 fs/gfs2/log.h   |  2 +-
 fs/gfs2/trans.c | 23 ---
 3 files changed, 20 insertions(+), 33 deletions(-)

diff --git a/fs/gfs2/log.c b/fs/gfs2/log.c
index 8c46f8f64c9e..b0d4ce4992ed 100644
--- a/fs/gfs2/log.c
+++ b/fs/gfs2/log.c
@@ -411,7 +411,6 @@ void gfs2_log_release(struct gfs2_sbd *sdp, unsigned int 
blks)
trace_gfs2_log_blocks(sdp, blks);
gfs2_assert_withdraw(sdp, atomic_read(>sd_log_blks_free) <=
  sdp->sd_jdesc->jd_blocks);
-   up_read(>sd_log_flush_lock);
 }
 
 /**
@@ -439,22 +438,16 @@ bool gfs2_log_is_empty(struct gfs2_sbd *sdp) {
  * with queued waiters, we use an exclusive wait. This means that when we
  * get woken with enough journal space to get our reservation, we need to
  * wake the next waiter on the list.
- *
- * Returns: errno
  */
 
-int gfs2_log_reserve(struct gfs2_sbd *sdp, unsigned int blks)
+void gfs2_log_reserve(struct gfs2_sbd *sdp, unsigned int blks)
 {
-   int ret = 0;
unsigned reserved_blks = 7 * (4096 / sdp->sd_vfs->s_blocksize);
unsigned wanted = blks + reserved_blks;
DEFINE_WAIT(wait);
int did_wait = 0;
unsigned int free_blocks;
 
-   if (gfs2_assert_warn(sdp, blks) ||
-   gfs2_assert_warn(sdp, blks <= sdp->sd_jdesc->jd_blocks))
-   return -EINVAL;
atomic_add(blks, >sd_log_blks_needed);
 retry:
free_blocks = atomic_read(>sd_log_blks_free);
@@ -482,13 +475,6 @@ int gfs2_log_reserve(struct gfs2_sbd *sdp, unsigned int 
blks)
 */
if (unlikely(did_wait))
wake_up(>sd_log_waitq);
-
-   down_read(>sd_log_flush_lock);
-   if (unlikely(!test_bit(SDF_JOURNAL_LIVE, >sd_flags))) {
-   gfs2_log_release(sdp, blks);
-   ret = -EROFS;
-   }
-   return ret;
 }
 
 /**
@@ -585,12 +571,7 @@ static void log_pull_tail(struct gfs2_sbd *sdp, unsigned 
int new_tail)
unsigned int dist = log_distance(sdp, new_tail, sdp->sd_log_tail);
 
ail2_empty(sdp, new_tail);
-
-   atomic_add(dist, >sd_log_blks_free);
-   trace_gfs2_log_blocks(sdp, dist);
-   gfs2_assert_withdraw(sdp, atomic_read(>sd_log_blks_free) <=
-sdp->sd_jdesc->jd_blocks);
-
+   gfs2_log_release(sdp, dist);
sdp->sd_log_tail = new_tail;
 }
 
@@ -1125,10 +1106,7 @@ static void log_refund(struct gfs2_sbd *sdp, struct 
gfs2_trans *tr)
maxres = sdp->sd_log_blks_reserved + tr->tr_reserved;
gfs2_assert_withdraw(sdp, maxres >= reserved);
unused = maxres - reserved;
-   atomic_add(unused, >sd_log_blks_free);
-   trace_gfs2_log_blocks(sdp, unused);
-   gfs2_assert_withdraw(sdp, atomic_read(>sd_log_blks_free) <=
-sdp->sd_jdesc->jd_blocks);
+   gfs2_log_release(sdp, unused);
sdp->sd_log_blks_reserved = reserved;
 
gfs2_log_unlock(sdp);
diff --git a/fs/gfs2/log.h b/fs/gfs2/log.h
index f483e706db3a..db3bb3564ea0 100644
--- a/fs/gfs2/log.h
+++ b/fs/gfs2/log.h
@@ -65,7 +65,7 @@ extern void gfs2_ordered_del_inode(struct gfs2_inode *ip);
 extern unsigned int gfs2_struct2blk(struct gfs2_sbd *sdp, unsigned int 
nstruct);
 extern void gfs2_remove_from_ail(struct gfs2_bufdata *bd);
 extern void gfs2_log_release(struct gfs2_sbd *sdp, unsigned int blks);
-extern int gfs2_log_reserve(struct gfs2_sbd *sdp, unsigned int blks);
+extern void gfs2_log_reserve(struct gfs2_sbd *sdp, unsigned int blks);
 extern bool gfs2_log_is_empty(struct gfs2_sbd *sdp);
 extern void gfs2_write_log_header(struct gfs2_sbd *sdp, struct gfs2_jdesc *jd,
  u64 seq, u32 tail, u32 lblock, u32 flags,
diff --git a/fs/gfs2/trans.c b/fs/gfs2/trans.c
index e33cb8da056a..c9d8247ffa19 100644
--- a/fs/gfs2/trans.c
+++ b/fs/gfs2/trans.c
@@ -70,12 +70,22 @@ int __gfs2_trans_begin(struct gfs2_sbd *sdp, unsigned int 
blocks,
INIT_LIST_HEAD(>tr_ail1_list);
INIT_LIST_HEAD(>tr_ail2_list);
 
+   if (gfs2_assert_warn(sdp, tr->tr_reserved <= sdp->sd_jdesc->jd_blocks)) 
{
+   error = -EINVAL;
+   goto fail;
+   }
+
sb_start_intwrite(sdp->sd_vfs);
 
-   error = gfs2_log_reserve(sdp, tr->tr_reserved);
-   if (error) {
-   if (error == -EROFS)
-   wake_up(>sd_log_waitq);
+   gfs2_log_reserve(sdp, tr->tr_reserved);
+
+   down_read(>sd_log_flush_lock);
+   if (unlikely(!test_bit(SDF_JOURNAL_LIVE, >sd_flags))) {
+   gfs2_log_release(sdp, tr->tr_reserved);
+   up_read(>sd_log_flush_lock);
+   sb_end_intwrite(sdp->sd_vfs);
+   wake_up(>sd_log_waitq);
+

[Cluster-devel] [PATCH 03/12] gfs2: Minor gfs2_write_revokes cleanups

2020-12-14 Thread Andreas Gruenbacher
Clean up the computations in gfs2_write_revokes (no change in functionality).

Signed-off-by: Andreas Gruenbacher 
---
 fs/gfs2/log.c | 7 ---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/fs/gfs2/log.c b/fs/gfs2/log.c
index 2e9314091c81..c65fdb1a30a0 100644
--- a/fs/gfs2/log.c
+++ b/fs/gfs2/log.c
@@ -712,11 +712,12 @@ void gfs2_glock_remove_revoke(struct gfs2_glock *gl)
 void gfs2_write_revokes(struct gfs2_sbd *sdp)
 {
/* number of revokes we still have room for */
-   int max_revokes = (sdp->sd_sb.sb_bsize - sizeof(struct 
gfs2_log_descriptor)) / sizeof(u64);
+   unsigned int max_revokes = sdp->sd_ldptrs;
 
gfs2_log_lock(sdp);
-   while (sdp->sd_log_num_revoke > max_revokes)
-   max_revokes += (sdp->sd_sb.sb_bsize - sizeof(struct 
gfs2_meta_header)) / sizeof(u64);
+   if (sdp->sd_log_num_revoke > sdp->sd_ldptrs)
+   max_revokes += roundup(sdp->sd_log_num_revoke - sdp->sd_ldptrs,
+  sdp->sd_inptrs);
max_revokes -= sdp->sd_log_num_revoke;
if (!sdp->sd_log_num_revoke) {
atomic_dec(>sd_log_blks_free);
-- 
2.26.2



[Cluster-devel] [PATCH 04/12] gfs2: Some documentation clarifications

2020-12-14 Thread Andreas Gruenbacher
The calc_reserved description claims that buf_limit is 502 (on 4k
filesystems), but it is actually 503.  Fix / clarify the entire
description.

Signed-off-by: Andreas Gruenbacher 
---
 fs/gfs2/log.c | 24 +++-
 1 file changed, 11 insertions(+), 13 deletions(-)

diff --git a/fs/gfs2/log.c b/fs/gfs2/log.c
index c65fdb1a30a0..f7c225520c38 100644
--- a/fs/gfs2/log.c
+++ b/fs/gfs2/log.c
@@ -50,10 +50,12 @@ unsigned int gfs2_struct2blk(struct gfs2_sbd *sdp, unsigned 
int nstruct)
unsigned int blks;
unsigned int first, second;
 
+   /* The initial struct gfs2_log_descriptor block */
blks = 1;
first = sdp->sd_ldptrs;
 
if (nstruct > first) {
+   /* Subsequent struct gfs2_meta_header blocks */
second = sdp->sd_inptrs;
blks += DIV_ROUND_UP(nstruct - first, second);
}
@@ -507,24 +509,20 @@ static inline unsigned int log_distance(struct gfs2_sbd 
*sdp, unsigned int newer
 }
 
 /**
- * calc_reserved - Calculate the number of blocks to reserve when
- * refunding a transaction's unused buffers.
+ * calc_reserved - Calculate the number of blocks to keep reserved
  * @sdp: The GFS2 superblock
  *
  * This is complex.  We need to reserve room for all our currently used
- * metadata buffers (e.g. normal file I/O rewriting file time stamps) and 
- * all our journaled data buffers for journaled files (e.g. files in the 
+ * metadata blocks (e.g. normal file I/O rewriting file time stamps) and
+ * all our journaled data blocks for journaled files (e.g. files in the
  * meta_fs like rindex, or files for which chattr +j was done.)
- * If we don't reserve enough space, gfs2_log_refund and gfs2_log_flush
- * will count it as free space (sd_log_blks_free) and corruption will follow.
+ * If we don't reserve enough space, corruption will follow.
  *
- * We can have metadata bufs and jdata bufs in the same journal.  So each
- * type gets its own log header, for which we need to reserve a block.
- * In fact, each type has the potential for needing more than one header 
- * in cases where we have more buffers than will fit on a journal page.
+ * We can have metadata blocks and jdata blocks in the same journal.  Each
+ * type gets its own log descriptor, for which we need to reserve a block.
+ * In fact, each type has the potential for needing more than one log 
descriptor
+ * in cases where we have more blocks than will fit in a log descriptor.
  * Metadata journal entries take up half the space of journaled buffer entries.
- * Thus, metadata entries have buf_limit (502) and journaled buffers have
- * databuf_limit (251) before they cause a wrap around.
  *
  * Also, we need to reserve blocks for revoke journal entries and one for an
  * overall header for the lot.
@@ -1007,7 +1005,7 @@ void gfs2_log_flush(struct gfs2_sbd *sdp, struct 
gfs2_glock *gl, u32 flags)
if (sdp->sd_log_head != sdp->sd_log_flush_head) {
log_flush_wait(sdp);
log_write_header(sdp, flags);
-   } else if (sdp->sd_log_tail != current_tail(sdp) && !sdp->sd_log_idle){
+   } else if (sdp->sd_log_tail != current_tail(sdp) && !sdp->sd_log_idle) {
atomic_dec(>sd_log_blks_free); /* Adjust for unreserved 
buffer */
trace_gfs2_log_blocks(sdp, -1);
log_write_header(sdp, flags);
-- 
2.26.2



[Cluster-devel] [PATCH 06/12] gfs2: Clean up ail2_empty

2020-12-14 Thread Andreas Gruenbacher
Clean up the logic in ail2_empty (no functional change).

Signed-off-by: Andreas Gruenbacher 
---
 fs/gfs2/log.c | 38 +-
 1 file changed, 21 insertions(+), 17 deletions(-)

diff --git a/fs/gfs2/log.c b/fs/gfs2/log.c
index f7c225520c38..33f7b1544958 100644
--- a/fs/gfs2/log.c
+++ b/fs/gfs2/log.c
@@ -367,29 +367,33 @@ static void gfs2_ail_empty_tr(struct gfs2_sbd *sdp, 
struct gfs2_trans *tr,
}
 }
 
+static void __ail2_empty(struct gfs2_sbd *sdp, struct gfs2_trans *tr)
+{
+   gfs2_ail_empty_tr(sdp, tr, >tr_ail2_list);
+   list_del(>tr_list);
+   gfs2_assert_warn(sdp, list_empty(>tr_ail1_list));
+   gfs2_assert_warn(sdp, list_empty(>tr_ail2_list));
+   gfs2_trans_free(sdp, tr);
+}
+
 static void ail2_empty(struct gfs2_sbd *sdp, unsigned int new_tail)
 {
-   struct gfs2_trans *tr, *safe;
+   struct list_head *ail2_list = >sd_ail2_list;
unsigned int old_tail = sdp->sd_log_tail;
-   int wrap = (new_tail < old_tail);
-   int a, b, rm;
+   struct gfs2_trans *tr, *safe;
 
spin_lock(>sd_ail_lock);
-
-   list_for_each_entry_safe(tr, safe, >sd_ail2_list, tr_list) {
-   a = (old_tail <= tr->tr_first);
-   b = (tr->tr_first < new_tail);
-   rm = (wrap) ? (a || b) : (a && b);
-   if (!rm)
-   continue;
-
-   gfs2_ail_empty_tr(sdp, tr, >tr_ail2_list);
-   list_del(>tr_list);
-   gfs2_assert_warn(sdp, list_empty(>tr_ail1_list));
-   gfs2_assert_warn(sdp, list_empty(>tr_ail2_list));
-   gfs2_trans_free(sdp, tr);
+   if (old_tail <= new_tail) {
+   list_for_each_entry_safe(tr, safe, ail2_list, tr_list) {
+   if (old_tail <= tr->tr_first && tr->tr_first < new_tail)
+   __ail2_empty(sdp, tr);
+   }
+   } else {
+   list_for_each_entry_safe(tr, safe, ail2_list, tr_list) {
+   if (old_tail <= tr->tr_first || tr->tr_first < new_tail)
+   __ail2_empty(sdp, tr);
+   }
}
-
spin_unlock(>sd_ail_lock);
 }
 
-- 
2.26.2



[Cluster-devel] [PATCH 05/12] gfs2: A minor debugging improvement

2020-12-14 Thread Andreas Gruenbacher
Split the assert in gfs2_trans_end into two parts.

Signed-off-by: Andreas Gruenbacher 
---
 fs/gfs2/trans.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/fs/gfs2/trans.c b/fs/gfs2/trans.c
index 6d4bf7ea7b3b..7705f04621f4 100644
--- a/fs/gfs2/trans.c
+++ b/fs/gfs2/trans.c
@@ -109,8 +109,8 @@ void gfs2_trans_end(struct gfs2_sbd *sdp)
nbuf -= tr->tr_num_buf_rm;
nbuf -= tr->tr_num_databuf_rm;
 
-   if (gfs2_assert_withdraw(sdp, (nbuf <= tr->tr_blocks) &&
-  (tr->tr_num_revoke <= tr->tr_revokes)))
+   if (gfs2_assert_withdraw(sdp, nbuf <= tr->tr_blocks) ||
+   gfs2_assert_withdraw(sdp, tr->tr_num_revoke <= tr->tr_revokes))
gfs2_print_trans(sdp, tr);
 
gfs2_log_commit(sdp, tr);
-- 
2.26.2



[Cluster-devel] [PATCH 02/12] gfs2: Simplify the buf_limit and databuf_limit definitions

2020-12-14 Thread Andreas Gruenbacher
The BUF_OFFSET and DATABUF_OFFSET definitions are only used in buf_limit
and databuf_limit, respectively, and the rounding done in those
definitions is immediately wiped out by dividing by the element size.

Signed-off-by: Andreas Gruenbacher 
---
 fs/gfs2/lops.h | 17 ++---
 1 file changed, 2 insertions(+), 15 deletions(-)

diff --git a/fs/gfs2/lops.h b/fs/gfs2/lops.h
index fbdbb08dcec6..3fca5bf239d3 100644
--- a/fs/gfs2/lops.h
+++ b/fs/gfs2/lops.h
@@ -10,13 +10,6 @@
 #include 
 #include "incore.h"
 
-#define BUF_OFFSET \
-   ((sizeof(struct gfs2_log_descriptor) + sizeof(__be64) - 1) & \
-~(sizeof(__be64) - 1))
-#define DATABUF_OFFSET \
-   ((sizeof(struct gfs2_log_descriptor) + (2 * sizeof(__be64) - 1)) & \
-~(2 * sizeof(__be64) - 1))
-
 extern const struct gfs2_log_operations *gfs2_log_ops[];
 extern void gfs2_log_incr_head(struct gfs2_sbd *sdp);
 extern u64 gfs2_log_bmap(struct gfs2_jdesc *jd, unsigned int lbn);
@@ -29,18 +22,12 @@ extern int gfs2_find_jhead(struct gfs2_jdesc *jd,
   struct gfs2_log_header_host *head, bool keep_cache);
 static inline unsigned int buf_limit(struct gfs2_sbd *sdp)
 {
-   unsigned int limit;
-
-   limit = (sdp->sd_sb.sb_bsize - BUF_OFFSET) / sizeof(__be64);
-   return limit;
+   return sdp->sd_ldptrs;
 }
 
 static inline unsigned int databuf_limit(struct gfs2_sbd *sdp)
 {
-   unsigned int limit;
-
-   limit = (sdp->sd_sb.sb_bsize - DATABUF_OFFSET) / (2 * sizeof(__be64));
-   return limit;
+   return sdp->sd_ldptrs / 2;
 }
 
 static inline void lops_before_commit(struct gfs2_sbd *sdp,
-- 
2.26.2



[Cluster-devel] [RFC PATCH 00/12] Some log space management cleanups

2020-12-14 Thread Andreas Gruenbacher
Hello,

here's a bit of fallout in the log space management code that resulted
from looking into a revokes accounting problem in conjunction with the
resource group glock sharing patches.  I'm still working on some
follow-up changes, but this patch set should be reasonably
self-contained.  Please review.

Thanks,
Andreas

Andreas Gruenbacher (12):
  gfs2: Deobfuscate function jdesc_find_i
  gfs2: Simplify the buf_limit and databuf_limit definitions
  gfs2: Minor gfs2_write_revokes cleanups
  gfs2: Some documentation clarifications
  gfs2: A minor debugging improvement
  gfs2: Clean up ail2_empty
  gfs2: Get rid of on-stack transactions
  gfs2: Get rid of sd_reserving_log
  gfs2: Move lock flush locking to gfs2_trans_{begin,end}
  gfs2: Don't wait for journal flush in clean_journal
  gfs2: Clean up gfs2_log_reserve
  gfs2: Use a tighter bound in gfs2_trans_begin

 fs/gfs2/glops.c  |  29 ++--
 fs/gfs2/incore.h |   4 -
 fs/gfs2/log.c| 174 ++-
 fs/gfs2/log.h|   3 +-
 fs/gfs2/lops.h   |  17 +
 fs/gfs2/ops_fstype.c |   2 -
 fs/gfs2/super.c  |  25 +++
 fs/gfs2/trans.c  |  59 ++-
 fs/gfs2/trans.h  |   2 +
 9 files changed, 135 insertions(+), 180 deletions(-)

-- 
2.26.2



[Cluster-devel] [PATCH 01/12] gfs2: Deobfuscate function jdesc_find_i

2020-12-14 Thread Andreas Gruenbacher
Clean up this function to show that it is trivial.

Signed-off-by: Andreas Gruenbacher 
---
 fs/gfs2/super.c | 13 +++--
 1 file changed, 3 insertions(+), 10 deletions(-)

diff --git a/fs/gfs2/super.c b/fs/gfs2/super.c
index b3d951ab8068..08aef061b29d 100644
--- a/fs/gfs2/super.c
+++ b/fs/gfs2/super.c
@@ -81,19 +81,12 @@ void gfs2_jindex_free(struct gfs2_sbd *sdp)
 static struct gfs2_jdesc *jdesc_find_i(struct list_head *head, unsigned int 
jid)
 {
struct gfs2_jdesc *jd;
-   int found = 0;
 
list_for_each_entry(jd, head, jd_list) {
-   if (jd->jd_jid == jid) {
-   found = 1;
-   break;
-   }
+   if (jd->jd_jid == jid)
+   return jd;
}
-
-   if (!found)
-   jd = NULL;
-
-   return jd;
+   return NULL;
 }
 
 struct gfs2_jdesc *gfs2_jdesc_find(struct gfs2_sbd *sdp, unsigned int jid)
-- 
2.26.2