@Test public void createFileWithInvalidBlockSize() throws Exception { mThrown.expect(BlockInfoException.class); mThrown.expectMessage("Invalid block size 0"); CreateFileContext context = CreateFileContext.mergeFrom(CreateFilePOptions.newBuilder().setBlockSizeBytes(0)); createPath(mTree, TEST_URI, context); }
public List<Inode> createPath(RpcContext rpcContext, LockedInodePath inodePath, CreatePathContext<?, ?> context) throws FileAlreadyExistsException, BlockInfoException, InvalidPathException, IOException, FileDoesNotExistException { Preconditions.checkState(inodePath.getLockPattern() == LockPattern.WRITE_EDGE); AlluxioURI path = inodePath.getUri(); if (path.isRoot()) { String errorMessage = "Not allowed to create existing root path: " + path; LOG.error(errorMessage); throw new FileAlreadyExistsException(errorMessage); } if (inodePath.fullPathExists()) { if (context instanceof CreateDirectoryContext && ((CreateDirectoryContext) context).getOptions().getAllowExists()) { return Collections.emptyList(); } else { String pathType = "file"; if (context instanceof CreateDirectoryContext) { pathType = "directory"; } String errorMessage = String .format("Not allowed to create %s because path already exists: %s", pathType, path); throw new FileAlreadyExistsException(errorMessage); } } if (context instanceof CreateFileContext) { CreateFileContext fileContext = (CreateFileContext) context; if (fileContext.getOptions().getBlockSizeBytes() < 1) { throw new BlockInfoException( "Invalid block size " + fileContext.getOptions().getBlockSizeBytes()); } } LOG.debug("createPath {}", path); String[] pathComponents = inodePath.mPathComponents; String name = path.getName(); int pathIndex = inodePath.getExistingInodeCount(); if (pathIndex < pathComponents.length - 1) { if (!context.isRecursive()) { throw new FileDoesNotExistException(String.format( "File %s creation failed. Component %d(%s) does not exist", path, pathIndex, pathComponents[pathIndex])); } } Inode ancestorInode = inodePath.getAncestorInode(); if (!ancestorInode.isDirectory()) { throw new InvalidPathException("Could not traverse to parent directory of path " + path + ". Component " + pathComponents[pathIndex - 1] + " is not a directory."); } InodeDirectoryView currentInodeDirectory = ancestorInode.asDirectory(); List<Inode> createdInodes = new ArrayList<>(); if (context.isPersisted()) { for (Inode inode : inodePath.getInodeList()) { if (!inode.isPersisted()) { syncPersistExistingDirectory(rpcContext, inode.asDirectory()); } } } if ((pathIndex < (pathComponents.length - 1) || !mInodeStore.getChild(currentInodeDirectory, name).isPresent()) && context.getOperationTimeMs() > currentInodeDirectory.getLastModificationTimeMs()) { long currentId = currentInodeDirectory.getId(); try (LockResource lr = mInodeLockManager.lockUpdate(currentId)) { long updatedLastModified = mInodeStore.get(currentId).get().getLastModificationTimeMs(); if (updatedLastModified < context.getOperationTimeMs()) { UpdateInodeEntry.Builder updateInodeEntry = UpdateInodeEntry.newBuilder() .setId(currentId) .setLastModificationTimeMs(context.getOperationTimeMs()) .setLastAccessTimeMs(context.getOperationTimeMs()); if (context.getXAttr() != null) { updateInodeEntry.putAllXAttr(CommonUtils.convertToByteString(context.getXAttr())); } mState.applyAndJournal(rpcContext, updateInodeEntry.build()); } } } CreateDirectoryContext missingDirContext = CreateDirectoryContext.defaults(); missingDirContext.getOptions().setCommonOptions(FileSystemMasterCommonPOptions.newBuilder() .setTtl(context.getTtl()).setTtlAction(context.getTtlAction())); missingDirContext.setWriteType(context.getWriteType()); missingDirContext.setOperationTimeMs(context.getOperationTimeMs()); missingDirContext.setMountPoint(false); missingDirContext.setOwner(context.getOwner()); missingDirContext.setGroup(context.getGroup()); missingDirContext.setXAttr(context.getXAttr()); StringBuilder pathBuilder = new StringBuilder().append( String.join(AlluxioURI.SEPARATOR, Arrays.asList(pathComponents).subList(0, pathIndex)) ); for (int k = pathIndex; k < (pathComponents.length - 1); k++) { MutableInodeDirectory newDir = MutableInodeDirectory.create( mDirectoryIdGenerator.getNewDirectoryId(rpcContext.getJournalContext()), currentInodeDirectory.getId(), pathComponents[k], missingDirContext); newDir.setPinned(currentInodeDirectory.isPinned()); inheritOwnerAndGroupIfEmpty(newDir, currentInodeDirectory); short mode = context.isMetadataLoad() ? Mode.createFullAccess().toShort() : newDir.getMode(); DefaultAccessControlList dAcl = currentInodeDirectory.getDefaultACL(); if (!dAcl.isEmpty()) { Pair<AccessControlList, DefaultAccessControlList> pair = dAcl.generateChildDirACL(mode); newDir.setInternalAcl(pair.getFirst()); newDir.setDefaultACL(pair.getSecond()); } String newDirPath = k == 0 ? ROOT_PATH : pathBuilder.append(AlluxioURI.SEPARATOR).append(pathComponents[k]).toString(); mState.applyAndJournal(rpcContext, newDir, newDirPath); inodePath.addNextInode(Inode.wrap(newDir)); if (context.isPersisted()) { syncPersistExistingDirectory(rpcContext, newDir); } createdInodes.add(Inode.wrap(newDir)); currentInodeDirectory = newDir; } MutableInode<?> newInode; if (context instanceof CreateDirectoryContext) { CreateDirectoryContext directoryContext = (CreateDirectoryContext) context; MutableInodeDirectory newDir = MutableInodeDirectory.create( mDirectoryIdGenerator.getNewDirectoryId(rpcContext.getJournalContext()), currentInodeDirectory.getId(), name, directoryContext); short mode = context.isMetadataLoad() ? Mode.createFullAccess().toShort() : newDir.getMode(); DefaultAccessControlList dAcl = currentInodeDirectory.getDefaultACL(); if (!dAcl.isEmpty()) { Pair<AccessControlList, DefaultAccessControlList> pair = dAcl.generateChildDirACL(mode); newDir.setInternalAcl(pair.getFirst()); newDir.setDefaultACL(pair.getSecond()); } if (directoryContext.isPersisted()) { if (context.isMetadataLoad()) { newDir.setOwner(context.getOwner()) .setGroup(context.getGroup()) .setMode(context.getMode().toShort()); Long operationTimeMs = context.getOperationTimeMs(); if (operationTimeMs != null) { newDir.setLastModificationTimeMs(operationTimeMs, true); newDir.setLastAccessTimeMs(operationTimeMs, true); } newDir.setPersistenceState(PersistenceState.PERSISTED); } else { syncPersistNewDirectory(newDir); } } inheritOwnerAndGroupIfEmpty(newDir, currentInodeDirectory); newInode = newDir; } else if (context instanceof CreateFileContext) { CreateFileContext fileContext = (CreateFileContext) context; MutableInodeFile newFile = MutableInodeFile.create(mContainerIdGenerator.getNewContainerId(), currentInodeDirectory.getId(), name, System.currentTimeMillis(), fileContext); DefaultAccessControlList dAcl = currentInodeDirectory.getDefaultACL(); short mode = context.isMetadataLoad() ? Mode.createFullAccess().toShort() : newFile.getMode(); if (!dAcl.isEmpty()) { AccessControlList acl = dAcl.generateChildFileACL(mode); newFile.setInternalAcl(acl); } if (fileContext.isCacheable()) { newFile.setCacheable(true); } if (fileContext.getWriteType() == WriteType.ASYNC_THROUGH) { newFile.setPersistenceState(PersistenceState.TO_BE_PERSISTED); } inheritOwnerAndGroupIfEmpty(newFile, currentInodeDirectory); newInode = newFile; } else { throw new IllegalStateException(String.format("Unrecognized create options: %s", context)); } newInode.setPinned(currentInodeDirectory.isPinned()); mState.applyAndJournal(rpcContext, newInode, inodePath.getUri().getPath()); Inode inode = Inode.wrap(newInode); inodePath.addNextInode(inode); createdInodes.add(inode); LOG.debug("createFile: File Created: {} parent: {}", newInode, currentInodeDirectory); return createdInodes; }
InodeTree implements DelegatingJournaled { public List<Inode> createPath(RpcContext rpcContext, LockedInodePath inodePath, CreatePathContext<?, ?> context) throws FileAlreadyExistsException, BlockInfoException, InvalidPathException, IOException, FileDoesNotExistException { Preconditions.checkState(inodePath.getLockPattern() == LockPattern.WRITE_EDGE); AlluxioURI path = inodePath.getUri(); if (path.isRoot()) { String errorMessage = "Not allowed to create existing root path: " + path; LOG.error(errorMessage); throw new FileAlreadyExistsException(errorMessage); } if (inodePath.fullPathExists()) { if (context instanceof CreateDirectoryContext && ((CreateDirectoryContext) context).getOptions().getAllowExists()) { return Collections.emptyList(); } else { String pathType = "file"; if (context instanceof CreateDirectoryContext) { pathType = "directory"; } String errorMessage = String .format("Not allowed to create %s because path already exists: %s", pathType, path); throw new FileAlreadyExistsException(errorMessage); } } if (context instanceof CreateFileContext) { CreateFileContext fileContext = (CreateFileContext) context; if (fileContext.getOptions().getBlockSizeBytes() < 1) { throw new BlockInfoException( "Invalid block size " + fileContext.getOptions().getBlockSizeBytes()); } } LOG.debug("createPath {}", path); String[] pathComponents = inodePath.mPathComponents; String name = path.getName(); int pathIndex = inodePath.getExistingInodeCount(); if (pathIndex < pathComponents.length - 1) { if (!context.isRecursive()) { throw new FileDoesNotExistException(String.format( "File %s creation failed. Component %d(%s) does not exist", path, pathIndex, pathComponents[pathIndex])); } } Inode ancestorInode = inodePath.getAncestorInode(); if (!ancestorInode.isDirectory()) { throw new InvalidPathException("Could not traverse to parent directory of path " + path + ". Component " + pathComponents[pathIndex - 1] + " is not a directory."); } InodeDirectoryView currentInodeDirectory = ancestorInode.asDirectory(); List<Inode> createdInodes = new ArrayList<>(); if (context.isPersisted()) { for (Inode inode : inodePath.getInodeList()) { if (!inode.isPersisted()) { syncPersistExistingDirectory(rpcContext, inode.asDirectory()); } } } if ((pathIndex < (pathComponents.length - 1) || !mInodeStore.getChild(currentInodeDirectory, name).isPresent()) && context.getOperationTimeMs() > currentInodeDirectory.getLastModificationTimeMs()) { long currentId = currentInodeDirectory.getId(); try (LockResource lr = mInodeLockManager.lockUpdate(currentId)) { long updatedLastModified = mInodeStore.get(currentId).get().getLastModificationTimeMs(); if (updatedLastModified < context.getOperationTimeMs()) { UpdateInodeEntry.Builder updateInodeEntry = UpdateInodeEntry.newBuilder() .setId(currentId) .setLastModificationTimeMs(context.getOperationTimeMs()) .setLastAccessTimeMs(context.getOperationTimeMs()); if (context.getXAttr() != null) { updateInodeEntry.putAllXAttr(CommonUtils.convertToByteString(context.getXAttr())); } mState.applyAndJournal(rpcContext, updateInodeEntry.build()); } } } CreateDirectoryContext missingDirContext = CreateDirectoryContext.defaults(); missingDirContext.getOptions().setCommonOptions(FileSystemMasterCommonPOptions.newBuilder() .setTtl(context.getTtl()).setTtlAction(context.getTtlAction())); missingDirContext.setWriteType(context.getWriteType()); missingDirContext.setOperationTimeMs(context.getOperationTimeMs()); missingDirContext.setMountPoint(false); missingDirContext.setOwner(context.getOwner()); missingDirContext.setGroup(context.getGroup()); missingDirContext.setXAttr(context.getXAttr()); StringBuilder pathBuilder = new StringBuilder().append( String.join(AlluxioURI.SEPARATOR, Arrays.asList(pathComponents).subList(0, pathIndex)) ); for (int k = pathIndex; k < (pathComponents.length - 1); k++) { MutableInodeDirectory newDir = MutableInodeDirectory.create( mDirectoryIdGenerator.getNewDirectoryId(rpcContext.getJournalContext()), currentInodeDirectory.getId(), pathComponents[k], missingDirContext); newDir.setPinned(currentInodeDirectory.isPinned()); inheritOwnerAndGroupIfEmpty(newDir, currentInodeDirectory); short mode = context.isMetadataLoad() ? Mode.createFullAccess().toShort() : newDir.getMode(); DefaultAccessControlList dAcl = currentInodeDirectory.getDefaultACL(); if (!dAcl.isEmpty()) { Pair<AccessControlList, DefaultAccessControlList> pair = dAcl.generateChildDirACL(mode); newDir.setInternalAcl(pair.getFirst()); newDir.setDefaultACL(pair.getSecond()); } String newDirPath = k == 0 ? ROOT_PATH : pathBuilder.append(AlluxioURI.SEPARATOR).append(pathComponents[k]).toString(); mState.applyAndJournal(rpcContext, newDir, newDirPath); inodePath.addNextInode(Inode.wrap(newDir)); if (context.isPersisted()) { syncPersistExistingDirectory(rpcContext, newDir); } createdInodes.add(Inode.wrap(newDir)); currentInodeDirectory = newDir; } MutableInode<?> newInode; if (context instanceof CreateDirectoryContext) { CreateDirectoryContext directoryContext = (CreateDirectoryContext) context; MutableInodeDirectory newDir = MutableInodeDirectory.create( mDirectoryIdGenerator.getNewDirectoryId(rpcContext.getJournalContext()), currentInodeDirectory.getId(), name, directoryContext); short mode = context.isMetadataLoad() ? Mode.createFullAccess().toShort() : newDir.getMode(); DefaultAccessControlList dAcl = currentInodeDirectory.getDefaultACL(); if (!dAcl.isEmpty()) { Pair<AccessControlList, DefaultAccessControlList> pair = dAcl.generateChildDirACL(mode); newDir.setInternalAcl(pair.getFirst()); newDir.setDefaultACL(pair.getSecond()); } if (directoryContext.isPersisted()) { if (context.isMetadataLoad()) { newDir.setOwner(context.getOwner()) .setGroup(context.getGroup()) .setMode(context.getMode().toShort()); Long operationTimeMs = context.getOperationTimeMs(); if (operationTimeMs != null) { newDir.setLastModificationTimeMs(operationTimeMs, true); newDir.setLastAccessTimeMs(operationTimeMs, true); } newDir.setPersistenceState(PersistenceState.PERSISTED); } else { syncPersistNewDirectory(newDir); } } inheritOwnerAndGroupIfEmpty(newDir, currentInodeDirectory); newInode = newDir; } else if (context instanceof CreateFileContext) { CreateFileContext fileContext = (CreateFileContext) context; MutableInodeFile newFile = MutableInodeFile.create(mContainerIdGenerator.getNewContainerId(), currentInodeDirectory.getId(), name, System.currentTimeMillis(), fileContext); DefaultAccessControlList dAcl = currentInodeDirectory.getDefaultACL(); short mode = context.isMetadataLoad() ? Mode.createFullAccess().toShort() : newFile.getMode(); if (!dAcl.isEmpty()) { AccessControlList acl = dAcl.generateChildFileACL(mode); newFile.setInternalAcl(acl); } if (fileContext.isCacheable()) { newFile.setCacheable(true); } if (fileContext.getWriteType() == WriteType.ASYNC_THROUGH) { newFile.setPersistenceState(PersistenceState.TO_BE_PERSISTED); } inheritOwnerAndGroupIfEmpty(newFile, currentInodeDirectory); newInode = newFile; } else { throw new IllegalStateException(String.format("Unrecognized create options: %s", context)); } newInode.setPinned(currentInodeDirectory.isPinned()); mState.applyAndJournal(rpcContext, newInode, inodePath.getUri().getPath()); Inode inode = Inode.wrap(newInode); inodePath.addNextInode(inode); createdInodes.add(inode); LOG.debug("createFile: File Created: {} parent: {}", newInode, currentInodeDirectory); return createdInodes; } }
InodeTree implements DelegatingJournaled { public List<Inode> createPath(RpcContext rpcContext, LockedInodePath inodePath, CreatePathContext<?, ?> context) throws FileAlreadyExistsException, BlockInfoException, InvalidPathException, IOException, FileDoesNotExistException { Preconditions.checkState(inodePath.getLockPattern() == LockPattern.WRITE_EDGE); AlluxioURI path = inodePath.getUri(); if (path.isRoot()) { String errorMessage = "Not allowed to create existing root path: " + path; LOG.error(errorMessage); throw new FileAlreadyExistsException(errorMessage); } if (inodePath.fullPathExists()) { if (context instanceof CreateDirectoryContext && ((CreateDirectoryContext) context).getOptions().getAllowExists()) { return Collections.emptyList(); } else { String pathType = "file"; if (context instanceof CreateDirectoryContext) { pathType = "directory"; } String errorMessage = String .format("Not allowed to create %s because path already exists: %s", pathType, path); throw new FileAlreadyExistsException(errorMessage); } } if (context instanceof CreateFileContext) { CreateFileContext fileContext = (CreateFileContext) context; if (fileContext.getOptions().getBlockSizeBytes() < 1) { throw new BlockInfoException( "Invalid block size " + fileContext.getOptions().getBlockSizeBytes()); } } LOG.debug("createPath {}", path); String[] pathComponents = inodePath.mPathComponents; String name = path.getName(); int pathIndex = inodePath.getExistingInodeCount(); if (pathIndex < pathComponents.length - 1) { if (!context.isRecursive()) { throw new FileDoesNotExistException(String.format( "File %s creation failed. Component %d(%s) does not exist", path, pathIndex, pathComponents[pathIndex])); } } Inode ancestorInode = inodePath.getAncestorInode(); if (!ancestorInode.isDirectory()) { throw new InvalidPathException("Could not traverse to parent directory of path " + path + ". Component " + pathComponents[pathIndex - 1] + " is not a directory."); } InodeDirectoryView currentInodeDirectory = ancestorInode.asDirectory(); List<Inode> createdInodes = new ArrayList<>(); if (context.isPersisted()) { for (Inode inode : inodePath.getInodeList()) { if (!inode.isPersisted()) { syncPersistExistingDirectory(rpcContext, inode.asDirectory()); } } } if ((pathIndex < (pathComponents.length - 1) || !mInodeStore.getChild(currentInodeDirectory, name).isPresent()) && context.getOperationTimeMs() > currentInodeDirectory.getLastModificationTimeMs()) { long currentId = currentInodeDirectory.getId(); try (LockResource lr = mInodeLockManager.lockUpdate(currentId)) { long updatedLastModified = mInodeStore.get(currentId).get().getLastModificationTimeMs(); if (updatedLastModified < context.getOperationTimeMs()) { UpdateInodeEntry.Builder updateInodeEntry = UpdateInodeEntry.newBuilder() .setId(currentId) .setLastModificationTimeMs(context.getOperationTimeMs()) .setLastAccessTimeMs(context.getOperationTimeMs()); if (context.getXAttr() != null) { updateInodeEntry.putAllXAttr(CommonUtils.convertToByteString(context.getXAttr())); } mState.applyAndJournal(rpcContext, updateInodeEntry.build()); } } } CreateDirectoryContext missingDirContext = CreateDirectoryContext.defaults(); missingDirContext.getOptions().setCommonOptions(FileSystemMasterCommonPOptions.newBuilder() .setTtl(context.getTtl()).setTtlAction(context.getTtlAction())); missingDirContext.setWriteType(context.getWriteType()); missingDirContext.setOperationTimeMs(context.getOperationTimeMs()); missingDirContext.setMountPoint(false); missingDirContext.setOwner(context.getOwner()); missingDirContext.setGroup(context.getGroup()); missingDirContext.setXAttr(context.getXAttr()); StringBuilder pathBuilder = new StringBuilder().append( String.join(AlluxioURI.SEPARATOR, Arrays.asList(pathComponents).subList(0, pathIndex)) ); for (int k = pathIndex; k < (pathComponents.length - 1); k++) { MutableInodeDirectory newDir = MutableInodeDirectory.create( mDirectoryIdGenerator.getNewDirectoryId(rpcContext.getJournalContext()), currentInodeDirectory.getId(), pathComponents[k], missingDirContext); newDir.setPinned(currentInodeDirectory.isPinned()); inheritOwnerAndGroupIfEmpty(newDir, currentInodeDirectory); short mode = context.isMetadataLoad() ? Mode.createFullAccess().toShort() : newDir.getMode(); DefaultAccessControlList dAcl = currentInodeDirectory.getDefaultACL(); if (!dAcl.isEmpty()) { Pair<AccessControlList, DefaultAccessControlList> pair = dAcl.generateChildDirACL(mode); newDir.setInternalAcl(pair.getFirst()); newDir.setDefaultACL(pair.getSecond()); } String newDirPath = k == 0 ? ROOT_PATH : pathBuilder.append(AlluxioURI.SEPARATOR).append(pathComponents[k]).toString(); mState.applyAndJournal(rpcContext, newDir, newDirPath); inodePath.addNextInode(Inode.wrap(newDir)); if (context.isPersisted()) { syncPersistExistingDirectory(rpcContext, newDir); } createdInodes.add(Inode.wrap(newDir)); currentInodeDirectory = newDir; } MutableInode<?> newInode; if (context instanceof CreateDirectoryContext) { CreateDirectoryContext directoryContext = (CreateDirectoryContext) context; MutableInodeDirectory newDir = MutableInodeDirectory.create( mDirectoryIdGenerator.getNewDirectoryId(rpcContext.getJournalContext()), currentInodeDirectory.getId(), name, directoryContext); short mode = context.isMetadataLoad() ? Mode.createFullAccess().toShort() : newDir.getMode(); DefaultAccessControlList dAcl = currentInodeDirectory.getDefaultACL(); if (!dAcl.isEmpty()) { Pair<AccessControlList, DefaultAccessControlList> pair = dAcl.generateChildDirACL(mode); newDir.setInternalAcl(pair.getFirst()); newDir.setDefaultACL(pair.getSecond()); } if (directoryContext.isPersisted()) { if (context.isMetadataLoad()) { newDir.setOwner(context.getOwner()) .setGroup(context.getGroup()) .setMode(context.getMode().toShort()); Long operationTimeMs = context.getOperationTimeMs(); if (operationTimeMs != null) { newDir.setLastModificationTimeMs(operationTimeMs, true); newDir.setLastAccessTimeMs(operationTimeMs, true); } newDir.setPersistenceState(PersistenceState.PERSISTED); } else { syncPersistNewDirectory(newDir); } } inheritOwnerAndGroupIfEmpty(newDir, currentInodeDirectory); newInode = newDir; } else if (context instanceof CreateFileContext) { CreateFileContext fileContext = (CreateFileContext) context; MutableInodeFile newFile = MutableInodeFile.create(mContainerIdGenerator.getNewContainerId(), currentInodeDirectory.getId(), name, System.currentTimeMillis(), fileContext); DefaultAccessControlList dAcl = currentInodeDirectory.getDefaultACL(); short mode = context.isMetadataLoad() ? Mode.createFullAccess().toShort() : newFile.getMode(); if (!dAcl.isEmpty()) { AccessControlList acl = dAcl.generateChildFileACL(mode); newFile.setInternalAcl(acl); } if (fileContext.isCacheable()) { newFile.setCacheable(true); } if (fileContext.getWriteType() == WriteType.ASYNC_THROUGH) { newFile.setPersistenceState(PersistenceState.TO_BE_PERSISTED); } inheritOwnerAndGroupIfEmpty(newFile, currentInodeDirectory); newInode = newFile; } else { throw new IllegalStateException(String.format("Unrecognized create options: %s", context)); } newInode.setPinned(currentInodeDirectory.isPinned()); mState.applyAndJournal(rpcContext, newInode, inodePath.getUri().getPath()); Inode inode = Inode.wrap(newInode); inodePath.addNextInode(inode); createdInodes.add(inode); LOG.debug("createFile: File Created: {} parent: {}", newInode, currentInodeDirectory); return createdInodes; } InodeTree(InodeStore inodeStore, ContainerIdGenerable containerIdGenerator,
      InodeDirectoryIdGenerator directoryIdGenerator, MountTable mountTable,
      InodeLockManager lockManager); }
InodeTree implements DelegatingJournaled { public List<Inode> createPath(RpcContext rpcContext, LockedInodePath inodePath, CreatePathContext<?, ?> context) throws FileAlreadyExistsException, BlockInfoException, InvalidPathException, IOException, FileDoesNotExistException { Preconditions.checkState(inodePath.getLockPattern() == LockPattern.WRITE_EDGE); AlluxioURI path = inodePath.getUri(); if (path.isRoot()) { String errorMessage = "Not allowed to create existing root path: " + path; LOG.error(errorMessage); throw new FileAlreadyExistsException(errorMessage); } if (inodePath.fullPathExists()) { if (context instanceof CreateDirectoryContext && ((CreateDirectoryContext) context).getOptions().getAllowExists()) { return Collections.emptyList(); } else { String pathType = "file"; if (context instanceof CreateDirectoryContext) { pathType = "directory"; } String errorMessage = String .format("Not allowed to create %s because path already exists: %s", pathType, path); throw new FileAlreadyExistsException(errorMessage); } } if (context instanceof CreateFileContext) { CreateFileContext fileContext = (CreateFileContext) context; if (fileContext.getOptions().getBlockSizeBytes() < 1) { throw new BlockInfoException( "Invalid block size " + fileContext.getOptions().getBlockSizeBytes()); } } LOG.debug("createPath {}", path); String[] pathComponents = inodePath.mPathComponents; String name = path.getName(); int pathIndex = inodePath.getExistingInodeCount(); if (pathIndex < pathComponents.length - 1) { if (!context.isRecursive()) { throw new FileDoesNotExistException(String.format( "File %s creation failed. Component %d(%s) does not exist", path, pathIndex, pathComponents[pathIndex])); } } Inode ancestorInode = inodePath.getAncestorInode(); if (!ancestorInode.isDirectory()) { throw new InvalidPathException("Could not traverse to parent directory of path " + path + ". Component " + pathComponents[pathIndex - 1] + " is not a directory."); } InodeDirectoryView currentInodeDirectory = ancestorInode.asDirectory(); List<Inode> createdInodes = new ArrayList<>(); if (context.isPersisted()) { for (Inode inode : inodePath.getInodeList()) { if (!inode.isPersisted()) { syncPersistExistingDirectory(rpcContext, inode.asDirectory()); } } } if ((pathIndex < (pathComponents.length - 1) || !mInodeStore.getChild(currentInodeDirectory, name).isPresent()) && context.getOperationTimeMs() > currentInodeDirectory.getLastModificationTimeMs()) { long currentId = currentInodeDirectory.getId(); try (LockResource lr = mInodeLockManager.lockUpdate(currentId)) { long updatedLastModified = mInodeStore.get(currentId).get().getLastModificationTimeMs(); if (updatedLastModified < context.getOperationTimeMs()) { UpdateInodeEntry.Builder updateInodeEntry = UpdateInodeEntry.newBuilder() .setId(currentId) .setLastModificationTimeMs(context.getOperationTimeMs()) .setLastAccessTimeMs(context.getOperationTimeMs()); if (context.getXAttr() != null) { updateInodeEntry.putAllXAttr(CommonUtils.convertToByteString(context.getXAttr())); } mState.applyAndJournal(rpcContext, updateInodeEntry.build()); } } } CreateDirectoryContext missingDirContext = CreateDirectoryContext.defaults(); missingDirContext.getOptions().setCommonOptions(FileSystemMasterCommonPOptions.newBuilder() .setTtl(context.getTtl()).setTtlAction(context.getTtlAction())); missingDirContext.setWriteType(context.getWriteType()); missingDirContext.setOperationTimeMs(context.getOperationTimeMs()); missingDirContext.setMountPoint(false); missingDirContext.setOwner(context.getOwner()); missingDirContext.setGroup(context.getGroup()); missingDirContext.setXAttr(context.getXAttr()); StringBuilder pathBuilder = new StringBuilder().append( String.join(AlluxioURI.SEPARATOR, Arrays.asList(pathComponents).subList(0, pathIndex)) ); for (int k = pathIndex; k < (pathComponents.length - 1); k++) { MutableInodeDirectory newDir = MutableInodeDirectory.create( mDirectoryIdGenerator.getNewDirectoryId(rpcContext.getJournalContext()), currentInodeDirectory.getId(), pathComponents[k], missingDirContext); newDir.setPinned(currentInodeDirectory.isPinned()); inheritOwnerAndGroupIfEmpty(newDir, currentInodeDirectory); short mode = context.isMetadataLoad() ? Mode.createFullAccess().toShort() : newDir.getMode(); DefaultAccessControlList dAcl = currentInodeDirectory.getDefaultACL(); if (!dAcl.isEmpty()) { Pair<AccessControlList, DefaultAccessControlList> pair = dAcl.generateChildDirACL(mode); newDir.setInternalAcl(pair.getFirst()); newDir.setDefaultACL(pair.getSecond()); } String newDirPath = k == 0 ? ROOT_PATH : pathBuilder.append(AlluxioURI.SEPARATOR).append(pathComponents[k]).toString(); mState.applyAndJournal(rpcContext, newDir, newDirPath); inodePath.addNextInode(Inode.wrap(newDir)); if (context.isPersisted()) { syncPersistExistingDirectory(rpcContext, newDir); } createdInodes.add(Inode.wrap(newDir)); currentInodeDirectory = newDir; } MutableInode<?> newInode; if (context instanceof CreateDirectoryContext) { CreateDirectoryContext directoryContext = (CreateDirectoryContext) context; MutableInodeDirectory newDir = MutableInodeDirectory.create( mDirectoryIdGenerator.getNewDirectoryId(rpcContext.getJournalContext()), currentInodeDirectory.getId(), name, directoryContext); short mode = context.isMetadataLoad() ? Mode.createFullAccess().toShort() : newDir.getMode(); DefaultAccessControlList dAcl = currentInodeDirectory.getDefaultACL(); if (!dAcl.isEmpty()) { Pair<AccessControlList, DefaultAccessControlList> pair = dAcl.generateChildDirACL(mode); newDir.setInternalAcl(pair.getFirst()); newDir.setDefaultACL(pair.getSecond()); } if (directoryContext.isPersisted()) { if (context.isMetadataLoad()) { newDir.setOwner(context.getOwner()) .setGroup(context.getGroup()) .setMode(context.getMode().toShort()); Long operationTimeMs = context.getOperationTimeMs(); if (operationTimeMs != null) { newDir.setLastModificationTimeMs(operationTimeMs, true); newDir.setLastAccessTimeMs(operationTimeMs, true); } newDir.setPersistenceState(PersistenceState.PERSISTED); } else { syncPersistNewDirectory(newDir); } } inheritOwnerAndGroupIfEmpty(newDir, currentInodeDirectory); newInode = newDir; } else if (context instanceof CreateFileContext) { CreateFileContext fileContext = (CreateFileContext) context; MutableInodeFile newFile = MutableInodeFile.create(mContainerIdGenerator.getNewContainerId(), currentInodeDirectory.getId(), name, System.currentTimeMillis(), fileContext); DefaultAccessControlList dAcl = currentInodeDirectory.getDefaultACL(); short mode = context.isMetadataLoad() ? Mode.createFullAccess().toShort() : newFile.getMode(); if (!dAcl.isEmpty()) { AccessControlList acl = dAcl.generateChildFileACL(mode); newFile.setInternalAcl(acl); } if (fileContext.isCacheable()) { newFile.setCacheable(true); } if (fileContext.getWriteType() == WriteType.ASYNC_THROUGH) { newFile.setPersistenceState(PersistenceState.TO_BE_PERSISTED); } inheritOwnerAndGroupIfEmpty(newFile, currentInodeDirectory); newInode = newFile; } else { throw new IllegalStateException(String.format("Unrecognized create options: %s", context)); } newInode.setPinned(currentInodeDirectory.isPinned()); mState.applyAndJournal(rpcContext, newInode, inodePath.getUri().getPath()); Inode inode = Inode.wrap(newInode); inodePath.addNextInode(inode); createdInodes.add(inode); LOG.debug("createFile: File Created: {} parent: {}", newInode, currentInodeDirectory); return createdInodes; } InodeTree(InodeStore inodeStore, ContainerIdGenerable containerIdGenerator,
      InodeDirectoryIdGenerator directoryIdGenerator, MountTable mountTable,
      InodeLockManager lockManager); void initializeRoot(String owner, String group, Mode mode, JournalContext context); TtlBucketList getTtlBuckets(); long getInodeCount(); void setDirectChildrenLoaded(Supplier<JournalContext> context, InodeDirectory dir); long newBlock(Supplier<JournalContext> context, NewBlockEntry entry); void updateInodeFile(Supplier<JournalContext> context, UpdateInodeFileEntry entry); void updateInode(Supplier<JournalContext> context, UpdateInodeEntry entry); UpdateInodeEntry updateInodeAccessTimeNoJournal(long inodeId, long accessTime); void rename(Supplier<JournalContext> context, RenameEntry entry); void setAcl(Supplier<JournalContext> context, SetAclEntry entry); @Nullable String getRootUserName(); int getPinnedSize(); boolean inodeIdExists(long id); LockedInodePath tryLockInodePath(LockingScheme scheme); LockedInodePath lockInodePath(LockingScheme scheme); LockedInodePath lockInodePath(AlluxioURI uri, LockPattern lockPattern); LockedInodePath lockInodePath(AlluxioURI uri, LockPattern lockPattern, boolean tryLock); boolean inodePathExists(AlluxioURI uri); LockedInodePath lockFullInodePath(AlluxioURI uri, LockingScheme lockScheme); LockedInodePath lockFullInodePath(AlluxioURI uri, LockPattern lockPattern); LockedInodePath lockFullInodePath(long id, LockPattern lockPattern); InodePathPair lockInodePathPair(AlluxioURI path1, LockPattern lockPattern1,
      AlluxioURI path2, LockPattern lockPattern2); void ensureFullInodePath(LockedInodePath inodePath); AlluxioURI getPath(InodeView inode); InodeDirectory getRoot(); List<Inode> createPath(RpcContext rpcContext, LockedInodePath inodePath,
      CreatePathContext<?, ?> context); LockedInodePathList getDescendants(LockedInodePath inodePath); void deleteInode(RpcContext rpcContext, LockedInodePath inodePath, long opTimeMs); void setPinned(RpcContext rpcContext, LockedInodePath inodePath, boolean pinned,
      List<String> mediumTypes, long opTimeMs); void setReplication(RpcContext rpcContext, LockedInodePath inodePath,
      Integer replicationMax, Integer replicationMin, long opTimeMs); Set<Long> getReplicationLimitedFileIds(); Set<Long> getToBePersistedIds(); Set<Long> getPinIdSet(); InodeLockManager getInodeLockManager(); boolean isRootId(long fileId); @Override Journaled getDelegate(); void syncPersistExistingDirectory(Supplier<JournalContext> context, InodeDirectoryView dir); void syncPersistNewDirectory(MutableInodeDirectory dir); void close(); }
InodeTree implements DelegatingJournaled { public List<Inode> createPath(RpcContext rpcContext, LockedInodePath inodePath, CreatePathContext<?, ?> context) throws FileAlreadyExistsException, BlockInfoException, InvalidPathException, IOException, FileDoesNotExistException { Preconditions.checkState(inodePath.getLockPattern() == LockPattern.WRITE_EDGE); AlluxioURI path = inodePath.getUri(); if (path.isRoot()) { String errorMessage = "Not allowed to create existing root path: " + path; LOG.error(errorMessage); throw new FileAlreadyExistsException(errorMessage); } if (inodePath.fullPathExists()) { if (context instanceof CreateDirectoryContext && ((CreateDirectoryContext) context).getOptions().getAllowExists()) { return Collections.emptyList(); } else { String pathType = "file"; if (context instanceof CreateDirectoryContext) { pathType = "directory"; } String errorMessage = String .format("Not allowed to create %s because path already exists: %s", pathType, path); throw new FileAlreadyExistsException(errorMessage); } } if (context instanceof CreateFileContext) { CreateFileContext fileContext = (CreateFileContext) context; if (fileContext.getOptions().getBlockSizeBytes() < 1) { throw new BlockInfoException( "Invalid block size " + fileContext.getOptions().getBlockSizeBytes()); } } LOG.debug("createPath {}", path); String[] pathComponents = inodePath.mPathComponents; String name = path.getName(); int pathIndex = inodePath.getExistingInodeCount(); if (pathIndex < pathComponents.length - 1) { if (!context.isRecursive()) { throw new FileDoesNotExistException(String.format( "File %s creation failed. Component %d(%s) does not exist", path, pathIndex, pathComponents[pathIndex])); } } Inode ancestorInode = inodePath.getAncestorInode(); if (!ancestorInode.isDirectory()) { throw new InvalidPathException("Could not traverse to parent directory of path " + path + ". Component " + pathComponents[pathIndex - 1] + " is not a directory."); } InodeDirectoryView currentInodeDirectory = ancestorInode.asDirectory(); List<Inode> createdInodes = new ArrayList<>(); if (context.isPersisted()) { for (Inode inode : inodePath.getInodeList()) { if (!inode.isPersisted()) { syncPersistExistingDirectory(rpcContext, inode.asDirectory()); } } } if ((pathIndex < (pathComponents.length - 1) || !mInodeStore.getChild(currentInodeDirectory, name).isPresent()) && context.getOperationTimeMs() > currentInodeDirectory.getLastModificationTimeMs()) { long currentId = currentInodeDirectory.getId(); try (LockResource lr = mInodeLockManager.lockUpdate(currentId)) { long updatedLastModified = mInodeStore.get(currentId).get().getLastModificationTimeMs(); if (updatedLastModified < context.getOperationTimeMs()) { UpdateInodeEntry.Builder updateInodeEntry = UpdateInodeEntry.newBuilder() .setId(currentId) .setLastModificationTimeMs(context.getOperationTimeMs()) .setLastAccessTimeMs(context.getOperationTimeMs()); if (context.getXAttr() != null) { updateInodeEntry.putAllXAttr(CommonUtils.convertToByteString(context.getXAttr())); } mState.applyAndJournal(rpcContext, updateInodeEntry.build()); } } } CreateDirectoryContext missingDirContext = CreateDirectoryContext.defaults(); missingDirContext.getOptions().setCommonOptions(FileSystemMasterCommonPOptions.newBuilder() .setTtl(context.getTtl()).setTtlAction(context.getTtlAction())); missingDirContext.setWriteType(context.getWriteType()); missingDirContext.setOperationTimeMs(context.getOperationTimeMs()); missingDirContext.setMountPoint(false); missingDirContext.setOwner(context.getOwner()); missingDirContext.setGroup(context.getGroup()); missingDirContext.setXAttr(context.getXAttr()); StringBuilder pathBuilder = new StringBuilder().append( String.join(AlluxioURI.SEPARATOR, Arrays.asList(pathComponents).subList(0, pathIndex)) ); for (int k = pathIndex; k < (pathComponents.length - 1); k++) { MutableInodeDirectory newDir = MutableInodeDirectory.create( mDirectoryIdGenerator.getNewDirectoryId(rpcContext.getJournalContext()), currentInodeDirectory.getId(), pathComponents[k], missingDirContext); newDir.setPinned(currentInodeDirectory.isPinned()); inheritOwnerAndGroupIfEmpty(newDir, currentInodeDirectory); short mode = context.isMetadataLoad() ? Mode.createFullAccess().toShort() : newDir.getMode(); DefaultAccessControlList dAcl = currentInodeDirectory.getDefaultACL(); if (!dAcl.isEmpty()) { Pair<AccessControlList, DefaultAccessControlList> pair = dAcl.generateChildDirACL(mode); newDir.setInternalAcl(pair.getFirst()); newDir.setDefaultACL(pair.getSecond()); } String newDirPath = k == 0 ? ROOT_PATH : pathBuilder.append(AlluxioURI.SEPARATOR).append(pathComponents[k]).toString(); mState.applyAndJournal(rpcContext, newDir, newDirPath); inodePath.addNextInode(Inode.wrap(newDir)); if (context.isPersisted()) { syncPersistExistingDirectory(rpcContext, newDir); } createdInodes.add(Inode.wrap(newDir)); currentInodeDirectory = newDir; } MutableInode<?> newInode; if (context instanceof CreateDirectoryContext) { CreateDirectoryContext directoryContext = (CreateDirectoryContext) context; MutableInodeDirectory newDir = MutableInodeDirectory.create( mDirectoryIdGenerator.getNewDirectoryId(rpcContext.getJournalContext()), currentInodeDirectory.getId(), name, directoryContext); short mode = context.isMetadataLoad() ? Mode.createFullAccess().toShort() : newDir.getMode(); DefaultAccessControlList dAcl = currentInodeDirectory.getDefaultACL(); if (!dAcl.isEmpty()) { Pair<AccessControlList, DefaultAccessControlList> pair = dAcl.generateChildDirACL(mode); newDir.setInternalAcl(pair.getFirst()); newDir.setDefaultACL(pair.getSecond()); } if (directoryContext.isPersisted()) { if (context.isMetadataLoad()) { newDir.setOwner(context.getOwner()) .setGroup(context.getGroup()) .setMode(context.getMode().toShort()); Long operationTimeMs = context.getOperationTimeMs(); if (operationTimeMs != null) { newDir.setLastModificationTimeMs(operationTimeMs, true); newDir.setLastAccessTimeMs(operationTimeMs, true); } newDir.setPersistenceState(PersistenceState.PERSISTED); } else { syncPersistNewDirectory(newDir); } } inheritOwnerAndGroupIfEmpty(newDir, currentInodeDirectory); newInode = newDir; } else if (context instanceof CreateFileContext) { CreateFileContext fileContext = (CreateFileContext) context; MutableInodeFile newFile = MutableInodeFile.create(mContainerIdGenerator.getNewContainerId(), currentInodeDirectory.getId(), name, System.currentTimeMillis(), fileContext); DefaultAccessControlList dAcl = currentInodeDirectory.getDefaultACL(); short mode = context.isMetadataLoad() ? Mode.createFullAccess().toShort() : newFile.getMode(); if (!dAcl.isEmpty()) { AccessControlList acl = dAcl.generateChildFileACL(mode); newFile.setInternalAcl(acl); } if (fileContext.isCacheable()) { newFile.setCacheable(true); } if (fileContext.getWriteType() == WriteType.ASYNC_THROUGH) { newFile.setPersistenceState(PersistenceState.TO_BE_PERSISTED); } inheritOwnerAndGroupIfEmpty(newFile, currentInodeDirectory); newInode = newFile; } else { throw new IllegalStateException(String.format("Unrecognized create options: %s", context)); } newInode.setPinned(currentInodeDirectory.isPinned()); mState.applyAndJournal(rpcContext, newInode, inodePath.getUri().getPath()); Inode inode = Inode.wrap(newInode); inodePath.addNextInode(inode); createdInodes.add(inode); LOG.debug("createFile: File Created: {} parent: {}", newInode, currentInodeDirectory); return createdInodes; } InodeTree(InodeStore inodeStore, ContainerIdGenerable containerIdGenerator,
      InodeDirectoryIdGenerator directoryIdGenerator, MountTable mountTable,
      InodeLockManager lockManager); void initializeRoot(String owner, String group, Mode mode, JournalContext context); TtlBucketList getTtlBuckets(); long getInodeCount(); void setDirectChildrenLoaded(Supplier<JournalContext> context, InodeDirectory dir); long newBlock(Supplier<JournalContext> context, NewBlockEntry entry); void updateInodeFile(Supplier<JournalContext> context, UpdateInodeFileEntry entry); void updateInode(Supplier<JournalContext> context, UpdateInodeEntry entry); UpdateInodeEntry updateInodeAccessTimeNoJournal(long inodeId, long accessTime); void rename(Supplier<JournalContext> context, RenameEntry entry); void setAcl(Supplier<JournalContext> context, SetAclEntry entry); @Nullable String getRootUserName(); int getPinnedSize(); boolean inodeIdExists(long id); LockedInodePath tryLockInodePath(LockingScheme scheme); LockedInodePath lockInodePath(LockingScheme scheme); LockedInodePath lockInodePath(AlluxioURI uri, LockPattern lockPattern); LockedInodePath lockInodePath(AlluxioURI uri, LockPattern lockPattern, boolean tryLock); boolean inodePathExists(AlluxioURI uri); LockedInodePath lockFullInodePath(AlluxioURI uri, LockingScheme lockScheme); LockedInodePath lockFullInodePath(AlluxioURI uri, LockPattern lockPattern); LockedInodePath lockFullInodePath(long id, LockPattern lockPattern); InodePathPair lockInodePathPair(AlluxioURI path1, LockPattern lockPattern1,
      AlluxioURI path2, LockPattern lockPattern2); void ensureFullInodePath(LockedInodePath inodePath); AlluxioURI getPath(InodeView inode); InodeDirectory getRoot(); List<Inode> createPath(RpcContext rpcContext, LockedInodePath inodePath,
      CreatePathContext<?, ?> context); LockedInodePathList getDescendants(LockedInodePath inodePath); void deleteInode(RpcContext rpcContext, LockedInodePath inodePath, long opTimeMs); void setPinned(RpcContext rpcContext, LockedInodePath inodePath, boolean pinned,
      List<String> mediumTypes, long opTimeMs); void setReplication(RpcContext rpcContext, LockedInodePath inodePath,
      Integer replicationMax, Integer replicationMin, long opTimeMs); Set<Long> getReplicationLimitedFileIds(); Set<Long> getToBePersistedIds(); Set<Long> getPinIdSet(); InodeLockManager getInodeLockManager(); boolean isRootId(long fileId); @Override Journaled getDelegate(); void syncPersistExistingDirectory(Supplier<JournalContext> context, InodeDirectoryView dir); void syncPersistNewDirectory(MutableInodeDirectory dir); void close(); static final long NO_PARENT; static final String ROOT_INODE_NAME; static final String ROOT_PATH; static final int PATH_TRAVERSAL_RETRIES; }