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
LockOwner(uint32 owner)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
~LockOwner()29 LockOwner::~LockOwner()
30 {
31 mutex_destroy(&fLock);
32 }
33
34
LockInfo(LockOwner * owner)35 LockInfo::LockInfo(LockOwner* owner)
36 :
37 fOwner(owner)
38 {
39 ASSERT(owner != NULL);
40 fOwner->fUseCount++;
41 }
42
43
~LockInfo()44 LockInfo::~LockInfo()
45 {
46 fOwner->fUseCount--;
47 }
48
49
50 bool
operator ==(const struct flock & lock) const51 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
operator ==(const LockInfo & lock) const63 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
Cookie(FileSystem * fileSystem)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
~Cookie()81 Cookie::~Cookie()
82 {
83 delete_sem(fSnoozeCancel);
84 mutex_destroy(&fRequestLock);
85 }
86
87
88 status_t
RegisterRequest(RPC::Request * request)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
UnregisterRequest(RPC::Request * request)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
CancelAll()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
OpenStateCookie(FileSystem * fileSystem)148 OpenStateCookie::OpenStateCookie(FileSystem* fileSystem)
149 :
150 Cookie(fileSystem)
151 {
152 }
153
154
OpenFileCookie(FileSystem * fileSystem)155 OpenFileCookie::OpenFileCookie(FileSystem* fileSystem)
156 :
157 OpenStateCookie(fileSystem),
158 fLocks(NULL)
159 {
160 }
161
162
163 void
AddLock(LockInfo * lock)164 OpenFileCookie::AddLock(LockInfo* lock)
165 {
166 ASSERT(lock != NULL);
167
168 lock->fCookieNext = fLocks;
169 fLocks = lock;
170 }
171
172
173 void
RemoveLock(LockInfo * lock,LockInfo * previous)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
OpenDirCookie(FileSystem * fileSystem)185 OpenDirCookie::OpenDirCookie(FileSystem* fileSystem)
186 :
187 Cookie(fileSystem),
188 fSnapshot(NULL)
189 {
190 }
191
192
~OpenDirCookie()193 OpenDirCookie::~OpenDirCookie()
194 {
195 if (fSnapshot != NULL)
196 fSnapshot->ReleaseReference();
197 }
198
199
OpenAttrCookie(FileSystem * fileSystem)200 OpenAttrCookie::OpenAttrCookie(FileSystem* fileSystem)
201 :
202 OpenStateCookie(fileSystem)
203 {
204 }
205
206