s3 onefs: Fix 1 second share mode delay handling
authorSteven Danneman <steven.danneman@isilon.com>
Thu, 14 May 2009 23:14:03 +0000 (23:14 +0000)
committerTim Prouty <tprouty@samba.org>
Thu, 24 Sep 2009 18:31:35 +0000 (11:31 -0700)
When racing to the open and loosing we may get a share_mode violation.
In this case handle the 1-second delay via a defferred open properly.

This requires us to retrieve the share_mode_lock before deferring
open so we don't dereference a NULL pointer assuming we already had
the lck because we were the first opener.

source3/modules/onefs_open.c

index fa1f883c591fe7b7562ac343514e7157e663b8f8..b9a2c30734cc7e0b94476324dec9ca7e6db6d092 100644 (file)
@@ -1095,9 +1095,39 @@ NTSTATUS onefs_open_file_ntcreate(connection_struct *conn,
                                state.id = id;
                                state.failed = false;
 
-                               if ((req != NULL)
-                                   && !request_timed_out(request_time,
-                                                         timeout)) {
+                               /*
+                                * We hit the race that when we did the stat
+                                * on the file it did not exist, and someone
+                                * has created it in between the stat and the
+                                * open_file() call.  Retrieve the share_mode
+                                * lock on the newly opened file so we can
+                                * defer our request.
+                                */
+                               if (lck == NULL) {
+                                       struct timespec old_write_time;
+                                       old_write_time = get_mtimespec(psbuf);
+
+                                       lck = get_share_mode_lock(talloc_tos(),
+                                           id, conn->connectpath, fname,
+                                           &old_write_time);
+                                       if (lck == NULL) {
+                                               DEBUG(0,
+                                                   ("onefs_open_file_ntcreate:"
+                                                    " Could not get share "
+                                                    "mode lock for %s\n",
+                                                    fname));
+                                               /* This will cause us to return
+                                                * immediately skipping the
+                                                * the 1 second delay, which
+                                                * isn't a big deal */
+                                               status = NT_STATUS_SHARING_VIOLATION;
+                                               goto cleanup_destroy;
+                                       }
+                               }
+
+                               if ((req != NULL) &&
+                                   !request_timed_out(request_time, timeout))
+                               {
                                        defer_open(lck, request_time, timeout,
                                                   req, &state);
                                }