nfs4: Add basic nfs4_read_stat() procedure

Not all data are retrieved and there is a room for improvement in handling
situations when server does not provide necessary information.
This commit is contained in:
Pawel Dziepak 2012-05-31 02:08:59 +02:00
parent d38e98d806
commit 212de72053
5 changed files with 112 additions and 4 deletions

View File

@ -56,3 +56,54 @@ Inode::Inode(Filesystem* fs, const Filehandle &fh)
delete values;
}
status_t
Inode::Stat(struct stat* st)
{
RequestBuilder req(ProcCompound);
req.PutFH(fHandle);
Attribute attr[] = { FATTR4_SIZE, FATTR4_MODE, FATTR4_NUMLINKS };
req.GetAttr(attr, sizeof(attr) / sizeof(Attribute));
RPC::Reply *rpl;
fFilesystem->Server()->SendCall(req.Request(), &rpl);
ReplyInterpreter reply(rpl);
status_t result;
result = reply.PutFH();
if (result != B_OK)
return result;
AttrValue* values;
uint32 count;
result = reply.GetAttr(&values, &count);
if (result != B_OK)
return result;
// FATTR4_SIZE is mandatory
if (count < 1 || values[0].fAttribute != FATTR4_SIZE)
return B_BAD_VALUE;
st->st_size = values[0].fData.fValue64;
uint32 next = 1;
st->st_mode = Type();
if (count >= next && values[next].fAttribute == FATTR4_MODE) {
st->st_mode |= values[next].fData.fValue32;
next++;
}
// TODO: else: get some info from ACCESS
if (count >= next && values[next].fAttribute == FATTR4_NUMLINKS) {
st->st_nlink = values[next].fData.fValue32;
next++;
} else
st->st_nlink = 1; // TODO: if !link_support we dont have to ask
st->st_uid = 0;
st->st_gid = 0;
delete values;
return B_OK;
}

View File

@ -9,6 +9,8 @@
#define INODE_H
#include <sys/stat.h>
#include <SupportDefs.h>
#include "Filesystem.h"
@ -22,6 +24,8 @@ public:
inline ino_t ID() const;
inline mode_t Type() const;
status_t Stat(struct stat* st);
private:
uint64 fFileId;
uint32 fType;

View File

@ -119,8 +119,8 @@ enum FileType {
};
static const mode_t sNFSFileTypeToHaiku[] = {
S_IFREG, S_IFDIR, S_IFBLK, S_IFCHR, S_IFLNK, S_IFSOCK, S_IFIFO, S_IFDIR,
S_IFREG
S_IFREG, S_IFREG, S_IFDIR, S_IFBLK, S_IFCHR, S_IFLNK, S_IFSOCK, S_IFIFO,
S_IFDIR, S_IFREG
};
enum FileHandleExpiryType {

View File

@ -83,7 +83,7 @@ ReplyInterpreter::GetAttr(AttrValue** attrs, uint32* count)
uint32 attr_count = 0;
for (uint32 i = 0; i < bcount; i++) {
bitmap[i] = fReply->Stream().GetUInt();
attr_count = sCountBits(bitmap[i]);
attr_count += sCountBits(bitmap[i]);
}
uint32 size;
@ -110,12 +110,30 @@ ReplyInterpreter::GetAttr(AttrValue** attrs, uint32* count)
current++;
}
if (sIsAttrSet(FATTR4_SIZE, bitmap, bcount)) {
values[current].fAttribute = FATTR4_SIZE;
values[current].fData.fValue64 = stream.GetUHyper();
current++;
}
if (sIsAttrSet(FATTR4_FILEID, bitmap, bcount)) {
values[current].fAttribute = FATTR4_FILEID;
values[current].fData.fValue64 = stream.GetUHyper();
current++;
}
if (sIsAttrSet(FATTR4_MODE, bitmap, bcount)) {
values[current].fAttribute = FATTR4_MODE;
values[current].fData.fValue32 = stream.GetUInt();
current++;
}
if (sIsAttrSet(FATTR4_NUMLINKS, bitmap, bcount)) {
values[current].fAttribute = FATTR4_NUMLINKS;
values[current].fData.fValue32 = stream.GetUInt();
current++;
}
delete bitmap;
*count = attr_count;

View File

@ -79,6 +79,14 @@ nfs4_put_vnode(fs_volume* volume, fs_vnode* vnode, bool reenter)
}
static status_t
nfs4_read_stat(fs_volume* volume, fs_vnode* vnode, struct stat* stat)
{
Inode* inode = reinterpret_cast<Inode*>(vnode->private_node);
return inode->Stat(stat);
}
status_t
nfs4_init()
{
@ -130,7 +138,34 @@ fs_volume_ops gNFSv4VolumeOps = {
fs_vnode_ops gNFSv4VnodeOps = {
NULL, // lookup()
NULL, // get_vnode_name()
&nfs4_put_vnode
&nfs4_put_vnode,
NULL, // remove_vnode()
/* VM file access */
NULL, // can_page()
NULL, // read_pages()
NULL, // write_pages()
NULL, // io()
NULL, // cancel_io()
NULL, // get_file_map()
NULL, // ioctl()
NULL,
NULL, // fs_select()
NULL, // fs_deselect()
NULL, // fsync()
NULL, // read_link()
NULL, // create_symlink()
NULL, // link()
NULL, // unlink()
NULL, // rename()
NULL, // access()
&nfs4_read_stat,
};
static file_system_module_info sNFSv4ModuleInfo = {