/// <exception cref="System.IO.IOException"/> internal static IList <AclEntry> UnprotectedSetAcl(FSDirectory fsd, string src, IList <AclEntry> aclSpec, bool fromEdits) { System.Diagnostics.Debug.Assert(fsd.HasWriteLock()); INodesInPath iip = fsd.GetINodesInPath4Write(FSDirectory.NormalizePath(src), true ); // ACL removal is logged to edits as OP_SET_ACL with an empty list. if (aclSpec.IsEmpty()) { UnprotectedRemoveAcl(fsd, iip); return(AclFeature.EmptyEntryList); } INode inode = FSDirectory.ResolveLastINode(iip); int snapshotId = iip.GetLatestSnapshotId(); IList <AclEntry> newAcl = aclSpec; if (!fromEdits) { IList <AclEntry> existingAcl = AclStorage.ReadINodeLogicalAcl(inode); newAcl = AclTransformation.ReplaceAclEntries(existingAcl, aclSpec); } AclStorage.UpdateINodeAcl(inode, newAcl, snapshotId); return(newAcl); }
/// <exception cref="System.IO.IOException"/> private static void UnprotectedRemoveAcl(FSDirectory fsd, INodesInPath iip) { System.Diagnostics.Debug.Assert(fsd.HasWriteLock()); INode inode = FSDirectory.ResolveLastINode(iip); int snapshotId = iip.GetLatestSnapshotId(); AclFeature f = inode.GetAclFeature(); if (f == null) { return; } FsPermission perm = inode.GetFsPermission(); IList <AclEntry> featureEntries = AclStorage.GetEntriesFromAclFeature(f); if (featureEntries[0].GetScope() == AclEntryScope.Access) { // Restore group permissions from the feature's entry to permission // bits, overwriting the mask, which is not part of a minimal ACL. AclEntry groupEntryKey = new AclEntry.Builder().SetScope(AclEntryScope.Access).SetType (AclEntryType.Group).Build(); int groupEntryIndex = Sharpen.Collections.BinarySearch(featureEntries, groupEntryKey , AclTransformation.AclEntryComparator); System.Diagnostics.Debug.Assert(groupEntryIndex >= 0); FsAction groupPerm = featureEntries[groupEntryIndex].GetPermission(); FsPermission newPerm = new FsPermission(perm.GetUserAction(), groupPerm, perm.GetOtherAction (), perm.GetStickyBit()); inode.SetPermission(newPerm, snapshotId); } inode.RemoveAclFeature(snapshotId); }
/// <exception cref="Org.Apache.Hadoop.Hdfs.Protocol.QuotaExceededException"/> internal virtual void UpdateMtimeAndLease(long timestamp) { srcParent.UpdateModificationTime(timestamp, srcIIP.GetLatestSnapshotId()); INode dstParent = dstParentIIP.GetLastINode(); dstParent.UpdateModificationTime(timestamp, dstIIP.GetLatestSnapshotId()); // update moved lease with new filename fsd.GetFSNamesystem().UnprotectedChangeLease(src, dst); }
/// <exception cref="Org.Apache.Hadoop.FS.UnresolvedLinkException"/> /// <exception cref="Org.Apache.Hadoop.Hdfs.Protocol.QuotaExceededException"/> internal static bool UnprotectedSetTimes(FSDirectory fsd, string src, long mtime, long atime, bool force) { System.Diagnostics.Debug.Assert(fsd.HasWriteLock()); INodesInPath i = fsd.GetINodesInPath(src, true); return(UnprotectedSetTimes(fsd, i.GetLastINode(), mtime, atime, force, i.GetLatestSnapshotId ())); }
internal virtual bool AddSourceToDestination() { INode dstParent = dstParentIIP.GetLastINode(); byte[] dstChildName = dstIIP.GetLastLocalName(); INode toDst; if (withCount == null) { srcChild.SetLocalName(dstChildName); toDst = srcChild; } else { withCount.GetReferredINode().SetLocalName(dstChildName); toDst = new INodeReference.DstReference(dstParent.AsDirectory(), withCount, dstIIP .GetLatestSnapshotId()); } return(fsd.AddLastINodeNoQuotaCheck(dstParentIIP, toDst) != null); }
/// <exception cref="System.IO.FileNotFoundException"/> /// <exception cref="Org.Apache.Hadoop.FS.UnresolvedLinkException"/> /// <exception cref="Org.Apache.Hadoop.Hdfs.Protocol.QuotaExceededException"/> /// <exception cref="Org.Apache.Hadoop.Hdfs.Protocol.SnapshotAccessControlException"/ /// > internal static void UnprotectedSetOwner(FSDirectory fsd, string src, string username , string groupname) { System.Diagnostics.Debug.Assert(fsd.HasWriteLock()); INodesInPath inodesInPath = fsd.GetINodesInPath4Write(src, true); INode inode = inodesInPath.GetLastINode(); if (inode == null) { throw new FileNotFoundException("File does not exist: " + src); } if (username != null) { inode = inode.SetUser(username, inodesInPath.GetLatestSnapshotId()); } if (groupname != null) { inode.SetGroup(groupname, inodesInPath.GetLatestSnapshotId()); } }
/// <exception cref="Org.Apache.Hadoop.Hdfs.Protocol.QuotaExceededException"/> internal RenameOperation(FSDirectory fsd, string src, string dst, INodesInPath srcIIP , INodesInPath dstIIP) { this.fsd = fsd; this.src = src; this.dst = dst; this.srcIIP = srcIIP; this.dstIIP = dstIIP; this.srcParentIIP = srcIIP.GetParentINodesInPath(); this.dstParentIIP = dstIIP.GetParentINodesInPath(); BlockStoragePolicySuite bsps = fsd.GetBlockStoragePolicySuite(); srcChild = this.srcIIP.GetLastINode(); srcChildName = srcChild.GetLocalNameBytes(); int srcLatestSnapshotId = srcIIP.GetLatestSnapshotId(); isSrcInSnapshot = srcChild.IsInLatestSnapshot(srcLatestSnapshotId); srcChildIsReference = srcChild.IsReference(); srcParent = this.srcIIP.GetINode(-2).AsDirectory(); // Record the snapshot on srcChild. After the rename, before any new // snapshot is taken on the dst tree, changes will be recorded in the // latest snapshot of the src tree. if (isSrcInSnapshot) { srcChild.RecordModification(srcLatestSnapshotId); } // check srcChild for reference srcRefDstSnapshot = srcChildIsReference ? srcChild.AsReference().GetDstSnapshotId () : Org.Apache.Hadoop.Hdfs.Server.Namenode.Snapshot.Snapshot.CurrentStateId; oldSrcCounts = new QuotaCounts.Builder().Build(); if (isSrcInSnapshot) { INodeReference.WithName withName = srcParent.ReplaceChild4ReferenceWithName(srcChild , srcLatestSnapshotId); withCount = (INodeReference.WithCount)withName.GetReferredINode(); srcChild = withName; this.srcIIP = INodesInPath.Replace(srcIIP, srcIIP.Length() - 1, srcChild); // get the counts before rename withCount.GetReferredINode().ComputeQuotaUsage(bsps, oldSrcCounts, true); } else { if (srcChildIsReference) { // srcChild is reference but srcChild is not in latest snapshot withCount = (INodeReference.WithCount)srcChild.AsReference().GetReferredINode(); } else { withCount = null; } } }
/// <summary> /// Delete a path from the name space /// Update the count at each ancestor directory with quota /// </summary> /// <param name="iip">the inodes resolved from the path</param> /// <param name="collectedBlocks">blocks collected from the deleted path</param> /// <param name="removedINodes">inodes that should be removed from inodeMap</param> /// <param name="mtime">the time the inode is removed</param> /// <returns>the number of inodes deleted; 0 if no inodes are deleted.</returns> private static long UnprotectedDelete(FSDirectory fsd, INodesInPath iip, INode.BlocksMapUpdateInfo collectedBlocks, IList <INode> removedINodes, long mtime) { System.Diagnostics.Debug.Assert(fsd.HasWriteLock()); // check if target node exists INode targetNode = iip.GetLastINode(); if (targetNode == null) { return(-1); } // record modification int latestSnapshot = iip.GetLatestSnapshotId(); targetNode.RecordModification(latestSnapshot); // Remove the node from the namespace long removed = fsd.RemoveLastINode(iip); if (removed == -1) { return(-1); } // set the parent's modification time INodeDirectory parent = targetNode.GetParent(); parent.UpdateModificationTime(mtime, latestSnapshot); fsd.UpdateCountForDelete(targetNode, iip); if (removed == 0) { return(0); } // collect block and update quota if (!targetNode.IsInLatestSnapshot(latestSnapshot)) { targetNode.DestroyAndCollectBlocks(fsd.GetBlockStoragePolicySuite(), collectedBlocks , removedINodes); } else { QuotaCounts counts = targetNode.CleanSubtree(fsd.GetBlockStoragePolicySuite(), Org.Apache.Hadoop.Hdfs.Server.Namenode.Snapshot.Snapshot .CurrentStateId, latestSnapshot, collectedBlocks, removedINodes); removed = counts.GetNameSpace(); fsd.UpdateCountNoQuotaCheck(iip, iip.Length() - 1, counts.Negation()); } if (NameNode.stateChangeLog.IsDebugEnabled()) { NameNode.stateChangeLog.Debug("DIR* FSDirectory.unprotectedDelete: " + iip.GetPath () + " is removed"); } return(removed); }
/// <summary>Concat all the blocks from srcs to trg and delete the srcs files</summary> /// <param name="fsd">FSDirectory</param> /// <exception cref="System.IO.IOException"/> internal static void UnprotectedConcat(FSDirectory fsd, INodesInPath targetIIP, INodeFile [] srcList, long timestamp) { System.Diagnostics.Debug.Assert(fsd.HasWriteLock()); if (NameNode.stateChangeLog.IsDebugEnabled()) { NameNode.stateChangeLog.Debug("DIR* FSNamesystem.concat to " + targetIIP.GetPath( )); } INodeFile trgInode = targetIIP.GetLastINode().AsFile(); QuotaCounts deltas = ComputeQuotaDeltas(fsd, trgInode, srcList); VerifyQuota(fsd, targetIIP, deltas); // the target file can be included in a snapshot trgInode.RecordModification(targetIIP.GetLatestSnapshotId()); INodeDirectory trgParent = targetIIP.GetINode(-2).AsDirectory(); trgInode.ConcatBlocks(srcList); // since we are in the same dir - we can use same parent to remove files int count = 0; foreach (INodeFile nodeToRemove in srcList) { if (nodeToRemove != null) { nodeToRemove.SetBlocks(null); nodeToRemove.GetParent().RemoveChild(nodeToRemove); fsd.GetINodeMap().Remove(nodeToRemove); count++; } } trgInode.SetModificationTime(timestamp, targetIIP.GetLatestSnapshotId()); trgParent.UpdateModificationTime(timestamp, targetIIP.GetLatestSnapshotId()); // update quota on the parent directory with deltas FSDirectory.UnprotectedUpdateCount(targetIIP, targetIIP.Length() - 1, deltas); }
/// <exception cref="System.IO.FileNotFoundException"/> /// <exception cref="Org.Apache.Hadoop.FS.UnresolvedLinkException"/> /// <exception cref="Org.Apache.Hadoop.Hdfs.Protocol.QuotaExceededException"/> /// <exception cref="Org.Apache.Hadoop.Hdfs.Protocol.SnapshotAccessControlException"/ /// > internal static void UnprotectedSetPermission(FSDirectory fsd, string src, FsPermission permissions) { System.Diagnostics.Debug.Assert(fsd.HasWriteLock()); INodesInPath inodesInPath = fsd.GetINodesInPath4Write(src, true); INode inode = inodesInPath.GetLastINode(); if (inode == null) { throw new FileNotFoundException("File does not exist: " + src); } int snapshotId = inodesInPath.GetLatestSnapshotId(); inode.SetPermission(permissions, snapshotId); }
internal static void AssertSnapshot(INodesInPath inodesInPath, bool isSnapshot, Org.Apache.Hadoop.Hdfs.Server.Namenode.Snapshot.Snapshot snapshot, int index) { NUnit.Framework.Assert.AreEqual(isSnapshot, inodesInPath.IsSnapshot()); NUnit.Framework.Assert.AreEqual(Org.Apache.Hadoop.Hdfs.Server.Namenode.Snapshot.Snapshot .GetSnapshotId(isSnapshot ? snapshot : null), inodesInPath.GetPathSnapshotId()); if (!isSnapshot) { NUnit.Framework.Assert.AreEqual(Org.Apache.Hadoop.Hdfs.Server.Namenode.Snapshot.Snapshot .GetSnapshotId(snapshot), inodesInPath.GetLatestSnapshotId()); } if (isSnapshot && index >= 0) { NUnit.Framework.Assert.AreEqual(typeof(Snapshot.Root), inodesInPath.GetINode(index ).GetType()); } }
/// <exception cref="System.IO.IOException"/> internal static void UnprotectedSetStoragePolicy(FSDirectory fsd, BlockManager bm , INodesInPath iip, byte policyId) { System.Diagnostics.Debug.Assert(fsd.HasWriteLock()); INode inode = iip.GetLastINode(); if (inode == null) { throw new FileNotFoundException("File/Directory does not exist: " + iip.GetPath() ); } int snapshotId = iip.GetLatestSnapshotId(); if (inode.IsFile()) { BlockStoragePolicy newPolicy = bm.GetStoragePolicy(policyId); if (newPolicy.IsCopyOnCreateFile()) { throw new HadoopIllegalArgumentException("Policy " + newPolicy + " cannot be set after file creation." ); } BlockStoragePolicy currentPolicy = bm.GetStoragePolicy(inode.GetLocalStoragePolicyID ()); if (currentPolicy != null && currentPolicy.IsCopyOnCreateFile()) { throw new HadoopIllegalArgumentException("Existing policy " + currentPolicy.GetName () + " cannot be changed after file creation."); } inode.AsFile().SetStoragePolicyID(policyId, snapshotId); } else { if (inode.IsDirectory()) { SetDirStoragePolicy(fsd, inode.AsDirectory(), policyId, snapshotId); } else { throw new FileNotFoundException(iip.GetPath() + " is not a file or directory"); } } }
/// <exception cref="System.IO.IOException"/> internal static IList <XAttr> UnprotectedRemoveXAttrs(FSDirectory fsd, string src, IList <XAttr> toRemove) { System.Diagnostics.Debug.Assert(fsd.HasWriteLock()); INodesInPath iip = fsd.GetINodesInPath4Write(FSDirectory.NormalizePath(src), true ); INode inode = FSDirectory.ResolveLastINode(iip); int snapshotId = iip.GetLatestSnapshotId(); IList <XAttr> existingXAttrs = XAttrStorage.ReadINodeXAttrs(inode); IList <XAttr> removedXAttrs = Lists.NewArrayListWithCapacity(toRemove.Count); IList <XAttr> newXAttrs = FilterINodeXAttrs(existingXAttrs, toRemove, removedXAttrs ); if (existingXAttrs.Count != newXAttrs.Count) { XAttrStorage.UpdateINodeXAttrs(inode, newXAttrs, snapshotId); return(removedXAttrs); } return(null); }
/// <exception cref="Org.Apache.Hadoop.Hdfs.Protocol.QuotaExceededException"/> /// <exception cref="Org.Apache.Hadoop.FS.UnresolvedLinkException"/> /// <exception cref="Org.Apache.Hadoop.Hdfs.Protocol.SnapshotAccessControlException"/ /// > internal static Block[] UnprotectedSetReplication(FSDirectory fsd, string src, short replication, short[] blockRepls) { System.Diagnostics.Debug.Assert(fsd.HasWriteLock()); INodesInPath iip = fsd.GetINodesInPath4Write(src, true); INode inode = iip.GetLastINode(); if (inode == null || !inode.IsFile()) { return(null); } INodeFile file = inode.AsFile(); short oldBR = file.GetBlockReplication(); // before setFileReplication, check for increasing block replication. // if replication > oldBR, then newBR == replication. // if replication < oldBR, we don't know newBR yet. if (replication > oldBR) { long dsDelta = file.StoragespaceConsumed() / oldBR; fsd.UpdateCount(iip, 0L, dsDelta, oldBR, replication, true); } file.SetFileReplication(replication, iip.GetLatestSnapshotId()); short newBR = file.GetBlockReplication(); // check newBR < oldBR case. if (newBR < oldBR) { long dsDelta = file.StoragespaceConsumed() / newBR; fsd.UpdateCount(iip, 0L, dsDelta, oldBR, newBR, true); } if (blockRepls != null) { blockRepls[0] = oldBR; blockRepls[1] = newBR; } return(file.GetBlocks()); }
/// <exception cref="System.Exception"/> private void TestTruncate(long newLength, long expectedDiff, long expectedUsage) { // before doing the real truncation, make sure the computation is correct INodesInPath iip = fsdir.GetINodesInPath4Write(file.ToString()); INodeFile fileNode = iip.GetLastINode().AsFile(); fileNode.RecordModification(iip.GetLatestSnapshotId(), true); long diff = fileNode.ComputeQuotaDeltaForTruncate(newLength); NUnit.Framework.Assert.AreEqual(expectedDiff, diff); // do the real truncation dfs.Truncate(file, newLength); // wait for truncate to finish TestFileTruncate.CheckBlockRecovery(file, dfs); INodeDirectory dirNode = fsdir.GetINode4Write(dir.ToString()).AsDirectory(); long spaceUsed = dirNode.GetDirectoryWithQuotaFeature().GetSpaceConsumed().GetStorageSpace (); long diskUsed = dirNode.GetDirectoryWithQuotaFeature().GetSpaceConsumed().GetTypeSpaces ().Get(StorageType.Disk); NUnit.Framework.Assert.AreEqual(expectedUsage, spaceUsed); NUnit.Framework.Assert.AreEqual(expectedUsage, diskUsed); }
/// <exception cref="System.IO.IOException"/> internal static INode UnprotectedSetXAttrs(FSDirectory fsd, string src, IList <XAttr > xAttrs, EnumSet <XAttrSetFlag> flag) { System.Diagnostics.Debug.Assert(fsd.HasWriteLock()); INodesInPath iip = fsd.GetINodesInPath4Write(FSDirectory.NormalizePath(src), true ); INode inode = FSDirectory.ResolveLastINode(iip); int snapshotId = iip.GetLatestSnapshotId(); IList <XAttr> existingXAttrs = XAttrStorage.ReadINodeXAttrs(inode); IList <XAttr> newXAttrs = SetINodeXAttrs(fsd, existingXAttrs, xAttrs, flag); bool isFile = inode.IsFile(); foreach (XAttr xattr in newXAttrs) { string xaName = XAttrHelper.GetPrefixName(xattr); /* * If we're adding the encryption zone xattr, then add src to the list * of encryption zones. */ if (HdfsServerConstants.CryptoXattrEncryptionZone.Equals(xaName)) { HdfsProtos.ZoneEncryptionInfoProto ezProto = HdfsProtos.ZoneEncryptionInfoProto.ParseFrom (xattr.GetValue()); fsd.ezManager.AddEncryptionZone(inode.GetId(), PBHelper.Convert(ezProto.GetSuite( )), PBHelper.Convert(ezProto.GetCryptoProtocolVersion()), ezProto.GetKeyName()); } if (!isFile && HdfsServerConstants.SecurityXattrUnreadableBySuperuser.Equals(xaName )) { throw new IOException("Can only set '" + HdfsServerConstants.SecurityXattrUnreadableBySuperuser + "' on a file."); } } XAttrStorage.UpdateINodeXAttrs(inode, newXAttrs, snapshotId); return(inode); }
/// <summary> /// See /// <see cref="Org.Apache.Hadoop.Hdfs.Protocol.ClientProtocol.SetQuota(string, long, long, Org.Apache.Hadoop.FS.StorageType) /// "/> /// for the contract. /// Sets quota for for a directory. /// </summary> /// <returns>INodeDirectory if any of the quotas have changed. null otherwise.</returns> /// <exception cref="System.IO.FileNotFoundException">if the path does not exist.</exception> /// <exception cref="Org.Apache.Hadoop.FS.PathIsNotDirectoryException">if the path is not a directory. /// </exception> /// <exception cref="Org.Apache.Hadoop.Hdfs.Protocol.QuotaExceededException"> /// if the directory tree size is /// greater than the given quota /// </exception> /// <exception cref="Org.Apache.Hadoop.FS.UnresolvedLinkException">if a symlink is encountered in src. /// </exception> /// <exception cref="Org.Apache.Hadoop.Hdfs.Protocol.SnapshotAccessControlException">if path is in RO snapshot /// </exception> /// <exception cref="Org.Apache.Hadoop.Hdfs.Server.Namenode.UnsupportedActionException /// "/> internal static INodeDirectory UnprotectedSetQuota(FSDirectory fsd, string src, long nsQuota, long ssQuota, StorageType type) { System.Diagnostics.Debug.Assert(fsd.HasWriteLock()); // sanity check if ((nsQuota < 0 && nsQuota != HdfsConstants.QuotaDontSet && nsQuota != HdfsConstants .QuotaReset) || (ssQuota < 0 && ssQuota != HdfsConstants.QuotaDontSet && ssQuota != HdfsConstants.QuotaReset)) { throw new ArgumentException("Illegal value for nsQuota or " + "ssQuota : " + nsQuota + " and " + ssQuota); } // sanity check for quota by storage type if ((type != null) && (!fsd.IsQuotaByStorageTypeEnabled() || nsQuota != HdfsConstants .QuotaDontSet)) { throw new UnsupportedActionException("Failed to set quota by storage type because either" + DFSConfigKeys.DfsQuotaByStoragetypeEnabledKey + " is set to " + fsd.IsQuotaByStorageTypeEnabled () + " or nsQuota value is illegal " + nsQuota); } string srcs = FSDirectory.NormalizePath(src); INodesInPath iip = fsd.GetINodesInPath4Write(srcs, true); INodeDirectory dirNode = INodeDirectory.ValueOf(iip.GetLastINode(), srcs); if (dirNode.IsRoot() && nsQuota == HdfsConstants.QuotaReset) { throw new ArgumentException("Cannot clear namespace quota on root."); } else { // a directory inode QuotaCounts oldQuota = dirNode.GetQuotaCounts(); long oldNsQuota = oldQuota.GetNameSpace(); long oldSsQuota = oldQuota.GetStorageSpace(); if (nsQuota == HdfsConstants.QuotaDontSet) { nsQuota = oldNsQuota; } if (ssQuota == HdfsConstants.QuotaDontSet) { ssQuota = oldSsQuota; } // unchanged space/namespace quota if (type == null && oldNsQuota == nsQuota && oldSsQuota == ssQuota) { return(null); } // unchanged type quota if (type != null) { EnumCounters <StorageType> oldTypeQuotas = oldQuota.GetTypeSpaces(); if (oldTypeQuotas != null && oldTypeQuotas.Get(type) == ssQuota) { return(null); } } int latest = iip.GetLatestSnapshotId(); dirNode.RecordModification(latest); dirNode.SetQuota(fsd.GetBlockStoragePolicySuite(), nsQuota, ssQuota, type); return(dirNode); } }
/// <exception cref="System.IO.IOException"/> private static INodeFile[] VerifySrcFiles(FSDirectory fsd, string[] srcs, INodesInPath targetIIP, FSPermissionChecker pc) { // to make sure no two files are the same ICollection <INodeFile> si = new LinkedHashSet <INodeFile>(); INodeFile targetINode = targetIIP.GetLastINode().AsFile(); INodeDirectory targetParent = targetINode.GetParent(); // now check the srcs foreach (string src in srcs) { INodesInPath iip = fsd.GetINodesInPath4Write(src); // permission check for srcs if (pc != null) { fsd.CheckPathAccess(pc, iip, FsAction.Read); // read the file fsd.CheckParentAccess(pc, iip, FsAction.Write); } // for delete INode srcINode = iip.GetLastINode(); INodeFile srcINodeFile = INodeFile.ValueOf(srcINode, src); // make sure the src file and the target file are in the same dir if (srcINodeFile.GetParent() != targetParent) { throw new HadoopIllegalArgumentException("Source file " + src + " is not in the same directory with the target " + targetIIP.GetPath()); } // make sure all the source files are not in snapshot if (srcINode.IsInLatestSnapshot(iip.GetLatestSnapshotId())) { throw new SnapshotException("Concat: the source file " + src + " is in snapshot"); } // check if the file has other references. if (srcINode.IsReference() && ((INodeReference.WithCount)srcINode.AsReference().GetReferredINode ()).GetReferenceCount() > 1) { throw new SnapshotException("Concat: the source file " + src + " is referred by some other reference in some snapshot." ); } // source file cannot be the same with the target file if (srcINode == targetINode) { throw new HadoopIllegalArgumentException("concat: the src file " + src + " is the same with the target file " + targetIIP.GetPath()); } // source file cannot be under construction or empty if (srcINodeFile.IsUnderConstruction() || srcINodeFile.NumBlocks() == 0) { throw new HadoopIllegalArgumentException("concat: source file " + src + " is invalid or empty or underConstruction" ); } // source file's preferred block size cannot be greater than the target // file if (srcINodeFile.GetPreferredBlockSize() > targetINode.GetPreferredBlockSize()) { throw new HadoopIllegalArgumentException("concat: source file " + src + " has preferred block size " + srcINodeFile.GetPreferredBlockSize() + " which is greater than the target file's preferred block size " + targetINode.GetPreferredBlockSize()); } si.AddItem(srcINodeFile); } // make sure no two files are the same if (si.Count < srcs.Length) { // it means at least two files are the same throw new HadoopIllegalArgumentException("concat: at least two of the source files are the same" ); } return(Sharpen.Collections.ToArray(si, new INodeFile[si.Count])); }