use of alluxio.master.file.meta.TempInodePathForDescendant in project alluxio by Alluxio.
the class FileSystemMaster method setAttributeAndJournal.
/**
* Sets the file attribute.
* <p>
* Writes to the journal.
*
* @param inodePath the {@link LockedInodePath} to set attribute for
* @param rootRequired indicates whether it requires to be the superuser
* @param ownerRequired indicates whether it requires to be the owner of this path
* @param options attributes to be set, see {@link SetAttributeOptions}
* @param journalContext the journal context
* @throws InvalidPathException if the given path is invalid
* @throws FileDoesNotExistException if the file does not exist
* @throws AccessControlException if permission checking fails
*/
private void setAttributeAndJournal(LockedInodePath inodePath, boolean rootRequired, boolean ownerRequired, SetAttributeOptions options, JournalContext journalContext) throws InvalidPathException, FileDoesNotExistException, AccessControlException {
Inode<?> targetInode = inodePath.getInode();
long opTimeMs = System.currentTimeMillis();
if (options.isRecursive() && targetInode.isDirectory()) {
try (InodeLockList lockList = mInodeTree.lockDescendants(inodePath, InodeTree.LockMode.WRITE)) {
List<Inode<?>> inodeChildren = lockList.getInodes();
for (Inode<?> inode : inodeChildren) {
// the path to inode for getPath should already be locked.
try (LockedInodePath childPath = mInodeTree.lockFullInodePath(mInodeTree.getPath(inode), InodeTree.LockMode.READ)) {
// TODO(gpang): a better way to check permissions
mPermissionChecker.checkSetAttributePermission(childPath, rootRequired, ownerRequired);
}
}
TempInodePathForDescendant tempInodePath = new TempInodePathForDescendant(inodePath);
for (Inode<?> inode : inodeChildren) {
// the path to inode for getPath should already be locked.
tempInodePath.setDescendant(inode, mInodeTree.getPath(inode));
List<Inode<?>> persistedInodes = setAttributeInternal(tempInodePath, false, opTimeMs, options);
journalPersistedInodes(persistedInodes, journalContext);
journalSetAttribute(tempInodePath, opTimeMs, options, journalContext);
}
}
}
List<Inode<?>> persistedInodes = setAttributeInternal(inodePath, false, opTimeMs, options);
journalPersistedInodes(persistedInodes, journalContext);
journalSetAttribute(inodePath, opTimeMs, options, journalContext);
}
use of alluxio.master.file.meta.TempInodePathForDescendant in project alluxio by Alluxio.
the class FileSystemMaster method freeAndJournal.
/**
* Implements free operation.
* <p>
* This may write to the journal as free operation may change the pinned state of inodes.
*
* @param inodePath inode of the path to free
* @param options options to free
* @param journalContext the journal context
* @throws FileDoesNotExistException if the file does not exist
* @throws AccessControlException if permission checking fails
* @throws InvalidPathException if the given path is invalid
* @throws UnexpectedAlluxioException if the file or directory can not be freed
*/
private void freeAndJournal(LockedInodePath inodePath, FreeOptions options, JournalContext journalContext) throws FileDoesNotExistException, UnexpectedAlluxioException, AccessControlException, InvalidPathException {
Inode<?> inode = inodePath.getInode();
if (inode.isDirectory() && !options.isRecursive() && ((InodeDirectory) inode).getNumberOfChildren() > 0) {
// inode is nonempty, and we don't free a nonempty directory unless recursive is true
throw new UnexpectedAlluxioException(ExceptionMessage.CANNOT_FREE_NON_EMPTY_DIR.getMessage(mInodeTree.getPath(inode)));
}
long opTimeMs = System.currentTimeMillis();
List<Inode<?>> freeInodes = new ArrayList<>();
freeInodes.add(inode);
try (InodeLockList lockList = mInodeTree.lockDescendants(inodePath, InodeTree.LockMode.WRITE)) {
freeInodes.addAll(lockList.getInodes());
TempInodePathForDescendant tempInodePath = new TempInodePathForDescendant(inodePath);
// We go through each inode.
for (int i = freeInodes.size() - 1; i >= 0; i--) {
Inode<?> freeInode = freeInodes.get(i);
if (freeInode.isFile()) {
if (freeInode.getPersistenceState() != PersistenceState.PERSISTED) {
throw new UnexpectedAlluxioException(ExceptionMessage.CANNOT_FREE_NON_PERSISTED_FILE.getMessage(mInodeTree.getPath(freeInode)));
}
if (freeInode.isPinned()) {
if (!options.isForced()) {
throw new UnexpectedAlluxioException(ExceptionMessage.CANNOT_FREE_PINNED_FILE.getMessage(mInodeTree.getPath(freeInode)));
}
// the path to inode for getPath should already be locked.
tempInodePath.setDescendant(freeInode, mInodeTree.getPath(freeInode));
SetAttributeOptions setAttributeOptions = SetAttributeOptions.defaults().setRecursive(false).setPinned(false);
setAttributeInternal(tempInodePath, false, opTimeMs, setAttributeOptions);
journalSetAttribute(tempInodePath, opTimeMs, setAttributeOptions, journalContext);
}
// Remove corresponding blocks from workers.
mBlockMaster.removeBlocks(((InodeFile) freeInode).getBlockIds(), false);
}
}
}
Metrics.FILES_FREED.inc(freeInodes.size());
}
use of alluxio.master.file.meta.TempInodePathForDescendant in project alluxio by Alluxio.
the class FileSystemMaster method listStatus.
/**
* Returns a list of {@link FileInfo} for a given path. If the given path is a file, the list only
* contains a single object. If it is a directory, the resulting list contains all direct children
* of the directory.
* <p>
* This operation requires users to have
* {@link Mode.Bits#READ} permission on the path, and also
* {@link Mode.Bits#EXECUTE} permission on the path if it is a directory.
*
* @param path the path to get the {@link FileInfo} list for
* @param listStatusOptions the {@link alluxio.master.file.options.ListStatusOptions}
* @return the list of {@link FileInfo}s
* @throws AccessControlException if permission checking fails
* @throws FileDoesNotExistException if the file does not exist
* @throws InvalidPathException if the path is invalid
*/
public List<FileInfo> listStatus(AlluxioURI path, ListStatusOptions listStatusOptions) throws AccessControlException, FileDoesNotExistException, InvalidPathException {
Metrics.GET_FILE_INFO_OPS.inc();
try (JournalContext journalContext = createJournalContext();
LockedInodePath inodePath = mInodeTree.lockInodePath(path, InodeTree.LockMode.WRITE)) {
// This is WRITE locked, since loading metadata is possible.
mPermissionChecker.checkPermission(Mode.Bits.READ, inodePath);
LoadMetadataOptions loadMetadataOptions = LoadMetadataOptions.defaults().setCreateAncestors(true).setLoadDirectChildren(listStatusOptions.getLoadMetadataType() != LoadMetadataType.Never);
Inode<?> inode;
if (inodePath.fullPathExists()) {
inode = inodePath.getInode();
if (inode.isDirectory() && listStatusOptions.getLoadMetadataType() != LoadMetadataType.Always && ((InodeDirectory) inode).isDirectChildrenLoaded()) {
loadMetadataOptions.setLoadDirectChildren(false);
}
}
loadMetadataIfNotExistAndJournal(inodePath, loadMetadataOptions, journalContext);
mInodeTree.ensureFullInodePath(inodePath, InodeTree.LockMode.READ);
inode = inodePath.getInode();
List<FileInfo> ret = new ArrayList<>();
if (inode.isDirectory()) {
TempInodePathForDescendant tempInodePath = new TempInodePathForDescendant(inodePath);
mPermissionChecker.checkPermission(Mode.Bits.EXECUTE, inodePath);
for (Inode<?> child : ((InodeDirectory) inode).getChildren()) {
child.lockReadAndCheckParent(inode);
try {
// the path to child for getPath should already be locked.
tempInodePath.setDescendant(child, mInodeTree.getPath(child));
ret.add(getFileInfoInternal(tempInodePath));
} finally {
child.unlockRead();
}
}
} else {
ret.add(getFileInfoInternal(inodePath));
}
Metrics.FILE_INFOS_GOT.inc();
return ret;
}
}
use of alluxio.master.file.meta.TempInodePathForDescendant in project alluxio by Alluxio.
the class FileSystemMaster method deleteInternal.
/**
* Implements file deletion.
*
* @param inodePath the file {@link LockedInodePath}
* @param replayed whether the operation is a result of replaying the journal
* @param opTimeMs the time of the operation
* @param deleteOptions the method optitions
* @throws FileDoesNotExistException if a non-existent file is encountered
* @throws IOException if an I/O error is encountered
* @throws InvalidPathException if the specified path is the root
* @throws DirectoryNotEmptyException if recursive is false and the file is a nonempty directory
*/
private void deleteInternal(LockedInodePath inodePath, boolean replayed, long opTimeMs, DeleteOptions deleteOptions) throws FileDoesNotExistException, IOException, DirectoryNotEmptyException, InvalidPathException {
// journaled will result in an inconsistency between Alluxio and UFS.
if (!inodePath.fullPathExists()) {
return;
}
Inode<?> inode = inodePath.getInode();
if (inode == null) {
return;
}
boolean recursive = deleteOptions.isRecursive();
boolean alluxioOnly = deleteOptions.isAlluxioOnly();
if (inode.isDirectory() && !recursive && ((InodeDirectory) inode).getNumberOfChildren() > 0) {
// true
throw new DirectoryNotEmptyException(ExceptionMessage.DELETE_NONEMPTY_DIRECTORY_NONRECURSIVE, inode.getName());
}
if (mInodeTree.isRootId(inode.getId())) {
// The root cannot be deleted.
throw new InvalidPathException(ExceptionMessage.DELETE_ROOT_DIRECTORY.getMessage());
}
List<Inode<?>> delInodes = new ArrayList<>();
delInodes.add(inode);
try (InodeLockList lockList = mInodeTree.lockDescendants(inodePath, InodeTree.LockMode.WRITE)) {
delInodes.addAll(lockList.getInodes());
TempInodePathForDescendant tempInodePath = new TempInodePathForDescendant(inodePath);
// file, we deal with the checkpoints and blocks as well.
for (int i = delInodes.size() - 1; i >= 0; i--) {
Inode<?> delInode = delInodes.get(i);
// the path to delInode for getPath should already be locked.
AlluxioURI alluxioUriToDel = mInodeTree.getPath(delInode);
tempInodePath.setDescendant(delInode, alluxioUriToDel);
// Currently, it will result in an inconsistency between Alluxio and UFS.
if (!replayed && delInode.isPersisted()) {
try {
// TODO(calvin): Add tests (ALLUXIO-1831)
if (mMountTable.isMountPoint(alluxioUriToDel)) {
unmountInternal(alluxioUriToDel);
} else {
// Delete the file in the under file system.
MountTable.Resolution resolution = mMountTable.resolve(alluxioUriToDel);
String ufsUri = resolution.getUri().toString();
UnderFileSystem ufs = resolution.getUfs();
boolean failedToDelete = false;
if (!alluxioOnly) {
if (delInode.isFile()) {
if (!ufs.deleteFile(ufsUri)) {
failedToDelete = ufs.isFile(ufsUri);
if (!failedToDelete) {
LOG.warn("The file to delete does not exist in ufs: {}", ufsUri);
}
}
} else {
if (!ufs.deleteDirectory(ufsUri, alluxio.underfs.options.DeleteOptions.defaults().setRecursive(true))) {
failedToDelete = ufs.isDirectory(ufsUri);
if (!failedToDelete) {
LOG.warn("The directory to delete does not exist in ufs: {}", ufsUri);
}
}
}
if (failedToDelete) {
LOG.error("Failed to delete {} from the under filesystem", ufsUri);
throw new IOException(ExceptionMessage.DELETE_FAILED_UFS.getMessage(ufsUri));
}
}
}
} catch (InvalidPathException e) {
LOG.warn(e.getMessage());
}
}
if (delInode.isFile()) {
// Remove corresponding blocks from workers and delete metadata in master.
mBlockMaster.removeBlocks(((InodeFile) delInode).getBlockIds(), true);
}
mInodeTree.deleteInode(tempInodePath, opTimeMs);
}
}
Metrics.PATHS_DELETED.inc(delInodes.size());
}
Aggregations