xref: /haiku/src/add-ons/kernel/file_systems/nfs4/Cookie.cpp (revision 1e60bdeab63fa7a57bc9a55b032052e95a18bd2c)
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 	ASSERT(owner != NULL);
40 	fOwner->fUseCount++;
41 }
42 
43 
44 LockInfo::~LockInfo()
45 {
46 	fOwner->fUseCount--;
47 }
48 
49 
50 bool
51 LockInfo::operator==(const struct flock& lock) const
52 {
53 	bool eof = lock.l_len + lock.l_start == OFF_MAX;
54 	uint64 start = static_cast<uint64>(lock.l_start);
55 	uint64 length = static_cast<uint64>(lock.l_len);
56 
57 	return fStart == start && (fLength == length
58 		|| (eof && fLength == UINT64_MAX));
59 }
60 
61 
62 bool
63 LockInfo::operator==(const LockInfo& lock) const
64 {
65 	return fOwner == lock.fOwner && fStart == lock.fStart
66 		&& fLength == lock.fLength && fType == lock.fType;
67 }
68 
69 
70 Cookie::Cookie(FileSystem* fileSystem)
71 	:
72 	fFileSystem(fileSystem),
73 	fRequests(NULL),
74 	fSnoozeCancel(create_sem(1, NULL))
75 {
76 	acquire_sem(fSnoozeCancel);
77 	mutex_init(&fRequestLock, NULL);
78 }
79 
80 
81 Cookie::~Cookie()
82 {
83 	delete_sem(fSnoozeCancel);
84 	mutex_destroy(&fRequestLock);
85 }
86 
87 
88 status_t
89 Cookie::RegisterRequest(RPC::Request* request)
90 {
91 	ASSERT(request != NULL);
92 
93 	RequestEntry* entry = new RequestEntry;
94 	if (entry == NULL)
95 		return B_NO_MEMORY;
96 
97 	MutexLocker _(fRequestLock);
98 	entry->fRequest = request;
99 	entry->fNext = fRequests;
100 	fRequests = entry;
101 
102 	return B_OK;
103 }
104 
105 
106 status_t
107 Cookie::UnregisterRequest(RPC::Request* request)
108 {
109 	ASSERT(request != NULL);
110 
111 	MutexLocker _(fRequestLock);
112 	RequestEntry* entry = fRequests;
113 	RequestEntry* previous = NULL;
114 	while (entry != NULL) {
115 		if (entry->fRequest == request) {
116 			if (previous == NULL)
117 				fRequests = entry->fNext;
118 			else
119 				previous->fNext = entry->fNext;
120 			delete entry;
121 			break;
122 		}
123 
124 		previous = entry;
125 		entry = entry->fNext;
126 	}
127 
128 	return B_OK;
129 }
130 
131 
132 status_t
133 Cookie::CancelAll()
134 {
135 	release_sem(fSnoozeCancel);
136 
137 	MutexLocker _(fRequestLock);
138 	RequestEntry* entry = fRequests;
139 	while (entry != NULL) {
140 		fFileSystem->Server()->WakeCall(entry->fRequest);
141 		entry = entry->fNext;
142 	}
143 
144 	return B_OK;
145 }
146 
147 
148 OpenStateCookie::OpenStateCookie(FileSystem* fileSystem)
149 	:
150 	Cookie(fileSystem)
151 {
152 }
153 
154 
155 OpenFileCookie::OpenFileCookie(FileSystem* fileSystem)
156 	:
157 	OpenStateCookie(fileSystem),
158 	fLocks(NULL)
159 {
160 }
161 
162 
163 void
164 OpenFileCookie::AddLock(LockInfo* lock)
165 {
166 	ASSERT(lock != NULL);
167 
168 	lock->fCookieNext = fLocks;
169 	fLocks = lock;
170 }
171 
172 
173 void
174 OpenFileCookie::RemoveLock(LockInfo* lock, LockInfo* previous)
175 {
176 	if (previous != NULL)
177 		previous->fCookieNext = lock->fCookieNext;
178 	else {
179 		ASSERT(previous == NULL && fLocks == lock);
180 		fLocks = lock->fCookieNext;
181 	}
182 }
183 
184 
185 OpenDirCookie::OpenDirCookie(FileSystem* fileSystem)
186 	:
187 	Cookie(fileSystem),
188 	fSnapshot(NULL)
189 {
190 }
191 
192 
193 OpenDirCookie::~OpenDirCookie()
194 {
195 	if (fSnapshot != NULL)
196 		fSnapshot->ReleaseReference();
197 }
198 
199 
200 OpenAttrCookie::OpenAttrCookie(FileSystem* fileSystem)
201 	:
202 	OpenStateCookie(fileSystem)
203 {
204 }
205 
206