HDFS-10979. Pass IIP for FSDirDeleteOp methods. Contributed by Daryn Sharp.
(cherry picked from commit 3565c9af17
)
This commit is contained in:
parent
2de2d0df1d
commit
5ea87e4aeb
|
@ -55,7 +55,7 @@ class FSDirDeleteOp {
|
||||||
FSNamesystem fsn = fsd.getFSNamesystem();
|
FSNamesystem fsn = fsd.getFSNamesystem();
|
||||||
fsd.writeLock();
|
fsd.writeLock();
|
||||||
try {
|
try {
|
||||||
if (deleteAllowed(iip, iip.getPath()) ) {
|
if (deleteAllowed(iip)) {
|
||||||
List<INodeDirectory> snapshottableDirs = new ArrayList<>();
|
List<INodeDirectory> snapshottableDirs = new ArrayList<>();
|
||||||
FSDirSnapshotOp.checkSnapshot(fsd, iip, snapshottableDirs);
|
FSDirSnapshotOp.checkSnapshot(fsd, iip, snapshottableDirs);
|
||||||
ReclaimContext context = new ReclaimContext(
|
ReclaimContext context = new ReclaimContext(
|
||||||
|
@ -98,20 +98,24 @@ class FSDirDeleteOp {
|
||||||
FSDirectory fsd = fsn.getFSDirectory();
|
FSDirectory fsd = fsn.getFSDirectory();
|
||||||
FSPermissionChecker pc = fsd.getPermissionChecker();
|
FSPermissionChecker pc = fsd.getPermissionChecker();
|
||||||
|
|
||||||
final INodesInPath iip = fsd.resolvePathForWrite(pc, src, false);
|
if (FSDirectory.isExactReservedName(src)) {
|
||||||
src = iip.getPath();
|
throw new InvalidPathException(src);
|
||||||
if (!recursive && fsd.isNonEmptyDirectory(iip)) {
|
|
||||||
throw new PathIsNotEmptyDirectoryException(src + " is non empty");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final INodesInPath iip = fsd.resolvePathForWrite(pc, src, false);
|
||||||
if (fsd.isPermissionEnabled()) {
|
if (fsd.isPermissionEnabled()) {
|
||||||
fsd.checkPermission(pc, iip, false, null, FsAction.WRITE, null,
|
fsd.checkPermission(pc, iip, false, null, FsAction.WRITE, null,
|
||||||
FsAction.ALL, true);
|
FsAction.ALL, true);
|
||||||
}
|
}
|
||||||
if (recursive && fsd.isNonEmptyDirectory(iip)) {
|
if (fsd.isNonEmptyDirectory(iip)) {
|
||||||
checkProtectedDescendants(fsd, src);
|
if (!recursive) {
|
||||||
|
throw new PathIsNotEmptyDirectoryException(
|
||||||
|
iip.getPath() + " is non empty");
|
||||||
|
}
|
||||||
|
checkProtectedDescendants(fsd, iip);
|
||||||
}
|
}
|
||||||
|
|
||||||
return deleteInternal(fsn, src, iip, logRetryCache);
|
return deleteInternal(fsn, iip, logRetryCache);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -126,17 +130,14 @@ class FSDirDeleteOp {
|
||||||
* @param src a string representation of a path to an inode
|
* @param src a string representation of a path to an inode
|
||||||
* @param mtime the time the inode is removed
|
* @param mtime the time the inode is removed
|
||||||
*/
|
*/
|
||||||
static void deleteForEditLog(FSDirectory fsd, String src, long mtime)
|
static void deleteForEditLog(FSDirectory fsd, INodesInPath iip, long mtime)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
assert fsd.hasWriteLock();
|
assert fsd.hasWriteLock();
|
||||||
FSNamesystem fsn = fsd.getFSNamesystem();
|
FSNamesystem fsn = fsd.getFSNamesystem();
|
||||||
BlocksMapUpdateInfo collectedBlocks = new BlocksMapUpdateInfo();
|
BlocksMapUpdateInfo collectedBlocks = new BlocksMapUpdateInfo();
|
||||||
List<INode> removedINodes = new ChunkedArrayList<>();
|
List<INode> removedINodes = new ChunkedArrayList<>();
|
||||||
List<Long> removedUCFiles = new ChunkedArrayList<>();
|
List<Long> removedUCFiles = new ChunkedArrayList<>();
|
||||||
|
if (!deleteAllowed(iip)) {
|
||||||
final INodesInPath iip = fsd.getINodesInPath4Write(
|
|
||||||
FSDirectory.normalizePath(src), false);
|
|
||||||
if (!deleteAllowed(iip, src)) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
List<INodeDirectory> snapshottableDirs = new ArrayList<>();
|
List<INodeDirectory> snapshottableDirs = new ArrayList<>();
|
||||||
|
@ -162,7 +163,6 @@ class FSDirDeleteOp {
|
||||||
* <p>
|
* <p>
|
||||||
* For small directory or file the deletion is done in one shot.
|
* For small directory or file the deletion is done in one shot.
|
||||||
* @param fsn namespace
|
* @param fsn namespace
|
||||||
* @param src path name to be deleted
|
|
||||||
* @param iip the INodesInPath instance containing all the INodes for the path
|
* @param iip the INodesInPath instance containing all the INodes for the path
|
||||||
* @param logRetryCache whether to record RPC ids in editlog for retry cache
|
* @param logRetryCache whether to record RPC ids in editlog for retry cache
|
||||||
* rebuilding
|
* rebuilding
|
||||||
|
@ -170,15 +170,11 @@ class FSDirDeleteOp {
|
||||||
* @throws IOException
|
* @throws IOException
|
||||||
*/
|
*/
|
||||||
static BlocksMapUpdateInfo deleteInternal(
|
static BlocksMapUpdateInfo deleteInternal(
|
||||||
FSNamesystem fsn, String src, INodesInPath iip, boolean logRetryCache)
|
FSNamesystem fsn, INodesInPath iip, boolean logRetryCache)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
assert fsn.hasWriteLock();
|
assert fsn.hasWriteLock();
|
||||||
if (NameNode.stateChangeLog.isDebugEnabled()) {
|
if (NameNode.stateChangeLog.isDebugEnabled()) {
|
||||||
NameNode.stateChangeLog.debug("DIR* NameSystem.delete: " + src);
|
NameNode.stateChangeLog.debug("DIR* NameSystem.delete: " + iip.getPath());
|
||||||
}
|
|
||||||
|
|
||||||
if (FSDirectory.isExactReservedName(src)) {
|
|
||||||
throw new InvalidPathException(src);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
FSDirectory fsd = fsn.getFSDirectory();
|
FSDirectory fsd = fsn.getFSDirectory();
|
||||||
|
@ -193,14 +189,14 @@ class FSDirDeleteOp {
|
||||||
if (filesRemoved < 0) {
|
if (filesRemoved < 0) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
fsd.getEditLog().logDelete(src, mtime, logRetryCache);
|
fsd.getEditLog().logDelete(iip.getPath(), mtime, logRetryCache);
|
||||||
incrDeletedFileCount(filesRemoved);
|
incrDeletedFileCount(filesRemoved);
|
||||||
|
|
||||||
fsn.removeLeasesAndINodes(removedUCFiles, removedINodes, true);
|
fsn.removeLeasesAndINodes(removedUCFiles, removedINodes, true);
|
||||||
|
|
||||||
if (NameNode.stateChangeLog.isDebugEnabled()) {
|
if (NameNode.stateChangeLog.isDebugEnabled()) {
|
||||||
NameNode.stateChangeLog.debug("DIR* Namesystem.delete: "
|
NameNode.stateChangeLog.debug(
|
||||||
+ src +" is removed");
|
"DIR* Namesystem.delete: " + iip.getPath() +" is removed");
|
||||||
}
|
}
|
||||||
return collectedBlocks;
|
return collectedBlocks;
|
||||||
}
|
}
|
||||||
|
@ -209,19 +205,18 @@ class FSDirDeleteOp {
|
||||||
NameNode.getNameNodeMetrics().incrFilesDeleted(count);
|
NameNode.getNameNodeMetrics().incrFilesDeleted(count);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean deleteAllowed(final INodesInPath iip,
|
private static boolean deleteAllowed(final INodesInPath iip) {
|
||||||
final String src) {
|
|
||||||
if (iip.length() < 1 || iip.getLastINode() == null) {
|
if (iip.length() < 1 || iip.getLastINode() == null) {
|
||||||
if (NameNode.stateChangeLog.isDebugEnabled()) {
|
if (NameNode.stateChangeLog.isDebugEnabled()) {
|
||||||
NameNode.stateChangeLog.debug(
|
NameNode.stateChangeLog.debug(
|
||||||
"DIR* FSDirectory.unprotectedDelete: failed to remove "
|
"DIR* FSDirectory.unprotectedDelete: failed to remove "
|
||||||
+ src + " because it does not exist");
|
+ iip.getPath() + " because it does not exist");
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
} else if (iip.length() == 1) { // src is the root
|
} else if (iip.length() == 1) { // src is the root
|
||||||
NameNode.stateChangeLog.warn(
|
NameNode.stateChangeLog.warn(
|
||||||
"DIR* FSDirectory.unprotectedDelete: failed to remove " + src +
|
"DIR* FSDirectory.unprotectedDelete: failed to remove " +
|
||||||
" because the root is not allowed to be deleted");
|
iip.getPath() + " because the root is not allowed to be deleted");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
@ -278,15 +273,19 @@ class FSDirDeleteOp {
|
||||||
* Throw if the given directory has any non-empty protected descendants
|
* Throw if the given directory has any non-empty protected descendants
|
||||||
* (including itself).
|
* (including itself).
|
||||||
*
|
*
|
||||||
* @param src directory whose descendants are to be checked. The caller
|
* @param iip directory whose descendants are to be checked.
|
||||||
* must ensure src is not terminated with {@link Path#SEPARATOR}.
|
|
||||||
* @throws AccessControlException if a non-empty protected descendant
|
* @throws AccessControlException if a non-empty protected descendant
|
||||||
* was found.
|
* was found.
|
||||||
*/
|
*/
|
||||||
private static void checkProtectedDescendants(FSDirectory fsd, String src)
|
private static void checkProtectedDescendants(
|
||||||
|
FSDirectory fsd, INodesInPath iip)
|
||||||
throws AccessControlException, UnresolvedLinkException {
|
throws AccessControlException, UnresolvedLinkException {
|
||||||
final SortedSet<String> protectedDirs = fsd.getProtectedDirectories();
|
final SortedSet<String> protectedDirs = fsd.getProtectedDirectories();
|
||||||
|
if (protectedDirs.isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
String src = iip.getPath();
|
||||||
// Is src protected? Caller has already checked it is non-empty.
|
// Is src protected? Caller has already checked it is non-empty.
|
||||||
if (protectedDirs.contains(src)) {
|
if (protectedDirs.contains(src)) {
|
||||||
throw new AccessControlException(
|
throw new AccessControlException(
|
||||||
|
|
|
@ -352,7 +352,7 @@ public class FSEditLogLoader {
|
||||||
INodeFile oldFile = INodeFile.valueOf(iip.getLastINode(), path, true);
|
INodeFile oldFile = INodeFile.valueOf(iip.getLastINode(), path, true);
|
||||||
if (oldFile != null && addCloseOp.overwrite) {
|
if (oldFile != null && addCloseOp.overwrite) {
|
||||||
// This is OP_ADD with overwrite
|
// This is OP_ADD with overwrite
|
||||||
FSDirDeleteOp.deleteForEditLog(fsDir, path, addCloseOp.mtime);
|
FSDirDeleteOp.deleteForEditLog(fsDir, iip, addCloseOp.mtime);
|
||||||
iip = INodesInPath.replace(iip, iip.length() - 1, null);
|
iip = INodesInPath.replace(iip, iip.length() - 1, null);
|
||||||
oldFile = null;
|
oldFile = null;
|
||||||
}
|
}
|
||||||
|
@ -552,9 +552,10 @@ public class FSEditLogLoader {
|
||||||
}
|
}
|
||||||
case OP_DELETE: {
|
case OP_DELETE: {
|
||||||
DeleteOp deleteOp = (DeleteOp)op;
|
DeleteOp deleteOp = (DeleteOp)op;
|
||||||
FSDirDeleteOp.deleteForEditLog(
|
final String src = renameReservedPathsOnUpgrade(
|
||||||
fsDir, renameReservedPathsOnUpgrade(deleteOp.path, logVersion),
|
deleteOp.path, logVersion);
|
||||||
deleteOp.timestamp);
|
final INodesInPath iip = fsDir.getINodesInPath4Write(src, false);
|
||||||
|
FSDirDeleteOp.deleteForEditLog(fsDir, iip, deleteOp.timestamp);
|
||||||
|
|
||||||
if (toAddRetryCache) {
|
if (toAddRetryCache) {
|
||||||
fsNamesys.addCacheEntry(deleteOp.rpcClientId, deleteOp.rpcCallId);
|
fsNamesys.addCacheEntry(deleteOp.rpcClientId, deleteOp.rpcCallId);
|
||||||
|
|
|
@ -3784,7 +3784,7 @@ public class FSNamesystem implements Namesystem, FSNamesystemMBean,
|
||||||
LOG.warn("Removing lazyPersist file " + bc.getName() + " with no replicas.");
|
LOG.warn("Removing lazyPersist file " + bc.getName() + " with no replicas.");
|
||||||
BlocksMapUpdateInfo toRemoveBlocks =
|
BlocksMapUpdateInfo toRemoveBlocks =
|
||||||
FSDirDeleteOp.deleteInternal(
|
FSDirDeleteOp.deleteInternal(
|
||||||
FSNamesystem.this, bc.getName(),
|
FSNamesystem.this,
|
||||||
INodesInPath.fromINode((INodeFile) bc), false);
|
INodesInPath.fromINode((INodeFile) bc), false);
|
||||||
changed |= toRemoveBlocks != null;
|
changed |= toRemoveBlocks != null;
|
||||||
if (toRemoveBlocks != null) {
|
if (toRemoveBlocks != null) {
|
||||||
|
|
Loading…
Reference in New Issue