Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 14 Aug 2014 23:38:04 +0000 (UTC)
From:      Kirk McKusick <mckusick@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org
Subject:   svn commit: r270007 - stable/10/sys/ufs/ffs
Message-ID:  <201408142338.s7ENc4kx078342@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: mckusick
Date: Thu Aug 14 23:38:04 2014
New Revision: 270007
URL: http://svnweb.freebsd.org/changeset/base/270007

Log:
  MFC of 269674:
  
  The 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 frags 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

Modified:
  stable/10/sys/ufs/ffs/ffs_softdep.c
Directory Properties:
  stable/10/   (props changed)

Modified: stable/10/sys/ufs/ffs/ffs_softdep.c
==============================================================================
--- stable/10/sys/ufs/ffs/ffs_softdep.c	Thu Aug 14 23:17:33 2014	(r270006)
+++ stable/10/sys/ufs/ffs/ffs_softdep.c	Thu Aug 14 23:38:04 2014	(r270007)
@@ -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);
@@ -4066,6 +4067,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 *
@@ -6432,6 +6460,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?201408142338.s7ENc4kx078342>