1
/*********************************************************
2
* Copyright (C) 2008 VMware, Inc. All rights reserved.
4
* This program is free software; you can redistribute it and/or modify it
5
* under the terms of the GNU General Public License as published by the
6
* Free Software Foundation version 2 and no later version.
8
* This program is distributed in the hope that it will be useful, but
9
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
10
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13
* You should have received a copy of the GNU General Public License along
14
* with this program; if not, write to the Free Software Foundation, Inc.,
15
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17
*********************************************************/
22
* Common VFS vfsop implementations that are shared between both OS X and FreeBSD.
25
#include <sys/param.h> // for everything
26
#include <sys/vnode.h> // for struct vnode
32
#include "vnopscommon.h"
33
#include "vfsopscommon.h"
36
*----------------------------------------------------------------------------
40
* Hgfs statfs method. Called by HgfsVfsStatfs on FreeBSD and
41
* HgfsVfsGetattr on OS X.
44
* Returns 0 on success and an error code on error.
49
*----------------------------------------------------------------------------
53
HgfsStatfsInt(struct vnode *vp, // IN: vnode
54
HgfsStatfs *stat) // IN: statfs structure to fill in
58
HgfsRequest *requestHeader;
59
HgfsReply *replyHeader;
60
HgfsRequestQueryVolumeV3 *request;
61
HgfsReplyQueryVolumeV3 *reply;
65
char *fullPath = NULL;
69
/* Get pointer to the superinfo. */
70
sip = HGFS_VP_TO_SIP(vp);
72
DEBUG(VM_DEBUG_FAIL, "couldn't acquire superinfo\n");
76
/* Prepare the request */
77
req = HgfsKReq_AllocateRequest(sip->reqs);
82
requestHeader = (HgfsRequest *)HgfsKReq_GetPayload(req);
83
request = (HgfsRequestQueryVolumeV3 *)HGFS_REQ_GET_PAYLOAD_V3(requestHeader);
85
/* Initialize the request header */
86
requestHeader->id = HgfsKReq_GetId(req);
87
requestHeader->op = HGFS_OP_QUERY_VOLUME_INFO_V3;
89
request->fileName.flags = 0;
90
request->fileName.fid = HGFS_INVALID_HANDLE;
91
request->fileName.caseType = HGFS_FILE_NAME_CASE_SENSITIVE;
92
request->reserved = 0;
94
reqSize = HGFS_REQ_PAYLOAD_SIZE_V3(request);
95
reqBufferSize = HGFS_NAME_BUFFER_SIZET(reqSize);
97
fullPath = HGFS_VP_TO_FILENAME(vp);
98
fullPathLen = HGFS_VP_TO_FILENAME_LENGTH(vp);
100
ret = HgfsNameToWireEncoding(fullPath, fullPathLen + 1,
101
request->fileName.name,
104
DEBUG(VM_DEBUG_FAIL, "Could not encode to wire format");
108
request->fileName.length = ret;
111
/* The request size includes header, request and file length */
112
HgfsKReq_SetPayloadSize(req, reqSize);
114
ret = HgfsSubmitRequest(sip, req);
117
/* HgfsSubmitRequest() destroys the request if necessary */
122
replyHeader = (HgfsReply *)HgfsKReq_GetPayload(req);
123
reply = (HgfsReplyQueryVolumeV3 *)HGFS_REP_GET_PAYLOAD_V3(replyHeader);
124
repSize = HGFS_REP_PAYLOAD_SIZE_V3(reply);
126
ret = HgfsGetStatus(req, repSize);
128
DEBUG(VM_DEBUG_FAIL, "reply was invalid");
132
ret = HgfsStatusToBSD(replyHeader->status);
138
stat->f_bsize = HGFS_BLOCKSIZE;
139
stat->f_iosize = HGFS_BLOCKSIZE;
140
stat->f_blocks = HGFS_CONVERT_TO_BLOCKS(reply->totalBytes);
141
stat->f_bfree = HGFS_CONVERT_TO_BLOCKS(reply->freeBytes);
142
stat->f_bavail = stat->f_bfree;
145
HgfsKReq_ReleaseRequest(sip->reqs, req);