All of lore.kernel.org
 help / color / mirror / Atom feed
* Detailed analysis of how tree connect state is handled in cifs.ko
@ 2022-03-29  5:12 Steve French
  0 siblings, 0 replies; only message in thread
From: Steve French @ 2022-03-29  5:12 UTC (permalink / raw)
  To: CIFS; +Cc: Shyam Prasad N

Did a detailed analysis of the 24 functions where we set or check the
tcon status (or need_reconnect).   Detailed analysis below.  There is
some overlap between TID_NEED_RECON and need_reconnect,
but generally the "TID_NEED_RECON" and "TID_NEED_FILES_INVALIDATE"
status are set more
generally by the equivalent boolean, but other status changes are
handled by the tid status enum.

Eight tree connect struct status values are defined for tcon->status
cifsglob.h:122: TID_NEW = 0,
cifsglob.h:123: TID_GOOD,
cifsglob.h:124: TID_EXITING,
cifsglob.h:125: TID_NEED_RECON,
cifsglob.h:126: TID_NEED_TCON,
cifsglob.h:127: TID_IN_TCON,
cifsglob.h:128: TID_NEED_FILES_INVALIDATE, /* currently unused */
cifsglob.h:129: TID_IN_FILES_INVALIDATE

and also a partially overlapping bool tcon->need_reconnect is defined,
and another one called tcon->need_reopen_files

The 23 functions which set or check these statuses are listed below:

1) cifs_umount_begin()
checks if other umount in progress, holds tcp_ses_lock
cifsfs.c:702: if ((tcon->tc_count > 1) || (tcon->status == TID_EXITING)) {
cifsfs.c:709: tcon->status = TID_EXITING;

2) cifs_mark_open_files_invalid()
holds tcp_set_lock
returns if TID_NEED_RECON already set, or if session status not CifsGood
otherwise sets TID_IN_FILES_INVALIDATE, marks the files as invalidHandle
unlocks then locks again to check if TID_IN_FILES_INVALIDATE is still set
then sets TID_NEED_TCON.  May be missing call to invalidate inodes on the sb
cifssmb.c:82: tcon->status = TID_IN_FILES_INVALIDATE;
cifssmb.c:102: if (tcon->status == TID_IN_FILES_INVALIDATE)
cifssmb.c:103: tcon->status = TID_NEED_TCON;

3) cifs_reconnect_tcon()
if TID_EXITING then doesn't allow Write or Open or Tree Disconnect
to be sent (holding tcp_ses_lock), and later it checks tcon->need_reconnect
(and exits without sending the tcon if it is not set).
Before sending negotiate, it checks if chan_needs_reconnect is not set
but no tcon needs to be sent (tcon->need_reconnect not set). And finally
after session setup (if it needed to be sent), before sending the tcon
(and marking the open files invalid) it checks need_reconnect once more
to see if it is really needed
cifssmb.c:138: if (tcon->status == TID_EXITING) {
cifssmb.c:191: if (!cifs_chan_needs_reconnect(ses, server) &&
!tcon->need_reconnect) {
cifssmb.c:221: if (tcon->need_reconnect)
cifssmb.c:235: if (rc || !tcon->need_reconnect) {

4) smb_init_no_reconnect()
if tcon->need_reconnect set then it doesn't do the __smb_init and
just returns EHOSTDOWN
cifssmb.c:382:     tcon->need_reconnect) {

5) CIFSSMBTDis()
while holding the chan lock it sees if tcon->need_reconnect and
if so returns EIO instead of sending the tree disconnect
cifssmb.c:650: if ((tcon->need_reconnect) ||
CIFS_ALL_CHANS_NEED_RECONNECT(tcon->ses)) {

6) cifs_mark_tcp_ses_conns_for_reconnect()
while holding tcp_ses_lock marks all ses structs as CifsNeedReconnect
and also marks all of the tcon structs they contain as TID_NEED_RECON
and need_reconnect
connect.c:247: tcon->need_reconnect = true;
connect.c:248: tcon->status = TID_NEED_RECON;
connect.c:251: ses->tcon_ipc->need_reconnect = true;


7) match_tcon()
Returns immediately (no match) if TID_EXITING set
connect.c:2210: if (tcon->status == TID_EXITING)

8) __tree_connect_dfs_target()
If ipc$ needs reconnect it connects that before doing the DFS share connect
connect.c:4402: if (ipc->need_reconnect) {

9) cifs_tree_connect()   [DFS enabled version]
While holding tcp_ses_lock sets tcon status as TID_IN_TCON
and if tree connect fails, sets tcon status again as TID_NEED_TCON
else if status is still TID_IN_TCON (presumably to see if reconnect
occurred after tcon in other thread) sets TID_GOOD and also
sets tcon->need_reconnect false
(holding the tcp_ses_lock)
connect.c:4494: tcon->status = TID_IN_TCON;
connect.c:4535: if (tcon->status == TID_IN_TCON)
connect.c:4536: tcon->status = TID_NEED_TCON;
connect.c:4540: if (tcon->status == TID_IN_TCON)
connect.c:4541: tcon->status = TID_GOOD;
connect.c:4543: tcon->need_reconnect = false;

10) cifs_tree_connect()  [non-DFS version]
similar logic to above other version of cifs_tree_connect
connect.c:4562: tcon->status = TID_IN_TCON;
connect.c:4568: if (tcon->status == TID_IN_TCON)
connect.c:4569: tcon->status = TID_NEED_TCON;
connect.c:4573: if (tcon->status == TID_IN_TCON)
connect.c:4574: tcon->status = TID_GOOD;
connect.c:4576: tcon->need_reconnect = false;

11) tconInfoAlloc()
sets TID_NEW when tcon buffer created, no lock needed since not in list yet
misc.c:119: ret_buf->status = TID_NEW;

12) smb2_compound_op()
if error EREMCHG returned from sending compound op then set need_reconnect
(EREMCHG is mapped from STATUS_NETWORK_NAME_DELETED)
smb2inode.c:384: tcon->need_reconnect = true;

13) open_cached_dir()
if error EREMCHG returned from sending compound op then set need_reconnect
smb2ops.c:890: tcon->need_reconnect = true;

14) smb2_is_network_name_deleted()
if STATUS_NETWORK_NAME_DELETED then set need_reconnect to true
(can be called from demultiplex_thread on error e.g.)
smb2ops.c:2541: tcon->need_reconnect = true;

15) smb2_query_info_compound()
similar to the above 3 examples
smb2ops.c:2746: tcon->need_reconnect = true;

16) smb2_reconnect()
checks if TID_EXITING, if so doesn't allow WRITE, CREATE, or TDIS
if tcon->need_reconnect not needed will return 0 (early)
if chan_needs_reconnect_not_set and tcon->need_reconnect can
skip session session setup, and finally just before marking files
invalid (and setting need_reopen_files to true) and sending the
tree_connect if tcon->need_reconnect not set then can exit
without having to send the tcon
smb2pdu.c:166: if (tcon->status == TID_EXITING) {
smb2pdu.c:243: if (!cifs_chan_needs_reconnect(ses, server) &&
!tcon->need_reconnect) {
smb2pdu.c:250: cifs_dbg(FYI, "tcon reconnect: %d", tcon->need_reconnect);
smb2pdu.c:276: if (tcon->need_reconnect)
smb2pdu.c:300: if (!tcon->need_reconnect) {
smb2pdu.c:306:          tcon->need_reopen_files = true;

17) SMB2_tcon()
if sending tree connect failed mark tcon->need_reconnect as true
smb2pdu.c:1891: tcon->need_reconnect = true;

18) SMB2_tdis()
If need_reconnect set, no need to send tree disconnect request
smb2pdu.c:1961: if ((tcon->need_reconnect) ||

19) SMB2_open()
if error EREMCHG (STATUS_NETWORK_NAME_DELETED) returned from open
then set need_reconnect to true
smb2pdu.c:3003: tcon->need_reconnect = true;

20) smb2_reconnect_server()
tcons with need_reconnect or need_reopen_files set are added to
tmp_list with the tcon->rlist (the tree connection's reconnect list).
Then allocates a dummy tcon used for reconnect, and sets it to TID_GOOD,
and its need_reconnect to false then frees it (doesn't hold
tcp_ses_lock but probably not needed)
smb2pdu.c:3799: if (tcon->need_reconnect || tcon->need_reopen_files) {
smb2pdu.c:3809: if (ses->tcon_ipc && ses->tcon_ipc->need_reconnect) {
smb2pdu.c:3863: tcon->status = TID_GOOD;
smb2pdu.c:3865: tcon->need_reconnect = false;

21) cifs_debug_tcon() and cifs_stats_proc_show()
Prints DISCONNECTED if need_reconnect is set to aid debugging
cifs_debug.c:120: if (tcon->need_reconnect)
cifs_debug.c:624: if (tcon->need_reconnect)

22) refresh_mounts()
goes through all sockets, servers and tcons, and if tcon doesn't
need_reconnect then adds it to tail of cache update list (tcon->ulist)
dfs_cache.c:1518: if (!tcon->ipc && !tcon->need_reconnect) {

23) _cifsFileInfo_put()
if tcon->need_reconnect set then don't need to close the file
file.c:489: if (!tcon->need_reconnect && !cifs_file->invalidHandle) {

24) cifs_reopen_persistent_handles()
if need_reopen_files set then returns immediately, else sets
need_reopen_files to false
(unless error returned reopening a file)
file.c:936:     if (!tcon->use_persistent || !tcon->need_reopen_files)
file.c:939:     tcon->need_reopen_files = false;
file.c:958:                     tcon->need_reopen_files = true;

-- 
Thanks,

Steve

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2022-03-29  5:12 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-03-29  5:12 Detailed analysis of how tree connect state is handled in cifs.ko Steve French

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.