Author: kib
Date: Thu Jun  4 12:23:15 2020
New Revision: 361785
URL: https://svnweb.freebsd.org/changeset/base/361785

Log:
  UFS: write inode block for fdatasync(2) if pointers in inode where allocated
  
  The fdatasync() description in POSIX specifies that
      all I/O operations shall be completed as defined for synchronized I/O
      data integrity completion.
  and then the explanation of Synchronized I/O Data Integrity Completion says
      The write is complete only when the data specified in the write
      request is successfully transferred and all file system
      information required to retrieve the data is successfully
      transferred.
  
  For UFS this means that all pointers must be on disk. Indirect
  pointers already contribute to the list of dirty data blocks, so only
  direct blocks and root pointers to indirect blocks, both of which
  reside in the inode block, should be taken care of. In ffs_balloc(),
  mark the inode with the new flag IN_IBLKDATA that specifies that
  ffs_syncvnode(DATA_ONLY) needs a call to ffs_update() to flush the
  inode block.
  
  Reviewed by:  mckusick
  Discussed with:       tmunro
  Sponsored by: The FreeBSD Foundation
  MFC after:    1 week
  Differential revision:        https://reviews.freebsd.org/D25072

Modified:
  head/sys/ufs/ffs/ffs_balloc.c
  head/sys/ufs/ffs/ffs_inode.c
  head/sys/ufs/ffs/ffs_vnops.c
  head/sys/ufs/ufs/inode.h

Modified: head/sys/ufs/ffs/ffs_balloc.c
==============================================================================
--- head/sys/ufs/ffs/ffs_balloc.c       Thu Jun  4 09:06:03 2020        
(r361784)
+++ head/sys/ufs/ffs/ffs_balloc.c       Thu Jun  4 12:23:15 2020        
(r361785)
@@ -224,7 +224,7 @@ ffs_balloc_ufs1(struct vnode *vp, off_t startoffset, i
                                    nsize, 0, bp);
                }
                dp->di_db[lbn] = dbtofsb(fs, bp->b_blkno);
-               UFS_INODE_SET_FLAG(ip, IN_CHANGE | IN_UPDATE);
+               UFS_INODE_SET_FLAG(ip, IN_CHANGE | IN_UPDATE | IN_IBLKDATA);
                *bpp = bp;
                return (0);
        }
@@ -280,7 +280,7 @@ ffs_balloc_ufs1(struct vnode *vp, off_t startoffset, i
                }
                allocib = &dp->di_ib[indirs[0].in_off];
                *allocib = nb;
-               UFS_INODE_SET_FLAG(ip, IN_CHANGE | IN_UPDATE);
+               UFS_INODE_SET_FLAG(ip, IN_CHANGE | IN_UPDATE | IN_IBLKDATA);
        }
        /*
         * Fetch through the indirect blocks, allocating as necessary.
@@ -721,7 +721,7 @@ ffs_balloc_ufs2(struct vnode *vp, off_t startoffset, i
                                    nsize, 0, bp);
                }
                dp->di_extb[lbn] = dbtofsb(fs, bp->b_blkno);
-               UFS_INODE_SET_FLAG(ip, IN_CHANGE);
+               UFS_INODE_SET_FLAG(ip, IN_CHANGE | IN_IBLKDATA);
                *bpp = bp;
                return (0);
        }
@@ -750,7 +750,8 @@ ffs_balloc_ufs2(struct vnode *vp, off_t startoffset, i
                        ip->i_size = smalllblktosize(fs, nb + 1);
                        dp->di_size = ip->i_size;
                        dp->di_db[nb] = dbtofsb(fs, bp->b_blkno);
-                       UFS_INODE_SET_FLAG(ip, IN_CHANGE | IN_UPDATE);
+                       UFS_INODE_SET_FLAG(ip, IN_CHANGE | IN_UPDATE |
+                           IN_IBLKDATA);
                        if (flags & IO_SYNC)
                                bwrite(bp);
                        else
@@ -820,7 +821,7 @@ ffs_balloc_ufs2(struct vnode *vp, off_t startoffset, i
                                    nsize, 0, bp);
                }
                dp->di_db[lbn] = dbtofsb(fs, bp->b_blkno);
-               UFS_INODE_SET_FLAG(ip, IN_CHANGE | IN_UPDATE);
+               UFS_INODE_SET_FLAG(ip, IN_CHANGE | IN_UPDATE | IN_IBLKDATA);
                *bpp = bp;
                return (0);
        }
@@ -877,7 +878,7 @@ ffs_balloc_ufs2(struct vnode *vp, off_t startoffset, i
                }
                allocib = &dp->di_ib[indirs[0].in_off];
                *allocib = nb;
-               UFS_INODE_SET_FLAG(ip, IN_CHANGE | IN_UPDATE);
+               UFS_INODE_SET_FLAG(ip, IN_CHANGE | IN_UPDATE | IN_IBLKDATA);
        }
        /*
         * Fetch through the indirect blocks, allocating as necessary.

Modified: head/sys/ufs/ffs/ffs_inode.c
==============================================================================
--- head/sys/ufs/ffs/ffs_inode.c        Thu Jun  4 09:06:03 2020        
(r361784)
+++ head/sys/ufs/ffs/ffs_inode.c        Thu Jun  4 12:23:15 2020        
(r361785)
@@ -94,7 +94,7 @@ ffs_update(vp, waitfor)
        ip = VTOI(vp);
        if ((ip->i_flag & IN_MODIFIED) == 0 && waitfor == 0)
                return (0);
-       ip->i_flag &= ~(IN_LAZYACCESS | IN_LAZYMOD | IN_MODIFIED);
+       ip->i_flag &= ~(IN_LAZYACCESS | IN_LAZYMOD | IN_MODIFIED | IN_IBLKDATA);
        fs = ITOFS(ip);
        if (fs->fs_ronly && ITOUMP(ip)->um_fsckpid == 0)
                return (0);

Modified: head/sys/ufs/ffs/ffs_vnops.c
==============================================================================
--- head/sys/ufs/ffs/ffs_vnops.c        Thu Jun  4 09:06:03 2020        
(r361784)
+++ head/sys/ufs/ffs/ffs_vnops.c        Thu Jun  4 12:23:15 2020        
(r361785)
@@ -416,6 +416,8 @@ next:
                        error = ffs_update(vp, 1);
                if (DOINGSUJ(vp))
                        softdep_journal_fsync(VTOI(vp));
+       } else if ((ip->i_flags & IN_IBLKDATA) != 0) {
+               error = ffs_update(vp, 1);
        }
        return (error);
 }

Modified: head/sys/ufs/ufs/inode.h
==============================================================================
--- head/sys/ufs/ufs/inode.h    Thu Jun  4 09:06:03 2020        (r361784)
+++ head/sys/ufs/ufs/inode.h    Thu Jun  4 12:23:15 2020        (r361785)
@@ -129,13 +129,13 @@ struct inode {
                                           suspension finished */
 #define        IN_EA_LOCKED    0x0080
 #define        IN_EA_LOCKWAIT  0x0100
-
 #define        IN_TRUNCATED    0x0200          /* Journaled truncation 
pending. */
-
 #define        IN_UFS2         0x0400          /* UFS2 vs UFS1 */
+#define        IN_IBLKDATA     0x0800          /* datasync requires inode block
+                                          update */
 
 #define PRINT_INODE_FLAGS "\20\20b16\17b15\16b14\15b13" \
-       "\14b12\13is_ufs2\12truncated\11ea_lockwait\10ea_locked" \
+       "\14iblkdata\13is_ufs2\12truncated\11ea_lockwait\10ea_locked" \
        "\7lazyaccess\6lazymod\5needsync\4modified\3update\2change\1access"
 
 #define UFS_INODE_FLAG_LAZY_MASK       \
_______________________________________________
svn-src-head@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to