BPicture: Fix archive constructor.
[haiku.git] / src / add-ons / kernel / file_systems / nfs4 / FileInfo.cpp
blob45f002d2021f249f6739e73ce21545d4f3c57c96
1 /*
2 * Copyright 2012 Haiku, Inc. All rights reserved.
3 * Distributed under the terms of the MIT License.
5 * Authors:
6 * Paweł Dziepak, pdziepak@quarnos.org
7 */
10 #include "FileInfo.h"
12 #include "FileSystem.h"
13 #include "Request.h"
16 InodeName::InodeName(InodeNames* parent, const char* name)
18 fParent(parent),
19 fName(strdup(name))
21 if (fParent != NULL)
22 fParent->AcquireReference();
26 InodeName::~InodeName()
28 if (fParent != NULL)
29 fParent->ReleaseReference();
30 free(const_cast<char*>(fName));
34 InodeNames::InodeNames()
36 mutex_init(&fLock, NULL);
40 InodeNames::~InodeNames()
42 while (!fNames.IsEmpty())
43 delete fNames.RemoveHead();
44 mutex_destroy(&fLock);
48 status_t
49 InodeNames::AddName(InodeNames* parent, const char* name)
51 MutexLocker _(fLock);
53 InodeName* current = fNames.Head();
54 while (current != NULL) {
55 if (current->fParent == parent && !strcmp(current->fName, name))
56 return B_OK;
57 current = fNames.GetNext(current);
60 InodeName* newName = new InodeName(parent, name);
61 if (newName == NULL)
62 return B_NO_MEMORY;
63 fNames.Add(newName);
64 return B_OK;
68 bool
69 InodeNames::RemoveName(InodeNames* parent, const char* name)
71 MutexLocker _(fLock);
73 InodeName* previous = NULL;
74 InodeName* current = fNames.Head();
75 while (current != NULL) {
76 if (current->fParent == parent && !strcmp(current->fName, name)) {
77 fNames.Remove(previous, current);
78 delete current;
79 break;
82 previous = current;
83 current = fNames.GetNext(current);
86 return fNames.IsEmpty();
90 FileInfo::FileInfo()
92 fFileId(0),
93 fNames(NULL)
98 FileInfo::~FileInfo()
100 if (fNames != NULL)
101 fNames->ReleaseReference();
105 FileInfo::FileInfo(const FileInfo& fi)
107 fFileId(fi.fFileId),
108 fHandle(fi.fHandle),
109 fNames(fi.fNames)
111 if (fNames != NULL)
112 fNames->AcquireReference();
116 FileInfo&
117 FileInfo::operator=(const FileInfo& fi)
119 fFileId = fi.fFileId;
120 fHandle = fi.fHandle;
122 if (fNames != NULL)
123 fNames->ReleaseReference();
124 fNames = fi.fNames;
125 if (fNames != NULL)
126 fNames->AcquireReference();
128 return *this;
132 status_t
133 FileInfo::UpdateFileHandles(FileSystem* fs)
135 ASSERT(fs != NULL);
137 Request request(fs->Server(), fs);
138 RequestBuilder& req = request.Builder();
140 req.PutRootFH();
142 uint32 lookupCount = 0;
143 const char** path = fs->Path();
144 if (path != NULL) {
145 for (; path[lookupCount] != NULL; lookupCount++)
146 req.LookUp(path[lookupCount]);
149 uint32 i;
150 InodeNames* names = fNames;
151 for (i = 0; names != NULL; i++) {
152 if (names->fNames.IsEmpty())
153 return B_ENTRY_NOT_FOUND;
155 names = names->fNames.Head()->fParent;
158 if (i > 0) {
159 names = fNames;
160 InodeNames** pathNames = new InodeNames*[i];
161 if (pathNames == NULL)
162 return B_NO_MEMORY;
164 for (i = 0; names != NULL; i++) {
165 pathNames[i] = names;
166 names = names->fNames.Head()->fParent;
169 for (; i > 0; i--) {
170 if (!strcmp(pathNames[i - 1]->fNames.Head()->fName, ""))
171 continue;
173 req.LookUp(pathNames[i - 1]->fNames.Head()->fName);
174 lookupCount++;
176 delete[] pathNames;
179 req.GetFH();
181 if (fs->IsAttrSupported(FATTR4_FILEID)) {
182 AttrValue attr;
183 attr.fAttribute = FATTR4_FILEID;
184 attr.fFreePointer = false;
185 attr.fData.fValue64 = fFileId;
186 req.Verify(&attr, 1);
189 status_t result = request.Send();
190 if (result != B_OK)
191 return result;
193 ReplyInterpreter& reply = request.Reply();
195 reply.PutRootFH();
196 for (uint32 i = 0; i < lookupCount; i++)
197 reply.LookUp();
199 FileHandle handle;
200 result = reply.GetFH(&handle);
201 if (result != B_OK)
202 return result;
204 if (fs->IsAttrSupported(FATTR4_FILEID)) {
205 result = reply.Verify();
206 if (result != B_OK)
207 return result;
210 fHandle = handle;
211 fNames->fHandle = handle;
213 return B_OK;