Commits

Paweł Wieczorek  committed b803a99

* prace nad przepisywaniem zwykłych katalogów i zapisem plików na nośnik

  • Participants
  • Parent commits fd7aa62
  • Branches impala-fatfs

Comments (0)

Files changed (3)

File sys/fs/fatfs/fat_dirent.c

     str_ncpy(node->name, name, sizeof(node->name));
     str_ncpy(dirent->name, name, sizeof(dirent->name));
     dirent->node = node;
+    dirent->dirnode = dir->node;
     node->dirent = dirent;
 
     dirent->type = type;
     node->size = 0;
     node->firstclu = clu;
     list_insert_tail(&dir->dirents, dirent);
+    fatfs_dir_sync(dir);
+    fatfs_node_ref(node);
+    return node;
+}
+
+void
+fatfs_dir_sync(fatfs_dir_t *dir)
+{
     if (dir->node->type == FATFS_ROOT) {
         rewrite_whole_root(dir);
     } else {
         rewrite_whole_dir(dir);
     }
-    fatfs_node_ref(node);
-    VFS_SYNC(node->fatfs->vfs);
-    return node;
 }
 
 void
 int
 rewrite_whole_dir(fatfs_dir_t *dir)
 {
-    panic("should never run");
+    uio_t u;
+    iovec_t iov;
+    fatfs_dirent_t *dirent;
+    size_t size = list_length(&dir->dirents);
+    fatfs_dentry_t *table = kmem_zalloc(size*32, KM_SLEEP);
+    if (table == NULL) {
+        DEBUGF("cannot allocate buffer for %u bytes", size);
+        return -ENOMEM;
+    }
+    u.space = UIO_SYSSPACE;
+    u.oper = UIO_WRITE;
+    u.iovs = &iov;
+    u.iovcnt = 1;
+    u.size = size*32;
+    u.resid = size*32;
+    u.completed = 0;
+    iov.iov_len = size*32;
+    iov.iov_base = table;
+
+    dirent = list_head(&dir->dirents);
+    for (int i = 0; i < size && dirent; ) {
+        i += fill_dentry(&table[i], dirent, size - i, i);
+        dirent = list_next(&dir->dirents, dirent);
+    }
+    ssize_t r = fatfs_node_write(dir->node, &u, 0);
+    if (r != size) {
+        kmem_free(table);
+        return (r < 0)? r : -EIO;
+    }
+    kmem_free(table);
+
     return 0;
 }
 
     fatfs_dentry_t *dentry;
     iobuf_t *bp;
 
-    bp = bio_read(fatfs->dev, fatfs->blkno_root, fatfs->maxroot*32);
+    bp = bio_getblk(fatfs->dev, fatfs->blkno_root, fatfs->maxroot*32);
     mem_zero(bp->addr, bp->size);
     dentry = bp->addr;
     dirent = list_head(&dir->dirents);
     uint8_t sum = 0;
     char *helper = (char*) copy.name;
     vfatlname_t vln;
+
     mem_zero(&copy, sizeof(copy));
     snprintf(helper, 9, "E%07u", n);
     mem_set(copy.ext, ' ', 3);
         }
         dirent->firstclu = FATFS_D_GET_INDEX(dentry);
         dirent->size = FATFS_D_GET_SIZE(dentry);
+        dirent->dirnode = dir->node;
         node = fatfs_node_alloc(dir->node->fatfs, dirent->type);
         node->firstclu = dirent->firstclu;
         node->size = dirent->size;
 }
 
 /*============================================================================
- * Obs�uga d�ugich nazw VFAT
- *
- * Technologia d�ugich nazw VFAT jest pocz�ci opatentowana przez Microsoft.
- * U�ycie tego kodu w komercyjnym produkcie mo�e by� ryzykowne.
+ * Obs�uga d�ugich nazw
  */
 
 void

File sys/fs/fatfs/fat_node.c

 int
 fatfs_read(vnode_t *v, uio_t *u, int flags)
 {
+    ssize_t r;
     fatfs_node_t *node = VTOFATFSN(v);
-    iobuf_t *bp;
-    blkno_t blk;
-    off_t off = u->offset % node->fatfs->clusize;
-    size_t cont = 1;
-    u->resid = MIN(u->resid, MAX(0, node->size - u->offset));
-    u->completed = 0;
-    while ((blk=fatfs_bmap(node,u->offset,u->resid,&cont)) != -1 && u->resid) {
-        size_t size = cont*node->fatfs->clusize;
-        bp = bio_read(node->fatfs->dev, blk, cont*node->fatfs->clusize);
-        if ( ISSET(bp->flags, BIO_ERROR) ) {
-            return -EIO;
-            bio_release(bp);
-        }
-        size -= off;
-        uio_move(bp->addr + off, MIN(size, u->resid), u);
-        off = 0;
-        bio_release(bp);
-    }
-    return u->completed;
+    r = fatfs_node_read(node, u, flags);
+    return r;
 }
 
 int
 fatfs_write(vnode_t *v, uio_t *u, int flags)
 {
-    DEBUGF("write not supported");
-    return -ENOTSUP;
+    ssize_t r;
+    fatfs_node_t *node = VTOFATFSN(v);
+    r = fatfs_node_write(node, u, flags);
+    return r;
 }
 
 int
     if (node->type != FATFS_REG || v->v_type != VNODE_TYPE_REG)
         return -EISDIR;
     fatfs_node_truncate(node, len);
+    if (node->dirent) {
+        fatfs_dir_sync(node->dirent->dirnode->dir);
+    }
     return 0;
 }
 
     newnode = fatfs_dir_create(dir, path, FATFS_DIR, clu);
 
     *vpp = fatfs_node_getv(newnode);
+    VFS_SYNC(fatfs->vfs);
     return 0;
 }
 
  * 
  */
 
+
+int
+fatfs_node_read(fatfs_node_t *node, uio_t *u, int flags)
+{
+    iobuf_t *bp;
+    blkno_t blk;
+    off_t off = u->offset % node->fatfs->clusize;
+    size_t cont = 1;
+    u->resid = MIN(u->resid, MAX(0, node->size - u->offset));
+    u->completed = 0;
+    while ((blk=fatfs_bmap(node,u->offset,u->resid,&cont)) != -1 && u->resid) {
+        size_t size = cont*node->fatfs->clusize;
+        bp = bio_read(node->fatfs->dev, blk, cont*node->fatfs->clusize);
+        if ( ISSET(bp->flags, BIO_ERROR) ) {
+            return -EIO;
+            bio_release(bp);
+        }
+        size -= off;
+        uio_move(bp->addr + off, MIN(size, u->resid), u);
+        off = 0;
+        bio_release(bp);
+    }
+    return u->completed;
+}
+
+int
+fatfs_node_write(fatfs_node_t *node, uio_t *u, int flags)
+{
+    return 0;
+}
+
+
 vnode_t *
 fatfs_node_getv(fatfs_node_t *node)
 {
     size_t need = (off+fatfs->clusize-1) / fatfs->clusize;
     size_t have = node->csize;
 
+    if (need == have) return 0;
     if (need < have) {
         DEBUGF("need=%u have=%u clu=%u", need, have, node->firstclu);
         blkno_t clu = node->firstclu;
     }
     node->size = off;
     node->csize = need;
-    VFS_SYNC(fatfs->vfs);
     return 0;
 }
 

File sys/fs/fatfs/fatfs.h

     size_t          size;
     blkno_t         firstclu;
     fatfs_node_t   *node;
+    fatfs_node_t   *dirnode;
     list_node_t     L_dirents;
 };
 
 void fatfs_node_ref(fatfs_node_t *);
 void fatfs_node_rel(fatfs_node_t *);
 fatfs_node_t *fatfs_node_alloc(fatfs_t *, int type);
+void fatfs_node_free(fatfs_node_t *);
 
-void fatfs_node_free(fatfs_node_t *);
 int fatfs_node_getdir(fatfs_node_t *, fatfs_dir_t **);
 vnode_t * fatfs_node_getv(fatfs_node_t *node);
 int fatfs_node_truncate(fatfs_node_t *node, off_t );
+int fatfs_node_read(fatfs_node_t *, uio_t *, int);
+int fatfs_node_write(fatfs_node_t *, uio_t *, int);
 
 int fatfs_dir_load(fatfs_node_t *);
 void fatfs_dir_free(fatfs_dir_t *);
 fatfs_node_t *fatfs_dir_lookup(fatfs_dir_t *, const char *name);
 fatfs_node_t *fatfs_dir_create(fatfs_dir_t *, const char *, int , blkno_t);
 void fatfs_dir_remove(fatfs_dir_t *, const char *path);
+void fatfs_dir_sync(fatfs_dir_t *);
 void fatfs_dir_release(fatfs_dir_t *, fatfs_node_t *n);
 int fatfs_dir_getdents(fatfs_dir_t *, dirent_t *, int first, int n);
 /// pomocnicze makro rzutuj�ce v_private