From 212de7205336baeee1889f9d5fb595e028b19a83 Mon Sep 17 00:00:00 2001 From: Pawel Dziepak Date: Thu, 31 May 2012 02:08:59 +0200 Subject: [PATCH] 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. --- .../kernel/file_systems/nfs4/Inode.cpp | 51 +++++++++++++++++++ src/add-ons/kernel/file_systems/nfs4/Inode.h | 4 ++ .../kernel/file_systems/nfs4/NFS4Defs.h | 4 +- .../file_systems/nfs4/ReplyInterpreter.cpp | 20 +++++++- .../file_systems/nfs4/kernel_interface.cpp | 37 +++++++++++++- 5 files changed, 112 insertions(+), 4 deletions(-) diff --git a/src/add-ons/kernel/file_systems/nfs4/Inode.cpp b/src/add-ons/kernel/file_systems/nfs4/Inode.cpp index eecf8358ce..80688d61d6 100644 --- a/src/add-ons/kernel/file_systems/nfs4/Inode.cpp +++ b/src/add-ons/kernel/file_systems/nfs4/Inode.cpp @@ -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; +} + diff --git a/src/add-ons/kernel/file_systems/nfs4/Inode.h b/src/add-ons/kernel/file_systems/nfs4/Inode.h index 1d878cd014..73ce182296 100644 --- a/src/add-ons/kernel/file_systems/nfs4/Inode.h +++ b/src/add-ons/kernel/file_systems/nfs4/Inode.h @@ -9,6 +9,8 @@ #define INODE_H +#include + #include #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; diff --git a/src/add-ons/kernel/file_systems/nfs4/NFS4Defs.h b/src/add-ons/kernel/file_systems/nfs4/NFS4Defs.h index 7c2f3dad2e..f9f4622fde 100644 --- a/src/add-ons/kernel/file_systems/nfs4/NFS4Defs.h +++ b/src/add-ons/kernel/file_systems/nfs4/NFS4Defs.h @@ -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 { diff --git a/src/add-ons/kernel/file_systems/nfs4/ReplyInterpreter.cpp b/src/add-ons/kernel/file_systems/nfs4/ReplyInterpreter.cpp index 4ff308137d..1cb5158609 100644 --- a/src/add-ons/kernel/file_systems/nfs4/ReplyInterpreter.cpp +++ b/src/add-ons/kernel/file_systems/nfs4/ReplyInterpreter.cpp @@ -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; diff --git a/src/add-ons/kernel/file_systems/nfs4/kernel_interface.cpp b/src/add-ons/kernel/file_systems/nfs4/kernel_interface.cpp index 078a3457d6..02214dac6e 100644 --- a/src/add-ons/kernel/file_systems/nfs4/kernel_interface.cpp +++ b/src/add-ons/kernel/file_systems/nfs4/kernel_interface.cpp @@ -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(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 = {