Search in sources :

Example 1 with TempInodePathForDescendant

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);
}
Also used : LockedInodePath(alluxio.master.file.meta.LockedInodePath) Inode(alluxio.master.file.meta.Inode) TempInodePathForDescendant(alluxio.master.file.meta.TempInodePathForDescendant) InodeLockList(alluxio.master.file.meta.InodeLockList)

Example 2 with TempInodePathForDescendant

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());
}
Also used : SetAttributeOptions(alluxio.master.file.options.SetAttributeOptions) InodeDirectory(alluxio.master.file.meta.InodeDirectory) Inode(alluxio.master.file.meta.Inode) TempInodePathForDescendant(alluxio.master.file.meta.TempInodePathForDescendant) InodeLockList(alluxio.master.file.meta.InodeLockList) UnexpectedAlluxioException(alluxio.exception.UnexpectedAlluxioException) ArrayList(java.util.ArrayList)

Example 3 with TempInodePathForDescendant

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;
    }
}
Also used : LockedInodePath(alluxio.master.file.meta.LockedInodePath) LoadMetadataOptions(alluxio.master.file.options.LoadMetadataOptions) InodeDirectory(alluxio.master.file.meta.InodeDirectory) TempInodePathForDescendant(alluxio.master.file.meta.TempInodePathForDescendant) FileInfo(alluxio.wire.FileInfo) ArrayList(java.util.ArrayList)

Example 4 with TempInodePathForDescendant

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());
}
Also used : InodeLockList(alluxio.master.file.meta.InodeLockList) ArrayList(java.util.ArrayList) DirectoryNotEmptyException(alluxio.exception.DirectoryNotEmptyException) IOException(java.io.IOException) MountTable(alluxio.master.file.meta.MountTable) InvalidPathException(alluxio.exception.InvalidPathException) InodeDirectory(alluxio.master.file.meta.InodeDirectory) Inode(alluxio.master.file.meta.Inode) TempInodePathForDescendant(alluxio.master.file.meta.TempInodePathForDescendant) UnderFileSystem(alluxio.underfs.UnderFileSystem) AlluxioURI(alluxio.AlluxioURI)

Aggregations

TempInodePathForDescendant (alluxio.master.file.meta.TempInodePathForDescendant)4 Inode (alluxio.master.file.meta.Inode)3 InodeDirectory (alluxio.master.file.meta.InodeDirectory)3 InodeLockList (alluxio.master.file.meta.InodeLockList)3 ArrayList (java.util.ArrayList)3 LockedInodePath (alluxio.master.file.meta.LockedInodePath)2 AlluxioURI (alluxio.AlluxioURI)1 DirectoryNotEmptyException (alluxio.exception.DirectoryNotEmptyException)1 InvalidPathException (alluxio.exception.InvalidPathException)1 UnexpectedAlluxioException (alluxio.exception.UnexpectedAlluxioException)1 MountTable (alluxio.master.file.meta.MountTable)1 LoadMetadataOptions (alluxio.master.file.options.LoadMetadataOptions)1 SetAttributeOptions (alluxio.master.file.options.SetAttributeOptions)1 UnderFileSystem (alluxio.underfs.UnderFileSystem)1 FileInfo (alluxio.wire.FileInfo)1 IOException (java.io.IOException)1