/* * xfs sync routine for internal use * * This routine supports all of the flags defined for the generic VFS_SYNC * interface as explained above under xfs_sync. In the interests of not * changing interfaces within the 6.5 family, additional internallly- * required functions are specified within a separate xflags parameter, * only available by calling this routine. * */ int xfs_syncsub( xfs_mount_t *mp, int flags, int xflags, int *bypassed) { int error = 0; int last_error = 0; uint log_flags = XFS_LOG_FORCE; xfs_buf_t *bp; xfs_buf_log_item_t *bip; /* * Sync out the log. This ensures that the log is periodically * flushed even if there is not enough activity to fill it up. */ if (flags & SYNC_WAIT) log_flags |= XFS_LOG_SYNC; xfs_log_force(mp, (xfs_lsn_t)0, log_flags); if (flags & (SYNC_ATTR|SYNC_DELWRI)) { if (flags & SYNC_BDFLUSH) xfs_finish_reclaim_all(mp, 1); else error = xfs_sync_inodes(mp, flags, xflags, bypassed); } /* * Flushing out dirty data above probably generated more * log activity, so if this isn't vfs_sync() then flush * the log again. */ if (flags & SYNC_DELWRI) { xfs_log_force(mp, (xfs_lsn_t)0, log_flags); } if (flags & SYNC_FSDATA) { /* * If this is vfs_sync() then only sync the superblock * if we can lock it without sleeping and it is not pinned. */ if (flags & SYNC_BDFLUSH) { bp = xfs_getsb(mp, XFS_BUF_TRYLOCK); if (bp != NULL) { bip = XFS_BUF_FSPRIVATE(bp,xfs_buf_log_item_t*); if ((bip != NULL) && xfs_buf_item_dirty(bip)) { if (!(XFS_BUF_ISPINNED(bp))) { XFS_BUF_ASYNC(bp); error = xfs_bwrite(mp, bp); } else { xfs_buf_relse(bp); } } else { xfs_buf_relse(bp); } } } else {
STATIC int xfs_sync_fsdata( struct xfs_mount *mp) { struct xfs_buf *bp; int error; bp = xfs_getsb(mp, 0); if (xfs_buf_ispinned(bp)) xfs_log_force(mp, 0); error = xfs_bwrite(bp); xfs_buf_relse(bp); return error; }
STATIC int xfs_sync_fsdata( struct xfs_mount *mp) { struct xfs_buf *bp; /* * If the buffer is pinned then push on the log so we won't get stuck * waiting in the write for someone, maybe ourselves, to flush the log. * * Even though we just pushed the log above, we did not have the * superblock buffer locked at that point so it can become pinned in * between there and here. */ bp = xfs_getsb(mp, 0); if (XFS_BUF_ISPINNED(bp)) xfs_log_force(mp, 0); return xfs_bwrite(mp, bp); }
int xfs_sync_fsdata( struct xfs_mount *mp, int flags) { struct xfs_buf *bp; struct xfs_buf_log_item *bip; int error = 0; /* * If this is xfssyncd() then only sync the superblock if we can * lock it without sleeping and it is not pinned. */ if (flags & SYNC_TRYLOCK) { ASSERT(!(flags & SYNC_WAIT)); bp = xfs_getsb(mp, XFS_BUF_TRYLOCK); if (!bp) goto out; bip = XFS_BUF_FSPRIVATE(bp, struct xfs_buf_log_item *); if (!bip || !xfs_buf_item_dirty(bip) || XFS_BUF_ISPINNED(bp)) goto out_brelse; } else {