Skip to content

Commit ac34bb4

Browse files
committed
Merge tag 'v6.12-rc-smb3-client-fixes-part2' of git://git.samba.org/sfrench/cifs-2.6
Pull smb client fixes from Steve French: "Most are from the recent SMB3.1.1 test event, and also an important netfs fix for a cifs mtime write regression - fix mode reported by stat of readonly directories and files - DFS (global namespace) related fixes - fixes for special file support via reparse points - mount improvement and reconnect fix - fix for noisy log message on umount - two netfs related fixes, one fixing a recent regression, and add new write tracepoint" * tag 'v6.12-rc-smb3-client-fixes-part2' of git://git.samba.org/sfrench/cifs-2.6: netfs, cifs: Fix mtime/ctime update for mmapped writes cifs: update internal version number smb: client: print failed session logoffs with FYI cifs: Fix reversion of the iter in cifs_readv_receive(). smb3: fix incorrect mode displayed for read-only files smb: client: fix parsing of device numbers smb: client: set correct device number on nfs reparse points smb: client: propagate error from cifs_construct_tcon() smb: client: fix DFS failover in multiuser mounts cifs: Make the write_{enter,done,err} tracepoints display netfs info smb: client: fix DFS interlink failover smb: client: improve purging of cached referrals smb: client: avoid unnecessary reconnects when refreshing referrals
2 parents 5159938 + 665db14 commit ac34bb4

File tree

18 files changed

+282
-224
lines changed

18 files changed

+282
-224
lines changed

fs/netfs/buffered_write.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -552,6 +552,7 @@ vm_fault_t netfs_page_mkwrite(struct vm_fault *vmf, struct netfs_group *netfs_gr
552552
trace_netfs_folio(folio, netfs_folio_trace_mkwrite);
553553
netfs_set_group(folio, netfs_group);
554554
file_update_time(file);
555+
set_bit(NETFS_ICTX_MODIFIED_ATTR, &ictx->flags);
555556
if (ictx->ops->post_modify)
556557
ictx->ops->post_modify(inode);
557558
ret = VM_FAULT_LOCKED;

fs/smb/client/cifsfs.h

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

148148
/* when changing internal version - update following two lines at same time */
149-
#define SMB3_PRODUCT_BUILD 50
150-
#define CIFS_VERSION "2.50"
149+
#define SMB3_PRODUCT_BUILD 51
150+
#define CIFS_VERSION "2.51"
151151
#endif /* _CIFSFS_H */

fs/smb/client/cifsglob.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -821,6 +821,7 @@ struct TCP_Server_Info {
821821
* format: \\HOST\SHARE[\OPTIONAL PATH]
822822
*/
823823
char *leaf_fullpath;
824+
bool dfs_conn:1;
824825
};
825826

826827
static inline bool is_smb1(struct TCP_Server_Info *server)
@@ -1059,6 +1060,7 @@ struct cifs_ses {
10591060
struct list_head smb_ses_list;
10601061
struct list_head rlist; /* reconnect list */
10611062
struct list_head tcon_list;
1063+
struct list_head dlist; /* dfs list */
10621064
struct cifs_tcon *tcon_ipc;
10631065
spinlock_t ses_lock; /* protect anything here that is not protected */
10641066
struct mutex session_mutex;
@@ -1287,6 +1289,7 @@ struct cifs_tcon {
12871289
/* BB add field for back pointer to sb struct(s)? */
12881290
#ifdef CONFIG_CIFS_DFS_UPCALL
12891291
struct delayed_work dfs_cache_work;
1292+
struct list_head dfs_ses_list;
12901293
#endif
12911294
struct delayed_work query_interfaces; /* query interfaces workqueue job */
12921295
char *origin_fullpath; /* canonical copy of smb3_fs_context::source */

fs/smb/client/cifsproto.h

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -724,15 +724,9 @@ static inline int cifs_create_options(struct cifs_sb_info *cifs_sb, int options)
724724

725725
int cifs_wait_for_server_reconnect(struct TCP_Server_Info *server, bool retry);
726726

727-
/* Put references of @ses and its children */
728727
static inline void cifs_put_smb_ses(struct cifs_ses *ses)
729728
{
730-
struct cifs_ses *next;
731-
732-
do {
733-
next = ses->dfs_root_ses;
734-
__cifs_put_smb_ses(ses);
735-
} while ((ses = next));
729+
__cifs_put_smb_ses(ses);
736730
}
737731

738732
/* Get an active reference of @ses and its children.
@@ -746,9 +740,7 @@ static inline void cifs_put_smb_ses(struct cifs_ses *ses)
746740
static inline void cifs_smb_ses_inc_refcount(struct cifs_ses *ses)
747741
{
748742
lockdep_assert_held(&cifs_tcp_ses_lock);
749-
750-
for (; ses; ses = ses->dfs_root_ses)
751-
ses->ses_count++;
743+
ses->ses_count++;
752744
}
753745

754746
static inline bool dfs_src_pathname_equal(const char *s1, const char *s2)

fs/smb/client/connect.c

Lines changed: 32 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -811,13 +811,9 @@ cifs_read_iter_from_socket(struct TCP_Server_Info *server, struct iov_iter *iter
811811
unsigned int to_read)
812812
{
813813
struct msghdr smb_msg = { .msg_iter = *iter };
814-
int ret;
815814

816815
iov_iter_truncate(&smb_msg.msg_iter, to_read);
817-
ret = cifs_readv_from_socket(server, &smb_msg);
818-
if (ret > 0)
819-
iov_iter_advance(iter, ret);
820-
return ret;
816+
return cifs_readv_from_socket(server, &smb_msg);
821817
}
822818

823819
static bool
@@ -1530,6 +1526,9 @@ static int match_server(struct TCP_Server_Info *server,
15301526
if (server->nosharesock)
15311527
return 0;
15321528

1529+
if (!match_super && (ctx->dfs_conn || server->dfs_conn))
1530+
return 0;
1531+
15331532
/* If multidialect negotiation see if existing sessions match one */
15341533
if (strcmp(ctx->vals->version_string, SMB3ANY_VERSION_STRING) == 0) {
15351534
if (server->vals->protocol_id < SMB30_PROT_ID)
@@ -1723,6 +1722,7 @@ cifs_get_tcp_session(struct smb3_fs_context *ctx,
17231722

17241723
if (ctx->nosharesock)
17251724
tcp_ses->nosharesock = true;
1725+
tcp_ses->dfs_conn = ctx->dfs_conn;
17261726

17271727
tcp_ses->ops = ctx->ops;
17281728
tcp_ses->vals = ctx->vals;
@@ -1873,13 +1873,15 @@ cifs_get_tcp_session(struct smb3_fs_context *ctx,
18731873
}
18741874

18751875
/* this function must be called with ses_lock and chan_lock held */
1876-
static int match_session(struct cifs_ses *ses, struct smb3_fs_context *ctx)
1876+
static int match_session(struct cifs_ses *ses,
1877+
struct smb3_fs_context *ctx,
1878+
bool match_super)
18771879
{
18781880
if (ctx->sectype != Unspecified &&
18791881
ctx->sectype != ses->sectype)
18801882
return 0;
18811883

1882-
if (ctx->dfs_root_ses != ses->dfs_root_ses)
1884+
if (!match_super && ctx->dfs_root_ses != ses->dfs_root_ses)
18831885
return 0;
18841886

18851887
/*
@@ -1998,7 +2000,7 @@ cifs_find_smb_ses(struct TCP_Server_Info *server, struct smb3_fs_context *ctx)
19982000
continue;
19992001
}
20002002
spin_lock(&ses->chan_lock);
2001-
if (match_session(ses, ctx)) {
2003+
if (match_session(ses, ctx, false)) {
20022004
spin_unlock(&ses->chan_lock);
20032005
spin_unlock(&ses->ses_lock);
20042006
ret = ses;
@@ -2058,8 +2060,7 @@ void __cifs_put_smb_ses(struct cifs_ses *ses)
20582060
if (do_logoff) {
20592061
xid = get_xid();
20602062
rc = server->ops->logoff(xid, ses);
2061-
if (rc)
2062-
cifs_server_dbg(VFS, "%s: Session Logoff failure rc=%d\n",
2063+
cifs_server_dbg(FYI, "%s: Session Logoff: rc=%d\n",
20632064
__func__, rc);
20642065
_free_xid(xid);
20652066
}
@@ -2382,8 +2383,6 @@ cifs_get_smb_ses(struct TCP_Server_Info *server, struct smb3_fs_context *ctx)
23822383
* need to lock before changing something in the session.
23832384
*/
23842385
spin_lock(&cifs_tcp_ses_lock);
2385-
if (ctx->dfs_root_ses)
2386-
cifs_smb_ses_inc_refcount(ctx->dfs_root_ses);
23872386
ses->dfs_root_ses = ctx->dfs_root_ses;
23882387
list_add(&ses->smb_ses_list, &server->smb_ses_list);
23892388
spin_unlock(&cifs_tcp_ses_lock);
@@ -2458,6 +2457,7 @@ cifs_put_tcon(struct cifs_tcon *tcon, enum smb3_tcon_ref_trace trace)
24582457
{
24592458
unsigned int xid;
24602459
struct cifs_ses *ses;
2460+
LIST_HEAD(ses_list);
24612461

24622462
/*
24632463
* IPC tcon share the lifetime of their session and are
@@ -2482,6 +2482,9 @@ cifs_put_tcon(struct cifs_tcon *tcon, enum smb3_tcon_ref_trace trace)
24822482

24832483
list_del_init(&tcon->tcon_list);
24842484
tcon->status = TID_EXITING;
2485+
#ifdef CONFIG_CIFS_DFS_UPCALL
2486+
list_replace_init(&tcon->dfs_ses_list, &ses_list);
2487+
#endif
24852488
spin_unlock(&tcon->tc_lock);
24862489
spin_unlock(&cifs_tcp_ses_lock);
24872490

@@ -2509,6 +2512,9 @@ cifs_put_tcon(struct cifs_tcon *tcon, enum smb3_tcon_ref_trace trace)
25092512
cifs_fscache_release_super_cookie(tcon);
25102513
tconInfoFree(tcon, netfs_trace_tcon_ref_free);
25112514
cifs_put_smb_ses(ses);
2515+
#ifdef CONFIG_CIFS_DFS_UPCALL
2516+
dfs_put_root_smb_sessions(&ses_list);
2517+
#endif
25122518
}
25132519

25142520
/**
@@ -2892,7 +2898,7 @@ cifs_match_super(struct super_block *sb, void *data)
28922898
spin_lock(&ses->chan_lock);
28932899
spin_lock(&tcon->tc_lock);
28942900
if (!match_server(tcp_srv, ctx, true) ||
2895-
!match_session(ses, ctx) ||
2901+
!match_session(ses, ctx, true) ||
28962902
!match_tcon(tcon, ctx) ||
28972903
!match_prepath(sb, tcon, mnt_data)) {
28982904
rc = 0;
@@ -3623,13 +3629,12 @@ int cifs_is_path_remote(struct cifs_mount_ctx *mnt_ctx)
36233629
int cifs_mount(struct cifs_sb_info *cifs_sb, struct smb3_fs_context *ctx)
36243630
{
36253631
struct cifs_mount_ctx mnt_ctx = { .cifs_sb = cifs_sb, .fs_ctx = ctx, };
3626-
bool isdfs;
36273632
int rc;
36283633

3629-
rc = dfs_mount_share(&mnt_ctx, &isdfs);
3634+
rc = dfs_mount_share(&mnt_ctx);
36303635
if (rc)
36313636
goto error;
3632-
if (!isdfs)
3637+
if (!ctx->dfs_conn)
36333638
goto out;
36343639

36353640
/*
@@ -4034,7 +4039,7 @@ cifs_set_vol_auth(struct smb3_fs_context *ctx, struct cifs_ses *ses)
40344039
}
40354040

40364041
static struct cifs_tcon *
4037-
__cifs_construct_tcon(struct cifs_sb_info *cifs_sb, kuid_t fsuid)
4042+
cifs_construct_tcon(struct cifs_sb_info *cifs_sb, kuid_t fsuid)
40384043
{
40394044
int rc;
40404045
struct cifs_tcon *master_tcon = cifs_sb_master_tcon(cifs_sb);
@@ -4132,17 +4137,6 @@ __cifs_construct_tcon(struct cifs_sb_info *cifs_sb, kuid_t fsuid)
41324137
return tcon;
41334138
}
41344139

4135-
static struct cifs_tcon *
4136-
cifs_construct_tcon(struct cifs_sb_info *cifs_sb, kuid_t fsuid)
4137-
{
4138-
struct cifs_tcon *ret;
4139-
4140-
cifs_mount_lock();
4141-
ret = __cifs_construct_tcon(cifs_sb, fsuid);
4142-
cifs_mount_unlock();
4143-
return ret;
4144-
}
4145-
41464140
struct cifs_tcon *
41474141
cifs_sb_master_tcon(struct cifs_sb_info *cifs_sb)
41484142
{
@@ -4212,9 +4206,9 @@ tlink_rb_insert(struct rb_root *root, struct tcon_link *new_tlink)
42124206
struct tcon_link *
42134207
cifs_sb_tlink(struct cifs_sb_info *cifs_sb)
42144208
{
4215-
int ret;
4216-
kuid_t fsuid = current_fsuid();
42174209
struct tcon_link *tlink, *newtlink;
4210+
kuid_t fsuid = current_fsuid();
4211+
int err;
42184212

42194213
if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MULTIUSER))
42204214
return cifs_get_tlink(cifs_sb_master_tlink(cifs_sb));
@@ -4249,9 +4243,9 @@ cifs_sb_tlink(struct cifs_sb_info *cifs_sb)
42494243
spin_unlock(&cifs_sb->tlink_tree_lock);
42504244
} else {
42514245
wait_for_construction:
4252-
ret = wait_on_bit(&tlink->tl_flags, TCON_LINK_PENDING,
4246+
err = wait_on_bit(&tlink->tl_flags, TCON_LINK_PENDING,
42534247
TASK_INTERRUPTIBLE);
4254-
if (ret) {
4248+
if (err) {
42554249
cifs_put_tlink(tlink);
42564250
return ERR_PTR(-ERESTARTSYS);
42574251
}
@@ -4262,8 +4256,9 @@ cifs_sb_tlink(struct cifs_sb_info *cifs_sb)
42624256

42634257
/* return error if we tried this already recently */
42644258
if (time_before(jiffies, tlink->tl_time + TLINK_ERROR_EXPIRE)) {
4259+
err = PTR_ERR(tlink->tl_tcon);
42654260
cifs_put_tlink(tlink);
4266-
return ERR_PTR(-EACCES);
4261+
return ERR_PTR(err);
42674262
}
42684263

42694264
if (test_and_set_bit(TCON_LINK_PENDING, &tlink->tl_flags))
@@ -4275,8 +4270,11 @@ cifs_sb_tlink(struct cifs_sb_info *cifs_sb)
42754270
wake_up_bit(&tlink->tl_flags, TCON_LINK_PENDING);
42764271

42774272
if (IS_ERR(tlink->tl_tcon)) {
4273+
err = PTR_ERR(tlink->tl_tcon);
4274+
if (err == -ENOKEY)
4275+
err = -EACCES;
42784276
cifs_put_tlink(tlink);
4279-
return ERR_PTR(-EACCES);
4277+
return ERR_PTR(err);
42804278
}
42814279

42824280
return tlink;

0 commit comments

Comments
 (0)