diff options
Diffstat (limited to 'fs/netfs')
| -rw-r--r-- | fs/netfs/buffered_read.c | 17 | 
1 files changed, 10 insertions, 7 deletions
| diff --git a/fs/netfs/buffered_read.c b/fs/netfs/buffered_read.c index 42f892c5712e..0ce535852151 100644 --- a/fs/netfs/buffered_read.c +++ b/fs/netfs/buffered_read.c @@ -319,8 +319,9 @@ zero_out:   * conflicting writes once the folio is grabbed and locked.  It is passed a   * pointer to the fsdata cookie that gets returned to the VM to be passed to   * write_end.  It is permitted to sleep.  It should return 0 if the request - * should go ahead; unlock the folio and return -EAGAIN to cause the folio to - * be regot; or return an error. + * should go ahead or it may return an error.  It may also unlock and put the + * folio, provided it sets ``*foliop`` to NULL, in which case a return of 0 + * will cause the folio to be re-got and the process to be retried.   *   * The calling netfs must initialise a netfs context contiguous to the vfs   * inode before calling this. @@ -348,13 +349,13 @@ retry:  	if (ctx->ops->check_write_begin) {  		/* Allow the netfs (eg. ceph) to flush conflicts. */ -		ret = ctx->ops->check_write_begin(file, pos, len, folio, _fsdata); +		ret = ctx->ops->check_write_begin(file, pos, len, &folio, _fsdata);  		if (ret < 0) {  			trace_netfs_failure(NULL, NULL, ret, netfs_fail_check_write_begin); -			if (ret == -EAGAIN) -				goto retry;  			goto error;  		} +		if (!folio) +			goto retry;  	}  	if (folio_test_uptodate(folio)) @@ -416,8 +417,10 @@ have_folio_no_wait:  error_put:  	netfs_put_request(rreq, false, netfs_rreq_trace_put_failed);  error: -	folio_unlock(folio); -	folio_put(folio); +	if (folio) { +		folio_unlock(folio); +		folio_put(folio); +	}  	_leave(" = %d", ret);  	return ret;  } |