Change the request initialisation function to return an error code so that the network filesystem can return a failure (ENOMEM, for example). This will also allow ceph to abort a ->readahead() op if the server refuses to give it a cap allowing local caching from within the netfslib framework (errors aren't passed back through ->readahead(), so returning, say, -ENOBUFS will cause the op to be aborted). Signed-off-by: David Howells <dhowells@redhat.com> Reviewed-by: Jeff Layton <jlayton@kernel.org> cc: linux-cachefs@redhat.com
Unified · Split
| @@ -56,12 +56,13 @@ static void v9fs_issue_read(struct netfs_io_subrequest *subreq) · 55 unmodified lines | ||
| 56 | 56 | * @rreq: The read request |
| 57 | 57 | * @file: The file being read from |
| 58 | 58 | */ |
| 59 | −static void v9fs_init_request(struct netfs_io_request *rreq, struct file *file) | |
| 59 | +static int v9fs_init_request(struct netfs_io_request *rreq, struct file *file) | |
| 60 | 60 | { |
| 61 | 61 | struct p9_fid *fid = file->private_data; |
| 62 | 62 | |
| 63 | 63 | refcount_inc(&fid->count); |
| 64 | 64 | rreq->netfs_priv = fid; |
| 65 | + return 0; | |
| 65 | 66 | } |
| 66 | 67 | |
| 67 | 68 | /** |
| @@ -359,9 +359,10 @@ static int afs_symlink_readpage(struct file *file, struct page *page) · 358 unmodified lines | ||
| 359 | 359 | return ret; |
| 360 | 360 | } |
| 361 | 361 | |
| 362 | −static void afs_init_request(struct netfs_io_request *rreq, struct file *file) | |
| 362 | +static int afs_init_request(struct netfs_io_request *rreq, struct file *file) | |
| 363 | 363 | { |
| 364 | 364 | rreq->netfs_priv = key_get(afs_file_key(file)); |
| 365 | + return 0; | |
| 365 | 366 | } |
| 366 | 367 | |
| 367 | 368 | static bool afs_is_cache_enabled(struct inode *inode) |
| @@ -20,27 +20,34 @@ struct netfs_io_request *netfs_alloc_request(struct address_space *mapping, · 19 unmodified lines | ||
| 20 | 20 | { |
| 21 | 21 | static atomic_t debug_ids; |
| 22 | 22 | struct netfs_io_request *rreq; |
| 23 | + int ret; | |
| 23 | 24 | |
| 24 | 25 | rreq = kzalloc(sizeof(struct netfs_io_request), GFP_KERNEL); |
| 25 | − if (rreq) { | |
| 26 | − rreq->start = start; | |
| 27 | − rreq->len = len; | |
| 28 | − rreq->origin = origin; | |
| 29 | − rreq->netfs_ops = ops; | |
| 30 | − rreq->netfs_priv = netfs_priv; | |
| 31 | − rreq->mapping = mapping; | |
| 32 | − rreq->inode = file_inode(file); | |
| 33 | − rreq->i_size = i_size_read(rreq->inode); | |
| 34 | − rreq->debug_id = atomic_inc_return(&debug_ids); | |
| 35 | − INIT_LIST_HEAD(&rreq->subrequests); | |
| 36 | − INIT_WORK(&rreq->work, netfs_rreq_work); | |
| 37 | − refcount_set(&rreq->ref, 1); | |
| 38 | − __set_bit(NETFS_RREQ_IN_PROGRESS, &rreq->flags); | |
| 39 | − if (ops->init_request) | |
| 40 | − ops->init_request(rreq, file); | |
| 41 | − netfs_stat(&netfs_n_rh_rreq); | |
| 26 | + if (!rreq) | |
| 27 | + return ERR_PTR(-ENOMEM); | |
| 28 | + | |
| 29 | + rreq->start = start; | |
| 30 | + rreq->len = len; | |
| 31 | + rreq->origin = origin; | |
| 32 | + rreq->netfs_ops = ops; | |
| 33 | + rreq->netfs_priv = netfs_priv; | |
| 34 | + rreq->mapping = mapping; | |
| 35 | + rreq->inode = file_inode(file); | |
| 36 | + rreq->i_size = i_size_read(rreq->inode); | |
| 37 | + rreq->debug_id = atomic_inc_return(&debug_ids); | |
| 38 | + INIT_LIST_HEAD(&rreq->subrequests); | |
| 39 | + INIT_WORK(&rreq->work, netfs_rreq_work); | |
| 40 | + refcount_set(&rreq->ref, 1); | |
| 41 | + __set_bit(NETFS_RREQ_IN_PROGRESS, &rreq->flags); | |
| 42 | + if (rreq->netfs_ops->init_request) { | |
| 43 | + ret = rreq->netfs_ops->init_request(rreq, file); | |
| 44 | + if (ret < 0) { | |
| 45 | + kfree(rreq); | |
| 46 | + return ERR_PTR(ret); | |
| 47 | + } | |
| 42 | 48 | } |
| 43 | 49 | |
| 50 | + netfs_stat(&netfs_n_rh_rreq); | |
| 44 | 51 | return rreq; |
| 45 | 52 | } |
| 46 | 53 | |
| @@ -768,7 +768,7 @@ void netfs_readahead(struct readahead_control *ractl, · 767 unmodified lines | ||
| 768 | 768 | readahead_pos(ractl), |
| 769 | 769 | readahead_length(ractl), |
| 770 | 770 | NETFS_READAHEAD); |
| 771 | − if (!rreq) | |
| 771 | + if (IS_ERR(rreq)) | |
| 772 | 772 | goto cleanup; |
| 773 | 773 | |
| 774 | 774 | if (ops->begin_cache_operation) { |
| @@ -842,11 +842,9 @@ int netfs_readpage(struct file *file, · 67 unmodified lines | ||
| 842 | 842 | rreq = netfs_alloc_request(folio->mapping, file, ops, netfs_priv, |
| 843 | 843 | folio_file_pos(folio), folio_size(folio), |
| 844 | 844 | NETFS_READPAGE); |
| 845 | − if (!rreq) { | |
| 846 | − if (netfs_priv) | |
| 847 | − ops->cleanup(folio_file_mapping(folio), netfs_priv); | |
| 848 | − folio_unlock(folio); | |
| 849 | − return -ENOMEM; | |
| 845 | + if (IS_ERR(rreq)) { | |
| 846 | + ret = PTR_ERR(rreq); | |
| 847 | + goto alloc_error; | |
| 850 | 848 | } |
| 851 | 849 | |
| 852 | 850 | if (ops->begin_cache_operation) { |
| @@ -887,6 +885,11 @@ int netfs_readpage(struct file *file, · 34 unmodified lines | ||
| 887 | 885 | out: |
| 888 | 886 | netfs_put_request(rreq, false, netfs_rreq_trace_put_hold); |
| 889 | 887 | return ret; |
| 888 | +alloc_error: | |
| 889 | + if (netfs_priv) | |
| 890 | + ops->cleanup(folio_file_mapping(folio), netfs_priv); | |
| 891 | + folio_unlock(folio); | |
| 892 | + return ret; | |
| 890 | 893 | } |
| 891 | 894 | EXPORT_SYMBOL(netfs_readpage); |
| 892 | 895 | |
| @@ -1007,12 +1010,13 @@ retry: · 114 unmodified lines | ||
| 1007 | 1010 | goto have_folio_no_wait; |
| 1008 | 1011 | } |
| 1009 | 1012 | |
| 1010 | − ret = -ENOMEM; | |
| 1011 | 1013 | rreq = netfs_alloc_request(mapping, file, ops, netfs_priv, |
| 1012 | 1014 | folio_file_pos(folio), folio_size(folio), |
| 1013 | 1015 | NETFS_READ_FOR_WRITE); |
| 1014 | − if (!rreq) | |
| 1016 | + if (IS_ERR(rreq)) { | |
| 1017 | + ret = PTR_ERR(rreq); | |
| 1015 | 1018 | goto error; |
| 1019 | + } | |
| 1016 | 1020 | rreq->no_unlock_folio = folio_index(folio); |
| 1017 | 1021 | __set_bit(NETFS_RREQ_NO_UNLOCK_FOLIO, &rreq->flags); |
| 1018 | 1022 | netfs_priv = NULL; |
| @@ -193,7 +193,7 @@ struct netfs_io_request { · 192 unmodified lines | ||
| 193 | 193 | */ |
| 194 | 194 | struct netfs_request_ops { |
| 195 | 195 | bool (*is_cache_enabled)(struct inode *inode); |
| 196 | − void (*init_request)(struct netfs_io_request *rreq, struct file *file); | |
| 196 | + int (*init_request)(struct netfs_io_request *rreq, struct file *file); | |
| 197 | 197 | int (*begin_cache_operation)(struct netfs_io_request *rreq); |
| 198 | 198 | void (*expand_readahead)(struct netfs_io_request *rreq); |
| 199 | 199 | bool (*clamp_length)(struct netfs_io_subrequest *subreq); |