aboutsummaryrefslogtreecommitdiffstats
path: root/cmd
diff options
context:
space:
mode:
authorJitendra Patidar <[email protected]>2022-02-23 02:36:43 +0530
committerGitHub <[email protected]>2022-02-22 13:06:43 -0800
commit361a7e821178e105c8e1206ead4479de83c2a617 (patch)
treee03d4741dc67a9a7aa469fdbb38104c9fe62f40f /cmd
parentccdcc1dbe8b2b741194cdbc5b81bdb8b58cc7142 (diff)
log xattr=sa create/remove/update to ZIL
As such, there are no specific synchronous semantics defined for the xattrs. But for xattr=on, it does log to ZIL and zil_commit() is done, if sync=always is set on dataset. This provides sync semantics for xattr=on with sync=always set on dataset. For the xattr=sa implementation, it doesn't log to ZIL, so, even with sync=always, xattrs are not guaranteed to be synced before xattr call returns to caller. So, xattr can be lost if system crash happens, before txg carrying xattr transaction is synced. This change adds xattr=sa logging to ZIL on xattr create/remove/update and xattrs are synced to ZIL (zil_commit() done) for sync=always. This makes xattr=sa behavior similar to xattr=on. Implementation notes: The actual logging is fairly straight-forward and does not warrant additional explanation. However, it has been 14 years since we last added new TX types to the ZIL [1], hence this is the first time we do it after the introduction of zpool features. Therefore, here is an overview of the feature activation and deactivation workflow: 1. The feature must be enabled. Otherwise, we don't log the new record type. This ensures compatibility with older software. 2. The feature is activated per-dataset, since the ZIL is per-dataset. 3. If the feature is enabled and dataset is not for zvol, any append to the ZIL chain will activate the feature for the dataset. Likewise for starting a new ZIL chain. 4. A dataset that doesn't have a ZIL chain has the feature deactivated. We ensure (3) by activating on the first zil_commit() after the feature was enabled. Since activating the features requires waiting for txg sync, the first zil_commit() after enabling the feature will be slower than usual. The downside is that this is really a conservative approximation: even if we never append a 'TX_SETSAXATTR' to the ZIL chain, we pay the penalty for feature activation. The upside is that the user is in control of when we pay the penalty, i.e., upon enabling the feature. We ensure (4) by hooking into zil_sync(), where ZIL destroy actually happens. One more piece on feature activation, since it's spread across multiple functions: zil_commit() zil_process_commit_list() if lwb == NULL // first zil_commit since zil_open zil_create() if no log block pointer in ZIL header: if feature enabled and not active: // CASE 1 enable, COALESCE txg wait with dmu_tx that allocated the log block else // log block was allocated earlier than this zil_open if feature enabled and not active: // CASE 2 enable, EXPLICIT txg wait else // already have an in-DRAM LWB if feature enabled and not active: // this happens when we enable the feature after zil_create // CASE 3 enable, EXPLICIT txg wait [1] https://github.com/illumos/illumos-gate/commit/da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0 Reviewed-by: Matthew Ahrens <[email protected]> Reviewed-by: Christian Schwarz <[email protected]> Reviewed-by: Ahelenia ZiemiaƄska <[email protected]> Reviewed-by: Ryan Moeller <[email protected]> Reviewed-by: Brian Behlendorf <[email protected]> Signed-off-by: Jitendra Patidar <[email protected]> Closes #8768 Closes #9078
Diffstat (limited to 'cmd')
-rw-r--r--cmd/zdb/zdb_il.c25
-rw-r--r--cmd/ztest/ztest.c1
2 files changed, 26 insertions, 0 deletions
diff --git a/cmd/zdb/zdb_il.c b/cmd/zdb/zdb_il.c
index d6f588d83..76b1d64d7 100644
--- a/cmd/zdb/zdb_il.c
+++ b/cmd/zdb/zdb_il.c
@@ -266,6 +266,29 @@ zil_prt_rec_setattr(zilog_t *zilog, int txtype, const void *arg)
}
static void
+zil_prt_rec_setsaxattr(zilog_t *zilog, int txtype, const void *arg)
+{
+ (void) zilog, (void) txtype;
+ const lr_setsaxattr_t *lr = arg;
+
+ char *name = (char *)(lr + 1);
+ (void) printf("%sfoid %llu\n", tab_prefix,
+ (u_longlong_t)lr->lr_foid);
+
+ (void) printf("%sXAT_NAME %s\n", tab_prefix, name);
+ if (lr->lr_size == 0) {
+ (void) printf("%sXAT_VALUE NULL\n", tab_prefix);
+ } else {
+ (void) printf("%sXAT_VALUE ", tab_prefix);
+ char *val = name + (strlen(name) + 1);
+ for (int i = 0; i < lr->lr_size; i++) {
+ (void) printf("%c", *val);
+ val++;
+ }
+ }
+}
+
+static void
zil_prt_rec_acl(zilog_t *zilog, int txtype, const void *arg)
{
(void) zilog, (void) txtype;
@@ -304,6 +327,8 @@ static zil_rec_info_t zil_rec_info[TX_MAX_TYPE] = {
{.zri_print = zil_prt_rec_create, .zri_name = "TX_MKDIR_ATTR "},
{.zri_print = zil_prt_rec_create, .zri_name = "TX_MKDIR_ACL_ATTR "},
{.zri_print = zil_prt_rec_write, .zri_name = "TX_WRITE2 "},
+ {.zri_print = zil_prt_rec_setsaxattr,
+ .zri_name = "TX_SETSAXATTR "},
};
static int
diff --git a/cmd/ztest/ztest.c b/cmd/ztest/ztest.c
index ed60d065c..0daaab69c 100644
--- a/cmd/ztest/ztest.c
+++ b/cmd/ztest/ztest.c
@@ -2386,6 +2386,7 @@ zil_replay_func_t *ztest_replay_vector[TX_MAX_TYPE] = {
NULL, /* TX_MKDIR_ATTR */
NULL, /* TX_MKDIR_ACL_ATTR */
NULL, /* TX_WRITE2 */
+ NULL, /* TX_SETSAXATTR */
};
/*