]> git.karo-electronics.de Git - karo-tx-redboot.git/blobdiff - packages/fs/fat/v2_0/src/fatfs.c
unified MX27, MX25, MX37 trees
[karo-tx-redboot.git] / packages / fs / fat / v2_0 / src / fatfs.c
index 77f3ab92b8950b7268e9d740a7ce071722989a99..5d38164d32dcfd924bb6974d3f550522cd7d20eb 100644 (file)
@@ -309,7 +309,15 @@ find_direntry(fatfs_dirsearch_t *ds)
 
     CYG_TRACE1(TFS, "searching for dir entry '%s'", ds->name);
 
-    // First check the cache
+    // Check for '.' 
+
+    if (!strncmp(".", ds->name, ds->namelen))
+    {
+        ds->node = ds->dir;
+        return ENOERR;
+    }
+   
+    // Check the cache
     
     ds->node = fatfs_node_find(ds->disk, 
                                ds->name, 
@@ -339,15 +347,53 @@ find_direntry(fatfs_dirsearch_t *ds)
             return (err == EEOF ? ENOERR : err);
 
         // Compare filenames
-        
+    
         if ('\0' == dentry.filename[ds->namelen] &&
                0 == strncasecmp(dentry.filename, ds->name, ds->namelen))
         {
             // Dir entry found - allocate new node and return
 
             CYG_TRACE0(TFS, "dir entry found");
+            
+            if (0 == strncmp(ds->name, "..", ds->namelen)) 
+            {
+                fatfs_dir_entry_t _dentry;
+                fatfs_data_pos_t  _pos;
+                if (0 == dentry.cluster) 
+                {
+                    ds->node = ds->disk->root;
+                    return ENOERR;
+                }
+             
+                fatfs_initpos(ds->disk, &dentry, &_pos);
+                while (true)
+                {
+                    err = fatfs_read_dir_entry(ds->disk, &dentry, &_pos, &_dentry);
+                    if (err != ENOERR)
+                        return err;
+                    if (0 == strcmp(".", _dentry.filename))
+                        break;
+                }
+                ds->node = fatfs_node_find(ds->disk, 
+                                           _dentry.filename, 
+                                           strlen(_dentry.filename),
+                                           _dentry.parent_cluster); 
+                
+                if (NULL != ds->node)
+                    fatfs_node_touch(ds->disk, ds->node);
+                else 
+                    ds->node = fatfs_node_alloc(ds->disk, &_dentry);
+                                
+                if (NULL == ds->node)
+                    return EMFILE;
+                                
+                return ENOERR;
+            }
+            else 
+                ds->node = fatfs_node_alloc(ds->disk, &dentry);
 
-            ds->node = fatfs_node_alloc(ds->disk, &dentry);
             if (NULL == ds->node)
                 return EMFILE;
 
@@ -756,6 +802,7 @@ fatfs_rmdir(cyg_mtab_entry *mte, cyg_dir dir, const char *name)
     fatfs_disk_t      *disk = (fatfs_disk_t *) mte->data;
     fatfs_dirsearch_t  ds;
     int                err;
+    fatfs_node_t      *node;
 
     CYG_TRACE3(TFS, "rmdir mte=%p dir=%p name='%s'", mte, dir, name);
 
@@ -774,8 +821,17 @@ fatfs_rmdir(cyg_mtab_entry *mte, cyg_dir dir, const char *name)
     
     err = fatfs_delete_file(disk, &ds.node->dentry);
     if (err == ENOERR)
+    {
+        node = fatfs_node_find( disk, ".", 1, ds.node->dentry.cluster );
+        if (node != NULL)
+             fatfs_node_free(disk, node);
+
+        node = fatfs_node_find( disk, "..", 2, ds.node->dentry.cluster );
+        if (node != NULL)
+            fatfs_node_free(disk, node);
+
         fatfs_node_free(disk, ds.node);
-    
+    }
     return err;
 }
 
@@ -1109,6 +1165,22 @@ fatfs_getinfo(cyg_mtab_entry *mte,
             err = fatfs_get_attrib(mte, dir, name, (cyg_fs_attrib_t*)buf);
             break;
 #endif // CYGCFG_FS_FAT_USE_ATTRIBUTES
+#if defined(CYGSEM_FILEIO_BLOCK_USAGE)
+        case FS_INFO_BLOCK_USAGE: {
+         cyg_uint32 total_clusters;
+         cyg_uint32 free_clusters;
+         struct cyg_fs_block_usage *usage = (struct cyg_fs_block_usage *) buf;
+         fatfs_disk_t  *disk   = (fatfs_disk_t *) mte->data;
+
+         err = fatfs_get_disk_usage(disk, &total_clusters, &free_clusters);
+         if (err)
+           return err;
+         usage->total_blocks = total_clusters; 
+         usage->free_blocks = free_clusters;
+         usage->block_size = disk->cluster_size;
+         break;
+       }
+#endif
         default:
             err = EINVAL;
             break;
@@ -1476,7 +1548,9 @@ fatfs_fo_dirread(struct CYG_FILE_TAG *fp, struct CYG_UIO_TAG *uio)
         return (err == EEOF ? ENOERR : err);
 
     strcpy(nbuf, dentry.filename);
-
+#ifdef CYGPKG_FS_FAT_RET_DIRENT_DTYPE
+    ent->d_type = dentry.mode;
+#endif
     fd->node->dentry.atime  = cyg_timestamp();
     uio->uio_resid         -= sizeof(struct dirent);
     fp->f_offset++;