<feed xmlns='http://www.w3.org/2005/Atom'>
<title>wireguard-linux/fs/gfs2/glops.c, branch jd/unified-crypt-queue</title>
<subtitle>WireGuard for the Linux kernel</subtitle>
<id>https://git.zx2c4.com/wireguard-linux/atom/fs/gfs2/glops.c?h=jd%2Funified-crypt-queue</id>
<link rel='self' href='https://git.zx2c4.com/wireguard-linux/atom/fs/gfs2/glops.c?h=jd%2Funified-crypt-queue'/>
<link rel='alternate' type='text/html' href='https://git.zx2c4.com/wireguard-linux/'/>
<updated>2020-02-27T13:53:18Z</updated>
<entry>
<title>gfs2: Do proper error checking for go_sync family of glops functions</title>
<updated>2020-02-27T13:53:18Z</updated>
<author>
<name>Bob Peterson</name>
<email>rpeterso@redhat.com</email>
</author>
<published>2019-11-13T20:09:28Z</published>
<link rel='alternate' type='text/html' href='https://git.zx2c4.com/wireguard-linux/commit/?id=1c634f94c3da39115270d35b3075af970810a927'/>
<id>urn:sha1:1c634f94c3da39115270d35b3075af970810a927</id>
<content type='text'>
Before this patch, function do_xmote would try to sync out the glock
dirty data by calling the appropriate glops function XXX_go_sync()
but it did not check for a good return code. If the sync was not
possible due to an io error or whatever, do_xmote would continue on
and call go_inval and release the glock to other cluster nodes.
When those nodes go to replay the journal, they may already be holding
glocks for the journal records that should have been synced, but were
not due to the ignored error.

This patch introduces proper error code checking to the go_sync
family of glops functions.

Signed-off-by: Bob Peterson &lt;rpeterso@redhat.com&gt;
Reviewed-by: Andreas Gruenbacher &lt;agruenba@redhat.com&gt;
</content>
</entry>
<entry>
<title>gfs2: Do log_flush in gfs2_ail_empty_gl even if ail list is empty</title>
<updated>2020-02-27T13:53:18Z</updated>
<author>
<name>Bob Peterson</name>
<email>rpeterso@redhat.com</email>
</author>
<published>2019-11-13T19:47:02Z</published>
<link rel='alternate' type='text/html' href='https://git.zx2c4.com/wireguard-linux/commit/?id=9ff78289356af640941bbb0dd3f46af2063f0046'/>
<id>urn:sha1:9ff78289356af640941bbb0dd3f46af2063f0046</id>
<content type='text'>
Before this patch, if gfs2_ail_empty_gl saw there was nothing on
the ail list, it would return and not flush the log. The problem
is that there could still be a revoke for the rgrp sitting on the
sd_log_le_revoke list that's been recently taken off the ail list.
But that revoke still needs to be written, and the rgrp_go_inval
still needs to call log_flush_wait to ensure the revokes are all
properly written to the journal before we relinquish control of
the glock to another node. If we give the glock to another node
before we have this knowledge, the node might crash and its journal
replayed, in which case the missing revoke would allow the journal
replay to replay the rgrp over top of the rgrp we already gave to
another node, thus overwriting its changes and corrupting the
file system.

This patch makes gfs2_ail_empty_gl still call gfs2_log_flush rather
than returning.

Signed-off-by: Bob Peterson &lt;rpeterso@redhat.com&gt;
Reviewed-by: Andreas Gruenbacher &lt;agruenba@redhat.com&gt;
</content>
</entry>
<entry>
<title>gfs2: fix infinite loop when checking ail item count before go_inval</title>
<updated>2020-02-27T13:53:17Z</updated>
<author>
<name>Bob Peterson</name>
<email>rpeterso@redhat.com</email>
</author>
<published>2019-05-22T14:21:21Z</published>
<link rel='alternate' type='text/html' href='https://git.zx2c4.com/wireguard-linux/commit/?id=33dbd1e41a1dd549eb19a29477119d4e29766210'/>
<id>urn:sha1:33dbd1e41a1dd549eb19a29477119d4e29766210</id>
<content type='text'>
Before this patch, the rgrp_go_inval and inode_go_inval functions each
checked if there were any items left on the ail count (by way of a
count), and if so, did a withdraw. But the withdraw code now uses
glocks when changing the file system to read-only status. So we can
not have glock functions withdrawing or a hang will likely result:
The glocks can't be serviced by the work_func if the work_func is
busy doing its own withdraw.

This patch removes the checks from the go_inval functions and adds
a centralized check in do_xmote to warn about the problem and not
withdraw, but flag the error so it's eventually caught when the logd
daemon eventually runs.

Signed-off-by: Bob Peterson &lt;rpeterso@redhat.com&gt;
Reviewed-by: Andreas Gruenbacher &lt;agruenba@redhat.com&gt;
</content>
</entry>
<entry>
<title>gfs2: Force withdraw to replay journals and wait for it to finish</title>
<updated>2020-02-27T13:53:12Z</updated>
<author>
<name>Bob Peterson</name>
<email>rpeterso@redhat.com</email>
</author>
<published>2020-01-28T19:23:45Z</published>
<link rel='alternate' type='text/html' href='https://git.zx2c4.com/wireguard-linux/commit/?id=601ef0d52e9617588fcff3df26953592f2eb44ac'/>
<id>urn:sha1:601ef0d52e9617588fcff3df26953592f2eb44ac</id>
<content type='text'>
When a node withdraws from a file system, it often leaves its journal
in an incomplete state. This is especially true when the withdraw is
caused by io errors writing to the journal. Before this patch, a
withdraw would try to write a "shutdown" record to the journal, tell
dlm it's done with the file system, and none of the other nodes
know about the problem. Later, when the problem is fixed and the
withdrawn node is rebooted, it would then discover that its own
journal was incomplete, and replay it. However, replaying it at this
point is almost guaranteed to introduce corruption because the other
nodes are likely to have used affected resource groups that appeared
in the journal since the time of the withdraw. Replaying the journal
later will overwrite any changes made, and not through any fault of
dlm, which was instructed during the withdraw to release those
resources.

This patch makes file system withdraws seen by the entire cluster.
Withdrawing nodes dequeue their journal glock to allow recovery.

The remaining nodes check all the journals to see if they are
clean or in need of replay. They try to replay dirty journals, but
only the journals of withdrawn nodes will be "not busy" and
therefore available for replay.

Until the journal replay is complete, no i/o related glocks may be
given out, to ensure that the replay does not cause the
aforementioned corruption: We cannot allow any journal replay to
overwrite blocks associated with a glock once it is held.

The "live" glock which is now used to signal when a withdraw
occurs. When a withdraw occurs, the node signals its withdraw by
dequeueing the "live" glock and trying to enqueue it in EX mode,
thus forcing the other nodes to all see a demote request, by way
of a "1CB" (one callback) try lock. The "live" glock is not
granted in EX; the callback is only just used to indicate a
withdraw has occurred.

Note that all nodes in the cluster must wait for the recovering
node to finish replaying the withdrawing node's journal before
continuing. To this end, it checks that the journals are clean
multiple times in a retry loop.

Also note that the withdraw function may be called from a wide
variety of situations, and therefore, we need to take extra
precautions to make sure pointers are valid before using them in
many circumstances.

We also need to take care when glocks decide to withdraw, since
the withdraw code now uses glocks.

Also, before this patch, if a process encountered an error and
decided to withdraw, if another process was already withdrawing,
the second withdraw would be silently ignored, which set it free
to unlock its glocks. That's correct behavior if the original
withdrawer encounters further errors down the road. But if
secondary waiters don't wait for the journal replay, unlocking
glocks will allow other nodes to use them, despite the fact that
the journal containing those blocks is being replayed. The
replay needs to finish before our glocks are released to other
nodes. IOW, secondary withdraws need to wait for the first
withdraw to finish.

For example, if an rgrp glock is unlocked by a process that didn't
wait for the first withdraw, a journal replay could introduce file
system corruption by replaying a rgrp block that has already been
granted to a different cluster node.

Signed-off-by: Bob Peterson &lt;rpeterso@redhat.com&gt;
</content>
</entry>
<entry>
<title>gfs2: Allow some glocks to be used during withdraw</title>
<updated>2020-02-20T17:01:36Z</updated>
<author>
<name>Bob Peterson</name>
<email>rpeterso@redhat.com</email>
</author>
<published>2019-06-13T18:28:45Z</published>
<link rel='alternate' type='text/html' href='https://git.zx2c4.com/wireguard-linux/commit/?id=a72d2401f54b7db41c77ab971238a06eafe929fb'/>
<id>urn:sha1:a72d2401f54b7db41c77ab971238a06eafe929fb</id>
<content type='text'>
We need to allow some glocks to be enqueued, dequeued, promoted, and demoted
when we're withdrawn. For example, to maintain metadata integrity, we should
disallow the use of inode and rgrp glocks when withdrawn. Other glocks, like
iopen or the transaction glocks may be safely used because none of their
metadata goes through the journal. So in general, we should disallow all
glocks with an address space, and allow all the others. One exception is:
we need to allow our active journal to be demoted so others may recover it.

Allowing glocks after withdraw gives us the ability to take appropriate
action (in a following patch) to have our journal properly replayed by
another node rather than just abandoning the current transactions and
pretending nothing bad happened, leaving the other nodes free to modify
the blocks we had in our journal, which may result in file system
corruption.

Signed-off-by: Bob Peterson &lt;rpeterso@redhat.com&gt;
</content>
</entry>
<entry>
<title>gfs2: Rework how rgrp buffer_heads are managed</title>
<updated>2020-02-10T13:39:48Z</updated>
<author>
<name>Bob Peterson</name>
<email>rpeterso@redhat.com</email>
</author>
<published>2019-11-13T17:50:30Z</published>
<link rel='alternate' type='text/html' href='https://git.zx2c4.com/wireguard-linux/commit/?id=b3422cacdd7e623e473b4c3977f3ee65e1fed62f'/>
<id>urn:sha1:b3422cacdd7e623e473b4c3977f3ee65e1fed62f</id>
<content type='text'>
Before this patch, the rgrp code had a serious problem related to
how it managed buffer_heads for resource groups. The problem caused
file system corruption, especially in cases of journal replay.

When an rgrp glock was demoted to transfer ownership to a
different cluster node, do_xmote() first calls rgrp_go_sync and then
rgrp_go_inval, as expected. When it calls rgrp_go_sync, that called
gfs2_rgrp_brelse() that dropped the buffer_head reference count.
In most cases, the reference count went to zero, which is right.
However, there were other places where the buffers are handled
differently.

After rgrp_go_sync, do_xmote called rgrp_go_inval which called
gfs2_rgrp_brelse a second time, then rgrp_go_inval's call to
truncate_inode_pages_range would get rid of the pages in memory,
but only if the reference count drops to 0.

Unfortunately, gfs2_rgrp_brelse was setting bi-&gt;bi_bh = NULL.
So when rgrp_go_sync called gfs2_rgrp_brelse, it lost the pointer
to the buffer_heads in cases where the reference count was still 1.
Therefore, when rgrp_go_inval called gfs2_rgrp_brelse a second time,
it failed the check for "if (bi-&gt;bi_bh)" and thus failed to call
brelse a second time. Because of that, the reference count on those
buffers sometimes failed to drop from 1 to 0. And that caused
function truncate_inode_pages_range to keep the pages in page cache
rather than freeing them.

The next time the rgrp glock was acquired, the metadata read of
the rgrp buffers re-used the pages in memory, which were now
wrong because they were likely modified by the other node who
acquired the glock in EX (which is why we demoted the glock).
This re-use of the page cache caused corruption because changes
made by the other nodes were never seen, so the bitmaps were
inaccurate.

For some reason, the problem became most apparent when journal
replay forced the replay of rgrps in memory, which caused newer
rgrp data to be overwritten by the older in-core pages.

A big part of the problem was that the rgrp buffer were released
in multiple places: The go_unlock function would release them when
the glock was released rather than when the glock is demoted,
which is clearly wrong because our intent was to cache them until
the glock is demoted from SH or EX.

This patch attempts to clean up the mess and make one consistent
and centralized mechanism for managing the rgrp buffer_heads by
implementing several changes:

1. It eliminates the call to gfs2_rgrp_brelse() from rgrp_go_sync.
   We don't want to release the buffers or zero the pointers when
   syncing for the reasons stated above. It only makes sense to
   release them when the glock is actually invalidated (go_inval).
   And when we do, then we set the bh pointers to NULL.
2. The go_unlock function (which was only used for rgrps) is
   eliminated, as we've talked about doing many times before.
   The go_unlock function was called too early in the glock dq
   process, and should not happen until the glock is invalidated.
3. It also eliminates the call to rgrp_brelse in gfs2_clear_rgrpd.
   That will now happen automatically when the rgrp glocks are
   demoted, and shouldn't happen any sooner or later than that.
   Instead, function gfs2_clear_rgrpd has been modified to demote
   the rgrp glocks, and therefore, free those pages, before the
   remaining glocks are culled by gfs2_gl_hash_clear. This
   prevents the gl_object from hanging around when the glocks are
   culled.

Signed-off-by: Bob Peterson &lt;rpeterso@redhat.com&gt;
Reviewed-by: Andreas Gruenbacher &lt;agruenba@redhat.com&gt;
</content>
</entry>
<entry>
<title>gfs2: Split gfs2_lm_withdraw into two functions</title>
<updated>2020-02-10T13:39:44Z</updated>
<author>
<name>Andreas Gruenbacher</name>
<email>agruenba@redhat.com</email>
</author>
<published>2020-01-23T17:41:00Z</published>
<link rel='alternate' type='text/html' href='https://git.zx2c4.com/wireguard-linux/commit/?id=badb55ec208adc4c406ed084f486deb1f9f5baa0'/>
<id>urn:sha1:badb55ec208adc4c406ed084f486deb1f9f5baa0</id>
<content type='text'>
Split gfs2_lm_withdraw into a function that prints an error message and a
function that withdraws the filesystem.

Signed-off-by: Andreas Gruenbacher &lt;agruenba@redhat.com&gt;
Signed-off-by: Bob Peterson &lt;rpeterso@redhat.com&gt;
</content>
</entry>
<entry>
<title>gfs2: eliminate ssize parameter from gfs2_struct2blk</title>
<updated>2020-01-07T17:46:06Z</updated>
<author>
<name>Bob Peterson</name>
<email>rpeterso@redhat.com</email>
</author>
<published>2019-12-13T14:10:51Z</published>
<link rel='alternate' type='text/html' href='https://git.zx2c4.com/wireguard-linux/commit/?id=2e9eeaa1175112ac494ba3c2ea4b71b1febeb6ab'/>
<id>urn:sha1:2e9eeaa1175112ac494ba3c2ea4b71b1febeb6ab</id>
<content type='text'>
Every caller of function gfs2_struct2blk specified sizeof(u64).

This patch eliminates the unnecessary parameter and replaces the
size calculation with a new superblock variable that is computed
to be the maximum number of block pointers we can fit inside a
log descriptor, as is done for pointers per dinode and indirect
block.

Signed-off-by: Bob Peterson &lt;rpeterso@redhat.com&gt;
Reviewed-by: Andrew Price &lt;anprice@redhat.com&gt;
Signed-off-by: Andreas Gruenbacher &lt;agruenba@redhat.com&gt;
</content>
</entry>
<entry>
<title>gfs2: Introduce function gfs2_withdrawn</title>
<updated>2019-11-14T18:46:18Z</updated>
<author>
<name>Bob Peterson</name>
<email>rpeterso@redhat.com</email>
</author>
<published>2019-11-14T14:52:15Z</published>
<link rel='alternate' type='text/html' href='https://git.zx2c4.com/wireguard-linux/commit/?id=eb43e660c094029fc1165e2641ce06c153129bdd'/>
<id>urn:sha1:eb43e660c094029fc1165e2641ce06c153129bdd</id>
<content type='text'>
Add function gfs2_withdrawn and replace all checks for the SDF_WITHDRAWN
bit to call it. This does not change the logic or function of gfs2, and
it facilitates later improvements to the withdraw sequence.

Signed-off-by: Bob Peterson &lt;rpeterso@redhat.com&gt;
Signed-off-by: Andreas Gruenbacher &lt;agruenba@redhat.com&gt;
</content>
</entry>
<entry>
<title>gfs2: removed unnecessary semicolon</title>
<updated>2019-10-30T11:17:04Z</updated>
<author>
<name>Aliasgar Surti</name>
<email>aliasgar.surti500@gmail.com</email>
</author>
<published>2019-10-04T15:55:29Z</published>
<link rel='alternate' type='text/html' href='https://git.zx2c4.com/wireguard-linux/commit/?id=098b9c1453629be7e637498f3ca8bb3c592eb394'/>
<id>urn:sha1:098b9c1453629be7e637498f3ca8bb3c592eb394</id>
<content type='text'>
There is use of unnecessary semicolon after switch case.
Removed the semicolon.

Signed-off-by: Aliasgar Surti &lt;aliasgar.surti500@gmail.com&gt;
Signed-off-by: Bob Peterson &lt;rpeterso@redhat.com&gt;
Signed-off-by: Andreas Gruenbacher &lt;agruenba@redhat.com&gt;
</content>
</entry>
</feed>
