summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStefan Metzmacher <metze@samba.org>2012-06-13 12:11:51 +0200
committerStefan Metzmacher <metze@samba.org>2012-06-14 18:13:31 +0200
commitc7c351b8171ee5536090a04b61fb1566a6092af5 (patch)
tree38e73d7f8200ab850187f4ed262c28c28ab72577
parent2fd28dc4cf4f40a690adfd846911e4da1a776bf2 (diff)
downloadsamba-c7c351b8171ee5536090a04b61fb1566a6092af5.tar.gz
samba-c7c351b8171ee5536090a04b61fb1566a6092af5.tar.bz2
samba-c7c351b8171ee5536090a04b61fb1566a6092af5.zip
s3:smbd: try to make fsp->fh->gen_id as globally unique as possible
This makes sure the value is never 0, it's between 1 and UINT32_MAX. While fsp->fh->gen_id is 'unsigned long' currently (which might by 8 bytes), there's some oplock code which truncates it to uint32_t (using IVAL()). Which means we could reuse fsp->fh->gen_id as persistent file id until we have a final fix, which uses database. See bug #8995 for more details. Based on code from Ira Cooper. Ensure fsp->fh->gen_id starts from a random point. We will use this as the SMB2 persistent_id. metze
-rw-r--r--source3/smbd/files.c20
1 files changed, 19 insertions, 1 deletions
diff --git a/source3/smbd/files.c b/source3/smbd/files.c
index 97db348a01..fb9dacce99 100644
--- a/source3/smbd/files.c
+++ b/source3/smbd/files.c
@@ -28,12 +28,26 @@
#define FILE_HANDLE_OFFSET 0x1000
/****************************************************************************
- Return a unique number identifying this fsp over the life of this pid.
+ Return a unique number identifying this fsp over the life of this pid,
+ and try to make it as globally unique as possible.
+ See bug #8995 for the details.
****************************************************************************/
static unsigned long get_gen_count(struct smbd_server_connection *sconn)
{
+ /*
+ * While fsp->fh->gen_id is 'unsigned long' currently
+ * (which might by 8 bytes),
+ * there's some oplock code which truncates it to
+ * uint32_t(using IVAL()).
+ */
+ if (sconn->file_gen_counter == 0) {
+ sconn->file_gen_counter = generate_random();
+ }
sconn->file_gen_counter += 1;
+ if (sconn->file_gen_counter >= UINT32_MAX) {
+ sconn->file_gen_counter = 0;
+ }
if (sconn->file_gen_counter == 0) {
sconn->file_gen_counter += 1;
}
@@ -315,6 +329,10 @@ files_struct *file_find_dif(struct smbd_server_connection *sconn,
int count=0;
files_struct *fsp;
+ if (gen_id == 0) {
+ return NULL;
+ }
+
for (fsp=sconn->files; fsp; fsp=fsp->next,count++) {
/* We can have a fsp->fh->fd == -1 here as it could be a stat open. */
if (file_id_equal(&fsp->file_id, &id) &&