From 941416ff8b37ee51eb663cb75c4d94e5d668766a Mon Sep 17 00:00:00 2001 From: Pawel Dziepak Date: Sat, 16 Jun 2012 18:21:16 +0200 Subject: [PATCH] nfs4: Add read_fs_info hook --- .../kernel/file_systems/nfs4/Filesystem.cpp | 74 +++++++++++++++++++ .../kernel/file_systems/nfs4/Filesystem.h | 4 + .../file_systems/nfs4/ReplyInterpreter.cpp | 36 +++++++++ .../file_systems/nfs4/kernel_interface.cpp | 10 ++- 4 files changed, 123 insertions(+), 1 deletion(-) diff --git a/src/add-ons/kernel/file_systems/nfs4/Filesystem.cpp b/src/add-ons/kernel/file_systems/nfs4/Filesystem.cpp index be5524171b..2913418884 100644 --- a/src/add-ons/kernel/file_systems/nfs4/Filesystem.cpp +++ b/src/add-ons/kernel/file_systems/nfs4/Filesystem.cpp @@ -142,3 +142,77 @@ Filesystem::CreateRootInode() return NULL; } + +status_t +Filesystem::ReadInfo(struct fs_info* info) +{ + Request request(fServer); + RequestBuilder& req = request.Builder(); + + req.PutFH(fRootFH); + Attribute attr[] = { FATTR4_FILES_FREE, FATTR4_FILES_TOTAL, + FATTR4_MAXREAD, FATTR4_MAXWRITE, FATTR4_SPACE_FREE, + FATTR4_SPACE_TOTAL }; + req.GetAttr(attr, sizeof(attr) / sizeof(Attribute)); + + status_t result = request.Send(); + if (result != B_OK) + return result; + + ReplyInterpreter& reply = request.Reply(); + + result = reply.PutFH(); + if (result != B_OK) + return result; + + AttrValue* values; + uint32 count, next = 0; + result = reply.GetAttr(&values, &count); + if (result != B_OK) + return result; + + if (count >= next && values[next].fAttribute == FATTR4_FILES_FREE) { + info->free_nodes = values[next].fData.fValue64; + next++; + } + + if (count >= next && values[next].fAttribute == FATTR4_FILES_TOTAL) { + info->total_nodes = values[next].fData.fValue64; + next++; + } + + uint64 io_size = LONGLONG_MAX; + if (count >= next && values[next].fAttribute == FATTR4_MAXREAD) { + io_size = min_c(io_size, values[next].fData.fValue64); + next++; + } + + if (count >= next && values[next].fAttribute == FATTR4_MAXWRITE) { + io_size = min_c(io_size, values[next].fData.fValue64); + next++; + } + + if (io_size == LONGLONG_MAX) + io_size = 32768; + info->io_size = io_size; + info->block_size = io_size; + + if (count >= next && values[next].fAttribute == FATTR4_SPACE_FREE) { + info->free_blocks = values[next].fData.fValue64 / io_size; + next++; + } + + if (count >= next && values[next].fAttribute == FATTR4_SPACE_TOTAL) { + info->total_blocks = values[next].fData.fValue64 / io_size; + next++; + } + + info->flags = B_FS_IS_READONLY; + const char* name = strrchr(fPath, '/'); + if (name != NULL) + name++; + strncpy(info->volume_name, name, B_FILE_NAME_LENGTH); + + return B_OK; +} + diff --git a/src/add-ons/kernel/file_systems/nfs4/Filesystem.h b/src/add-ons/kernel/file_systems/nfs4/Filesystem.h index 2d1d076a94..7000f4bd59 100644 --- a/src/add-ons/kernel/file_systems/nfs4/Filesystem.h +++ b/src/add-ons/kernel/file_systems/nfs4/Filesystem.h @@ -9,6 +9,8 @@ #define FILESYSTEM_H +#include + #include "InodeIdMap.h" #include "NFS4Defs.h" #include "NFS4Server.h" @@ -26,6 +28,8 @@ public: status_t GetInode(ino_t id, Inode** inode); Inode* CreateRootInode(); + status_t ReadInfo(struct fs_info* info); + inline RPC::Server* Server(); inline NFS4Server* NFSServer(); diff --git a/src/add-ons/kernel/file_systems/nfs4/ReplyInterpreter.cpp b/src/add-ons/kernel/file_systems/nfs4/ReplyInterpreter.cpp index 756e7239a5..cd9378f523 100644 --- a/src/add-ons/kernel/file_systems/nfs4/ReplyInterpreter.cpp +++ b/src/add-ons/kernel/file_systems/nfs4/ReplyInterpreter.cpp @@ -349,6 +349,30 @@ ReplyInterpreter::_DecodeAttrs(XDR::ReadStream& str, AttrValue** attrs, current++; } + if (sIsAttrSet(FATTR4_FILES_FREE, bitmap, bcount)) { + values[current].fAttribute = FATTR4_FILES_FREE; + values[current].fData.fValue64 = stream.GetUHyper(); + current++; + } + + if (sIsAttrSet(FATTR4_FILES_TOTAL, bitmap, bcount)) { + values[current].fAttribute = FATTR4_FILES_TOTAL; + values[current].fData.fValue64 = stream.GetUHyper(); + current++; + } + + if (sIsAttrSet(FATTR4_MAXREAD, bitmap, bcount)) { + values[current].fAttribute = FATTR4_MAXREAD; + values[current].fData.fValue64 = stream.GetUHyper(); + current++; + } + + if (sIsAttrSet(FATTR4_MAXWRITE, bitmap, bcount)) { + values[current].fAttribute = FATTR4_MAXWRITE; + values[current].fData.fValue64 = stream.GetUHyper(); + current++; + } + if (sIsAttrSet(FATTR4_MODE, bitmap, bcount)) { values[current].fAttribute = FATTR4_MODE; values[current].fData.fValue32 = stream.GetUInt(); @@ -361,6 +385,18 @@ ReplyInterpreter::_DecodeAttrs(XDR::ReadStream& str, AttrValue** attrs, current++; } + if (sIsAttrSet(FATTR4_SPACE_FREE, bitmap, bcount)) { + values[current].fAttribute = FATTR4_SPACE_FREE; + values[current].fData.fValue64 = stream.GetUHyper(); + current++; + } + + if (sIsAttrSet(FATTR4_SPACE_TOTAL, bitmap, bcount)) { + values[current].fAttribute = FATTR4_SPACE_TOTAL; + values[current].fData.fValue64 = stream.GetUHyper(); + current++; + } + if (sIsAttrSet(FATTR4_TIME_ACCESS, bitmap, bcount)) { values[current].fAttribute = FATTR4_TIME_ACCESS; values[current].fFreePointer = true; 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 bd44f8dffd..281fe9b371 100644 --- a/src/add-ons/kernel/file_systems/nfs4/kernel_interface.cpp +++ b/src/add-ons/kernel/file_systems/nfs4/kernel_interface.cpp @@ -112,6 +112,14 @@ nfs4_unmount(fs_volume* volume) } +static status_t +nfs4_read_fs_info(fs_volume* volume, struct fs_info* info) +{ + Filesystem* fs = reinterpret_cast(volume->private_volume); + return fs->ReadInfo(info); +} + + static status_t nfs4_lookup(fs_volume* volume, fs_vnode* dir, const char* name, ino_t* _id) { @@ -323,7 +331,7 @@ nfs4_std_ops(int32 op, ...) fs_volume_ops gNFSv4VolumeOps = { nfs4_unmount, - NULL, + nfs4_read_fs_info, NULL, NULL, nfs4_get_vnode,