Add a function that checks for duplicate requests (based

on some fairly tight criteria) so we avoid having broken
clients spam rpc.lockd to death.

PR:		107530
Obtained from:	Doug Rudoff
MFC after:	1 week
This commit is contained in:
Matt Jacob 2007-01-04 20:38:50 +00:00
parent 4ed23cf283
commit 96f8e17c48
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=165775

View File

@ -1195,12 +1195,53 @@ test_hwlock(fl, conflicting_fl)
* if at all possible
*/
int
duplicate_block(struct file_lock *fl)
{
struct file_lock *ifl,*nfl;
int retval = 0;
debuglog("Entering duplicate_block");
/*
* Is this lock request already on the blocking list?
* Condider it a dupe if the file handles, offset, length,
* exclusivity and client match.
*/
LIST_FOREACH(ifl, &blockedlocklist_head, nfslocklist) {
if (!bcmp(&fl->filehandle, &ifl->filehandle,
sizeof(fhandle_t)) &&
fl->client.exclusive == ifl->client.exclusive &&
fl->client.l_offset == ifl->client.l_offset &&
fl->client.l_len == ifl->client.l_len &&
same_filelock_identity(fl, ifl)) {
retval = 1;
break;
}
}
debuglog("Exiting duplicate_block: %s\n", retval ? "already blocked"
: "not already blocked");
return retval;
}
void
add_blockingfilelock(struct file_lock *fl)
{
debuglog("Entering add_blockingfilelock\n");
/*
* A blocking lock request _should_ never be duplicated as a client
* that is already blocked shouldn't be able to request another
* lock. Alas, there are some buggy clients that do request the same
* lock repeatedly. Make sure only unique locks are on the blocked
* lock list.
*/
if (duplicate_block(fl)) {
debuglog("Exiting add_blockingfilelock: already blocked\n");
return;
}
/*
* Clear the blocking flag so that it can be reused without
* adding it to the blocking queue a second time
@ -1209,7 +1250,7 @@ add_blockingfilelock(struct file_lock *fl)
fl->blocking = 0;
LIST_INSERT_HEAD(&blockedlocklist_head, fl, nfslocklist);
debuglog("Exiting add_blockingfilelock\n");
debuglog("Exiting add_blockingfilelock: added blocked lock\n");
}
void