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"));
 
_______________________________________________
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to