Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/usr.sbin/makefs fixed directory entry allocation. Now the fi...



details:   https://anonhg.NetBSD.org/src/rev/d95dd763016f
branches:  trunk
changeset: 784387:d95dd763016f
user:      christos <christos%NetBSD.org@localhost>
date:      Sun Jan 27 15:35:45 2013 +0000

description:
fixed directory entry allocation. Now the file data remains and is currently
broken.

diffstat:

 usr.sbin/makefs/msdos.c                |   12 +-
 usr.sbin/makefs/msdos/msdosfs_vfsops.c |   17 +-
 usr.sbin/makefs/msdos/msdosfs_vnops.c  |  286 ++++++++++++++++++++++++++++++--
 3 files changed, 281 insertions(+), 34 deletions(-)

diffs (truncated from 490 to 300 lines):

diff -r a7171c2af6b7 -r d95dd763016f usr.sbin/makefs/msdos.c
--- a/usr.sbin/makefs/msdos.c   Sun Jan 27 15:21:38 2013 +0000
+++ b/usr.sbin/makefs/msdos.c   Sun Jan 27 15:35:45 2013 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: msdos.c,v 1.6 2013/01/26 00:20:40 christos Exp $       */
+/*     $NetBSD: msdos.c,v 1.7 2013/01/27 15:35:45 christos Exp $       */
 
 /*-
  * Copyright (c) 2013 The NetBSD Foundation, Inc.
@@ -37,7 +37,7 @@
 
 #include <sys/cdefs.h>
 #if defined(__RCSID) && !defined(__lint)
-__RCSID("$NetBSD: msdos.c,v 1.6 2013/01/26 00:20:40 christos Exp $");
+__RCSID("$NetBSD: msdos.c,v 1.7 2013/01/27 15:35:45 christos Exp $");
 #endif /* !__lint */
 
 #include <sys/param.h>
@@ -62,6 +62,8 @@
 #include "msdos.h"
 #include "mkfs_msdos.h"
 
+extern int sectorsize; /* XXX: horrid */
+
 static int msdos_populate_dir(const char *, struct denode *, fsnode *,
     fsnode *, fsinfo_t *);
 
@@ -149,6 +151,7 @@
         * Is minsize right here?
         */
        msdos_opt->create_size = MAX(msdos_opt->create_size, fsopts->minsize);
+       msdos_opt->bytes_per_sector = sectorsize = 512;
 
                /* create image */
        printf("Creating `%s'\n", image);
@@ -159,7 +162,7 @@
 
        vp.fd = open(image, O_RDWR);
        vp.fs = msdos_opt;
-       vp.offset = 1;
+       vp.offset = 0;
 
        if ((pmp = msdosfs_mount(&vp, 0)) == NULL)
                err(1, "msdosfs_mount");
@@ -171,9 +174,6 @@
                printf("msdos_makefs: image %s directory %s root %p\n",
                    image, dir, root);
 
-       printf("Calculated size of `%s': %lld bytes, %lld inodes\n",
-           image, (long long)fsopts->size, (long long)fsopts->inodes);
-
                /* populate image */
        printf("Populating `%s'\n", image);
        TIMER_START(start);
diff -r a7171c2af6b7 -r d95dd763016f usr.sbin/makefs/msdos/msdosfs_vfsops.c
--- a/usr.sbin/makefs/msdos/msdosfs_vfsops.c    Sun Jan 27 15:21:38 2013 +0000
+++ b/usr.sbin/makefs/msdos/msdosfs_vfsops.c    Sun Jan 27 15:35:45 2013 +0000
@@ -50,7 +50,7 @@
 #endif
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: msdosfs_vfsops.c,v 1.3 2013/01/26 16:50:46 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: msdosfs_vfsops.c,v 1.4 2013/01/27 15:35:45 christos Exp $");
 
 #include <sys/param.h>
 
@@ -94,7 +94,8 @@
        uint64_t psize = m->create_size;
        unsigned secsize = 512;
 
-       if ((error = bread(devvp, 1, secsize, NULL, 0, &bp)) != 0)
+       DPRINTF(("%s(bread 0)\n", __func__));
+       if ((error = bread(devvp, 0, secsize, NULL, 0, &bp)) != 0)
                goto error_exit;
 
        bsp = (union bootsector *)bp->b_data;
@@ -135,6 +136,11 @@
        pmp->pm_Heads = getushort(b50->bpbHeads);
        pmp->pm_Media = b50->bpbMedia;
 
+       DPRINTF(("%s(BytesPerSec=%u, ResSectors=%u, FATs=%d, RootDirEnts=%u, "
+           "Sectors=%u, FATsecs=%lu, SecPerTrack=%u, Heads=%u, Media=%u)\n",
+           __func__, pmp->pm_BytesPerSec, pmp->pm_ResSectors, pmp->pm_FATs,
+           pmp->pm_RootDirEnts, pmp->pm_Sectors, pmp->pm_FATsecs,
+           pmp->pm_SecPerTrack, pmp->pm_Heads, pmp->pm_Media));
        if (!(flags & MSDOSFSMNT_GEMDOSFS)) {
                /* XXX - We should probably check more values here */
                if (!pmp->pm_BytesPerSec || !SecPerClust
@@ -323,6 +329,8 @@
                 *      2KB or larger sectors, is the fsinfo structure
                 *      padded at the end or in the middle?
                 */
+               DPRINTF(("%s(bread %lu)\n", __func__,
+                   (unsigned long)de_bn2kb(pmp, pmp->pm_fsinfo)));
                if ((error = bread(devvp, de_bn2kb(pmp, pmp->pm_fsinfo),
                    pmp->pm_BytesPerSec, NULL, 0, &bp)) != 0)
                        goto error_exit;
@@ -352,9 +360,8 @@
         * Allocate memory for the bitmap of allocated clusters, and then
         * fill it in.
         */
-       pmp->pm_inusemap = malloc(((pmp->pm_maxcluster + N_INUSEBITS)
-                                  / N_INUSEBITS)
-                                 * sizeof(*pmp->pm_inusemap));
+       pmp->pm_inusemap = calloc(sizeof(*pmp->pm_inusemap),
+           ((pmp->pm_maxcluster + N_INUSEBITS) / N_INUSEBITS));
        if (pmp->pm_inusemap == NULL)
                goto error_exit;
 
diff -r a7171c2af6b7 -r d95dd763016f usr.sbin/makefs/msdos/msdosfs_vnops.c
--- a/usr.sbin/makefs/msdos/msdosfs_vnops.c     Sun Jan 27 15:21:38 2013 +0000
+++ b/usr.sbin/makefs/msdos/msdosfs_vnops.c     Sun Jan 27 15:35:45 2013 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: msdosfs_vnops.c,v 1.6 2013/01/27 12:25:13 martin Exp $ */
+/*     $NetBSD: msdosfs_vnops.c,v 1.7 2013/01/27 15:35:45 christos Exp $ */
 
 /*-
  * Copyright (C) 1994, 1995, 1997 Wolfgang Solfrank.
@@ -51,7 +51,7 @@
 #endif
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: msdosfs_vnops.c,v 1.6 2013/01/27 12:25:13 martin Exp $");
+__KERNEL_RCSID(0, "$NetBSD: msdosfs_vnops.c,v 1.7 2013/01/27 15:35:45 christos Exp $");
 
 #include <sys/param.h>
 #include <sys/mman.h>
@@ -78,9 +78,9 @@
  * the contents of a file are read/written using the vnode for the file
  * (including directories when they are read/written as files). This
  * presents problems for the dos filesystem because data that should be in
- * an inode (if dos had them) resides in the directory itself.  Since we
+ * an inode (if dos had them) resides in the directory itself. Since we
  * must update directory entries without the benefit of having the vnode
- * for the directory we must use the vnode for the filesystem.  This means
+ * for the directory we must use the vnode for the filesystem. This means
  * that when a directory is actually read/written (via read, write, or
  * readdir, or seek) we must use the vnode for the filesystem instead of
  * the vnode for the directory as would happen in ufs. This is to insure we
@@ -106,6 +106,235 @@
 }
 
 /*
+ * When we search a directory the blocks containing directory entries are
+ * read and examined.  The directory entries contain information that would
+ * normally be in the inode of a unix filesystem.  This means that some of
+ * a directory's contents may also be in memory resident denodes (sort of
+ * an inode).  This can cause problems if we are searching while some other
+ * process is modifying a directory.  To prevent one process from accessing
+ * incompletely modified directory information we depend upon being the
+ * sole owner of a directory block.  bread/brelse provide this service.
+ * This being the case, when a process modifies a directory it must first
+ * acquire the disk block that contains the directory entry to be modified.
+ * Then update the disk block and the denode, and then write the disk block
+ * out to disk.         This way disk blocks containing directory entries and in
+ * memory denode's will be in synch.
+ */
+static int
+msdosfs_findslot(struct denode *dp, struct componentname *cnp) 
+{
+       daddr_t bn;
+       int error;
+       int slotcount;
+       int slotoffset = 0;
+       int frcn;
+       u_long cluster;
+       int blkoff;
+       u_int diroff;
+       int blsize;
+       struct denode *tdp;
+       struct msdosfsmount *pmp;
+       struct buf *bp = 0;
+       struct direntry *dep;
+       u_char dosfilename[12];
+       int wincnt = 1;
+       int chksum = -1, chksum_ok;
+       int olddos = 1;
+
+       pmp = dp->de_pmp;
+       switch (unix2dosfn((const u_char *)cnp->cn_nameptr, dosfilename,
+           cnp->cn_namelen, 0)) {
+       case 0:
+               return (EINVAL);
+       case 1:
+               break;
+       case 2:
+               wincnt = winSlotCnt((const u_char *)cnp->cn_nameptr,
+                   cnp->cn_namelen) + 1;
+               break;
+       case 3:
+               olddos = 0;
+               wincnt = winSlotCnt((const u_char *)cnp->cn_nameptr,
+                   cnp->cn_namelen) + 1;
+               break;
+       }
+
+       if (pmp->pm_flags & MSDOSFSMNT_SHORTNAME)
+               wincnt = 1;
+
+       /*
+        * Suppress search for slots unless creating
+        * file and at end of pathname, in which case
+        * we watch for a place to put the new file in
+        * case it doesn't already exist.
+        */
+       slotcount = 0;
+#ifdef MSDOSFS_DEBUG
+       printf("%s(): dos filename: %s\n", __func__, dosfilename);
+#endif
+       /*
+        * Search the directory pointed at by vdp for the name pointed at
+        * by cnp->cn_nameptr.
+        */
+       tdp = NULL;
+       /*
+        * The outer loop ranges over the clusters that make up the
+        * directory.  Note that the root directory is different from all
+        * other directories.  It has a fixed number of blocks that are not
+        * part of the pool of allocatable clusters.  So, we treat it a
+        * little differently. The root directory starts at "cluster" 0.
+        */
+       diroff = 0;
+       for (frcn = 0; diroff < dp->de_FileSize; frcn++) {
+               if ((error = pcbmap(dp, frcn, &bn, &cluster, &blsize)) != 0) {
+                       if (error == E2BIG)
+                               break;
+                       return (error);
+               }
+               error = bread(pmp->pm_devvp, de_bn2kb(pmp, bn), blsize, NOCRED,
+                   0, &bp);
+               if (error) {
+                       return (error);
+               }
+               for (blkoff = 0; blkoff < blsize;
+                    blkoff += sizeof(struct direntry),
+                    diroff += sizeof(struct direntry)) {
+                       dep = (struct direntry *)((char *)bp->b_data + blkoff);
+                       /*
+                        * If the slot is empty and we are still looking
+                        * for an empty then remember this one.  If the
+                        * slot is not empty then check to see if it
+                        * matches what we are looking for.  If the slot
+                        * has never been filled with anything, then the
+                        * remainder of the directory has never been used,
+                        * so there is no point in searching it.
+                        */
+                       if (dep->deName[0] == SLOT_EMPTY ||
+                           dep->deName[0] == SLOT_DELETED) {
+                               /*
+                                * Drop memory of previous long matches
+                                */
+                               chksum = -1;
+
+                               if (slotcount < wincnt) {
+                                       slotcount++;
+                                       slotoffset = diroff;
+                               }
+                               if (dep->deName[0] == SLOT_EMPTY) {
+                                       brelse(bp, 0);
+                                       goto notfound;
+                               }
+                       } else {
+                               /*
+                                * If there wasn't enough space for our
+                                * winentries, forget about the empty space
+                                */
+                               if (slotcount < wincnt)
+                                       slotcount = 0;
+
+                               /*
+                                * Check for Win95 long filename entry
+                                */
+                               if (dep->deAttributes == ATTR_WIN95) {
+                                       if (pmp->pm_flags & MSDOSFSMNT_SHORTNAME)
+                                               continue;
+
+                                       chksum = winChkName((const u_char *)cnp->cn_nameptr,
+                                                           cnp->cn_namelen,
+                                                           (struct winentry *)dep,
+                                                           chksum);
+                                       continue;
+                               }
+
+                               /*
+                                * Ignore volume labels (anywhere, not just
+                                * the root directory).
+                                */
+                               if (dep->deAttributes & ATTR_VOLUME) {
+                                       chksum = -1;
+                                       continue;
+                               }
+
+                               /*
+                                * Check for a checksum or name match
+                                */
+                               chksum_ok = (chksum == winChksum(dep->deName));
+                               if (!chksum_ok
+                                   && (!olddos || memcmp(dosfilename, dep->deName, 11))) {
+                                       chksum = -1;
+                                       continue;



Home | Main Index | Thread Index | Old Index