HDFS-4078. Handle replication in snapshots.
git-svn-id: https://svn.apache.org/repos/asf/hadoop/common/branches/HDFS-2802@1400743 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
f29724956a
commit
9a0651b4b8
|
@ -18,3 +18,5 @@ Branch-2802 Snapshot (Unreleased)
|
||||||
HDFS-4079. Add SnapshotManager which maintains a list for all the
|
HDFS-4079. Add SnapshotManager which maintains a list for all the
|
||||||
snapshottable directories and supports snapshot methods such as setting a
|
snapshottable directories and supports snapshot methods such as setting a
|
||||||
directory to snapshottable and creating a snapshot. (szetszwo)
|
directory to snapshottable and creating a snapshot. (szetszwo)
|
||||||
|
|
||||||
|
HDFS-4078. Handle replication in snapshots. (szetszwo)
|
||||||
|
|
|
@ -315,9 +315,19 @@ public class FSDirectory implements Closeable {
|
||||||
//add destination snaplink
|
//add destination snaplink
|
||||||
snapshot = addNode(dstPath, snapshot, UNKNOWN_DISK_SPACE);
|
snapshot = addNode(dstPath, snapshot, UNKNOWN_DISK_SPACE);
|
||||||
|
|
||||||
if (snapshot != null && src.getClass() == INodeFile.class) {
|
final INodeFileWithLink srcWithLink;
|
||||||
//created a snapshot and the source is an INodeFile, replace the source.
|
if (snapshot != null) {
|
||||||
replaceNode(srcPath, src, new INodeFileWithLink(src));
|
//added snapshot node successfully, check source type,
|
||||||
|
if (src instanceof INodeFileWithLink) {
|
||||||
|
srcWithLink = (INodeFileWithLink)src;
|
||||||
|
} else {
|
||||||
|
//source is an INodeFile, replace the source.
|
||||||
|
srcWithLink = new INodeFileWithLink(src);
|
||||||
|
replaceNode(srcPath, src, srcWithLink);
|
||||||
|
}
|
||||||
|
|
||||||
|
//insert the snapshot to src's linked list.
|
||||||
|
srcWithLink.insert(snapshot);
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
writeUnlock();
|
writeUnlock();
|
||||||
|
@ -384,13 +394,13 @@ public class FSDirectory implements Closeable {
|
||||||
|
|
||||||
// check quota limits and updated space consumed
|
// check quota limits and updated space consumed
|
||||||
updateCount(inodes, inodes.length-1, 0,
|
updateCount(inodes, inodes.length-1, 0,
|
||||||
fileINode.getPreferredBlockSize()*fileINode.getBlockReplication(), true);
|
fileINode.getPreferredBlockSize()*fileINode.getFileReplication(), true);
|
||||||
|
|
||||||
// associate new last block for the file
|
// associate new last block for the file
|
||||||
BlockInfoUnderConstruction blockInfo =
|
BlockInfoUnderConstruction blockInfo =
|
||||||
new BlockInfoUnderConstruction(
|
new BlockInfoUnderConstruction(
|
||||||
block,
|
block,
|
||||||
fileINode.getBlockReplication(),
|
fileINode.getFileReplication(),
|
||||||
BlockUCState.UNDER_CONSTRUCTION,
|
BlockUCState.UNDER_CONSTRUCTION,
|
||||||
targets);
|
targets);
|
||||||
getBlockManager().addBlockCollection(blockInfo, fileINode);
|
getBlockManager().addBlockCollection(blockInfo, fileINode);
|
||||||
|
@ -481,7 +491,7 @@ public class FSDirectory implements Closeable {
|
||||||
// update space consumed
|
// update space consumed
|
||||||
INode[] pathINodes = getExistingPathINodes(path);
|
INode[] pathINodes = getExistingPathINodes(path);
|
||||||
updateCount(pathINodes, pathINodes.length-1, 0,
|
updateCount(pathINodes, pathINodes.length-1, 0,
|
||||||
-fileNode.getPreferredBlockSize()*fileNode.getBlockReplication(), true);
|
-fileNode.getPreferredBlockSize()*fileNode.getFileReplication(), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -860,13 +870,13 @@ public class FSDirectory implements Closeable {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
INodeFile fileNode = (INodeFile)inode;
|
INodeFile fileNode = (INodeFile)inode;
|
||||||
final short oldRepl = fileNode.getBlockReplication();
|
final short oldRepl = fileNode.getFileReplication();
|
||||||
|
|
||||||
// check disk quota
|
// check disk quota
|
||||||
long dsDelta = (replication - oldRepl) * (fileNode.diskspaceConsumed()/oldRepl);
|
long dsDelta = (replication - oldRepl) * (fileNode.diskspaceConsumed()/oldRepl);
|
||||||
updateCount(inodes, inodes.length-1, 0, dsDelta, true);
|
updateCount(inodes, inodes.length-1, 0, dsDelta, true);
|
||||||
|
|
||||||
fileNode.setReplication(replication);
|
fileNode.setFileReplication(replication);
|
||||||
|
|
||||||
if (oldReplication != null) {
|
if (oldReplication != null) {
|
||||||
oldReplication[0] = oldRepl;
|
oldReplication[0] = oldRepl;
|
||||||
|
@ -2124,7 +2134,7 @@ public class FSDirectory implements Closeable {
|
||||||
if (node instanceof INodeFile) {
|
if (node instanceof INodeFile) {
|
||||||
INodeFile fileNode = (INodeFile)node;
|
INodeFile fileNode = (INodeFile)node;
|
||||||
size = fileNode.computeFileSize(true);
|
size = fileNode.computeFileSize(true);
|
||||||
replication = fileNode.getBlockReplication();
|
replication = fileNode.getFileReplication();
|
||||||
blocksize = fileNode.getPreferredBlockSize();
|
blocksize = fileNode.getPreferredBlockSize();
|
||||||
}
|
}
|
||||||
return new HdfsFileStatus(
|
return new HdfsFileStatus(
|
||||||
|
@ -2154,7 +2164,7 @@ public class FSDirectory implements Closeable {
|
||||||
if (node instanceof INodeFile) {
|
if (node instanceof INodeFile) {
|
||||||
INodeFile fileNode = (INodeFile)node;
|
INodeFile fileNode = (INodeFile)node;
|
||||||
size = fileNode.computeFileSize(true);
|
size = fileNode.computeFileSize(true);
|
||||||
replication = fileNode.getBlockReplication();
|
replication = fileNode.getFileReplication();
|
||||||
blocksize = fileNode.getPreferredBlockSize();
|
blocksize = fileNode.getPreferredBlockSize();
|
||||||
loc = getFSNamesystem().getBlockManager().createLocatedBlocks(
|
loc = getFSNamesystem().getBlockManager().createLocatedBlocks(
|
||||||
fileNode.getBlocks(), fileNode.computeFileSize(false),
|
fileNode.getBlocks(), fileNode.computeFileSize(false),
|
||||||
|
|
|
@ -661,7 +661,7 @@ public class FSEditLog implements LogsPurgeable {
|
||||||
public void logOpenFile(String path, INodeFileUnderConstruction newNode) {
|
public void logOpenFile(String path, INodeFileUnderConstruction newNode) {
|
||||||
AddOp op = AddOp.getInstance(cache.get())
|
AddOp op = AddOp.getInstance(cache.get())
|
||||||
.setPath(path)
|
.setPath(path)
|
||||||
.setReplication(newNode.getBlockReplication())
|
.setReplication(newNode.getFileReplication())
|
||||||
.setModificationTime(newNode.getModificationTime())
|
.setModificationTime(newNode.getModificationTime())
|
||||||
.setAccessTime(newNode.getAccessTime())
|
.setAccessTime(newNode.getAccessTime())
|
||||||
.setBlockSize(newNode.getPreferredBlockSize())
|
.setBlockSize(newNode.getPreferredBlockSize())
|
||||||
|
@ -679,7 +679,7 @@ public class FSEditLog implements LogsPurgeable {
|
||||||
public void logCloseFile(String path, INodeFile newNode) {
|
public void logCloseFile(String path, INodeFile newNode) {
|
||||||
CloseOp op = CloseOp.getInstance(cache.get())
|
CloseOp op = CloseOp.getInstance(cache.get())
|
||||||
.setPath(path)
|
.setPath(path)
|
||||||
.setReplication(newNode.getBlockReplication())
|
.setReplication(newNode.getFileReplication())
|
||||||
.setModificationTime(newNode.getModificationTime())
|
.setModificationTime(newNode.getModificationTime())
|
||||||
.setAccessTime(newNode.getAccessTime())
|
.setAccessTime(newNode.getAccessTime())
|
||||||
.setBlockSize(newNode.getPreferredBlockSize())
|
.setBlockSize(newNode.getPreferredBlockSize())
|
||||||
|
|
|
@ -126,7 +126,7 @@ public class FSImageSerialization {
|
||||||
String path)
|
String path)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
writeString(path, out);
|
writeString(path, out);
|
||||||
out.writeShort(cons.getBlockReplication());
|
out.writeShort(cons.getFileReplication());
|
||||||
out.writeLong(cons.getModificationTime());
|
out.writeLong(cons.getModificationTime());
|
||||||
out.writeLong(cons.getPreferredBlockSize());
|
out.writeLong(cons.getPreferredBlockSize());
|
||||||
int nrBlocks = cons.getBlocks().length;
|
int nrBlocks = cons.getBlocks().length;
|
||||||
|
@ -175,7 +175,7 @@ public class FSImageSerialization {
|
||||||
filePerm);
|
filePerm);
|
||||||
} else {
|
} else {
|
||||||
INodeFile fileINode = (INodeFile)node;
|
INodeFile fileINode = (INodeFile)node;
|
||||||
out.writeShort(fileINode.getBlockReplication());
|
out.writeShort(fileINode.getFileReplication());
|
||||||
out.writeLong(fileINode.getModificationTime());
|
out.writeLong(fileINode.getModificationTime());
|
||||||
out.writeLong(fileINode.getAccessTime());
|
out.writeLong(fileINode.getAccessTime());
|
||||||
out.writeLong(fileINode.getPreferredBlockSize());
|
out.writeLong(fileINode.getPreferredBlockSize());
|
||||||
|
|
|
@ -1414,7 +1414,7 @@ public class FSNamesystem implements Namesystem, FSClusterStats,
|
||||||
}
|
}
|
||||||
|
|
||||||
si.add(trgInode);
|
si.add(trgInode);
|
||||||
short repl = trgInode.getBlockReplication();
|
final short repl = trgInode.getFileReplication();
|
||||||
|
|
||||||
// now check the srcs
|
// now check the srcs
|
||||||
boolean endSrc = false; // final src file doesn't have to have full end block
|
boolean endSrc = false; // final src file doesn't have to have full end block
|
||||||
|
@ -1434,10 +1434,10 @@ public class FSNamesystem implements Namesystem, FSClusterStats,
|
||||||
}
|
}
|
||||||
|
|
||||||
// check replication and blocks size
|
// check replication and blocks size
|
||||||
if(repl != srcInode.getBlockReplication()) {
|
if(repl != srcInode.getFileReplication()) {
|
||||||
throw new IllegalArgumentException(src + " and " + target + " " +
|
throw new IllegalArgumentException(src + " and " + target + " " +
|
||||||
"should have same replication: "
|
"should have same replication: "
|
||||||
+ repl + " vs. " + srcInode.getBlockReplication());
|
+ repl + " vs. " + srcInode.getFileReplication());
|
||||||
}
|
}
|
||||||
|
|
||||||
//boolean endBlock=false;
|
//boolean endBlock=false;
|
||||||
|
@ -1878,9 +1878,10 @@ public class FSNamesystem implements Namesystem, FSClusterStats,
|
||||||
LocatedBlock prepareFileForWrite(String src, INodeFile file,
|
LocatedBlock prepareFileForWrite(String src, INodeFile file,
|
||||||
String leaseHolder, String clientMachine, DatanodeDescriptor clientNode,
|
String leaseHolder, String clientMachine, DatanodeDescriptor clientNode,
|
||||||
boolean writeToEditLog) throws IOException {
|
boolean writeToEditLog) throws IOException {
|
||||||
|
//TODO SNAPSHOT: INodeFileUnderConstruction with link
|
||||||
INodeFileUnderConstruction cons = new INodeFileUnderConstruction(
|
INodeFileUnderConstruction cons = new INodeFileUnderConstruction(
|
||||||
file.getLocalNameBytes(),
|
file.getLocalNameBytes(),
|
||||||
file.getBlockReplication(),
|
file.getFileReplication(),
|
||||||
file.getModificationTime(),
|
file.getModificationTime(),
|
||||||
file.getPreferredBlockSize(),
|
file.getPreferredBlockSize(),
|
||||||
file.getBlocks(),
|
file.getBlocks(),
|
||||||
|
@ -2194,7 +2195,7 @@ public class FSNamesystem implements Namesystem, FSClusterStats,
|
||||||
fileLength = pendingFile.computeContentSummary().getLength();
|
fileLength = pendingFile.computeContentSummary().getLength();
|
||||||
blockSize = pendingFile.getPreferredBlockSize();
|
blockSize = pendingFile.getPreferredBlockSize();
|
||||||
clientNode = pendingFile.getClientNode();
|
clientNode = pendingFile.getClientNode();
|
||||||
replication = pendingFile.getBlockReplication();
|
replication = pendingFile.getFileReplication();
|
||||||
} finally {
|
} finally {
|
||||||
writeUnlock();
|
writeUnlock();
|
||||||
}
|
}
|
||||||
|
@ -3157,7 +3158,7 @@ public class FSNamesystem implements Namesystem, FSClusterStats,
|
||||||
if (diff > 0) {
|
if (diff > 0) {
|
||||||
try {
|
try {
|
||||||
String path = leaseManager.findPath(fileINode);
|
String path = leaseManager.findPath(fileINode);
|
||||||
dir.updateSpaceConsumed(path, 0, -diff * fileINode.getBlockReplication());
|
dir.updateSpaceConsumed(path, 0, -diff*fileINode.getFileReplication());
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
LOG.warn("Unexpected exception while updating disk space.", e);
|
LOG.warn("Unexpected exception while updating disk space.", e);
|
||||||
}
|
}
|
||||||
|
|
|
@ -49,13 +49,13 @@ public class INodeFile extends INode implements BlockCollection {
|
||||||
short replication, long modificationTime,
|
short replication, long modificationTime,
|
||||||
long atime, long preferredBlockSize) {
|
long atime, long preferredBlockSize) {
|
||||||
super(permissions, modificationTime, atime);
|
super(permissions, modificationTime, atime);
|
||||||
this.setReplication(replication);
|
this.setFileReplication(replication);
|
||||||
this.setPreferredBlockSize(preferredBlockSize);
|
this.setPreferredBlockSize(preferredBlockSize);
|
||||||
blocks = blklist;
|
blocks = blklist;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected INodeFile(INodeFile f) {
|
protected INodeFile(INodeFile f) {
|
||||||
this(f.getPermissionStatus(), f.getBlocks(), f.getBlockReplication(),
|
this(f.getPermissionStatus(), f.getBlocks(), f.getFileReplication(),
|
||||||
f.getModificationTime(), f.getAccessTime(), f.getPreferredBlockSize());
|
f.getModificationTime(), f.getAccessTime(), f.getPreferredBlockSize());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -75,12 +75,16 @@ public class INodeFile extends INode implements BlockCollection {
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @return the replication factor of the file. */
|
/** @return the replication factor of the file. */
|
||||||
@Override
|
public final short getFileReplication() {
|
||||||
public short getBlockReplication() {
|
|
||||||
return (short) ((header & HEADERMASK) >> BLOCKBITS);
|
return (short) ((header & HEADERMASK) >> BLOCKBITS);
|
||||||
}
|
}
|
||||||
|
|
||||||
void setReplication(short replication) {
|
@Override
|
||||||
|
public short getBlockReplication() {
|
||||||
|
return getFileReplication();
|
||||||
|
}
|
||||||
|
|
||||||
|
void setFileReplication(short replication) {
|
||||||
if(replication <= 0)
|
if(replication <= 0)
|
||||||
throw new IllegalArgumentException("Unexpected value for the replication");
|
throw new IllegalArgumentException("Unexpected value for the replication");
|
||||||
header = ((long)replication << BLOCKBITS) | (header & ~HEADERMASK);
|
header = ((long)replication << BLOCKBITS) | (header & ~HEADERMASK);
|
||||||
|
@ -220,7 +224,7 @@ public class INodeFile extends INode implements BlockCollection {
|
||||||
isUnderConstruction()) {
|
isUnderConstruction()) {
|
||||||
size += getPreferredBlockSize() - blkArr[blkArr.length-1].getNumBytes();
|
size += getPreferredBlockSize() - blkArr[blkArr.length-1].getNumBytes();
|
||||||
}
|
}
|
||||||
return size * getBlockReplication();
|
return size * getFileReplication();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -102,9 +102,10 @@ class INodeFileUnderConstruction extends INodeFile implements MutableBlockCollec
|
||||||
assert allBlocksComplete() :
|
assert allBlocksComplete() :
|
||||||
"Can't finalize inode " + this + " since it contains " +
|
"Can't finalize inode " + this + " since it contains " +
|
||||||
"non-complete blocks! Blocks are: " + blocksAsString();
|
"non-complete blocks! Blocks are: " + blocksAsString();
|
||||||
|
//TODO SNAPSHOT: may convert to INodeFileWithLink
|
||||||
INodeFile obj = new INodeFile(getPermissionStatus(),
|
INodeFile obj = new INodeFile(getPermissionStatus(),
|
||||||
getBlocks(),
|
getBlocks(),
|
||||||
getBlockReplication(),
|
getFileReplication(),
|
||||||
getModificationTime(),
|
getModificationTime(),
|
||||||
getModificationTime(),
|
getModificationTime(),
|
||||||
getPreferredBlockSize());
|
getPreferredBlockSize());
|
||||||
|
|
|
@ -834,7 +834,7 @@ class NamenodeJspHelper {
|
||||||
doc.endTag();
|
doc.endTag();
|
||||||
|
|
||||||
doc.startTag("replication");
|
doc.startTag("replication");
|
||||||
doc.pcdata(""+inode.getBlockReplication());
|
doc.pcdata(""+inode.getFileReplication());
|
||||||
doc.endTag();
|
doc.endTag();
|
||||||
|
|
||||||
doc.startTag("disk_space_consumed");
|
doc.startTag("disk_space_consumed");
|
||||||
|
|
|
@ -33,6 +33,7 @@ public class INodeFileWithLink extends INodeFile {
|
||||||
|
|
||||||
public INodeFileWithLink(INodeFile f) {
|
public INodeFileWithLink(INodeFile f) {
|
||||||
super(f);
|
super(f);
|
||||||
|
next = this;
|
||||||
}
|
}
|
||||||
|
|
||||||
void setNext(INodeFileWithLink next) {
|
void setNext(INodeFileWithLink next) {
|
||||||
|
@ -42,4 +43,26 @@ public class INodeFileWithLink extends INodeFile {
|
||||||
INodeFileWithLink getNext() {
|
INodeFileWithLink getNext() {
|
||||||
return next;
|
return next;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Insert inode to the circular linked list. */
|
||||||
|
public void insert(INodeFileWithLink inode) {
|
||||||
|
inode.setNext(this.getNext());
|
||||||
|
this.setNext(inode);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the max file replication of the elements
|
||||||
|
* in the circular linked list.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public short getBlockReplication() {
|
||||||
|
short max = getFileReplication();
|
||||||
|
for(INodeFileWithLink i = next; i != this; i = i.getNext()) {
|
||||||
|
final short replication = i.getFileReplication();
|
||||||
|
if (replication > max) {
|
||||||
|
max = replication;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return max;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,7 +48,7 @@ public class TestINodeFile {
|
||||||
FsPermission.getDefault()), null, replication,
|
FsPermission.getDefault()), null, replication,
|
||||||
0L, 0L, preferredBlockSize);
|
0L, 0L, preferredBlockSize);
|
||||||
assertEquals("True has to be returned in this case", replication,
|
assertEquals("True has to be returned in this case", replication,
|
||||||
inf.getBlockReplication());
|
inf.getFileReplication());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Reference in New Issue