mirror of
https://gitee.com/bianbu-linux/linux-6.6
synced 2025-04-24 14:07:52 -04:00
netfs, cachefiles: Add a method to query presence of data in the cache
Add a netfs_cache_ops method by which a network filesystem can ask the cache about what data it has available and where so that it can make a multipage read more efficient. Signed-off-by: David Howells <dhowells@redhat.com> cc: linux-cachefs@redhat.com Acked-by: Jeff Layton <jlayton@kernel.org> Reviewed-by: Rohith Surabattula <rohiths@microsoft.com> Signed-off-by: Steve French <stfrench@microsoft.com>
This commit is contained in:
parent
052e04a52d
commit
bee9f65523
3 changed files with 82 additions and 0 deletions
|
@ -462,6 +462,10 @@ operation table looks like the following::
|
||||||
struct iov_iter *iter,
|
struct iov_iter *iter,
|
||||||
netfs_io_terminated_t term_func,
|
netfs_io_terminated_t term_func,
|
||||||
void *term_func_priv);
|
void *term_func_priv);
|
||||||
|
|
||||||
|
int (*query_occupancy)(struct netfs_cache_resources *cres,
|
||||||
|
loff_t start, size_t len, size_t granularity,
|
||||||
|
loff_t *_data_start, size_t *_data_len);
|
||||||
};
|
};
|
||||||
|
|
||||||
With a termination handler function pointer::
|
With a termination handler function pointer::
|
||||||
|
@ -536,6 +540,18 @@ The methods defined in the table are:
|
||||||
indicating whether the termination is definitely happening in the caller's
|
indicating whether the termination is definitely happening in the caller's
|
||||||
context.
|
context.
|
||||||
|
|
||||||
|
* ``query_occupancy()``
|
||||||
|
|
||||||
|
[Required] Called to find out where the next piece of data is within a
|
||||||
|
particular region of the cache. The start and length of the region to be
|
||||||
|
queried are passed in, along with the granularity to which the answer needs
|
||||||
|
to be aligned. The function passes back the start and length of the data,
|
||||||
|
if any, available within that region. Note that there may be a hole at the
|
||||||
|
front.
|
||||||
|
|
||||||
|
It returns 0 if some data was found, -ENODATA if there was no usable data
|
||||||
|
within the region or -ENOBUFS if there is no caching on this file.
|
||||||
|
|
||||||
Note that these methods are passed a pointer to the cache resource structure,
|
Note that these methods are passed a pointer to the cache resource structure,
|
||||||
not the read request structure as they could be used in other situations where
|
not the read request structure as they could be used in other situations where
|
||||||
there isn't a read request structure as well, such as writing dirty data to the
|
there isn't a read request structure as well, such as writing dirty data to the
|
||||||
|
|
|
@ -191,6 +191,64 @@ presubmission_error:
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Query the occupancy of the cache in a region, returning where the next chunk
|
||||||
|
* of data starts and how long it is.
|
||||||
|
*/
|
||||||
|
static int cachefiles_query_occupancy(struct netfs_cache_resources *cres,
|
||||||
|
loff_t start, size_t len, size_t granularity,
|
||||||
|
loff_t *_data_start, size_t *_data_len)
|
||||||
|
{
|
||||||
|
struct cachefiles_object *object;
|
||||||
|
struct file *file;
|
||||||
|
loff_t off, off2;
|
||||||
|
|
||||||
|
*_data_start = -1;
|
||||||
|
*_data_len = 0;
|
||||||
|
|
||||||
|
if (!fscache_wait_for_operation(cres, FSCACHE_WANT_READ))
|
||||||
|
return -ENOBUFS;
|
||||||
|
|
||||||
|
object = cachefiles_cres_object(cres);
|
||||||
|
file = cachefiles_cres_file(cres);
|
||||||
|
granularity = max_t(size_t, object->volume->cache->bsize, granularity);
|
||||||
|
|
||||||
|
_enter("%pD,%li,%llx,%zx/%llx",
|
||||||
|
file, file_inode(file)->i_ino, start, len,
|
||||||
|
i_size_read(file_inode(file)));
|
||||||
|
|
||||||
|
off = cachefiles_inject_read_error();
|
||||||
|
if (off == 0)
|
||||||
|
off = vfs_llseek(file, start, SEEK_DATA);
|
||||||
|
if (off == -ENXIO)
|
||||||
|
return -ENODATA; /* Beyond EOF */
|
||||||
|
if (off < 0 && off >= (loff_t)-MAX_ERRNO)
|
||||||
|
return -ENOBUFS; /* Error. */
|
||||||
|
if (round_up(off, granularity) >= start + len)
|
||||||
|
return -ENODATA; /* No data in range */
|
||||||
|
|
||||||
|
off2 = cachefiles_inject_read_error();
|
||||||
|
if (off2 == 0)
|
||||||
|
off2 = vfs_llseek(file, off, SEEK_HOLE);
|
||||||
|
if (off2 == -ENXIO)
|
||||||
|
return -ENODATA; /* Beyond EOF */
|
||||||
|
if (off2 < 0 && off2 >= (loff_t)-MAX_ERRNO)
|
||||||
|
return -ENOBUFS; /* Error. */
|
||||||
|
|
||||||
|
/* Round away partial blocks */
|
||||||
|
off = round_up(off, granularity);
|
||||||
|
off2 = round_down(off2, granularity);
|
||||||
|
if (off2 <= off)
|
||||||
|
return -ENODATA;
|
||||||
|
|
||||||
|
*_data_start = off;
|
||||||
|
if (off2 > start + len)
|
||||||
|
*_data_len = len;
|
||||||
|
else
|
||||||
|
*_data_len = off2 - off;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Handle completion of a write to the cache.
|
* Handle completion of a write to the cache.
|
||||||
*/
|
*/
|
||||||
|
@ -545,6 +603,7 @@ static const struct netfs_cache_ops cachefiles_netfs_cache_ops = {
|
||||||
.write = cachefiles_write,
|
.write = cachefiles_write,
|
||||||
.prepare_read = cachefiles_prepare_read,
|
.prepare_read = cachefiles_prepare_read,
|
||||||
.prepare_write = cachefiles_prepare_write,
|
.prepare_write = cachefiles_prepare_write,
|
||||||
|
.query_occupancy = cachefiles_query_occupancy,
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -244,6 +244,13 @@ struct netfs_cache_ops {
|
||||||
int (*prepare_write)(struct netfs_cache_resources *cres,
|
int (*prepare_write)(struct netfs_cache_resources *cres,
|
||||||
loff_t *_start, size_t *_len, loff_t i_size,
|
loff_t *_start, size_t *_len, loff_t i_size,
|
||||||
bool no_space_allocated_yet);
|
bool no_space_allocated_yet);
|
||||||
|
|
||||||
|
/* Query the occupancy of the cache in a region, returning where the
|
||||||
|
* next chunk of data starts and how long it is.
|
||||||
|
*/
|
||||||
|
int (*query_occupancy)(struct netfs_cache_resources *cres,
|
||||||
|
loff_t start, size_t len, size_t granularity,
|
||||||
|
loff_t *_data_start, size_t *_data_len);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct readahead_control;
|
struct readahead_control;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue