ceph: new mount option to disable usage of copy-from op
authorLuis Henriques <lhenriques@suse.com>
Mon, 15 Oct 2018 15:46:00 +0000 (16:46 +0100)
committerIlya Dryomov <idryomov@gmail.com>
Mon, 22 Oct 2018 08:28:24 +0000 (10:28 +0200)
Add a new mount option 'nocopyfrom' that will prevent the usage of the
RADOS 'copy-from' operation in cephfs.  This could be useful, for example,
for an administrator to temporarily mitigate any possible bugs in the
'copy-from' implementation.

Currently, only copy_file_range uses this RADOS operation.  Setting this
mount option will result in this syscall reverting to the default VFS
implementation, i.e. to perform the copies locally instead of doing remote
object copies.

Signed-off-by: Luis Henriques <lhenriques@suse.com>
Reviewed-by: "Yan, Zheng" <zyan@redhat.com>
Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
Documentation/filesystems/ceph.txt
fs/ceph/file.c
fs/ceph/super.c
fs/ceph/super.h

index 8bf62240e10d35a7dc99fac14f86afeb14313490..1177052701e138e22d63319e8c96001077b90660 100644 (file)
@@ -151,6 +151,11 @@ Mount Options
         Report overall filesystem usage in statfs instead of using the root
         directory quota.
 
+  nocopyfrom
+        Don't use the RADOS 'copy-from' operation to perform remote object
+        copies.  Currently, it's only used in copy_file_range, which will revert
+        to the default VFS implementation if this option is used.
+
 More Information
 ================
 
index 5557ec6760ea5dddfb8a62083d873c06fce21551..f788496fafcc9eeab5907cdcd7c68b16e0aecf8a 100644 (file)
@@ -1917,6 +1917,9 @@ static ssize_t ceph_copy_file_range(struct file *src_file, loff_t src_off,
         * efficient).
         */
 
+       if (ceph_test_mount_opt(ceph_inode_to_client(src_inode), NOCOPYFROM))
+               return -EOPNOTSUPP;
+
        if ((src_ci->i_layout.stripe_unit != dst_ci->i_layout.stripe_unit) ||
            (src_ci->i_layout.stripe_count != dst_ci->i_layout.stripe_count) ||
            (src_ci->i_layout.object_size != dst_ci->i_layout.object_size))
index eab1359d05532afb6960c7acfb5c4fee2891eac9..b5ecd6f50360d53e0fe24c4ea79416722e93fc6c 100644 (file)
@@ -165,6 +165,8 @@ enum {
        Opt_noacl,
        Opt_quotadf,
        Opt_noquotadf,
+       Opt_copyfrom,
+       Opt_nocopyfrom,
 };
 
 static match_table_t fsopt_tokens = {
@@ -203,6 +205,8 @@ static match_table_t fsopt_tokens = {
        {Opt_noacl, "noacl"},
        {Opt_quotadf, "quotadf"},
        {Opt_noquotadf, "noquotadf"},
+       {Opt_copyfrom, "copyfrom"},
+       {Opt_nocopyfrom, "nocopyfrom"},
        {-1, NULL}
 };
 
@@ -355,6 +359,12 @@ static int parse_fsopt_token(char *c, void *private)
        case Opt_noquotadf:
                fsopt->flags |= CEPH_MOUNT_OPT_NOQUOTADF;
                break;
+       case Opt_copyfrom:
+               fsopt->flags &= ~CEPH_MOUNT_OPT_NOCOPYFROM;
+               break;
+       case Opt_nocopyfrom:
+               fsopt->flags |= CEPH_MOUNT_OPT_NOCOPYFROM;
+               break;
 #ifdef CONFIG_CEPH_FS_POSIX_ACL
        case Opt_acl:
                fsopt->sb_flags |= SB_POSIXACL;
@@ -553,6 +563,9 @@ static int ceph_show_options(struct seq_file *m, struct dentry *root)
                seq_puts(m, ",noacl");
 #endif
 
+       if (fsopt->flags & CEPH_MOUNT_OPT_NOCOPYFROM)
+               seq_puts(m, ",nocopyfrom");
+
        if (fsopt->mds_namespace)
                seq_show_option(m, "mds_namespace", fsopt->mds_namespace);
        if (fsopt->wsize != CEPH_MAX_WRITE_SIZE)
index 91b13400badd42c8d7d650bed17fc0dbc5884138..c005a5400f2ed9b1e0e932ea680c2f0824020277 100644 (file)
@@ -40,6 +40,7 @@
 #define CEPH_MOUNT_OPT_NOPOOLPERM      (1<<11) /* no pool permission check */
 #define CEPH_MOUNT_OPT_MOUNTWAIT       (1<<12) /* mount waits if no mds is up */
 #define CEPH_MOUNT_OPT_NOQUOTADF       (1<<13) /* no root dir quota in statfs */
+#define CEPH_MOUNT_OPT_NOCOPYFROM      (1<<14) /* don't use RADOS 'copy-from' op */
 
 #define CEPH_MOUNT_OPT_DEFAULT    CEPH_MOUNT_OPT_DCACHE