Index: cpukit/libfs/src/dosfs/fat_file.c
===================================================================
--- cpukit/libfs/src/dosfs/fat_file.c	(revision 040ed0b4cdd1c663408664ba3a8b2e5de0cf54e0)
+++ cpukit/libfs/src/dosfs/fat_file.c	(revision a7eaaae85b9b536b4d77c86e39c138d7c4f8f8fc)
@@ -166,4 +166,36 @@
 }
 
+int
+fat_file_update(fat_fs_info_t *fs_info, fat_file_fd_t *fat_fd)
+{
+    int ret_rc = RC_OK;
+
+    /*
+     * if fat-file descriptor is not marked as "removed", synchronize
+     * size, first cluster number, write time and date fields of the file
+     */
+    if (!FAT_FILE_IS_REMOVED(fat_fd))
+    {
+        int rc;
+
+        if (fat_fd->fat_file_type == FAT_FILE)
+        {
+            rc = fat_file_write_first_cluster_num(fs_info, fat_fd);
+            if (rc != RC_OK)
+                ret_rc = rc;
+
+            rc = fat_file_write_file_size(fs_info, fat_fd);
+            if (rc != RC_OK)
+                ret_rc = rc;
+        }
+
+        rc = fat_file_write_time_and_date(fs_info, fat_fd);
+        if (rc != RC_OK)
+            ret_rc = rc;
+    }
+
+    return ret_rc;
+}
+
 /* fat_file_close --
  *     Close fat-file. If count of links to fat-file
@@ -204,4 +236,6 @@
     {
         uint32_t key = fat_construct_key(fs_info, &fat_fd->dir_pos.sname);
+
+        fat_file_update(fs_info, fat_fd);
 
         if (fat_fd->flags & FAT_FILE_REMOVED)
Index: cpukit/libfs/src/dosfs/fat_file.h
===================================================================
--- cpukit/libfs/src/dosfs/fat_file.h	(revision 040ed0b4cdd1c663408664ba3a8b2e5de0cf54e0)
+++ cpukit/libfs/src/dosfs/fat_file.h	(revision a7eaaae85b9b536b4d77c86e39c138d7c4f8f8fc)
@@ -89,4 +89,5 @@
     uint8_t          flags;
     fat_file_map_t   map;
+    time_t           ctime;
     time_t           mtime;
 
@@ -140,4 +141,20 @@
 }
 
+static inline void fat_file_set_ctime(fat_file_fd_t *fat_fd, time_t t)
+{
+    fat_fd->ctime = t;
+}
+
+static inline void fat_file_set_mtime(fat_file_fd_t *fat_fd, time_t t)
+{
+    fat_fd->mtime = t;
+}
+
+static inline void fat_file_set_ctime_mtime(fat_file_fd_t *fat_fd, time_t t)
+{
+    fat_fd->ctime = t;
+    fat_fd->mtime = t;
+}
+
 /* Prototypes for "fat-file" operations */
 int
@@ -193,4 +210,24 @@
                       fat_file_fd_t                        *fat_fd);
 
+int
+fat_file_size(fat_fs_info_t                        *fs_info,
+              fat_file_fd_t                        *fat_fd);
+
+int
+fat_file_write_first_cluster_num(fat_fs_info_t *fs_info,
+                                 fat_file_fd_t *fat_fd);
+
+int
+fat_file_write_file_size(fat_fs_info_t *fs_info,
+                         fat_file_fd_t *fat_fd);
+
+int
+fat_file_write_time_and_date(fat_fs_info_t *fs_info,
+                             fat_file_fd_t *fat_fd);
+
+int
+fat_file_update(fat_fs_info_t *fs_info,
+                fat_file_fd_t *fat_fd);
+
 #ifdef __cplusplus
 }
Index: cpukit/libfs/src/dosfs/msdos.h
===================================================================
--- cpukit/libfs/src/dosfs/msdos.h	(revision 040ed0b4cdd1c663408664ba3a8b2e5de0cf54e0)
+++ cpukit/libfs/src/dosfs/msdos.h	(revision a7eaaae85b9b536b4d77c86e39c138d7c4f8f8fc)
@@ -135,4 +135,6 @@
 #define MSDOS_FILE_WTIME_OFFSET           22
 #define MSDOS_FILE_ADATE_OFFSET           18
+#define MSDOS_FILE_CDATE_OFFSET           16
+#define MSDOS_FILE_CTIME_OFFSET           14
 
 /*
@@ -334,6 +336,4 @@
 );
 
-int msdos_file_close(rtems_libio_t *iop /* IN  */);
-
 ssize_t msdos_file_read(
   rtems_libio_t *iop,              /* IN  */
@@ -360,6 +360,4 @@
 
 int msdos_file_sync(rtems_libio_t *iop);
-
-int msdos_file_datasync(rtems_libio_t *iop);
 
 ssize_t msdos_dir_read(
@@ -462,14 +460,4 @@
 unsigned int msdos_date_dos2unix(unsigned int dd, unsigned int dt);
 
-int msdos_set_first_cluster_num(
-  rtems_filesystem_mount_table_entry_t *mt_entry,
-  fat_file_fd_t                        *fat_fd
-);
-
-int msdos_set_file_size(
-  rtems_filesystem_mount_table_entry_t *mt_entry,
-  fat_file_fd_t                        *fat_fd
-);
-
 int msdos_set_first_char4file_name(
   rtems_filesystem_mount_table_entry_t *mt_entry,
@@ -477,10 +465,4 @@
   unsigned char                         first_char
 );
-
-int msdos_set_dir_wrt_time_and_date(
-    rtems_filesystem_mount_table_entry_t *mt_entry,
-    fat_file_fd_t                        *fat_fd
-);
-
 
 int msdos_dir_is_empty(
Index: cpukit/libfs/src/dosfs/msdos_create.c
===================================================================
--- cpukit/libfs/src/dosfs/msdos_create.c	(revision 040ed0b4cdd1c663408664ba3a8b2e5de0cf54e0)
+++ cpukit/libfs/src/dosfs/msdos_create.c	(revision a7eaaae85b9b536b4d77c86e39c138d7c4f8f8fc)
@@ -71,5 +71,5 @@
     fat_file_fd_t    *parent_fat_fd = parent_loc->node_access;
     fat_file_fd_t    *fat_fd = NULL;
-    time_t            time_ret = 0;
+    time_t            now;
     uint16_t          time_val = 0;
     uint16_t          date = 0;
@@ -103,9 +103,8 @@
 
     /* set up last write date and time */
-    time_ret = time(NULL);
-    if ( time_ret == -1 )
-        return -1;
-
-    msdos_date_unix2dos(time_ret, &date, &time_val);
+    now = time(NULL);
+    fat_file_set_ctime_mtime(parent_fat_fd, now);
+
+    msdos_date_unix2dos(now, &date, &time_val);
     *MSDOS_DIR_CRT_TIME(short_node) = CT_LE_W(time_val);
     *MSDOS_DIR_CRT_DATE(short_node) = CT_LE_W(date);
@@ -193,4 +192,5 @@
         fat_fd->fat_file_type = FAT_DIRECTORY;
         fat_fd->size_limit = MSDOS_MAX_DIR_LENGHT;
+        fat_file_set_ctime_mtime(fat_fd, now);
 
         /*
@@ -261,5 +261,5 @@
 
         /* write first cluster num of a new directory to disk */
-        rc = msdos_set_first_cluster_num(parent_loc->mt_entry, fat_fd);
+        rc = fat_file_write_first_cluster_num(&fs_info->fat, fat_fd);
         if (rc != RC_OK)
             goto error;
Index: cpukit/libfs/src/dosfs/msdos_dir.c
===================================================================
--- cpukit/libfs/src/dosfs/msdos_dir.c	(revision 040ed0b4cdd1c663408664ba3a8b2e5de0cf54e0)
+++ cpukit/libfs/src/dosfs/msdos_dir.c	(revision a7eaaae85b9b536b4d77c86e39c138d7c4f8f8fc)
@@ -404,4 +404,6 @@
     buf->st_blocks = fat_fd->fat_file_size >> FAT_SECTOR512_BITS;
     buf->st_blksize = fs_info->fat.vol.bps;
+    buf->st_atime = fat_fd->mtime;
+    buf->st_ctime = fat_fd->ctime;
     buf->st_mtime = fat_fd->mtime;
 
Index: cpukit/libfs/src/dosfs/msdos_file.c
===================================================================
--- cpukit/libfs/src/dosfs/msdos_file.c	(revision 040ed0b4cdd1c663408664ba3a8b2e5de0cf54e0)
+++ cpukit/libfs/src/dosfs/msdos_file.c	(revision a7eaaae85b9b536b4d77c86e39c138d7c4f8f8fc)
@@ -30,68 +30,4 @@
 
 #include "msdos.h"
-
-static int
-msdos_file_update(rtems_libio_t *iop)
-{
-    int              rc = RC_OK;
-    fat_file_fd_t   *fat_fd = iop->pathinfo.node_access;
-
-    /*
-     * if fat-file descriptor is not marked as "removed", synchronize
-     * size, first cluster number, write time and date fields of the file
-     */
-    if (!FAT_FILE_IS_REMOVED(fat_fd))
-    {
-        rc = msdos_set_first_cluster_num(iop->pathinfo.mt_entry, fat_fd);
-        if (rc != RC_OK)
-        {
-            return rc;
-        }
-
-        rc = msdos_set_file_size(iop->pathinfo.mt_entry, fat_fd);
-        if (rc != RC_OK)
-        {
-            return rc;
-        }
-
-        rc = msdos_set_dir_wrt_time_and_date(iop->pathinfo.mt_entry, fat_fd);
-        if (rc != RC_OK)
-        {
-            return rc;
-        }
-    }
-
-    return rc;
-}
-
-/* msdos_file_close --
- *     Close fat-file which correspondes to the file. If fat-file descriptor
- *     which correspondes to the file is not marked "removed", synchronize
- *     size, first cluster number, write time and date fields of the file.
- *
- * PARAMETERS:
- *     iop - file control block
- *
- * RETURNS:
- *     RC_OK, if file closed successfully, or -1 if error occured (errno set
- *     appropriately)
- */
-int
-msdos_file_close(rtems_libio_t *iop)
-{
-    int                rc = RC_OK;
-    rtems_status_code  sc = RTEMS_SUCCESSFUL;
-    msdos_fs_info_t   *fs_info = iop->pathinfo.mt_entry->fs_info;
-
-    sc = rtems_semaphore_obtain(fs_info->vol_sema, RTEMS_WAIT,
-                                MSDOS_VOLUME_SEMAPHORE_TIMEOUT);
-    if (sc != RTEMS_SUCCESSFUL)
-        rtems_set_errno_and_return_minus_one(EIO);
-
-    rc = msdos_file_update(iop);
-
-    rtems_semaphore_release(fs_info->vol_sema);
-    return rc;
-}
 
 /* msdos_file_read --
@@ -174,4 +110,7 @@
     if (iop->offset > fat_fd->fat_file_size)
         fat_fd->fat_file_size = iop->offset;
+
+    if (ret > 0)
+        fat_file_set_ctime_mtime(fat_fd, time(NULL));
 
     rtems_semaphore_release(fs_info->vol_sema);
@@ -212,4 +151,6 @@
       >> FAT_SECTOR512_BITS;
     buf->st_blksize = fs_info->fat.vol.bpc;
+    buf->st_atime = fat_fd->mtime;
+    buf->st_ctime = fat_fd->ctime;
     buf->st_mtime = fat_fd->mtime;
 
@@ -260,6 +201,8 @@
     }
 
-    if (rc == RC_OK) {
+    if (rc == RC_OK)
+    {
         fat_fd->fat_file_size = length;
+        fat_file_set_ctime_mtime(fat_fd, time(NULL));
     }
 
@@ -285,11 +228,12 @@
     rtems_status_code  sc = RTEMS_SUCCESSFUL;
     msdos_fs_info_t   *fs_info = iop->pathinfo.mt_entry->fs_info;
-
-    sc = rtems_semaphore_obtain(fs_info->vol_sema, RTEMS_WAIT,
-                                MSDOS_VOLUME_SEMAPHORE_TIMEOUT);
-    if (sc != RTEMS_SUCCESSFUL)
-        rtems_set_errno_and_return_minus_one(EIO);
-
-    rc = msdos_file_update(iop);
+    fat_file_fd_t     *fat_fd = iop->pathinfo.node_access;
+
+    sc = rtems_semaphore_obtain(fs_info->vol_sema, RTEMS_WAIT,
+                                MSDOS_VOLUME_SEMAPHORE_TIMEOUT);
+    if (sc != RTEMS_SUCCESSFUL)
+        rtems_set_errno_and_return_minus_one(EIO);
+
+    rc = fat_file_update(&fs_info->fat, fat_fd);
     if (rc != RC_OK)
     {
Index: cpukit/libfs/src/dosfs/msdos_handlers_file.c
===================================================================
--- cpukit/libfs/src/dosfs/msdos_handlers_file.c	(revision 040ed0b4cdd1c663408664ba3a8b2e5de0cf54e0)
+++ cpukit/libfs/src/dosfs/msdos_handlers_file.c	(revision a7eaaae85b9b536b4d77c86e39c138d7c4f8f8fc)
@@ -24,5 +24,5 @@
 const rtems_filesystem_file_handlers_r msdos_file_handlers = {
   .open_h = rtems_filesystem_default_open,
-  .close_h = msdos_file_close,
+  .close_h = rtems_filesystem_default_close,
   .read_h = msdos_file_read,
   .write_h = msdos_file_write,
Index: cpukit/libfs/src/dosfs/msdos_init.c
===================================================================
--- cpukit/libfs/src/dosfs/msdos_init.c	(revision 040ed0b4cdd1c663408664ba3a8b2e5de0cf54e0)
+++ cpukit/libfs/src/dosfs/msdos_init.c	(revision a7eaaae85b9b536b4d77c86e39c138d7c4f8f8fc)
@@ -36,4 +36,20 @@
 }
 
+static int msdos_utime(
+  const rtems_filesystem_location_info_t *loc,
+  time_t                                  actime,
+  time_t                                  modtime
+)
+{
+    fat_file_fd_t *fat_fd = loc->node_access;
+
+    if (actime != modtime)
+        rtems_set_errno_and_return_minus_one( ENOTSUP );
+
+    fat_file_set_mtime(fat_fd, modtime);
+
+    return RC_OK;
+}
+
 const rtems_filesystem_operations_table  msdos_ops = {
   .lock_h         =  msdos_lock,
@@ -53,5 +69,5 @@
   .unmount_h      =  rtems_filesystem_default_unmount,
   .fsunmount_me_h =  msdos_shut_down,
-  .utime_h        =  rtems_filesystem_default_utime,
+  .utime_h        =  msdos_utime,
   .symlink_h      =  rtems_filesystem_default_symlink,
   .readlink_h     =  rtems_filesystem_default_readlink,
Index: cpukit/libfs/src/dosfs/msdos_misc.c
===================================================================
--- cpukit/libfs/src/dosfs/msdos_misc.c	(revision 040ed0b4cdd1c663408664ba3a8b2e5de0cf54e0)
+++ cpukit/libfs/src/dosfs/msdos_misc.c	(revision a7eaaae85b9b536b4d77c86e39c138d7c4f8f8fc)
@@ -380,4 +380,9 @@
 
         fat_fd->mtime = msdos_date_dos2unix(CF_LE_W(date), CF_LE_W(time_val));
+
+        time_val = *MSDOS_DIR_CRT_TIME(node_entry);
+        date = *MSDOS_DIR_CRT_DATE(node_entry);
+
+        fat_fd->ctime = msdos_date_dos2unix(CF_LE_W(date), CF_LE_W(time_val));
 
         if ((*MSDOS_DIR_ATTR(node_entry)) & MSDOS_ATTR_DIRECTORY)
@@ -671,10 +676,10 @@
 
 
-/* msdos_set_dir_wrt_time_and_date --
+/* fat_file_write_time_and_date --
  *     Write last write date and time for a file to the disk (to corresponded
  *     32bytes node)
  *
  * PARAMETERS:
- *     mt_entry - mount table entry
+ *     fs_info  - fat fs info
  *     fat_fd   - fat-file descriptor
  *
@@ -684,11 +689,11 @@
  */
 int
-msdos_set_dir_wrt_time_and_date(
-    rtems_filesystem_mount_table_entry_t *mt_entry,
+fat_file_write_time_and_date(
+    fat_fs_info_t                        *fs_info,
     fat_file_fd_t                        *fat_fd
     )
 {
-    ssize_t          ret1 = 0, ret2 = 0, ret3 = 0;
-    msdos_fs_info_t *fs_info = mt_entry->fs_info;
+    int              rc = RC_OK;
+    ssize_t          ret;
     uint16_t         time_val;
     uint16_t         date;
@@ -696,36 +701,55 @@
     uint32_t         byte = 0;
 
-    msdos_date_unix2dos(fat_fd->mtime, &date, &time_val);
-
     /*
      * calculate input for fat_sector_write: convert (cluster num, offset) to
      * (sector num, new offset)
      */
-    sec = fat_cluster_num_to_sector_num(&fs_info->fat, fat_fd->dir_pos.sname.cln);
-    sec += (fat_fd->dir_pos.sname.ofs >> fs_info->fat.vol.sec_log2);
+    sec = fat_cluster_num_to_sector_num(fs_info, fat_fd->dir_pos.sname.cln);
+    sec += (fat_fd->dir_pos.sname.ofs >> fs_info->vol.sec_log2);
     /* byte points to start of 32bytes structure */
-    byte = fat_fd->dir_pos.sname.ofs & (fs_info->fat.vol.bps - 1);
+    byte = fat_fd->dir_pos.sname.ofs & (fs_info->vol.bps - 1);
+
+    msdos_date_unix2dos(fat_fd->mtime, &date, &time_val);
 
     time_val = CT_LE_W(time_val);
-    ret1 = fat_sector_write(&fs_info->fat, sec, byte + MSDOS_FILE_WTIME_OFFSET,
-                            2, (char *)(&time_val));
+    ret = fat_sector_write(fs_info, sec, byte + MSDOS_FILE_WTIME_OFFSET,
+                           2, (char *)(&time_val));
+    if ( ret < 0 )
+        rc = -1;
+
     date = CT_LE_W(date);
-    ret2 = fat_sector_write(&fs_info->fat, sec, byte + MSDOS_FILE_WDATE_OFFSET,
-                            2, (char *)(&date));
-    ret3 = fat_sector_write(&fs_info->fat, sec, byte + MSDOS_FILE_ADATE_OFFSET,
-                            2, (char *)(&date));
-
-    if ( (ret1 < 0) || (ret2 < 0) || (ret3 < 0) )
-        return -1;
-
-    return RC_OK;
-}
-
-/* msdos_set_first_cluster_num --
+    ret = fat_sector_write(fs_info, sec, byte + MSDOS_FILE_WDATE_OFFSET,
+                           2, (char *)(&date));
+    if ( ret < 0 )
+        rc = -1;
+
+    ret = fat_sector_write(fs_info, sec, byte + MSDOS_FILE_ADATE_OFFSET,
+                           2, (char *)(&date));
+    if ( ret < 0 )
+        rc = -1;
+
+    msdos_date_unix2dos(fat_fd->ctime, &date, &time_val);
+
+    time_val = CT_LE_W(time_val);
+    ret = fat_sector_write(fs_info, sec, byte + MSDOS_FILE_CTIME_OFFSET,
+                           2, (char *)(&time_val));
+    if ( ret < 0 )
+        rc = -1;
+
+    date = CT_LE_W(date);
+    ret = fat_sector_write(fs_info, sec, byte + MSDOS_FILE_CDATE_OFFSET,
+                           2, (char *)(&date));
+    if ( ret < 0 )
+        rc = -1;
+
+    return rc;
+}
+
+/* fat_set_first_cluster_num --
  *     Write number of first cluster of the file to the disk (to corresponded
  *     32bytes slot)
  *
  * PARAMETERS:
- *     mt_entry - mount table entry
+ *     fs_info  - fat fs info
  *     fat_fd   - fat-file descriptor
  *
@@ -735,11 +759,10 @@
  */
 int
-msdos_set_first_cluster_num(
-    rtems_filesystem_mount_table_entry_t *mt_entry,
+fat_file_write_first_cluster_num(
+    fat_fs_info_t                        *fs_info,
     fat_file_fd_t                        *fat_fd
     )
 {
     ssize_t          ret1 = 0, ret2 = 0;
-    msdos_fs_info_t *fs_info = mt_entry->fs_info;
     uint32_t         new_cln = fat_fd->cln;
     uint16_t         le_cl_low = 0;
@@ -752,15 +775,15 @@
      * (sector num, new offset)
      */
-    sec = fat_cluster_num_to_sector_num(&fs_info->fat, fat_fd->dir_pos.sname.cln);
-    sec += (fat_fd->dir_pos.sname.ofs >> fs_info->fat.vol.sec_log2);
+    sec = fat_cluster_num_to_sector_num(fs_info, fat_fd->dir_pos.sname.cln);
+    sec += (fat_fd->dir_pos.sname.ofs >> fs_info->vol.sec_log2);
     /* byte from points to start of 32bytes structure */
-    byte = fat_fd->dir_pos.sname.ofs & (fs_info->fat.vol.bps - 1);
+    byte = fat_fd->dir_pos.sname.ofs & (fs_info->vol.bps - 1);
 
     le_cl_low = CT_LE_W((uint16_t  )(new_cln & 0x0000FFFF));
-    ret1 = fat_sector_write(&fs_info->fat, sec,
+    ret1 = fat_sector_write(fs_info, sec,
                             byte + MSDOS_FIRST_CLUSTER_LOW_OFFSET, 2,
                             (char *)(&le_cl_low));
     le_cl_hi = CT_LE_W((uint16_t  )((new_cln & 0xFFFF0000) >> 16));
-    ret2 = fat_sector_write(&fs_info->fat, sec,
+    ret2 = fat_sector_write(fs_info, sec,
                             byte + MSDOS_FIRST_CLUSTER_HI_OFFSET, 2,
                             (char *)(&le_cl_hi));
@@ -772,9 +795,9 @@
 
 
-/* msdos_set_file size --
+/* fat_set_file size --
  *     Write file size of the file to the disk (to corresponded 32bytes slot)
  *
  * PARAMETERS:
- *     mt_entry - mount table entry
+ *     fs_info  - fat fs info
  *     fat_fd   - fat-file descriptor
  *
@@ -784,21 +807,20 @@
  */
 int
-msdos_set_file_size(
-    rtems_filesystem_mount_table_entry_t *mt_entry,
+fat_file_write_file_size(
+    fat_fs_info_t                        *fs_info,
     fat_file_fd_t                        *fat_fd
     )
 {
     ssize_t          ret = 0;
-    msdos_fs_info_t *fs_info = mt_entry->fs_info;
     uint32_t         le_new_length = 0;
     uint32_t         sec = 0;
     uint32_t         byte = 0;
 
-    sec = fat_cluster_num_to_sector_num(&fs_info->fat, fat_fd->dir_pos.sname.cln);
-    sec += (fat_fd->dir_pos.sname.ofs >> fs_info->fat.vol.sec_log2);
-    byte = (fat_fd->dir_pos.sname.ofs & (fs_info->fat.vol.bps - 1));
+    sec = fat_cluster_num_to_sector_num(fs_info, fat_fd->dir_pos.sname.cln);
+    sec += (fat_fd->dir_pos.sname.ofs >> fs_info->vol.sec_log2);
+    byte = (fat_fd->dir_pos.sname.ofs & (fs_info->vol.bps - 1));
 
     le_new_length = CT_LE_L((fat_fd->fat_file_size));
-    ret = fat_sector_write(&fs_info->fat, sec, byte + MSDOS_FILE_SIZE_OFFSET, 4,
+    ret = fat_sector_write(fs_info, sec, byte + MSDOS_FILE_SIZE_OFFSET, 4,
                            (char *)(&le_new_length));
     if ( ret < 0 )
