Skip to content

Commit f3996e6

Browse files
committed
Merge branch 'for-next' of git://git.samba.org/sfrench/cifs-2.6
Pull SMB3 updates from Steve French: "A collection of SMB3 patches adding some reliability features (persistent and resilient handles) and improving SMB3 copy offload. I will have some additional patches for SMB3 encryption and SMB3.1.1 signing (important security features), and also for improving SMB3 persistent handle reconnection (setting ChannelSequence number e.g.) that I am still working on but wanted to get this set in since they can stand alone" * 'for-next' of git://git.samba.org/sfrench/cifs-2.6: Allow copy offload (CopyChunk) across shares Add resilienthandles mount parm [SMB3] Send durable handle v2 contexts when use of persistent handles required [SMB3] Display persistenthandles in /proc/mounts for SMB3 shares if enabled [SMB3] Enable checking for continuous availability and persistent handle support [SMB3] Add parsing for new mount option controlling persistent handles Allow duplicate extents in SMB3 not just SMB3.1.1
2 parents e75cdf9 + 7b52e27 commit f3996e6

File tree

9 files changed

+287
-25
lines changed

9 files changed

+287
-25
lines changed

fs/cifs/cifsfs.c

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -454,6 +454,10 @@ cifs_show_options(struct seq_file *s, struct dentry *root)
454454
seq_puts(s, ",nocase");
455455
if (tcon->retry)
456456
seq_puts(s, ",hard");
457+
if (tcon->use_persistent)
458+
seq_puts(s, ",persistenthandles");
459+
else if (tcon->use_resilient)
460+
seq_puts(s, ",resilienthandles");
457461
if (tcon->unix_ext)
458462
seq_puts(s, ",unix");
459463
else
@@ -921,9 +925,7 @@ const struct file_operations cifs_file_ops = {
921925
.mmap = cifs_file_mmap,
922926
.splice_read = generic_file_splice_read,
923927
.llseek = cifs_llseek,
924-
#ifdef CONFIG_CIFS_POSIX
925928
.unlocked_ioctl = cifs_ioctl,
926-
#endif /* CONFIG_CIFS_POSIX */
927929
.setlease = cifs_setlease,
928930
.fallocate = cifs_fallocate,
929931
};
@@ -939,9 +941,7 @@ const struct file_operations cifs_file_strict_ops = {
939941
.mmap = cifs_file_strict_mmap,
940942
.splice_read = generic_file_splice_read,
941943
.llseek = cifs_llseek,
942-
#ifdef CONFIG_CIFS_POSIX
943944
.unlocked_ioctl = cifs_ioctl,
944-
#endif /* CONFIG_CIFS_POSIX */
945945
.setlease = cifs_setlease,
946946
.fallocate = cifs_fallocate,
947947
};
@@ -957,9 +957,7 @@ const struct file_operations cifs_file_direct_ops = {
957957
.flush = cifs_flush,
958958
.mmap = cifs_file_mmap,
959959
.splice_read = generic_file_splice_read,
960-
#ifdef CONFIG_CIFS_POSIX
961960
.unlocked_ioctl = cifs_ioctl,
962-
#endif /* CONFIG_CIFS_POSIX */
963961
.llseek = cifs_llseek,
964962
.setlease = cifs_setlease,
965963
.fallocate = cifs_fallocate,
@@ -975,9 +973,7 @@ const struct file_operations cifs_file_nobrl_ops = {
975973
.mmap = cifs_file_mmap,
976974
.splice_read = generic_file_splice_read,
977975
.llseek = cifs_llseek,
978-
#ifdef CONFIG_CIFS_POSIX
979976
.unlocked_ioctl = cifs_ioctl,
980-
#endif /* CONFIG_CIFS_POSIX */
981977
.setlease = cifs_setlease,
982978
.fallocate = cifs_fallocate,
983979
};
@@ -992,9 +988,7 @@ const struct file_operations cifs_file_strict_nobrl_ops = {
992988
.mmap = cifs_file_strict_mmap,
993989
.splice_read = generic_file_splice_read,
994990
.llseek = cifs_llseek,
995-
#ifdef CONFIG_CIFS_POSIX
996991
.unlocked_ioctl = cifs_ioctl,
997-
#endif /* CONFIG_CIFS_POSIX */
998992
.setlease = cifs_setlease,
999993
.fallocate = cifs_fallocate,
1000994
};
@@ -1009,9 +1003,7 @@ const struct file_operations cifs_file_direct_nobrl_ops = {
10091003
.flush = cifs_flush,
10101004
.mmap = cifs_file_mmap,
10111005
.splice_read = generic_file_splice_read,
1012-
#ifdef CONFIG_CIFS_POSIX
10131006
.unlocked_ioctl = cifs_ioctl,
1014-
#endif /* CONFIG_CIFS_POSIX */
10151007
.llseek = cifs_llseek,
10161008
.setlease = cifs_setlease,
10171009
.fallocate = cifs_fallocate,

fs/cifs/cifsglob.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -493,7 +493,10 @@ struct smb_vol {
493493
bool mfsymlinks:1; /* use Minshall+French Symlinks */
494494
bool multiuser:1;
495495
bool rwpidforward:1; /* pid forward for read/write operations */
496-
bool nosharesock;
496+
bool nosharesock:1;
497+
bool persistent:1;
498+
bool nopersistent:1;
499+
bool resilient:1; /* noresilient not required since not fored for CA */
497500
unsigned int rsize;
498501
unsigned int wsize;
499502
bool sockopt_tcp_nodelay:1;
@@ -895,6 +898,8 @@ struct cifs_tcon {
895898
bool broken_posix_open; /* e.g. Samba server versions < 3.3.2, 3.2.9 */
896899
bool broken_sparse_sup; /* if server or share does not support sparse */
897900
bool need_reconnect:1; /* connection reset, tid now invalid */
901+
bool use_resilient:1; /* use resilient instead of durable handles */
902+
bool use_persistent:1; /* use persistent instead of durable handles */
898903
#ifdef CONFIG_CIFS_SMB2
899904
bool print:1; /* set if connection to printer share */
900905
bool bad_network_name:1; /* set if ret status STATUS_BAD_NETWORK_NAME */
@@ -1015,6 +1020,7 @@ struct cifs_fid {
10151020
__u64 persistent_fid; /* persist file id for smb2 */
10161021
__u64 volatile_fid; /* volatile file id for smb2 */
10171022
__u8 lease_key[SMB2_LEASE_KEY_SIZE]; /* lease key for smb2 */
1023+
__u8 create_guid[16];
10181024
#endif
10191025
struct cifs_pending_open *pending_open;
10201026
unsigned int epoch;

fs/cifs/connect.c

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,8 @@ enum {
8787
Opt_sign, Opt_seal, Opt_noac,
8888
Opt_fsc, Opt_mfsymlinks,
8989
Opt_multiuser, Opt_sloppy, Opt_nosharesock,
90+
Opt_persistent, Opt_nopersistent,
91+
Opt_resilient, Opt_noresilient,
9092

9193
/* Mount options which take numeric value */
9294
Opt_backupuid, Opt_backupgid, Opt_uid,
@@ -169,6 +171,10 @@ static const match_table_t cifs_mount_option_tokens = {
169171
{ Opt_multiuser, "multiuser" },
170172
{ Opt_sloppy, "sloppy" },
171173
{ Opt_nosharesock, "nosharesock" },
174+
{ Opt_persistent, "persistenthandles"},
175+
{ Opt_nopersistent, "nopersistenthandles"},
176+
{ Opt_resilient, "resilienthandles"},
177+
{ Opt_noresilient, "noresilienthandles"},
172178

173179
{ Opt_backupuid, "backupuid=%s" },
174180
{ Opt_backupgid, "backupgid=%s" },
@@ -1497,6 +1503,33 @@ cifs_parse_mount_options(const char *mountdata, const char *devname,
14971503
case Opt_nosharesock:
14981504
vol->nosharesock = true;
14991505
break;
1506+
case Opt_nopersistent:
1507+
vol->nopersistent = true;
1508+
if (vol->persistent) {
1509+
cifs_dbg(VFS,
1510+
"persistenthandles mount options conflict\n");
1511+
goto cifs_parse_mount_err;
1512+
}
1513+
break;
1514+
case Opt_persistent:
1515+
vol->persistent = true;
1516+
if ((vol->nopersistent) || (vol->resilient)) {
1517+
cifs_dbg(VFS,
1518+
"persistenthandles mount options conflict\n");
1519+
goto cifs_parse_mount_err;
1520+
}
1521+
break;
1522+
case Opt_resilient:
1523+
vol->resilient = true;
1524+
if (vol->persistent) {
1525+
cifs_dbg(VFS,
1526+
"persistenthandles mount options conflict\n");
1527+
goto cifs_parse_mount_err;
1528+
}
1529+
break;
1530+
case Opt_noresilient:
1531+
vol->resilient = false; /* already the default */
1532+
break;
15001533

15011534
/* Numeric Values */
15021535
case Opt_backupuid:
@@ -2655,6 +2688,42 @@ cifs_get_tcon(struct cifs_ses *ses, struct smb_vol *volume_info)
26552688
cifs_dbg(FYI, "DFS disabled (%d)\n", tcon->Flags);
26562689
}
26572690
tcon->seal = volume_info->seal;
2691+
tcon->use_persistent = false;
2692+
/* check if SMB2 or later, CIFS does not support persistent handles */
2693+
if (volume_info->persistent) {
2694+
if (ses->server->vals->protocol_id == 0) {
2695+
cifs_dbg(VFS,
2696+
"SMB3 or later required for persistent handles\n");
2697+
rc = -EOPNOTSUPP;
2698+
goto out_fail;
2699+
#ifdef CONFIG_CIFS_SMB2
2700+
} else if (ses->server->capabilities &
2701+
SMB2_GLOBAL_CAP_PERSISTENT_HANDLES)
2702+
tcon->use_persistent = true;
2703+
else /* persistent handles requested but not supported */ {
2704+
cifs_dbg(VFS,
2705+
"Persistent handles not supported on share\n");
2706+
rc = -EOPNOTSUPP;
2707+
goto out_fail;
2708+
#endif /* CONFIG_CIFS_SMB2 */
2709+
}
2710+
#ifdef CONFIG_CIFS_SMB2
2711+
} else if ((tcon->capabilities & SMB2_SHARE_CAP_CONTINUOUS_AVAILABILITY)
2712+
&& (ses->server->capabilities & SMB2_GLOBAL_CAP_PERSISTENT_HANDLES)
2713+
&& (volume_info->nopersistent == false)) {
2714+
cifs_dbg(FYI, "enabling persistent handles\n");
2715+
tcon->use_persistent = true;
2716+
#endif /* CONFIG_CIFS_SMB2 */
2717+
} else if (volume_info->resilient) {
2718+
if (ses->server->vals->protocol_id == 0) {
2719+
cifs_dbg(VFS,
2720+
"SMB2.1 or later required for resilient handles\n");
2721+
rc = -EOPNOTSUPP;
2722+
goto out_fail;
2723+
}
2724+
tcon->use_resilient = true;
2725+
}
2726+
26582727
/*
26592728
* We can have only one retry value for a connection to a share so for
26602729
* resources mounted more than once to the same server share the last
@@ -3503,6 +3572,15 @@ cifs_mount(struct cifs_sb_info *cifs_sb, struct smb_vol *volume_info)
35033572
goto mount_fail_check;
35043573
}
35053574

3575+
#ifdef CONFIG_CIFS_SMB2
3576+
if ((volume_info->persistent == true) && ((ses->server->capabilities &
3577+
SMB2_GLOBAL_CAP_PERSISTENT_HANDLES) == 0)) {
3578+
cifs_dbg(VFS, "persistent handles not supported by server\n");
3579+
rc = -EOPNOTSUPP;
3580+
goto mount_fail_check;
3581+
}
3582+
#endif /* CONFIG_CIFS_SMB2*/
3583+
35063584
/* search for existing tcon to this server share */
35073585
tcon = cifs_get_tcon(ses, volume_info);
35083586
if (IS_ERR(tcon)) {

fs/cifs/ioctl.c

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -85,9 +85,14 @@ static long cifs_ioctl_clone(unsigned int xid, struct file *dst_file,
8585
src_tcon = tlink_tcon(smb_file_src->tlink);
8686
target_tcon = tlink_tcon(smb_file_target->tlink);
8787

88-
/* check if source and target are on same tree connection */
89-
if (src_tcon != target_tcon) {
90-
cifs_dbg(VFS, "file copy src and target on different volume\n");
88+
/* check source and target on same server (or volume if dup_extents) */
89+
if (dup_extents && (src_tcon != target_tcon)) {
90+
cifs_dbg(VFS, "source and target of copy not on same share\n");
91+
goto out_fput;
92+
}
93+
94+
if (!dup_extents && (src_tcon->ses != target_tcon->ses)) {
95+
cifs_dbg(VFS, "source and target of copy not on same server\n");
9196
goto out_fput;
9297
}
9398

fs/cifs/smb2file.c

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ smb2_open_file(const unsigned int xid, struct cifs_open_parms *oparms,
4343
struct smb2_file_all_info *smb2_data = NULL;
4444
__u8 smb2_oplock[17];
4545
struct cifs_fid *fid = oparms->fid;
46+
struct network_resiliency_req nr_ioctl_req;
4647

4748
smb2_path = cifs_convert_path_to_utf16(oparms->path, oparms->cifs_sb);
4849
if (smb2_path == NULL) {
@@ -67,6 +68,24 @@ smb2_open_file(const unsigned int xid, struct cifs_open_parms *oparms,
6768
if (rc)
6869
goto out;
6970

71+
72+
if (oparms->tcon->use_resilient) {
73+
nr_ioctl_req.Timeout = 0; /* use server default (120 seconds) */
74+
nr_ioctl_req.Reserved = 0;
75+
rc = SMB2_ioctl(xid, oparms->tcon, fid->persistent_fid,
76+
fid->volatile_fid, FSCTL_LMR_REQUEST_RESILIENCY, true,
77+
(char *)&nr_ioctl_req, sizeof(nr_ioctl_req),
78+
NULL, NULL /* no return info */);
79+
if (rc == -EOPNOTSUPP) {
80+
cifs_dbg(VFS,
81+
"resiliency not supported by server, disabling\n");
82+
oparms->tcon->use_resilient = false;
83+
} else if (rc)
84+
cifs_dbg(FYI, "error %d setting resiliency\n", rc);
85+
86+
rc = 0;
87+
}
88+
7089
if (buf) {
7190
/* open response does not have IndexNumber field - get it */
7291
rc = SMB2_get_srv_num(xid, oparms->tcon, fid->persistent_fid,

fs/cifs/smb2ops.c

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -810,7 +810,6 @@ smb2_set_file_size(const unsigned int xid, struct cifs_tcon *tcon,
810810
cfile->fid.volatile_fid, cfile->pid, &eof, false);
811811
}
812812

813-
#ifdef CONFIG_CIFS_SMB311
814813
static int
815814
smb2_duplicate_extents(const unsigned int xid,
816815
struct cifsFileInfo *srcfile,
@@ -854,8 +853,6 @@ smb2_duplicate_extents(const unsigned int xid,
854853
duplicate_extents_out:
855854
return rc;
856855
}
857-
#endif /* CONFIG_CIFS_SMB311 */
858-
859856

860857
static int
861858
smb2_set_compression(const unsigned int xid, struct cifs_tcon *tcon,
@@ -1703,6 +1700,7 @@ struct smb_version_operations smb30_operations = {
17031700
.create_lease_buf = smb3_create_lease_buf,
17041701
.parse_lease_buf = smb3_parse_lease_buf,
17051702
.clone_range = smb2_clone_range,
1703+
.duplicate_extents = smb2_duplicate_extents,
17061704
.validate_negotiate = smb3_validate_negotiate,
17071705
.wp_retry_size = smb2_wp_retry_size,
17081706
.dir_needs_close = smb2_dir_needs_close,
@@ -1840,7 +1838,7 @@ struct smb_version_values smb21_values = {
18401838
struct smb_version_values smb30_values = {
18411839
.version_string = SMB30_VERSION_STRING,
18421840
.protocol_id = SMB30_PROT_ID,
1843-
.req_capabilities = SMB2_GLOBAL_CAP_DFS | SMB2_GLOBAL_CAP_LEASING | SMB2_GLOBAL_CAP_LARGE_MTU,
1841+
.req_capabilities = SMB2_GLOBAL_CAP_DFS | SMB2_GLOBAL_CAP_LEASING | SMB2_GLOBAL_CAP_LARGE_MTU | SMB2_GLOBAL_CAP_PERSISTENT_HANDLES,
18441842
.large_lock_type = 0,
18451843
.exclusive_lock_type = SMB2_LOCKFLAG_EXCLUSIVE_LOCK,
18461844
.shared_lock_type = SMB2_LOCKFLAG_SHARED_LOCK,
@@ -1860,7 +1858,7 @@ struct smb_version_values smb30_values = {
18601858
struct smb_version_values smb302_values = {
18611859
.version_string = SMB302_VERSION_STRING,
18621860
.protocol_id = SMB302_PROT_ID,
1863-
.req_capabilities = SMB2_GLOBAL_CAP_DFS | SMB2_GLOBAL_CAP_LEASING | SMB2_GLOBAL_CAP_LARGE_MTU,
1861+
.req_capabilities = SMB2_GLOBAL_CAP_DFS | SMB2_GLOBAL_CAP_LEASING | SMB2_GLOBAL_CAP_LARGE_MTU | SMB2_GLOBAL_CAP_PERSISTENT_HANDLES,
18641862
.large_lock_type = 0,
18651863
.exclusive_lock_type = SMB2_LOCKFLAG_EXCLUSIVE_LOCK,
18661864
.shared_lock_type = SMB2_LOCKFLAG_SHARED_LOCK,
@@ -1881,7 +1879,7 @@ struct smb_version_values smb302_values = {
18811879
struct smb_version_values smb311_values = {
18821880
.version_string = SMB311_VERSION_STRING,
18831881
.protocol_id = SMB311_PROT_ID,
1884-
.req_capabilities = SMB2_GLOBAL_CAP_DFS | SMB2_GLOBAL_CAP_LEASING | SMB2_GLOBAL_CAP_LARGE_MTU,
1882+
.req_capabilities = SMB2_GLOBAL_CAP_DFS | SMB2_GLOBAL_CAP_LEASING | SMB2_GLOBAL_CAP_LARGE_MTU | SMB2_GLOBAL_CAP_PERSISTENT_HANDLES,
18851883
.large_lock_type = 0,
18861884
.exclusive_lock_type = SMB2_LOCKFLAG_EXCLUSIVE_LOCK,
18871885
.shared_lock_type = SMB2_LOCKFLAG_SHARED_LOCK,

0 commit comments

Comments
 (0)