}
static int
-filelayout_scan_ds_commit_list(struct nfs4_fl_commit_bucket *bucket, int max)
+filelayout_scan_ds_commit_list(struct nfs4_fl_commit_bucket *bucket, int max,
+ spinlock_t *lock)
{
struct list_head *src = &bucket->written;
struct list_head *dst = &bucket->committing;
list_for_each_entry_safe(req, tmp, src, wb_list) {
if (!nfs_lock_request(req))
continue;
+ if (cond_resched_lock(lock))
+ list_safe_reset_next(req, tmp, wb_list);
nfs_request_remove_commit_list(req);
clear_bit(PG_COMMIT_TO_DS, &req->wb_flags);
nfs_list_add_request(req, dst);
/* Move reqs from written to committing lists, returning count of number moved.
* Note called with i_lock held.
*/
-static int filelayout_scan_commit_lists(struct inode *inode, int max)
+static int filelayout_scan_commit_lists(struct inode *inode, int max,
+ spinlock_t *lock)
{
struct pnfs_layout_segment *lseg;
struct nfs4_filelayout_segment *fl;
if (fl->commit_through_mds)
goto out_done;
for (i = 0; i < fl->number_of_buckets && max != 0; i++) {
- cnt = filelayout_scan_ds_commit_list(&fl->commit_buckets[i], max);
+ cnt = filelayout_scan_ds_commit_list(&fl->commit_buckets[i],
+ max, lock);
max -= cnt;
rv += cnt;
}
void (*mark_request_commit) (struct nfs_page *req,
struct pnfs_layout_segment *lseg);
void (*clear_request_commit) (struct nfs_page *req);
- int (*scan_commit_lists) (struct inode *inode, int max);
+ int (*scan_commit_lists) (struct inode *inode, int max, spinlock_t *lock);
int (*commit_pagelist)(struct inode *inode, struct list_head *mds_pages, int how);
/*
}
static inline int
-pnfs_scan_commit_lists(struct inode *inode, int max)
+pnfs_scan_commit_lists(struct inode *inode, int max, spinlock_t *lock)
{
struct pnfs_layoutdriver_type *ld = NFS_SERVER(inode)->pnfs_curr_ld;
int ret;
if (ld == NULL || ld->scan_commit_lists == NULL)
return 0;
- ret = ld->scan_commit_lists(inode, max);
+ ret = ld->scan_commit_lists(inode, max, lock);
if (ret != 0)
set_bit(NFS_INO_PNFS_COMMIT, &NFS_I(inode)->flags);
return ret;
}
static inline int
-pnfs_scan_commit_lists(struct inode *inode, int max)
+pnfs_scan_commit_lists(struct inode *inode, int max, spinlock_t *lock)
{
return 0;
}
/* i_lock held by caller */
static int
-nfs_scan_commit_list(struct list_head *src, struct list_head *dst, int max)
+nfs_scan_commit_list(struct list_head *src, struct list_head *dst, int max,
+ spinlock_t *lock)
{
struct nfs_page *req, *tmp;
int ret = 0;
list_for_each_entry_safe(req, tmp, src, wb_list) {
if (!nfs_lock_request(req))
continue;
+ if (cond_resched_lock(lock))
+ list_safe_reset_next(req, tmp, wb_list);
nfs_request_remove_commit_list(req);
nfs_list_add_request(req, dst);
ret++;
if (nfsi->ncommit > 0) {
const int max = INT_MAX;
- ret = nfs_scan_commit_list(&nfsi->commit_list, dst, max);
- ret += pnfs_scan_commit_lists(inode, max - ret);
+ ret = nfs_scan_commit_list(&nfsi->commit_list, dst, max,
+ &inode->i_lock);
+ ret += pnfs_scan_commit_lists(inode, max - ret,
+ &inode->i_lock);
}
spin_unlock(&inode->i_lock);
return ret;