|
@@ -153,6 +153,7 @@ public class RpcProgramNfs3 extends RpcProgram implements Nfs3Interface {
|
|
|
private final short replication;
|
|
|
private final long blockSize;
|
|
|
private final int bufferSize;
|
|
|
+ private final boolean aixCompatMode;
|
|
|
private Statistics statistics;
|
|
|
private String writeDumpDir; // The dir save dump files
|
|
|
|
|
@@ -170,8 +171,11 @@ public class RpcProgramNfs3 extends RpcProgram implements Nfs3Interface {
|
|
|
config.set(FsPermission.UMASK_LABEL, "000");
|
|
|
iug = new IdUserGroup(config);
|
|
|
|
|
|
+ aixCompatMode = config.getBoolean(
|
|
|
+ NfsConfigKeys.AIX_COMPAT_MODE_KEY,
|
|
|
+ NfsConfigKeys.AIX_COMPAT_MODE_DEFAULT);
|
|
|
exports = NfsExports.getInstance(config);
|
|
|
- writeManager = new WriteManager(iug, config);
|
|
|
+ writeManager = new WriteManager(iug, config, aixCompatMode);
|
|
|
clientCache = new DFSClientCache(config);
|
|
|
replication = (short) config.getInt(DFSConfigKeys.DFS_REPLICATION_KEY,
|
|
|
DFSConfigKeys.DFS_REPLICATION_DEFAULT);
|
|
@@ -900,7 +904,8 @@ public class RpcProgramNfs3 extends RpcProgram implements Nfs3Interface {
|
|
|
|
|
|
// Add open stream
|
|
|
OpenFileCtx openFileCtx = new OpenFileCtx(fos, postOpObjAttr,
|
|
|
- writeDumpDir + "/" + postOpObjAttr.getFileId(), dfsClient, iug);
|
|
|
+ writeDumpDir + "/" + postOpObjAttr.getFileId(), dfsClient, iug,
|
|
|
+ aixCompatMode);
|
|
|
fileHandle = new FileHandle(postOpObjAttr.getFileId());
|
|
|
if (!writeManager.addOpenFileStream(fileHandle, openFileCtx)) {
|
|
|
LOG.warn("Can't add more stream, close it."
|
|
@@ -1438,9 +1443,24 @@ public class RpcProgramNfs3 extends RpcProgram implements Nfs3Interface {
|
|
|
}
|
|
|
long cookieVerf = request.getCookieVerf();
|
|
|
if ((cookieVerf != 0) && (cookieVerf != dirStatus.getModificationTime())) {
|
|
|
- LOG.error("CookierVerf mismatch. request cookierVerf:" + cookieVerf
|
|
|
- + " dir cookieVerf:" + dirStatus.getModificationTime());
|
|
|
- return new READDIR3Response(Nfs3Status.NFS3ERR_BAD_COOKIE);
|
|
|
+ if (aixCompatMode) {
|
|
|
+ // The AIX NFS client misinterprets RFC-1813 and will repeatedly send
|
|
|
+ // the same cookieverf value even across VFS-level readdir calls,
|
|
|
+ // instead of getting a new cookieverf for every VFS-level readdir
|
|
|
+ // call, and reusing the cookieverf only in the event that multiple
|
|
|
+ // incremental NFS-level readdir calls must be made to fetch all of
|
|
|
+ // the directory entries. This means that whenever a readdir call is
|
|
|
+ // made by an AIX NFS client for a given directory, and that directory
|
|
|
+ // is subsequently modified, thus changing its mtime, no later readdir
|
|
|
+ // calls will succeed from AIX for that directory until the FS is
|
|
|
+ // unmounted/remounted. See HDFS-6549 for more info.
|
|
|
+ LOG.warn("AIX compatibility mode enabled, ignoring cookieverf " +
|
|
|
+ "mismatches.");
|
|
|
+ } else {
|
|
|
+ LOG.error("CookieVerf mismatch. request cookieVerf: " + cookieVerf
|
|
|
+ + " dir cookieVerf: " + dirStatus.getModificationTime());
|
|
|
+ return new READDIR3Response(Nfs3Status.NFS3ERR_BAD_COOKIE);
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
if (cookie == 0) {
|
|
@@ -1588,9 +1608,22 @@ public class RpcProgramNfs3 extends RpcProgram implements Nfs3Interface {
|
|
|
}
|
|
|
long cookieVerf = request.getCookieVerf();
|
|
|
if ((cookieVerf != 0) && (cookieVerf != dirStatus.getModificationTime())) {
|
|
|
- LOG.error("CookierVerf mismatch. request cookierVerf:" + cookieVerf
|
|
|
- + " dir cookieVerf:" + dirStatus.getModificationTime());
|
|
|
- return new READDIRPLUS3Response(Nfs3Status.NFS3ERR_BAD_COOKIE);
|
|
|
+ if (aixCompatMode) {
|
|
|
+ // The AIX NFS client misinterprets RFC-1813 and will repeatedly send
|
|
|
+ // the same cookieverf value even across VFS-level readdir calls,
|
|
|
+ // instead of getting a new cookieverf for every VFS-level readdir
|
|
|
+ // call. This means that whenever a readdir call is made by an AIX NFS
|
|
|
+ // client for a given directory, and that directory is subsequently
|
|
|
+ // modified, thus changing its mtime, no later readdir calls will
|
|
|
+ // succeed for that directory from AIX until the FS is
|
|
|
+ // unmounted/remounted. See HDFS-6549 for more info.
|
|
|
+ LOG.warn("AIX compatibility mode enabled, ignoring cookieverf " +
|
|
|
+ "mismatches.");
|
|
|
+ } else {
|
|
|
+ LOG.error("cookieverf mismatch. request cookieverf: " + cookieVerf
|
|
|
+ + " dir cookieverf: " + dirStatus.getModificationTime());
|
|
|
+ return new READDIRPLUS3Response(Nfs3Status.NFS3ERR_BAD_COOKIE);
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
if (cookie == 0) {
|