]> git.saurik.com Git - apple/xnu.git/blobdiff - bsd/ufs/ffs/ffs_vfsops.c
xnu-344.tar.gz
[apple/xnu.git] / bsd / ufs / ffs / ffs_vfsops.c
index 7da3b2a3e856a6a4d36a4cbaf1a5244d3c4146c8..e91a041f756e30767217f5d0448b1b57c04a8d74 100644 (file)
@@ -72,6 +72,7 @@
 #include <sys/errno.h>
 #include <sys/malloc.h>
 #include <sys/ubc.h>
+#include <sys/quota.h>
 
 #include <miscfs/specfs/specdev.h>
 
@@ -126,8 +127,10 @@ ffs_mountroot()
                printf("ffs_mountroot: can't setup bdevvp");
                return (error);
        }
-       if (error = vfs_rootmountalloc("ufs", "root_device", &mp))
+       if (error = vfs_rootmountalloc("ufs", "root_device", &mp)) {
+               vrele(rootvp); /* release the reference from bdevvp() */
                return (error);
+       }
 
        /* Must set the MNT_ROOTFS flag before doing the actual mount */
        mp->mnt_flag |= MNT_ROOTFS;
@@ -135,6 +138,7 @@ ffs_mountroot()
        if (error = ffs_mountfs(rootvp, mp, p)) {
                mp->mnt_vfc->vfc_refcount--;
                vfs_unbusy(mp, p);
+               vrele(rootvp); /* release the reference from bdevvp() */
                _FREE_ZONE(mp, sizeof (struct mount), M_MOUNT);
                return (error);
        }
@@ -325,7 +329,7 @@ ffs_reload(mountp, cred, p)
 {
        register struct vnode *vp, *nvp, *devvp;
        struct inode *ip;
-       struct csum *space;
+       void *space;
        struct buf *bp;
        struct fs *fs, *newfs;
        int i, blks, size, error;
@@ -374,7 +378,7 @@ ffs_reload(mountp, cred, p)
         * new superblock. These should really be in the ufsmount.      XXX
         * Note that important parameters (eg fs_ncg) are unchanged.
         */
-       bcopy(&fs->fs_csp[0], &newfs->fs_csp[0], sizeof(fs->fs_csp));
+       newfs->fs_csp = fs->fs_csp;
        newfs->fs_maxcluster = fs->fs_maxcluster;
        bcopy(newfs, fs, (u_int)fs->fs_sbsize);
        if (fs->fs_sbsize < SBSIZE)
@@ -393,7 +397,7 @@ ffs_reload(mountp, cred, p)
         * Step 3: re-read summary information from disk.
         */
        blks = howmany(fs->fs_cssize, fs->fs_fsize);
-       space = fs->fs_csp[0];
+       space = fs->fs_csp;
        for (i = 0; i < blks; i += fs->fs_frag) {
                size = fs->fs_bsize;
                if (i + fs->fs_frag > blks)
@@ -409,7 +413,7 @@ ffs_reload(mountp, cred, p)
                        byte_swap_ints((int *)bp->b_data, size / sizeof(int));
                }
 #endif /* REV_ENDIAN_FS */
-               bcopy(bp->b_data, fs->fs_csp[fragstoblks(fs, i)], (u_int)size);
+               bcopy(bp->b_data, space, (u_int)size);
 #if REV_ENDIAN_FS
                if (rev_endian) {
                        /* csum swaps */
@@ -496,7 +500,7 @@ ffs_mountfs(devvp, mp, p)
        struct buf *cgbp;
        struct cg *cgp;
        int32_t clustersumoff;
-       caddr_t base, space;
+       void *space;
        int error, i, blks, size, ronly;
        int32_t *lp;
        struct ucred *cred;
@@ -683,15 +687,15 @@ ffs_mountfs(devvp, mp, p)
        blks = howmany(size, fs->fs_fsize);
        if (fs->fs_contigsumsize > 0)
                size += fs->fs_ncg * sizeof(int32_t);
-       base = space = _MALLOC((u_long)size, M_UFSMNT, M_WAITOK);
-       base = space;
+       space = _MALLOC((u_long)size, M_UFSMNT, M_WAITOK);
+       fs->fs_csp = space;
        for (i = 0; i < blks; i += fs->fs_frag) {
                size = fs->fs_bsize;
                if (i + fs->fs_frag > blks)
                        size = (blks - i) * fs->fs_fsize;
                if (error = bread(devvp, fsbtodb(fs, fs->fs_csaddr + i), size,
                    cred, &bp)) {
-                       _FREE(base, M_UFSMNT);
+                       _FREE(fs->fs_csp, M_UFSMNT);
                        goto out;
                }
                bcopy(bp->b_data, space, (u_int)size);
@@ -699,13 +703,12 @@ ffs_mountfs(devvp, mp, p)
                if (rev_endian)
                        byte_swap_ints((int *) space, size / sizeof(int));
 #endif /* REV_ENDIAN_FS */
-               fs->fs_csp[fragstoblks(fs, i)] = (struct csum *)space;
-               space += size;
+               space = (char *)space + size;
                brelse(bp);
                bp = NULL;
        }
        if (fs->fs_contigsumsize > 0) {
-               fs->fs_maxcluster = lp = (int32_t *)space;
+               fs->fs_maxcluster = lp = space;
                for (i = 0; i < fs->fs_ncg; i++)
                        *lp++ = fs->fs_contigsumsize;
        }
@@ -725,7 +728,7 @@ ffs_mountfs(devvp, mp, p)
        ump->um_bptrtodb = fs->fs_fsbtodb;
        ump->um_seqinc = fs->fs_frag;
        for (i = 0; i < MAXQUOTAS; i++)
-               ump->um_quotas[i] = NULLVP;
+               ump->um_qfiles[i].qf_vp = NULLVP;
        devvp->v_specflags |= SI_MOUNTEDON;
        ffs_oldfscompat(fs);
        ump->um_savedmaxfilesize = fs->fs_maxfilesize;          /* XXX */
@@ -792,10 +795,15 @@ ffs_unmount(mp, mntflags, p)
        register struct ufsmount *ump;
        register struct fs *fs;
        int error, flags;
+       int force;
+
        flags = 0;
-       if (mntflags & MNT_FORCE)
+       force = 0;
+       if (mntflags & MNT_FORCE) {
                flags |= FORCECLOSE;
-       if (error = ffs_flushfiles(mp, flags, p))
+               force = 1;
+       }
+       if ( (error = ffs_flushfiles(mp, flags, p)) && !force )
                return (error);
        ump = VFSTOUFS(mp);
        fs = ump->um_fs;
@@ -816,16 +824,18 @@ ffs_unmount(mp, mntflags, p)
        ump->um_devvp->v_specflags &= ~SI_MOUNTEDON;
        error = VOP_CLOSE(ump->um_devvp, fs->fs_ronly ? FREAD : FREAD|FWRITE,
                NOCRED, p);
+       if (error && !force)
+               return (error);
        vrele(ump->um_devvp);
 
-       _FREE(fs->fs_csp[0], M_UFSMNT);
+       _FREE(fs->fs_csp, M_UFSMNT);
        _FREE(fs, M_UFSMNT);
        _FREE(ump, M_UFSMNT);
        mp->mnt_data = (qaddr_t)0;
 #if REV_ENDIAN_FS
        mp->mnt_flag &= ~MNT_REVEND;
 #endif /* REV_ENDIAN_FS */
-       return (error);
+       return (0);
 }
 
 /*
@@ -845,7 +855,7 @@ ffs_flushfiles(mp, flags, p)
                if (error = vflush(mp, NULLVP, SKIPSYSTEM|flags))
                        return (error);
                for (i = 0; i < MAXQUOTAS; i++) {
-                       if (ump->um_quotas[i] == NULLVP)
+                       if (ump->um_qfiles[i].qf_vp == NULLVP)
                                continue;
                        quotaoff(p, mp, i);
                }
@@ -1244,7 +1254,7 @@ ffs_sbupdate(mp, waitfor)
        register struct fs *dfs, *fs = mp->um_fs;
        register struct buf *bp;
        int blks;
-       caddr_t space;
+       void *space;
        int i, size, error, allerror = 0;
        int devBlockSize=0;
 #if REV_ENDIAN_FS
@@ -1255,7 +1265,7 @@ ffs_sbupdate(mp, waitfor)
         * First write back the summary information.
         */
        blks = howmany(fs->fs_cssize, fs->fs_fsize);
-       space = (caddr_t)fs->fs_csp[0];
+       space = fs->fs_csp;
        for (i = 0; i < blks; i += fs->fs_frag) {
                size = fs->fs_bsize;
                if (i + fs->fs_frag > blks)
@@ -1268,7 +1278,7 @@ ffs_sbupdate(mp, waitfor)
                        byte_swap_ints((int *)bp->b_data, size / sizeof(int));
                }
 #endif /* REV_ENDIAN_FS */
-               space += size;
+               space = (char *)space + size;
                if (waitfor != MNT_WAIT)
                        bawrite(bp);
                else if (error = bwrite(bp))