summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2012-05-16 12:41:33 +0200
committerSebastian Huber <sebastian.huber@embedded-brains.de>2012-05-16 12:41:33 +0200
commitffd9575a7637688466e675cd81ac88d1a57440b5 (patch)
treec34327e9af1e03f6d8bdf6613c8399dddc9d2681
parentMerge branch 'upstream' (diff)
parentnfsclient: Fix symbolic link evaluation (diff)
downloadrtems-ffd9575a7637688466e675cd81ac88d1a57440b5.tar.bz2
Merge branch 'upstream'
-rw-r--r--cpukit/libcsupport/include/rtems/libcsupport.h2
-rw-r--r--cpukit/libcsupport/include/rtems/malloc.h1
-rw-r--r--cpukit/libcsupport/src/malloc_walk.c4
-rw-r--r--cpukit/libfs/src/nfsclient/src/nfs.c163
-rw-r--r--testsuites/libtests/malloctest/init.c12
-rw-r--r--testsuites/libtests/malloctest/task1.c8
6 files changed, 111 insertions, 79 deletions
diff --git a/cpukit/libcsupport/include/rtems/libcsupport.h b/cpukit/libcsupport/include/rtems/libcsupport.h
index bbe8e41da8..d2640476df 100644
--- a/cpukit/libcsupport/include/rtems/libcsupport.h
+++ b/cpukit/libcsupport/include/rtems/libcsupport.h
@@ -34,7 +34,7 @@ void RTEMS_Malloc_Initialize(
);
extern void malloc_dump(void);
-extern void malloc_walk(size_t source, size_t printf_enabled);
+extern bool malloc_walk(int source, bool printf_enabled);
void malloc_set_heap_pointer(Heap_Control *new_heap);
Heap_Control *malloc_get_heap_pointer( void );
extern void libc_init(void);
diff --git a/cpukit/libcsupport/include/rtems/malloc.h b/cpukit/libcsupport/include/rtems/malloc.h
index e4d7ee8ce8..7f56a842e5 100644
--- a/cpukit/libcsupport/include/rtems/malloc.h
+++ b/cpukit/libcsupport/include/rtems/malloc.h
@@ -18,6 +18,7 @@
#include <rtems.h>
#include <rtems/bspIo.h>
+#include <rtems/libcsupport.h> /* for malloc_walk() */
#include <stdint.h>
diff --git a/cpukit/libcsupport/src/malloc_walk.c b/cpukit/libcsupport/src/malloc_walk.c
index 209d19bd6f..fa810888c9 100644
--- a/cpukit/libcsupport/src/malloc_walk.c
+++ b/cpukit/libcsupport/src/malloc_walk.c
@@ -18,9 +18,9 @@
#include <stdlib.h>
-void malloc_walk(size_t source, size_t printf_enabled)
+bool malloc_walk(int source, bool printf_enabled)
{
- _Protected_heap_Walk( RTEMS_Malloc_Heap, (int) source, printf_enabled );
+ return _Protected_heap_Walk( RTEMS_Malloc_Heap, source, printf_enabled );
}
#endif
diff --git a/cpukit/libfs/src/nfsclient/src/nfs.c b/cpukit/libfs/src/nfsclient/src/nfs.c
index bff5d6da16..bbec6b803c 100644
--- a/cpukit/libfs/src/nfsclient/src/nfs.c
+++ b/cpukit/libfs/src/nfsclient/src/nfs.c
@@ -574,8 +574,8 @@ typedef struct NfsNodeRec_ {
Forward Declarations
*****************************************/
-static ssize_t nfs_readlink(
- const rtems_filesystem_location_info_t *loc,
+static ssize_t nfs_readlink_with_node(
+ NfsNode node,
char *buf,
size_t len
);
@@ -1299,19 +1299,24 @@ static bool nfs_is_directory(
return is_dir;
}
-static NfsNode nfs_search_in_directory(
+static int nfs_search_in_directory(
Nfs nfs,
- NfsNode node,
- char *part
+ const NfsNode dir,
+ char *part,
+ NfsNode entry
)
{
int rv;
+ entry->nfs = nfs;
+
/* lookup one element */
- SERP_ARGS(node).diroparg.name = part;
+ SERP_ATTR(entry) = SERP_ATTR(dir);
+ SERP_FILE(entry) = SERP_FILE(dir);
+ SERP_ARGS(entry).diroparg.name = part;
/* remember args / directory fh */
- memcpy( &node->args, &SERP_FILE(node), sizeof(node->args));
+ memcpy(&entry->args, &SERP_FILE(dir), sizeof(dir->args));
#if DEBUG & DEBUG_EVALPATH
fprintf(stderr,"Looking up '%s'\n",part);
@@ -1320,92 +1325,100 @@ static NfsNode nfs_search_in_directory(
rv = nfscall(
nfs->server,
NFSPROC_LOOKUP,
- (xdrproc_t) xdr_diropargs, &SERP_FILE(node),
- (xdrproc_t) xdr_serporid, &node->serporid
+ (xdrproc_t) xdr_diropargs, &SERP_FILE(entry),
+ (xdrproc_t) xdr_serporid, &entry->serporid
);
- if (rv == 0 && node->serporid.status == NFS_OK) {
+ if (rv == 0 && entry->serporid.status == NFS_OK) {
int force_update = 1;
- rv = updateAttr(node, force_update);
- if (rv != 0) {
- node = NULL;
- }
+ rv = updateAttr(entry, force_update);
} else {
- node = NULL;
+ rv = -1;
}
- return node;
+ return rv;
}
-static void nfs_follow_link(rtems_filesystem_eval_path_context_t *ctx)
+static void nfs_eval_follow_link(
+ rtems_filesystem_eval_path_context_t *ctx,
+ NfsNode link
+)
{
const size_t len = NFS_MAXPATHLEN + 1;
- char *link = malloc(len);
+ char *buf = malloc(len);
- 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 (buf != NULL) {
+ ssize_t rv = nfs_readlink_with_node(link, buf, len);
if (rv >= 0) {
- rtems_filesystem_eval_path_recursive(ctx, link, (size_t) rv);
+ rtems_filesystem_eval_path_recursive(ctx, buf, (size_t) rv);
} else {
rtems_filesystem_eval_path_error(ctx, 0);
}
- free(link);
+ free(buf);
} else {
rtems_filesystem_eval_path_error(ctx, ENOMEM);
}
}
-static bool nfs_update_currentloc(
+static void nfs_eval_set_handlers(
rtems_filesystem_eval_path_context_t *ctx,
- Nfs nfs,
- NfsNode node
+ ftype type
)
{
- bool ok = true;
- rtems_filesystem_location_info_t *pathloc =
+ rtems_filesystem_location_info_t *currentloc =
rtems_filesystem_eval_path_get_currentloc(ctx);
- pathloc->node_access = node;
-
- 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;
+ switch (type) {
+ case NFDIR:
+ currentloc->handlers = &nfs_dir_file_handlers;
+ break;
+ case NFREG:
+ currentloc->handlers = &nfs_file_file_handlers;
+ break;
+ case NFLNK:
+ currentloc->handlers = &nfs_link_file_handlers;
+ break;
+ default:
+ currentloc->handlers = &rtems_filesystem_handlers_default;
+ break;
}
+}
- /* remember the name of this directory entry */
+static int nfs_move_node(NfsNode dst, const NfsNode src)
+{
+ int rv = 0;
- if (node->args.name) {
- if (node->str) {
+ if (dst->str != NULL) {
#if DEBUG & DEBUG_COUNT_NODES
- rtems_interrupt_level flags;
- rtems_interrupt_disable(flags);
- nfs->stringsInUse--;
- rtems_interrupt_enable(flags);
+ rtems_interrupt_level flags;
+ rtems_interrupt_disable(flags);
+ dst->nfs->stringsInUse--;
+ rtems_interrupt_enable(flags);
#endif
- free(node->str);
- }
- node->args.name = node->str = strdup(node->args.name);
- if (node->str != NULL) {
+ free(dst->str);
+ }
+
+ *dst = *src;
+ dst->str = NULL;
+
+ if (src->args.name != NULL) {
+ dst->str = dst->args.name = strdup(src->args.name);
+ if (dst->str != NULL) {
#if DEBUG & DEBUG_COUNT_NODES
rtems_interrupt_level flags;
rtems_interrupt_disable(flags);
- nfs->stringsInUse++;
+ dst->nfs->stringsInUse++;
rtems_interrupt_enable(flags);
#endif
} else {
- rtems_filesystem_eval_path_error(ctx, ENOMEM);
- ok = false;
+ rv = -1;
}
}
- return ok;
+ return rv;
}
static rtems_filesystem_eval_path_generic_status nfs_eval_part(
@@ -1419,20 +1432,28 @@ static rtems_filesystem_eval_path_generic_status nfs_eval_part(
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);
+ NfsNodeRec entry;
+ int rv = nfs_search_in_directory(nfs, dir, part, &entry);
- if (entry != NULL) {
- rtems_filesystem_eval_path_clear_token(ctx);
+ if (rv == 0) {
+ bool terminal = !rtems_filesystem_eval_path_has_path(ctx);
+ int eval_flags = rtems_filesystem_eval_path_get_flags(ctx);
+ bool follow_sym_link = (eval_flags & RTEMS_FS_FOLLOW_SYM_LINK) != 0;
+ ftype type = SERP_ATTR(&entry).type;
- if (nfs_update_currentloc(ctx, nfs, entry)) {
- int eval_flags = rtems_filesystem_eval_path_get_flags(ctx);
- bool follow_sym_link = (eval_flags & RTEMS_FS_FOLLOW_SYM_LINK) != 0;
- bool terminal = !rtems_filesystem_eval_path_has_path( ctx );
+ rtems_filesystem_eval_path_clear_token(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;
+ if (type == NFLNK && (follow_sym_link || !terminal)) {
+ nfs_eval_follow_link(ctx, &entry);
+ } else {
+ rv = nfs_move_node(dir, &entry);
+ if (rv == 0) {
+ nfs_eval_set_handlers(ctx, type);
+ if (!terminal) {
+ status = RTEMS_FILESYSTEM_EVAL_PATH_GENERIC_CONTINUE;
+ }
+ } else {
+ rtems_filesystem_eval_path_error(ctx, ENOMEM);
}
}
} else {
@@ -2015,13 +2036,12 @@ char *dupname;
return rv;
}
-static ssize_t nfs_readlink(
- const rtems_filesystem_location_info_t *loc,
+static ssize_t nfs_readlink_with_node(
+ NfsNode node,
char *buf,
size_t len
)
{
- NfsNode node = loc->node_access;
Nfs nfs = node->nfs;
readlinkres_strbuf rr;
@@ -2034,7 +2054,7 @@ static ssize_t nfs_readlink(
(xdrproc_t)xdr_readlinkres_strbuf, &rr)
|| (NFS_OK != (errno = rr.status)) ) {
#if DEBUG & DEBUG_SYSCALLS
- perror("nfs_readlink");
+ perror("nfs_readlink_with_node");
#endif
return -1;
}
@@ -2042,6 +2062,17 @@ static ssize_t nfs_readlink(
return (ssize_t) strlen(rr.strbuf.buf);
}
+static ssize_t nfs_readlink(
+ const rtems_filesystem_location_info_t *loc,
+ char *buf,
+ size_t len
+)
+{
+ NfsNode node = loc->node_access;
+
+ return nfs_readlink_with_node(node, buf, len);
+}
+
static int nfs_rename(
const rtems_filesystem_location_info_t *oldparentloc,
const rtems_filesystem_location_info_t *oldloc,
diff --git a/testsuites/libtests/malloctest/init.c b/testsuites/libtests/malloctest/init.c
index b81df2c1d9..a93edc41a6 100644
--- a/testsuites/libtests/malloctest/init.c
+++ b/testsuites/libtests/malloctest/init.c
@@ -34,10 +34,7 @@
#include <inttypes.h>
#include <errno.h>
#include <rtems/score/protectedheap.h>
-
-/* HACK: Blatant visibility violations */
-extern int malloc_info(Heap_Information_block *the_info);
-extern void malloc_walk(size_t source, size_t printf_enabled);
+#include <rtems/malloc.h>
/*
* A simple test of realloc
@@ -47,6 +44,7 @@ static void test_realloc(void)
void *p1, *p2, *p3, *p4;
size_t i;
int sc;
+ bool malloc_walk_ok;
/* Test growing reallocation "in place" */
p1 = malloc(1);
@@ -103,11 +101,13 @@ static void test_realloc(void)
* Walk the C Program Heap
*/
puts( "malloc_walk - normal path" );
- malloc_walk( 1234, 0 );
+ malloc_walk_ok = malloc_walk( 1234, false );
+ rtems_test_assert( malloc_walk_ok );
puts( "malloc_walk - in critical section path" );
_Thread_Disable_dispatch();
- malloc_walk( 1234, 0 );
+ malloc_walk_ok = malloc_walk( 1234, false );
+ rtems_test_assert( malloc_walk_ok );
_Thread_Enable_dispatch();
/*
diff --git a/testsuites/libtests/malloctest/task1.c b/testsuites/libtests/malloctest/task1.c
index c042c8a010..1416ae12c6 100644
--- a/testsuites/libtests/malloctest/task1.c
+++ b/testsuites/libtests/malloctest/task1.c
@@ -20,9 +20,6 @@
#include <string.h>
#include <stdlib.h>
-/* HACK: Blatant visibility violation */
-extern void malloc_walk(size_t source, size_t printf_enabled);
-
#define NUM_PASSES 100
rtems_task Task_1_through_5(
@@ -42,6 +39,8 @@ rtems_task Task_1_through_5(
while (TRUE)
{
+ bool malloc_walk_ok;
+
if ( passes++ > NUM_PASSES ) {
puts("*** END OF MALLOC TEST ***");
rtems_test_exit(0);
@@ -61,7 +60,8 @@ rtems_task Task_1_through_5(
printf("mallocing %d bytes\n",mem_amt);
memset( mem_ptr, mem_amt, mem_amt );
malloc_report_statistics();
- malloc_walk(1,FALSE);
+ malloc_walk_ok = malloc_walk( 1, false );
+ rtems_test_assert( malloc_walk_ok );
status = rtems_task_wake_after(
task_number( tid ) * 1 * rtems_clock_get_ticks_per_second()/4 );
for (i=0; i < mem_amt; i++)