xref: /haiku/src/add-ons/kernel/file_systems/nfs4/Cookie.cpp (revision d4eea7d43cf24aa5174f40958575c5ce439a84ec)
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 			break;
121 		}
122 
123 		prev = ent;
124 		ent = ent->fNext;
125 	}
126 
127 	return B_OK;
128 }
129 
130 
131 status_t
132 Cookie::CancelAll()
133 {
134 	release_sem(fSnoozeCancel);
135 
136 	MutexLocker _(fRequestLock);
137 	RequestEntry* ent = fRequests;
138 	while (ent != NULL) {
139 		fFileSystem->Server()->WakeCall(ent->fRequest);
140 		ent = ent->fNext;
141 	}
142 
143 	return B_OK;
144 }
145 
146 
147 OpenFileCookie::OpenFileCookie()
148 	:
149 	fLocks(NULL)
150 {
151 }
152 
153 
154 void
155 OpenFileCookie::AddLock(LockInfo* lock)
156 {
157 	ASSERT(lock != NULL);
158 
159 	lock->fCookieNext = fLocks;
160 	fLocks = lock;
161 }
162 
163 
164 void
165 OpenFileCookie::RemoveLock(LockInfo* lock, LockInfo* prev)
166 {
167 	if (prev != NULL)
168 		prev->fCookieNext = lock->fCookieNext;
169 	else {
170 		ASSERT(prev == NULL && fLocks == lock);
171 		fLocks = lock->fCookieNext;
172 	}
173 }
174 
175 
176 OpenDirCookie::~OpenDirCookie()
177 {
178 	if (fSnapshot != NULL)
179 		fSnapshot->ReleaseReference();
180 }
181 
182