summaryrefslogtreecommitdiffstats
path: root/cpukit/libfs/src/nfsclient/src/nfs.c
diff options
context:
space:
mode:
Diffstat (limited to 'cpukit/libfs/src/nfsclient/src/nfs.c')
-rw-r--r--cpukit/libfs/src/nfsclient/src/nfs.c1165
1 files changed, 398 insertions, 767 deletions
diff --git a/cpukit/libfs/src/nfsclient/src/nfs.c b/cpukit/libfs/src/nfsclient/src/nfs.c
index 80e757cbdf..ee1185367f 100644
--- a/cpukit/libfs/src/nfsclient/src/nfs.c
+++ b/cpukit/libfs/src/nfsclient/src/nfs.c
@@ -4,7 +4,12 @@
/* Author: Till Straumann <strauman@slac.stanford.edu> 2002 */
-/* Hacked on by others. */
+/*
+ * Hacked on by others.
+ *
+ * Modifications to support reference counting in the file system are
+ * Copyright (c) 2012 embedded brains GmbH.
+ */
/*
* Authorship
@@ -74,6 +79,7 @@
#include <mount_prot.h>
#include "rpcio.h"
+#include "librtemsNfs.h"
/* Configurable parameters */
@@ -201,6 +207,21 @@ static struct timeval _nfscalltimeout = { 10, 0 }; /* {secs, us } */
#define UNLOCK(s) do { rtems_semaphore_release((s)); \
} while (0)
+static inline char *
+nfs_dupname(const char *name, size_t namelen)
+{
+ char *dupname = malloc(namelen + 1);
+
+ if (dupname != NULL) {
+ memcpy(dupname, name, namelen);
+ dupname [namelen] = '\0';
+ } else {
+ errno = ENOMEM;
+ }
+
+ return dupname;
+}
+
/*****************************************
Types with Associated XDR Routines
*****************************************/
@@ -214,12 +235,6 @@ typedef struct strbuf {
u_int max;
} strbuf;
-static bool_t
-xdr_strbuf(XDR *xdrs, strbuf *obj)
-{
- return xdr_string(xdrs, &obj->buf, obj->max);
-}
-
/* Read 'readlink' results into a 'strbuf'.
* This is convenient as it avoids
* one extra step of copying / lenght
@@ -562,9 +577,9 @@ typedef struct NfsNodeRec_ {
*****************************************/
static ssize_t nfs_readlink(
- rtems_filesystem_location_info_t *loc, /* IN */
- char *buf, /* OUT */
- size_t len
+ const rtems_filesystem_location_info_t *loc,
+ char *buf,
+ size_t len
);
static int updateAttr(NfsNode node, int force);
@@ -591,10 +606,10 @@ static int updateAttr(NfsNode node, int force);
static int
nfs_sattr(NfsNode node, sattr *arg, u_long mask);
-extern struct _rtems_filesystem_operations_table nfs_fs_ops;
-static struct _rtems_filesystem_file_handlers_r nfs_file_file_handlers;
-static struct _rtems_filesystem_file_handlers_r nfs_dir_file_handlers;
-static struct _rtems_filesystem_file_handlers_r nfs_link_file_handlers;
+extern const struct _rtems_filesystem_operations_table nfs_fs_ops;
+static const struct _rtems_filesystem_file_handlers_r nfs_file_file_handlers;
+static const struct _rtems_filesystem_file_handlers_r nfs_dir_file_handlers;
+static const struct _rtems_filesystem_file_handlers_r nfs_link_file_handlers;
static rtems_driver_address_table drvNfs;
int
@@ -603,64 +618,6 @@ nfsMountsShow(FILE*);
rtems_status_code
rtems_filesystem_resolve_location(char *buf, int len, rtems_filesystem_location_info_t *loc);
-
-/*****************************************
- Inline Routines
- *****************************************/
-
-
-/* * * * * * * * * * * * * * * * * *
- Trivial Operations on a NfsNode
- * * * * * * * * * * * * * * * * * */
-
-/* determine if a location 'l' is an NFS root node */
-static inline int
-locIsRoot(rtems_filesystem_location_info_t *l)
-{
-NfsNode me = (NfsNode) l->node_access;
-NfsNode r;
- r = (NfsNode)l->mt_entry->mt_fs_root.node_access;
- return SERP_ATTR(r).fileid == SERP_ATTR(me).fileid &&
- SERP_ATTR(r).fsid == SERP_ATTR(me).fsid;
-}
-
-/* determine if a location 'l' is an NFS node */
-static inline int
-locIsNfs(rtems_filesystem_location_info_t *l)
-{
- return l->ops == &nfs_fs_ops;
-}
-
-/* determine if two locations refer to the
- * same entity. We know that 'nfsloc' is a
- * location inside nfs. However, we needn't
- * know anything about 'anyloc'.
- */
-static inline int
-locAreEqual(
- rtems_filesystem_location_info_t *nfsloc,
- rtems_filesystem_location_info_t *anyloc
-)
-{
-NfsNode na = (NfsNode) nfsloc->node_access;
-NfsNode nb;
-
- if (!locIsNfs(anyloc))
- return 0;
-
- nb = (NfsNode) anyloc->node_access;
-
- if (na->nfs != nb->nfs)
- return 0;
-
- updateAttr(nb, 0);
-
- return SERP_ATTR(na).fileid == SERP_ATTR(nb).fileid &&
- SERP_ATTR(na).fsid == SERP_ATTR(nb).fsid;
-}
-
-
-
/*****************************************
Global Variables
*****************************************/
@@ -1326,409 +1283,229 @@ enum clnt_stat stat = RPC_FAILED;
RTEMS File System Operations for NFS
*****************************************/
-#if 0 /* for reference */
-
-struct rtems_filesystem_location_info_tt
-{
- void *node_access;
- rtems_filesystem_file_handlers_r *handlers;
- rtems_filesystem_operations_table *ops;
- rtems_filesystem_mount_table_entry_t *mt_entry;
-};
-
-#endif
-
-/*
- * Evaluate a path letting 'pathloc' travel along.
- *
- * The important semantics of this operation are:
- *
- * If this routine returns -1, the caller assumes
- * pathloc to be _invalid_ and hence it will not
- * invoke rtems_filesystem_freenode() on it.
- *
- * OTOH, if evalpath returns 0,
- * rtems_filesystem_freenode() will eventually be
- * called which results in our freeing the associated
- * NfsNode attached to node_access.
- *
- * Therefore, this routine will _always_ allocate
- * a NfsNode and pass it out to *pathloc (provided
- * that the evaluation succeeds).
- *
- * However, if the evaluation finds that it has to
- * step across FS boundaries (mount point or a symlink
- * pointing outside), the NfsNode is destroyed
- * before passing control to the new FS' evalpath_h()
- *
- */
-
-union nfs_evalpath_arg {
- int i;
- const char **c;
- };
-
-STATIC int nfs_do_evalpath(
- const char *pathname, /* IN */
- int pathnamelen, /* IN */
- union nfs_evalpath_arg *arg,
- rtems_filesystem_location_info_t *pathloc, /* IN/OUT */
- int forMake
+static bool nfs_is_directory(
+ rtems_filesystem_eval_path_context_t *ctx,
+ void *arg
)
{
-char *del = 0, *part;
-int e = 0;
-NfsNode node = pathloc->node_access;
-char *p = malloc(MAXPATHLEN+1);
-Nfs nfs = (Nfs)pathloc->mt_entry->fs_info;
-RpcUdpServer server = nfs->server;
-unsigned long flags;
-#if DEBUG & DEBUG_COUNT_NODES
-unsigned long niu,siu;
-#endif
+ bool is_dir = false;
+ rtems_filesystem_location_info_t *currentloc =
+ rtems_filesystem_eval_path_get_currentloc(ctx);
+ NfsNode node = currentloc->node_access;
+ int force_update = 0;
- if ( !p ) {
- e = ENOMEM;
- goto cleanup;
+ if (updateAttr(node, force_update) == 0) {
+ is_dir = SERP_ATTR(node).type == NFDIR;
}
- memset(p, 0, MAXPATHLEN+1);
- memcpy(p, pathname, pathnamelen);
- LOCK(nfsGlob.lock);
- node = nfsNodeClone(node);
- UNLOCK(nfsGlob.lock);
-
- /* from here on, the NFS is protected from being unmounted
- * since the node refcount is > 1
- */
-
- /* clone the node */
- if ( !node ) {
- /* nodeClone sets errno */
- pathloc->node_access = 0;
- if ( ! (e = errno) ) {
- /* if we have no node, e must not be zero! */
- e = ENOMEM;
- }
- goto cleanup;
- }
-
- pathloc->node_access = node;
-
- /* Special case: the RTEMS filesystem code
- * may emit '..' on a regular file node to
- * find the parent directory :-(.
- * (eval.c: rtems_filesystem_evaluate_parent())
- * Try to catch this case here:
- */
- if ( NFDIR != SERP_ATTR(node).type && '.'==*p && '.'==*(p+1) ) {
- for ( part = p+2; '/'==*part; part++ )
- /* skip trailing '/' */;
- if ( !*part ) {
- /* this is it; back out dir and let them look up the dir itself... */
- memcpy( &SERP_FILE(node),
- &node->args.dir,
- sizeof(node->args.dir));
- *(p+1)=0;
- }
- }
-
- for (part=p; part && *part; part=del) {
-
- if ( NFLNK == SERP_ATTR(node).type ) {
- /* follow midpath link */
- char *b = malloc(NFS_MAXPATHLEN+1);
- int l;
-
- if (!b) {
- e = ENOMEM;
- goto cleanup;
- }
- if (nfs_readlink(pathloc, b, NFS_MAXPATHLEN+1)) {
- free(b);
- e = errno;
- goto cleanup;
- }
-
- /* prepend the link value to the rest of the path */
- if ( (l=strlen(b)) + strlen(part) + 1 > NFS_MAXPATHLEN ) {
- free(b);
- e = EINVAL;
- goto cleanup;
- }
- /* swap string buffers and reset delimiter */
- b[l++] = DELIM;
- strcpy(b+l,part);
- part = b;
- b = p;
- p = del = part;
-
- free(b);
-
- /* back up the directory filehandle (only necessary
- * if we don't back out to the root
- */
- if (! (DELIM == *part) ) {
- memcpy( &SERP_FILE(node),
- &node->args.dir,
- sizeof(node->args.dir));
-
- if (updateAttr(node, 1 /* force */)) {
- e = errno;
- goto cleanup;
- }
- }
- }
+ return is_dir;
+}
- /* find delimiter and eat /// sequences
- * (only if we don't restart at the root)
- */
- if ( DELIM != *part && (del = strchr(part, DELIM))) {
- do {
- *del++=0;
- } while (DELIM==*del);
- }
+static NfsNode nfs_search_in_directory(
+ Nfs nfs,
+ NfsNode node,
+ char *part
+)
+{
+ int rv;
- /* refuse to backup over the root */
- if ( 0==strcmp(part,UPDIR)
- && locAreEqual(pathloc, &rtems_filesystem_root) ) {
- part++;
- }
+ /* lookup one element */
+ SERP_ARGS(node).diroparg.name = part;
- /* cross mountpoint upwards */
- if ( (0==strcmp(part,UPDIR) && locIsRoot(pathloc)) /* cross mountpoint up */
- || DELIM == *part /* link starts at root */
- ) {
- int rval;
+ /* remember args / directory fh */
+ memcpy( &node->args, &SERP_FILE(node), sizeof(node->args));
#if DEBUG & DEBUG_EVALPATH
- fprintf(stderr,
- "Crossing mountpoint upwards\n");
+ fprintf(stderr,"Looking up '%s'\n",part);
#endif
- if (DELIM == *part) {
- *pathloc = rtems_filesystem_root;
- } else {
- *pathloc = pathloc->mt_entry->mt_point_node;
- /* re-append the rest of the path */
- if (del)
- while ( 0 == *--del )
- *del = DELIM;
- }
-
- nfsNodeDestroy(node);
-
-#if DEBUG & DEBUG_EVALPATH
- fprintf(stderr,
- "Re-evaluating '%s'\n",
- part);
-#endif
+ rv = nfscall(
+ nfs->server,
+ NFSPROC_LOOKUP,
+ (xdrproc_t) xdr_diropargs, &SERP_FILE(node),
+ (xdrproc_t) xdr_serporid, &node->serporid
+ );
- if (forMake)
- rval = pathloc->ops->evalformake_h(part, pathloc, arg->c);
- else
- rval = pathloc->ops->evalpath_h(part, strlen(part), arg->i, pathloc);
+ if (rv == 0 && node->serporid.status == NFS_OK) {
+ int force_update = 1;
- free(p);
- return rval;
+ rv = updateAttr(node, force_update);
+ if (rv != 0) {
+ node = NULL;
}
+ } else {
+ node = NULL;
+ }
- /* lookup one element */
- SERP_ARGS(node).diroparg.name = part;
-
- /* remember args / directory fh */
- memcpy( &node->args, &SERP_FILE(node), sizeof(node->args));
-
- /* don't lookup the item we want to create */
- if ( forMake && (!del || !*del) )
- break;
+ return node;
+}
-#if DEBUG & DEBUG_EVALPATH
- fprintf(stderr,"Looking up '%s'\n",part);
-#endif
+static void nfs_follow_link(rtems_filesystem_eval_path_context_t *ctx)
+{
+ const size_t len = NFS_MAXPATHLEN + 1;
+ char *link = malloc(len);
- if ( nfscall(server,
- NFSPROC_LOOKUP,
- (xdrproc_t)xdr_diropargs, &SERP_FILE(node),
- (xdrproc_t)xdr_serporid, &node->serporid) ||
- NFS_OK != (errno=node->serporid.status) ) {
- e = errno;
- goto cleanup;
- }
- node->age = nowSeconds();
+ if (link != NULL) {
+ rtems_filesystem_location_info_t *currentloc =
+ rtems_filesystem_eval_path_get_currentloc(ctx);
+ ssize_t rv = nfs_readlink(currentloc, link, len);
-#if DEBUG & DEBUG_EVALPATH
- if (NFLNK == SERP_ATTR(node).type && del) {
- fprintf(stderr,
- "Following midpath link '%s'\n",
- part);
+ if (rv >= 0) {
+ rtems_filesystem_eval_path_recursive(ctx, link, (size_t) rv);
+ } else {
+ rtems_filesystem_eval_path_error(ctx, 0);
}
-#endif
+ free(link);
+ } else {
+ rtems_filesystem_eval_path_error(ctx, ENOMEM);
}
+}
- if (forMake) {
- /* remember the name - do this _before_ copying
- * the name to local storage; the caller expects a
- * pointer into pathloc
- */
- assert( node->args.name );
-
- *(arg->c) = pathname + (node->args.name - p);
-
-#if 0
- /* restore the directory node */
+static bool nfs_update_currentloc(
+ rtems_filesystem_eval_path_context_t *ctx,
+ Nfs nfs,
+ NfsNode node
+)
+{
+ bool ok = true;
+ rtems_filesystem_location_info_t *pathloc =
+ rtems_filesystem_eval_path_get_currentloc(ctx);
- memcpy( &SERP_FILE(node),
- &node->args.dir,
- sizeof(node->args.dir));
+ pathloc->node_access = node;
- if ( (nfscall(nfs->server,
- NFSPROC_GETATTR,
- (xdrproc_t)xdr_nfs_fh, &SERP_FILE(node),
- (xdrproc_t)xdr_attrstat, &node->serporid) && !errno && (errno = EIO)) ||
- (NFS_OK != (errno=node->serporid.status) ) ) {
- goto cleanup;
- }
-#endif
+ switch (SERP_ATTR(node).type) {
+ case NFDIR: pathloc->handlers = &nfs_dir_file_handlers; break;
+ case NFREG: pathloc->handlers = &nfs_file_file_handlers; break;
+ case NFLNK: pathloc->handlers = &nfs_link_file_handlers; break;
+ default: pathloc->handlers = &rtems_filesystem_handlers_default; break;
}
- if (locIsRoot(pathloc)) {
-
- /* stupid filesystem code has no 'op' for comparing nodes
- * but just compares the 'node_access' pointers.
- * Luckily, this is only done for comparing the root nodes.
- * Hence, we never give them a copy of the root but always
- * the root itself.
- */
- pathloc->node_access = pathloc->mt_entry->mt_fs_root.node_access;
- /* increment the 'in use' counter since we return one more
- * reference to the root node
- */
- rtems_interrupt_disable(flags);
- nfs->nodesInUse++;
- rtems_interrupt_enable(flags);
- nfsNodeDestroy(node);
-
-
- } else {
- switch (SERP_ATTR(node).type) {
- case NFDIR: pathloc->handlers = &nfs_dir_file_handlers; break;
- case NFREG: pathloc->handlers = &nfs_file_file_handlers; break;
- case NFLNK: pathloc->handlers = &nfs_link_file_handlers; break;
- default: pathloc->handlers = &rtems_filesystem_handlers_default; break;
- }
- pathloc->node_access = node;
-
- /* remember the name of this directory entry */
+ /* remember the name of this directory entry */
- if (node->args.name) {
- if (node->str) {
+ if (node->args.name) {
+ if (node->str) {
#if DEBUG & DEBUG_COUNT_NODES
- rtems_interrupt_disable(flags);
- nfs->stringsInUse--;
- rtems_interrupt_enable(flags);
+ rtems_interrupt_level flags;
+ rtems_interrupt_disable(flags);
+ nfs->stringsInUse--;
+ rtems_interrupt_enable(flags);
#endif
- free(node->str);
- }
- node->args.name = node->str = strdup(node->args.name);
- if (!node->str) {
- e = ENOMEM;
- goto cleanup;
- }
-
+ free(node->str);
+ }
+ node->args.name = node->str = strdup(node->args.name);
+ if (node->str != NULL) {
#if DEBUG & DEBUG_COUNT_NODES
+ rtems_interrupt_level flags;
rtems_interrupt_disable(flags);
nfs->stringsInUse++;
rtems_interrupt_enable(flags);
#endif
+ } else {
+ rtems_filesystem_eval_path_error(ctx, ENOMEM);
+ ok = false;
}
-
}
- node = 0;
- e = 0;
+ return ok;
+}
-cleanup:
- free(p);
-#if DEBUG & DEBUG_COUNT_NODES
- /* cache counters; nfs may be unmounted by other thread after the last
- * node is destroyed
- */
- niu = nfs->nodesInUse;
- siu = nfs->stringsInUse;
-#endif
- if (node) {
- nfsNodeDestroy(node);
- pathloc->node_access = 0;
- }
-#if DEBUG & DEBUG_COUNT_NODES
- fprintf(stderr,
- "leaving evalpath, in use count is %i nodes, %i strings\n",
- niu,siu);
-#endif
- if (e) {
-#if DEBUG & DEBUG_EVALPATH
- perror("Evalpath");
-#endif
- rtems_set_errno_and_return_minus_one(e);
+static rtems_filesystem_eval_path_generic_status nfs_eval_part(
+ rtems_filesystem_eval_path_context_t *ctx,
+ char *part
+)
+{
+ rtems_filesystem_eval_path_generic_status status =
+ RTEMS_FILESYSTEM_EVAL_PATH_GENERIC_DONE;
+ rtems_filesystem_location_info_t *currentloc =
+ rtems_filesystem_eval_path_get_currentloc(ctx);
+ Nfs nfs = currentloc->mt_entry->fs_info;
+ NfsNode dir = currentloc->node_access;
+ NfsNode entry = nfs_search_in_directory(nfs, dir, part);
+
+ if (entry != NULL) {
+ rtems_filesystem_eval_path_clear_token(ctx);
+
+ if (nfs_update_currentloc(ctx, nfs, entry)) {
+ int eval_flags = rtems_filesystem_eval_path_get_flags(ctx);
+ bool follow_sym_link = (eval_flags & RTEMS_LIBIO_FOLLOW_SYM_LINK) != 0;
+ bool terminal = !rtems_filesystem_eval_path_has_path( ctx );
+
+ if (SERP_ATTR(entry).type == NFLNK && (follow_sym_link || !terminal)) {
+ nfs_follow_link(ctx);
+ } else if (!terminal) {
+ status = RTEMS_FILESYSTEM_EVAL_PATH_GENERIC_CONTINUE;
+ }
+ }
} else {
- return 0;
+ status = RTEMS_FILESYSTEM_EVAL_PATH_GENERIC_NO_ENTRY;
}
+
+ return status;
}
-/* MANDATORY; may set errno=ENOSYS and return -1 */
-static int nfs_evalformake(
- const char *path, /* IN */
- rtems_filesystem_location_info_t *pathloc, /* IN/OUT */
- const char **pname /* OUT */
+static rtems_filesystem_eval_path_generic_status nfs_eval_token(
+ rtems_filesystem_eval_path_context_t *ctx,
+ void *arg,
+ const char *token,
+ size_t tokenlen
)
{
- union nfs_evalpath_arg args;
- args.c = pname;
-
- return nfs_do_evalpath(path, strlen(path), &args, pathloc, 1 /*forMake*/);
+ rtems_filesystem_eval_path_generic_status status =
+ RTEMS_FILESYSTEM_EVAL_PATH_GENERIC_DONE;
+
+ if (rtems_filesystem_is_current_directory(token, tokenlen)) {
+ rtems_filesystem_eval_path_clear_token(ctx);
+ if (rtems_filesystem_eval_path_has_path(ctx)) {
+ status = RTEMS_FILESYSTEM_EVAL_PATH_GENERIC_CONTINUE;
+ }
+ } else {
+ char *part = nfs_dupname(token, tokenlen);
+
+ if (part != NULL) {
+ status = nfs_eval_part(ctx, part);
+ free(part);
+ } else {
+ rtems_filesystem_eval_path_error(ctx, ENOMEM);
+ }
+ }
+
+ return status;
}
-static int nfs_evalpath(
- const char *path, /* IN */
- size_t pathlen, /* IN */
- int flags, /* IN */
- rtems_filesystem_location_info_t *pathloc /* IN/OUT */
-)
+static const rtems_filesystem_eval_path_generic_config nfs_eval_config = {
+ .is_directory = nfs_is_directory,
+ .eval_token = nfs_eval_token
+};
+
+static void nfs_eval_path(rtems_filesystem_eval_path_context_t *ctx)
{
- union nfs_evalpath_arg args;
- args.i = flags;
- return nfs_do_evalpath(path, pathlen, &args, pathloc, 0 /*not forMake*/);
+ rtems_filesystem_eval_path_generic(ctx, NULL, &nfs_eval_config);
}
-
/* create a hard link */
static int nfs_link(
- rtems_filesystem_location_info_t *to_loc, /* IN */
- rtems_filesystem_location_info_t *parent_loc, /* IN */
- const char *name /* IN */
+ const rtems_filesystem_location_info_t *parentloc,
+ const rtems_filesystem_location_info_t *targetloc,
+ const char *name,
+ size_t namelen
)
{
+int rv = 0;
NfsNode pNode;
nfsstat status;
-NfsNode tNode = to_loc->node_access;
+NfsNode tNode = targetloc->node_access;
+char *dupname;
+
+ dupname = nfs_dupname(name, namelen);
+ if (dupname == NULL)
+ return -1;
#if DEBUG & DEBUG_SYSCALLS
- fprintf(stderr,"Creating link '%s'\n",name);
+ fprintf(stderr,"Creating link '%s'\n",dupname);
#endif
- if ( !locIsNfs(parent_loc) ) {
- errno = EXDEV;
- return -1;
- }
-
- pNode = parent_loc->node_access;
- if ( tNode->nfs != pNode->nfs ) {
- errno = EXDEV;
- return -1;
- }
memcpy(&SERP_ARGS(tNode).linkarg.to.dir,
&SERP_FILE(pNode),
sizeof(SERP_FILE(pNode)));
@@ -1744,16 +1521,18 @@ NfsNode tNode = to_loc->node_access;
#if DEBUG & DEBUG_SYSCALLS
perror("nfs_link");
#endif
- return -1;
+ rv = -1;
}
- return 0;
+ free(dupname);
+
+ return rv;
}
static int nfs_do_unlink(
- rtems_filesystem_location_info_t *parent_loc,/* IN */
- rtems_filesystem_location_info_t *loc, /* IN */
+ const rtems_filesystem_location_info_t *parentloc,
+ const rtems_filesystem_location_info_t *loc,
int proc
)
{
@@ -1791,18 +1570,10 @@ char *name = NFSPROC_REMOVE == proc ?
return 0;
}
-static int nfs_unlink(
- rtems_filesystem_location_info_t *parent_loc, /* IN */
- rtems_filesystem_location_info_t *loc /* IN */
-)
-{
- return nfs_do_unlink(parent_loc, loc, NFSPROC_REMOVE);
-}
-
static int nfs_chown(
- rtems_filesystem_location_info_t *pathloc, /* IN */
- uid_t owner, /* IN */
- gid_t group /* IN */
+ const rtems_filesystem_location_info_t *pathloc, /* IN */
+ uid_t owner, /* IN */
+ gid_t group /* IN */
)
{
sattr arg;
@@ -1814,14 +1585,27 @@ sattr arg;
}
+static int nfs_clonenode(rtems_filesystem_location_info_t *loc)
+{
+ NfsNode node = loc->node_access;
+
+ LOCK(nfsGlob.lock);
+ node = nfsNodeClone(node);
+ UNLOCK(nfsGlob.lock);
+
+ loc->node_access = node;
+
+ return node != NULL ? 0 : -1;
+}
+
/* Cleanup the FS private info attached to pathloc->node_access */
-static int nfs_freenode(
- rtems_filesystem_location_info_t *pathloc /* IN */
+static void nfs_freenode(
+ const rtems_filesystem_location_info_t *pathloc /* IN */
)
{
+#if DEBUG & DEBUG_COUNT_NODES
Nfs nfs = ((NfsNode)pathloc->node_access)->nfs;
-#if DEBUG & DEBUG_COUNT_NODES
/* print counts at entry where they are > 0 so 'nfs' is safe from being destroyed
* and there's no race condition
*/
@@ -1831,22 +1615,7 @@ Nfs nfs = ((NfsNode)pathloc->node_access)->nfs;
nfs->stringsInUse);
#endif
- /* never destroy the root node; it is released by the unmount
- * code
- */
- if (locIsRoot(pathloc)) {
- unsigned long flags;
- /* just adjust the references to the root node but
- * don't really release it
- */
- rtems_interrupt_disable(flags);
- nfs->nodesInUse--;
- rtems_interrupt_enable(flags);
- } else {
- nfsNodeDestroy(pathloc->node_access);
- pathloc->node_access = 0;
- }
- return 0;
+ nfsNodeDestroy(pathloc->node_access);
}
/* NOTE/TODO: mounting on top of NFS is not currently supported
@@ -1982,12 +1751,12 @@ char *path = mt_entry->dev;
/* looks good so far */
- mt_entry->mt_fs_root.node_access = rootNode;
+ mt_entry->mt_fs_root->location.node_access = rootNode;
rootNode = 0;
- mt_entry->mt_fs_root.ops = &nfs_fs_ops;
- mt_entry->mt_fs_root.handlers = &nfs_dir_file_handlers;
+ mt_entry->mt_fs_root->location.ops = &nfs_fs_ops;
+ mt_entry->mt_fs_root->location.handlers = &nfs_dir_file_handlers;
mt_entry->pathconf_limits_and_options = nfs_limits_and_options;
LOCK(nfsGlob.llock);
@@ -2016,7 +1785,7 @@ cleanup:
}
/* This op is called when they try to unmount THIS fs */
-STATIC int nfs_fsunmount_me(
+STATIC void nfs_fsunmount_me(
rtems_filesystem_mount_table_entry_t *mt_entry /* in */
)
{
@@ -2035,7 +1804,8 @@ LOCK(nfsGlob.llock);
fprintf(stderr,
"Refuse to unmount; there are still %i nodes in use (1 used by us)\n",
nodesInUse);
- rtems_set_errno_and_return_minus_one(EBUSY);
+ rtems_fatal_error_occurred(0xdeadbeef);
+ return;
}
status = buildIpAddr(&uid, &gid, 0, &saddr, &path);
@@ -2052,20 +1822,17 @@ LOCK(nfsGlob.llock);
if (stat) {
UNLOCK(nfsGlob.llock);
fprintf(stderr,"NFS UMOUNT -- %s\n", clnt_sperrno(stat));
- errno = EIO;
- return -1;
+ return;
}
- nfsNodeDestroy(mt_entry->mt_fs_root.node_access);
- mt_entry->mt_fs_root.node_access = 0;
+ nfsNodeDestroy(mt_entry->mt_fs_root->location.node_access);
+ mt_entry->mt_fs_root->location.node_access = 0;
nfsDestroy(mt_entry->fs_info);
mt_entry->fs_info = 0;
nfsGlob.num_mounted_fs--;
UNLOCK(nfsGlob.llock);
-
- return 0;
}
/* OPTIONAL; may be NULL - BUT: CAUTION; mount() doesn't check
@@ -2073,10 +1840,10 @@ UNLOCK(nfsGlob.llock);
* //NOTE: (10/25/2002) patch submitted and probably applied
*/
static rtems_filesystem_node_types_t nfs_node_type(
- rtems_filesystem_location_info_t *pathloc /* in */
+ const rtems_filesystem_location_info_t *loc
)
{
-NfsNode node = pathloc->node_access;
+NfsNode node = loc->node_access;
if (updateAttr(node, 0 /* only if old */))
return -1;
@@ -2104,28 +1871,35 @@ NfsNode node = pathloc->node_access;
}
static int nfs_mknod(
- const char *path, /* IN */
- mode_t mode, /* IN */
- dev_t dev, /* IN */
- rtems_filesystem_location_info_t *pathloc /* IN/OUT */
+ const rtems_filesystem_location_info_t *parentloc,
+ const char *name,
+ size_t namelen,
+ mode_t mode,
+ dev_t dev
)
{
+int rv = 0;
struct timeval now;
diropres res;
-NfsNode node = pathloc->node_access;
+NfsNode node = parentloc->node_access;
mode_t type = S_IFMT & mode;
+char *dupname;
if (type != S_IFDIR && type != S_IFREG)
rtems_set_errno_and_return_minus_one(ENOTSUP);
+ dupname = nfs_dupname(name, namelen);
+ if (dupname == NULL)
+ return -1;
+
#if DEBUG & DEBUG_SYSCALLS
- fprintf(stderr,"nfs_mknod: creating %s\n", path);
+ fprintf(stderr,"nfs_mknod: creating %s\n", dupname);
#endif
rtems_clock_get_tod_timeval(&now);
- SERP_ARGS(node).createarg.name = (filename)path;
+ SERP_ARGS(node).createarg.name = dupname;
SERP_ARGS(node).createarg.attributes.mode = mode;
/* TODO: either use our uid or use the Nfs credentials */
SERP_ARGS(node).createarg.attributes.uid = 0;
@@ -2144,16 +1918,40 @@ mode_t type = S_IFMT & mode;
#if DEBUG & DEBUG_SYSCALLS
perror("nfs_mknod");
#endif
- return -1;
+ rv = -1;
}
- return 0;
+ free(dupname);
+
+ return rv;
+}
+
+static int nfs_rmnod(
+ const rtems_filesystem_location_info_t *parentloc,
+ const rtems_filesystem_location_info_t *loc
+)
+{
+ int rv = 0;
+ NfsNode node = loc->node_access;
+ int force_update = 0;
+
+ if (updateAttr(node, force_update) == 0) {
+ int proc = SERP_ATTR(node).type == NFDIR
+ ? NFSPROC_RMDIR
+ : NFSPROC_REMOVE;
+
+ rv = nfs_do_unlink(parentloc, loc, proc);
+ } else {
+ rv = -1;
+ }
+
+ return rv;
}
static int nfs_utime(
- rtems_filesystem_location_info_t *pathloc, /* IN */
- time_t actime, /* IN */
- time_t modtime /* IN */
+ const rtems_filesystem_location_info_t *pathloc, /* IN */
+ time_t actime, /* IN */
+ time_t modtime /* IN */
)
{
sattr arg;
@@ -2168,24 +1966,30 @@ sattr arg;
}
static int nfs_symlink(
- rtems_filesystem_location_info_t *loc, /* IN */
- const char *link_name, /* IN */
- const char *node_name
+ const rtems_filesystem_location_info_t *parentloc,
+ const char *name,
+ size_t namelen,
+ const char *target
)
{
+int rv = 0;
struct timeval now;
nfsstat status;
-NfsNode node = loc->node_access;
+NfsNode node = parentloc->node_access;
+char *dupname;
+ dupname = nfs_dupname(name, namelen);
+ if (dupname == NULL)
+ return -1;
#if DEBUG & DEBUG_SYSCALLS
- fprintf(stderr,"nfs_symlink: creating %s -> %s\n", link_name, node_name);
+ fprintf(stderr,"nfs_symlink: creating %s -> %s\n", dupname, target);
#endif
rtems_clock_get_tod_timeval(&now);
- SERP_ARGS(node).symlinkarg.name = (filename)link_name;
- SERP_ARGS(node).symlinkarg.to = (nfspath) node_name;
+ SERP_ARGS(node).symlinkarg.name = dupname;
+ SERP_ARGS(node).symlinkarg.to = (nfspath) target;
SERP_ARGS(node).symlinkarg.attributes.mode = S_IFLNK | S_IRWXU | S_IRWXG | S_IRWXO;
/* TODO */
@@ -2205,243 +2009,103 @@ NfsNode node = loc->node_access;
#if DEBUG & DEBUG_SYSCALLS
perror("nfs_symlink");
#endif
- return -1;
+ rv = -1;
}
- return 0;
+ free(dupname);
+
+ return rv;
}
-static int nfs_do_readlink(
- rtems_filesystem_location_info_t *loc, /* IN */
- strbuf *psbuf /* IN/OUT */
+static ssize_t nfs_readlink(
+ const rtems_filesystem_location_info_t *loc,
+ char *buf,
+ size_t len
)
{
-NfsNode node = loc->node_access;
-Nfs nfs = node->nfs;
-readlinkres_strbuf rr;
-int wasAlloced;
-int rval;
-
- rr.strbuf = *psbuf;
+ NfsNode node = loc->node_access;
+ Nfs nfs = node->nfs;
+ readlinkres_strbuf rr;
- wasAlloced = (0 == psbuf->buf);
+ rr.strbuf.buf = buf;
+ rr.strbuf.max = len - 1;
- if ( (rval = nfscall(nfs->server,
+ if ( nfscall(nfs->server,
NFSPROC_READLINK,
(xdrproc_t)xdr_nfs_fh, &SERP_FILE(node),
- (xdrproc_t)xdr_readlinkres_strbuf, &rr)) ) {
- if (wasAlloced)
- xdr_free( (xdrproc_t)xdr_strbuf, (caddr_t)&rr.strbuf );
- }
-
-
- if (NFS_OK != rr.status) {
- if (wasAlloced)
- xdr_free( (xdrproc_t)xdr_strbuf, (caddr_t)&rr.strbuf );
- rtems_set_errno_and_return_minus_one(rr.status);
+ (xdrproc_t)xdr_readlinkres_strbuf, &rr)
+ || (NFS_OK != (errno = rr.status)) ) {
+#if DEBUG & DEBUG_SYSCALLS
+ perror("nfs_readlink");
+#endif
+ return -1;
}
- *psbuf = rr.strbuf;
-
- return 0;
+ return (ssize_t) strlen(rr.strbuf.buf);
}
-static ssize_t nfs_readlink(
- rtems_filesystem_location_info_t *loc, /* IN */
- char *buf, /* OUT */
- size_t len
-)
+static void nfs_lock(rtems_filesystem_mount_table_entry_t *mt_entry)
{
-strbuf sbuf;
- sbuf.buf = buf;
- sbuf.max = len;
-
- return nfs_do_readlink(loc, &sbuf);
}
-/* The semantics of this routine are:
- *
- * The caller submits a valid pathloc, i.e. it has
- * an NfsNode attached to node_access.
- * On return, pathloc points to the target node which
- * may or may not be an NFS node.
- * Hence, the original NFS node is released in either
- * case:
- * - link evaluation fails; pathloc points to no valid node
- * - link evaluation success; pathloc points to a new valid
- * node. If it's an NFS node, a new NfsNode will be attached
- * to node_access...
- */
-
-#define LINKVAL_BUFLEN (MAXPATHLEN+1)
-#define RVAL_ERR_BUT_DONT_FREENODE (-1)
-#define RVAL_ERR_AND_DO_FREENODE ( 1)
-#define RVAL_OK ( 0)
+static void nfs_unlock(rtems_filesystem_mount_table_entry_t *mt_entry)
+{
+}
-static int nfs_eval_link(
- rtems_filesystem_location_info_t *pathloc, /* IN/OUT */
- int flags /* IN */
+static bool nfs_are_nodes_equal(
+ const rtems_filesystem_location_info_t *a,
+ const rtems_filesystem_location_info_t *b
)
{
-rtems_filesystem_node_types_t type;
-char *buf = malloc(LINKVAL_BUFLEN);
-int rval = RVAL_ERR_AND_DO_FREENODE;
+ bool equal = false;
+ NfsNode na = a->node_access;
- if (!buf) {
- errno = ENOMEM;
- goto cleanup;
- }
-
- /* in this loop, we must not use NFS specific ops as we might
- * step out of our FS during the process...
- * This algorithm should actually be performed by the
- * generic's evaluate_path routine :-(
- *
- * Unfortunately, there is no way of finding the
- * directory node who contains 'pathloc', however :-(
- */
- do {
- /* assume the generics have verified 'pathloc' to be
- * a link...
- */
- if ( !pathloc->ops->readlink_h ) {
- errno = ENOTSUP;
- goto cleanup;
- }
-
- if ( pathloc->ops->readlink_h(pathloc, buf, LINKVAL_BUFLEN) ) {
- goto cleanup;
- }
-
-#if DEBUG & DEBUG_EVALPATH
- fprintf(stderr, "link value is '%s'\n", buf);
-#endif
-
- /* is the link value an absolute path ? */
- if ( DELIM != *buf ) {
- /* NO; a relative path */
-
- /* we must backup to the link's directory - we
- * know only how to do that for NFS, however.
- * In this special case, we can avoid recursion.
- * Otherwise (i.e. if the link is on another FS),
- * we must step into its eval_link_h().
- */
- if (locIsNfs(pathloc)) {
- NfsNode node = pathloc->node_access;
- int err;
-
- memcpy( &SERP_FILE(node),
- &node->args.dir,
- sizeof(node->args.dir) );
-
- if (updateAttr(node, 1 /* force */))
- goto cleanup;
-
- if (SERP_ATTR(node).type != NFDIR) {
- errno = ENOTDIR;
- goto cleanup;
- }
-
- pathloc->handlers = &nfs_dir_file_handlers;
-
- err = nfs_evalpath(buf, strlen(buf), flags, pathloc);
-
- /* according to its semantics,
- * nfs_evalpath cloned the node attached
- * to pathloc. Hence we have to
- * release the old one (referring to
- * the link; the new clone has been
- * updated and refers to the link _value_).
- */
- nfsNodeDestroy(node);
-
- if (err) {
- /* nfs_evalpath has set errno;
- * pathloc->node_access has no
- * valid node attached in this case
- */
- rval = RVAL_ERR_BUT_DONT_FREENODE;
- goto cleanup;
- }
-
- } else {
- if ( ! pathloc->ops->eval_link_h ) {
- errno = ENOTSUP;
- goto cleanup;
- }
- if (!pathloc->ops->eval_link_h(pathloc, flags)) {
- /* FS is responsible for freeing its pathloc->node_access
- * if necessary
- */
- rval = RVAL_ERR_BUT_DONT_FREENODE;
- goto cleanup;
- }
- }
- } else {
- /* link points to an absolute path '/xxx' */
-
- /* release this node; filesystem_evaluate_path() will
- * lookup a new one.
- */
- rtems_filesystem_freenode(pathloc);
-
- if (rtems_filesystem_evaluate_path(buf, strlen(buf), flags, pathloc, 1)) {
- /* If evalpath fails then there is no valid node
- * attached to pathloc; hence we must not attempt
- * to free the node
- */
- rval = RVAL_ERR_BUT_DONT_FREENODE;
- goto cleanup;
- }
- }
+ if (updateAttr(na, 0) == 0) {
+ NfsNode nb = b->node_access;
- if ( !pathloc->ops->node_type_h ) {
- errno = ENOTSUP;
- goto cleanup;
+ if (updateAttr(nb, 0) == 0) {
+ equal = SERP_ATTR(na).fileid == SERP_ATTR(nb).fileid
+ && SERP_ATTR(na).fsid == SERP_ATTR(nb).fsid;
}
-
- type = pathloc->ops->node_type_h(pathloc);
-
-
- /* I dont know what to do about hard links */
- } while ( RTEMS_FILESYSTEM_SYM_LINK == type );
-
- rval = RVAL_OK;
-
-cleanup:
-
- free(buf);
-
- if (RVAL_ERR_AND_DO_FREENODE == rval) {
- rtems_filesystem_freenode(pathloc);
- return -1;
}
- return rval;
+ return equal;
}
+static int nfs_fchmod(
+ const rtems_filesystem_location_info_t *loc,
+ mode_t mode
+)
+{
+sattr arg;
+
+ arg.mode = mode;
+ return nfs_sattr(loc->node_access, &arg, SATTR_MODE);
-struct _rtems_filesystem_operations_table nfs_fs_ops = {
- nfs_evalpath, /* MANDATORY */
- nfs_evalformake, /* MANDATORY; may set errno=ENOSYS and return -1 */
- nfs_link, /* OPTIONAL; may be defaulted */
- nfs_unlink, /* OPTIONAL; may be defaulted */
- nfs_node_type, /* OPTIONAL; may be defaulted; BUG in mount - no test!! */
- nfs_mknod, /* OPTIONAL; may be defaulted */
- nfs_chown, /* OPTIONAL; may be defaulted */
- nfs_freenode, /* OPTIONAL; may be defaulted; (release node_access) */
- rtems_filesystem_default_mount,
- rtems_nfs_initialize, /* OPTIONAL; may be defaulted -- not used anymore */
- rtems_filesystem_default_unmount,
- nfs_fsunmount_me, /* OPTIONAL; may be defaulted */
- nfs_utime, /* OPTIONAL; may be defaulted */
- nfs_eval_link, /* OPTIONAL; may be defaulted */
- nfs_symlink, /* OPTIONAL; may be defaulted */
- nfs_readlink, /* OPTIONAL; may be defaulted */
- rtems_filesystem_default_rename, /* OPTIONAL; may be defaulted */
- rtems_filesystem_default_statvfs /* OPTIONAL; may be defaulted */
+}
+const struct _rtems_filesystem_operations_table nfs_fs_ops = {
+ .lock_h = nfs_lock,
+ .unlock_h = nfs_unlock,
+ .eval_path_h = nfs_eval_path,
+ .link_h = nfs_link,
+ .are_nodes_equal_h = nfs_are_nodes_equal,
+ .node_type_h = nfs_node_type,
+ .mknod_h = nfs_mknod,
+ .rmnod_h = nfs_rmnod,
+ .fchmod_h = nfs_fchmod,
+ .chown_h = nfs_chown,
+ .clonenod_h = nfs_clonenode,
+ .freenod_h = nfs_freenode,
+ .mount_h = rtems_filesystem_default_mount,
+ .fsmount_me_h = rtems_nfs_initialize,
+ .unmount_h = rtems_filesystem_default_unmount,
+ .fsunmount_me_h = nfs_fsunmount_me,
+ .utime_h = nfs_utime,
+ .symlink_h = nfs_symlink,
+ .readlink_h = nfs_readlink,
+ .rename_h = rtems_filesystem_default_rename,
+ .statvfs_h = rtems_filesystem_default_statvfs
};
/*****************************************
@@ -2472,8 +2136,8 @@ struct _rtems_filesystem_operations_table nfs_fs_ops = {
static int nfs_file_open(
rtems_libio_t *iop,
const char *pathname,
- uint32_t flag,
- uint32_t mode
+ int oflag,
+ mode_t mode
)
{
return 0;
@@ -2487,8 +2151,8 @@ static int nfs_file_open(
static int nfs_dir_open(
rtems_libio_t *iop,
const char *pathname,
- uint32_t flag,
- uint32_t mode
+ int oflag,
+ mode_t mode
)
{
NfsNode node = iop->pathinfo.node_access;
@@ -2796,8 +2460,8 @@ struct stat
/* common for file/dir/link */
static int nfs_fstat(
- rtems_filesystem_location_info_t *loc,
- struct stat *buf
+ const rtems_filesystem_location_info_t *loc,
+ struct stat *buf
)
{
NfsNode node = loc->node_access;
@@ -2939,20 +2603,6 @@ u_int mode;
return 0;
}
-
-/* common for file/dir/link */
-static int nfs_fchmod(
- rtems_filesystem_location_info_t *loc,
- mode_t mode
-)
-{
-sattr arg;
-
- arg.mode = mode;
- return nfs_sattr(loc->node_access, &arg, SATTR_MODE);
-
-}
-
/* just set the size attribute to 'length'
* the server will take care of the rest :-)
*/
@@ -2973,71 +2623,52 @@ sattr arg;
SATTR_SIZE);
}
-/* files and symlinks are removed
- * by the common nfs_unlink() routine.
- * NFS has a different NFSPROC_RMDIR
- * call, though...
- */
-static int nfs_dir_rmnod(
- rtems_filesystem_location_info_t *parentpathloc, /* IN */
- rtems_filesystem_location_info_t *pathloc /* IN */
-)
-{
- return nfs_do_unlink(parentpathloc, pathloc, NFSPROC_RMDIR);
-}
-
/* the file handlers table */
-static
+static const
struct _rtems_filesystem_file_handlers_r nfs_file_file_handlers = {
- nfs_file_open, /* OPTIONAL; may be defaulted */
- nfs_file_close, /* OPTIONAL; may be defaulted */
- nfs_file_read, /* OPTIONAL; may be defaulted */
- nfs_file_write, /* OPTIONAL; may be defaulted */
- rtems_filesystem_default_ioctl,
- nfs_file_lseek, /* OPTIONAL; may be defaulted */
- nfs_fstat, /* OPTIONAL; may be defaulted */
- nfs_fchmod, /* OPTIONAL; may be defaulted */
- nfs_file_ftruncate, /* OPTIONAL; may be defaulted */
- rtems_filesystem_default_fsync,
- rtems_filesystem_default_fdatasync,
- rtems_filesystem_default_fcntl,
- nfs_unlink, /* OPTIONAL; may be defaulted */
+ .open_h = nfs_file_open,
+ .close_h = nfs_file_close,
+ .read_h = nfs_file_read,
+ .write_h = nfs_file_write,
+ .ioctl_h = rtems_filesystem_default_ioctl,
+ .lseek_h = nfs_file_lseek,
+ .fstat_h = nfs_fstat,
+ .ftruncate_h = nfs_file_ftruncate,
+ .fsync_h = rtems_filesystem_default_fsync,
+ .fdatasync_h = rtems_filesystem_default_fdatasync,
+ .fcntl_h = rtems_filesystem_default_fcntl
};
/* the directory handlers table */
-static
+static const
struct _rtems_filesystem_file_handlers_r nfs_dir_file_handlers = {
- nfs_dir_open, /* OPTIONAL; may be defaulted */
- nfs_dir_close, /* OPTIONAL; may be defaulted */
- nfs_dir_read, /* OPTIONAL; may be defaulted */
- rtems_filesystem_default_write,
- rtems_filesystem_default_ioctl,
- nfs_dir_lseek, /* OPTIONAL; may be defaulted */
- nfs_fstat, /* OPTIONAL; may be defaulted */
- nfs_fchmod, /* OPTIONAL; may be defaulted */
- rtems_filesystem_default_ftruncate,
- rtems_filesystem_default_fsync,
- rtems_filesystem_default_fdatasync,
- rtems_filesystem_default_fcntl,
- nfs_dir_rmnod, /* OPTIONAL; may be defaulted */
+ .open_h = nfs_dir_open,
+ .close_h = nfs_dir_close,
+ .read_h = nfs_dir_read,
+ .write_h = rtems_filesystem_default_write,
+ .ioctl_h = rtems_filesystem_default_ioctl,
+ .lseek_h = nfs_dir_lseek,
+ .fstat_h = nfs_fstat,
+ .ftruncate_h = rtems_filesystem_default_ftruncate_directory,
+ .fsync_h = rtems_filesystem_default_fsync,
+ .fdatasync_h = rtems_filesystem_default_fdatasync,
+ .fcntl_h = rtems_filesystem_default_fcntl
};
/* the link handlers table */
-static
+static const
struct _rtems_filesystem_file_handlers_r nfs_link_file_handlers = {
- rtems_filesystem_default_open,
- rtems_filesystem_default_close,
- rtems_filesystem_default_read,
- rtems_filesystem_default_write,
- rtems_filesystem_default_ioctl,
- rtems_filesystem_default_lseek,
- nfs_fstat, /* OPTIONAL; may be defaulted */
- nfs_fchmod, /* OPTIONAL; may be defaulted */
- rtems_filesystem_default_ftruncate,
- rtems_filesystem_default_fsync,
- rtems_filesystem_default_fdatasync,
- rtems_filesystem_default_fcntl,
- nfs_unlink, /* OPTIONAL; may be defaulted */
+ .open_h = rtems_filesystem_default_open,
+ .close_h = rtems_filesystem_default_close,
+ .read_h = rtems_filesystem_default_read,
+ .write_h = rtems_filesystem_default_write,
+ .ioctl_h = rtems_filesystem_default_ioctl,
+ .lseek_h = rtems_filesystem_default_lseek,
+ .fstat_h = nfs_fstat,
+ .ftruncate_h = rtems_filesystem_default_ftruncate,
+ .fsync_h = rtems_filesystem_default_fsync,
+ .fdatasync_h = rtems_filesystem_default_fdatasync,
+ .fcntl_h = rtems_filesystem_default_fcntl
};
/* we need a dummy driver entry table to get a
@@ -3096,7 +2727,7 @@ Nfs nfs;
for (nfs = nfsGlob.mounted_fs; nfs; nfs=nfs->next) {
fprintf(f,"%s on ", nfs->mt_entry->dev);
- if (rtems_filesystem_resolve_location(mntpt, MAXPATHLEN, &nfs->mt_entry->mt_fs_root))
+ if (rtems_filesystem_resolve_location(mntpt, MAXPATHLEN, &nfs->mt_entry->mt_fs_root->location))
fprintf(f,"<UNABLE TO LOOKUP MOUNTPOINT>\n");
else
fprintf(f,"%s\n",mntpt);
@@ -3236,15 +2867,15 @@ rtems_filesystem_location_info_t old;
/* IMPORTANT: let the helper task have its own libio environment (i.e. cwd) */
if (RTEMS_SUCCESSFUL == (rpa->status = rtems_libio_set_private_env())) {
- old = rtems_filesystem_current;
+ old = rtems_filesystem_current->location;
- rtems_filesystem_current = *(rpa->loc);
+ rtems_filesystem_current->location = *(rpa->loc);
if ( !getcwd(rpa->buf, rpa->len) )
rpa->status = RTEMS_UNSATISFIED;
/* must restore the cwd because 'freenode' will be called on it */
- rtems_filesystem_current = old;
+ rtems_filesystem_current->location = old;
}
rtems_semaphore_release(rpa->sync);
rtems_task_delete(RTEMS_SELF);