示例#1
0
            /// <exception cref="System.IO.IOException"/>
            private INodeReference LoadINodeReference(FsImageProto.INodeReferenceSection.INodeReference
                                                      r)
            {
                long  referredId = r.GetReferredId();
                INode referred   = fsDir.GetInode(referredId);

                INodeReference.WithCount withCount = (INodeReference.WithCount)referred.GetParentReference
                                                         ();
                if (withCount == null)
                {
                    withCount = new INodeReference.WithCount(null, referred);
                }
                INodeReference @ref;

                if (r.HasDstSnapshotId())
                {
                    // DstReference
                    @ref = new INodeReference.DstReference(null, withCount, r.GetDstSnapshotId());
                }
                else
                {
                    @ref = new INodeReference.WithName(null, withCount, r.GetName().ToByteArray(), r.
                                                       GetLastSnapshotId());
                }
                return(@ref);
            }
示例#2
0
        /// <summary>We just found a deleted WithName node as the source of a rename operation.
        ///     </summary>
        /// <remarks>
        /// We just found a deleted WithName node as the source of a rename operation.
        /// However, we should include it in our snapshot diff report as rename only
        /// if the rename target is also under the same snapshottable directory.
        /// </remarks>
        private byte[][] FindRenameTargetPath(INodeDirectory snapshotRoot, INodeReference.WithName
                                              wn, int snapshotId)
        {
            INode         inode     = wn.GetReferredINode();
            List <byte[]> ancestors = Lists.NewLinkedList();

            while (inode != null)
            {
                if (inode == snapshotRoot)
                {
                    return(Sharpen.Collections.ToArray(ancestors, new byte[ancestors.Count][]));
                }
                if (inode is INodeReference.WithCount)
                {
                    inode = ((INodeReference.WithCount)inode).GetParentRef(snapshotId);
                }
                else
                {
                    INode parent = inode.GetParentReference() != null?inode.GetParentReference() :
                                       inode.GetParent();

                    if (parent != null && parent is INodeDirectory)
                    {
                        int sid = parent.AsDirectory().SearchChild(inode);
                        if (sid < snapshotId)
                        {
                            return(null);
                        }
                    }
                    if (!(parent is INodeReference.WithCount))
                    {
                        ancestors.AddFirst(inode.GetLocalNameBytes());
                    }
                    inode = parent;
                }
            }
            return(null);
        }
示例#3
0
        /// <summary>
        /// Clean an inode while we move it from the deleted list of post to the
        /// deleted list of prior.
        /// </summary>
        /// <param name="bsps">The block storage policy suite.</param>
        /// <param name="inode">The inode to clean.</param>
        /// <param name="post">The post snapshot.</param>
        /// <param name="prior">The id of the prior snapshot.</param>
        /// <param name="collectedBlocks">Used to collect blocks for later deletion.</param>
        /// <returns>Quota usage update.</returns>
        private static QuotaCounts CleanDeletedINode(BlockStoragePolicySuite bsps, INode
                                                     inode, int post, int prior, INode.BlocksMapUpdateInfo collectedBlocks, IList <INode
                                                                                                                                   > removedINodes)
        {
            QuotaCounts   counts = new QuotaCounts.Builder().Build();
            Deque <INode> queue  = new ArrayDeque <INode>();

            queue.AddLast(inode);
            while (!queue.IsEmpty())
            {
                INode topNode = queue.PollFirst();
                if (topNode is INodeReference.WithName)
                {
                    INodeReference.WithName wn = (INodeReference.WithName)topNode;
                    if (wn.GetLastSnapshotId() >= post)
                    {
                        wn.CleanSubtree(bsps, post, prior, collectedBlocks, removedINodes);
                    }
                }
                else
                {
                    // For DstReference node, since the node is not in the created list of
                    // prior, we should treat it as regular file/dir
                    if (topNode.IsFile() && topNode.AsFile().IsWithSnapshot())
                    {
                        INodeFile file = topNode.AsFile();
                        counts.Add(file.GetDiffs().DeleteSnapshotDiff(bsps, post, prior, file, collectedBlocks
                                                                      , removedINodes));
                    }
                    else
                    {
                        if (topNode.IsDirectory())
                        {
                            INodeDirectory dir = topNode.AsDirectory();
                            DirectoryWithSnapshotFeature.ChildrenDiff priorChildrenDiff = null;
                            DirectoryWithSnapshotFeature sf = dir.GetDirectoryWithSnapshotFeature();
                            if (sf != null)
                            {
                                // delete files/dirs created after prior. Note that these
                                // files/dirs, along with inode, were deleted right after post.
                                DirectoryWithSnapshotFeature.DirectoryDiff priorDiff = sf.GetDiffs().GetDiffById(
                                    prior);
                                if (priorDiff != null && priorDiff.GetSnapshotId() == prior)
                                {
                                    priorChildrenDiff = priorDiff.GetChildrenDiff();
                                    counts.Add(priorChildrenDiff.DestroyCreatedList(bsps, dir, collectedBlocks, removedINodes
                                                                                    ));
                                }
                            }
                            foreach (INode child in dir.GetChildrenList(prior))
                            {
                                if (priorChildrenDiff != null && priorChildrenDiff.Search(Diff.ListType.Deleted,
                                                                                          child.GetLocalNameBytes()) != null)
                                {
                                    continue;
                                }
                                queue.AddLast(child);
                            }
                        }
                    }
                }
            }
            return(counts);
        }