xref: /haiku/src/add-ons/kernel/file_systems/nfs4/Cookie.cpp (revision 870528b79923b065c9d04bc598b43a518f3cfafa)
1 /*
2  * Copyright 2012 Haiku, Inc. All rights reserved.
3  * Distributed under the terms of the MIT License.
4  *
5  * Authors:
6  *		Paweł Dziepak, pdziepak@quarnos.org
7  */
8 
9 
10 #include "Cookie.h"
11 
12 #include "Inode.h"
13 #include "Request.h"
14 
15 
16 LockOwner::LockOwner(uint32 owner)
17 	:
18 	fSequence(0),
19 	fOwner(owner),
20 	fUseCount(0),
21 	fNext(NULL),
22 	fPrev(NULL)
23 {
24 	memset(fStateId, 0, sizeof(fStateId));
25 	mutex_init(&fLock, NULL);
26 }
27 
28 
29 LockOwner::~LockOwner()
30 {
31 	mutex_destroy(&fLock);
32 }
33 
34 
35 LockInfo::LockInfo(LockOwner* owner)
36 	:
37 	fOwner(owner)
38 {
39 	fOwner->fUseCount++;
40 }
41 
42 
43 LockInfo::~LockInfo()
44 {
45 	fOwner->fUseCount--;
46 }
47 
48 
49 bool
50 LockInfo::operator==(const struct flock& lock) const
51 {
52 	bool eof = lock.l_len + lock.l_start == OFF_MAX;
53 	uint64 start = static_cast<uint64>(lock.l_start);
54 	uint64 len = static_cast<uint64>(lock.l_len);
55 
56 	return fStart == start && (fLength == len
57 		|| (eof && fLength == UINT64_MAX));
58 }
59 
60 
61 bool
62 LockInfo::operator==(const LockInfo& lock) const
63 {
64 	return fOwner == lock.fOwner && fStart == lock.fStart
65 		&& fLength == lock.fLength && fType == lock.fType;
66 }
67 
68 
69 Cookie::Cookie()
70 	:
71 	fRequests(NULL),
72 	fSnoozeCancel(create_sem(1, NULL))
73 {
74 	acquire_sem(fSnoozeCancel);
75 	mutex_init(&fRequestLock, NULL);
76 }
77 
78 
79 Cookie::~Cookie()
80 {
81 	delete_sem(fSnoozeCancel);
82 	mutex_destroy(&fRequestLock);
83 }
84 
85 
86 status_t
87 Cookie::RegisterRequest(RPC::Request* req)
88 {
89 	RequestEntry* ent = new RequestEntry;
90 	if (ent == NULL)
91 		return B_NO_MEMORY;
92 
93 	MutexLocker _(fRequestLock);
94 	ent->fRequest = req;
95 	ent->fNext = fRequests;
96 	fRequests = ent;
97 
98 	return B_OK;
99 }
100 
101 
102 status_t
103 Cookie::UnregisterRequest(RPC::Request* req)
104 {
105 	MutexLocker _(fRequestLock);
106 	RequestEntry* ent = fRequests;
107 	RequestEntry* prev = NULL;
108 	while (ent != NULL) {
109 		if (ent->fRequest == req) {
110 			if (prev == NULL)
111 				fRequests = ent->fNext;
112 			else
113 				prev->fNext = ent->fNext;
114 			delete ent;
115 		}
116 
117 		prev = ent;
118 		ent = ent->fNext;
119 	}
120 
121 	return B_OK;
122 }
123 
124 
125 status_t
126 Cookie::CancelAll()
127 {
128 	release_sem(fSnoozeCancel);
129 
130 	MutexLocker _(fRequestLock);
131 	RequestEntry* ent = fRequests;
132 	while (ent != NULL) {
133 		fFileSystem->Server()->WakeCall(ent->fRequest);
134 		ent = ent->fNext;
135 	}
136 
137 	return B_OK;
138 }
139 
140 
141 OpenFileCookie::OpenFileCookie()
142 	:
143 	fLocks(NULL)
144 {
145 }
146 
147 
148 void
149 OpenFileCookie::AddLock(LockInfo* lock)
150 {
151 	lock->fCookieNext = fLocks;
152 	fLocks = lock;
153 }
154 
155 
156 void
157 OpenFileCookie::RemoveLock(LockInfo* lock, LockInfo* prev)
158 {
159 	if (prev != NULL)
160 		prev->fCookieNext = lock->fCookieNext;
161 	else
162 		fLocks = lock->fCookieNext;
163 }
164 
165 
166 OpenDirCookie::~OpenDirCookie()
167 {
168 	if (fSnapshot != NULL)
169 		fSnapshot->ReleaseReference();
170 }
171 
172