]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
smb3: add rasize mount parameter to improve readahead performance
authorSteve French <stfrench@microsoft.com>
Sun, 25 Apr 2021 02:46:23 +0000 (21:46 -0500)
committerSteve French <stfrench@microsoft.com>
Mon, 26 Apr 2021 04:59:08 +0000 (23:59 -0500)
In some cases readahead of more than the read size can help
(to allow parallel i/o of read ahead which can improve performance).

Ceph introduced a mount parameter "rasize" to allow controlling this.
Add mount parameter "rasize" to allow control of amount of readahead
requested of the server. If rasize not set, rasize defaults to
negotiated rsize as before.

Reviewed-by: Shyam Prasad N <sprasad@microsoft.com>
Signed-off-by: Steve French <stfrench@microsoft.com>
fs/cifs/cifsfs.c
fs/cifs/fs_context.c
fs/cifs/fs_context.h

index 39f4889a036bccdf11468d96194c82112a442ec0..5f2c139143a74f48d50eb1fb11ec201720a15964 100644 (file)
@@ -217,8 +217,11 @@ cifs_read_super(struct super_block *sb)
        rc = super_setup_bdi(sb);
        if (rc)
                goto out_no_root;
-       /* tune readahead according to rsize */
-       sb->s_bdi->ra_pages = cifs_sb->ctx->rsize / PAGE_SIZE;
+       /* tune readahead according to rsize if readahead size not set on mount */
+       if (cifs_sb->ctx->rasize)
+               sb->s_bdi->ra_pages = cifs_sb->ctx->rasize / PAGE_SIZE;
+       else
+               sb->s_bdi->ra_pages = cifs_sb->ctx->rsize / PAGE_SIZE;
 
        sb->s_blocksize = CIFS_MAX_MSGSIZE;
        sb->s_blocksize_bits = 14;      /* default 2**14 = CIFS_MAX_MSGSIZE */
@@ -649,6 +652,8 @@ cifs_show_options(struct seq_file *s, struct dentry *root)
        seq_printf(s, ",rsize=%u", cifs_sb->ctx->rsize);
        seq_printf(s, ",wsize=%u", cifs_sb->ctx->wsize);
        seq_printf(s, ",bsize=%u", cifs_sb->ctx->bsize);
+       if (cifs_sb->ctx->rasize)
+               seq_printf(s, ",rasize=%u", cifs_sb->ctx->rasize);
        if (tcon->ses->server->min_offload)
                seq_printf(s, ",esize=%u", tcon->ses->server->min_offload);
        seq_printf(s, ",echo_interval=%lu",
index 74758e954035b346c4ed641910a9d8ab2a882981..3e0d016849e302d2060c749cbbedadab6875f5e9 100644 (file)
@@ -137,6 +137,7 @@ const struct fs_parameter_spec smb3_fs_parameters[] = {
        fsparam_u32("min_enc_offload", Opt_min_enc_offload),
        fsparam_u32("esize", Opt_min_enc_offload),
        fsparam_u32("bsize", Opt_blocksize),
+       fsparam_u32("rasize", Opt_rasize),
        fsparam_u32("rsize", Opt_rsize),
        fsparam_u32("wsize", Opt_wsize),
        fsparam_u32("actimeo", Opt_actimeo),
@@ -941,6 +942,26 @@ static int smb3_fs_context_parse_param(struct fs_context *fc,
                ctx->bsize = result.uint_32;
                ctx->got_bsize = true;
                break;
+       case Opt_rasize:
+               /*
+                * readahead size realistically should never need to be
+                * less than 1M (CIFS_DEFAULT_IOSIZE) or greater than 32M
+                * (perhaps an exception should be considered in the
+                * for the case of a large number of channels
+                * when multichannel is negotiated) since that would lead
+                * to plenty of parallel I/O in flight to the server.
+                * Note that smaller read ahead sizes would
+                * hurt performance of common tools like cp and scp
+                * which often trigger sequential i/o with read ahead
+                */
+               if ((result.uint_32 > (8 * SMB3_DEFAULT_IOSIZE)) ||
+                   (result.uint_32 < CIFS_DEFAULT_IOSIZE)) {
+                       cifs_errorf(fc, "%s: Invalid rasize %d vs. %d\n",
+                               __func__, result.uint_32, SMB3_DEFAULT_IOSIZE);
+                       goto cifs_parse_mount_err;
+               }
+               ctx->rasize = result.uint_32;
+               break;
        case Opt_rsize:
                ctx->rsize = result.uint_32;
                ctx->got_rsize = true;
@@ -1377,7 +1398,9 @@ int smb3_init_fs_context(struct fs_context *fc)
        ctx->cred_uid = current_uid();
        ctx->linux_uid = current_uid();
        ctx->linux_gid = current_gid();
-       ctx->bsize = 1024 * 1024; /* can improve cp performance significantly */
+       /* By default 4MB read ahead size, 1MB block size */
+       ctx->bsize = CIFS_DEFAULT_IOSIZE; /* can improve cp performance significantly */
+       ctx->rasize = 0; /* 0 = use default (ie negotiated rsize) for read ahead pages */
 
        /*
         * default to SFM style remapping of seven reserved characters
index 56d7a75e2390b946d81ea5b1a0ca7667dd2aa010..2a71c8e411ac1b6acdc6b39f10021e278e2ccbf4 100644 (file)
@@ -120,6 +120,7 @@ enum cifs_param {
        Opt_dirmode,
        Opt_min_enc_offload,
        Opt_blocksize,
+       Opt_rasize,
        Opt_rsize,
        Opt_wsize,
        Opt_actimeo,
@@ -235,6 +236,7 @@ struct smb3_fs_context {
        /* reuse existing guid for multichannel */
        u8 client_guid[SMB2_CLIENT_GUID_SIZE];
        unsigned int bsize;
+       unsigned int rasize;
        unsigned int rsize;
        unsigned int wsize;
        unsigned int min_offload;