svn commit: r264657 - head/sys/fs/nandfs

Warner Losh imp at FreeBSD.org
Fri Apr 18 17:03:36 UTC 2014


Author: imp
Date: Fri Apr 18 17:03:35 2014
New Revision: 264657
URL: http://svnweb.freebsd.org/changeset/base/264657

Log:
  More properly account for free/reserved segments to avoid deadlock or
  worse when filling up a device and then trying to erase files to make
  space. Without enough space, you can't do that. Also, ensure that the
  metadata writes don't generate ENOSPC. They will be retried later
  since the buffers are still dirty...
  
  Submitted by: mjg@

Modified:
  head/sys/fs/nandfs/bmap.c
  head/sys/fs/nandfs/nandfs.h
  head/sys/fs/nandfs/nandfs_subr.c
  head/sys/fs/nandfs/nandfs_vfsops.c

Modified: head/sys/fs/nandfs/bmap.c
==============================================================================
--- head/sys/fs/nandfs/bmap.c	Fri Apr 18 17:03:09 2014	(r264656)
+++ head/sys/fs/nandfs/bmap.c	Fri Apr 18 17:03:35 2014	(r264657)
@@ -387,11 +387,10 @@ bmap_truncate_indirect(struct nandfs_nod
 	if (modified)
 		bcopy(copy, bp->b_data, fsdev->nd_blocksize);
 
-	error = nandfs_dirty_buf_meta(bp, 0);
-	if (error)
-		return (error);
+	/* Force success even if we can't dirty the buffer metadata when freeing space */
+	nandfs_dirty_buf_meta(bp, 1);
 
-	return (error);
+	return (0);
 }
 
 int

Modified: head/sys/fs/nandfs/nandfs.h
==============================================================================
--- head/sys/fs/nandfs/nandfs.h	Fri Apr 18 17:03:09 2014	(r264656)
+++ head/sys/fs/nandfs/nandfs.h	Fri Apr 18 17:03:35 2014	(r264657)
@@ -200,6 +200,8 @@ struct nandfs_device {
 
 	uint32_t		nd_devblocksize;
 
+	uint32_t		nd_segs_reserved;
+
 	/* Segment usage */
 	uint64_t		nd_clean_segs;
 	uint64_t		*nd_free_base;

Modified: head/sys/fs/nandfs/nandfs_subr.c
==============================================================================
--- head/sys/fs/nandfs/nandfs_subr.c	Fri Apr 18 17:03:09 2014	(r264656)
+++ head/sys/fs/nandfs/nandfs_subr.c	Fri Apr 18 17:03:35 2014	(r264657)
@@ -910,7 +910,7 @@ nandfs_fs_full(struct nandfs_device *nff
 	DPRINTF(BUF, ("%s: bufs:%jx space:%jx\n", __func__,
 	    (uintmax_t)nffsdev->nd_dirty_bufs, (uintmax_t)space));
 
-	if (nffsdev->nd_dirty_bufs + (10 * bps) >= space)
+	if (nffsdev->nd_dirty_bufs + (nffsdev->nd_segs_reserved * bps) >= space)
 		return (1);
 
 	return (0);

Modified: head/sys/fs/nandfs/nandfs_vfsops.c
==============================================================================
--- head/sys/fs/nandfs/nandfs_vfsops.c	Fri Apr 18 17:03:09 2014	(r264656)
+++ head/sys/fs/nandfs/nandfs_vfsops.c	Fri Apr 18 17:03:35 2014	(r264657)
@@ -718,15 +718,24 @@ nandfs_mount_base(struct nandfs_device *
 	nandfsdev->nd_ts.tv_sec = nandfsdev->nd_last_segsum.ss_create;
 	nandfsdev->nd_last_cno = nandfsdev->nd_super.s_last_cno;
 	nandfsdev->nd_fakevblk = 1;
+	/*
+	 * FIXME: bogus calculation. Should use actual number of usable segments
+	 * instead of total amount.
+	 */
+	nandfsdev->nd_segs_reserved =
+	    nandfsdev->nd_fsdata.f_nsegments *
+	    nandfsdev->nd_fsdata.f_r_segments_percentage / 100;
 	nandfsdev->nd_last_ino  = NANDFS_USER_INO;
 	DPRINTF(VOLUMES, ("%s: last_pseg %#jx last_cno %#jx last_seq %#jx\n"
-	    "fsdev: last_seg: seq %#jx num %#jx, next_seg_num %#jx\n",
+	    "fsdev: last_seg: seq %#jx num %#jx, next_seg_num %#jx "
+	    "segs_reserved %#jx\n",
 	    __func__, (uintmax_t)nandfsdev->nd_last_pseg,
 	    (uintmax_t)nandfsdev->nd_last_cno,
 	    (uintmax_t)nandfsdev->nd_seg_sequence,
 	    (uintmax_t)nandfsdev->nd_seg_sequence,
 	    (uintmax_t)nandfsdev->nd_seg_num,
-	    (uintmax_t)nandfsdev->nd_next_seg_num));
+	    (uintmax_t)nandfsdev->nd_next_seg_num,
+	    (uintmax_t)nandfsdev->nd_segs_reserved));
 
 	DPRINTF(VOLUMES, ("nandfs_mount: accepted super root\n"));
 


More information about the svn-src-head mailing list