Skip to content

Commit 279d44c

Browse files
committed
Merge tag '6.9-rc-smb3-client-fixes-part1' of git://git.samba.org/sfrench/cifs-2.6
Pull smb client updates from Steve French: - fix for folios/netfs data corruption in cifs_extend_writeback - additional tracepoint added - updates for special files and symlinks: improvements to allow selecting use of either WSL or NFS reparse point format on creating special files - allocation size improvement for cached files - minor cleanup patches - fix to allow changing the password on remount when password for the session is expired. - lease key related fixes: caching hardlinked files, deletes of deferred close files, and an important fix to better reuse lease keys for compound operations, which also can avoid lease break timeouts when low on credits - fix potential data corruption with write/readdir races - compression cleanups and a fix for compression headers * tag '6.9-rc-smb3-client-fixes-part1' of git://git.samba.org/sfrench/cifs-2.6: (24 commits) cifs: update internal module version number for cifs.ko smb: common: simplify compression headers smb: common: fix fields sizes in compression_pattern_payload_v1 smb: client: negotiate compression algorithms smb3: add dynamic trace point for ioctls cifs: Fix writeback data corruption smb: client: return reparse type in /proc/mounts smb: client: set correct d_type for reparse DFS/DFSR and mount point smb: client: parse uid, gid, mode and dev from WSL reparse points smb: client: introduce SMB2_OP_QUERY_WSL_EA smb: client: Fix a NULL vs IS_ERR() check in wsl_set_xattrs() smb: client: add support for WSL reparse points smb: client: reduce number of parameters in smb2_compound_op() smb: client: fix potential broken compound request smb: client: move most of reparse point handling code to common file smb: client: introduce reparse mount option smb: client: retry compound request without reusing lease smb: client: do not defer close open handles to deleted files smb: client: reuse file lease key in compound operations smb3: update allocation size more accurately on write completion ...
2 parents 9d9539d + 3681fe1 commit 279d44c

27 files changed

+1565
-707
lines changed

MAINTAINERS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5255,6 +5255,7 @@ R: Paulo Alcantara <[email protected]> (DFS, global name space)
52555255
R: Ronnie Sahlberg <[email protected]> (directory leases, sparse files)
52565256
R: Shyam Prasad N <[email protected]> (multichannel)
52575257
R: Tom Talpey <[email protected]> (RDMA, smbdirect)
5258+
R: Bharath SM <[email protected]> (deferred close, directory leases)
52585259
52595260
L: [email protected] (moderated for non-subscribers)
52605261
S: Supported

fs/smb/client/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ cifs-y := trace.o cifsfs.o cifs_debug.o connect.o dir.o file.o \
1212
smb2ops.o smb2maperror.o smb2transport.o \
1313
smb2misc.o smb2pdu.o smb2inode.o smb2file.o cifsacl.o fs_context.o \
1414
dns_resolve.o cifs_spnego_negtokeninit.asn1.o asn1.o \
15-
namespace.o
15+
namespace.o reparse.o
1616

1717
$(obj)/asn1.o: $(obj)/cifs_spnego_negtokeninit.asn1.h
1818

fs/smb/client/cifs_debug.c

Lines changed: 28 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -278,6 +278,24 @@ static int cifs_debug_files_proc_show(struct seq_file *m, void *v)
278278
return 0;
279279
}
280280

281+
static __always_inline const char *compression_alg_str(__le16 alg)
282+
{
283+
switch (alg) {
284+
case SMB3_COMPRESS_NONE:
285+
return "NONE";
286+
case SMB3_COMPRESS_LZNT1:
287+
return "LZNT1";
288+
case SMB3_COMPRESS_LZ77:
289+
return "LZ77";
290+
case SMB3_COMPRESS_LZ77_HUFF:
291+
return "LZ77-Huffman";
292+
case SMB3_COMPRESS_PATTERN:
293+
return "Pattern_V1";
294+
default:
295+
return "invalid";
296+
}
297+
}
298+
281299
static int cifs_debug_data_proc_show(struct seq_file *m, void *v)
282300
{
283301
struct mid_q_entry *mid_entry;
@@ -423,12 +441,6 @@ static int cifs_debug_data_proc_show(struct seq_file *m, void *v)
423441
server->echo_credits,
424442
server->oplock_credits,
425443
server->dialect);
426-
if (server->compress_algorithm == SMB3_COMPRESS_LZNT1)
427-
seq_printf(m, " COMPRESS_LZNT1");
428-
else if (server->compress_algorithm == SMB3_COMPRESS_LZ77)
429-
seq_printf(m, " COMPRESS_LZ77");
430-
else if (server->compress_algorithm == SMB3_COMPRESS_LZ77_HUFF)
431-
seq_printf(m, " COMPRESS_LZ77_HUFF");
432444
if (server->sign)
433445
seq_printf(m, " signed");
434446
if (server->posix_ext_supported)
@@ -460,6 +472,14 @@ static int cifs_debug_data_proc_show(struct seq_file *m, void *v)
460472
server->leaf_fullpath);
461473
}
462474

475+
seq_puts(m, "\nCompression: ");
476+
if (!server->compression.requested)
477+
seq_puts(m, "disabled on mount");
478+
else if (server->compression.enabled)
479+
seq_printf(m, "enabled (%s)", compression_alg_str(server->compression.alg));
480+
else
481+
seq_puts(m, "disabled (not supported by this server)");
482+
463483
seq_printf(m, "\n\n\tSessions: ");
464484
i = 0;
465485
list_for_each_entry(ses, &server->smb_ses_list, smb_ses_list) {
@@ -488,6 +508,8 @@ static int cifs_debug_data_proc_show(struct seq_file *m, void *v)
488508
ses->ses_count, ses->serverOS, ses->serverNOS,
489509
ses->capabilities, ses->ses_status);
490510
}
511+
if (ses->expired_pwd)
512+
seq_puts(m, "password no longer valid ");
491513
spin_unlock(&ses->ses_lock);
492514

493515
seq_printf(m, "\n\tSecurity type: %s ",

fs/smb/client/cifsfs.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -673,6 +673,8 @@ cifs_show_options(struct seq_file *s, struct dentry *root)
673673
seq_printf(s, ",backupgid=%u",
674674
from_kgid_munged(&init_user_ns,
675675
cifs_sb->ctx->backupgid));
676+
seq_show_option(s, "reparse",
677+
cifs_reparse_type_str(cifs_sb->ctx->reparse_type));
676678

677679
seq_printf(s, ",rsize=%u", cifs_sb->ctx->rsize);
678680
seq_printf(s, ",wsize=%u", cifs_sb->ctx->wsize);

fs/smb/client/cifsfs.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,6 @@ extern const struct export_operations cifs_export_ops;
152152
#endif /* CONFIG_CIFS_NFSD_EXPORT */
153153

154154
/* when changing internal version - update following two lines at same time */
155-
#define SMB3_PRODUCT_BUILD 47
156-
#define CIFS_VERSION "2.47"
155+
#define SMB3_PRODUCT_BUILD 48
156+
#define CIFS_VERSION "2.48"
157157
#endif /* _CIFSFS_H */

fs/smb/client/cifsglob.h

Lines changed: 45 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,24 @@ enum securityEnum {
153153
Kerberos, /* Kerberos via SPNEGO */
154154
};
155155

156+
enum cifs_reparse_type {
157+
CIFS_REPARSE_TYPE_NFS,
158+
CIFS_REPARSE_TYPE_WSL,
159+
CIFS_REPARSE_TYPE_DEFAULT = CIFS_REPARSE_TYPE_NFS,
160+
};
161+
162+
static inline const char *cifs_reparse_type_str(enum cifs_reparse_type type)
163+
{
164+
switch (type) {
165+
case CIFS_REPARSE_TYPE_NFS:
166+
return "nfs";
167+
case CIFS_REPARSE_TYPE_WSL:
168+
return "wsl";
169+
default:
170+
return "unknown";
171+
}
172+
}
173+
156174
struct session_key {
157175
unsigned int len;
158176
char *response;
@@ -208,6 +226,10 @@ struct cifs_open_info_data {
208226
struct reparse_posix_data *posix;
209227
};
210228
} reparse;
229+
struct {
230+
__u8 eas[SMB2_WSL_MAX_QUERY_EA_RESP_SIZE];
231+
unsigned int eas_len;
232+
} wsl;
211233
char *symlink_target;
212234
struct cifs_sid posix_owner;
213235
struct cifs_sid posix_group;
@@ -217,19 +239,6 @@ struct cifs_open_info_data {
217239
};
218240
};
219241

220-
static inline bool cifs_open_data_reparse(struct cifs_open_info_data *data)
221-
{
222-
struct smb2_file_all_info *fi = &data->fi;
223-
u32 attrs = le32_to_cpu(fi->Attributes);
224-
bool ret;
225-
226-
ret = data->reparse_point || (attrs & ATTR_REPARSE);
227-
if (ret)
228-
attrs |= ATTR_REPARSE;
229-
fi->Attributes = cpu_to_le32(attrs);
230-
return ret;
231-
}
232-
233242
/*
234243
*****************************************************************
235244
* Except the CIFS PDUs themselves all the
@@ -371,7 +380,8 @@ struct smb_version_operations {
371380
struct cifs_open_info_data *data);
372381
/* set size by path */
373382
int (*set_path_size)(const unsigned int, struct cifs_tcon *,
374-
const char *, __u64, struct cifs_sb_info *, bool);
383+
const char *, __u64, struct cifs_sb_info *, bool,
384+
struct dentry *);
375385
/* set size by file handle */
376386
int (*set_file_size)(const unsigned int, struct cifs_tcon *,
377387
struct cifsFileInfo *, __u64, bool);
@@ -401,7 +411,7 @@ struct smb_version_operations {
401411
struct cifs_sb_info *);
402412
/* unlink file */
403413
int (*unlink)(const unsigned int, struct cifs_tcon *, const char *,
404-
struct cifs_sb_info *);
414+
struct cifs_sb_info *, struct dentry *);
405415
/* open, rename and delete file */
406416
int (*rename_pending_delete)(const char *, struct dentry *,
407417
const unsigned int);
@@ -759,7 +769,11 @@ struct TCP_Server_Info {
759769
unsigned int max_write;
760770
unsigned int min_offload;
761771
unsigned int retrans;
762-
__le16 compress_algorithm;
772+
struct {
773+
bool requested; /* "compress" mount option set*/
774+
bool enabled; /* actually negotiated with server */
775+
__le16 alg; /* preferred alg negotiated with server */
776+
} compression;
763777
__u16 signing_algorithm;
764778
__le16 cipher_type;
765779
/* save initital negprot hash */
@@ -1066,6 +1080,7 @@ struct cifs_ses {
10661080
enum securityEnum sectype; /* what security flavor was specified? */
10671081
bool sign; /* is signing required? */
10681082
bool domainAuto:1;
1083+
bool expired_pwd; /* track if access denied or expired pwd so can know if need to update */
10691084
unsigned int flags;
10701085
__u16 session_flags;
10711086
__u8 smb3signingkey[SMB3_SIGN_KEY_SIZE];
@@ -1379,6 +1394,7 @@ struct cifs_open_parms {
13791394
umode_t mode;
13801395
bool reconnect:1;
13811396
bool replay:1; /* indicates that this open is for a replay */
1397+
struct kvec *ea_cctx;
13821398
};
13831399

13841400
struct cifs_fid {
@@ -1420,6 +1436,7 @@ struct cifsFileInfo {
14201436
bool invalidHandle:1; /* file closed via session abend */
14211437
bool swapfile:1;
14221438
bool oplock_break_cancelled:1;
1439+
bool status_file_deleted:1; /* file has been deleted */
14231440
unsigned int oplock_epoch; /* epoch from the lease break */
14241441
__u32 oplock_level; /* oplock/lease level from the lease break */
14251442
int count;
@@ -2277,6 +2294,17 @@ static inline void cifs_sg_set_buf(struct sg_table *sgtable,
22772294
}
22782295
}
22792296

2297+
#define CIFS_OPARMS(_cifs_sb, _tcon, _path, _da, _cd, _co, _mode) \
2298+
((struct cifs_open_parms) { \
2299+
.tcon = _tcon, \
2300+
.path = _path, \
2301+
.desired_access = (_da), \
2302+
.disposition = (_cd), \
2303+
.create_options = cifs_create_options(_cifs_sb, (_co)), \
2304+
.mode = (_mode), \
2305+
.cifs_sb = _cifs_sb, \
2306+
})
2307+
22802308
struct smb2_compound_vars {
22812309
struct cifs_open_parms oparms;
22822310
struct kvec rsp_iov[MAX_COMPOUND];
@@ -2288,6 +2316,7 @@ struct smb2_compound_vars {
22882316
struct kvec close_iov;
22892317
struct smb2_file_rename_info rename_info;
22902318
struct smb2_file_link_info link_info;
2319+
struct kvec ea_iov;
22912320
};
22922321

22932322
#endif /* _CIFS_GLOB_H */

fs/smb/client/cifsproto.h

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,8 @@ extern int cifs_reconnect(struct TCP_Server_Info *server,
144144
extern int checkSMB(char *buf, unsigned int len, struct TCP_Server_Info *srvr);
145145
extern bool is_valid_oplock_break(char *, struct TCP_Server_Info *);
146146
extern bool backup_cred(struct cifs_sb_info *);
147-
extern bool is_size_safe_to_change(struct cifsInodeInfo *, __u64 eof);
147+
extern bool is_size_safe_to_change(struct cifsInodeInfo *cifsInode, __u64 eof,
148+
bool from_readdir);
148149
extern void cifs_update_eof(struct cifsInodeInfo *cifsi, loff_t offset,
149150
unsigned int bytes_written);
150151
extern struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *, int);
@@ -201,17 +202,14 @@ extern void cifs_unix_basic_to_fattr(struct cifs_fattr *fattr,
201202
struct cifs_sb_info *cifs_sb);
202203
extern void cifs_dir_info_to_fattr(struct cifs_fattr *, FILE_DIRECTORY_INFO *,
203204
struct cifs_sb_info *);
204-
extern int cifs_fattr_to_inode(struct inode *inode, struct cifs_fattr *fattr);
205+
extern int cifs_fattr_to_inode(struct inode *inode, struct cifs_fattr *fattr,
206+
bool from_readdir);
205207
extern struct inode *cifs_iget(struct super_block *sb,
206208
struct cifs_fattr *fattr);
207209

208210
int cifs_get_inode_info(struct inode **inode, const char *full_path,
209211
struct cifs_open_info_data *data, struct super_block *sb, int xid,
210212
const struct cifs_fid *fid);
211-
bool cifs_reparse_point_to_fattr(struct cifs_sb_info *cifs_sb,
212-
struct cifs_fattr *fattr,
213-
struct cifs_open_info_data *data);
214-
215213
extern int smb311_posix_get_inode_info(struct inode **inode,
216214
const char *full_path,
217215
struct cifs_open_info_data *data,
@@ -296,6 +294,10 @@ extern void cifs_close_all_deferred_files(struct cifs_tcon *cifs_tcon);
296294

297295
extern void cifs_close_deferred_file_under_dentry(struct cifs_tcon *cifs_tcon,
298296
const char *path);
297+
298+
extern void cifs_mark_open_handles_for_deleted_file(struct inode *inode,
299+
const char *path);
300+
299301
extern struct TCP_Server_Info *
300302
cifs_get_tcp_session(struct smb3_fs_context *ctx,
301303
struct TCP_Server_Info *primary_server);
@@ -402,7 +404,8 @@ extern int CIFSSMBSetFileDisposition(const unsigned int xid,
402404
__u32 pid_of_opener);
403405
extern int CIFSSMBSetEOF(const unsigned int xid, struct cifs_tcon *tcon,
404406
const char *file_name, __u64 size,
405-
struct cifs_sb_info *cifs_sb, bool set_allocation);
407+
struct cifs_sb_info *cifs_sb, bool set_allocation,
408+
struct dentry *dentry);
406409
extern int CIFSSMBSetFileSize(const unsigned int xid, struct cifs_tcon *tcon,
407410
struct cifsFileInfo *cfile, __u64 size,
408411
bool set_allocation);
@@ -438,7 +441,8 @@ extern int CIFSPOSIXDelFile(const unsigned int xid, struct cifs_tcon *tcon,
438441
const struct nls_table *nls_codepage,
439442
int remap_special_chars);
440443
extern int CIFSSMBDelFile(const unsigned int xid, struct cifs_tcon *tcon,
441-
const char *name, struct cifs_sb_info *cifs_sb);
444+
const char *name, struct cifs_sb_info *cifs_sb,
445+
struct dentry *dentry);
442446
int CIFSSMBRename(const unsigned int xid, struct cifs_tcon *tcon,
443447
struct dentry *source_dentry,
444448
const char *from_name, const char *to_name,

fs/smb/client/cifssmb.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -738,7 +738,7 @@ CIFSPOSIXDelFile(const unsigned int xid, struct cifs_tcon *tcon,
738738

739739
int
740740
CIFSSMBDelFile(const unsigned int xid, struct cifs_tcon *tcon, const char *name,
741-
struct cifs_sb_info *cifs_sb)
741+
struct cifs_sb_info *cifs_sb, struct dentry *dentry)
742742
{
743743
DELETE_FILE_REQ *pSMB = NULL;
744744
DELETE_FILE_RSP *pSMBr = NULL;
@@ -4993,7 +4993,7 @@ CIFSSMBQFSPosixInfo(const unsigned int xid, struct cifs_tcon *tcon,
49934993
int
49944994
CIFSSMBSetEOF(const unsigned int xid, struct cifs_tcon *tcon,
49954995
const char *file_name, __u64 size, struct cifs_sb_info *cifs_sb,
4996-
bool set_allocation)
4996+
bool set_allocation, struct dentry *dentry)
49974997
{
49984998
struct smb_com_transaction2_spi_req *pSMB = NULL;
49994999
struct smb_com_transaction2_spi_rsp *pSMBr = NULL;

fs/smb/client/connect.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1736,7 +1736,7 @@ cifs_get_tcp_session(struct smb3_fs_context *ctx,
17361736
tcp_ses->channel_sequence_num = 0; /* only tracked for primary channel */
17371737
tcp_ses->reconnect_instance = 1;
17381738
tcp_ses->lstrp = jiffies;
1739-
tcp_ses->compress_algorithm = cpu_to_le16(ctx->compression);
1739+
tcp_ses->compression.requested = ctx->compress;
17401740
spin_lock_init(&tcp_ses->req_lock);
17411741
spin_lock_init(&tcp_ses->srv_lock);
17421742
spin_lock_init(&tcp_ses->mid_lock);
@@ -2803,6 +2803,8 @@ compare_mount_options(struct super_block *sb, struct cifs_mnt_data *mnt_data)
28032803
return 0;
28042804
if (old->ctx->closetimeo != new->ctx->closetimeo)
28052805
return 0;
2806+
if (old->ctx->reparse_type != new->ctx->reparse_type)
2807+
return 0;
28062808

28072809
return 1;
28082810
}

0 commit comments

Comments
 (0)