diff --git a/src/add-ons/kernel/file_systems/nfs4/Inode.cpp b/src/add-ons/kernel/file_systems/nfs4/Inode.cpp index 53a76a453f..dd7ade5340 100644 --- a/src/add-ons/kernel/file_systems/nfs4/Inode.cpp +++ b/src/add-ons/kernel/file_systems/nfs4/Inode.cpp @@ -892,6 +892,8 @@ bool Inode::_HandleErrors(uint32 nfs4Error, RPC::Server* serv, OpenFileCookie* cookie) { + uint32 leaseTime; + switch (nfs4Error) { case NFS4_OK: return false; @@ -900,11 +902,12 @@ Inode::_HandleErrors(uint32 nfs4Error, RPC::Server* serv, case NFS4ERR_LOCKED: case NFS4ERR_DELAY: if (cookie == NULL) { - snooze_etc(5 * 1000000, B_SYSTEM_TIMEBASE, B_RELATIVE_TIMEOUT); + snooze_etc(sSecToBigTime(5), B_SYSTEM_TIMEBASE, + B_RELATIVE_TIMEOUT); return true; } else if ((cookie->fMode & O_NONBLOCK) == 0) { status_t result = acquire_sem_etc(cookie->fSnoozeCancel, 1, - B_RELATIVE_TIMEOUT, 5 * 1000000); + B_RELATIVE_TIMEOUT, sSecToBigTime(5)); if (result == B_TIMED_OUT) return true; else { @@ -916,14 +919,14 @@ Inode::_HandleErrors(uint32 nfs4Error, RPC::Server* serv, // server is in grace period, we need to wait case NFS4ERR_GRACE: + leaseTime = fFilesystem->NFSServer()->LeaseTime(); if (cookie == NULL) { - snooze_etc(fFilesystem->NFSServer()->LeaseTime() / 3, - B_SYSTEM_TIMEBASE, B_RELATIVE_TIMEOUT); + snooze_etc(sSecToBigTime(leaseTime) / 3, B_SYSTEM_TIMEBASE, + B_RELATIVE_TIMEOUT); return true; } else if ((cookie->fMode & O_NONBLOCK) == 0) { status_t result = acquire_sem_etc(cookie->fSnoozeCancel, 1, - B_RELATIVE_TIMEOUT, - fFilesystem->NFSServer()->LeaseTime() / 3); + B_RELATIVE_TIMEOUT, sSecToBigTime(leaseTime) / 3); if (result == B_TIMED_OUT) return true; else { @@ -952,6 +955,14 @@ Inode::_HandleErrors(uint32 nfs4Error, RPC::Server* serv, fFilesystem->Migrate(serv); return true; + // lease has expired + case NFS4ERR_EXPIRED: + if (cookie != NULL) { + fFilesystem->NFSServer()->ClientId(cookie->fClientId, true); + return true; + } else + return false; + default: return false; } diff --git a/src/add-ons/kernel/file_systems/nfs4/NFS4Defs.h b/src/add-ons/kernel/file_systems/nfs4/NFS4Defs.h index 813586a667..f83cc011d4 100644 --- a/src/add-ons/kernel/file_systems/nfs4/NFS4Defs.h +++ b/src/add-ons/kernel/file_systems/nfs4/NFS4Defs.h @@ -309,5 +309,12 @@ enum Errors { }; +static inline bigtime_t +sSecToBigTime(uint32 sec) +{ + return static_cast(sec) * 1000000; +} + + #endif // NFS4DEFS_H diff --git a/src/add-ons/kernel/file_systems/nfs4/NFS4Server.cpp b/src/add-ons/kernel/file_systems/nfs4/NFS4Server.cpp index 80a54b545f..6fd109e7b3 100644 --- a/src/add-ons/kernel/file_systems/nfs4/NFS4Server.cpp +++ b/src/add-ons/kernel/file_systems/nfs4/NFS4Server.cpp @@ -181,7 +181,7 @@ uint64 NFS4Server::ClientId(uint64 prevId, bool forceNew) { MutexLocker _(fClientIdLock); - if (fClientIdLastUse + (time_t)LeaseTime() < time(NULL) + if (fUseCount == 0 && fClientIdLastUse + (time_t)LeaseTime() < time(NULL) || forceNew && fClientId == prevId) { Request request(fServer); @@ -256,7 +256,7 @@ NFS4Server::_GetLeaseTime() return B_BAD_VALUE; } - fLeaseTime = values[0].fData.fValue32 * 1000000; + fLeaseTime = values[0].fData.fValue32; return B_OK; } @@ -295,8 +295,8 @@ NFS4Server::_Renewal() { while (!fThreadCancel) { // TODO: operations like OPEN, READ, CLOSE, etc also renew leases - snooze_etc(fLeaseTime - 2, B_SYSTEM_TIMEBASE, B_RELATIVE_TIMEOUT - | B_CAN_INTERRUPT); + snooze_etc(sSecToBigTime(fLeaseTime - 2), B_SYSTEM_TIMEBASE, + B_RELATIVE_TIMEOUT | B_CAN_INTERRUPT); uint64 clientId = fClientId;