diff options
author | Steve French <smfrench@gmail.com> | 2015-06-24 04:17:02 -0400 |
---|---|---|
committer | Steve French <steve.french@primarydata.com> | 2015-06-28 22:15:45 -0400 |
commit | b3152e2c7aa9ad0c50085738d048fbf16d01d32d (patch) | |
tree | 2015cead72bda343290909c2187cf3039171d53b | |
parent | 9d1b06602eb6716220c5988735c0b4944d62abaa (diff) |
Add ioctl to set integrity
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>
-rw-r--r-- | fs/cifs/cifsglob.h | 2 | ||||
-rw-r--r-- | fs/cifs/ioctl.c | 11 | ||||
-rw-r--r-- | fs/cifs/smb2ops.c | 24 | ||||
-rw-r--r-- | fs/cifs/smb2pdu.h | 1 |
4 files changed, 38 insertions, 0 deletions
diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h index 81194e6c7601..b406a32deb1f 100644 --- a/fs/cifs/cifsglob.h +++ b/fs/cifs/cifsglob.h | |||
@@ -372,6 +372,8 @@ struct smb_version_operations { | |||
372 | void (*new_lease_key)(struct cifs_fid *); | 372 | void (*new_lease_key)(struct cifs_fid *); |
373 | int (*generate_signingkey)(struct cifs_ses *); | 373 | int (*generate_signingkey)(struct cifs_ses *); |
374 | int (*calc_signature)(struct smb_rqst *, struct TCP_Server_Info *); | 374 | int (*calc_signature)(struct smb_rqst *, struct TCP_Server_Info *); |
375 | int (*set_integrity)(const unsigned int, struct cifs_tcon *tcon, | ||
376 | struct cifsFileInfo *src_file); | ||
375 | int (*query_mf_symlink)(unsigned int, struct cifs_tcon *, | 377 | int (*query_mf_symlink)(unsigned int, struct cifs_tcon *, |
376 | struct cifs_sb_info *, const unsigned char *, | 378 | struct cifs_sb_info *, const unsigned char *, |
377 | char *, unsigned int *); | 379 | char *, unsigned int *); |
diff --git a/fs/cifs/ioctl.c b/fs/cifs/ioctl.c index 7843b19ef5be..49b8b6e41a18 100644 --- a/fs/cifs/ioctl.c +++ b/fs/cifs/ioctl.c | |||
@@ -35,6 +35,7 @@ | |||
35 | 35 | ||
36 | #define CIFS_IOCTL_MAGIC 0xCF | 36 | #define CIFS_IOCTL_MAGIC 0xCF |
37 | #define CIFS_IOC_COPYCHUNK_FILE _IOW(CIFS_IOCTL_MAGIC, 3, int) | 37 | #define CIFS_IOC_COPYCHUNK_FILE _IOW(CIFS_IOCTL_MAGIC, 3, int) |
38 | #define CIFS_IOC_SET_INTEGRITY _IO(CIFS_IOCTL_MAGIC, 4) | ||
38 | 39 | ||
39 | static long cifs_ioctl_clone(unsigned int xid, struct file *dst_file, | 40 | static long cifs_ioctl_clone(unsigned int xid, struct file *dst_file, |
40 | unsigned long srcfd, u64 off, u64 len, u64 destoff, | 41 | 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) | |||
217 | case BTRFS_IOC_CLONE: | 218 | case BTRFS_IOC_CLONE: |
218 | rc = cifs_ioctl_clone(xid, filep, arg, 0, 0, 0, true); | 219 | rc = cifs_ioctl_clone(xid, filep, arg, 0, 0, 0, true); |
219 | break; | 220 | break; |
221 | case CIFS_IOC_SET_INTEGRITY: | ||
222 | if (pSMBFile == NULL) | ||
223 | break; | ||
224 | tcon = tlink_tcon(pSMBFile->tlink); | ||
225 | if (tcon->ses->server->ops->set_integrity) | ||
226 | rc = tcon->ses->server->ops->set_integrity(xid, | ||
227 | tcon, pSMBFile); | ||
228 | else | ||
229 | rc = -EOPNOTSUPP; | ||
230 | break; | ||
220 | default: | 231 | default: |
221 | cifs_dbg(FYI, "unsupported ioctl\n"); | 232 | cifs_dbg(FYI, "unsupported ioctl\n"); |
222 | break; | 233 | break; |
diff --git a/fs/cifs/smb2ops.c b/fs/cifs/smb2ops.c index b1e9c0f1b24c..df91bcf56d67 100644 --- a/fs/cifs/smb2ops.c +++ b/fs/cifs/smb2ops.c | |||
@@ -862,6 +862,28 @@ smb2_set_compression(const unsigned int xid, struct cifs_tcon *tcon, | |||
862 | } | 862 | } |
863 | 863 | ||
864 | static int | 864 | static int |
865 | smb3_set_integrity(const unsigned int xid, struct cifs_tcon *tcon, | ||
866 | struct cifsFileInfo *cfile) | ||
867 | { | ||
868 | struct fsctl_set_integrity_information_req integr_info; | ||
869 | char *retbuf = NULL; | ||
870 | unsigned int ret_data_len; | ||
871 | |||
872 | integr_info.ChecksumAlgorithm = cpu_to_le16(CHECKSUM_TYPE_UNCHANGED); | ||
873 | integr_info.Flags = 0; | ||
874 | integr_info.Reserved = 0; | ||
875 | |||
876 | return SMB2_ioctl(xid, tcon, cfile->fid.persistent_fid, | ||
877 | cfile->fid.volatile_fid, | ||
878 | FSCTL_SET_INTEGRITY_INFORMATION, | ||
879 | true /* is_fsctl */, (char *)&integr_info, | ||
880 | sizeof(struct fsctl_set_integrity_information_req), | ||
881 | (char **)&retbuf, | ||
882 | &ret_data_len); | ||
883 | |||
884 | } | ||
885 | |||
886 | static int | ||
865 | smb2_query_dir_first(const unsigned int xid, struct cifs_tcon *tcon, | 887 | smb2_query_dir_first(const unsigned int xid, struct cifs_tcon *tcon, |
866 | const char *path, struct cifs_sb_info *cifs_sb, | 888 | const char *path, struct cifs_sb_info *cifs_sb, |
867 | struct cifs_fid *fid, __u16 search_flags, | 889 | struct cifs_fid *fid, __u16 search_flags, |
@@ -1671,6 +1693,7 @@ struct smb_version_operations smb30_operations = { | |||
1671 | .new_lease_key = smb2_new_lease_key, | 1693 | .new_lease_key = smb2_new_lease_key, |
1672 | .generate_signingkey = generate_smb3signingkey, | 1694 | .generate_signingkey = generate_smb3signingkey, |
1673 | .calc_signature = smb3_calc_signature, | 1695 | .calc_signature = smb3_calc_signature, |
1696 | .set_integrity = smb3_set_integrity, | ||
1674 | .is_read_op = smb21_is_read_op, | 1697 | .is_read_op = smb21_is_read_op, |
1675 | .set_oplock_level = smb3_set_oplock_level, | 1698 | .set_oplock_level = smb3_set_oplock_level, |
1676 | .create_lease_buf = smb3_create_lease_buf, | 1699 | .create_lease_buf = smb3_create_lease_buf, |
@@ -1756,6 +1779,7 @@ struct smb_version_operations smb311_operations = { | |||
1756 | .new_lease_key = smb2_new_lease_key, | 1779 | .new_lease_key = smb2_new_lease_key, |
1757 | .generate_signingkey = generate_smb3signingkey, | 1780 | .generate_signingkey = generate_smb3signingkey, |
1758 | .calc_signature = smb3_calc_signature, | 1781 | .calc_signature = smb3_calc_signature, |
1782 | .set_integrity = smb3_set_integrity, | ||
1759 | .is_read_op = smb21_is_read_op, | 1783 | .is_read_op = smb21_is_read_op, |
1760 | .set_oplock_level = smb3_set_oplock_level, | 1784 | .set_oplock_level = smb3_set_oplock_level, |
1761 | .create_lease_buf = smb3_create_lease_buf, | 1785 | .create_lease_buf = smb3_create_lease_buf, |
diff --git a/fs/cifs/smb2pdu.h b/fs/cifs/smb2pdu.h index c302e82f2575..2d91c2a7b218 100644 --- a/fs/cifs/smb2pdu.h +++ b/fs/cifs/smb2pdu.h | |||
@@ -638,6 +638,7 @@ struct fsctl_get_integrity_information_rsp { | |||
638 | /* Integrity ChecksumAlgorithm choices for above */ | 638 | /* Integrity ChecksumAlgorithm choices for above */ |
639 | #define CHECKSUM_TYPE_NONE 0x0000 | 639 | #define CHECKSUM_TYPE_NONE 0x0000 |
640 | #define CHECKSUM_TYPE_CRC64 0x0002 | 640 | #define CHECKSUM_TYPE_CRC64 0x0002 |
641 | #define CHECKSUM_TYPE_UNCHANGED 0xFFFF /* set only */ | ||
641 | 642 | ||
642 | /* Integrity flags for above */ | 643 | /* Integrity flags for above */ |
643 | #define FSCTL_INTEGRITY_FLAG_CHECKSUM_ENFORCEMENT_OFF 0x00000001 | 644 | #define FSCTL_INTEGRITY_FLAG_CHECKSUM_ENFORCEMENT_OFF 0x00000001 |