ceph: add a dedicated private data for netfs rreq
authorXiubo Li <xiubli@redhat.com>
Wed, 10 May 2023 11:55:46 +0000 (19:55 +0800)
committerIlya Dryomov <idryomov@gmail.com>
Fri, 30 Jun 2023 10:08:55 +0000 (12:08 +0200)
We need to save the 'f_ra.ra_pages' to expand the readahead window
later.

Cc: stable@vger.kernel.org
Fixes: 49870056005c ("ceph: convert ceph_readpages to ceph_readahead")
Link: https://lore.kernel.org/ceph-devel/20230504082510.247-1-sehuww@mail.scut.edu.cn
Link: https://www.spinics.net/lists/ceph-users/msg76183.html
Signed-off-by: Xiubo Li <xiubli@redhat.com>
Reviewed-and-tested-by: Hu Weiwen <sehuww@mail.scut.edu.cn>
Reviewed-by: Milind Changire <mchangir@redhat.com>
Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
fs/ceph/addr.c
fs/ceph/super.h

index 6bb251a..19c4f08 100644 (file)
@@ -362,18 +362,28 @@ static int ceph_init_request(struct netfs_io_request *rreq, struct file *file)
 {
        struct inode *inode = rreq->inode;
        int got = 0, want = CEPH_CAP_FILE_CACHE;
+       struct ceph_netfs_request_data *priv;
        int ret = 0;
 
        if (rreq->origin != NETFS_READAHEAD)
                return 0;
 
+       priv = kzalloc(sizeof(*priv), GFP_NOFS);
+       if (!priv)
+               return -ENOMEM;
+
        if (file) {
                struct ceph_rw_context *rw_ctx;
                struct ceph_file_info *fi = file->private_data;
 
+               priv->file_ra_pages = file->f_ra.ra_pages;
+               priv->file_ra_disabled = file->f_mode & FMODE_RANDOM;
+
                rw_ctx = ceph_find_rw_context(fi);
-               if (rw_ctx)
+               if (rw_ctx) {
+                       rreq->netfs_priv = priv;
                        return 0;
+               }
        }
 
        /*
@@ -383,27 +393,40 @@ static int ceph_init_request(struct netfs_io_request *rreq, struct file *file)
        ret = ceph_try_get_caps(inode, CEPH_CAP_FILE_RD, want, true, &got);
        if (ret < 0) {
                dout("start_read %p, error getting cap\n", inode);
-               return ret;
+               goto out;
        }
 
        if (!(got & want)) {
                dout("start_read %p, no cache cap\n", inode);
-               return -EACCES;
+               ret = -EACCES;
+               goto out;
+       }
+       if (ret == 0) {
+               ret = -EACCES;
+               goto out;
        }
-       if (ret == 0)
-               return -EACCES;
 
-       rreq->netfs_priv = (void *)(uintptr_t)got;
-       return 0;
+       priv->caps = got;
+       rreq->netfs_priv = priv;
+
+out:
+       if (ret < 0)
+               kfree(priv);
+
+       return ret;
 }
 
 static void ceph_netfs_free_request(struct netfs_io_request *rreq)
 {
-       struct ceph_inode_info *ci = ceph_inode(rreq->inode);
-       int got = (uintptr_t)rreq->netfs_priv;
+       struct ceph_netfs_request_data *priv = rreq->netfs_priv;
+
+       if (!priv)
+               return;
 
-       if (got)
-               ceph_put_cap_refs(ci, got);
+       if (priv->caps)
+               ceph_put_cap_refs(ceph_inode(rreq->inode), priv->caps);
+       kfree(priv);
+       rreq->netfs_priv = NULL;
 }
 
 const struct netfs_request_ops ceph_netfs_ops = {
index d24bf0d..3bfddf3 100644 (file)
@@ -451,6 +451,19 @@ struct ceph_inode_info {
        unsigned long  i_work_mask;
 };
 
+struct ceph_netfs_request_data {
+       int caps;
+
+       /*
+        * Maximum size of a file readahead request.
+        * The fadvise could update the bdi's default ra_pages.
+        */
+       unsigned int file_ra_pages;
+
+       /* Set it if fadvise disables file readahead entirely */
+       bool file_ra_disabled;
+};
+
 static inline struct ceph_inode_info *
 ceph_inode(const struct inode *inode)
 {