HDFS-13380. RBF: mv/rm fail after the directory exceeded the quota limit. Contributed by Yiqun Lin.

(cherry picked from commit e9b9f48dad)
This commit is contained in:
Inigo Goiri 2018-04-09 10:09:25 -07:00
parent 7e692425d5
commit 78ec00155e
2 changed files with 28 additions and 6 deletions

View File

@ -882,7 +882,8 @@ public class RouterRpcServer extends AbstractService
throws IOException {
checkOperation(OperationCategory.WRITE);
final List<RemoteLocation> srcLocations = getLocationsForPath(src, true);
final List<RemoteLocation> srcLocations =
getLocationsForPath(src, true, false);
// srcLocations may be trimmed by getRenameDestinations()
final List<RemoteLocation> locs = new LinkedList<>(srcLocations);
RemoteParam dstParam = getRenameDestinations(locs, dst);
@ -903,7 +904,8 @@ public class RouterRpcServer extends AbstractService
final Options.Rename... options) throws IOException {
checkOperation(OperationCategory.WRITE);
final List<RemoteLocation> srcLocations = getLocationsForPath(src, true);
final List<RemoteLocation> srcLocations =
getLocationsForPath(src, true, false);
// srcLocations may be trimmed by getRenameDestinations()
final List<RemoteLocation> locs = new LinkedList<>(srcLocations);
RemoteParam dstParam = getRenameDestinations(locs, dst);
@ -980,7 +982,8 @@ public class RouterRpcServer extends AbstractService
public boolean delete(String src, boolean recursive) throws IOException {
checkOperation(OperationCategory.WRITE);
final List<RemoteLocation> locations = getLocationsForPath(src, true);
final List<RemoteLocation> locations =
getLocationsForPath(src, true, false);
RemoteMethod method = new RemoteMethod("delete",
new Class<?>[] {String.class, boolean.class}, new RemoteParam(),
recursive);
@ -2081,14 +2084,29 @@ public class RouterRpcServer extends AbstractService
/**
* Get the possible locations of a path in the federated cluster.
* During the get operation, it will do the quota verification.
*
* @param path Path to check.
* @param failIfLocked Fail the request if locked (top mount point).
* @return Prioritized list of locations in the federated cluster.
* @throws IOException If the location for this path cannot be determined.
*/
protected List<RemoteLocation> getLocationsForPath(
String path, boolean failIfLocked) throws IOException {
protected List<RemoteLocation> getLocationsForPath(String path,
boolean failIfLocked) throws IOException {
return getLocationsForPath(path, failIfLocked, true);
}
/**
* Get the possible locations of a path in the federated cluster.
*
* @param path Path to check.
* @param failIfLocked Fail the request if locked (top mount point).
* @param needQuotaVerify If need to do the quota verification.
* @return Prioritized list of locations in the federated cluster.
* @throws IOException If the location for this path cannot be determined.
*/
protected List<RemoteLocation> getLocationsForPath(String path,
boolean failIfLocked, boolean needQuotaVerify) throws IOException {
try {
// Check the location for this path
final PathLocation location =
@ -2109,7 +2127,7 @@ public class RouterRpcServer extends AbstractService
}
// Check quota
if (this.router.isQuotaEnabled()) {
if (this.router.isQuotaEnabled() && needQuotaVerify) {
RouterQuotaUsage quotaUsage = this.router.getQuotaManager()
.getQuotaUsage(path);
if (quotaUsage != null) {

View File

@ -151,6 +151,10 @@ public class TestRouterQuota {
// mkdir in real FileSystem should be okay
nnFs1.mkdirs(new Path("/testdir1/" + UUID.randomUUID()));
nnFs2.mkdirs(new Path("/testdir2/" + UUID.randomUUID()));
// delete/rename call should be still okay
routerFs.delete(new Path("/nsquota"), true);
routerFs.rename(new Path("/nsquota/subdir"), new Path("/nsquota/subdir"));
}
@Test