From 951e61cc629996d4bc8aee4cd4aee60556a30565 Mon Sep 17 00:00:00 2001 From: Olaf Barthel Date: Tue, 22 May 2018 12:34:02 +0200 Subject: [PATCH] Updated to version 1.136 Please keep in mind that this is still a development version and might surprise you (not necessarily in a good way). Do not let me discourage you to build and test this version, although there will be some risks involved such as data corruption or loss of data. --- documentation/history.doc | 11 +++ source_code/include/smb/smb.h | 4 +- source_code/proc.c | 124 +++++++++++++++++++++++++++++++--- source_code/smb_abstraction.c | 6 +- source_code/smbfs_rev.h | 10 +-- source_code/smbfs_rev.rev | 2 +- source_code/sock.c | 4 ++ 7 files changed, 141 insertions(+), 20 deletions(-) diff --git a/documentation/history.doc b/documentation/history.doc index d8851b1..8436612 100644 --- a/documentation/history.doc +++ b/documentation/history.doc @@ -1649,3 +1649,14 @@ smbfs 1.135 (21.5.2018) restrictions as the read and write operations. Should the server communication fail because of a timeout, reestablishing a connection to the server should no longer hang indefinitely. + + +smbfs 1.136 (22.5.2018) + +- The network connection opened for the server now has the + "keepalive" option enabled, just in case... + +- Looks like reconnecting to the server after that connection + broke down or was severed never actually worked for read, write, + record locking and file attribute operations. Now it might + just work... diff --git a/source_code/include/smb/smb.h b/source_code/include/smb/smb.h index 23b54a1..08405e8 100644 --- a/source_code/include/smb/smb.h +++ b/source_code/include/smb/smb.h @@ -63,7 +63,6 @@ struct smb_dskattr */ struct smb_dirent { - int opened; /* is it open on the fileserver? */ word fileid; /* What id to handle a file with? */ dword attr; /* Attribute fields, DOS value */ @@ -77,6 +76,9 @@ struct smb_dirent char * complete_path; /* Complete path, MS-DOS notation, with '\' */ size_t complete_path_size; /* Number of bytes allocated for name */ int len; /* Namelength. */ + + unsigned opened:1; /* is it open on the fileserver? */ + unsigned writable:1; /* was opened for read/write access? */ }; #endif /* _LINUX_SMB_H */ diff --git a/source_code/proc.c b/source_code/proc.c index 4515126..6b5700f 100644 --- a/source_code/proc.c +++ b/source_code/proc.c @@ -840,6 +840,32 @@ smb_request_ok (struct smb_server *s, int command, int wct, int bcc, int * error return(smb_request_ok_with_payload (s, command, wct, bcc, NULL, NULL, 0, error_ptr)); } +/* Try to reopen a file after the server has dropped the connection, or + * was disconnected. + */ +static int +reopen_entry(struct smb_server *server, struct smb_dirent *entry,int * error_ptr) +{ + int result; + + ASSERT( server != NULL && entry != NULL ); + + if(!entry->opened) + { + int ignored_error; + + LOG (("trying to reopen file %s\n", entry->complete_path)); + + result = smb_proc_open (server, entry->complete_path, entry->len, entry->writable, FALSE, entry, error_ptr != NULL ? error_ptr : &ignored_error); + } + else + { + result = 0; + } + + return(result); +} + /* smb_retry: This function should be called when smb_request_ok has * indicated an error. If the error was indicated because the * connection was killed, we try to reconnect. If smb_retry returns FALSE, @@ -1092,6 +1118,7 @@ smb_proc_open (struct smb_server *server, const char *pathname, int len, int wri entry->size = end_of_file_low; entry->opened = TRUE; + entry->writable = writable; goto out; } @@ -1149,6 +1176,7 @@ smb_proc_open (struct smb_server *server, const char *pathname, int len, int wri entry->ctime = entry->atime = entry->mtime = entry->wtime = local2utc (DVAL (buf, smb_vwv2)); entry->size = DVAL (buf, smb_vwv4); entry->opened = TRUE; + entry->writable = writable; out: @@ -1210,9 +1238,21 @@ smb_proc_read (struct smb_server *server, struct smb_dirent *finfo, off_t offset if (result < 0) { if (smb_retry (server)) - goto retry; + { + if(reopen_entry(server,finfo,NULL) < 0) + { + LOG(("that didn't work.\n")); + goto out; + } + else + { + goto retry; + } + } else + { goto out; + } } /* The buffer format must be 1; smb_request_ok_with_payload() already checked this. */ @@ -1255,7 +1295,12 @@ smb_proc_read_raw (struct smb_server *server, struct smb_dirent *finfo, off_t of if (result < 0) { if (smb_retry (server)) - goto retry; + { + if(reopen_entry(server,finfo,NULL) < 0) + LOG(("that didn't work.\n")); + else + goto retry; + } } return result; @@ -1285,7 +1330,12 @@ smb_proc_write (struct smb_server *server, struct smb_dirent *finfo, off_t offse if (result < 0) { if (smb_retry (server)) - goto retry; + { + if(reopen_entry(server,finfo,NULL) < 0) + LOG(("that didn't work.\n")); + else + goto retry; + } } else { @@ -1388,9 +1438,21 @@ smb_proc_write_raw (struct smb_server *server, struct smb_dirent *finfo, off_t o if (result < 0) { if (smb_retry (server)) - goto retry; + { + if(reopen_entry(server,finfo,NULL) < 0) + { + LOG(("that didn't work.\n")); + goto out; + } + else + { + goto retry; + } + } else + { goto out; + } } num_bytes_written += len; @@ -1416,9 +1478,21 @@ smb_proc_write_raw (struct smb_server *server, struct smb_dirent *finfo, off_t o count += len; if (smb_retry (server)) - goto retry; + { + if(reopen_entry(server,finfo,NULL) < 0) + { + LOG(("that didn't work.\n")); + goto out; + } + else + { + goto retry; + } + } else + { goto out; + } } if(server->write_behind) @@ -1511,7 +1585,12 @@ smb_proc_writex (struct smb_server *server, struct smb_dirent *finfo, off_t offs if (result < 0) { if (smb_retry (server)) - goto retry; + { + if(reopen_entry(server,finfo,NULL) < 0) + LOG(("that didn't work.\n")); + else + goto retry; + } } else { @@ -1565,7 +1644,12 @@ smb_proc_readx (struct smb_server *server, struct smb_dirent *finfo, off_t offse if (result < 0) { if (smb_retry (server)) - goto retry; + { + if(reopen_entry(server,finfo,NULL) < 0) + LOG(("that didn't work.\n")); + else + goto retry; + } } else { @@ -1625,7 +1709,12 @@ smb_proc_lockingX (struct smb_server *server, struct smb_dirent *finfo, struct s if (result < 0) { if (smb_retry (server)) - goto retry; + { + if(reopen_entry(server,finfo,NULL) < 0) + LOG(("that didn't work.\n")); + else + goto retry; + } } return result; @@ -2995,7 +3084,17 @@ smb_set_file_information(struct smb_server *server, struct smb_dirent *entry, co if((*error_ptr) != error_check_smb_error) { if (smb_retry (server)) - goto retry; + { + if(reopen_entry(server,entry,NULL) < 0) + { + LOG(("that didn't work.\n")); + goto out; + } + else + { + goto retry; + } + } } goto out; @@ -3077,7 +3176,12 @@ smb_proc_setattrE (struct smb_server *server, word fid, struct smb_dirent *new_e if (result < 0) { if (smb_retry (server)) - goto retry; + { + if(reopen_entry(server,new_entry,NULL) < 0) + LOG(("that didn't work.\n")); + else + goto retry; + } } return result; diff --git a/source_code/smb_abstraction.c b/source_code/smb_abstraction.c index 78a4562..aa105a7 100644 --- a/source_code/smb_abstraction.c +++ b/source_code/smb_abstraction.c @@ -56,8 +56,8 @@ struct smba_file struct smb_dirent dirent; ULONG attr_time; /* time when dirent was read */ dircache_t * dircache; /* content cache for directories */ - unsigned attr_dirty:1; /* attribute cache is dirty */ unsigned is_valid:1; /* server was down, entry removed, ... */ + unsigned attr_dirty:1; /* attribute cache is dirty */ }; /*****************************************************************************/ @@ -1461,8 +1461,8 @@ smb_invalidate_all_inodes (struct smb_server *server) f->node.mln_Succ != NULL; f = (smba_file_t *)f->node.mln_Succ) { - f->dirent.opened = FALSE; - f->is_valid = FALSE; + f->dirent.opened = FALSE; + f->is_valid = FALSE; } } diff --git a/source_code/smbfs_rev.h b/source_code/smbfs_rev.h index 1d409ef..d051a1d 100644 --- a/source_code/smbfs_rev.h +++ b/source_code/smbfs_rev.h @@ -1,6 +1,6 @@ #define VERSION 1 -#define REVISION 135 -#define DATE "21.5.2018" -#define VERS "smbfs 1.135" -#define VSTRING "smbfs 1.135 (21.5.2018)\r\n" -#define VERSTAG "\0$VER: smbfs 1.135 (21.5.2018)" +#define REVISION 136 +#define DATE "22.5.2018" +#define VERS "smbfs 1.136" +#define VSTRING "smbfs 1.136 (22.5.2018)\r\n" +#define VERSTAG "\0$VER: smbfs 1.136 (22.5.2018)" diff --git a/source_code/smbfs_rev.rev b/source_code/smbfs_rev.rev index c8b255f..7296f25 100644 --- a/source_code/smbfs_rev.rev +++ b/source_code/smbfs_rev.rev @@ -1 +1 @@ -135 +136 diff --git a/source_code/sock.c b/source_code/sock.c index 8039acc..59dad41 100644 --- a/source_code/sock.c +++ b/source_code/sock.c @@ -834,6 +834,7 @@ smb_release (struct smb_server *server) int smb_connect (struct smb_server *server, int * error_ptr) { + int enabled = TRUE; int result; ASSERT( server != NULL ); @@ -969,6 +970,9 @@ smb_connect (struct smb_server *server, int * error_ptr) } } + /* Enable socket keepalives, for good measure. */ + setsockopt(server->mount_data.fd, SOL_SOCKET, SO_KEEPALIVE, &enabled, sizeof(enabled)); + /* Configure the send/receive timeout (in seconds)? */ if(server->timeout > 0) {