-
Notifications
You must be signed in to change notification settings - Fork 9.2k
HDFS-14925. Rename operation should check nest snapshot #1670
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -143,8 +143,8 @@ private static INodesInPath dstForRenameTo( | |
| * Change a path name | ||
| * | ||
| * @param fsd FSDirectory | ||
| * @param src source path | ||
| * @param dst destination path | ||
| * @param srcIIP source path | ||
| * @param dstIIP destination path | ||
| * @return true INodesInPath if rename succeeds; null otherwise | ||
| * @deprecated See {@link #renameToInt(FSDirectory, String, String, | ||
| * boolean, Options.Rename...)} | ||
|
|
@@ -155,8 +155,9 @@ static INodesInPath unprotectedRenameTo(FSDirectory fsd, | |
| throws IOException { | ||
| assert fsd.hasWriteLock(); | ||
| final INode srcInode = srcIIP.getLastINode(); | ||
| List<INodeDirectory> snapshottableDirs = new ArrayList<>(); | ||
| try { | ||
| validateRenameSource(fsd, srcIIP); | ||
| validateRenameSource(fsd, srcIIP, snapshottableDirs); | ||
| } catch (SnapshotException e) { | ||
| throw e; | ||
| } catch (IOException ignored) { | ||
|
|
@@ -190,6 +191,8 @@ static INodesInPath unprotectedRenameTo(FSDirectory fsd, | |
| return null; | ||
| } | ||
|
|
||
| validateNestSnapshot(fsd, dstParent.asDirectory(), snapshottableDirs); | ||
|
|
||
| fsd.ezManager.checkMoveValidity(srcIIP, dstIIP); | ||
| // Ensure dst has quota to accommodate rename | ||
| verifyFsLimitsForRename(fsd, srcIIP, dstIIP); | ||
|
|
@@ -342,8 +345,8 @@ static void renameForEditLog( | |
| * for details related to rename semantics and exceptions. | ||
| * | ||
| * @param fsd FSDirectory | ||
| * @param src source path | ||
| * @param dst destination path | ||
| * @param srcIIP source path | ||
| * @param dstIIP destination path | ||
| * @param timestamp modification time | ||
| * @param collectedBlocks blocks to be removed | ||
| * @param options Rename options | ||
|
|
@@ -361,7 +364,8 @@ static RenameResult unprotectedRenameTo(FSDirectory fsd, | |
| final String dst = dstIIP.getPath(); | ||
| final String error; | ||
| final INode srcInode = srcIIP.getLastINode(); | ||
| validateRenameSource(fsd, srcIIP); | ||
| List<INodeDirectory> srcSnapshottableDirs = new ArrayList<>(); | ||
| validateRenameSource(fsd, srcIIP, srcSnapshottableDirs); | ||
|
|
||
| // validate the destination | ||
| if (dst.equals(src)) { | ||
|
|
@@ -380,10 +384,10 @@ static RenameResult unprotectedRenameTo(FSDirectory fsd, | |
| BlockStoragePolicySuite bsps = fsd.getBlockStoragePolicySuite(); | ||
| fsd.ezManager.checkMoveValidity(srcIIP, dstIIP); | ||
| final INode dstInode = dstIIP.getLastINode(); | ||
| List<INodeDirectory> snapshottableDirs = new ArrayList<>(); | ||
| List<INodeDirectory> dstSnapshottableDirs = new ArrayList<>(); | ||
| if (dstInode != null) { // Destination exists | ||
| validateOverwrite(src, dst, overwrite, srcInode, dstInode); | ||
| FSDirSnapshotOp.checkSnapshot(fsd, dstIIP, snapshottableDirs); | ||
| FSDirSnapshotOp.checkSnapshot(fsd, dstIIP, dstSnapshottableDirs); | ||
| } | ||
|
|
||
| INode dstParent = dstIIP.getINode(-2); | ||
|
|
@@ -400,6 +404,8 @@ static RenameResult unprotectedRenameTo(FSDirectory fsd, | |
| throw new ParentNotDirectoryException(error); | ||
| } | ||
|
|
||
| validateNestSnapshot(fsd, dstParent.asDirectory(), srcSnapshottableDirs); | ||
|
|
||
| // Ensure dst has quota to accommodate rename | ||
| verifyFsLimitsForRename(fsd, srcIIP, dstIIP); | ||
| verifyQuotaForRename(fsd, srcIIP, dstIIP); | ||
|
|
@@ -439,10 +445,10 @@ static RenameResult unprotectedRenameTo(FSDirectory fsd, | |
| } | ||
| } | ||
|
|
||
| if (snapshottableDirs.size() > 0) { | ||
| if (dstSnapshottableDirs.size() > 0) { | ||
| // There are snapshottable directories (without snapshots) to be | ||
| // deleted. Need to update the SnapshotManager. | ||
| fsd.getFSNamesystem().removeSnapshottableDirs(snapshottableDirs); | ||
| fsd.getFSNamesystem().removeSnapshottableDirs(dstSnapshottableDirs); | ||
| } | ||
|
|
||
| tx.updateQuotasInSourceTree(bsps); | ||
|
|
@@ -556,7 +562,7 @@ private static void validateOverwrite( | |
| } | ||
|
|
||
| private static void validateRenameSource(FSDirectory fsd, | ||
| INodesInPath srcIIP) throws IOException { | ||
| INodesInPath srcIIP, List<INodeDirectory> snapshottableDirs) throws IOException { | ||
| String error; | ||
| final INode srcInode = srcIIP.getLastINode(); | ||
| // validate source | ||
|
|
@@ -574,7 +580,28 @@ private static void validateRenameSource(FSDirectory fsd, | |
| } | ||
| // srcInode and its subtree cannot contain snapshottable directories with | ||
| // snapshots | ||
| FSDirSnapshotOp.checkSnapshot(fsd, srcIIP, null); | ||
| FSDirSnapshotOp.checkSnapshot(fsd, srcIIP, snapshottableDirs); | ||
| } | ||
|
|
||
| private static void validateNestSnapshot(FSDirectory fsd, INodeDirectory dstParent, | ||
| List<INodeDirectory> snapshottableDirs) throws SnapshotException { | ||
|
|
||
| if (fsd.getFSNamesystem().getSnapshotManager().isAllowNestedSnapshots()) { | ||
| return; | ||
| } | ||
|
|
||
| /* | ||
| * snapshottableDirs is a list of snapshottable directory(child of rename src) | ||
| * which do not have snapshots yet. If this list is not empty, that means rename | ||
| * src have snapshottable descendant directories. | ||
| */ | ||
| if (snapshottableDirs != null && snapshottableDirs.size() > 0) { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I was concerned about the case where the source already has a snapshot.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, that's it ;) |
||
| if (fsd.getFSNamesystem().getSnapshotManager().isDescendantOfSnapshotRoot(dstParent)) { | ||
| String fullPath = dstParent.getFullPathName(); | ||
| throw new SnapshotException("Failed to rename to " + fullPath + | ||
| " due to nested snapshottable directory"); | ||
zhjwpku marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| } | ||
| } | ||
| } | ||
|
|
||
| private static class RenameOperation { | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.