2 * Copyright 2012 Haiku, Inc. All rights reserved.
3 * Distributed under the terms of the MIT License.
6 * Paweł Dziepak, pdziepak@quarnos.org
10 #include "RootInode.h"
14 #include "MetadataCache.h"
18 RootInode::RootInode()
24 mutex_init(&fInfoCacheLock
, NULL
);
28 RootInode::~RootInode()
30 free(const_cast<char*>(fName
));
31 mutex_destroy(&fInfoCacheLock
);
36 RootInode::ReadInfo(struct fs_info
* info
)
40 status_t result
= _UpdateInfo();
44 memcpy(info
, &fInfoCache
, sizeof(struct fs_info
));
51 RootInode::_UpdateInfo(bool force
)
53 if (!force
&& fInfoCacheExpire
> time(NULL
))
56 MutexLocker
_(fInfoCacheLock
);
58 if (fInfoCacheExpire
> time(NULL
))
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
,
71 req
.GetAttr(attr
, sizeof(attr
) / sizeof(Attribute
));
73 status_t result
= request
.Send();
77 ReplyInterpreter
& reply
= request
.Reply();
79 if (HandleErrors(attempt
, reply
.NFS4Error(), server
))
85 uint32 count
, next
= 0;
86 result
= reply
.GetAttr(&values
, &count
);
90 if (count
>= next
&& values
[next
].fAttribute
== FATTR4_FILES_FREE
) {
91 fInfoCache
.free_nodes
= values
[next
].fData
.fValue64
;
95 if (count
>= next
&& values
[next
].fAttribute
== FATTR4_FILES_TOTAL
) {
96 fInfoCache
.total_nodes
= values
[next
].fData
.fValue64
;
100 uint64 ioSize
= LONGLONG_MAX
;
101 if (count
>= next
&& values
[next
].fAttribute
== FATTR4_MAXREAD
) {
102 ioSize
= min_c(ioSize
, values
[next
].fData
.fValue64
);
106 if (count
>= next
&& values
[next
].fAttribute
== FATTR4_MAXWRITE
) {
107 ioSize
= min_c(ioSize
, values
[next
].fData
.fValue64
);
111 if (ioSize
== LONGLONG_MAX
)
115 fInfoCache
.io_size
= ioSize
;
116 fInfoCache
.block_size
= ioSize
;
119 if (count
>= next
&& values
[next
].fAttribute
== FATTR4_SPACE_FREE
) {
120 fInfoCache
.free_blocks
= values
[next
].fData
.fValue64
/ ioSize
;
124 if (count
>= next
&& values
[next
].fAttribute
== FATTR4_SPACE_TOTAL
) {
125 fInfoCache
.total_blocks
= values
[next
].fData
.fValue64
/ ioSize
;
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
;
150 RootInode::ProbeMigration()
154 RPC::Server
* server
= fFileSystem
->Server();
155 Request
request(server
, fFileSystem
);
156 RequestBuilder
& req
= request
.Builder();
158 req
.PutFH(fInfo
.fHandle
);
161 status_t result
= request
.Send();
165 ReplyInterpreter
& reply
= request
.Reply();
167 if (reply
.NFS4Error() == NFS4ERR_MOVED
)
170 if (HandleErrors(attempt
, reply
.NFS4Error(), server
))
179 RootInode::GetLocations(AttrValue
** attrv
)
181 ASSERT(attrv
!= NULL
);
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();
197 ReplyInterpreter
& reply
= request
.Reply();
199 if (HandleErrors(attempt
, reply
.NFS4Error(), server
))
205 result
= reply
.GetAttr(attrv
, &count
);
221 RootInode::Name() const
223 ASSERT(fName
!= NULL
);