diff options
Diffstat (limited to 'fs/xfs')
-rw-r--r-- | fs/xfs/linux-2.6/xfs_aops.c | 1 | ||||
-rw-r--r-- | fs/xfs/linux-2.6/xfs_super.c | 4 | ||||
-rw-r--r-- | fs/xfs/xfs_filestream.c | 10 | ||||
-rw-r--r-- | fs/xfs/xfs_mru_cache.c | 72 | ||||
-rw-r--r-- | fs/xfs/xfs_mru_cache.h | 6 | ||||
-rw-r--r-- | fs/xfs/xfs_vnodeops.c | 20 |
6 files changed, 51 insertions, 62 deletions
diff --git a/fs/xfs/linux-2.6/xfs_aops.c b/fs/xfs/linux-2.6/xfs_aops.c index d9c40fe..5f152f6 100644 --- a/fs/xfs/linux-2.6/xfs_aops.c +++ b/fs/xfs/linux-2.6/xfs_aops.c @@ -181,6 +181,7 @@ xfs_setfilesize( ip->i_d.di_size = isize; ip->i_update_core = 1; ip->i_update_size = 1; + mark_inode_dirty_sync(vn_to_inode(ioend->io_vnode)); } xfs_iunlock(ip, XFS_ILOCK_EXCL); diff --git a/fs/xfs/linux-2.6/xfs_super.c b/fs/xfs/linux-2.6/xfs_super.c index 4528f9a..491d1f4 100644 --- a/fs/xfs/linux-2.6/xfs_super.c +++ b/fs/xfs/linux-2.6/xfs_super.c @@ -415,8 +415,10 @@ xfs_fs_write_inode( if (vp) { vn_trace_entry(vp, __FUNCTION__, (inst_t *)__return_address); - if (sync) + if (sync) { + filemap_fdatawait(inode->i_mapping); flags |= FLUSH_SYNC; + } error = bhv_vop_iflush(vp, flags); if (error == EAGAIN) error = sync? bhv_vop_iflush(vp, flags | FLUSH_LOG) : 0; diff --git a/fs/xfs/xfs_filestream.c b/fs/xfs/xfs_filestream.c index ce22786..36d8f6a 100644 --- a/fs/xfs/xfs_filestream.c +++ b/fs/xfs/xfs_filestream.c @@ -350,9 +350,10 @@ _xfs_filestream_update_ag( /* xfs_fstrm_free_func(): callback for freeing cached stream items. */ void xfs_fstrm_free_func( - xfs_ino_t ino, - fstrm_item_t *item) + unsigned long ino, + void *data) { + fstrm_item_t *item = (fstrm_item_t *)data; xfs_inode_t *ip = item->ip; int ref; @@ -438,7 +439,7 @@ xfs_filestream_mount( grp_count = 10; err = xfs_mru_cache_create(&mp->m_filestream, lifetime, grp_count, - (xfs_mru_cache_free_func_t)xfs_fstrm_free_func); + xfs_fstrm_free_func); return err; } @@ -467,8 +468,7 @@ void xfs_filestream_flush( xfs_mount_t *mp) { - /* point in time flush, so keep the reaper running */ - xfs_mru_cache_flush(mp->m_filestream, 1); + xfs_mru_cache_flush(mp->m_filestream); } /* diff --git a/fs/xfs/xfs_mru_cache.c b/fs/xfs/xfs_mru_cache.c index 7deb9e3..e0b358c 100644 --- a/fs/xfs/xfs_mru_cache.c +++ b/fs/xfs/xfs_mru_cache.c @@ -206,8 +206,11 @@ _xfs_mru_cache_list_insert( */ if (!_xfs_mru_cache_migrate(mru, now)) { mru->time_zero = now; - if (!mru->next_reap) - mru->next_reap = mru->grp_count * mru->grp_time; + if (!mru->queued) { + mru->queued = 1; + queue_delayed_work(xfs_mru_reap_wq, &mru->work, + mru->grp_count * mru->grp_time); + } } else { grp = (now - mru->time_zero) / mru->grp_time; grp = (mru->lru_grp + grp) % mru->grp_count; @@ -271,29 +274,26 @@ _xfs_mru_cache_reap( struct work_struct *work) { xfs_mru_cache_t *mru = container_of(work, xfs_mru_cache_t, work.work); - unsigned long now; + unsigned long now, next; ASSERT(mru && mru->lists); if (!mru || !mru->lists) return; mutex_spinlock(&mru->lock); - now = jiffies; - if (mru->reap_all || - (mru->next_reap && time_after(now, mru->next_reap))) { - if (mru->reap_all) - now += mru->grp_count * mru->grp_time * 2; - mru->next_reap = _xfs_mru_cache_migrate(mru, now); - _xfs_mru_cache_clear_reap_list(mru); + next = _xfs_mru_cache_migrate(mru, jiffies); + _xfs_mru_cache_clear_reap_list(mru); + + mru->queued = next; + if ((mru->queued > 0)) { + now = jiffies; + if (next <= now) + next = 0; + else + next -= now; + queue_delayed_work(xfs_mru_reap_wq, &mru->work, next); } - /* - * the process that triggered the reap_all is responsible - * for restating the periodic reap if it is required. - */ - if (!mru->reap_all) - queue_delayed_work(xfs_mru_reap_wq, &mru->work, mru->grp_time); - mru->reap_all = 0; mutex_spinunlock(&mru->lock, 0); } @@ -352,7 +352,7 @@ xfs_mru_cache_create( /* An extra list is needed to avoid reaping up to a grp_time early. */ mru->grp_count = grp_count + 1; - mru->lists = kmem_alloc(mru->grp_count * sizeof(*mru->lists), KM_SLEEP); + mru->lists = kmem_zalloc(mru->grp_count * sizeof(*mru->lists), KM_SLEEP); if (!mru->lists) { err = ENOMEM; @@ -374,11 +374,6 @@ xfs_mru_cache_create( mru->grp_time = grp_time; mru->free_func = free_func; - /* start up the reaper event */ - mru->next_reap = 0; - mru->reap_all = 0; - queue_delayed_work(xfs_mru_reap_wq, &mru->work, mru->grp_time); - *mrup = mru; exit: @@ -394,35 +389,25 @@ exit: * Call xfs_mru_cache_flush() to flush out all cached entries, calling their * free functions as they're deleted. When this function returns, the caller is * guaranteed that all the free functions for all the elements have finished - * executing. - * - * While we are flushing, we stop the periodic reaper event from triggering. - * Normally, we want to restart this periodic event, but if we are shutting - * down the cache we do not want it restarted. hence the restart parameter - * where 0 = do not restart reaper and 1 = restart reaper. + * executing and the reaper is not running. */ void xfs_mru_cache_flush( - xfs_mru_cache_t *mru, - int restart) + xfs_mru_cache_t *mru) { if (!mru || !mru->lists) return; - cancel_rearming_delayed_workqueue(xfs_mru_reap_wq, &mru->work); - mutex_spinlock(&mru->lock); - mru->reap_all = 1; - mutex_spinunlock(&mru->lock, 0); + if (mru->queued) { + mutex_spinunlock(&mru->lock, 0); + cancel_rearming_delayed_workqueue(xfs_mru_reap_wq, &mru->work); + mutex_spinlock(&mru->lock); + } - queue_work(xfs_mru_reap_wq, &mru->work.work); - flush_workqueue(xfs_mru_reap_wq); + _xfs_mru_cache_migrate(mru, jiffies + mru->grp_count * mru->grp_time); + _xfs_mru_cache_clear_reap_list(mru); - mutex_spinlock(&mru->lock); - WARN_ON_ONCE(mru->reap_all != 0); - mru->reap_all = 0; - if (restart) - queue_delayed_work(xfs_mru_reap_wq, &mru->work, mru->grp_time); mutex_spinunlock(&mru->lock, 0); } @@ -433,8 +418,7 @@ xfs_mru_cache_destroy( if (!mru || !mru->lists) return; - /* we don't want the reaper to restart here */ - xfs_mru_cache_flush(mru, 0); + xfs_mru_cache_flush(mru); kmem_free(mru->lists, mru->grp_count * sizeof(*mru->lists)); kmem_free(mru, sizeof(*mru)); diff --git a/fs/xfs/xfs_mru_cache.h b/fs/xfs/xfs_mru_cache.h index 624fd10..dd58ea1 100644 --- a/fs/xfs/xfs_mru_cache.h +++ b/fs/xfs/xfs_mru_cache.h @@ -32,11 +32,9 @@ typedef struct xfs_mru_cache unsigned int grp_time; /* Time period spanned by grps. */ unsigned int lru_grp; /* Group containing time zero. */ unsigned long time_zero; /* Time first element was added. */ - unsigned long next_reap; /* Time that the reaper should - next do something. */ - unsigned int reap_all; /* if set, reap all lists */ xfs_mru_cache_free_func_t free_func; /* Function pointer for freeing. */ struct delayed_work work; /* Workqueue data for reaping. */ + unsigned int queued; /* work has been queued */ } xfs_mru_cache_t; int xfs_mru_cache_init(void); @@ -44,7 +42,7 @@ void xfs_mru_cache_uninit(void); int xfs_mru_cache_create(struct xfs_mru_cache **mrup, unsigned int lifetime_ms, unsigned int grp_count, xfs_mru_cache_free_func_t free_func); -void xfs_mru_cache_flush(xfs_mru_cache_t *mru, int restart); +void xfs_mru_cache_flush(xfs_mru_cache_t *mru); void xfs_mru_cache_destroy(struct xfs_mru_cache *mru); int xfs_mru_cache_insert(struct xfs_mru_cache *mru, unsigned long key, void *value); diff --git a/fs/xfs/xfs_vnodeops.c b/fs/xfs/xfs_vnodeops.c index 1a5ad8c..6034592 100644 --- a/fs/xfs/xfs_vnodeops.c +++ b/fs/xfs/xfs_vnodeops.c @@ -1082,6 +1082,9 @@ xfs_fsync( if (XFS_FORCED_SHUTDOWN(ip->i_mount)) return XFS_ERROR(EIO); + if (flag & FSYNC_DATA) + filemap_fdatawait(vn_to_inode(XFS_ITOV(ip))->i_mapping); + /* * We always need to make sure that the required inode state * is safe on disk. The vnode might be clean but because @@ -3769,12 +3772,16 @@ xfs_inode_flush( sync_lsn = log->l_last_sync_lsn; GRANT_UNLOCK(log, s); - if ((XFS_LSN_CMP(iip->ili_last_lsn, sync_lsn) <= 0)) - return 0; + if ((XFS_LSN_CMP(iip->ili_last_lsn, sync_lsn) > 0)) { + if (flags & FLUSH_SYNC) + log_flags |= XFS_LOG_SYNC; + error = xfs_log_force(mp, iip->ili_last_lsn, log_flags); + if (error) + return error; + } - if (flags & FLUSH_SYNC) - log_flags |= XFS_LOG_SYNC; - return xfs_log_force(mp, iip->ili_last_lsn, log_flags); + if (ip->i_update_core == 0) + return 0; } } @@ -3788,9 +3795,6 @@ xfs_inode_flush( if (flags & FLUSH_INODE) { int flush_flags; - if (xfs_ipincount(ip)) - return EAGAIN; - if (flags & FLUSH_SYNC) { xfs_ilock(ip, XFS_ILOCK_SHARED); xfs_iflock(ip); |