internal static Org.Apache.Hadoop.Hdfs.Server.Namenode.INodesInPath FromINode(INode inode) { int depth = 0; int index; INode tmp = inode; while (tmp != null) { depth++; tmp = tmp.GetParent(); } byte[][] path = new byte[depth][]; INode[] inodes = new INode[depth]; tmp = inode; index = depth; while (tmp != null) { index--; path[index] = tmp.GetKey(); inodes[index] = tmp; tmp = tmp.GetParent(); } return(new Org.Apache.Hadoop.Hdfs.Server.Namenode.INodesInPath(inodes, path)); }
/// <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>for snapshot file.</summary> /// <exception cref="System.Exception"/> public virtual void TestSnapshotPathINodes() { // Create a snapshot for the dir, and check the inodes for the path // pointing to a snapshot file hdfs.AllowSnapshot(sub1); hdfs.CreateSnapshot(sub1, "s1"); // The path when accessing the snapshot file of file1 is // /TestSnapshot/sub1/.snapshot/s1/file1 string snapshotPath = sub1.ToString() + "/.snapshot/s1/file1"; string[] names = INode.GetPathNames(snapshotPath); byte[][] components = INode.GetPathComponents(names); INodesInPath nodesInPath = INodesInPath.Resolve(fsdir.rootDir, components, false); // Length of inodes should be (components.length - 1), since we will ignore // ".snapshot" NUnit.Framework.Assert.AreEqual(nodesInPath.Length(), components.Length - 1); // SnapshotRootIndex should be 3: {root, Testsnapshot, sub1, s1, file1} Org.Apache.Hadoop.Hdfs.Server.Namenode.Snapshot.Snapshot snapshot = GetSnapshot(nodesInPath , "s1", 3); AssertSnapshot(nodesInPath, true, snapshot, 3); // Check the INode for file1 (snapshot file) INode snapshotFileNode = nodesInPath.GetLastINode(); AssertINodeFile(snapshotFileNode, file1); NUnit.Framework.Assert.IsTrue(snapshotFileNode.GetParent().IsWithSnapshot()); // Call getExistingPathINodes and request only one INode. nodesInPath = INodesInPath.Resolve(fsdir.rootDir, components, false); NUnit.Framework.Assert.AreEqual(nodesInPath.Length(), components.Length - 1); AssertSnapshot(nodesInPath, true, snapshot, 3); // Check the INode for file1 (snapshot file) AssertINodeFile(nodesInPath.GetLastINode(), file1); // Resolve the path "/TestSnapshot/sub1/.snapshot" string dotSnapshotPath = sub1.ToString() + "/.snapshot"; names = INode.GetPathNames(dotSnapshotPath); components = INode.GetPathComponents(names); nodesInPath = INodesInPath.Resolve(fsdir.rootDir, components, false); // The number of INodes returned should still be components.length // since we put a null in the inode array for ".snapshot" NUnit.Framework.Assert.AreEqual(nodesInPath.Length(), components.Length); // No SnapshotRoot dir is included in the resolved inodes AssertSnapshot(nodesInPath, true, snapshot, -1); // The last INode should be null, the last but 1 should be sub1 NUnit.Framework.Assert.IsNull(nodesInPath.GetLastINode()); NUnit.Framework.Assert.AreEqual(nodesInPath.GetINode(-2).GetFullPathName(), sub1. ToString()); NUnit.Framework.Assert.IsTrue(nodesInPath.GetINode(-2).IsDirectory()); string[] invalidPathComponent = new string[] { "invalidDir", "foo", ".snapshot", "bar" }; Path invalidPath = new Path(invalidPathComponent[0]); for (int i = 1; i < invalidPathComponent.Length; i++) { invalidPath = new Path(invalidPath, invalidPathComponent[i]); try { hdfs.GetFileStatus(invalidPath); NUnit.Framework.Assert.Fail(); } catch (FileNotFoundException fnfe) { System.Console.Out.WriteLine("The exception is expected: " + fnfe); } } hdfs.DeleteSnapshot(sub1, "s1"); hdfs.DisallowSnapshot(sub1); }
/// <summary> /// If a default ACL is defined on a parent directory, then copies that default /// ACL to a newly created child file or directory. /// </summary> /// <param name="child">INode newly created child</param> public static void CopyINodeDefaultAcl(INode child) { INodeDirectory parent = child.GetParent(); AclFeature parentAclFeature = parent.GetAclFeature(); if (parentAclFeature == null || !(child.IsFile() || child.IsDirectory())) { return; } // Split parent's entries into access vs. default. IList <AclEntry> featureEntries = GetEntriesFromAclFeature(parent.GetAclFeature()); ScopedAclEntries scopedEntries = new ScopedAclEntries(featureEntries); IList <AclEntry> parentDefaultEntries = scopedEntries.GetDefaultEntries(); // The parent may have an access ACL but no default ACL. If so, exit. if (parentDefaultEntries.IsEmpty()) { return; } // Pre-allocate list size for access entries to copy from parent. IList <AclEntry> accessEntries = Lists.NewArrayListWithCapacity(parentDefaultEntries .Count); FsPermission childPerm = child.GetFsPermission(); // Copy each default ACL entry from parent to new child's access ACL. bool parentDefaultIsMinimal = AclUtil.IsMinimalAcl(parentDefaultEntries); foreach (AclEntry entry in parentDefaultEntries) { AclEntryType type = entry.GetType(); string name = entry.GetName(); AclEntry.Builder builder = new AclEntry.Builder().SetScope(AclEntryScope.Access). SetType(type).SetName(name); // The child's initial permission bits are treated as the mode parameter, // which can filter copied permission values for owner, mask and other. FsAction permission; if (type == AclEntryType.User && name == null) { permission = entry.GetPermission().And(childPerm.GetUserAction()); } else { if (type == AclEntryType.Group && parentDefaultIsMinimal) { // This only happens if the default ACL is a minimal ACL: exactly 3 // entries corresponding to owner, group and other. In this case, // filter the group permissions. permission = entry.GetPermission().And(childPerm.GetGroupAction()); } else { if (type == AclEntryType.Mask) { // Group bits from mode parameter filter permission of mask entry. permission = entry.GetPermission().And(childPerm.GetGroupAction()); } else { if (type == AclEntryType.Other) { permission = entry.GetPermission().And(childPerm.GetOtherAction()); } else { permission = entry.GetPermission(); } } } } builder.SetPermission(permission); accessEntries.AddItem(builder.Build()); } // A new directory also receives a copy of the parent's default ACL. IList <AclEntry> defaultEntries = child.IsDirectory() ? parentDefaultEntries : Sharpen.Collections .EmptyList <AclEntry>(); FsPermission newPerm; if (!AclUtil.IsMinimalAcl(accessEntries) || !defaultEntries.IsEmpty()) { // Save the new ACL to the child. child.AddAclFeature(CreateAclFeature(accessEntries, defaultEntries)); newPerm = CreateFsPermissionForExtendedAcl(accessEntries, childPerm); } else { // The child is receiving a minimal ACL. newPerm = CreateFsPermissionForMinimalAcl(accessEntries, childPerm); } child.SetPermission(newPerm); }