/* * Every sync period we need to unpin all items, reclaim inodes and sync * disk quotas. We might need to cover the log to indicate that the * filesystem is idle and not frozen. */ STATIC void xfs_sync_worker( struct work_struct *work) { struct xfs_mount *mp = container_of(to_delayed_work(work), struct xfs_mount, m_sync_work); int error; /* * We shouldn't write/force the log if we are in the mount/unmount * process or on a read only filesystem. The workqueue still needs to be * active in both cases, however, because it is used for inode reclaim * during these times. Use the MS_ACTIVE flag to avoid doing anything * during mount. Doing work during unmount is avoided by calling * cancel_delayed_work_sync on this work queue before tearing down * the ail and the log in xfs_log_unmount. */ if (!(mp->m_super->s_flags & MS_ACTIVE) && !(mp->m_flags & XFS_MOUNT_RDONLY)) { /* dgc: errors ignored here */ if (mp->m_super->s_writers.frozen == SB_UNFROZEN && xfs_log_need_covered(mp)) error = xfs_fs_log_dummy(mp); else xfs_log_force(mp, 0); /* start pushing all the metadata that is currently * dirty */ xfs_ail_push_all(mp->m_ail); } /* queue us up again */ xfs_syncd_queue_sync(mp); }
/* * Every sync period we need to unpin all items, reclaim inodes and sync * disk quotas. We might need to cover the log to indicate that the * filesystem is idle and not frozen. */ STATIC void xfs_sync_worker( struct work_struct *work) { struct xfs_mount *mp = container_of(to_delayed_work(work), struct xfs_mount, m_sync_work); int error; /* * We shouldn't write/force the log if we are in the mount/unmount * process or on a read only filesystem. The workqueue still needs to be * active in both cases, however, because it is used for inode reclaim * during these times. Use the s_umount semaphore to provide exclusion * with unmount. */ if (down_read_trylock(&mp->m_super->s_umount)) { if (!(mp->m_flags & XFS_MOUNT_RDONLY)) { /* dgc: errors ignored here */ if (mp->m_super->s_frozen == SB_UNFROZEN && xfs_log_need_covered(mp)) error = xfs_fs_log_dummy(mp); else xfs_log_force(mp, 0); /* start pushing all the metadata that is currently * dirty */ xfs_ail_push_all(mp->m_ail); } up_read(&mp->m_super->s_umount); } /* queue us up again */ xfs_syncd_queue_sync(mp); }
void xfs_reclaim_inodes_nr( struct xfs_mount *mp, int nr_to_scan) { xfs_syncd_queue_reclaim(mp); xfs_ail_push_all(mp->m_ail); xfs_reclaim_inodes_ag(mp, SYNC_TRYLOCK | SYNC_WAIT, &nr_to_scan); }
/* * Scan a certain number of inodes for reclaim. * * When called we make sure that there is a background (fast) inode reclaim in * progress, while we will throttle the speed of reclaim via doing synchronous * reclaim of inodes. That means if we come across dirty inodes, we wait for * them to be cleaned, which we hope will not be very long due to the * background walker having already kicked the IO off on those dirty inodes. */ long xfs_reclaim_inodes_nr( struct xfs_mount *mp, int nr_to_scan) { /* kick background reclaimer and push the AIL */ xfs_reclaim_work_queue(mp); xfs_ail_push_all(mp->m_ail); return xfs_reclaim_inodes_ag(mp, SYNC_TRYLOCK | SYNC_WAIT, &nr_to_scan); }
STATIC void xfs_sync_worker( struct work_struct *work) { struct xfs_mount *mp = container_of(to_delayed_work(work), struct xfs_mount, m_sync_work); int error; if (!(mp->m_flags & XFS_MOUNT_RDONLY)) { if (mp->m_super->s_frozen == SB_UNFROZEN && xfs_log_need_covered(mp)) error = xfs_fs_log_dummy(mp); else xfs_log_force(mp, 0); xfs_ail_push_all(mp->m_ail); } xfs_syncd_queue_sync(mp); }
/* * Inode cache shrinker. * * When called we make sure that there is a background (fast) inode reclaim in * progress, while we will throttle the speed of reclaim via doiing synchronous * reclaim of inodes. That means if we come across dirty inodes, we wait for * them to be cleaned, which we hope will not be very long due to the * background walker having already kicked the IO off on those dirty inodes. */ static int xfs_reclaim_inode_shrink( struct shrinker *shrink, struct shrink_control *sc) { struct xfs_mount *mp; struct xfs_perag *pag; xfs_agnumber_t ag; int reclaimable; int nr_to_scan = sc->nr_to_scan; gfp_t gfp_mask = sc->gfp_mask; mp = container_of(shrink, struct xfs_mount, m_inode_shrink); if (nr_to_scan) { /* kick background reclaimer and push the AIL */ xfs_syncd_queue_reclaim(mp); xfs_ail_push_all(mp->m_ail); if (!(gfp_mask & __GFP_FS)) return -1; xfs_reclaim_inodes_ag(mp, SYNC_TRYLOCK | SYNC_WAIT, &nr_to_scan); /* terminate if we don't exhaust the scan */ if (nr_to_scan > 0) return -1; } reclaimable = 0; ag = 0; while ((pag = xfs_perag_get_tag(mp, ag, XFS_ICI_RECLAIM_TAG))) { ag = pag->pag_agno + 1; reclaimable += pag->pag_ici_reclaimable; xfs_perag_put(pag); } return reclaimable; }
/* * Every sync period we need to unpin all items, reclaim inodes and sync * disk quotas. We might need to cover the log to indicate that the * filesystem is idle and not frozen. */ STATIC void xfs_sync_worker( struct work_struct *work) { struct xfs_mount *mp = container_of(to_delayed_work(work), struct xfs_mount, m_sync_work); int error; if (!(mp->m_flags & XFS_MOUNT_RDONLY)) { /* dgc: errors ignored here */ if (mp->m_super->s_frozen == SB_UNFROZEN && xfs_log_need_covered(mp)) error = xfs_fs_log_dummy(mp); else xfs_log_force(mp, 0); error = xfs_qm_sync(mp, SYNC_TRYLOCK); /* start pushing all the metadata that is currently dirty */ xfs_ail_push_all(mp->m_ail); } /* queue us up again */ xfs_syncd_queue_sync(mp); }