smbd: Remove "file_sync_all" function
[kai/samba-autobuild/.git] / source3 / smbd / files.c
index ba24eda27f3d555b99cfa91df6617bef0c80e1d3..397baea84cbf01543ee6fb303daec94ee42cd091 100644 (file)
@@ -22,7 +22,6 @@
 #include "smbd/globals.h"
 #include "libcli/security/security.h"
 #include "util_tdb.h"
-#include <ccan/hash/hash.h>
 #include "lib/util/bitmap.h"
 
 #define FILE_HANDLE_OFFSET 0x1000
@@ -93,11 +92,12 @@ NTSTATUS file_new(struct smb_request *req, connection_struct *conn,
 
        GetTimeOfDay(&fsp->open_time);
 
-       if (sconn->conn) {
+       if (req) {
+               struct smbXsrv_connection *xconn = req->xconn;
                struct smbXsrv_open *op = NULL;
                NTTIME now = timeval_to_nttime(&fsp->open_time);
 
-               status = smbXsrv_open_create(sconn->conn,
+               status = smbXsrv_open_create(xconn,
                                             conn->session_info,
                                             now, &op);
                if (!NT_STATUS_IS_OK(status)) {
@@ -108,6 +108,9 @@ NTSTATUS file_new(struct smb_request *req, connection_struct *conn,
                op->compat = fsp;
                fsp->fnum = op->local_id;
                fsp->fh->gen_id = smbXsrv_open_hash(op);
+       } else {
+               DEBUG(10, ("%s: req==NULL, INTERNAL_OPEN_ONLY, smbXsrv_open "
+                          "allocated\n", __func__));
        }
 
        /*
@@ -115,7 +118,7 @@ NTSTATUS file_new(struct smb_request *req, connection_struct *conn,
         * few NULL checks, so make sure it's initialized with something. to
         * be safe until an audit can be done.
         */
-       fsp->fsp_name = synthetic_smb_fname(fsp, "", NULL, NULL);
+       fsp->fsp_name = synthetic_smb_fname(fsp, "", NULL, NULL, 0);
        if (fsp->fsp_name == NULL) {
                file_free(NULL, fsp);
                return NT_STATUS_NO_MEMORY;
@@ -167,7 +170,7 @@ void file_close_conn(connection_struct *conn)
  Close all open files for a pid and a vuid.
 ****************************************************************************/
 
-void file_close_pid(struct smbd_server_connection *sconn, uint16 smbpid,
+void file_close_pid(struct smbd_server_connection *sconn, uint16_t smbpid,
                    uint64_t vuid)
 {
        files_struct *fsp, *next;
@@ -318,7 +321,8 @@ files_struct *file_find_dif(struct smbd_server_connection *sconn,
                        }
                        /* Paranoia check. */
                        if ((fsp->fh->fd == -1) &&
-                           (fsp->oplock_type != NO_OPLOCK)) {
+                           (fsp->oplock_type != NO_OPLOCK &&
+                            fsp->oplock_type != LEASE_OPLOCK)) {
                                DEBUG(0,("file_find_dif: file %s file_id = "
                                         "%s, gen = %u oplock_type = %u is a "
                                         "stat open with oplock type !\n",
@@ -383,6 +387,24 @@ files_struct *file_find_di_next(files_struct *start_fsp)
        return NULL;
 }
 
+struct files_struct *file_find_one_fsp_from_lease_key(
+       struct smbd_server_connection *sconn,
+       const struct smb2_lease_key *lease_key)
+{
+       struct files_struct *fsp;
+
+       for (fsp = sconn->files; fsp; fsp=fsp->next) {
+               if ((fsp->lease != NULL) &&
+                   (fsp->lease->lease.lease_key.data[0] ==
+                    lease_key->data[0]) &&
+                   (fsp->lease->lease.lease_key.data[1] ==
+                    lease_key->data[1])) {
+                       return fsp;
+               }
+       }
+       return NULL;
+}
+
 /****************************************************************************
  Find any fsp open with a pathname below that of an already open path.
 ****************************************************************************/
@@ -432,22 +454,6 @@ bool file_find_subpath(files_struct *dir_fsp)
        return false;
 }
 
-/****************************************************************************
- Sync open files on a connection.
-****************************************************************************/
-
-void file_sync_all(connection_struct *conn)
-{
-       files_struct *fsp, *next;
-
-       for (fsp=conn->sconn->files; fsp; fsp=next) {
-               next=fsp->next;
-               if ((conn == fsp->conn) && (fsp->fh->fd != -1)) {
-                       sync_file(conn, fsp, True /* write through */);
-               }
-       }
-}
-
 /****************************************************************************
  Free up a fsp.
 ****************************************************************************/
@@ -456,6 +462,10 @@ void fsp_free(files_struct *fsp)
 {
        struct smbd_server_connection *sconn = fsp->conn->sconn;
 
+       if (fsp == sconn->fsp_fi_cache.fsp) {
+               ZERO_STRUCT(sconn->fsp_fi_cache);
+       }
+
        DLIST_REMOVE(sconn->files, fsp);
        SMB_ASSERT(sconn->num_files > 0);
        sconn->num_files--;
@@ -468,6 +478,14 @@ void fsp_free(files_struct *fsp)
                fsp->fh->ref_count--;
        }
 
+       if (fsp->lease != NULL) {
+               if (fsp->lease->ref_count == 1) {
+                       TALLOC_FREE(fsp->lease);
+               } else {
+                       fsp->lease->ref_count--;
+               }
+       }
+
        fsp->conn->num_files_open--;
 
        /* this is paranoia, just in case someone tries to reuse the
@@ -484,9 +502,21 @@ void file_free(struct smb_request *req, files_struct *fsp)
        uint64_t fnum = fsp->fnum;
 
        if (fsp->notify) {
-               struct notify_context *notify_ctx =
-                       fsp->conn->sconn->notify_ctx;
-               notify_remove(notify_ctx, fsp);
+               size_t len = fsp_fullbasepath(fsp, NULL, 0);
+               char fullpath[len+1];
+
+               fsp_fullbasepath(fsp, fullpath, sizeof(fullpath));
+
+               /*
+                * Avoid /. at the end of the path name. notify can't
+                * deal with it.
+                */
+               if (len > 1 && fullpath[len-1] == '.' &&
+                   fullpath[len-2] == '/') {
+                       fullpath[len-2] = '\0';
+               }
+
+               notify_remove(fsp->conn->sconn->notify_ctx, fsp, fullpath);
                TALLOC_FREE(fsp->notify);
        }
 
@@ -506,14 +536,7 @@ void file_free(struct smb_request *req, files_struct *fsp)
         * Clear all possible chained fsp
         * pointers in the SMB2 request queue.
         */
-       if (req != NULL && req->smb2req) {
-               remove_smb2_chained_fsp(fsp);
-       }
-
-       /* Closing a file can invalidate the positive cache. */
-       if (fsp == sconn->fsp_fi_cache.fsp) {
-               ZERO_STRUCT(sconn->fsp_fi_cache);
-       }
+       remove_smb2_chained_fsp(fsp);
 
        /* Drop all remaining extensions. */
        vfs_remove_all_fsp_extensions(fsp);
@@ -528,7 +551,7 @@ void file_free(struct smb_request *req, files_struct *fsp)
  Get an fsp from a packet given a 16 bit fnum.
 ****************************************************************************/
 
-files_struct *file_fsp(struct smb_request *req, uint16 fid)
+files_struct *file_fsp(struct smb_request *req, uint16_t fid)
 {
        struct smbXsrv_open *op;
        NTSTATUS status;
@@ -555,13 +578,13 @@ files_struct *file_fsp(struct smb_request *req, uint16 fid)
                return req->chain_fsp;
        }
 
-       if (req->sconn->conn == NULL) {
+       if (req->xconn == NULL) {
                return NULL;
        }
 
        now = timeval_to_nttime(&req->request_time);
 
-       status = smb1srv_open_lookup(req->sconn->conn,
+       status = smb1srv_open_lookup(req->xconn,
                                     fid, now, &op);
        if (!NT_STATUS_IS_OK(status)) {
                return NULL;
@@ -591,7 +614,7 @@ struct files_struct *file_fsp_get(struct smbd_smb2_request *smb2req,
 
        now = timeval_to_nttime(&smb2req->request_time);
 
-       status = smb2srv_open_lookup(smb2req->sconn->conn,
+       status = smb2srv_open_lookup(smb2req->xconn,
                                     persistent_id, volatile_id,
                                     now, &op);
        if (!NT_STATUS_IS_OK(status)) {
@@ -657,8 +680,8 @@ struct files_struct *file_fsp_smb2(struct smbd_smb2_request *smb2req,
 ****************************************************************************/
 
 NTSTATUS dup_file_fsp(struct smb_request *req, files_struct *from,
-                     uint32 access_mask, uint32 share_access,
-                     uint32 create_options, files_struct *to)
+                     uint32_t access_mask, uint32_t share_access,
+                     uint32_t create_options, files_struct *to)
 {
        /* this can never happen for print files */
        SMB_ASSERT(from->print_file == NULL);
@@ -688,45 +711,6 @@ NTSTATUS dup_file_fsp(struct smb_request *req, files_struct *from,
        return fsp_set_smb_fname(to, from->fsp_name);
 }
 
-/*
- * This routine improves performance for operations temporarily acting on a
- * full path. It is equivalent to the much more expensive
- *
- * talloc_asprintf(talloc_tos(), "%s/%s", dir, name)
- *
- * This actually does make a difference in metadata-heavy workloads (i.e. the
- * "standard" client.txt nbench run.
- */
-
-ssize_t full_path_tos(const char *dir, const char *name,
-                     char *tmpbuf, size_t tmpbuf_len,
-                     char **pdst, char **to_free)
-{
-       size_t dirlen, namelen, len;
-       char *dst;
-
-       dirlen = strlen(dir);
-       namelen = strlen(name);
-       len = dirlen + namelen + 1;
-
-       if (len < tmpbuf_len) {
-               dst = tmpbuf;
-               *to_free = NULL;
-       } else {
-               dst = talloc_array(talloc_tos(), char, len+1);
-               if (dst == NULL) {
-                       return -1;
-               }
-               *to_free = dst;
-       }
-
-       memcpy(dst, dir, dirlen);
-       dst[dirlen] = '/';
-       memcpy(dst+dirlen+1, name, namelen+1);
-       *pdst = dst;
-       return len;
-}
-
 /**
  * Return a jenkins hash of a pathname on a connection.
  */
@@ -734,9 +718,10 @@ ssize_t full_path_tos(const char *dir, const char *name,
 NTSTATUS file_name_hash(connection_struct *conn,
                        const char *name, uint32_t *p_name_hash)
 {
-       char tmpbuf[1024];
+       char tmpbuf[PATH_MAX];
        char *fullpath, *to_free;
-       size_t len;
+       ssize_t len;
+       TDB_DATA key;
 
        /* Set the hash of the full pathname. */
 
@@ -745,7 +730,8 @@ NTSTATUS file_name_hash(connection_struct *conn,
        if (len == -1) {
                return NT_STATUS_NO_MEMORY;
        }
-       *p_name_hash = hash(fullpath, len+1, 0);
+       key = (TDB_DATA) { .dptr = (uint8_t *)fullpath, .dsize = len+1 };
+       *p_name_hash = tdb_jenkins_hash(&key);
 
        DEBUG(10,("file_name_hash: %s hash 0x%x\n",
                  fullpath,
@@ -775,3 +761,19 @@ NTSTATUS fsp_set_smb_fname(struct files_struct *fsp,
                        smb_fname_str_dbg(fsp->fsp_name),
                        &fsp->name_hash);
 }
+
+const struct GUID *fsp_client_guid(const files_struct *fsp)
+{
+       return &fsp->conn->sconn->client->connections->smb2.client.guid;
+}
+
+size_t fsp_fullbasepath(struct files_struct *fsp, char *buf, size_t buflen)
+{
+       int len;
+
+       len = snprintf(buf, buflen, "%s/%s", fsp->conn->connectpath,
+                      fsp->fsp_name->base_name);
+       SMB_ASSERT(len>0);
+
+       return len;
+}