#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
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)) {
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__));
}
/*
* 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;
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;
}
/* 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",
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.
****************************************************************************/
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.
****************************************************************************/
{
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--;
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
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);
}
* 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);
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;
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;
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)) {
****************************************************************************/
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);
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.
*/
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. */
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,
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;
+}