ReactOS  0.4.12-dev-43-g63b00d8
nfs41_superblock.c File Reference
#include <windows.h>
#include <stdio.h>
#include "daemon_debug.h"
#include "nfs41.h"
#include "nfs41_ops.h"
#include "from_kernel.h"
#include "util.h"
Include dependency graph for nfs41_superblock.c:

Go to the source code of this file.

Macros

#define SBLVL   3 /* dprintf level for superblock logging */
 
#define superblock_entry(pos)   list_container(pos, nfs41_superblock, entry)
 

Functions

static __inline int compare_fsid (IN const nfs41_fsid *lhs, IN const nfs41_fsid *rhs)
 
static int superblock_create (IN const nfs41_fsid *fsid, OUT nfs41_superblock **superblock_out)
 
static int get_superblock_attrs (IN nfs41_session *session, IN nfs41_superblock *superblock, IN nfs41_path_fh *file)
 
void nfs41_superblock_fs_attributes (IN const nfs41_superblock *superblock, OUT PFILE_FS_ATTRIBUTE_INFORMATION FsAttrs)
 
static int superblock_compare (const struct list_entry *entry, const void *value)
 
static nfs41_superblockfind_superblock (IN nfs41_superblock_list *superblocks, IN const nfs41_fsid *fsid)
 
void nfs41_superblock_list_init (IN nfs41_superblock_list *superblocks)
 
void nfs41_superblock_list_free (IN nfs41_superblock_list *superblocks)
 
int nfs41_superblock_for_fh (IN nfs41_session *session, IN const nfs41_fsid *fsid, IN const nfs41_fh *parent OPTIONAL, OUT nfs41_path_fh *file)
 
void nfs41_superblock_space_changed (IN nfs41_superblock *superblock)
 

Macro Definition Documentation

◆ SBLVL

◆ superblock_entry

#define superblock_entry (   pos)    list_container(pos, nfs41_superblock, entry)

Function Documentation

◆ compare_fsid()

static __inline int compare_fsid ( IN const nfs41_fsid lhs,
IN const nfs41_fsid rhs 
)
static

Definition at line 35 of file nfs41_superblock.c.

Referenced by nfs41_superblock_for_fh(), and superblock_compare().

38 {
39  if (lhs->major > rhs->major) return 1;
40  if (lhs->major < rhs->major) return -1;
41  if (lhs->minor > rhs->minor) return 1;
42  if (lhs->minor < rhs->minor) return -1;
43  return 0;
44 }

◆ find_superblock()

static nfs41_superblock* find_superblock ( IN nfs41_superblock_list superblocks,
IN const nfs41_fsid fsid 
)
static

Definition at line 205 of file nfs41_superblock.c.

Referenced by nfs41_superblock_for_fh().

208 {
209  struct list_entry *entry;
210  entry = list_search(&superblocks->head, fsid, superblock_compare);
211  return entry ? superblock_entry(entry) : NULL;
212 }
uint8_t entry
Definition: isohybrid.c:63
smooth NULL
Definition: ftsmooth.c:416
static int superblock_compare(const struct list_entry *entry, const void *value)
static struct list_entry * list_search(const struct list_entry *head, const void *value, list_compare_fn compare)
Definition: list.h:102
Definition: list.h:27
#define superblock_entry(pos)

◆ get_superblock_attrs()

static int get_superblock_attrs ( IN nfs41_session session,
IN nfs41_superblock superblock,
IN nfs41_path_fh file 
)
static

Definition at line 74 of file nfs41_superblock.c.

Referenced by nfs41_superblock_for_fh().

78 {
79  bool_t supports_named_attrs;
80  int status;
81  bitmap4 attr_request;
82  nfs41_file_info info = { 0 };
83 
84  attr_request.arr[0] = FATTR4_WORD0_SUPPORTED_ATTRS |
89  attr_request.arr[1] = FATTR4_WORD1_FS_LAYOUT_TYPE |
91  attr_request.arr[2] = FATTR4_WORD2_SUPPATTR_EXCLCREAT;
92  attr_request.count = 3;
93 
94  info.supported_attrs = &superblock->supported_attrs;
95  info.suppattr_exclcreat = &superblock->suppattr_exclcreat;
96  info.time_delta = &superblock->time_delta;
97 
98  status = nfs41_superblock_getattr(session, file,
99  &attr_request, &info, &supports_named_attrs);
100  if (status) {
101  eprintf("nfs41_superblock_getattr() failed with %s when fetching "
102  "attributes for fsid(%llu,%llu)\n", nfs_error_string(status),
103  superblock->fsid.major, superblock->fsid.minor);
104  goto out;
105  }
106 
107  if (info.maxread)
108  superblock->maxread = info.maxread;
109  else
110  superblock->maxread = session->fore_chan_attrs.ca_maxresponsesize;
111 
112  if (info.maxwrite)
113  superblock->maxwrite = info.maxwrite;
114  else
115  superblock->maxwrite = session->fore_chan_attrs.ca_maxrequestsize;
116 
117  superblock->layout_types = info.fs_layout_types;
118  superblock->aclsupport = info.aclsupport;
119  superblock->link_support = info.link_support;
120  superblock->symlink_support = info.symlink_support;
121  superblock->ea_support = supports_named_attrs;
122  superblock->case_preserving = info.case_preserving;
123  superblock->case_insensitive = info.case_insensitive;
124 
126  superblock->cansettime = info.cansettime;
127  else /* cansettime is not supported, try setting them anyway */
128  superblock->cansettime = 1;
129 
130  /* if time_delta is not supported, default to 1s */
132  superblock->time_delta.seconds = 1;
133 
134  /* initialize the default getattr mask */
135  superblock->default_getattr.count = 2;
136  superblock->default_getattr.arr[0] = FATTR4_WORD0_TYPE
140  superblock->default_getattr.arr[1] = FATTR4_WORD1_MODE
144  superblock->default_getattr.arr[2] = 0;
145 
147 
148  dprintf(SBLVL, "attributes for fsid(%llu,%llu): "
149  "maxread=%llu, maxwrite=%llu, layout_types: 0x%X, "
150  "cansettime=%u, time_delta={%llu,%u}, aclsupport=%u, "
151  "link_support=%u, symlink_support=%u, case_preserving=%u, "
152  "case_insensitive=%u\n",
153  superblock->fsid.major, superblock->fsid.minor,
154  superblock->maxread, superblock->maxwrite,
155  superblock->layout_types, superblock->cansettime,
156  superblock->time_delta.seconds, superblock->time_delta.nseconds,
157  superblock->aclsupport, superblock->link_support,
158  superblock->symlink_support, superblock->case_preserving,
159  superblock->case_insensitive);
160 out:
161  return status;
162 }
#define SBLVL
uint32_t fs_layout_types
Definition: nfs41_types.h:234
bitmap4 * supported_attrs
Definition: nfs41_types.h:217
int32_t bool_t
Definition: types.h:101
void eprintf(LPCSTR format,...)
Definition: daemon_debug.c:86
bool_t symlink_support
Definition: nfs41_types.h:242
uint32_t arr[3]
Definition: nfs41_types.h:97
int nfs41_superblock_getattr(IN nfs41_session *session, IN nfs41_path_fh *file, IN bitmap4 *attr_request, OUT nfs41_file_info *info, OUT bool_t *supports_named_attrs)
Definition: nfs41_ops.c:1116
bool_t case_preserving
Definition: nfs41_types.h:240
#define dprintf
Definition: regdump.c:33
uint32_t count
Definition: nfs41_types.h:96
static __inline void nfs41_superblock_supported_attrs(IN const nfs41_superblock *superblock, IN OUT bitmap4 *attrs)
Definition: nfs41.h:454
static FILE * out
Definition: regtests2xml.c:44
const char * nfs_error_string(int status)
Definition: daemon_debug.c:370
uint32_t aclsupport
Definition: nfs41_types.h:246
bitmap4 * suppattr_exclcreat
Definition: nfs41_types.h:218
nfstime4 * time_delta
Definition: nfs41_types.h:215
bool_t case_insensitive
Definition: nfs41_types.h:239
#define uint32_t
Definition: nsiface.idl:61
static SERVICE_STATUS status
Definition: service.c:31
static __inline bool_t bitmap_isset(IN const bitmap4 *mask, IN uint32_t word, IN uint32_t flag)
Definition: util.h:55
Definition: fci.c:126

◆ nfs41_superblock_for_fh()

int nfs41_superblock_for_fh ( IN nfs41_session session,
IN const nfs41_fsid fsid,
IN const nfs41_fh *parent  OPTIONAL,
OUT nfs41_path_fh file 
)

Definition at line 233 of file nfs41_superblock.c.

Referenced by client_server(), nfs41_link(), nfs41_open(), and server_lookup().

238 {
239  int status = NFS4_OK;
240  nfs41_server *server = client_server(session->client);
241  nfs41_superblock_list *superblocks = &server->superblocks;
243 
244  dprintf(SBLVL, "--> nfs41_superblock_for_fh(fsid(%llu,%llu))\n",
245  fsid->major, fsid->minor);
246 
247  /* compare with the parent's fsid, and use that if it matches */
248  if (parent && parent->superblock &&
249  compare_fsid(fsid, &parent->superblock->fsid) == 0) {
250  file->fh.superblock = parent->superblock;
251  dprintf(SBLVL, "using superblock from parent\n");
252  goto out;
253  }
254 
255  /* using a shared lock, search for an existing superblock */
256  AcquireSRWLockShared(&superblocks->lock);
257  superblock = find_superblock(superblocks, fsid);
258  ReleaseSRWLockShared(&superblocks->lock);
259 
260  if (superblock) {
261  dprintf(SBLVL, "found existing superblock in server list "
262  "[shared lock]\n");
263  } else {
264  AcquireSRWLockExclusive(&superblocks->lock);
265  /* must search again under an exclusive lock, in case another thread
266  * created it after our first search */
267  superblock = find_superblock(superblocks, fsid);
268  if (superblock) {
269  dprintf(SBLVL, "found newly created superblock in server list "
270  "[exclusive lock]\n");
271  } else {
272  /* create the superblock */
273  status = superblock_create(fsid, &superblock);
274  if (status == NO_ERROR) /* add it to the list */
275  list_add_tail(&superblocks->head, &superblock->entry);
276  }
277  ReleaseSRWLockExclusive(&superblocks->lock);
278  }
279 
280  if (status == NO_ERROR && superblock->supported_attrs.count == 0) {
281  /* exclusive lock on the superblock while fetching attributes */
282  AcquireSRWLockExclusive(&superblock->lock);
283  if (superblock->supported_attrs.count == 0)
284  status = get_superblock_attrs(session, superblock, file);
285  ReleaseSRWLockExclusive(&superblock->lock);
286  }
287 
288  file->fh.superblock = superblock;
289 out:
290  dprintf(SBLVL, "<-- nfs41_superblock_for_fh() returning %p, status %d\n",
291  file->fh.superblock, status);
292  return status;
293 }
#define SBLVL
static int get_superblock_attrs(IN nfs41_session *session, IN nfs41_superblock *superblock, IN nfs41_path_fh *file)
VOID WINAPI AcquireSRWLockExclusive(PSRWLOCK Lock)
Definition: sync.c:54
SRWLOCK lock
Definition: nfs41.h:65
static rfbScreenInfoPtr server
Definition: vnc.c:74
static int superblock_create(IN const nfs41_fsid *fsid, OUT nfs41_superblock **superblock_out)
struct list_entry entry
Definition: nfs41.h:39
#define NO_ERROR
Definition: dderror.h:5
static __inline int compare_fsid(IN const nfs41_fsid *lhs, IN const nfs41_fsid *rhs)
__WINE_SERVER_LIST_INLINE void list_add_tail(struct list *list, struct list *elem)
Definition: list.h:102
#define dprintf
Definition: regdump.c:33
uint32_t count
Definition: nfs41_types.h:96
static __inline nfs41_server * client_server(IN nfs41_client *client)
Definition: nfs41.h:428
r parent
Definition: btrfs.c:2644
static nfs41_superblock * find_superblock(IN nfs41_superblock_list *superblocks, IN const nfs41_fsid *fsid)
struct list_entry head
Definition: nfs41.h:69
static FILE * out
Definition: regtests2xml.c:44
VOID WINAPI ReleaseSRWLockExclusive(PSRWLOCK Lock)
Definition: sync.c:82
nfs41_superblock_list superblocks
Definition: nfs41.h:83
static SERVICE_STATUS status
Definition: service.c:31
VOID WINAPI AcquireSRWLockShared(PSRWLOCK Lock)
Definition: sync.c:61
bitmap4 supported_attrs
Definition: nfs41.h:41
VOID WINAPI ReleaseSRWLockShared(PSRWLOCK Lock)
Definition: sync.c:89
Definition: fci.c:126
Definition: ps.c:97

◆ nfs41_superblock_fs_attributes()

void nfs41_superblock_fs_attributes ( IN const nfs41_superblock superblock,
OUT PFILE_FS_ATTRIBUTE_INFORMATION  FsAttrs 
)

Definition at line 164 of file nfs41_superblock.c.

167 {
168  FsAttrs->FileSystemAttributes = FILE_SUPPORTS_REMOTE_STORAGE;
169  if (superblock->link_support)
170  FsAttrs->FileSystemAttributes |= FILE_SUPPORTS_HARD_LINKS;
171  if (superblock->symlink_support)
172  FsAttrs->FileSystemAttributes |= FILE_SUPPORTS_REPARSE_POINTS;
173  if (superblock->ea_support)
174  FsAttrs->FileSystemAttributes |= FILE_SUPPORTS_EXTENDED_ATTRIBUTES;
175  if (superblock->case_preserving)
176  FsAttrs->FileSystemAttributes |= FILE_CASE_PRESERVED_NAMES;
177  if (!superblock->case_insensitive)
178  FsAttrs->FileSystemAttributes |= FILE_CASE_SENSITIVE_SEARCH;
179  if (superblock->aclsupport)
180  FsAttrs->FileSystemAttributes |= FILE_PERSISTENT_ACLS;
181 
182  FsAttrs->MaximumComponentNameLength = NFS41_MAX_COMPONENT_LEN;
183 
184  /* let the driver fill in FileSystemName */
185  FsAttrs->FileSystemNameLength = 0;
186 
187  dprintf(SBLVL, "FileFsAttributeInformation: case_preserving %u, "
188  "case_insensitive %u, max component %u\n",
189  superblock->case_preserving, superblock->case_insensitive,
190  FsAttrs->MaximumComponentNameLength);
191 }
#define SBLVL
#define NFS41_MAX_COMPONENT_LEN
Definition: nfs41_const.h:45
#define FILE_SUPPORTS_REPARSE_POINTS
Definition: from_kernel.h:240
#define dprintf
Definition: regdump.c:33
#define FILE_CASE_SENSITIVE_SEARCH
Definition: from_kernel.h:233
#define FILE_CASE_PRESERVED_NAMES
Definition: from_kernel.h:234
#define FILE_SUPPORTS_HARD_LINKS
Definition: from_kernel.h:249
#define FILE_SUPPORTS_EXTENDED_ATTRIBUTES
Definition: from_kernel.h:250
#define FILE_PERSISTENT_ACLS
Definition: from_kernel.h:236
#define FILE_SUPPORTS_REMOTE_STORAGE
Definition: from_kernel.h:241

◆ nfs41_superblock_list_free()

void nfs41_superblock_list_free ( IN nfs41_superblock_list superblocks)

Definition at line 221 of file nfs41_superblock.c.

Referenced by nfs41_superblock_supported_attrs_exclcreat(), and server_free().

223 {
224  struct list_entry *entry, *tmp;
225 
226  dprintf(SBLVL, "nfs41_superblock_list_free()\n");
227 
228  list_for_each_tmp(entry, tmp, &superblocks->head)
229  free(superblock_entry(entry));
230 }
#define SBLVL
#define free
Definition: debug_ros.c:5
uint8_t entry
Definition: isohybrid.c:63
#define dprintf
Definition: regdump.c:33
Definition: list.h:27
#define list_for_each_tmp(entry, tmp, head)
Definition: list.h:39
#define superblock_entry(pos)

◆ nfs41_superblock_list_init()

void nfs41_superblock_list_init ( IN nfs41_superblock_list superblocks)

Definition at line 214 of file nfs41_superblock.c.

Referenced by nfs41_superblock_supported_attrs_exclcreat(), and server_create().

216 {
217  list_init(&superblocks->head);
218  InitializeSRWLock(&superblocks->lock);
219 }
VOID WINAPI InitializeSRWLock(PSRWLOCK Lock)
Definition: sync.c:75
__WINE_SERVER_LIST_INLINE void list_init(struct list *list)
Definition: list.h:149

◆ nfs41_superblock_space_changed()

void nfs41_superblock_space_changed ( IN nfs41_superblock superblock)

Definition at line 295 of file nfs41_superblock.c.

Referenced by nfs41_commit(), nfs41_create(), nfs41_link(), nfs41_open(), nfs41_remove(), nfs41_setattr(), nfs41_superblock_supported_attrs_exclcreat(), and nfs41_write().

297 {
298  /* invalidate cached volume size attributes */
300  superblock->cache_expiration = 0;
302 }
VOID WINAPI AcquireSRWLockExclusive(PSRWLOCK Lock)
Definition: sync.c:54
VOID WINAPI ReleaseSRWLockExclusive(PSRWLOCK Lock)
Definition: sync.c:82

◆ superblock_compare()

static int superblock_compare ( const struct list_entry entry,
const void value 
)
static

Definition at line 197 of file nfs41_superblock.c.

Referenced by find_superblock().

200 {
202  return compare_fsid(&superblock->fsid, (const nfs41_fsid*)value);
203 }
static __inline int compare_fsid(IN const nfs41_fsid *lhs, IN const nfs41_fsid *rhs)
nfs41_fsid fsid
Definition: nfs41.h:38
#define superblock_entry(pos)

◆ superblock_create()

static int superblock_create ( IN const nfs41_fsid fsid,
OUT nfs41_superblock **  superblock_out 
)
static

Definition at line 48 of file nfs41_superblock.c.

Referenced by nfs41_superblock_for_fh().

51 {
52  int status = NO_ERROR;
54 
55  dprintf(SBLVL, "creating superblock for fsid(%llu,%llu)\n",
56  fsid->major, fsid->minor);
57 
58  superblock = calloc(1, sizeof(nfs41_superblock));
59  if (superblock == NULL) {
60  status = GetLastError();
61  eprintf("failed to allocate superblock "
62  "for fsid(%llu,%llu)\n", fsid->major, fsid->minor);
63  goto out;
64  }
65 
66  memcpy(&superblock->fsid, fsid, sizeof(nfs41_fsid));
67  InitializeSRWLock(&superblock->lock);
68 
69  *superblock_out = superblock;
70 out:
71  return status;
72 }
#define SBLVL
SRWLOCK lock
Definition: nfs41.h:65
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1059
void eprintf(LPCSTR format,...)
Definition: daemon_debug.c:86
#define NO_ERROR
Definition: dderror.h:5
#define dprintf
Definition: regdump.c:33
smooth NULL
Definition: ftsmooth.c:416
nfs41_fsid fsid
Definition: nfs41.h:38
static FILE * out
Definition: regtests2xml.c:44
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
VOID WINAPI InitializeSRWLock(PSRWLOCK Lock)
Definition: sync.c:75
#define calloc
Definition: rosglue.h:14
static SERVICE_STATUS status
Definition: service.c:31
Definition: ps.c:97