linux/include/linux/netfs.h
<<
>>
Prefs
   1/* SPDX-License-Identifier: GPL-2.0-or-later */
   2/* Network filesystem support services.
   3 *
   4 * Copyright (C) 2021 Red Hat, Inc. All Rights Reserved.
   5 * Written by David Howells (dhowells@redhat.com)
   6 *
   7 * See:
   8 *
   9 *      Documentation/filesystems/netfs_library.rst
  10 *
  11 * for a description of the network filesystem interface declared here.
  12 */
  13
  14#ifndef _LINUX_NETFS_H
  15#define _LINUX_NETFS_H
  16
  17#include <linux/workqueue.h>
  18#include <linux/fs.h>
  19#include <linux/pagemap.h>
  20
  21/*
  22 * Overload PG_private_2 to give us PG_fscache - this is used to indicate that
  23 * a page is currently backed by a local disk cache
  24 */
  25#define PageFsCache(page)               PagePrivate2((page))
  26#define SetPageFsCache(page)            SetPagePrivate2((page))
  27#define ClearPageFsCache(page)          ClearPagePrivate2((page))
  28#define TestSetPageFsCache(page)        TestSetPagePrivate2((page))
  29#define TestClearPageFsCache(page)      TestClearPagePrivate2((page))
  30
  31/**
  32 * set_page_fscache - Set PG_fscache on a page and take a ref
  33 * @page: The page.
  34 *
  35 * Set the PG_fscache (PG_private_2) flag on a page and take the reference
  36 * needed for the VM to handle its lifetime correctly.  This sets the flag and
  37 * takes the reference unconditionally, so care must be taken not to set the
  38 * flag again if it's already set.
  39 */
  40static inline void set_page_fscache(struct page *page)
  41{
  42        set_page_private_2(page);
  43}
  44
  45/**
  46 * end_page_fscache - Clear PG_fscache and release any waiters
  47 * @page: The page
  48 *
  49 * Clear the PG_fscache (PG_private_2) bit on a page and wake up any sleepers
  50 * waiting for this.  The page ref held for PG_private_2 being set is released.
  51 *
  52 * This is, for example, used when a netfs page is being written to a local
  53 * disk cache, thereby allowing writes to the cache for the same page to be
  54 * serialised.
  55 */
  56static inline void end_page_fscache(struct page *page)
  57{
  58        end_page_private_2(page);
  59}
  60
  61/**
  62 * wait_on_page_fscache - Wait for PG_fscache to be cleared on a page
  63 * @page: The page to wait on
  64 *
  65 * Wait for PG_fscache (aka PG_private_2) to be cleared on a page.
  66 */
  67static inline void wait_on_page_fscache(struct page *page)
  68{
  69        wait_on_page_private_2(page);
  70}
  71
  72/**
  73 * wait_on_page_fscache_killable - Wait for PG_fscache to be cleared on a page
  74 * @page: The page to wait on
  75 *
  76 * Wait for PG_fscache (aka PG_private_2) to be cleared on a page or until a
  77 * fatal signal is received by the calling task.
  78 *
  79 * Return:
  80 * - 0 if successful.
  81 * - -EINTR if a fatal signal was encountered.
  82 */
  83static inline int wait_on_page_fscache_killable(struct page *page)
  84{
  85        return wait_on_page_private_2_killable(page);
  86}
  87
  88enum netfs_read_source {
  89        NETFS_FILL_WITH_ZEROES,
  90        NETFS_DOWNLOAD_FROM_SERVER,
  91        NETFS_READ_FROM_CACHE,
  92        NETFS_INVALID_READ,
  93} __mode(byte);
  94
  95typedef void (*netfs_io_terminated_t)(void *priv, ssize_t transferred_or_error,
  96                                      bool was_async);
  97
  98/*
  99 * Resources required to do operations on a cache.
 100 */
 101struct netfs_cache_resources {
 102        const struct netfs_cache_ops    *ops;
 103        void                            *cache_priv;
 104        void                            *cache_priv2;
 105        unsigned int                    debug_id;       /* Cookie debug ID */
 106};
 107
 108/*
 109 * Descriptor for a single component subrequest.
 110 */
 111struct netfs_read_subrequest {
 112        struct netfs_read_request *rreq;        /* Supervising read request */
 113        struct list_head        rreq_link;      /* Link in rreq->subrequests */
 114        loff_t                  start;          /* Where to start the I/O */
 115        size_t                  len;            /* Size of the I/O */
 116        size_t                  transferred;    /* Amount of data transferred */
 117        refcount_t              usage;
 118        short                   error;          /* 0 or error that occurred */
 119        unsigned short          debug_index;    /* Index in list (for debugging output) */
 120        enum netfs_read_source  source;         /* Where to read from */
 121        unsigned long           flags;
 122#define NETFS_SREQ_WRITE_TO_CACHE       0       /* Set if should write to cache */
 123#define NETFS_SREQ_CLEAR_TAIL           1       /* Set if the rest of the read should be cleared */
 124#define NETFS_SREQ_SHORT_READ           2       /* Set if there was a short read from the cache */
 125#define NETFS_SREQ_SEEK_DATA_READ       3       /* Set if ->read() should SEEK_DATA first */
 126#define NETFS_SREQ_NO_PROGRESS          4       /* Set if we didn't manage to read any data */
 127};
 128
 129/*
 130 * Descriptor for a read helper request.  This is used to make multiple I/O
 131 * requests on a variety of sources and then stitch the result together.
 132 */
 133struct netfs_read_request {
 134        struct work_struct      work;
 135        struct inode            *inode;         /* The file being accessed */
 136        struct address_space    *mapping;       /* The mapping being accessed */
 137        struct netfs_cache_resources cache_resources;
 138        struct list_head        subrequests;    /* Requests to fetch I/O from disk or net */
 139        void                    *netfs_priv;    /* Private data for the netfs */
 140        unsigned int            debug_id;
 141        atomic_t                nr_rd_ops;      /* Number of read ops in progress */
 142        atomic_t                nr_wr_ops;      /* Number of write ops in progress */
 143        size_t                  submitted;      /* Amount submitted for I/O so far */
 144        size_t                  len;            /* Length of the request */
 145        short                   error;          /* 0 or error that occurred */
 146        loff_t                  i_size;         /* Size of the file */
 147        loff_t                  start;          /* Start position */
 148        pgoff_t                 no_unlock_page; /* Don't unlock this page after read */
 149        refcount_t              usage;
 150        unsigned long           flags;
 151#define NETFS_RREQ_INCOMPLETE_IO        0       /* Some ioreqs terminated short or with error */
 152#define NETFS_RREQ_WRITE_TO_CACHE       1       /* Need to write to the cache */
 153#define NETFS_RREQ_NO_UNLOCK_PAGE       2       /* Don't unlock no_unlock_page on completion */
 154#define NETFS_RREQ_DONT_UNLOCK_PAGES    3       /* Don't unlock the pages on completion */
 155#define NETFS_RREQ_FAILED               4       /* The request failed */
 156#define NETFS_RREQ_IN_PROGRESS          5       /* Unlocked when the request completes */
 157        const struct netfs_read_request_ops *netfs_ops;
 158};
 159
 160/*
 161 * Operations the network filesystem can/must provide to the helpers.
 162 */
 163struct netfs_read_request_ops {
 164        bool (*is_cache_enabled)(struct inode *inode);
 165        void (*init_rreq)(struct netfs_read_request *rreq, struct file *file);
 166        int (*begin_cache_operation)(struct netfs_read_request *rreq);
 167        void (*expand_readahead)(struct netfs_read_request *rreq);
 168        bool (*clamp_length)(struct netfs_read_subrequest *subreq);
 169        void (*issue_op)(struct netfs_read_subrequest *subreq);
 170        bool (*is_still_valid)(struct netfs_read_request *rreq);
 171        int (*check_write_begin)(struct file *file, loff_t pos, unsigned len,
 172                                 struct page *page, void **_fsdata);
 173        void (*done)(struct netfs_read_request *rreq);
 174        void (*cleanup)(struct address_space *mapping, void *netfs_priv);
 175};
 176
 177/*
 178 * Table of operations for access to a cache.  This is obtained by
 179 * rreq->ops->begin_cache_operation().
 180 */
 181struct netfs_cache_ops {
 182        /* End an operation */
 183        void (*end_operation)(struct netfs_cache_resources *cres);
 184
 185        /* Read data from the cache */
 186        int (*read)(struct netfs_cache_resources *cres,
 187                    loff_t start_pos,
 188                    struct iov_iter *iter,
 189                    bool seek_data,
 190                    netfs_io_terminated_t term_func,
 191                    void *term_func_priv);
 192
 193        /* Write data to the cache */
 194        int (*write)(struct netfs_cache_resources *cres,
 195                     loff_t start_pos,
 196                     struct iov_iter *iter,
 197                     netfs_io_terminated_t term_func,
 198                     void *term_func_priv);
 199
 200        /* Expand readahead request */
 201        void (*expand_readahead)(struct netfs_cache_resources *cres,
 202                                 loff_t *_start, size_t *_len, loff_t i_size);
 203
 204        /* Prepare a read operation, shortening it to a cached/uncached
 205         * boundary as appropriate.
 206         */
 207        enum netfs_read_source (*prepare_read)(struct netfs_read_subrequest *subreq,
 208                                               loff_t i_size);
 209
 210        /* Prepare a write operation, working out what part of the write we can
 211         * actually do.
 212         */
 213        int (*prepare_write)(struct netfs_cache_resources *cres,
 214                             loff_t *_start, size_t *_len, loff_t i_size);
 215};
 216
 217struct readahead_control;
 218extern void netfs_readahead(struct readahead_control *,
 219                            const struct netfs_read_request_ops *,
 220                            void *);
 221extern int netfs_readpage(struct file *,
 222                          struct page *,
 223                          const struct netfs_read_request_ops *,
 224                          void *);
 225extern int netfs_write_begin(struct file *, struct address_space *,
 226                             loff_t, unsigned int, unsigned int, struct page **,
 227                             void **,
 228                             const struct netfs_read_request_ops *,
 229                             void *);
 230
 231extern void netfs_subreq_terminated(struct netfs_read_subrequest *, ssize_t, bool);
 232extern void netfs_stats_show(struct seq_file *);
 233
 234#endif /* _LINUX_NETFS_H */
 235