001 /** 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, software 013 * distributed under the License is distributed on an "AS IS" BASIS, 014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 015 * See the License for the specific language governing permissions and 016 * limitations under the License. 017 */ 018 package org.apache.hadoop.hdfs.server.namenode; 019 020 import java.io.IOException; 021 022 import org.apache.hadoop.fs.permission.PermissionStatus; 023 import org.apache.hadoop.hdfs.protocol.Block; 024 import org.apache.hadoop.hdfs.server.blockmanagement.BlockInfo; 025 import org.apache.hadoop.hdfs.server.blockmanagement.BlockInfoUnderConstruction; 026 import org.apache.hadoop.hdfs.server.blockmanagement.DatanodeDescriptor; 027 import org.apache.hadoop.hdfs.server.common.HdfsServerConstants.BlockUCState; 028 029 /** 030 * I-node for file being written. 031 */ 032 public class INodeFileUnderConstruction extends INodeFile { 033 private String clientName; // lease holder 034 private final String clientMachine; 035 private final DatanodeDescriptor clientNode; // if client is a cluster node too. 036 037 INodeFileUnderConstruction(PermissionStatus permissions, 038 short replication, 039 long preferredBlockSize, 040 long modTime, 041 String clientName, 042 String clientMachine, 043 DatanodeDescriptor clientNode) { 044 this(permissions, 0, replication, preferredBlockSize, modTime, 045 clientName, clientMachine, clientNode); 046 } 047 048 INodeFileUnderConstruction(PermissionStatus permissions, 049 int nrBlocks, 050 short replication, 051 long preferredBlockSize, 052 long modTime, 053 String clientName, 054 String clientMachine, 055 DatanodeDescriptor clientNode) { 056 super(permissions.applyUMask(UMASK), nrBlocks, replication, 057 modTime, modTime, preferredBlockSize); 058 this.clientName = clientName; 059 this.clientMachine = clientMachine; 060 this.clientNode = clientNode; 061 } 062 063 INodeFileUnderConstruction(byte[] name, 064 short blockReplication, 065 long modificationTime, 066 long preferredBlockSize, 067 BlockInfo[] blocks, 068 PermissionStatus perm, 069 String clientName, 070 String clientMachine, 071 DatanodeDescriptor clientNode) { 072 super(perm, blocks, blockReplication, modificationTime, modificationTime, 073 preferredBlockSize); 074 setLocalName(name); 075 this.clientName = clientName; 076 this.clientMachine = clientMachine; 077 this.clientNode = clientNode; 078 } 079 080 String getClientName() { 081 return clientName; 082 } 083 084 void setClientName(String clientName) { 085 this.clientName = clientName; 086 } 087 088 String getClientMachine() { 089 return clientMachine; 090 } 091 092 DatanodeDescriptor getClientNode() { 093 return clientNode; 094 } 095 096 /** 097 * Is this inode being constructed? 098 */ 099 @Override 100 public boolean isUnderConstruction() { 101 return true; 102 } 103 104 // 105 // converts a INodeFileUnderConstruction into a INodeFile 106 // use the modification time as the access time 107 // 108 INodeFile convertToInodeFile() { 109 INodeFile obj = new INodeFile(getPermissionStatus(), 110 getBlocks(), 111 getReplication(), 112 getModificationTime(), 113 getModificationTime(), 114 getPreferredBlockSize()); 115 return obj; 116 117 } 118 119 /** 120 * Remove a block from the block list. This block should be 121 * the last one on the list. 122 */ 123 void removeLastBlock(Block oldblock) throws IOException { 124 if (blocks == null) { 125 throw new IOException("Trying to delete non-existant block " + oldblock); 126 } 127 int size_1 = blocks.length - 1; 128 if (!blocks[size_1].equals(oldblock)) { 129 throw new IOException("Trying to delete non-last block " + oldblock); 130 } 131 132 //copy to a new list 133 BlockInfo[] newlist = new BlockInfo[size_1]; 134 System.arraycopy(blocks, 0, newlist, 0, size_1); 135 blocks = newlist; 136 } 137 138 /** 139 * Convert the last block of the file to an under-construction block. 140 * Set its locations. 141 */ 142 public BlockInfoUnderConstruction setLastBlock(BlockInfo lastBlock, 143 DatanodeDescriptor[] targets) 144 throws IOException { 145 if (blocks == null || blocks.length == 0) { 146 throw new IOException("Trying to update non-existant block. " + 147 "File is empty."); 148 } 149 BlockInfoUnderConstruction ucBlock = 150 lastBlock.convertToBlockUnderConstruction( 151 BlockUCState.UNDER_CONSTRUCTION, targets); 152 ucBlock.setINode(this); 153 setBlock(numBlocks()-1, ucBlock); 154 return ucBlock; 155 } 156 }