Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

netfs: Change ->init_request() to return an error code

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

Link: https://lore.kernel.org/r/164678212401.1200972.16537041523832944934.stgit@warthog.procyon.org.uk/ # v2
Link: https://lore.kernel.org/r/164692905398.2099075.5238033621684646524.stgit@warthog.procyon.org.uk/ # v3

+41 -28
+2 -1
fs/9p/vfs_addr.c
··· 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 /**
+2 -1
fs/afs/file.c
··· 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)
+24 -17
fs/netfs/objects.c
··· 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
+12 -8
fs/netfs/read_helper.c
··· 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 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) { ··· 884 886 } 885 887 out: 886 888 netfs_put_request(rreq, false, netfs_rreq_trace_put_hold); 889 + return ret; 890 + alloc_error: 891 + if (netfs_priv) 892 + ops->cleanup(folio_file_mapping(folio), netfs_priv); 893 + folio_unlock(folio); 887 894 return ret; 888 895 } 889 896 EXPORT_SYMBOL(netfs_readpage); ··· 1010 1007 goto have_folio_no_wait; 1011 1008 } 1012 1009 1013 - ret = -ENOMEM; 1014 1010 rreq = netfs_alloc_request(mapping, file, ops, netfs_priv, 1015 1011 folio_file_pos(folio), folio_size(folio), 1016 1012 NETFS_READ_FOR_WRITE); 1017 - if (!rreq) 1013 + if (IS_ERR(rreq)) { 1014 + ret = PTR_ERR(rreq); 1018 1015 goto error; 1016 + } 1019 1017 rreq->no_unlock_folio = folio_index(folio); 1020 1018 __set_bit(NETFS_RREQ_NO_UNLOCK_FOLIO, &rreq->flags); 1021 1019 netfs_priv = NULL;
+1 -1
include/linux/netfs.h
··· 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);