Index: testsuites/fstests/Makefile.am
===================================================================
--- testsuites/fstests/Makefile.am	(revision 62f3fa84aac65623c95bcc1e48e5d71345adb256)
+++ testsuites/fstests/Makefile.am	(revision baef823cd550449bfbcc36625b9571389d8ad1af)
@@ -3,4 +3,5 @@
 _SUBDIRS  =
 _SUBDIRS += fsbdpart01
+_SUBDIRS += fsclose01
 _SUBDIRS += fsdosfsformat01
 _SUBDIRS += fsdosfsname01
Index: testsuites/fstests/configure.ac
===================================================================
--- testsuites/fstests/configure.ac	(revision 62f3fa84aac65623c95bcc1e48e5d71345adb256)
+++ testsuites/fstests/configure.ac	(revision baef823cd550449bfbcc36625b9571389d8ad1af)
@@ -79,4 +79,5 @@
 AC_CONFIG_FILES([Makefile
 fsbdpart01/Makefile
+fsclose01/Makefile
 fsdosfsformat01/Makefile
 fsdosfsname01/Makefile
Index: testsuites/fstests/fsclose01/Makefile.am
===================================================================
--- testsuites/fstests/fsclose01/Makefile.am	(revision baef823cd550449bfbcc36625b9571389d8ad1af)
+++ testsuites/fstests/fsclose01/Makefile.am	(revision baef823cd550449bfbcc36625b9571389d8ad1af)
@@ -0,0 +1,19 @@
+rtems_tests_PROGRAMS = fsclose01
+fsclose01_SOURCES = init.c
+
+dist_rtems_tests_DATA = fsclose01.scn fsclose01.doc
+
+include $(RTEMS_ROOT)/make/custom/@RTEMS_BSP@.cfg
+include $(top_srcdir)/../automake/compile.am
+include $(top_srcdir)/../automake/leaf.am
+
+AM_CPPFLAGS += -I$(top_srcdir)/../support/include
+
+LINK_OBJS = $(fsclose01_OBJECTS)
+LINK_LIBS = $(fsclose01_LDLIBS)
+
+fsclose01$(EXEEXT): $(fsclose01_OBJECTS) $(fsclose01_DEPENDENCIES)
+	@rm -f fsclose01$(EXEEXT)
+	$(make-exe)
+
+include $(top_srcdir)/../automake/local.am
Index: testsuites/fstests/fsclose01/fsclose01.scn
===================================================================
--- testsuites/fstests/fsclose01/fsclose01.scn	(revision baef823cd550449bfbcc36625b9571389d8ad1af)
+++ testsuites/fstests/fsclose01/fsclose01.scn	(revision baef823cd550449bfbcc36625b9571389d8ad1af)
@@ -0,0 +1,2 @@
+*** BEGIN OF TEST FSCLOSE 1 ***
+*** END OF TEST FSCLOSE 1 ***
Index: testsuites/fstests/fsclose01/init.c
===================================================================
--- testsuites/fstests/fsclose01/init.c	(revision baef823cd550449bfbcc36625b9571389d8ad1af)
+++ testsuites/fstests/fsclose01/init.c	(revision baef823cd550449bfbcc36625b9571389d8ad1af)
@@ -0,0 +1,511 @@
+/*
+ * Copyright (c) 2012, 2017 embedded brains GmbH.  All rights reserved.
+ *
+ *  embedded brains GmbH
+ *  Dornierstr. 4
+ *  82178 Puchheim
+ *  Germany
+ *  <rtems@embedded-brains.de>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <sys/stat.h>
+#include <sys/ioctl.h>
+#include <sys/uio.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <errno.h>
+
+#include <rtems/imfs.h>
+#include <rtems/malloc.h>
+#include <rtems/libcsupport.h>
+
+#include <tmacros.h>
+
+const char rtems_test_name[] = "FSCLOSE 1";
+
+typedef enum {
+  ACTION_ClOSE,
+  ACTION_FCNTL,
+  ACTION_FDATASYNC,
+  ACTION_FCHDIR,
+  ACTION_FCHMOD,
+  ACTION_FCHOWN,
+  /* ACTION_FPATHCONF, not easy to test */
+  ACTION_FSTAT,
+  ACTION_FSYNC,
+  ACTION_FTRUNCATE,
+  ACTION_IOCTL,
+  ACTION_LSEEK,
+  ACTION_READ,
+  ACTION_READV,
+  ACTION_WRITE,
+  ACTION_WRITEV
+} test_action;
+
+typedef struct {
+  rtems_id worker_id;
+  int fd;
+  test_action action;
+  bool wait_in_close;
+  bool wait_in_fstat;
+  int close_count;
+  int fcntl_count;
+  int fdatasync_count;
+  int fstat_count;
+  int fsync_count;
+  int ftruncate_count;
+  int ioctl_count;
+  int lseek_count;
+  int open_count;
+  int read_count;
+  int readv_count;
+  int write_count;
+  int writev_count;
+} test_context;
+
+static test_context test_instance;
+
+static void wait(void)
+{
+  rtems_status_code sc;
+
+  sc = rtems_event_transient_receive(RTEMS_WAIT, RTEMS_NO_TIMEOUT);
+  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+}
+
+static void wakeup_worker(const test_context *ctx)
+{
+  rtems_status_code sc;
+
+  sc = rtems_event_transient_send(ctx->worker_id);
+  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+}
+
+static int handler_open(
+  rtems_libio_t *iop,
+  const char *path,
+  int oflag,
+  mode_t mode
+)
+{
+  test_context *ctx;
+
+  ctx = IMFS_generic_get_context_by_iop(iop);
+  ++ctx->open_count;
+
+  return 0;
+}
+
+static int handler_close(
+  rtems_libio_t *iop
+)
+{
+  test_context *ctx;
+
+  ctx = IMFS_generic_get_context_by_iop(iop);
+  ++ctx->close_count;
+
+  if (ctx->wait_in_close) {
+    ctx->wait_in_close = false;
+    wait();
+  }
+
+  return 0;
+}
+
+static ssize_t handler_read(
+  rtems_libio_t *iop,
+  void *buffer,
+  size_t count
+)
+{
+  test_context *ctx;
+
+  ctx = IMFS_generic_get_context_by_iop(iop);
+  ++ctx->read_count;
+
+  wait();
+  return 0;
+}
+
+static ssize_t handler_write(
+  rtems_libio_t *iop,
+  const void *buffer,
+  size_t count
+)
+{
+  test_context *ctx;
+
+  ctx = IMFS_generic_get_context_by_iop(iop);
+  ++ctx->write_count;
+
+  wait();
+  return 0;
+}
+
+static int handler_ioctl(
+  rtems_libio_t *iop,
+  ioctl_command_t request,
+  void *buffer
+)
+{
+  test_context *ctx;
+
+  ctx = IMFS_generic_get_context_by_iop(iop);
+  ++ctx->ioctl_count;
+
+  wait();
+  return 0;
+}
+
+static off_t handler_lseek(
+  rtems_libio_t *iop,
+  off_t length,
+  int whence
+)
+{
+  test_context *ctx;
+
+  ctx = IMFS_generic_get_context_by_iop(iop);
+  ++ctx->lseek_count;
+
+  wait();
+  return 0;
+}
+
+static int handler_fstat(
+  const rtems_filesystem_location_info_t *loc,
+  struct stat *buf
+)
+{
+  test_context *ctx;
+
+  buf->st_mode = S_IFCHR | S_IRWXU | S_IRWXG | S_IRWXO;
+  ctx = IMFS_generic_get_context_by_location(loc);
+  ++ctx->fstat_count;
+
+  if (ctx->wait_in_fstat) {
+    ctx->wait_in_fstat = false;
+    wait();
+  }
+
+  return 0;
+}
+
+static int handler_ftruncate(
+  rtems_libio_t *iop,
+  off_t length
+)
+{
+  test_context *ctx;
+
+  ctx = IMFS_generic_get_context_by_iop(iop);
+  ++ctx->ftruncate_count;
+
+  wait();
+  return 0;
+}
+
+static int handler_fsync(
+  rtems_libio_t *iop
+)
+{
+  test_context *ctx;
+
+  ctx = IMFS_generic_get_context_by_iop(iop);
+  ++ctx->fsync_count;
+
+  wait();
+  return 0;
+}
+
+static int handler_fdatasync(
+  rtems_libio_t *iop
+)
+{
+  test_context *ctx;
+
+  ctx = IMFS_generic_get_context_by_iop(iop);
+  ++ctx->fdatasync_count;
+
+  wait();
+  return 0;
+}
+
+static int handler_fcntl(
+  rtems_libio_t *iop,
+  int cmd
+)
+{
+  test_context *ctx;
+
+  ctx = IMFS_generic_get_context_by_iop(iop);
+  ++ctx->fcntl_count;
+
+  wait();
+  return 0;
+}
+
+static ssize_t handler_readv(
+  rtems_libio_t *iop,
+  const struct iovec *iov,
+  int iovcnt,
+  ssize_t total
+)
+{
+  test_context *ctx;
+
+  ctx = IMFS_generic_get_context_by_iop(iop);
+  ++ctx->readv_count;
+
+  wait();
+  return 0;
+}
+
+static ssize_t handler_writev(
+  rtems_libio_t *iop,
+  const struct iovec *iov,
+  int iovcnt,
+  ssize_t total
+)
+{
+  test_context *ctx;
+
+  ctx = IMFS_generic_get_context_by_iop(iop);
+  ++ctx->writev_count;
+
+  wait();
+  return 0;
+}
+
+static const rtems_filesystem_file_handlers_r node_handlers = {
+  .open_h = handler_open,
+  .close_h = handler_close,
+  .read_h = handler_read,
+  .write_h = handler_write,
+  .ioctl_h = handler_ioctl,
+  .lseek_h = handler_lseek,
+  .fstat_h = handler_fstat,
+  .ftruncate_h = handler_ftruncate,
+  .fsync_h = handler_fsync,
+  .fdatasync_h = handler_fdatasync,
+  .fcntl_h = handler_fcntl,
+  .readv_h = handler_readv,
+  .writev_h = handler_writev
+};
+
+static const IMFS_node_control node_control = {
+  .handlers = &node_handlers,
+  .node_initialize = IMFS_node_initialize_generic,
+  .node_remove = IMFS_node_remove_default,
+  .node_destroy = IMFS_node_destroy_default
+};
+
+static void worker_task(rtems_task_argument arg)
+{
+  test_context *ctx;
+  int rv;
+  char buf[1];
+  ssize_t n;
+  off_t off;
+  struct iovec iov = {
+    .iov_base = &buf[0],
+    .iov_len = sizeof(buf)
+  };
+  struct stat st;
+
+  ctx = (test_context *) arg;
+
+  while (true) {
+    wait();
+
+    switch (ctx->action) {
+      case ACTION_ClOSE:
+        ctx->wait_in_close = true;
+        rv = close(ctx->fd);
+        rtems_test_assert(rv == 0);
+        break;
+      case ACTION_FCNTL:
+        rv = fcntl(ctx->fd, F_GETFD);
+        rtems_test_assert(rv >= 0);
+        break;
+      case ACTION_FDATASYNC:
+        rv = fdatasync(ctx->fd);
+        rtems_test_assert(rv == 0);
+        break;
+      case ACTION_FCHDIR:
+        ctx->wait_in_fstat = true;
+        rv = fchdir(ctx->fd);
+        rtems_test_assert(rv == -1);
+        rtems_test_assert(errno == ENOTDIR);
+        break;
+      case ACTION_FCHMOD:
+        rv = fstat(ctx->fd, &st);
+        rtems_test_assert(rv == 0);
+        ctx->wait_in_fstat = true;
+        rv = fchmod(ctx->fd, st.st_mode);
+        rtems_test_assert(rv == 0);
+        break;
+      case ACTION_FCHOWN:
+        rv = fstat(ctx->fd, &st);
+        rtems_test_assert(rv == 0);
+        ctx->wait_in_fstat = true;
+        rv = fchown(ctx->fd, st.st_uid, st.st_gid);
+        rtems_test_assert(rv == 0);
+        break;
+      case ACTION_FSTAT:
+        ctx->wait_in_fstat = true;
+        rv = fstat(ctx->fd, &st);
+        rtems_test_assert(rv == 0);
+        break;
+      case ACTION_FSYNC:
+        rv = fsync(ctx->fd);
+        rtems_test_assert(rv == 0);
+        break;
+      case ACTION_FTRUNCATE:
+        rv = ftruncate(ctx->fd, 0);
+        rtems_test_assert(rv == 0);
+        break;
+      case ACTION_IOCTL:
+        rv = ioctl(ctx->fd, 0);
+        rtems_test_assert(rv == 0);
+        break;
+      case ACTION_LSEEK:
+        off = lseek(ctx->fd, off, SEEK_SET);
+        rtems_test_assert(off == 0);
+        break;
+      case ACTION_READ:
+        n = read(ctx->fd, buf, sizeof(buf));
+        rtems_test_assert(n == 0);
+        break;
+      case ACTION_READV:
+        n = readv(ctx->fd, &iov, 1);
+        rtems_test_assert(n == 0);
+        break;
+      case ACTION_WRITE:
+        n = write(ctx->fd, buf, sizeof(buf));
+        rtems_test_assert(n == 0);
+        break;
+      case ACTION_WRITEV:
+        n = writev(ctx->fd, &iov, 1);
+        rtems_test_assert(n == 0);
+        break;
+      default:
+        rtems_test_assert(0);
+        break;
+    }
+  }
+}
+
+static void test(test_context *ctx)
+{
+  const char *path = "generic";
+  int rv;
+  rtems_status_code sc;
+  test_action ac;
+
+  rv = IMFS_make_generic_node(
+    path,
+    S_IFCHR | S_IRWXU | S_IRWXG | S_IRWXO,
+    &node_control,
+    ctx
+  );
+  rtems_test_assert(rv == 0);
+
+  sc = rtems_task_create(
+    rtems_build_name('W', 'O', 'R', 'K'),
+    1,
+    RTEMS_MINIMUM_STACK_SIZE,
+    RTEMS_DEFAULT_MODES,
+    RTEMS_DEFAULT_ATTRIBUTES,
+    &ctx->worker_id
+  );
+  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+
+  sc = rtems_task_start(
+    ctx->worker_id,
+    worker_task,
+    (rtems_task_argument) ctx
+  );
+  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+
+  for (ac = ACTION_ClOSE; ac <= ACTION_WRITEV; ++ac) {
+    ctx->action = ac;
+    ctx->fd = open(path, O_RDWR);
+    rtems_test_assert(ctx->fd >= 0);
+
+    wakeup_worker(ctx);
+    rv = close(ctx->fd);
+    rtems_test_assert(rv == -1);
+
+    if (ac == ACTION_ClOSE) {
+      rtems_test_assert(errno == EBADF);
+    } else {
+      rtems_test_assert(errno == EBUSY);
+    }
+
+    wakeup_worker(ctx);
+    rv = close(ctx->fd);
+
+    if (ac == ACTION_ClOSE) {
+      rtems_test_assert(rv == -1);
+      rtems_test_assert(errno == EBADF);
+    } else {
+      rtems_test_assert(rv == 0);
+    }
+  }
+
+  sc = rtems_task_delete(ctx->worker_id);
+  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+
+  rv = unlink(path);
+  rtems_test_assert(rv == 0);
+
+  rtems_test_assert(ctx->close_count == 15);
+  rtems_test_assert(ctx->fcntl_count == 1);
+  rtems_test_assert(ctx->fdatasync_count == 1);
+  rtems_test_assert(ctx->fstat_count == 38);
+  rtems_test_assert(ctx->fsync_count == 1);
+  rtems_test_assert(ctx->ftruncate_count == 1);
+  rtems_test_assert(ctx->ioctl_count == 1);
+  rtems_test_assert(ctx->lseek_count == 1);
+  rtems_test_assert(ctx->open_count == 15);
+  rtems_test_assert(ctx->read_count == 1);
+  rtems_test_assert(ctx->readv_count == 1);
+  rtems_test_assert(ctx->write_count == 1);
+  rtems_test_assert(ctx->writev_count == 1);
+}
+
+static void Init(rtems_task_argument arg)
+{
+  TEST_BEGIN();
+  test(&test_instance);
+  TEST_END();
+  rtems_test_exit(0);
+}
+
+#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
+#define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER
+
+#define CONFIGURE_LIBIO_MAXIMUM_FILE_DESCRIPTORS 4
+
+#define CONFIGURE_MAXIMUM_TASKS 2
+
+#define CONFIGURE_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION
+
+#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
+
+#define CONFIGURE_INIT_TASK_PRIORITY 2
+#define CONFIGURE_INIT_TASK_INITIAL_MODES RTEMS_DEFAULT_MODES
+
+#define CONFIGURE_INIT
+
+#include <rtems/confdefs.h>
