Add ioctl to set integrity
authorSteve French <smfrench@gmail.com>
Wed, 24 Jun 2015 08:17:02 +0000 (03:17 -0500)
committerSteve French <steve.french@primarydata.com>
Mon, 29 Jun 2015 02:15:45 +0000 (21:15 -0500)
set integrity increases reliability of files stored on SMB3 servers.
Add ioctl to allow setting this on files on SMB3 and later mounts.

Signed-off-by: Steve French <steve.french@primarydata.com>
fs/cifs/cifsglob.h
fs/cifs/ioctl.c
fs/cifs/smb2ops.c
fs/cifs/smb2pdu.h

index 81194e6c76010ed9d36a928d922ad161c66b0101..b406a32deb1f6bf2f9e8d416bc019a71f589d8db 100644 (file)
@@ -372,6 +372,8 @@ struct smb_version_operations {
        void (*new_lease_key)(struct cifs_fid *);
        int (*generate_signingkey)(struct cifs_ses *);
        int (*calc_signature)(struct smb_rqst *, struct TCP_Server_Info *);
+       int (*set_integrity)(const unsigned int, struct cifs_tcon *tcon,
+                            struct cifsFileInfo *src_file);
        int (*query_mf_symlink)(unsigned int, struct cifs_tcon *,
                                struct cifs_sb_info *, const unsigned char *,
                                char *, unsigned int *);
index 7843b19ef5bef63e97deebf507c6a629ab0582bd..49b8b6e41a188b3a832c3e32c482ed7a99091aa1 100644 (file)
@@ -35,6 +35,7 @@
 
 #define CIFS_IOCTL_MAGIC       0xCF
 #define CIFS_IOC_COPYCHUNK_FILE        _IOW(CIFS_IOCTL_MAGIC, 3, int)
+#define CIFS_IOC_SET_INTEGRITY  _IO(CIFS_IOCTL_MAGIC, 4)
 
 static long cifs_ioctl_clone(unsigned int xid, struct file *dst_file,
                        unsigned long srcfd, u64 off, u64 len, u64 destoff,
@@ -217,6 +218,16 @@ long cifs_ioctl(struct file *filep, unsigned int command, unsigned long arg)
                case BTRFS_IOC_CLONE:
                        rc = cifs_ioctl_clone(xid, filep, arg, 0, 0, 0, true);
                        break;
+               case CIFS_IOC_SET_INTEGRITY:
+                       if (pSMBFile == NULL)
+                               break;
+                       tcon = tlink_tcon(pSMBFile->tlink);
+                       if (tcon->ses->server->ops->set_integrity)
+                               rc = tcon->ses->server->ops->set_integrity(xid,
+                                               tcon, pSMBFile);
+                       else
+                               rc = -EOPNOTSUPP;
+                       break;
                default:
                        cifs_dbg(FYI, "unsupported ioctl\n");
                        break;
index b1e9c0f1b24c413e561660ab7fcfcb5fdab31b72..df91bcf56d67a35f0dd60d0361514f65cdc6705e 100644 (file)
@@ -861,6 +861,28 @@ smb2_set_compression(const unsigned int xid, struct cifs_tcon *tcon,
                            cfile->fid.volatile_fid);
 }
 
+static int
+smb3_set_integrity(const unsigned int xid, struct cifs_tcon *tcon,
+                  struct cifsFileInfo *cfile)
+{
+       struct fsctl_set_integrity_information_req integr_info;
+       char *retbuf = NULL;
+       unsigned int ret_data_len;
+
+       integr_info.ChecksumAlgorithm = cpu_to_le16(CHECKSUM_TYPE_UNCHANGED);
+       integr_info.Flags = 0;
+       integr_info.Reserved = 0;
+
+       return SMB2_ioctl(xid, tcon, cfile->fid.persistent_fid,
+                       cfile->fid.volatile_fid,
+                       FSCTL_SET_INTEGRITY_INFORMATION,
+                       true /* is_fsctl */, (char *)&integr_info,
+                       sizeof(struct fsctl_set_integrity_information_req),
+                       (char **)&retbuf,
+                       &ret_data_len);
+
+}
+
 static int
 smb2_query_dir_first(const unsigned int xid, struct cifs_tcon *tcon,
                     const char *path, struct cifs_sb_info *cifs_sb,
@@ -1671,6 +1693,7 @@ struct smb_version_operations smb30_operations = {
        .new_lease_key = smb2_new_lease_key,
        .generate_signingkey = generate_smb3signingkey,
        .calc_signature = smb3_calc_signature,
+       .set_integrity  = smb3_set_integrity,
        .is_read_op = smb21_is_read_op,
        .set_oplock_level = smb3_set_oplock_level,
        .create_lease_buf = smb3_create_lease_buf,
@@ -1756,6 +1779,7 @@ struct smb_version_operations smb311_operations = {
        .new_lease_key = smb2_new_lease_key,
        .generate_signingkey = generate_smb3signingkey,
        .calc_signature = smb3_calc_signature,
+       .set_integrity  = smb3_set_integrity,
        .is_read_op = smb21_is_read_op,
        .set_oplock_level = smb3_set_oplock_level,
        .create_lease_buf = smb3_create_lease_buf,
index c302e82f25759ed9b0153586de383f74f65af0b4..2d91c2a7b218e09979b959724f0563b496b234a7 100644 (file)
@@ -638,6 +638,7 @@ struct fsctl_get_integrity_information_rsp {
 /* Integrity ChecksumAlgorithm choices for above */
 #define        CHECKSUM_TYPE_NONE      0x0000
 #define        CHECKSUM_TYPE_CRC64     0x0002
+#define CHECKSUM_TYPE_UNCHANGED        0xFFFF  /* set only */
 
 /* Integrity flags for above */
 #define FSCTL_INTEGRITY_FLAG_CHECKSUM_ENFORCEMENT_OFF  0x00000001