aboutsummaryrefslogtreecommitdiff
path: root/usr.sbin/rpc.lockd/lockd_lock.c
diff options
context:
space:
mode:
authorAlfred Perlstein <alfred@FreeBSD.org>2001-11-18 05:08:19 +0000
committerAlfred Perlstein <alfred@FreeBSD.org>2001-11-18 05:08:19 +0000
commitb6dc41baf1d20dddc8768ee8ed6f3d156ba7909a (patch)
tree69f8c23776f291036be9e1ab633512b07d7b5d4a /usr.sbin/rpc.lockd/lockd_lock.c
parenta4a8a04d08e0753f9a8909b35a00a17a2893d61c (diff)
downloadsrc-b6dc41baf1d20dddc8768ee8ed6f3d156ba7909a.tar.gz
src-b6dc41baf1d20dddc8768ee8ed6f3d156ba7909a.zip
Cleanup.
use LIST_FOREACH, add prototypes (functions should be made static probably), change DEBUG=1 to LOCKD_DEBUG, K&R function instantiation for functions with long args lists, Move comments about functions from within to above the function, Simplified some if/else logic and reduced nested blocks. parens around 'return' argument (return FOO -> return (FOO))
Notes
Notes: svn path=/cvs2svn/branches/ANDREW_LOCKD/; revision=86537
Diffstat (limited to 'usr.sbin/rpc.lockd/lockd_lock.c')
-rw-r--r--usr.sbin/rpc.lockd/lockd_lock.c673
1 files changed, 344 insertions, 329 deletions
diff --git a/usr.sbin/rpc.lockd/lockd_lock.c b/usr.sbin/rpc.lockd/lockd_lock.c
index 9d34660d37da..bbb763edab0a 100644
--- a/usr.sbin/rpc.lockd/lockd_lock.c
+++ b/usr.sbin/rpc.lockd/lockd_lock.c
@@ -35,10 +35,10 @@
*
*/
-#define DEBUG 1
+#define LOCKD_DEBUG
#include <stdio.h>
-#ifdef DEBUG
+#ifdef LOCKD_DEBUG
#include <stdarg.h>
#endif
#include <stdlib.h>
@@ -144,6 +144,9 @@ enum hwlock_status { HW_GRANTED = 0, HW_GRANTED_DUPLICATE,
HW_DENIED, HW_DENIED_NOLOCK,
HW_STALEFH, HW_READONLY, HW_RESERR };
+enum split_status {SPL_DISJOINT, SPL_LOCK_CONTAINED, SPL_LOCK_LEFT,
+ SPL_LOCK_RIGHT, SPL_UNLOCK_CONTAINED};
+
enum partialfilelock_status { PFL_GRANTED=0, PFL_GRANTED_DUPLICATE, PFL_DENIED,
PFL_NFSDENIED, PFL_NFSBLOCKED, PFL_NFSDENIED_NOLOCK, PFL_NFSRESERR,
PFL_HWDENIED, PFL_HWBLOCKED, PFL_HWDENIED_NOLOCK, PFL_HWRESERR};
@@ -156,6 +159,52 @@ void sigunlock(void);
void monitor_lock_host(const char *hostname);
void unmonitor_lock_host(const char *hostname);
+void copy_nlm4_lock_to_nlm4_holder(const struct nlm4_lock *src,
+ const bool_t exclusive, struct nlm4_holder *dest);
+void deallocate_file_lock(struct file_lock *fl);
+int regions_overlap(const u_int64_t start1, const u_int64_t len1,
+ const u_int64_t start2, const u_int64_t len2);;
+int same_netobj(const netobj *n0, const netobj *n1);
+int same_filelock_identity(const struct file_lock *fl0,
+ const struct file_lock *fl2);
+
+static void debuglog(char const *fmt, ...);
+void dump_static_object(const unsigned char* object, const int sizeof_object,
+ unsigned char* hbuff, const int sizeof_hbuff,
+ unsigned char* cbuff, const int sizeof_cbuff);
+void dump_netobj(const struct netobj *nobj);
+void dump_filelock(const struct file_lock *fl);
+struct file_lock * malloccopy_filelock(struct file_lock *fl);
+struct file_lock * get_lock_matching_unlock(const struct file_lock *fl);
+enum nfslock_status test_nfslock(const struct file_lock *fl,
+ struct file_lock **conflicting_fl);
+enum nfslock_status lock_nfslock(struct file_lock *fl);
+enum nfslock_status delete_nfslock(struct file_lock *fl);
+enum nfslock_status unlock_nfslock(const struct file_lock *fl,
+ struct file_lock **released_lock, struct file_lock *left_lock,
+ struct file_lock *right_lock);
+enum hwlock_status lock_hwlock(struct file_lock *fl);
+enum split_status split_nfslock(const struct file_lock *exist_lock,
+ const struct file_lock *unlock_lock, const struct file_lock *right_lock);
+void add_blockingfilelock(struct file_lock *fl);
+enum hwlock_status unlock_hwlock(const struct file_lock *fl);
+enum hwlock_status test_hwlock(const struct file_lock *fl,
+ struct file_lock **conflicting_fl);
+void remove_blockingfilelock(struct file_lock *fl);
+void clear_blockingfilelock(const char *hostname);
+void retry_blockingfilelocklist(void);
+enum partialfilelock_status unlock_partialfilelock(
+ const struct file_lock *fl);
+void clear_partialfilelock(const char *hostname);
+enum partialfilelock_status test_partialfilelock(
+ const struct file_lock *fl, struct file_lock **conflicting_fl);
+enum nlm_stats do_test(struct file_lock *fl,
+ struct file_lock **conflicting_fl);
+enum nlm_stats do_unlock(struct file_lock *fl);
+enum nlm_stats do_lock(struct file_lock *fl);
+void do_clear(const char *hostname);
+
+
void
debuglog(char const *fmt, ...)
{
@@ -172,17 +221,22 @@ debuglog(char const *fmt, ...)
va_end(ap);
}
-void dump_static_object(const unsigned char* object, const int sizeof_object,
- unsigned char* hbuff, const int sizeof_hbuff,
- unsigned char* cbuff, const int sizeof_cbuff)
+void
+dump_static_object(object, size_object, hbuff, size_hbuff, cbuff, size_cbuff)
+ const unsigned char *object;
+ const int size_object;
+ unsigned char *hbuff;
+ const int size_hbuff;
+ unsigned char *cbuff;
+ const int size_cbuff;
{
- int i,objectsize;
+ int i, objectsize;
if (debug_level < 2) {
return;
}
- objectsize = sizeof_object;
+ objectsize = size_object;
if (objectsize == 0) {
debuglog("object is size 0\n");
@@ -194,7 +248,7 @@ void dump_static_object(const unsigned char* object, const int sizeof_object,
}
if (hbuff != NULL) {
- if (sizeof_hbuff < objectsize*2+1) {
+ if (size_hbuff < objectsize*2+1) {
debuglog("Hbuff not large enough."
" Increase size\n");
} else {
@@ -206,7 +260,7 @@ void dump_static_object(const unsigned char* object, const int sizeof_object,
}
if (cbuff != NULL) {
- if (sizeof_cbuff < objectsize+1) {
+ if (size_cbuff < objectsize+1) {
debuglog("Cbuff not large enough."
" Increase Size\n");
}
@@ -223,7 +277,8 @@ void dump_static_object(const unsigned char* object, const int sizeof_object,
}
}
-void dump_netobj(const struct netobj *nobj)
+void
+dump_netobj(const struct netobj *nobj)
{
char hbuff[MAXBUFFERSIZE*2];
char cbuff[MAXBUFFERSIZE];
@@ -238,14 +293,15 @@ void dump_netobj(const struct netobj *nobj)
else if (nobj->n_len == 0) {
debuglog("Size zero netobj\n");
} else {
- dump_static_object(nobj->n_bytes,nobj->n_len,
- hbuff,sizeof(hbuff),cbuff,sizeof(cbuff));
+ dump_static_object(nobj->n_bytes, nobj->n_len,
+ hbuff, sizeof(hbuff), cbuff, sizeof(cbuff));
debuglog("netobj: len: %d data: %s ::: %s\n",
- nobj->n_len,hbuff,cbuff);
+ nobj->n_len, hbuff, cbuff);
}
}
-void dump_filelock(const struct file_lock *fl)
+void
+dump_filelock(const struct file_lock *fl)
{
char hbuff[MAXBUFFERSIZE*2];
char cbuff[MAXBUFFERSIZE];
@@ -262,8 +318,8 @@ void dump_filelock(const struct file_lock *fl)
cbuff, sizeof(cbuff));
debuglog("Filehandle: %8s ::: %8s\n", hbuff, cbuff);
- debuglog("Dumping nlm4_holder:\n");
- debuglog("exc: %x svid: %x offset:len %llx:%llx\n",
+ debuglog("Dumping nlm4_holder:\n"
+ "exc: %x svid: %x offset:len %llx:%llx\n",
fl->client.exclusive, fl->client.svid,
fl->client.l_offset, fl->client.l_len);
@@ -284,12 +340,16 @@ void dump_filelock(const struct file_lock *fl)
struct file_lock *
malloccopy_filelock(struct file_lock *fl)
{
+
}
void
-copy_nlm4_lock_to_nlm4_holder(const struct nlm4_lock *src,
- const bool_t exclusive, struct nlm4_holder *dest)
+copy_nlm4_lock_to_nlm4_holder(src, exclusive, dest)
+ const struct nlm4_lock *src;
+ const bool_t exclusive;
+ struct nlm4_holder *dest;
{
+
dest->exclusive = exclusive;
dest->oh.n_len = src->oh.n_len;
dest->oh.n_bytes = src->oh.n_bytes;
@@ -300,14 +360,12 @@ copy_nlm4_lock_to_nlm4_holder(const struct nlm4_lock *src,
/*
* deallocate_file_lock: Free all storage associated with a file lock
+ * XXX: Check to see if this gets *all* the dynamic structures.
+ * XXX: It should be placed closer to the file_lock definition.
*/
-
void
deallocate_file_lock(struct file_lock *fl)
{
- /* XXX: Check to see if this gets *all* the dynamic structures */
- /* XXX: It should be placed closer to the file_lock definition */
-
free(fl->client.oh.n_bytes);
free(fl->client_cookie.n_bytes);
free(fl);
@@ -317,13 +375,13 @@ deallocate_file_lock(struct file_lock *fl)
* regions_overlap(): This function examines the two provided regions for
* overlap. It is non-trivial because start+len *CAN* overflow a 64-bit
* unsigned integer and NFS semantics are unspecified on this account.
+ * XXX: Check to make sure I got *ALL* the cases.
+ * XXX: This DESPERATELY needs a regression test.
*/
int
-regions_overlap(const u_int64_t start1, const u_int64_t len1,
- const u_int64_t start2, const u_int64_t len2)
+regions_overlap(start1, len1, start2, len2)
+ const u_int64_t start1, len1, start2, len2;
{
- /* XXX: Check to make sure I got *ALL* the cases */
- /* XXX: This DESPERATELY needs a regression test */
int result;
debuglog("Entering region overlap with vals: %llu:%llu--%llu:%llu\n",
@@ -336,29 +394,17 @@ regions_overlap(const u_int64_t start1, const u_int64_t len1,
/* Regions *must* overlap if they both extend to the end */
result = 1;
} else if (len1 == 0) {
- if (start2+len2 <= start1) {
- /* Region 2 is completely left of region 1 */
- result = 0;
- } else {
- result = 1;
- }
+ /* Region 2 is completely left of region 1 */
+ result = (start2 + len2 > start1);
} else if (len2 == 0) {
- if (start1+len1 <= start2) {
- /* Region 1 is completely left of region 2 */
- result = 0;
- } else {
- result = 1;
- }
+ /* Region 1 is completely left of region 2 */
+ result = (start1 + len1 > start2);
} else {
- if (start1+len1 <= start2 || start2+len2 <= start1) {
- /*
- * 1 is completely left of 2 or
- * 2 is completely left of 1
- */
- result = 0;
- } else {
- result = 1;
- }
+ /*
+ * 1 is completely left of 2 or
+ * 2 is completely left of 1
+ */
+ result = !(start1+len1 <= start2 || start2+len2 <= start1);
}
debuglog("Exiting region overlap with val: %d\n",result);
@@ -374,30 +420,25 @@ same_netobj(const netobj *n0, const netobj *n1)
{
int retval;
- retval=0;
+ retval = 0;
debuglog("Entering netobj identity check\n");
if (n0->n_len == n1->n_len) {
debuglog("Preliminary length check passed\n");
-
- if (!bcmp(n0->n_bytes,n1->n_bytes,n0->n_len)) {
- retval = 1;
- debuglog("netobj match\n");
- } else {
- debuglog("netobj mismatch\n");
- }
+ retval = !bcmp(n0->n_bytes, n1->n_bytes, n0->n_len);
+ debuglog("netobj %smatch\n", retval ? "" : "mis");
}
- return retval;
+ return (retval);
}
/*
* same_filelock_identity: Compares the appropriate bits of a file_lock
*/
int
-same_filelock_identity(const struct file_lock *fl0,
- const struct file_lock *fl1)
+same_filelock_identity(fl0, fl1)
+ const struct file_lock *fl0, *fl1;
{
int retval;
@@ -405,14 +446,15 @@ same_filelock_identity(const struct file_lock *fl0,
debuglog("Checking filelock identity\n");
- if (fl0->client.svid == fl1->client.svid) {
- /* Process ids match now check host information */
- retval = same_netobj(&(fl0->client.oh),&(fl1->client.oh));
- }
+ /*
+ * Check process ids and host information.
+ */
+ retval = (fl0->client.svid == fl1->client.svid &&
+ same_netobj(&(fl0->client.oh), &(fl1->client.oh)));
debuglog("Exiting checking filelock identity: retval: %d\n",retval);
- return retval;
+ return (retval);
}
/*
@@ -423,24 +465,18 @@ same_filelock_identity(const struct file_lock *fl0,
/*
* get_lock_matching_unlock: Return a lock which matches the given unlock lock
* or NULL otehrwise
+ * XXX: It is a shame that this duplicates so much code from test_nfslock.
*/
-struct file_lock*
-get_lock_matching_unlock (const struct file_lock *fl)
+struct file_lock *
+get_lock_matching_unlock(const struct file_lock *fl)
{
- /* XXX: It is annoying that this duplicates so much code from test_nfslock */
-
struct file_lock *ifl; /* Iterator */
- struct file_lock *retval;
debuglog("Entering lock_matching_unlock\n");
debuglog("********Dump of fl*****************\n");
dump_filelock(fl);
- retval = NULL;
-
- for (ifl = LIST_FIRST(&nfslocklist_head);
- ifl != NULL && retval == NULL;
- ifl = LIST_NEXT(ifl, nfslocklist)) {
+ LIST_FOREACH(ifl, &nfslocklist_head, nfslocklist) {
debuglog("Pointer to file lock: %p\n",ifl);
debuglog("****Dump of ifl****\n");
@@ -453,32 +489,33 @@ get_lock_matching_unlock (const struct file_lock *fl)
* security hazard as the filehandle code may bypass normal
* file access controls
*/
- if (!bcmp(&fl->filehandle, &ifl->filehandle,
- sizeof(fhandle_t))) {
- debuglog("matching_unlock: Filehandles match."
- " Checking regions\n");
-
- /* Filehandles match, check for region overlap */
- if (regions_overlap(fl->client.l_offset, fl->client.l_len,
- ifl->client.l_offset, ifl->client.l_len)) {
- debuglog("matching_unlock: Region overlap"
- " found %llu : %llu -- %llu : %llu\n",
- fl->client.l_offset,fl->client.l_len,
- ifl->client.l_offset,ifl->client.l_len);
-
- /* Regions overlap, check the identity */
- if (same_filelock_identity(fl,ifl)) {
- debuglog("matching_unlock: Duplicate"
- " lock id. Granting\n");
- retval = ifl;
- }
- }
- }
+ if (bcmp(&fl->filehandle, &ifl->filehandle, sizeof(fhandle_t)))
+ continue;
+
+ debuglog("matching_unlock: Filehandles match, "
+ "checking regions\n");
+
+ /* Filehandles match, check for region overlap */
+ if (!regions_overlap(fl->client.l_offset, fl->client.l_len,
+ ifl->client.l_offset, ifl->client.l_len))
+ continue;
+
+ debuglog("matching_unlock: Region overlap"
+ " found %llu : %llu -- %llu : %llu\n",
+ fl->client.l_offset,fl->client.l_len,
+ ifl->client.l_offset,ifl->client.l_len);
+
+ /* Regions overlap, check the identity */
+ if (!same_filelock_identity(fl,ifl))
+ continue;
+
+ debuglog("matching_unlock: Duplicate lock id. Granting\n");
+ return (ifl);
}
debuglog("Exiting lock_matching_unlock\n");
- return retval;
+ return (NULL);
}
/*
@@ -513,9 +550,10 @@ test_nfslock(const struct file_lock *fl, struct file_lock **conflicting_fl)
dump_filelock(fl);
debuglog("***********************************\n");
- for (ifl = LIST_FIRST(&nfslocklist_head);
- ifl != NULL && retval != NFS_DENIED;
- ifl = LIST_NEXT(ifl, nfslocklist)) {
+ LIST_FOREACH(ifl, &nfslocklist_head, nfslocklist) {
+ if (retval == NFS_DENIED)
+ break;
+
debuglog("Top of lock loop\n");
debuglog("Pointer to file lock: %p\n",ifl);
@@ -531,52 +569,49 @@ test_nfslock(const struct file_lock *fl, struct file_lock **conflicting_fl)
* security hazard as the filehandle code may bypass normal
* file access controls
*/
- if (!bcmp(&fl->filehandle, &ifl->filehandle,
- sizeof(fhandle_t))) {
- debuglog("test_nfslock: filehandle match found\n");
-
- /* Filehandles match, check for region overlap */
- if (regions_overlap(fl->client.l_offset, fl->client.l_len,
- ifl->client.l_offset, ifl->client.l_len)) {
- debuglog("test_nfslock: Region overlap found"
- " %llu : %llu -- %llu : %llu\n",
- fl->client.l_offset,fl->client.l_len,
- ifl->client.l_offset,ifl->client.l_len);
-
- /* Regions overlap, check the exclusivity */
- if (fl->client.exclusive ||
- ifl->client.exclusive) {
- debuglog("test_nfslock: "
- "Exclusivity failure: %d %d\n",
- fl->client.exclusive,
- ifl->client.exclusive);
-
- if (same_filelock_identity(fl,ifl)) {
- debuglog("test_nfslock: "
- "Duplicate lock id. "
- "Granting\n");
- (*conflicting_fl) = ifl;
- retval = NFS_GRANTED_DUPLICATE;
- } else {
- /* locking attempt fails */
- debuglog("test_nfslock: "
- "Lock attempt failed\n");
- debuglog("Desired lock\n");
- dump_filelock(fl);
- debuglog("Conflicting lock\n");
- dump_filelock(ifl);
- (*conflicting_fl) = ifl;
- retval = NFS_DENIED;
- }
- }
- }
+ if (bcmp(&fl->filehandle, &ifl->filehandle, sizeof(fhandle_t)))
+ continue;
+
+ debuglog("test_nfslock: filehandle match found\n");
+
+ /* Filehandles match, check for region overlap */
+ if (!regions_overlap(fl->client.l_offset, fl->client.l_len,
+ ifl->client.l_offset, ifl->client.l_len))
+ continue;
+
+ debuglog("test_nfslock: Region overlap found"
+ " %llu : %llu -- %llu : %llu\n",
+ fl->client.l_offset,fl->client.l_len,
+ ifl->client.l_offset,ifl->client.l_len);
+
+ /* Regions overlap, check the exclusivity */
+ if (!(fl->client.exclusive || ifl->client.exclusive))
+ continue;
+
+ debuglog("test_nfslock: Exclusivity failure: %d %d\n",
+ fl->client.exclusive,
+ ifl->client.exclusive);
+
+ if (same_filelock_identity(fl,ifl)) {
+ debuglog("test_nfslock: Duplicate id. Granting\n");
+ (*conflicting_fl) = ifl;
+ retval = NFS_GRANTED_DUPLICATE;
+ } else {
+ /* locking attempt fails */
+ debuglog("test_nfslock: Lock attempt failed\n");
+ debuglog("Desired lock\n");
+ dump_filelock(fl);
+ debuglog("Conflicting lock\n");
+ dump_filelock(ifl);
+ (*conflicting_fl) = ifl;
+ retval = NFS_DENIED;
}
}
debuglog("Dumping file locks\n");
debuglog("Exiting test_nfslock\n");
- return retval;
+ return (retval);
}
/*
@@ -617,7 +652,7 @@ lock_nfslock(struct file_lock *fl)
debuglog("Exiting lock_nfslock...\n");
- return retval;
+ return (retval);
}
/*
@@ -634,25 +669,25 @@ lock_nfslock(struct file_lock *fl)
enum nfslock_status
delete_nfslock(struct file_lock *fl)
{
+
LIST_REMOVE(fl, nfslocklist);
- return NFS_GRANTED;
+ return (NFS_GRANTED);
}
-
-enum split_status {SPL_DISJOINT, SPL_LOCK_CONTAINED, SPL_LOCK_LEFT,
- SPL_LOCK_RIGHT, SPL_UNLOCK_CONTAINED};
-
enum split_status
-split_nfslock(const struct file_lock *exist_lock,
- const struct file_lock *unlock_lock,
- const struct file_lock *left_lock, const struct file_lock *right_lock)
+split_nfslock(exist_lock, unlock_lock, right_lock)
+ const struct file_lock *exist_lock, *unlock_lock, *right_lock;
{
+
}
enum nfslock_status
-unlock_nfslock(const struct file_lock *fl, struct file_lock **released_lock,
- struct file_lock *left_lock, struct file_lock *right_lock)
+unlock_nfslock(fl, released_lock, left_lock, right_lock)
+ const struct file_lock *fl;
+ struct file_lock **released_lock;
+ struct file_lock *left_lock;
+ struct file_lock *right_lock;
{
struct file_lock *mfl; /* Matching file lock */
enum nfslock_status retval;
@@ -676,28 +711,21 @@ unlock_nfslock(const struct file_lock *fl, struct file_lock **released_lock,
retval = NFS_GRANTED;
}
-/* split_status = split_nfslock(mfl,fl,lfl,rfl); */
-
-/* if (split_status == SPL_DISJOINT) */
-/* { */
-/* /* Shouldn't happen, throw error */
-/* } */
-/* else if (split_status == SPL_LOCK_CONTAINED) */
-/* { */
-/* /* Delete entire lock */
-/* } */
-/* else if (split_status == SPL_LOCK_LEFT) */
-/* { */
-/* /* Create new lock for left lock and delete old one */
-/* } */
-/* else if (split_status == SPL_LOCK_RIGHT) */
-/* { */
-/* /* Create new lock for right lock and delete old one */
-/* } */
-/* else if (split_status == SPL_UNLOCK_CONTAINED) */
-/* { */
-/* /* Create new locks for both and then delete old one */
-/* } */
+#if 0
+ split_status = split_nfslock(mfl,fl,lfl,rfl);
+
+ if (split_status == SPL_DISJOINT) {
+ /* Shouldn't happen, throw error */
+ } else if (split_status == SPL_LOCK_CONTAINED) {
+ /* Delete entire lock */
+ } else if (split_status == SPL_LOCK_LEFT) {
+ /* Create new lock for left lock and delete old one */
+ } else if (split_status == SPL_LOCK_RIGHT) {
+ /* Create new lock for right lock and delete old one */
+ } else if (split_status == SPL_UNLOCK_CONTAINED) {
+ /* Create new locks for both and then delete old one */
+ }
+#endif
debuglog("Exiting unlock_nfslock\n");
@@ -712,7 +740,6 @@ enum hwlock_status
lock_hwlock(struct file_lock *fl)
{
struct monfile *imf,*nmf;
- enum hwlock_status retval;
int lflags, flerror;
/* Scan to see if filehandle already present */
@@ -724,95 +751,81 @@ lock_hwlock(struct file_lock *fl)
}
}
- if (imf == NULL) {
- /* No filehandle found, create and go */
- nmf = malloc(sizeof(struct monfile));
- if (nmf == NULL) {
- debuglog("hwlock resource allocation failure\n");
- retval = HW_RESERR;
- return retval;
- }
+ /*
+ * Filehandle already exists (we control the file)
+ * *AND* NFS has already cleared the lock for availability
+ * Grant it and bump the refcount.
+ */
+ if (imf != NULL) {
+ ++(imf->refcount);
+ return (HW_GRANTED);
+ }
- /* XXX: Is O_RDWR always the correct mode? */
- nmf->fd = fhopen(&fl->filehandle, O_RDWR);
- if (nmf->fd < 0) {
- switch (errno) {
- case ESTALE:
- retval = HW_STALEFH;
- break;
- case EROFS:
- retval = HW_READONLY;
- break;
- default:
- retval = HW_RESERR;
- break;
- }
- debuglog("fhopen failed (from %16s): %32s\n",
- fl->client_name, strerror(errno));
- free(nmf);
- } else {
- /* File opened correctly, fill the monitor struct */
- bcopy(&fl->filehandle, &nmf->filehandle, sizeof(fl->filehandle));
- nmf->refcount = 1;
- nmf->exclusive = fl->client.exclusive;
-
- lflags = (nmf->exclusive == 1) ?
- (LOCK_EX | LOCK_NB) : (LOCK_SH | LOCK_NB);
-
- flerror = flock(nmf->fd, lflags);
-
- if (flerror != 0) {
- switch (errno) {
- case EAGAIN:
- retval = HW_DENIED;
- break;
- case ESTALE:
- retval = HW_STALEFH;
- break;
- case EROFS:
- retval = HW_READONLY;
- break;
- default:
- retval = HW_RESERR;
- break;
- }
-
- debuglog("flock failed (from %16s): %32s\n",
- fl->client_name, strerror(errno));
+ /* No filehandle found, create and go */
+ nmf = malloc(sizeof(struct monfile));
+ if (nmf == NULL) {
+ debuglog("hwlock resource allocation failure\n");
+ return (HW_RESERR);
+ }
- close(nmf->fd);
- free(nmf);
- } else {
- /* File opened and locked */
- LIST_INSERT_HEAD(&monfilelist_head, nmf, monfilelist);
- retval = HW_GRANTED;
+ /* XXX: Is O_RDWR always the correct mode? */
+ nmf->fd = fhopen(&fl->filehandle, O_RDWR);
+ if (nmf->fd < 0) {
+ debuglog("fhopen failed (from %16s): %32s\n",
+ fl->client_name, strerror(errno));
+ free(nmf);
+ switch (errno) {
+ case ESTALE:
+ return (HW_STALEFH);
+ case EROFS:
+ return (HW_READONLY);
+ default:
+ return (HW_RESERR);
+ }
+ }
- debuglog("flock succeeded (from %16s)\n",
- fl->client_name);
- }
+ /* File opened correctly, fill the monitor struct */
+ bcopy(&fl->filehandle, &nmf->filehandle, sizeof(fl->filehandle));
+ nmf->refcount = 1;
+ nmf->exclusive = fl->client.exclusive;
+
+ lflags = (nmf->exclusive == 1) ?
+ (LOCK_EX | LOCK_NB) : (LOCK_SH | LOCK_NB);
+
+ flerror = flock(nmf->fd, lflags);
+
+ if (flerror != 0) {
+ debuglog("flock failed (from %16s): %32s\n",
+ fl->client_name, strerror(errno));
+ close(nmf->fd);
+ free(nmf);
+ switch (errno) {
+ case EAGAIN:
+ return (HW_DENIED);
+ case ESTALE:
+ return (HW_STALEFH);
+ case EROFS:
+ return (HW_READONLY);
+ default:
+ return (HW_RESERR);
+ break;
}
- } else {
- /*
- * Filehandle already exists (we control the file)
- * *AND* NFS has already cleared the lock for availability
- * Grant it and bump the refcount.
- */
- ++(imf->refcount);
- retval = HW_GRANTED;
}
- return retval;
+ /* File opened and locked */
+ LIST_INSERT_HEAD(&monfilelist_head, nmf, monfilelist);
+
+ debuglog("flock succeeded (from %16s)\n", fl->client_name);
+ return (HW_GRANTED);
}
enum hwlock_status
unlock_hwlock(const struct file_lock *fl)
{
struct monfile *imf;
- enum hwlock_status retval;
debuglog("Entering unlock_hwlock\n");
debuglog("Entering loop interation\n");
-
/* Scan to see if filehandle already present */
LIST_FOREACH(imf, &monfilelist_head, monfilelist) {
@@ -827,37 +840,35 @@ unlock_hwlock(const struct file_lock *fl)
if (imf == NULL) {
/* No lock found */
- debuglog("No hardware lock found.\n");
- retval = HW_DENIED_NOLOCK;
- } else {
- /* Lock found */
- --imf->refcount;
+ debuglog("Exiting unlock_hwlock (HW_DENIED_NOLOCK)\n");
+ return (HW_DENIED_NOLOCK);
+ }
- if (imf->refcount < 0) {
- debuglog("Negative hardware reference count\n");
- }
+ /* Lock found */
+ --imf->refcount;
- if (imf->refcount <= 0) {
- close(imf->fd);
- LIST_REMOVE(imf, monfilelist);
- free(imf);
- }
- retval = HW_GRANTED;
+ if (imf->refcount < 0) {
+ debuglog("Negative hardware reference count\n");
}
- debuglog("Exiting unlock_hwlock\n");
-
- return retval;
+ if (imf->refcount <= 0) {
+ close(imf->fd);
+ LIST_REMOVE(imf, monfilelist);
+ free(imf);
+ }
+ debuglog("Exiting unlock_hwlock (HW_GRANTED)\n");
+ return (HW_GRANTED);
}
enum hwlock_status
test_hwlock(const struct file_lock *fl, struct file_lock **conflicting_fl)
{
+
/*
* XXX: lock tests on hardware are not required until
* true partial file testing is done on the underlying file
*/
- return HW_RESERR;
+ return (HW_RESERR);
}
@@ -871,6 +882,7 @@ test_hwlock(const struct file_lock *fl, struct file_lock **conflicting_fl)
void
add_blockingfilelock(struct file_lock *fl)
{
+
debuglog("Entering add_blockingfilelock\n");
/*
@@ -887,6 +899,7 @@ add_blockingfilelock(struct file_lock *fl)
void
remove_blockingfilelock(struct file_lock *fl)
{
+
debuglog("Entering remove_blockingfilelock\n");
LIST_REMOVE(fl, nfslocklist);
@@ -1472,8 +1485,9 @@ do_unlock(struct file_lock *fl)
*/
void
-do_clear(const char* hostname)
+do_clear(const char *hostname)
{
+
clear_partialfilelock(hostname);
}
@@ -1663,63 +1677,62 @@ monitor_lock_host(const char *hostname)
rpcret = 0;
statflag = 0;
-
- for( ihp=LIST_FIRST(&hostlst_head); ihp != NULL;
- ihp=LIST_NEXT(ihp, hostlst)) {
+
+ LIST_FOREACH(ihp, &hostlst_head, hostlst) {
if (strncmp(hostname, ihp->name, SM_MAXSTRLEN) == 0) {
/* Host is already monitored, bump refcount */
++ihp->refcnt;
/* Host should only be in the monitor list once */
- break;
+ return;
}
}
- if (ihp == NULL) {
- /* Host is not yet monitored, add it */
- nhp = malloc(sizeof(struct host));
+ /* Host is not yet monitored, add it */
+ nhp = malloc(sizeof(struct host));
- if (nhp == NULL) {
- debuglog("Unable to allocate entry for statd mon\n");
- return;
- } else {
- /* Allocated new host entry, now fill the fields */
- strncpy(nhp->name, hostname, SM_MAXSTRLEN);
- nhp->refcnt = 1;
- debuglog("Locally Monitoring host %16s\n",hostname);
+ if (nhp == NULL) {
+ debuglog("Unable to allocate entry for statd mon\n");
+ return;
+ }
+
+ /* Allocated new host entry, now fill the fields */
+ strncpy(nhp->name, hostname, SM_MAXSTRLEN);
+ nhp->refcnt = 1;
+ debuglog("Locally Monitoring host %16s\n",hostname);
- debuglog("Attempting to tell statd\n");
+ debuglog("Attempting to tell statd\n");
- bzero(&smon,sizeof(smon));
+ bzero(&smon,sizeof(smon));
- smon.mon_id.mon_name = nhp->name;
- smon.mon_id.my_id.my_name = "localhost\0";
+ smon.mon_id.mon_name = nhp->name;
+ smon.mon_id.my_id.my_name = "localhost\0";
- smon.mon_id.my_id.my_prog = NLM_PROG;
- smon.mon_id.my_id.my_vers = NLM_SM;
- smon.mon_id.my_id.my_proc = NLM_SM_NOTIFY;
+ smon.mon_id.my_id.my_prog = NLM_PROG;
+ smon.mon_id.my_id.my_vers = NLM_SM;
+ smon.mon_id.my_id.my_proc = NLM_SM_NOTIFY;
- rpcret = callrpc("localhost", SM_PROG, SM_VERS, SM_MON, xdr_mon,
- &smon, xdr_sm_stat_res, &sres);
+ rpcret = callrpc("localhost", SM_PROG, SM_VERS, SM_MON, xdr_mon,
+ &smon, xdr_sm_stat_res, &sres);
- if (rpcret == 0) {
- if (sres.res_stat == stat_fail) {
- debuglog("Statd call failed\n");
- statflag = 0;
- } else {
- statflag = 1;
- }
- } else {
- debuglog("Rpc call to statd failed with return value: %d\n",rpcret);
- statflag = 0;
- }
-
- if (statflag == 1) {
- LIST_INSERT_HEAD(&hostlst_head, nhp, hostlst);
- } else {
- free(nhp);
- }
+ if (rpcret == 0) {
+ if (sres.res_stat == stat_fail) {
+ debuglog("Statd call failed\n");
+ statflag = 0;
+ } else {
+ statflag = 1;
}
+ } else {
+ debuglog("Rpc call to statd failed with return value: %d\n",
+ rpcret);
+ statflag = 0;
}
+
+ if (statflag == 1) {
+ LIST_INSERT_HEAD(&hostlst_head, nhp, hostlst);
+ } else {
+ free(nhp);
+ }
+
}
/*
@@ -1747,35 +1760,37 @@ unmonitor_lock_host(const char *hostname)
if (ihp == NULL) {
debuglog("Could not find host %16s in mon list\n", hostname);
- } else {
- if (ihp->refcnt <= 0) {
- if (ihp->refcnt < 0) {
- debuglog("Negative refcount!: %d\n",
- ihp->refcnt);
- }
+ return;
+ }
- debuglog("Attempting to unmonitor host %16s\n",
- hostname);
+ if (ihp->refcnt > 0)
+ return;
+
+ if (ihp->refcnt < 0) {
+ debuglog("Negative refcount!: %d\n",
+ ihp->refcnt);
+ }
+
+ debuglog("Attempting to unmonitor host %16s\n", hostname);
- bzero(&smon_id,sizeof(smon_id));
+ bzero(&smon_id,sizeof(smon_id));
- smon_id.mon_name = (char *)hostname;
- smon_id.my_id.my_name = "localhost";
- smon_id.my_id.my_prog = NLM_PROG;
- smon_id.my_id.my_vers = NLM_SM;
- smon_id.my_id.my_proc = NLM_SM_NOTIFY;
+ smon_id.mon_name = (char *)hostname;
+ smon_id.my_id.my_name = "localhost";
+ smon_id.my_id.my_prog = NLM_PROG;
+ smon_id.my_id.my_vers = NLM_SM;
+ smon_id.my_id.my_proc = NLM_SM_NOTIFY;
- rpcret = callrpc("localhost", SM_PROG, SM_VERS, SM_UNMON, xdr_mon,
- &smon_id, xdr_sm_stat_res, &smstat);
+ rpcret = callrpc("localhost", SM_PROG, SM_VERS, SM_UNMON, xdr_mon,
+ &smon_id, xdr_sm_stat_res, &smstat);
- if (rpcret != 0) {
- debuglog("Rpc call to unmonitor statd failed with return value: %d\n",rpcret);
- }
-
- LIST_REMOVE(ihp, hostlst);
- free(ihp);
- }
+ if (rpcret != 0) {
+ debuglog("Rpc call to unmonitor statd failed with "
+ " return value: %d\n", rpcret);
}
+
+ LIST_REMOVE(ihp, hostlst);
+ free(ihp);
}
/*