/// <summary> /// For a given absolute path, create all ancestors as directories along the /// path. /// </summary> /// <remarks> /// For a given absolute path, create all ancestors as directories along the /// path. All ancestors inherit their parent's permission plus an implicit /// u+wx permission. This is used by create() and addSymlink() for /// implicitly creating all directories along the path. /// For example, path="/foo/bar/spam", "/foo" is an existing directory, /// "/foo/bar" is not existing yet, the function will create directory bar. /// </remarks> /// <returns> /// a tuple which contains both the new INodesInPath (with all the /// existing and newly created directories) and the last component in the /// relative path. Or return null if there are errors. /// </returns> /// <exception cref="System.IO.IOException"/> internal static KeyValuePair <INodesInPath, string> CreateAncestorDirectories(FSDirectory fsd, INodesInPath iip, PermissionStatus permission) { string last = new string(iip.GetLastLocalName(), Charsets.Utf8); INodesInPath existing = iip.GetExistingINodes(); IList <string> children = iip.GetPath(existing.Length(), iip.Length() - existing.Length ()); int size = children.Count; if (size > 1) { // otherwise all ancestors have been created IList <string> directories = children.SubList(0, size - 1); INode parentINode = existing.GetLastINode(); // Ensure that the user can traversal the path by adding implicit // u+wx permission to all ancestor directories existing = CreateChildrenDirectories(fsd, existing, directories, AddImplicitUwx(parentINode .GetPermissionStatus(), permission)); if (existing == null) { return(null); } } return(new AbstractMap.SimpleImmutableEntry <INodesInPath, string>(existing, last)); }
/// <summary>Add the given symbolic link to the fs.</summary> /// <remarks>Add the given symbolic link to the fs. Record it in the edits log.</remarks> /// <exception cref="System.IO.IOException"/> private static INodeSymlink AddSymlink(FSDirectory fsd, string path, INodesInPath iip, string target, PermissionStatus dirPerms, bool createParent, bool logRetryCache ) { long mtime = Time.Now(); byte[] localName = iip.GetLastLocalName(); if (createParent) { KeyValuePair <INodesInPath, string> e = FSDirMkdirOp.CreateAncestorDirectories(fsd , iip, dirPerms); if (e == null) { return(null); } iip = INodesInPath.Append(e.Key, null, localName); } string userName = dirPerms.GetUserName(); long id = fsd.AllocateNewInodeId(); PermissionStatus perm = new PermissionStatus(userName, null, FsPermission.GetDefault ()); INodeSymlink newNode = UnprotectedAddSymlink(fsd, iip.GetExistingINodes(), localName , id, target, mtime, mtime, perm); if (newNode == null) { NameNode.stateChangeLog.Info("addSymlink: failed to add " + path); return(null); } fsd.GetEditLog().LogSymlink(path, target, mtime, mtime, newNode, logRetryCache); if (NameNode.stateChangeLog.IsDebugEnabled()) { NameNode.stateChangeLog.Debug("addSymlink: " + path + " is added"); } return(newNode); }
/// <exception cref="System.IO.IOException"/> internal static HdfsFileStatus Mkdirs(FSNamesystem fsn, string src, PermissionStatus permissions, bool createParent) { FSDirectory fsd = fsn.GetFSDirectory(); if (NameNode.stateChangeLog.IsDebugEnabled()) { NameNode.stateChangeLog.Debug("DIR* NameSystem.mkdirs: " + src); } if (!DFSUtil.IsValidName(src)) { throw new InvalidPathException(src); } FSPermissionChecker pc = fsd.GetPermissionChecker(); byte[][] pathComponents = FSDirectory.GetPathComponentsForReservedPath(src); fsd.WriteLock(); try { src = fsd.ResolvePath(pc, src, pathComponents); INodesInPath iip = fsd.GetINodesInPath4Write(src); if (fsd.IsPermissionEnabled()) { fsd.CheckTraverse(pc, iip); } INode lastINode = iip.GetLastINode(); if (lastINode != null && lastINode.IsFile()) { throw new FileAlreadyExistsException("Path is not a directory: " + src); } INodesInPath existing = lastINode != null ? iip : iip.GetExistingINodes(); if (lastINode == null) { if (fsd.IsPermissionEnabled()) { fsd.CheckAncestorAccess(pc, iip, FsAction.Write); } if (!createParent) { fsd.VerifyParentDir(iip, src); } // validate that we have enough inodes. This is, at best, a // heuristic because the mkdirs() operation might need to // create multiple inodes. fsn.CheckFsObjectLimit(); IList <string> nonExisting = iip.GetPath(existing.Length(), iip.Length() - existing .Length()); int length = nonExisting.Count; if (length > 1) { IList <string> ancestors = nonExisting.SubList(0, length - 1); // Ensure that the user can traversal the path by adding implicit // u+wx permission to all ancestor directories existing = CreateChildrenDirectories(fsd, existing, ancestors, AddImplicitUwx(permissions , permissions)); if (existing == null) { throw new IOException("Failed to create directory: " + src); } } if ((existing = CreateChildrenDirectories(fsd, existing, nonExisting.SubList(length - 1, length), permissions)) == null) { throw new IOException("Failed to create directory: " + src); } } return(fsd.GetAuditFileInfo(existing)); } finally { fsd.WriteUnlock(); } }