nfs4: close() should also wake snoozing threads
When server returns error codes like LOCKED, DEALY, etc the client waits some time before retrying (unless in O_NONBLOCK mode), close() should wake snoozing threads.
This commit is contained in:
@@ -18,14 +18,17 @@ vint64 OpenFileCookie::fLastOwnerId = 0;
|
||||
|
||||
Cookie::Cookie()
|
||||
:
|
||||
fRequests(NULL)
|
||||
fRequests(NULL),
|
||||
fSnoozeCancel(create_sem(1, NULL))
|
||||
{
|
||||
acquire_sem(fSnoozeCancel);
|
||||
mutex_init(&fRequestLock, NULL);
|
||||
}
|
||||
|
||||
|
||||
Cookie::~Cookie()
|
||||
{
|
||||
delete_sem(fSnoozeCancel);
|
||||
mutex_destroy(&fRequestLock);
|
||||
}
|
||||
|
||||
@@ -74,6 +77,8 @@ Cookie::UnregisterRequest(RPC::Request* req)
|
||||
status_t
|
||||
Cookie::CancelAll()
|
||||
{
|
||||
release_sem(fSnoozeCancel);
|
||||
|
||||
mutex_lock(&fRequestLock);
|
||||
RequestEntry* ent = fRequests;
|
||||
while (ent != NULL) {
|
||||
|
||||
@@ -38,6 +38,8 @@ struct Cookie {
|
||||
RequestEntry* fRequests;
|
||||
mutex fRequestLock;
|
||||
|
||||
sem_id fSnoozeCancel;
|
||||
|
||||
Cookie();
|
||||
virtual ~Cookie();
|
||||
|
||||
|
||||
@@ -1533,18 +1533,37 @@ Inode::_HandleErrors(uint32 nfs4Error, RPC::Server* serv,
|
||||
// server needs more time, we need to wait
|
||||
case NFS4ERR_LOCKED:
|
||||
case NFS4ERR_DELAY:
|
||||
if (cookie == NULL || (cookie->fMode & O_NONBLOCK) == 0) {
|
||||
if (cookie == NULL) {
|
||||
snooze_etc(5 * 1000000, 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);
|
||||
if (result == B_TIMED_OUT)
|
||||
return true;
|
||||
else {
|
||||
release_sem(cookie->fSnoozeCancel);
|
||||
return false;
|
||||
}
|
||||
} else
|
||||
return false;
|
||||
|
||||
// server is in grace period, we need to wait
|
||||
case NFS4ERR_GRACE:
|
||||
if (cookie == NULL || (cookie->fMode & O_NONBLOCK) == 0) {
|
||||
if (cookie == NULL) {
|
||||
snooze_etc(fFilesystem->NFSServer()->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);
|
||||
if (result == B_TIMED_OUT)
|
||||
return true;
|
||||
else {
|
||||
release_sem(cookie->fSnoozeCancel);
|
||||
return false;
|
||||
}
|
||||
} else
|
||||
return false;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user