xref: /haiku/src/add-ons/kernel/file_systems/nfs4/Cookie.cpp (revision 8b72ce26511afc3cc9984174a20f6786f0f93363)
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 len = static_cast<uint64>(lock.l_len);
56 
57 	return fStart == start && (fLength == len
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()
71 	:
72 	fRequests(NULL),
73 	fSnoozeCancel(create_sem(1, NULL))
74 {
75 	acquire_sem(fSnoozeCancel);
76 	mutex_init(&fRequestLock, NULL);
77 }
78 
79 
80 Cookie::~Cookie()
81 {
82 	delete_sem(fSnoozeCancel);
83 	mutex_destroy(&fRequestLock);
84 }
85 
86 
87 status_t
88 Cookie::RegisterRequest(RPC::Request* req)
89 {
90 	ASSERT(req != NULL);
91 
92 	RequestEntry* ent = new RequestEntry;
93 	if (ent == NULL)
94 		return B_NO_MEMORY;
95 
96 	MutexLocker _(fRequestLock);
97 	ent->fRequest = req;
98 	ent->fNext = fRequests;
99 	fRequests = ent;
100 
101 	return B_OK;
102 }
103 
104 
105 status_t
106 Cookie::UnregisterRequest(RPC::Request* req)
107 {
108 	ASSERT(req != NULL);
109 
110 	MutexLocker _(fRequestLock);
111 	RequestEntry* ent = fRequests;
112 	RequestEntry* prev = NULL;
113 	while (ent != NULL) {
114 		if (ent->fRequest == req) {
115 			if (prev == NULL)
116 				fRequests = ent->fNext;
117 			else
118 				prev->fNext = ent->fNext;
119 			delete ent;
120 		}
121 
122 		prev = ent;
123 		ent = ent->fNext;
124 	}
125 
126 	return B_OK;
127 }
128 
129 
130 status_t
131 Cookie::CancelAll()
132 {
133 	release_sem(fSnoozeCancel);
134 
135 	MutexLocker _(fRequestLock);
136 	RequestEntry* ent = fRequests;
137 	while (ent != NULL) {
138 		fFileSystem->Server()->WakeCall(ent->fRequest);
139 		ent = ent->fNext;
140 	}
141 
142 	return B_OK;
143 }
144 
145 
146 OpenFileCookie::OpenFileCookie()
147 	:
148 	fLocks(NULL)
149 {
150 }
151 
152 
153 void
154 OpenFileCookie::AddLock(LockInfo* lock)
155 {
156 	ASSERT(lock != NULL);
157 
158 	lock->fCookieNext = fLocks;
159 	fLocks = lock;
160 }
161 
162 
163 void
164 OpenFileCookie::RemoveLock(LockInfo* lock, LockInfo* prev)
165 {
166 	if (prev != NULL)
167 		prev->fCookieNext = lock->fCookieNext;
168 	else {
169 		ASSERT(prev == NULL && fLocks == lock);
170 		fLocks = lock->fCookieNext;
171 	}
172 }
173 
174 
175 OpenDirCookie::~OpenDirCookie()
176 {
177 	if (fSnapshot != NULL)
178 		fSnapshot->ReleaseReference();
179 }
180 
181