summaryrefslogtreecommitdiff
path: root/open-vm-tools/modules/solaris/vmhgfs/hgfsState.h
blob: 9fc349a4ace88107a416d54e1d616c4d0d0c48d7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
/*********************************************************
 * Copyright (C) 2004-2015 VMware, Inc. All rights reserved.
 *
 * The contents of this file are subject to the terms of the Common
 * Development and Distribution License (the "License") version 1.0
 * and no later version.  You may not use this file except in
 * compliance with the License.
 *
 * You can obtain a copy of the License at
 *         http://www.opensource.org/licenses/cddl1.php
 *
 * See the License for the specific language governing permissions
 * and limitations under the License.
 *
 *********************************************************/

/*
 * hgfsState.h --
 *
 * Public functions, types, and macros for Hgfs state that is attached to
 * vnodes.
 */

#ifndef __HGFS_STATE_H_
#define __HGFS_STATE_H_

/*
 * Includes
 */
#include <sys/param.h>          /* MAXPATHLEN */
#include <sys/rwlock.h>         /* krwlock_t */
#include <sys/ksynch.h>         /* kmutex_t */
#include <sys/vnode.h>          /* struct vnode */

#include "hgfsProto.h"
#include "dbllnklst.h"


/*
 * Macros
 */
/* Number of buckets for the HgfsInode hash table */
#define HGFS_HT_NR_BUCKETS             5

/* Conversion between different state structures */
#define HGFS_VP_TO_OFP(vp)      ((HgfsOpenFile *)(vp)->v_data)
#define HGFS_VP_TO_FP(vp)       ((HgfsFile *)(HGFS_VP_TO_OFP(vp))->hgfsFile)
#define HGFS_OFP_TO_VP(ofp)     (ofp)->vnodep

#define HGFS_VP_TO_FILENAME(vp)                         \
         HGFS_VP_TO_FP(vp)->fileName

#define HGFS_VP_TO_FILENAME_LENGTH(vp)                  \
         HGFS_VP_TO_FP(vp)->fileNameLength

#define HGFS_VP_TO_NODEID(vp)                           \
         HGFS_VP_TO_FP(vp)->nodeId

#define HGFS_VP_TO_RWLOCK(vp)                           \
         HGFS_VP_TO_FP(vp)->rwlock

#define HGFS_VP_TO_RWLOCKP(vp)  &(HGFS_VP_TO_RWLOCK(vp))

#define HGFS_VP_TO_HGFSFILETYPE(vp)                     \
         HGFS_VP_TO_FP(vp)->fileType

/*
 * This macro is used for sanity checking the fact that Solaris won't ever call
 * one of our vnode operations without first calling lookup(), which is the
 * place where we acquire the filename.  I have never seen a function fail
 * because of this, so it is likely that we can kill this macro and the checks
 * on it throughout vnode.c.
 */
#define HGFS_KNOW_FILENAME(vp)                          \
         (                                              \
          vp &&                                         \
          HGFS_VP_TO_FP(vp) &&                          \
          HGFS_VP_TO_FP(vp)->fileName[0] != '\0'        \
         )

/*
 * Types
 */

typedef uint32_t HgfsMode;

/*
 * State kept per shared file from the host.
 *
 * All fields are read-only after initialization except reference count, which
 * is protected by the mutex.
 */
typedef struct HgfsFile {
   /* Link to place this state on the file state hash table */
   DblLnkLst_Links listNode;
   /*
    * Full path of file within the filesystem (that is, taking /mnt/hgfs as /).
    * These are built from / in HgfsMount() and appending names as provided to
    * HgfsLookup(). Saving the length in HgfsIget() saves having to calculate
    * it in each HgfsMakeFullName().
    */
   char fileName[MAXPATHLEN + 1];
   uint32_t fileNameLength;
   ino64_t nodeId;
   /*
    * The file type is saved so additional per-open-file vnodes can be
    * recreated from a Hgfs file without sending a request to the Hgfs server.
    */
   HgfsFileType fileType;
   /*
    * Readers/writers lock for this file.  Needed by rwlock() and rwunlock()
    * entry points.
    */
   krwlock_t rwlock;
   /* Lock to protect the reference count of this file state. */
   kmutex_t mutex;
   uint32_t refCount;
} HgfsFile;


/*
 * State kept per vnode, which implies per open file within a process.
 *
 * Once created, the hgfsFile and vnode/vnodep values are read-only.  The
 * handle and mode will change throughout this structure's existence, and are
 * both protected by their own mutex.
 */
typedef struct HgfsOpenFile {
   /* Handle provided by reply to a request */
   HgfsHandle handle;
   Bool handleIsSet;
   kmutex_t handleMutex;
   /*
    * Mode specified for this file to be created with.  This is necessary
    * because create is called with the mode then open is called without it.
    * We save this value in create and access it in open.
    */
   HgfsMode mode;
   Bool modeIsSet;
   kmutex_t modeMutex;
   /*
    * Pointer to the single Hgfs file state structure shared amongst all open
    * instances of this file.
    */
   HgfsFile *hgfsFile;
   /*
    * A pointer back to the vnode this open-file state is for.
    */
   struct vnode *vnodep;
} HgfsOpenFile;

/* The hash table for file state. */
typedef struct HgfsFileHashTable {
   kmutex_t mutex;
   DblLnkLst_Links hashTable[HGFS_HT_NR_BUCKETS];
} HgfsFileHashTable;

/* Forward declaration to prevent circular dependency between this and hgfs.h. */
struct HgfsSuperInfo;


/*
 * Functions
 */
int HgfsVnodeGet(struct vnode **vpp, struct HgfsSuperInfo *sip, struct vfs *vfsp,
                 const char *fileName, HgfsFileType fileType, HgfsFileHashTable *htp);
int HgfsVnodePut(struct vnode *vp, HgfsFileHashTable *ht);
int HgfsVnodeDup(struct vnode **newVpp, struct vnode *origVp, struct HgfsSuperInfo *sip,
                 HgfsFileHashTable *htp);
int HgfsFileNameToVnode(const char *fileName, struct vnode **vpp,
                        struct HgfsSuperInfo *sip, struct vfs *vfsp,
                        HgfsFileHashTable *htp);
void HgfsNodeIdGet(HgfsFileHashTable *ht, const char *fileName,
                   uint32_t fileNameLength, ino64_t *outNodeId);
void HgfsInitFileHashTable(HgfsFileHashTable *htp);
Bool HgfsFileHashTableIsEmpty(struct HgfsSuperInfo *sip, HgfsFileHashTable *htp);

/* Handle get/set/clear functions */
int HgfsSetOpenFileHandle(struct vnode *vp, HgfsHandle handle);
int HgfsGetOpenFileHandle(struct vnode *vp, HgfsHandle *outHandle);
int HgfsClearOpenFileHandle(struct vnode *vp);
Bool HgfsHandleIsSet(struct vnode *vp);

/* Mode get/set/clear functions */
int HgfsSetOpenFileMode(struct vnode *vp, HgfsMode mode);
int HgfsGetOpenFileMode(struct vnode *vp, HgfsMode *outMode);
int HgfsClearOpenFileMode(struct vnode *vp);

/* Debugging function */
void HgfsDebugPrintFileHashTable(HgfsFileHashTable *htp, int level);

#endif /* __HGFS_STATE_H_ */