diff options
| author | Daniel Vetter <daniel.vetter@ffwll.ch> | 2019-10-23 12:02:47 +0200 | 
|---|---|---|
| committer | Daniel Vetter <daniel.vetter@ffwll.ch> | 2019-10-23 12:10:05 +0200 | 
| commit | 2e79e22e092acd55da0b2db066e4826d7d152c41 (patch) | |
| tree | e7ec9782c0b7831c511af711424126a2b9a4eb07 /fs/nfs/direct.c | |
| parent | f1b4a9217efd61d0b84c6dc404596c8519ff6f59 (diff) | |
| parent | 7d194c2100ad2a6dded545887d02754948ca5241 (diff) | |
Merge v5.4-rc4 into drm-next
Thierry needs fd70c7755bf0 ("drm/bridge: tc358767: fix max_tu_symbol
value") to be able to merge his dp_link patch series.
Some adjacent changes conflicts, plus some clashes in i915 due to
cherry-picking and git trying to be helpful and leaving both versions
in.
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Diffstat (limited to 'fs/nfs/direct.c')
| -rw-r--r-- | fs/nfs/direct.c | 106 | 
1 files changed, 36 insertions, 70 deletions
diff --git a/fs/nfs/direct.c b/fs/nfs/direct.c index 222d7115db71..040a50fd9bf3 100644 --- a/fs/nfs/direct.c +++ b/fs/nfs/direct.c @@ -64,13 +64,6 @@  static struct kmem_cache *nfs_direct_cachep; -/* - * This represents a set of asynchronous requests that we're waiting on - */ -struct nfs_direct_mirror { -	ssize_t count; -}; -  struct nfs_direct_req {  	struct kref		kref;		/* release manager */ @@ -84,9 +77,6 @@ struct nfs_direct_req {  	atomic_t		io_count;	/* i/os we're waiting for */  	spinlock_t		lock;		/* protect completion state */ -	struct nfs_direct_mirror mirrors[NFS_PAGEIO_DESCRIPTOR_MIRROR_MAX]; -	int			mirror_count; -  	loff_t			io_start;	/* Start offset for I/O */  	ssize_t			count,		/* bytes actually processed */  				max_count,	/* max expected count */ @@ -123,32 +113,42 @@ static inline int put_dreq(struct nfs_direct_req *dreq)  }  static void -nfs_direct_good_bytes(struct nfs_direct_req *dreq, struct nfs_pgio_header *hdr) +nfs_direct_handle_truncated(struct nfs_direct_req *dreq, +			    const struct nfs_pgio_header *hdr, +			    ssize_t dreq_len)  { -	int i; -	ssize_t count; +	if (!(test_bit(NFS_IOHDR_ERROR, &hdr->flags) || +	      test_bit(NFS_IOHDR_EOF, &hdr->flags))) +		return; +	if (dreq->max_count >= dreq_len) { +		dreq->max_count = dreq_len; +		if (dreq->count > dreq_len) +			dreq->count = dreq_len; -	WARN_ON_ONCE(dreq->count >= dreq->max_count); +		if (test_bit(NFS_IOHDR_ERROR, &hdr->flags)) +			dreq->error = hdr->error; +		else /* Clear outstanding error if this is EOF */ +			dreq->error = 0; +	} +} -	if (dreq->mirror_count == 1) { -		dreq->mirrors[hdr->pgio_mirror_idx].count += hdr->good_bytes; -		dreq->count += hdr->good_bytes; -	} else { -		/* mirrored writes */ -		count = dreq->mirrors[hdr->pgio_mirror_idx].count; -		if (count + dreq->io_start < hdr->io_start + hdr->good_bytes) { -			count = hdr->io_start + hdr->good_bytes - dreq->io_start; -			dreq->mirrors[hdr->pgio_mirror_idx].count = count; -		} -		/* update the dreq->count by finding the minimum agreed count from all -		 * mirrors */ -		count = dreq->mirrors[0].count; +static void +nfs_direct_count_bytes(struct nfs_direct_req *dreq, +		       const struct nfs_pgio_header *hdr) +{ +	loff_t hdr_end = hdr->io_start + hdr->good_bytes; +	ssize_t dreq_len = 0; -		for (i = 1; i < dreq->mirror_count; i++) -			count = min(count, dreq->mirrors[i].count); +	if (hdr_end > dreq->io_start) +		dreq_len = hdr_end - dreq->io_start; -		dreq->count = count; -	} +	nfs_direct_handle_truncated(dreq, hdr, dreq_len); + +	if (dreq_len > dreq->max_count) +		dreq_len = dreq->max_count; + +	if (dreq->count < dreq_len) +		dreq->count = dreq_len;  }  /* @@ -293,18 +293,6 @@ void nfs_init_cinfo_from_dreq(struct nfs_commit_info *cinfo,  	cinfo->completion_ops = &nfs_direct_commit_completion_ops;  } -static inline void nfs_direct_setup_mirroring(struct nfs_direct_req *dreq, -					     struct nfs_pageio_descriptor *pgio, -					     struct nfs_page *req) -{ -	int mirror_count = 1; - -	if (pgio->pg_ops->pg_get_mirror_count) -		mirror_count = pgio->pg_ops->pg_get_mirror_count(pgio, req); - -	dreq->mirror_count = mirror_count; -} -  static inline struct nfs_direct_req *nfs_direct_req_alloc(void)  {  	struct nfs_direct_req *dreq; @@ -319,7 +307,6 @@ static inline struct nfs_direct_req *nfs_direct_req_alloc(void)  	INIT_LIST_HEAD(&dreq->mds_cinfo.list);  	dreq->verf.committed = NFS_INVALID_STABLE_HOW;	/* not set yet */  	INIT_WORK(&dreq->work, nfs_direct_write_schedule_work); -	dreq->mirror_count = 1;  	spin_lock_init(&dreq->lock);  	return dreq; @@ -402,20 +389,12 @@ static void nfs_direct_read_completion(struct nfs_pgio_header *hdr)  	struct nfs_direct_req *dreq = hdr->dreq;  	spin_lock(&dreq->lock); -	if (test_bit(NFS_IOHDR_ERROR, &hdr->flags)) -		dreq->error = hdr->error; -  	if (test_bit(NFS_IOHDR_REDO, &hdr->flags)) {  		spin_unlock(&dreq->lock);  		goto out_put;  	} -	if (hdr->good_bytes != 0) -		nfs_direct_good_bytes(dreq, hdr); - -	if (test_bit(NFS_IOHDR_EOF, &hdr->flags)) -		dreq->error = 0; - +	nfs_direct_count_bytes(dreq, hdr);  	spin_unlock(&dreq->lock);  	while (!list_empty(&hdr->pages)) { @@ -646,29 +625,22 @@ static void nfs_direct_write_reschedule(struct nfs_direct_req *dreq)  	LIST_HEAD(reqs);  	struct nfs_commit_info cinfo;  	LIST_HEAD(failed); -	int i;  	nfs_init_cinfo_from_dreq(&cinfo, dreq);  	nfs_direct_write_scan_commit_list(dreq->inode, &reqs, &cinfo);  	dreq->count = 0; +	dreq->max_count = 0; +	list_for_each_entry(req, &reqs, wb_list) +		dreq->max_count += req->wb_bytes;  	dreq->verf.committed = NFS_INVALID_STABLE_HOW;  	nfs_clear_pnfs_ds_commit_verifiers(&dreq->ds_cinfo); -	for (i = 0; i < dreq->mirror_count; i++) -		dreq->mirrors[i].count = 0;  	get_dreq(dreq);  	nfs_pageio_init_write(&desc, dreq->inode, FLUSH_STABLE, false,  			      &nfs_direct_write_completion_ops);  	desc.pg_dreq = dreq; -	req = nfs_list_entry(reqs.next); -	nfs_direct_setup_mirroring(dreq, &desc, req); -	if (desc.pg_error < 0) { -		list_splice_init(&reqs, &failed); -		goto out_failed; -	} -  	list_for_each_entry_safe(req, tmp, &reqs, wb_list) {  		/* Bump the transmission count */  		req->wb_nio++; @@ -686,7 +658,6 @@ static void nfs_direct_write_reschedule(struct nfs_direct_req *dreq)  	}  	nfs_pageio_complete(&desc); -out_failed:  	while (!list_empty(&failed)) {  		req = nfs_list_entry(failed.next);  		nfs_list_remove_request(req); @@ -791,17 +762,13 @@ static void nfs_direct_write_completion(struct nfs_pgio_header *hdr)  	nfs_init_cinfo_from_dreq(&cinfo, dreq);  	spin_lock(&dreq->lock); - -	if (test_bit(NFS_IOHDR_ERROR, &hdr->flags)) -		dreq->error = hdr->error; -  	if (test_bit(NFS_IOHDR_REDO, &hdr->flags)) {  		spin_unlock(&dreq->lock);  		goto out_put;  	} +	nfs_direct_count_bytes(dreq, hdr);  	if (hdr->good_bytes != 0) { -		nfs_direct_good_bytes(dreq, hdr);  		if (nfs_write_need_commit(hdr)) {  			if (dreq->flags == NFS_ODIRECT_RESCHED_WRITES)  				request_commit = true; @@ -923,7 +890,6 @@ static ssize_t nfs_direct_write_schedule_iovec(struct nfs_direct_req *dreq,  				break;  			} -			nfs_direct_setup_mirroring(dreq, &desc, req);  			if (desc.pg_error < 0) {  				nfs_free_request(req);  				result = desc.pg_error;  | 
