1 | /* SPDX-License-Identifier: GPL-2.0-or-later */ |
2 | /* |
3 | * Copyright (C) 2020, Microsoft Corporation. |
4 | * |
5 | * Author(s): Steve French <stfrench@microsoft.com> |
6 | * David Howells <dhowells@redhat.com> |
7 | */ |
8 | |
9 | #ifndef _FS_CONTEXT_H |
10 | #define _FS_CONTEXT_H |
11 | |
12 | #include "cifsglob.h" |
13 | #include <linux/parser.h> |
14 | #include <linux/fs_parser.h> |
15 | |
16 | /* Log errors in fs_context (new mount api) but also in dmesg (old style) */ |
17 | #define cifs_errorf(fc, fmt, ...) \ |
18 | do { \ |
19 | errorf(fc, fmt, ## __VA_ARGS__); \ |
20 | cifs_dbg(VFS, fmt, ## __VA_ARGS__); \ |
21 | } while (0) |
22 | |
23 | static inline size_t cifs_io_align(struct fs_context *fc, |
24 | const char *name, size_t size) |
25 | { |
26 | if (!size || !IS_ALIGNED(size, PAGE_SIZE)) { |
27 | cifs_errorf(fc, "unaligned %s, making it a multiple of %lu bytes\n" , |
28 | name, PAGE_SIZE); |
29 | size = umax(round_down(size, PAGE_SIZE), PAGE_SIZE); |
30 | } |
31 | return size; |
32 | } |
33 | |
34 | #define CIFS_ALIGN_WSIZE(_fc, _size) cifs_io_align(_fc, "wsize", _size) |
35 | #define CIFS_ALIGN_RSIZE(_fc, _size) cifs_io_align(_fc, "rsize", _size) |
36 | #define CIFS_ALIGN_BSIZE(_fc, _size) cifs_io_align(_fc, "bsize", _size) |
37 | |
38 | enum smb_version { |
39 | Smb_1 = 1, |
40 | Smb_20, |
41 | Smb_21, |
42 | Smb_30, |
43 | Smb_302, |
44 | Smb_311, |
45 | Smb_3any, |
46 | Smb_default, |
47 | Smb_version_err |
48 | }; |
49 | |
50 | enum { |
51 | Opt_cache_loose, |
52 | Opt_cache_strict, |
53 | Opt_cache_none, |
54 | Opt_cache_ro, |
55 | Opt_cache_rw, |
56 | Opt_cache_err |
57 | }; |
58 | |
59 | enum cifs_reparse_parm { |
60 | Opt_reparse_default, |
61 | Opt_reparse_none, |
62 | Opt_reparse_nfs, |
63 | Opt_reparse_wsl, |
64 | Opt_reparse_err |
65 | }; |
66 | |
67 | enum cifs_symlink_parm { |
68 | Opt_symlink_default, |
69 | Opt_symlink_none, |
70 | Opt_symlink_native, |
71 | Opt_symlink_unix, |
72 | Opt_symlink_mfsymlinks, |
73 | Opt_symlink_sfu, |
74 | Opt_symlink_nfs, |
75 | Opt_symlink_wsl, |
76 | Opt_symlink_err |
77 | }; |
78 | |
79 | enum cifs_sec_param { |
80 | Opt_sec_krb5, |
81 | Opt_sec_krb5i, |
82 | Opt_sec_krb5p, |
83 | Opt_sec_ntlmsspi, |
84 | Opt_sec_ntlmssp, |
85 | Opt_sec_ntlmv2, |
86 | Opt_sec_ntlmv2i, |
87 | Opt_sec_none, |
88 | |
89 | Opt_sec_err |
90 | }; |
91 | |
92 | enum cifs_upcall_target_param { |
93 | Opt_upcall_target_mount, |
94 | Opt_upcall_target_application, |
95 | Opt_upcall_target_err |
96 | }; |
97 | |
98 | enum cifs_param { |
99 | /* Mount options that take no arguments */ |
100 | Opt_user_xattr, |
101 | Opt_forceuid, |
102 | Opt_forcegid, |
103 | Opt_noblocksend, |
104 | Opt_noautotune, |
105 | Opt_nolease, |
106 | Opt_nosparse, |
107 | Opt_hard, |
108 | Opt_soft, |
109 | Opt_perm, |
110 | Opt_nodelete, |
111 | Opt_mapposix, |
112 | Opt_mapchars, |
113 | Opt_nomapchars, |
114 | Opt_sfu, |
115 | Opt_nodfs, |
116 | Opt_posixpaths, |
117 | Opt_unix, |
118 | Opt_nocase, |
119 | Opt_brl, |
120 | Opt_handlecache, |
121 | Opt_forcemandatorylock, |
122 | Opt_setuidfromacl, |
123 | Opt_setuids, |
124 | Opt_dynperm, |
125 | Opt_intr, |
126 | Opt_strictsync, |
127 | Opt_serverino, |
128 | Opt_rwpidforward, |
129 | Opt_cifsacl, |
130 | Opt_acl, |
131 | Opt_locallease, |
132 | Opt_sign, |
133 | Opt_ignore_signature, |
134 | Opt_seal, |
135 | Opt_noac, |
136 | Opt_fsc, |
137 | Opt_mfsymlinks, |
138 | Opt_multiuser, |
139 | Opt_sloppy, |
140 | Opt_nosharesock, |
141 | Opt_persistent, |
142 | Opt_resilient, |
143 | Opt_tcp_nodelay, |
144 | Opt_domainauto, |
145 | Opt_rdma, |
146 | Opt_modesid, |
147 | Opt_rootfs, |
148 | Opt_multichannel, |
149 | Opt_compress, |
150 | Opt_witness, |
151 | Opt_is_upcall_target_mount, |
152 | Opt_is_upcall_target_application, |
153 | Opt_unicode, |
154 | |
155 | /* Mount options which take numeric value */ |
156 | Opt_backupuid, |
157 | Opt_backupgid, |
158 | Opt_uid, |
159 | Opt_cruid, |
160 | Opt_gid, |
161 | Opt_port, |
162 | Opt_file_mode, |
163 | Opt_dirmode, |
164 | Opt_min_enc_offload, |
165 | Opt_retrans, |
166 | Opt_blocksize, |
167 | Opt_rasize, |
168 | Opt_rsize, |
169 | Opt_wsize, |
170 | Opt_actimeo, |
171 | Opt_acdirmax, |
172 | Opt_acregmax, |
173 | Opt_closetimeo, |
174 | Opt_echo_interval, |
175 | Opt_max_credits, |
176 | Opt_max_cached_dirs, |
177 | Opt_snapshot, |
178 | Opt_max_channels, |
179 | Opt_handletimeout, |
180 | |
181 | /* Mount options which take string value */ |
182 | Opt_source, |
183 | Opt_user, |
184 | Opt_pass, |
185 | Opt_pass2, |
186 | Opt_ip, |
187 | Opt_domain, |
188 | Opt_srcaddr, |
189 | Opt_iocharset, |
190 | Opt_netbiosname, |
191 | Opt_servern, |
192 | Opt_nbsessinit, |
193 | Opt_ver, |
194 | Opt_vers, |
195 | Opt_sec, |
196 | Opt_cache, |
197 | Opt_reparse, |
198 | Opt_upcalltarget, |
199 | Opt_nativesocket, |
200 | Opt_symlink, |
201 | Opt_symlinkroot, |
202 | |
203 | /* Mount options to be ignored */ |
204 | Opt_ignore, |
205 | |
206 | Opt_err |
207 | }; |
208 | |
209 | struct smb3_fs_context { |
210 | bool forceuid_specified; |
211 | bool forcegid_specified; |
212 | bool uid_specified; |
213 | bool cruid_specified; |
214 | bool gid_specified; |
215 | bool sloppy; |
216 | bool got_ip; |
217 | bool got_version; |
218 | bool got_rsize; |
219 | bool got_wsize; |
220 | bool got_bsize; |
221 | unsigned short port; |
222 | |
223 | char *username; |
224 | char *password; |
225 | char *password2; |
226 | char *domainname; |
227 | char *source; |
228 | char *server_hostname; |
229 | char *UNC; |
230 | char *nodename; |
231 | char workstation_name[CIFS_MAX_WORKSTATION_LEN]; |
232 | char *iocharset; /* local code page for mapping to and from Unicode */ |
233 | char source_rfc1001_name[RFC1001_NAME_LEN_WITH_NULL]; /* clnt nb name */ |
234 | char target_rfc1001_name[RFC1001_NAME_LEN_WITH_NULL]; /* srvr nb name */ |
235 | int rfc1001_sessinit; |
236 | kuid_t cred_uid; |
237 | kuid_t linux_uid; |
238 | kgid_t linux_gid; |
239 | kuid_t backupuid; |
240 | kgid_t backupgid; |
241 | umode_t file_mode; |
242 | umode_t dir_mode; |
243 | enum securityEnum sectype; /* sectype requested via mnt opts */ |
244 | enum upcall_target_enum upcall_target; /* where to upcall for mount */ |
245 | bool sign; /* was signing requested via mnt opts? */ |
246 | bool ignore_signature:1; |
247 | bool retry:1; |
248 | bool intr:1; |
249 | bool setuids:1; |
250 | bool setuidfromacl:1; |
251 | bool override_uid:1; |
252 | bool override_gid:1; |
253 | bool dynperm:1; |
254 | bool noperm:1; |
255 | bool nodelete:1; |
256 | bool mode_ace:1; |
257 | bool no_psx_acl:1; /* set if posix acl support should be disabled */ |
258 | bool cifs_acl:1; |
259 | bool backupuid_specified; /* mount option backupuid is specified */ |
260 | bool backupgid_specified; /* mount option backupgid is specified */ |
261 | bool no_xattr:1; /* set if xattr (EA) support should be disabled*/ |
262 | bool server_ino:1; /* use inode numbers from server ie UniqueId */ |
263 | bool direct_io:1; |
264 | bool strict_io:1; /* strict cache behavior */ |
265 | bool cache_ro:1; |
266 | bool cache_rw:1; |
267 | bool remap:1; /* set to remap seven reserved chars in filenames */ |
268 | bool sfu_remap:1; /* remap seven reserved chars ala SFU */ |
269 | bool posix_paths:1; /* unset to not ask for posix pathnames. */ |
270 | bool no_linux_ext:1; |
271 | bool linux_ext:1; |
272 | bool sfu_emul:1; |
273 | bool nullauth:1; /* attempt to authenticate with null user */ |
274 | bool nocase:1; /* request case insensitive filenames */ |
275 | bool nobrl:1; /* disable sending byte range locks to srv */ |
276 | bool nohandlecache:1; /* disable caching dir handles if srvr probs */ |
277 | bool mand_lock:1; /* send mandatory not posix byte range lock reqs */ |
278 | bool seal:1; /* request transport encryption on share */ |
279 | bool nodfs:1; /* Do not request DFS, even if available */ |
280 | bool local_lease:1; /* check leases only on local system, not remote */ |
281 | bool noblocksnd:1; |
282 | bool noautotune:1; |
283 | bool nostrictsync:1; /* do not force expensive SMBflush on every sync */ |
284 | bool no_lease:1; /* disable requesting leases */ |
285 | bool no_sparse:1; /* do not attempt to set files sparse */ |
286 | bool fsc:1; /* enable fscache */ |
287 | bool mfsymlinks:1; /* use Minshall+French Symlinks */ |
288 | bool multiuser:1; |
289 | bool rwpidforward:1; /* pid forward for read/write operations */ |
290 | bool nosharesock:1; |
291 | bool persistent:1; |
292 | bool nopersistent:1; |
293 | bool resilient:1; /* noresilient not required since not fored for CA */ |
294 | bool domainauto:1; |
295 | bool rdma:1; |
296 | bool multichannel:1; |
297 | bool use_client_guid:1; |
298 | /* reuse existing guid for multichannel */ |
299 | u8 client_guid[SMB2_CLIENT_GUID_SIZE]; |
300 | /* User-specified original r/wsize value */ |
301 | unsigned int vol_rsize; |
302 | unsigned int vol_wsize; |
303 | unsigned int bsize; |
304 | unsigned int rasize; |
305 | unsigned int rsize; |
306 | unsigned int wsize; |
307 | unsigned int min_offload; |
308 | unsigned int retrans; |
309 | bool sockopt_tcp_nodelay:1; |
310 | /* attribute cache timeout for files and directories in jiffies */ |
311 | unsigned long acregmax; |
312 | unsigned long acdirmax; |
313 | /* timeout for deferred close of files in jiffies */ |
314 | unsigned long closetimeo; |
315 | struct smb_version_operations *ops; |
316 | struct smb_version_values *vals; |
317 | char *prepath; |
318 | struct sockaddr_storage dstaddr; /* destination address */ |
319 | struct sockaddr_storage srcaddr; /* allow binding to a local IP */ |
320 | struct nls_table *local_nls; /* This is a copy of the pointer in cifs_sb */ |
321 | unsigned int echo_interval; /* echo interval in secs */ |
322 | __u64 snapshot_time; /* needed for timewarp tokens */ |
323 | __u32 handle_timeout; /* persistent and durable handle timeout in ms */ |
324 | unsigned int max_credits; /* smb3 max_credits 10 < credits < 60000 */ |
325 | unsigned int max_channels; |
326 | unsigned int max_cached_dirs; |
327 | bool compress; /* enable SMB2 messages (READ/WRITE) de/compression */ |
328 | bool rootfs:1; /* if it's a SMB root file system */ |
329 | bool witness:1; /* use witness protocol */ |
330 | int unicode; |
331 | char *leaf_fullpath; |
332 | struct cifs_ses *dfs_root_ses; |
333 | bool dfs_automount:1; /* set for dfs automount only */ |
334 | enum cifs_reparse_type reparse_type; |
335 | enum cifs_symlink_type symlink_type; |
336 | bool nonativesocket:1; |
337 | bool dfs_conn:1; /* set for dfs mounts */ |
338 | char *dns_dom; |
339 | char *symlinkroot; /* top level directory for native SMB symlinks in absolute format */ |
340 | }; |
341 | |
342 | extern const struct fs_parameter_spec smb3_fs_parameters[]; |
343 | |
344 | extern enum cifs_symlink_type get_cifs_symlink_type(struct cifs_sb_info *cifs_sb); |
345 | |
346 | extern int smb3_init_fs_context(struct fs_context *fc); |
347 | extern void smb3_cleanup_fs_context_contents(struct smb3_fs_context *ctx); |
348 | extern void smb3_cleanup_fs_context(struct smb3_fs_context *ctx); |
349 | |
350 | static inline struct smb3_fs_context *smb3_fc2context(const struct fs_context *fc) |
351 | { |
352 | return fc->fs_private; |
353 | } |
354 | |
355 | extern int smb3_fs_context_dup(struct smb3_fs_context *new_ctx, struct smb3_fs_context *ctx); |
356 | extern int smb3_sync_session_ctx_passwords(struct cifs_sb_info *cifs_sb, struct cifs_ses *ses); |
357 | extern void smb3_update_mnt_flags(struct cifs_sb_info *cifs_sb); |
358 | |
359 | /* |
360 | * max deferred close timeout (jiffies) - 2^30 |
361 | */ |
362 | #define SMB3_MAX_DCLOSETIMEO (1 << 30) |
363 | #define SMB3_DEF_DCLOSETIMEO (1 * HZ) /* even 1 sec enough to help eg open/write/close/open/read */ |
364 | #define MAX_CACHED_FIDS 16 |
365 | extern char *cifs_sanitize_prepath(char *prepath, gfp_t gfp); |
366 | |
367 | extern struct mutex cifs_mount_mutex; |
368 | |
369 | static inline void cifs_mount_lock(void) |
370 | { |
371 | mutex_lock(&cifs_mount_mutex); |
372 | } |
373 | |
374 | static inline void cifs_mount_unlock(void) |
375 | { |
376 | mutex_unlock(lock: &cifs_mount_mutex); |
377 | } |
378 | |
379 | static inline void cifs_negotiate_rsize(struct TCP_Server_Info *server, |
380 | struct smb3_fs_context *ctx, |
381 | struct cifs_tcon *tcon) |
382 | { |
383 | unsigned int size; |
384 | |
385 | size = umax(server->ops->negotiate_rsize(tcon, ctx), PAGE_SIZE); |
386 | if (ctx->rsize) |
387 | size = umax(umin(ctx->rsize, size), PAGE_SIZE); |
388 | ctx->rsize = round_down(size, PAGE_SIZE); |
389 | } |
390 | |
391 | static inline void cifs_negotiate_wsize(struct TCP_Server_Info *server, |
392 | struct smb3_fs_context *ctx, |
393 | struct cifs_tcon *tcon) |
394 | { |
395 | unsigned int size; |
396 | |
397 | size = umax(server->ops->negotiate_wsize(tcon, ctx), PAGE_SIZE); |
398 | if (ctx->wsize) |
399 | size = umax(umin(ctx->wsize, size), PAGE_SIZE); |
400 | ctx->wsize = round_down(size, PAGE_SIZE); |
401 | } |
402 | |
403 | static inline void cifs_negotiate_iosize(struct TCP_Server_Info *server, |
404 | struct smb3_fs_context *ctx, |
405 | struct cifs_tcon *tcon) |
406 | { |
407 | cifs_negotiate_rsize(server, ctx, tcon); |
408 | cifs_negotiate_wsize(server, ctx, tcon); |
409 | } |
410 | |
411 | #endif |
412 | |