Skip to content

Commit

Permalink
netfs: Change ->init_request() to return an error code
Browse files Browse the repository at this point in the history
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
  • Loading branch information
dhowells committed Mar 9, 2022
1 parent 5186d2f commit 44dadcd
Show file tree
Hide file tree
Showing 5 changed files with 41 additions and 28 deletions.
3 changes: 2 additions & 1 deletion fs/9p/vfs_addr.c
Original file line number Diff line number Diff line change
Expand Up @@ -56,12 +56,13 @@ static void v9fs_issue_read(struct netfs_io_subrequest *subreq)
* @rreq: The read request
* @file: The file being read from
*/
static void v9fs_init_request(struct netfs_io_request *rreq, struct file *file)
static int v9fs_init_request(struct netfs_io_request *rreq, struct file *file)
{
struct p9_fid *fid = file->private_data;

refcount_inc(&fid->count);
rreq->netfs_priv = fid;
return 0;
}

/**
Expand Down
3 changes: 2 additions & 1 deletion fs/afs/file.c
Original file line number Diff line number Diff line change
Expand Up @@ -359,9 +359,10 @@ static int afs_symlink_readpage(struct file *file, struct page *page)
return ret;
}

static void afs_init_request(struct netfs_io_request *rreq, struct file *file)
static int afs_init_request(struct netfs_io_request *rreq, struct file *file)
{
rreq->netfs_priv = key_get(afs_file_key(file));
return 0;
}

static bool afs_is_cache_enabled(struct inode *inode)
Expand Down
41 changes: 24 additions & 17 deletions fs/netfs/objects.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,27 +20,34 @@ struct netfs_io_request *netfs_alloc_request(struct address_space *mapping,
{
static atomic_t debug_ids;
struct netfs_io_request *rreq;
int ret;

rreq = kzalloc(sizeof(struct netfs_io_request), GFP_KERNEL);
if (rreq) {
rreq->start = start;
rreq->len = len;
rreq->origin = origin;
rreq->netfs_ops = ops;
rreq->netfs_priv = netfs_priv;
rreq->mapping = mapping;
rreq->inode = file_inode(file);
rreq->i_size = i_size_read(rreq->inode);
rreq->debug_id = atomic_inc_return(&debug_ids);
INIT_LIST_HEAD(&rreq->subrequests);
INIT_WORK(&rreq->work, netfs_rreq_work);
refcount_set(&rreq->ref, 1);
__set_bit(NETFS_RREQ_IN_PROGRESS, &rreq->flags);
if (ops->init_request)
ops->init_request(rreq, file);
netfs_stat(&netfs_n_rh_rreq);
if (!rreq)
return ERR_PTR(-ENOMEM);

rreq->start = start;
rreq->len = len;
rreq->origin = origin;
rreq->netfs_ops = ops;
rreq->netfs_priv = netfs_priv;
rreq->mapping = mapping;
rreq->inode = file_inode(file);
rreq->i_size = i_size_read(rreq->inode);
rreq->debug_id = atomic_inc_return(&debug_ids);
INIT_LIST_HEAD(&rreq->subrequests);
INIT_WORK(&rreq->work, netfs_rreq_work);
refcount_set(&rreq->ref, 1);
__set_bit(NETFS_RREQ_IN_PROGRESS, &rreq->flags);
if (rreq->netfs_ops->init_request) {
ret = rreq->netfs_ops->init_request(rreq, file);
if (ret < 0) {
kfree(rreq);
return ERR_PTR(ret);
}
}

netfs_stat(&netfs_n_rh_rreq);
return rreq;
}

Expand Down
20 changes: 12 additions & 8 deletions fs/netfs/read_helper.c
Original file line number Diff line number Diff line change
Expand Up @@ -768,7 +768,7 @@ void netfs_readahead(struct readahead_control *ractl,
readahead_pos(ractl),
readahead_length(ractl),
NETFS_READAHEAD);
if (!rreq)
if (IS_ERR(rreq))
goto cleanup;

if (ops->begin_cache_operation) {
Expand Down Expand Up @@ -842,11 +842,9 @@ int netfs_readpage(struct file *file,
rreq = netfs_alloc_request(folio->mapping, file, ops, netfs_priv,
folio_file_pos(folio), folio_size(folio),
NETFS_READPAGE);
if (!rreq) {
if (netfs_priv)
ops->cleanup(folio_file_mapping(folio), netfs_priv);
folio_unlock(folio);
return -ENOMEM;
if (IS_ERR(rreq)) {
ret = PTR_ERR(rreq);
goto alloc_error;
}

if (ops->begin_cache_operation) {
Expand Down Expand Up @@ -887,6 +885,11 @@ int netfs_readpage(struct file *file,
out:
netfs_put_request(rreq, false, netfs_rreq_trace_put_hold);
return ret;
alloc_error:
if (netfs_priv)
ops->cleanup(folio_file_mapping(folio), netfs_priv);
folio_unlock(folio);
return ret;
}
EXPORT_SYMBOL(netfs_readpage);

Expand Down Expand Up @@ -1007,12 +1010,13 @@ int netfs_write_begin(struct file *file, struct address_space *mapping,
goto have_folio_no_wait;
}

ret = -ENOMEM;
rreq = netfs_alloc_request(mapping, file, ops, netfs_priv,
folio_file_pos(folio), folio_size(folio),
NETFS_READ_FOR_WRITE);
if (!rreq)
if (IS_ERR(rreq)) {
ret = PTR_ERR(rreq);
goto error;
}
rreq->no_unlock_folio = folio_index(folio);
__set_bit(NETFS_RREQ_NO_UNLOCK_FOLIO, &rreq->flags);
netfs_priv = NULL;
Expand Down
2 changes: 1 addition & 1 deletion include/linux/netfs.h
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@ struct netfs_io_request {
*/
struct netfs_request_ops {
bool (*is_cache_enabled)(struct inode *inode);
void (*init_request)(struct netfs_io_request *rreq, struct file *file);
int (*init_request)(struct netfs_io_request *rreq, struct file *file);
int (*begin_cache_operation)(struct netfs_io_request *rreq);
void (*expand_readahead)(struct netfs_io_request *rreq);
bool (*clamp_length)(struct netfs_io_subrequest *subreq);
Expand Down

0 comments on commit 44dadcd

Please sign in to comment.