Source-Changes-HG archive

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

[src/trunk]: src/sys/ufs/lfs Comments



details:   https://anonhg.NetBSD.org/src/rev/9fffcc8448e8
branches:  trunk
changeset: 817061:9fffcc8448e8
user:      dholland <dholland%NetBSD.org@localhost>
date:      Sun Aug 07 00:12:48 2016 +0000

description:
Comments

diffstat:

 sys/ufs/lfs/lfs_alloc.c |  264 +++++++++++++++++++++++++++++++++++++++++++----
 1 files changed, 241 insertions(+), 23 deletions(-)

diffs (truncated from 609 to 300 lines):

diff -r a238a3137817 -r 9fffcc8448e8 sys/ufs/lfs/lfs_alloc.c
--- a/sys/ufs/lfs/lfs_alloc.c   Sat Aug 06 23:46:30 2016 +0000
+++ b/sys/ufs/lfs/lfs_alloc.c   Sun Aug 07 00:12:48 2016 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: lfs_alloc.c,v 1.131 2015/10/10 22:34:33 dholland Exp $ */
+/*     $NetBSD: lfs_alloc.c,v 1.132 2016/08/07 00:12:48 dholland Exp $ */
 
 /*-
  * Copyright (c) 1999, 2000, 2001, 2002, 2003, 2007 The NetBSD Foundation, Inc.
@@ -60,7 +60,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: lfs_alloc.c,v 1.131 2015/10/10 22:34:33 dholland Exp $");
+__KERNEL_RCSID(0, "$NetBSD: lfs_alloc.c,v 1.132 2016/08/07 00:12:48 dholland Exp $");
 
 #if defined(_KERNEL_OPT)
 #include "opt_quota.h"
@@ -127,6 +127,13 @@
 
        ASSERT_SEGLOCK(fs);
 
+       /* XXX should check or assert that we aren't readonly. */
+
+       /*
+        * Get a block and extend the ifile inode. Leave the buffer for
+        * the block in bp.
+        */
+
        vp = fs->lfs_ivnode;
        ip = VTOI(vp);
        blkno = lfs_lblkno(fs, ip->i_size);
@@ -138,6 +145,11 @@
        lfs_dino_setsize(fs, ip->i_din, ip->i_size);
        uvm_vnp_setsize(vp, ip->i_size);
 
+       /*
+        * Compute the new number of inodes, and reallocate the in-memory
+        * inode freemap.
+        */
+
        maxino = ((ip->i_size >> lfs_sb_getbshift(fs)) - lfs_sb_getcleansz(fs) -
                  lfs_sb_getsegtabsz(fs)) * lfs_sb_getifpb(fs);
        fs->lfs_ino_bitmap = (lfs_bm_t *)
@@ -145,6 +157,7 @@
                        sizeof(lfs_bm_t), M_SEGMENT, M_WAITOK);
        KASSERT(fs->lfs_ino_bitmap != NULL);
 
+       /* first new inode number */
        i = (blkno - lfs_sb_getsegtabsz(fs) - lfs_sb_getcleansz(fs)) *
                lfs_sb_getifpb(fs);
 
@@ -160,8 +173,17 @@
        if (lfs_sb_getfreehd(fs) == LFS_UNUSED_INUM)
                panic("inode 0 allocated [2]");
 #endif /* DIAGNOSTIC */
+
+       /* inode number to stop at (XXX: why *x*max?) */
        xmax = i + lfs_sb_getifpb(fs);
 
+       /*
+        * Initialize the ifile block.
+        *
+        * XXX: these loops should be restructured to use the accessor
+        * functions instead of using cutpaste polymorphism.
+        */
+
        if (fs->lfs_is64) {
                for (ifp64 = (IFILE64 *)bp->b_data; i < xmax; ++ifp64) {
                        SET_BITMAP_FREE(fs, i);
@@ -192,12 +214,23 @@
        }
        LFS_PUT_TAILFREE(fs, cip, cbp, xmax - 1);
 
+       /*
+        * Write out the new block.
+        */
+
        (void) LFS_BWRITE_LOG(bp); /* Ifile */
 
        return 0;
 }
 
-/* Allocate a new inode. */
+/*
+ * Allocate an inode for a new file.
+ *
+ * Takes the segment lock. Also (while holding it) takes lfs_lock
+ * to frob fs->lfs_fmod.
+ *
+ * XXX: the mode argument is unused; should just get rid of it.
+ */
 /* ARGSUSED */
 /* VOP_BWRITE 2i times */
 int
@@ -220,32 +253,48 @@
 
        /* Get the head of the freelist. */
        LFS_GET_HEADFREE(fs, cip, cbp, ino);
+
+       /* paranoia */
        KASSERT(*ino != LFS_UNUSED_INUM && *ino != LFS_IFILE_INUM);
-
        DLOG((DLOG_ALLOC, "lfs_valloc: allocate inode %" PRId64 "\n",
             *ino));
 
+       /* Update the in-memory inode freemap */
+       CLR_BITMAP_FREE(fs, *ino);
+
        /*
-        * Remove the inode from the free list and write the new start
-        * of the free list into the superblock.
+        * Fetch the ifile entry and make sure the inode is really
+        * free.
         */
-       CLR_BITMAP_FREE(fs, *ino);
        LFS_IENTRY(ifp, fs, *ino, bp);
        if (lfs_if_getdaddr(fs, ifp) != LFS_UNUSED_DADDR)
                panic("lfs_valloc: inuse inode %" PRId64 " on the free list",
                    *ino);
+
+       /* Update the inode freelist head in the superblock. */
        LFS_PUT_HEADFREE(fs, cip, cbp, lfs_if_getnextfree(fs, ifp));
        DLOG((DLOG_ALLOC, "lfs_valloc: headfree %" PRId64 " -> %ju\n",
             *ino, (uintmax_t)lfs_if_getnextfree(fs, ifp)));
 
-       /* version was updated by vfree */
+       /*
+        * Retrieve the version number from the ifile entry. It was
+        * bumped by vfree, so don't bump it again.
+        */
        *gen = lfs_if_getversion(fs, ifp);
+
+       /* Done with ifile entry */
        brelse(bp, 0);
 
-       /* Extend IFILE so that the next lfs_valloc will succeed. */
        if (lfs_sb_getfreehd(fs) == LFS_UNUSED_INUM) {
+               /*
+                * No more inodes; extend the ifile so that the next
+                * lfs_valloc will succeed.
+                */
                if ((error = lfs_extend_ifile(fs, cred)) != 0) {
+                       /* restore the freelist */
                        LFS_PUT_HEADFREE(fs, cip, cbp, *ino);
+
+                       /* unlock and return */
                        lfs_segunlock(fs);
                        return error;
                }
@@ -255,19 +304,28 @@
                panic("inode 0 allocated [3]");
 #endif /* DIAGNOSTIC */
 
-       /* Set superblock modified bit and increment file count. */
+       /* Set superblock modified bit */
        mutex_enter(&lfs_lock);
        fs->lfs_fmod = 1;
        mutex_exit(&lfs_lock);
+
+       /* increment file count */
        lfs_sb_addnfiles(fs, 1);
 
+       /* done */
        lfs_segunlock(fs);
-
        return 0;
 }
 
 /*
- * Allocate a new inode with given inode number and version.
+ * Allocate an inode for a new file, with given inode number and
+ * version.
+ *
+ * Called in the same context as lfs_valloc and therefore shares the
+ * same locking assumptions.
+ *
+ * XXX: WHICH MEANS IT OUGHT TO TAKE THE SEGLOCK WHILE FROBBING THIS
+ * XXX: STUFF. REALLY.
  */
 int
 lfs_valloc_fixed(struct lfs *fs, ino_t ino, int vers)
@@ -277,42 +335,68 @@
        ino_t headino, thisino, oldnext;
        CLEANERINFO *cip;
 
-       /* If the Ifile is too short to contain this inum, extend it */
+       /* XXX: check for readonly */
+       /* XXX: assert no seglock */
+       /* XXX: should take seglock (as noted above) */
+
+       /*
+        * If the ifile is too short to contain this inum, extend it.
+        *
+        * XXX: lfs_extend_ifile should take a size instead of always
+        * doing just one block at time.
+        */
        while (VTOI(fs->lfs_ivnode)->i_size <= (ino /
                lfs_sb_getifpb(fs) + lfs_sb_getcleansz(fs) + lfs_sb_getsegtabsz(fs))
                << lfs_sb_getbshift(fs)) {
                lfs_extend_ifile(fs, NOCRED);
        }
 
+       /*
+        * fetch the ifile entry; get the inode freelist next pointer,
+        * and set the version as directed.
+        */
        LFS_IENTRY(ifp, fs, ino, bp);
        oldnext = lfs_if_getnextfree(fs, ifp);
        lfs_if_setversion(fs, ifp, vers);
        brelse(bp, 0);
 
+       /* Get head of inode freelist */
        LFS_GET_HEADFREE(fs, cip, cbp, &headino);
        if (headino == ino) {
+               /* Easy case: the inode we wanted was at the head */
                LFS_PUT_HEADFREE(fs, cip, cbp, oldnext);
        } else {
                ino_t nextfree;
 
+               /* Have to find the desired inode in the freelist... */
+
                thisino = headino;
                while (1) {
+                       /* read this ifile entry */
                        LFS_IENTRY(ifp, fs, thisino, bp);
                        nextfree = lfs_if_getnextfree(fs, ifp);
+                       /* stop if we find it or we hit the end */
                        if (nextfree == ino ||
                            nextfree == LFS_UNUSED_INUM)
                                break;
+                       /* nope, keep going... */
                        thisino = nextfree;
                        brelse(bp, 0);
                }
                if (nextfree == LFS_UNUSED_INUM) {
+                       /* hit the end -- this inode is not available */
                        brelse(bp, 0);
+                       /* XXX release seglock (see above) */
                        return ENOENT;
                }
+               /* found it; update the next pointer */
                lfs_if_setnextfree(fs, ifp, oldnext);
+               /* write the ifile block */
                LFS_BWRITE_LOG(bp);
        }
 
+       /* done */
+       /* XXX release seglock (see above) */
        return 0;
 }
 
@@ -340,14 +424,18 @@
 /*
  * Find the previous (next lowest numbered) free inode, if any.
  * If there is none, return LFS_UNUSED_INUM.
+ *
+ * XXX: locking?
  */
 static inline ino_t
 lfs_freelist_prev(struct lfs *fs, ino_t ino)
 {
        ino_t tino, bound, bb, freehdbb;
 
-       if (lfs_sb_getfreehd(fs) == LFS_UNUSED_INUM)     /* No free inodes at all */
+       if (lfs_sb_getfreehd(fs) == LFS_UNUSED_INUM) {
+               /* No free inodes at all */
                return LFS_UNUSED_INUM;
+       }
 
        /* Search our own word first */
        bound = ino & ~BMMASK;
@@ -375,13 +463,18 @@
                if (ISSET_BITMAP_FREE(fs, tino))
                        break;
 
+       /* Avoid returning reserved inode numbers */
        if (tino <= LFS_IFILE_INUM)
                tino = LFS_UNUSED_INUM;
 
        return tino;
 }
 
-/* Free an inode. */
+/*
+ * Free an inode.
+ *
+ * Takes lfs_seglock. Also (independently) takes vp->v_interlock.
+ */
 /* ARGUSED */
 /* VOP_BWRITE 2i times */
 int
@@ -401,6 +494,8 @@
        fs = ip->i_lfs;
        ino = ip->i_number;
 
+       /* XXX: assert not readonly */
+
        ASSERT_NO_SEGLOCK(fs);
        DLOG((DLOG_ALLOC, "lfs_vfree: free ino %lld\n", (long long)ino));



Home | Main Index | Thread Index | Old Index