migration.
-CACHE EXPIRATION FOR FROZEN SUBTREES
+CACHE EXPIRATION FOR EXPORTING SUBTREES
Cache expiration messages that are received for a subtree that is
-frozen are temporarily set aside instead of being processed. Only
-when the subtree is unfrozen are the expirations either processed (if
-the MDS is authoritative) or discarded (if it is not). Because either
+being exported are either deferred or handled immediately, based on
+the sender and reciever states. The importing MDS will always defer until
+after the export finishes, because the import could fail. The exporting MDS
+processes the expire UNLESS the expiring MDS does not know about the export or
+the exporting MDS is no longer auth.
+Because MDSes get witness notifications on export, this is safe. Either:
+a) The expiring MDS knows about the export, and has sent messages to both
+MDSes involved, or
+b) The expiring MDS did not know about the export at the time the message
+was sent, and so only sent it to the exporting MDS. (This implies that the
+exporting MDS hasn't yet encoded the state to send to the replica MDS.)
+
+When the subtree export completes, deferred expirations are either processed
+(if the MDS is authoritative) or discarded (if it is not). Because either
the exporting or importing metadata can fail during the migration
process, the MDS cannot tell whether it will be authoritative or not
until the process completes.
-
NORMAL MIGRATION
The exporter begins by doing some checks in export_dir() to verify
if (!con->is_auth() ||
(con->is_auth() && con->is_exporting() &&
+ // this person has acked that we're exporting
migrator->get_export_state(con) == Migrator::EXPORT_WARNING &&
migrator->export_has_warned(con,from))) {
// not auth.
delayed_expire[con][from]->add_realm(p->first, p->second);
continue;
}
+ assert(!(parent_dir->is_auth() && parent_dir->is_exporting()) ||
+ (migrator->get_export_state(parent_dir) == Migrator::EXPORT_WARNING &&
+ !migrator->export_has_warned(parent_dir, from)));
+
dout(7) << "expires for " << *con << dendl;
} else {
dout(7) << "containerless expires (root, stray inodes)" << dendl;