/* * Copyright (C) 2015 hops.io. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package io.hops.transaction.lock; import com.google.common.collect.Lists; import io.hops.common.INodeUtil; import io.hops.exception.StorageException; import io.hops.exception.TransactionContextException; import io.hops.metadata.hdfs.entity.INodeIdentifier; import io.hops.security.Users; import org.apache.hadoop.hdfs.server.namenode.INode; import org.apache.hadoop.hdfs.server.namenode.INodeDirectory; import java.io.IOException; import java.util.LinkedList; import java.util.List; final class IndividualINodeLock extends BaseINodeLock { private static final INodeIdentifier NON_EXISTING_INODE = new INodeIdentifier(INode.NON_EXISTING_ID); private final TransactionLockTypes.INodeLockType lockType; private final INodeIdentifier inodeIdentifier; private final boolean readUpPathInodes; IndividualINodeLock(TransactionLockTypes.INodeLockType lockType, INodeIdentifier inodeIdentifier, boolean readUpPathInodes) { this.lockType = lockType; this.inodeIdentifier = inodeIdentifier == null ? NON_EXISTING_INODE : inodeIdentifier; this.readUpPathInodes = readUpPathInodes; if (lockType.equals( TransactionLockTypes.INodeLockType.WRITE_ON_TARGET_AND_PARENT)) { throw new UnsupportedOperationException(); } } IndividualINodeLock(TransactionLockTypes.INodeLockType lockType, INodeIdentifier inodeIdentifier) { this(lockType, inodeIdentifier, false); } @Override protected void acquire(TransactionLocks locks) throws IOException { setPartitioningKey(inodeIdentifier.getInodeId()); INode inode = null; if (inodeIdentifier.getName() != null && inodeIdentifier.getPid() != null) { inode = find(lockType, inodeIdentifier.getName(), inodeIdentifier.getPid(), inodeIdentifier.getPartitionId(), inodeIdentifier.getInodeId()); } else if (inodeIdentifier.getInodeId() != null) { inode = find(lockType, inodeIdentifier.getInodeId()); } else { throw new StorageException( "INodeIdentifier object is not properly " + "initialized "); } if (readUpPathInodes) { List<INode> pathInodes = readUpInodes(inode); addPathINodesAndUpdateResolvingCache(INodeUtil.constructPath(pathInodes), pathInodes); } else { addIndividualINode(inode); } acquireINodeAttributes(); } private List<INode> readUpInodes(INode leaf) throws StorageException, TransactionContextException { LinkedList<INode> pathInodes = new LinkedList<INode>(); pathInodes.add(leaf); INode curr = leaf; while (curr.getParentId() != INodeDirectory.ROOT_PARENT_ID) { curr = find(TransactionLockTypes.INodeLockType.READ_COMMITTED, curr.getParentId()); pathInodes.addFirst(curr); } return pathInodes; } }