boolean changedBetweenSnapshots(INodeFile file, Snapshot from, Snapshot to) { int[] diffIndexPair = diffs.changedBetweenSnapshots(from, to); if (diffIndexPair == null) { return false; } int earlierDiffIndex = diffIndexPair[0]; int laterDiffIndex = diffIndexPair[1]; final List<FileDiff> diffList = diffs.asList(); final long earlierLength = diffList.get(earlierDiffIndex).getFileSize(); final long laterLength = laterDiffIndex == diffList.size() ? file.computeFileSize(true, false) : diffList.get(laterDiffIndex).getFileSize(); if (earlierLength != laterLength) { // file length has been changed return true; } INodeFileAttributes earlierAttr = null; // check the metadata for (int i = earlierDiffIndex; i < laterDiffIndex; i++) { FileDiff diff = diffList.get(i); if (diff.snapshotINode != null) { earlierAttr = diff.snapshotINode; break; } } if (earlierAttr == null) { // no meta-change at all, return false return false; } INodeFileAttributes laterAttr = diffs.getSnapshotINode( Math.max(Snapshot.getSnapshotId(from), Snapshot.getSnapshotId(to)), file); return !earlierAttr.metadataEquals(laterAttr); }
/** Load FileDiff list for a file with snapshot feature */ private void loadFileDiffList(InputStream in, INodeFile file, int size) throws IOException { final FileDiffList diffs = new FileDiffList(); final LoaderContext state = parent.getLoaderContext(); for (int i = 0; i < size; i++) { SnapshotDiffSection.FileDiff pbf = SnapshotDiffSection.FileDiff.parseDelimitedFrom(in); INodeFileAttributes copy = null; if (pbf.hasSnapshotCopy()) { INodeSection.INodeFile fileInPb = pbf.getSnapshotCopy(); PermissionStatus permission = loadPermission(fileInPb.getPermission(), state.getStringTable()); AclFeature acl = null; if (fileInPb.hasAcl()) { acl = new AclFeature( FSImageFormatPBINode.Loader.loadAclEntries( fileInPb.getAcl(), state.getStringTable())); } copy = new INodeFileAttributes.SnapshotCopy( pbf.getName().toByteArray(), permission, acl, fileInPb.getModificationTime(), fileInPb.getAccessTime(), (short) fileInPb.getReplication(), fileInPb.getPreferredBlockSize()); } FileDiff diff = new FileDiff(pbf.getSnapshotId(), copy, null, pbf.getFileSize()); diffs.addFirst(diff); } file.addSnapshotFeature(diffs); }
public Quota.Counts cleanFile( final INodeFile file, final int snapshotId, int priorSnapshotId, final BlocksMapUpdateInfo collectedBlocks, final List<INode> removedINodes, final boolean countDiffChange) throws QuotaExceededException { if (snapshotId == Snapshot.CURRENT_STATE_ID) { // delete the current file while the file has snapshot feature if (!isCurrentFileDeleted()) { file.recordModification(priorSnapshotId); deleteCurrentFile(); } collectBlocksAndClear(file, collectedBlocks, removedINodes); return Quota.Counts.newInstance(); } else { // delete the snapshot priorSnapshotId = getDiffs().updatePrior(snapshotId, priorSnapshotId); return diffs.deleteSnapshotDiff( snapshotId, priorSnapshotId, file, collectedBlocks, removedINodes, countDiffChange); } }