Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 7 Aug 2014 16:53:07 +0000 (UTC)
From:      Kirk McKusick <mckusick@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r269674 - head/sys/ufs/ffs
Message-ID:  <53e3aef3.242f.1f52e61b@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: mckusick
Date: Thu Aug  7 16:53:07 2014
New Revision: 269674
URL: http://svnweb.freebsd.org/changeset/base/269674

Log:
  The SUJ journal is only prepared to handle full-size block numbers, so we
  have to adjust freeblk records to reflect the change to a full-size block.
  For example, suppose we have a block made up of fragments 8-15 and
  want to free its last two fragments. We are given a request that says:
      FREEBLK ino=5, blkno=14, lbn=0, frags=2, oldfrags=0
  where frags are the number of fragments to free and oldfrags are the
  number of fragments to keep. To block align it, we have to change it to
  have a valid full-size blkno, so it becomes:
      FREEBLK ino=5, blkno=8, lbn=0, frags=2, oldfrags=6
  
  Submitted by: Mikihito Takehara
  Tested by:    Mikihito Takehara
  Reviewed by:  Jeff Roberson
  MFC after:    1 week

Modified:
  head/sys/ufs/ffs/ffs_softdep.c

Modified: head/sys/ufs/ffs/ffs_softdep.c
==============================================================================
--- head/sys/ufs/ffs/ffs_softdep.c	Thu Aug  7 16:52:59 2014	(r269673)
+++ head/sys/ufs/ffs/ffs_softdep.c	Thu Aug  7 16:53:07 2014	(r269674)
@@ -931,6 +931,7 @@ static	inline struct jsegdep *inoref_jse
 static	struct jmvref *newjmvref(struct inode *, ino_t, off_t, off_t);
 static	struct jfreeblk *newjfreeblk(struct freeblks *, ufs_lbn_t,
 	    ufs2_daddr_t, int);
+static	void adjust_newfreework(struct freeblks *, int);
 static	struct jtrunc *newjtrunc(struct freeblks *, off_t, int);
 static	void move_newblock_dep(struct jaddref *, struct inodedep *);
 static	void cancel_jfreeblk(struct freeblks *, ufs2_daddr_t);
@@ -4163,6 +4164,33 @@ newjfreeblk(freeblks, lbn, blkno, frags)
 }
 
 /*
+ * The journal is only prepared to handle full-size block numbers, so we
+ * have to adjust the record to reflect the change to a full-size block.
+ * For example, suppose we have a block made up of fragments 8-15 and
+ * want to free its last two fragments. We are given a request that says:
+ *     FREEBLK ino=5, blkno=14, lbn=0, frags=2, oldfrags=0
+ * where frags are the number of fragments to free and oldfrags are the
+ * number of fragments to keep. To block align it, we have to change it to
+ * have a valid full-size blkno, so it becomes:
+ *     FREEBLK ino=5, blkno=8, lbn=0, frags=2, oldfrags=6
+ */
+static void
+adjust_newfreework(freeblks, frag_offset)
+	struct freeblks *freeblks;
+	int frag_offset;
+{
+	struct jfreeblk *jfreeblk;
+
+	KASSERT((LIST_FIRST(&freeblks->fb_jblkdephd) != NULL &&
+	    LIST_FIRST(&freeblks->fb_jblkdephd)->jb_list.wk_type == D_JFREEBLK),
+	    ("adjust_newfreework: Missing freeblks dependency"));
+
+	jfreeblk = WK_JFREEBLK(LIST_FIRST(&freeblks->fb_jblkdephd));
+	jfreeblk->jf_blkno -= frag_offset;
+	jfreeblk->jf_frags += frag_offset;
+}
+
+/*
  * Allocate a new jtrunc to track a partial truncation.
  */
 static struct jtrunc *
@@ -6529,6 +6557,9 @@ softdep_journal_freeblocks(ip, cred, len
 				blkno += numfrags(ip->i_fs, frags);
 				newfreework(ump, freeblks, NULL, lastlbn,
 				    blkno, oldfrags, 0, needj);
+				if (needj)
+					adjust_newfreework(freeblks,
+					    numfrags(ip->i_fs, frags));
 			} else if (blkno == 0)
 				allocblock = 1;
 		}



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?53e3aef3.242f.1f52e61b>