s3:smbd: initial durable handle support: special treatment of durable handles in...
authorMichael Adam <obnox@samba.org>
Fri, 3 Aug 2012 14:47:57 +0000 (16:47 +0200)
committerStefan Metzmacher <metze@samba.org>
Sat, 8 Sep 2012 01:39:06 +0000 (03:39 +0200)
Pair-Programmed-With: Stefan Metzmacher <metze@samba.org>

source3/smbd/close.c

index 51432320b0293deb0d6b98e597e4a9963b9a7a84..8bf481dc37081a8bbbc7357eb1469d6783d863fc 100644 (file)
@@ -706,6 +706,7 @@ static NTSTATUS close_normal_file(struct smb_request *req, files_struct *fsp,
        NTSTATUS status = NT_STATUS_OK;
        NTSTATUS tmp;
        connection_struct *conn = fsp->conn;
+       bool is_durable = false;
 
        if (fsp->num_aio_requests != 0) {
 
@@ -752,6 +753,49 @@ static NTSTATUS close_normal_file(struct smb_request *req, files_struct *fsp,
        tmp = close_filestruct(fsp);
        status = ntstatus_keeperror(status, tmp);
 
+       if (NT_STATUS_IS_OK(status) && fsp->op != NULL) {
+               is_durable = fsp->op->global->durable;
+       }
+
+       if (close_type != SHUTDOWN_CLOSE) {
+               is_durable = false;
+       }
+
+       if (is_durable) {
+               DATA_BLOB new_cookie = data_blob_null;
+
+               tmp = SMB_VFS_DURABLE_DISCONNECT(fsp,
+                                       fsp->op->global->backend_cookie,
+                                       fsp->op,
+                                       &new_cookie);
+               if (NT_STATUS_IS_OK(tmp)) {
+                       data_blob_free(&fsp->op->global->backend_cookie);
+                       fsp->op->global->backend_cookie = new_cookie;
+
+                       tmp = smbXsrv_open_update(fsp->op);
+               }
+               if (!NT_STATUS_IS_OK(tmp)) {
+                       is_durable = false;
+               }
+       }
+
+       if (is_durable) {
+               /*
+                * This is the case where we successfully disconnected
+                * a durable handle and closed the underlying file.
+                * In all other cases, we proceed with a genuine close.
+                */
+               file_free(req, fsp);
+               return NT_STATUS_OK;
+       }
+
+       if (fsp->op != NULL) {
+               /*
+                * Make sure the handle is not marked as durable anymore
+                */
+               fsp->op->global->durable = false;
+       }
+
        if (fsp->print_file) {
                /* FIXME: return spool errors */
                print_spool_end(fsp, close_type);