BPicture: Fix archive constructor.
[haiku.git] / src / add-ons / kernel / file_systems / nfs4 / RootInode.cpp
blob627eede6737ccf2aaed38d6c0fe11ef944b76f58
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 "RootInode.h"
12 #include <string.h>
14 #include "MetadataCache.h"
15 #include "Request.h"
18 RootInode::RootInode()
20 fInfoCacheExpire(0),
21 fName(NULL),
22 fIOSize(0)
24 mutex_init(&fInfoCacheLock, NULL);
28 RootInode::~RootInode()
30 free(const_cast<char*>(fName));
31 mutex_destroy(&fInfoCacheLock);
35 status_t
36 RootInode::ReadInfo(struct fs_info* info)
38 ASSERT(info != NULL);
40 status_t result = _UpdateInfo();
41 if (result != B_OK)
42 return result;
44 memcpy(info, &fInfoCache, sizeof(struct fs_info));
46 return B_OK;
50 status_t
51 RootInode::_UpdateInfo(bool force)
53 if (!force && fInfoCacheExpire > time(NULL))
54 return B_OK;
56 MutexLocker _(fInfoCacheLock);
58 if (fInfoCacheExpire > time(NULL))
59 return B_OK;
61 uint32 attempt = 0;
62 do {
63 RPC::Server* server = fFileSystem->Server();
64 Request request(server, fFileSystem);
65 RequestBuilder& req = request.Builder();
67 req.PutFH(fInfo.fHandle);
68 Attribute attr[] = { FATTR4_FILES_FREE, FATTR4_FILES_TOTAL,
69 FATTR4_MAXREAD, FATTR4_MAXWRITE, FATTR4_SPACE_FREE,
70 FATTR4_SPACE_TOTAL };
71 req.GetAttr(attr, sizeof(attr) / sizeof(Attribute));
73 status_t result = request.Send();
74 if (result != B_OK)
75 return result;
77 ReplyInterpreter& reply = request.Reply();
79 if (HandleErrors(attempt, reply.NFS4Error(), server))
80 continue;
82 reply.PutFH();
84 AttrValue* values;
85 uint32 count, next = 0;
86 result = reply.GetAttr(&values, &count);
87 if (result != B_OK)
88 return result;
90 if (count >= next && values[next].fAttribute == FATTR4_FILES_FREE) {
91 fInfoCache.free_nodes = values[next].fData.fValue64;
92 next++;
95 if (count >= next && values[next].fAttribute == FATTR4_FILES_TOTAL) {
96 fInfoCache.total_nodes = values[next].fData.fValue64;
97 next++;
100 uint64 ioSize = LONGLONG_MAX;
101 if (count >= next && values[next].fAttribute == FATTR4_MAXREAD) {
102 ioSize = min_c(ioSize, values[next].fData.fValue64);
103 next++;
106 if (count >= next && values[next].fAttribute == FATTR4_MAXWRITE) {
107 ioSize = min_c(ioSize, values[next].fData.fValue64);
108 next++;
111 if (ioSize == LONGLONG_MAX)
112 ioSize = 32768;
113 if (ioSize == 0)
114 ioSize = 4096;
115 fInfoCache.io_size = ioSize;
116 fInfoCache.block_size = ioSize;
117 fIOSize = ioSize;
119 if (count >= next && values[next].fAttribute == FATTR4_SPACE_FREE) {
120 fInfoCache.free_blocks = values[next].fData.fValue64 / ioSize;
121 next++;
124 if (count >= next && values[next].fAttribute == FATTR4_SPACE_TOTAL) {
125 fInfoCache.total_blocks = values[next].fData.fValue64 / ioSize;
126 next++;
129 delete[] values;
131 break;
132 } while (true);
134 fInfoCache.flags = B_FS_IS_PERSISTENT | B_FS_IS_SHARED
135 | B_FS_SUPPORTS_NODE_MONITORING;
137 if (fFileSystem->NamedAttrs()
138 || fFileSystem->GetConfiguration().fEmulateNamedAttrs)
139 fInfoCache.flags |= B_FS_HAS_MIME | B_FS_HAS_ATTR;
141 strlcpy(fInfoCache.volume_name, fName, sizeof(fInfoCache.volume_name));
143 fInfoCacheExpire = time(NULL) + MetadataCache::kExpirationTime;
145 return B_OK;
149 bool
150 RootInode::ProbeMigration()
152 uint32 attempt = 0;
153 do {
154 RPC::Server* server = fFileSystem->Server();
155 Request request(server, fFileSystem);
156 RequestBuilder& req = request.Builder();
158 req.PutFH(fInfo.fHandle);
159 req.Access();
161 status_t result = request.Send();
162 if (result != B_OK)
163 continue;
165 ReplyInterpreter& reply = request.Reply();
167 if (reply.NFS4Error() == NFS4ERR_MOVED)
168 return true;
170 if (HandleErrors(attempt, reply.NFS4Error(), server))
171 continue;
173 return false;
174 } while (true);
178 status_t
179 RootInode::GetLocations(AttrValue** attrv)
181 ASSERT(attrv != NULL);
183 uint32 attempt = 0;
184 do {
185 RPC::Server* server = fFileSystem->Server();
186 Request request(server, fFileSystem);
187 RequestBuilder& req = request.Builder();
189 req.PutFH(fInfo.fHandle);
190 Attribute attr[] = { FATTR4_FS_LOCATIONS };
191 req.GetAttr(attr, sizeof(attr) / sizeof(Attribute));
193 status_t result = request.Send();
194 if (result != B_OK)
195 return result;
197 ReplyInterpreter& reply = request.Reply();
199 if (HandleErrors(attempt, reply.NFS4Error(), server))
200 continue;
202 reply.PutFH();
204 uint32 count;
205 result = reply.GetAttr(attrv, &count);
206 if (result != B_OK)
207 return result;
208 if (count < 1) {
209 delete[] *attrv;
210 return B_ERROR;
213 return B_OK;
214 } while (true);
216 return B_OK;
220 const char*
221 RootInode::Name() const
223 ASSERT(fName != NULL);
224 return fName;