summaryrefslogtreecommitdiff
path: root/source4/ntvfs
diff options
context:
space:
mode:
authorStefan Metzmacher <metze@samba.org>2006-05-20 08:15:22 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 14:08:10 -0500
commit9ef33f5f5c786b83311ca088357fb2f0aa72fc9e (patch)
tree66335dced1641119f94e6c656dd1ccc673218d0c /source4/ntvfs
parent0dcecc314899b6f36e9215e0b3881220062ba4f9 (diff)
downloadsamba-9ef33f5f5c786b83311ca088357fb2f0aa72fc9e.tar.gz
samba-9ef33f5f5c786b83311ca088357fb2f0aa72fc9e.tar.bz2
samba-9ef33f5f5c786b83311ca088357fb2f0aa72fc9e.zip
r15734: This is a major change to the NTVFS subsystem:
- to use a struct ntvfs_handle instead of a uint16_t fnum. (to make it independend from the frontend protocol) - the allocation of handles now is provided by the frontend (smbsrv_*) via callbacks and not by each backend module - this also makes sure that file handles are only passed to the ntvfs subsystem when the tcon and session matches, so modules can rely on this and need to check this. - this allows multiple modules in the ntvfs module chain to allocate file handles. This can be used for virtual files like "\\$Extend\\$Quota:$Q:$INDEX_ALLOCATION"... - also this will make SMB2 with 128 bit file handles possible metze (This used to be commit 287fc1c22d670f6e568014b420f7f4cb31dc7958)
Diffstat (limited to 'source4/ntvfs')
-rw-r--r--source4/ntvfs/cifs/vfs_cifs.c188
-rw-r--r--source4/ntvfs/cifs_posix_cli/vfs_simple.c4
-rw-r--r--source4/ntvfs/common/brlock.c22
-rw-r--r--source4/ntvfs/ipc/vfs_ipc.c106
-rw-r--r--source4/ntvfs/nbench/vfs_nbench.c68
-rw-r--r--source4/ntvfs/ntvfs.h38
-rw-r--r--source4/ntvfs/ntvfs_generic.c46
-rw-r--r--source4/ntvfs/ntvfs_interface.c6
-rw-r--r--source4/ntvfs/ntvfs_util.c97
-rw-r--r--source4/ntvfs/posix/pvfs_flush.c2
-rw-r--r--source4/ntvfs/posix/pvfs_ioctl.c2
-rw-r--r--source4/ntvfs/posix/pvfs_lock.c4
-rw-r--r--source4/ntvfs/posix/pvfs_notify.c2
-rw-r--r--source4/ntvfs/posix/pvfs_open.c154
-rw-r--r--source4/ntvfs/posix/pvfs_qfileinfo.c2
-rw-r--r--source4/ntvfs/posix/pvfs_read.c2
-rw-r--r--source4/ntvfs/posix/pvfs_seek.c2
-rw-r--r--source4/ntvfs/posix/pvfs_setfileinfo.c2
-rw-r--r--source4/ntvfs/posix/pvfs_write.c2
-rw-r--r--source4/ntvfs/posix/vfs_posix.c4
-rw-r--r--source4/ntvfs/posix/vfs_posix.h5
-rw-r--r--source4/ntvfs/simple/svfs.h3
-rw-r--r--source4/ntvfs/simple/vfs_simple.c81
23 files changed, 538 insertions, 304 deletions
diff --git a/source4/ntvfs/cifs/vfs_cifs.c b/source4/ntvfs/cifs/vfs_cifs.c
index e12fd3de2f..c669414e09 100644
--- a/source4/ntvfs/cifs/vfs_cifs.c
+++ b/source4/ntvfs/cifs/vfs_cifs.c
@@ -32,12 +32,19 @@
#include "ntvfs/ntvfs.h"
#include "include/dlinklist.h"
+struct cvfs_file {
+ struct cvfs_file *prev, *next;
+ uint16_t fnum;
+ struct ntvfs_handle *h;
+};
+
/* this is stored in ntvfs_private */
struct cvfs_private {
struct smbcli_tree *tree;
struct smbcli_transport *transport;
struct ntvfs_module_context *ntvfs;
struct async_info *pending;
+ struct cvfs_file *files;
BOOL map_generic;
BOOL map_trans2;
};
@@ -49,11 +56,24 @@ struct async_info {
struct cvfs_private *cvfs;
struct ntvfs_request *req;
struct smbcli_request *c_req;
+ struct cvfs_file *f;
void *parms;
};
#define SETUP_PID private->tree->session->pid = req->smbpid
+#define SETUP_FILE do { \
+ struct cvfs_file *f; \
+ f = ntvfs_handle_get_backend_data(io->generic.in.file.ntvfs, ntvfs); \
+ if (!f) return NT_STATUS_INVALID_HANDLE; \
+ io->generic.in.file.fnum = f->fnum; \
+} while (0)
+
+#define SETUP_PID_AND_FILE do { \
+ SETUP_PID; \
+ SETUP_FILE; \
+} while (0)
+
/*
a handler for oplock break events from the server - these need to be passed
along to the client
@@ -62,9 +82,22 @@ static BOOL oplock_handler(struct smbcli_transport *transport, uint16_t tid, uin
{
struct cvfs_private *private = p_private;
NTSTATUS status;
+ struct ntvfs_handle *h = NULL;
+ struct cvfs_file *f;
+
+ for (f=private->files; f; f=f->next) {
+ if (f->fnum != fnum) continue;
+ h = f->h;
+ break;
+ }
+
+ if (!h) {
+ DEBUG(5,("vfs_cifs: ignoring oplock break level %d for fnum %d\n", level, fnum));
+ return True;
+ }
DEBUG(5,("vfs_cifs: sending oplock break level %d for fnum %d\n", level, fnum));
- status = ntvfs_send_oplock_break(private->ntvfs, fnum, level);
+ status = ntvfs_send_oplock_break(private->ntvfs, h, level);
if (!NT_STATUS_IS_OK(status)) return False;
return True;
}
@@ -227,7 +260,7 @@ static void async_simple(struct smbcli_request *c_req)
/* save some typing for the simple functions */
-#define ASYNC_RECV_TAIL(io, async_fn) do { \
+#define ASYNC_RECV_TAIL_F(io, async_fn, file) do { \
if (!c_req) return NT_STATUS_UNSUCCESSFUL; \
{ \
struct async_info *async; \
@@ -235,6 +268,7 @@ static void async_simple(struct smbcli_request *c_req)
if (!async) return NT_STATUS_NO_MEMORY; \
async->parms = io; \
async->req = req; \
+ async->f = file; \
async->cvfs = private; \
async->c_req = c_req; \
DLIST_ADD(private->pending, async); \
@@ -246,6 +280,8 @@ static void async_simple(struct smbcli_request *c_req)
return NT_STATUS_OK; \
} while (0)
+#define ASYNC_RECV_TAIL(io, async_fn) ASYNC_RECV_TAIL_F(io, async_fn, NULL)
+
#define SIMPLE_ASYNC_TAIL ASYNC_RECV_TAIL(NULL, async_simple)
/*
@@ -287,12 +323,12 @@ static void async_ioctl(struct smbcli_request *c_req)
ioctl interface
*/
static NTSTATUS cvfs_ioctl(struct ntvfs_module_context *ntvfs,
- struct ntvfs_request *req, union smb_ioctl *io)
+ struct ntvfs_request *req, union smb_ioctl *io)
{
struct cvfs_private *private = ntvfs->private_data;
struct smbcli_request *c_req;
- SETUP_PID;
+ SETUP_PID_AND_FILE;
/* see if the front end will allow us to perform this
function asynchronously. */
@@ -309,7 +345,7 @@ static NTSTATUS cvfs_ioctl(struct ntvfs_module_context *ntvfs,
check if a directory exists
*/
static NTSTATUS cvfs_chkpath(struct ntvfs_module_context *ntvfs,
- struct ntvfs_request *req, union smb_chkpath *cp)
+ struct ntvfs_request *req, union smb_chkpath *cp)
{
struct cvfs_private *private = ntvfs->private_data;
struct smbcli_request *c_req;
@@ -341,7 +377,7 @@ static void async_qpathinfo(struct smbcli_request *c_req)
return info on a pathname
*/
static NTSTATUS cvfs_qpathinfo(struct ntvfs_module_context *ntvfs,
- struct ntvfs_request *req, union smb_fileinfo *info)
+ struct ntvfs_request *req, union smb_fileinfo *info)
{
struct cvfs_private *private = ntvfs->private_data;
struct smbcli_request *c_req;
@@ -373,20 +409,20 @@ static void async_qfileinfo(struct smbcli_request *c_req)
query info on a open file
*/
static NTSTATUS cvfs_qfileinfo(struct ntvfs_module_context *ntvfs,
- struct ntvfs_request *req, union smb_fileinfo *info)
+ struct ntvfs_request *req, union smb_fileinfo *io)
{
struct cvfs_private *private = ntvfs->private_data;
struct smbcli_request *c_req;
- SETUP_PID;
+ SETUP_PID_AND_FILE;
if (!(req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) {
- return smb_raw_fileinfo(private->tree, req, info);
+ return smb_raw_fileinfo(private->tree, req, io);
}
- c_req = smb_raw_fileinfo_send(private->tree, info);
+ c_req = smb_raw_fileinfo_send(private->tree, io);
- ASYNC_RECV_TAIL(info, async_qfileinfo);
+ ASYNC_RECV_TAIL(io, async_qfileinfo);
}
@@ -394,7 +430,7 @@ static NTSTATUS cvfs_qfileinfo(struct ntvfs_module_context *ntvfs,
set info on a pathname
*/
static NTSTATUS cvfs_setpathinfo(struct ntvfs_module_context *ntvfs,
- struct ntvfs_request *req, union smb_setfileinfo *st)
+ struct ntvfs_request *req, union smb_setfileinfo *st)
{
struct cvfs_private *private = ntvfs->private_data;
struct smbcli_request *c_req;
@@ -417,9 +453,21 @@ static NTSTATUS cvfs_setpathinfo(struct ntvfs_module_context *ntvfs,
static void async_open(struct smbcli_request *c_req)
{
struct async_info *async = c_req->async.private;
+ struct cvfs_private *cvfs = async->cvfs;
struct ntvfs_request *req = async->req;
- req->async_states->status = smb_raw_open_recv(c_req, req, async->parms);
+ struct cvfs_file *f = async->f;
+ union smb_open *io = async->parms;
+ union smb_handle *file;
talloc_free(async);
+ req->async_states->status = smb_raw_open_recv(c_req, req, io);
+ SMB_OPEN_OUT_FILE(io, file);
+ f->fnum = file->fnum;
+ file->ntvfs = NULL;
+ if (!NT_STATUS_IS_OK(req->async_states->status)) goto failed;
+ req->async_states->status = ntvfs_handle_set_backend_data(f->h, cvfs->ntvfs, f);
+ if (!NT_STATUS_IS_OK(req->async_states->status)) goto failed;
+ file->ntvfs = f->h;
+failed:
req->async_states->send_fn(req);
}
@@ -427,10 +475,13 @@ static void async_open(struct smbcli_request *c_req)
open a file
*/
static NTSTATUS cvfs_open(struct ntvfs_module_context *ntvfs,
- struct ntvfs_request *req, union smb_open *io)
+ struct ntvfs_request *req, union smb_open *io)
{
struct cvfs_private *private = ntvfs->private_data;
struct smbcli_request *c_req;
+ struct ntvfs_handle *h;
+ struct cvfs_file *f;
+ NTSTATUS status;
SETUP_PID;
@@ -439,20 +490,39 @@ static NTSTATUS cvfs_open(struct ntvfs_module_context *ntvfs,
return ntvfs_map_open(ntvfs, req, io);
}
+ status = ntvfs_handle_new(ntvfs, req, &h);
+ NT_STATUS_NOT_OK_RETURN(status);
+
+ f = talloc_zero(h, struct cvfs_file);
+ NT_STATUS_HAVE_NO_MEMORY(f);
+ f->h = h;
+
if (!(req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) {
- return smb_raw_open(private->tree, req, io);
+ union smb_handle *file;
+
+ status = smb_raw_open(private->tree, req, io);
+ NT_STATUS_NOT_OK_RETURN(status);
+
+ SMB_OPEN_OUT_FILE(io, file);
+ f->fnum = file->fnum;
+ file->ntvfs = NULL;
+ status = ntvfs_handle_set_backend_data(f->h, private->ntvfs, f);
+ NT_STATUS_NOT_OK_RETURN(status);
+ file->ntvfs = f->h;
+
+ return NT_STATUS_OK;
}
c_req = smb_raw_open_send(private->tree, io);
- ASYNC_RECV_TAIL(io, async_open);
+ ASYNC_RECV_TAIL_F(io, async_open, f);
}
/*
create a directory
*/
static NTSTATUS cvfs_mkdir(struct ntvfs_module_context *ntvfs,
- struct ntvfs_request *req, union smb_mkdir *md)
+ struct ntvfs_request *req, union smb_mkdir *md)
{
struct cvfs_private *private = ntvfs->private_data;
struct smbcli_request *c_req;
@@ -472,7 +542,7 @@ static NTSTATUS cvfs_mkdir(struct ntvfs_module_context *ntvfs,
remove a directory
*/
static NTSTATUS cvfs_rmdir(struct ntvfs_module_context *ntvfs,
- struct ntvfs_request *req, struct smb_rmdir *rd)
+ struct ntvfs_request *req, struct smb_rmdir *rd)
{
struct cvfs_private *private = ntvfs->private_data;
struct smbcli_request *c_req;
@@ -491,7 +561,7 @@ static NTSTATUS cvfs_rmdir(struct ntvfs_module_context *ntvfs,
rename a set of files
*/
static NTSTATUS cvfs_rename(struct ntvfs_module_context *ntvfs,
- struct ntvfs_request *req, union smb_rename *ren)
+ struct ntvfs_request *req, union smb_rename *ren)
{
struct cvfs_private *private = ntvfs->private_data;
struct smbcli_request *c_req;
@@ -511,7 +581,7 @@ static NTSTATUS cvfs_rename(struct ntvfs_module_context *ntvfs,
copy a set of files
*/
static NTSTATUS cvfs_copy(struct ntvfs_module_context *ntvfs,
- struct ntvfs_request *req, struct smb_copy *cp)
+ struct ntvfs_request *req, struct smb_copy *cp)
{
return NT_STATUS_NOT_SUPPORTED;
}
@@ -532,25 +602,27 @@ static void async_read(struct smbcli_request *c_req)
read from a file
*/
static NTSTATUS cvfs_read(struct ntvfs_module_context *ntvfs,
- struct ntvfs_request *req, union smb_read *rd)
+ struct ntvfs_request *req, union smb_read *io)
{
struct cvfs_private *private = ntvfs->private_data;
struct smbcli_request *c_req;
SETUP_PID;
- if (rd->generic.level != RAW_READ_GENERIC &&
+ if (io->generic.level != RAW_READ_GENERIC &&
private->map_generic) {
- return ntvfs_map_read(ntvfs, req, rd);
+ return ntvfs_map_read(ntvfs, req, io);
}
+ SETUP_FILE;
+
if (!(req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) {
- return smb_raw_read(private->tree, rd);
+ return smb_raw_read(private->tree, io);
}
- c_req = smb_raw_read_send(private->tree, rd);
+ c_req = smb_raw_read_send(private->tree, io);
- ASYNC_RECV_TAIL(rd, async_read);
+ ASYNC_RECV_TAIL(io, async_read);
}
/*
@@ -569,25 +641,26 @@ static void async_write(struct smbcli_request *c_req)
write to a file
*/
static NTSTATUS cvfs_write(struct ntvfs_module_context *ntvfs,
- struct ntvfs_request *req, union smb_write *wr)
+ struct ntvfs_request *req, union smb_write *io)
{
struct cvfs_private *private = ntvfs->private_data;
struct smbcli_request *c_req;
SETUP_PID;
- if (wr->generic.level != RAW_WRITE_GENERIC &&
+ if (io->generic.level != RAW_WRITE_GENERIC &&
private->map_generic) {
- return ntvfs_map_write(ntvfs, req, wr);
+ return ntvfs_map_write(ntvfs, req, io);
}
+ SETUP_FILE;
if (!(req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) {
- return smb_raw_write(private->tree, wr);
+ return smb_raw_write(private->tree, io);
}
- c_req = smb_raw_write_send(private->tree, wr);
+ c_req = smb_raw_write_send(private->tree, io);
- ASYNC_RECV_TAIL(wr, async_write);
+ ASYNC_RECV_TAIL(io, async_write);
}
/*
@@ -612,7 +685,7 @@ static NTSTATUS cvfs_seek(struct ntvfs_module_context *ntvfs,
struct cvfs_private *private = ntvfs->private_data;
struct smbcli_request *c_req;
- SETUP_PID;
+ SETUP_PID_AND_FILE;
if (!(req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) {
return smb_raw_seek(private->tree, io);
@@ -634,6 +707,14 @@ static NTSTATUS cvfs_flush(struct ntvfs_module_context *ntvfs,
struct smbcli_request *c_req;
SETUP_PID;
+ switch (io->generic.level) {
+ case RAW_FLUSH_FLUSH:
+ SETUP_FILE;
+ break;
+ case RAW_FLUSH_ALL:
+ io->generic.in.file.fnum = 0xFFFF;
+ break;
+ }
if (!(req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) {
return smb_raw_flush(private->tree, io);
@@ -648,7 +729,7 @@ static NTSTATUS cvfs_flush(struct ntvfs_module_context *ntvfs,
close a file
*/
static NTSTATUS cvfs_close(struct ntvfs_module_context *ntvfs,
- struct ntvfs_request *req, union smb_close *io)
+ struct ntvfs_request *req, union smb_close *io)
{
struct cvfs_private *private = ntvfs->private_data;
struct smbcli_request *c_req;
@@ -659,6 +740,7 @@ static NTSTATUS cvfs_close(struct ntvfs_module_context *ntvfs,
private->map_generic) {
return ntvfs_map_close(ntvfs, req, io);
}
+ SETUP_FILE;
if (!(req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) {
return smb_raw_close(private->tree, io);
@@ -673,7 +755,7 @@ static NTSTATUS cvfs_close(struct ntvfs_module_context *ntvfs,
exit - closing files open by the pid
*/
static NTSTATUS cvfs_exit(struct ntvfs_module_context *ntvfs,
- struct ntvfs_request *req)
+ struct ntvfs_request *req)
{
struct cvfs_private *private = ntvfs->private_data;
struct smbcli_request *c_req;
@@ -693,7 +775,7 @@ static NTSTATUS cvfs_exit(struct ntvfs_module_context *ntvfs,
logoff - closing files open by the user
*/
static NTSTATUS cvfs_logoff(struct ntvfs_module_context *ntvfs,
- struct ntvfs_request *req)
+ struct ntvfs_request *req)
{
/* we can't do this right in the cifs backend .... */
return NT_STATUS_OK;
@@ -736,23 +818,24 @@ static NTSTATUS cvfs_cancel(struct ntvfs_module_context *ntvfs,
lock a byte range
*/
static NTSTATUS cvfs_lock(struct ntvfs_module_context *ntvfs,
- struct ntvfs_request *req, union smb_lock *lck)
+ struct ntvfs_request *req, union smb_lock *io)
{
struct cvfs_private *private = ntvfs->private_data;
struct smbcli_request *c_req;
SETUP_PID;
- if (lck->generic.level != RAW_LOCK_GENERIC &&
+ if (io->generic.level != RAW_LOCK_GENERIC &&
private->map_generic) {
- return ntvfs_map_lock(ntvfs, req, lck);
+ return ntvfs_map_lock(ntvfs, req, io);
}
+ SETUP_FILE;
if (!(req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) {
- return smb_raw_lock(private->tree, lck);
+ return smb_raw_lock(private->tree, io);
}
- c_req = smb_raw_lock_send(private->tree, lck);
+ c_req = smb_raw_lock_send(private->tree, io);
SIMPLE_ASYNC_TAIL;
}
@@ -761,17 +844,17 @@ static NTSTATUS cvfs_lock(struct ntvfs_module_context *ntvfs,
*/
static NTSTATUS cvfs_setfileinfo(struct ntvfs_module_context *ntvfs,
struct ntvfs_request *req,
- union smb_setfileinfo *info)
+ union smb_setfileinfo *io)
{
struct cvfs_private *private = ntvfs->private_data;
struct smbcli_request *c_req;
- SETUP_PID;
+ SETUP_PID_AND_FILE;
if (!(req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) {
- return smb_raw_setfileinfo(private->tree, info);
+ return smb_raw_setfileinfo(private->tree, io);
}
- c_req = smb_raw_setfileinfo_send(private->tree, info);
+ c_req = smb_raw_setfileinfo_send(private->tree, io);
SIMPLE_ASYNC_TAIL;
}
@@ -793,7 +876,7 @@ static void async_fsinfo(struct smbcli_request *c_req)
return filesystem space info
*/
static NTSTATUS cvfs_fsinfo(struct ntvfs_module_context *ntvfs,
- struct ntvfs_request *req, union smb_fsinfo *fs)
+ struct ntvfs_request *req, union smb_fsinfo *fs)
{
struct cvfs_private *private = ntvfs->private_data;
struct smbcli_request *c_req;
@@ -813,7 +896,7 @@ static NTSTATUS cvfs_fsinfo(struct ntvfs_module_context *ntvfs,
return print queue info
*/
static NTSTATUS cvfs_lpq(struct ntvfs_module_context *ntvfs,
- struct ntvfs_request *req, union smb_lpq *lpq)
+ struct ntvfs_request *req, union smb_lpq *lpq)
{
return NT_STATUS_NOT_SUPPORTED;
}
@@ -916,14 +999,19 @@ static void async_changenotify(struct smbcli_request *c_req)
/* change notify request - always async */
static NTSTATUS cvfs_notify(struct ntvfs_module_context *ntvfs,
struct ntvfs_request *req,
- struct smb_notify *info)
+ struct smb_notify *io)
{
struct cvfs_private *private = ntvfs->private_data;
struct smbcli_request *c_req;
int saved_timeout = private->transport->options.request_timeout;
+ struct cvfs_file *f;
SETUP_PID;
+ f = ntvfs_handle_get_backend_data(io->in.file.ntvfs, ntvfs);
+ if (!f) return NT_STATUS_INVALID_HANDLE;
+ io->in.file.fnum = f->fnum;
+
/* this request doesn't make sense unless its async */
if (!(req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) {
return NT_STATUS_INVALID_PARAMETER;
@@ -933,11 +1021,11 @@ static NTSTATUS cvfs_notify(struct ntvfs_module_context *ntvfs,
forever */
private->transport->options.request_timeout = 0;
- c_req = smb_raw_changenotify_send(private->tree, info);
+ c_req = smb_raw_changenotify_send(private->tree, io);
private->transport->options.request_timeout = saved_timeout;
- ASYNC_RECV_TAIL(info, async_changenotify);
+ ASYNC_RECV_TAIL(io, async_changenotify);
}
/*
diff --git a/source4/ntvfs/cifs_posix_cli/vfs_simple.c b/source4/ntvfs/cifs_posix_cli/vfs_simple.c
index bbe52d9db1..cf28a02806 100644
--- a/source4/ntvfs/cifs_posix_cli/vfs_simple.c
+++ b/source4/ntvfs/cifs_posix_cli/vfs_simple.c
@@ -19,6 +19,10 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
+
+/* this module needs to be converted to use ntvfs_handle's! */
+#define fnum _XXX_use_ntvfs_handle_not_fnum_XXX_
+
/*
this implements a very simple NTVFS filesystem backend.
diff --git a/source4/ntvfs/common/brlock.c b/source4/ntvfs/common/brlock.c
index b5df434435..2816c563b8 100644
--- a/source4/ntvfs/common/brlock.c
+++ b/source4/ntvfs/common/brlock.c
@@ -57,7 +57,7 @@ struct lock_context {
size of the record */
struct lock_struct {
struct lock_context context;
- uint16_t fnum;
+ struct ntvfs_handle *ntvfs;
uint64_t start;
uint64_t size;
enum brl_type lock_type;
@@ -67,7 +67,7 @@ struct lock_struct {
/* this struct is attached to on oprn file handle */
struct brl_handle {
DATA_BLOB key;
- uint16_t fnum;
+ struct ntvfs_handle *ntvfs;
struct lock_struct last_lock;
};
@@ -109,7 +109,7 @@ struct brl_context *brl_init(TALLOC_CTX *mem_ctx, uint32_t server,
return brl;
}
-struct brl_handle *brl_create_handle(TALLOC_CTX *mem_ctx, DATA_BLOB *file_key, uint16_t fnum)
+struct brl_handle *brl_create_handle(TALLOC_CTX *mem_ctx, struct ntvfs_handle *ntvfs, DATA_BLOB *file_key)
{
struct brl_handle *brlh;
@@ -119,7 +119,7 @@ struct brl_handle *brl_create_handle(TALLOC_CTX *mem_ctx, DATA_BLOB *file_key, u
}
brlh->key = *file_key;
- brlh->fnum = fnum;
+ brlh->ntvfs = ntvfs;
ZERO_STRUCT(brlh->last_lock);
return brlh;
@@ -173,7 +173,7 @@ static BOOL brl_conflict(struct lock_struct *lck1,
}
if (brl_same_context(&lck1->context, &lck2->context) &&
- lck2->lock_type == READ_LOCK && lck1->fnum == lck2->fnum) {
+ lck2->lock_type == READ_LOCK && lck1->ntvfs == lck2->ntvfs) {
return False;
}
@@ -202,7 +202,7 @@ static BOOL brl_conflict_other(struct lock_struct *lck1, struct lock_struct *lck
* in smbtorture.
*/
if (brl_same_context(&lck1->context, &lck2->context) &&
- lck1->fnum == lck2->fnum &&
+ lck1->ntvfs == lck2->ntvfs &&
(lck2->lock_type == READ_LOCK || lck1->lock_type == WRITE_LOCK)) {
return False;
}
@@ -251,7 +251,7 @@ static NTSTATUS brl_lock_failed(struct brl_handle *brlh, struct lock_struct *loc
*/
if (lock->context.server == brlh->last_lock.context.server &&
lock->context.ctx == brlh->last_lock.context.ctx &&
- lock->fnum == brlh->last_lock.fnum &&
+ lock->ntvfs == brlh->last_lock.ntvfs &&
lock->start == brlh->last_lock.start) {
return NT_STATUS_FILE_LOCK_CONFLICT;
}
@@ -310,7 +310,7 @@ NTSTATUS brl_lock(struct brl_context *brl,
lock.context.smbpid = smbpid;
lock.context.server = brl->server;
lock.context.ctx = brl;
- lock.fnum = brlh->fnum;
+ lock.ntvfs = brlh->ntvfs;
lock.context.ctx = brl;
lock.start = start;
lock.size = size;
@@ -454,7 +454,7 @@ NTSTATUS brl_unlock(struct brl_context *brl,
struct lock_struct *lock = &locks[i];
if (brl_same_context(&lock->context, &context) &&
- lock->fnum == brlh->fnum &&
+ lock->ntvfs == brlh->ntvfs &&
lock->start == start &&
lock->size == size &&
lock->lock_type < PENDING_READ_LOCK) {
@@ -595,7 +595,7 @@ NTSTATUS brl_locktest(struct brl_context *brl,
lock.context.smbpid = smbpid;
lock.context.server = brl->server;
lock.context.ctx = brl;
- lock.fnum = brlh->fnum;
+ lock.ntvfs = brlh->ntvfs;
lock.start = start;
lock.size = size;
lock.lock_type = lock_type;
@@ -649,7 +649,7 @@ NTSTATUS brl_close(struct brl_context *brl,
if (lock->context.ctx == brl &&
lock->context.server == brl->server &&
- lock->fnum == brlh->fnum) {
+ lock->ntvfs == brlh->ntvfs) {
/* found it - delete it */
if (count > 1 && i < count-1) {
memmove(&locks[i], &locks[i+1],
diff --git a/source4/ntvfs/ipc/vfs_ipc.c b/source4/ntvfs/ipc/vfs_ipc.c
index 6ef380c4eb..fdad41145b 100644
--- a/source4/ntvfs/ipc/vfs_ipc.c
+++ b/source4/ntvfs/ipc/vfs_ipc.c
@@ -32,16 +32,12 @@
#include "ntvfs/ipc/proto.h"
#include "rpc_server/dcerpc_server.h"
-#define IPC_BASE_FNUM 0x400
-
/* this is the private structure used to keep the state of an open
ipc$ connection. It needs to keep information about all open
pipes */
struct ipc_private {
struct ntvfs_module_context *ntvfs;
- struct idr_context *idtree_fnum;
-
struct dcesrv_context *dcesrv;
/* a list of open pipes */
@@ -49,41 +45,43 @@ struct ipc_private {
struct pipe_state *next, *prev;
struct ipc_private *private;
const char *pipe_name;
- uint16_t fnum;
+ struct ntvfs_handle *handle;
struct dcesrv_connection *dce_conn;
uint16_t ipc_state;
- /* we need to remember the session it was opened on,
- as it is illegal to operate on someone elses fnum */
- struct auth_session_info *session_info;
-
- /* we need to remember the client pid that
- opened the file so SMBexit works */
- uint16_t smbpid;
} *pipe_list;
};
/*
- find a open pipe give a file descriptor
+ find a open pipe give a file handle
*/
-static struct pipe_state *pipe_state_find(struct ipc_private *private, uint16_t fnum,
- struct auth_session_info *session_info)
+static struct pipe_state *pipe_state_find(struct ipc_private *private, struct ntvfs_handle *handle)
{
struct pipe_state *s;
void *p;
- p = idr_find(private->idtree_fnum, fnum);
+ p = ntvfs_handle_get_backend_data(handle, private->ntvfs);
if (!p) return NULL;
s = talloc_get_type(p, struct pipe_state);
-
- if (s->session_info != session_info) {
- return NULL;
- }
+ if (!s) return NULL;
return s;
}
+/*
+ find a open pipe give a wire fnum
+*/
+static struct pipe_state *pipe_state_find_key(struct ipc_private *private, struct ntvfs_request *req, const DATA_BLOB *key)
+{
+ struct ntvfs_handle *h;
+
+ h = ntvfs_handle_search_by_wire_key(private->ntvfs, req, key);
+ if (!h) return NULL;
+
+ return pipe_state_find(private, h);
+}
+
/*
connect to a share - always works
@@ -109,9 +107,6 @@ static NTSTATUS ipc_connect(struct ntvfs_module_context *ntvfs,
private->ntvfs = ntvfs;
private->pipe_list = NULL;
- private->idtree_fnum = idr_init(private);
- NT_STATUS_HAVE_NO_MEMORY(private->idtree_fnum);
-
/* setup the DCERPC server subsystem */
status = dcesrv_init_ipc_context(private, &private->dcesrv);
NT_STATUS_NOT_OK_RETURN(status);
@@ -182,7 +177,6 @@ static NTSTATUS ipc_setpathinfo(struct ntvfs_module_context *ntvfs,
static int ipc_fd_destructor(void *ptr)
{
struct pipe_state *p = ptr;
- idr_remove(p->private->idtree_fnum, p->fnum);
DLIST_REMOVE(p->private->pipe_list, p);
return 0;
}
@@ -212,9 +206,12 @@ static NTSTATUS ipc_open_generic(struct ntvfs_module_context *ntvfs,
NTSTATUS status;
struct dcerpc_binding *ep_description;
struct ipc_private *private = ntvfs->private_data;
- int fnum;
+ struct ntvfs_handle *h;
+
+ status = ntvfs_handle_new(ntvfs, req, &h);
+ NT_STATUS_NOT_OK_RETURN(status);
- p = talloc(req, struct pipe_state);
+ p = talloc(h, struct pipe_state);
NT_STATUS_HAVE_NO_MEMORY(p);
ep_description = talloc(req, struct dcerpc_binding);
@@ -225,12 +222,7 @@ static NTSTATUS ipc_open_generic(struct ntvfs_module_context *ntvfs,
p->pipe_name = talloc_asprintf(p, "\\pipe\\%s", fname);
NT_STATUS_HAVE_NO_MEMORY(p->pipe_name);
- fnum = idr_get_new_above(private->idtree_fnum, p, IPC_BASE_FNUM, UINT16_MAX);
- if (fnum == -1) {
- return NT_STATUS_TOO_MANY_OPENED_FILES;
- }
-
- p->fnum = fnum;
+ p->handle = h;
p->ipc_state = 0x5ff;
/*
@@ -248,14 +240,11 @@ static NTSTATUS ipc_open_generic(struct ntvfs_module_context *ntvfs,
status = dcesrv_endpoint_search_connect(private->dcesrv,
p,
ep_description,
- req->session_info,
+ h->session_info,
ntvfs->ctx->event_ctx,
0,
&p->dce_conn);
- if (!NT_STATUS_IS_OK(status)) {
- idr_remove(private->idtree_fnum, p->fnum);
- return status;
- }
+ NT_STATUS_NOT_OK_RETURN(status);
p->dce_conn->transport.private_data = private;
p->dce_conn->transport.report_output_data = NULL;
@@ -264,16 +253,14 @@ static NTSTATUS ipc_open_generic(struct ntvfs_module_context *ntvfs,
DLIST_ADD(private->pipe_list, p);
- p->smbpid = req->smbpid;
- p->session_info = req->session_info;
p->private = private;
- *ps = p;
-
- talloc_steal(private, p);
-
talloc_set_destructor(p, ipc_fd_destructor);
+ status = ntvfs_handle_set_backend_data(h, private->ntvfs, p);
+ NT_STATUS_NOT_OK_RETURN(status);
+
+ *ps = p;
return NT_STATUS_OK;
}
@@ -292,7 +279,7 @@ static NTSTATUS ipc_open_ntcreatex(struct ntvfs_module_context *ntvfs,
}
ZERO_STRUCT(oi->ntcreatex.out);
- oi->ntcreatex.out.file.fnum = p->fnum;
+ oi->ntcreatex.out.file.ntvfs= p->handle;
oi->ntcreatex.out.ipc_state = p->ipc_state;
oi->ntcreatex.out.file_type = FILE_TYPE_MESSAGE_MODE_PIPE;
@@ -315,7 +302,7 @@ static NTSTATUS ipc_open_openx(struct ntvfs_module_context *ntvfs,
}
ZERO_STRUCT(oi->openx.out);
- oi->openx.out.file.fnum = p->fnum;
+ oi->openx.out.file.ntvfs= p->handle;
oi->openx.out.ftype = 2;
oi->openx.out.devstate = p->ipc_state;
@@ -401,7 +388,6 @@ static NTSTATUS ipc_read(struct ntvfs_module_context *ntvfs,
{
struct ipc_private *private = ntvfs->private_data;
DATA_BLOB data;
- uint16_t fnum;
struct pipe_state *p;
NTSTATUS status = NT_STATUS_OK;
@@ -409,9 +395,7 @@ static NTSTATUS ipc_read(struct ntvfs_module_context *ntvfs,
return ntvfs_map_read(ntvfs, req, rd);
}
- fnum = rd->readx.in.file.fnum;
-
- p = pipe_state_find(private, fnum, req->session_info);
+ p = pipe_state_find(private, rd->readx.in.file.ntvfs);
if (!p) {
return NT_STATUS_INVALID_HANDLE;
}
@@ -444,7 +428,6 @@ static NTSTATUS ipc_write(struct ntvfs_module_context *ntvfs,
{
struct ipc_private *private = ntvfs->private_data;
DATA_BLOB data;
- uint16_t fnum;
struct pipe_state *p;
NTSTATUS status;
@@ -452,11 +435,10 @@ static NTSTATUS ipc_write(struct ntvfs_module_context *ntvfs,
return ntvfs_map_write(ntvfs, req, wr);
}
- fnum = wr->writex.in.file.fnum;
data.data = discard_const_p(void, wr->writex.in.data);
data.length = wr->writex.in.count;
- p = pipe_state_find(private, fnum, req->session_info);
+ p = pipe_state_find(private, wr->writex.in.file.ntvfs);
if (!p) {
return NT_STATUS_INVALID_HANDLE;
}
@@ -505,7 +487,7 @@ static NTSTATUS ipc_close(struct ntvfs_module_context *ntvfs,
return ntvfs_map_close(ntvfs, req, io);
}
- p = pipe_state_find(private, io->close.in.file.fnum, req->session_info);
+ p = pipe_state_find(private, io->close.in.file.ntvfs);
if (!p) {
return NT_STATUS_INVALID_HANDLE;
}
@@ -526,8 +508,8 @@ static NTSTATUS ipc_exit(struct ntvfs_module_context *ntvfs,
for (p=private->pipe_list; p; p=next) {
next = p->next;
- if (p->session_info == req->session_info &&
- p->smbpid == req->smbpid) {
+ if (p->handle->session_info == req->session_info &&
+ p->handle->smbpid == req->smbpid) {
talloc_free(p);
}
}
@@ -546,7 +528,7 @@ static NTSTATUS ipc_logoff(struct ntvfs_module_context *ntvfs,
for (p=private->pipe_list; p; p=next) {
next = p->next;
- if (p->session_info == req->session_info) {
+ if (p->handle->session_info == req->session_info) {
talloc_free(p);
}
}
@@ -674,9 +656,12 @@ static NTSTATUS ipc_dcerpc_cmd(struct ntvfs_module_context *ntvfs,
struct pipe_state *p;
struct ipc_private *private = ntvfs->private_data;
NTSTATUS status;
+ DATA_BLOB fnum_key;
/* the fnum is in setup[1] */
- p = pipe_state_find(private, trans->in.setup[1], req->session_info);
+ fnum_key = data_blob_const(&trans->in.setup[1], sizeof(trans->in.setup[1]));
+
+ p = pipe_state_find_key(private, req, &fnum_key);
if (!p) {
return NT_STATUS_INVALID_HANDLE;
}
@@ -715,13 +700,16 @@ static NTSTATUS ipc_dcerpc_cmd(struct ntvfs_module_context *ntvfs,
/* SMBtrans - set named pipe state */
static NTSTATUS ipc_set_nm_pipe_state(struct ntvfs_module_context *ntvfs,
- struct ntvfs_request *req, struct smb_trans2 *trans)
+ struct ntvfs_request *req, struct smb_trans2 *trans)
{
struct ipc_private *private = ntvfs->private_data;
struct pipe_state *p;
+ DATA_BLOB fnum_key;
/* the fnum is in setup[1] */
- p = pipe_state_find(private, trans->in.setup[1], req->session_info);
+ fnum_key = data_blob_const(&trans->in.setup[1], sizeof(trans->in.setup[1]));
+
+ p = pipe_state_find_key(private, req, &fnum_key);
if (!p) {
return NT_STATUS_INVALID_HANDLE;
}
diff --git a/source4/ntvfs/nbench/vfs_nbench.c b/source4/ntvfs/nbench/vfs_nbench.c
index 963d422cf0..2df3b95494 100644
--- a/source4/ntvfs/nbench/vfs_nbench.c
+++ b/source4/ntvfs/nbench/vfs_nbench.c
@@ -54,6 +54,26 @@ static void nbench_log(struct ntvfs_request *req,
free(s);
}
+static char *nbench_ntvfs_handle_string(struct ntvfs_request *req, struct ntvfs_handle *h)
+{
+ DATA_BLOB key;
+ uint16_t fnum = 0;
+
+ key = ntvfs_handle_get_wire_key(h, req);
+
+ switch (key.length) {
+ case 2: /* SMB fnum */
+ fnum = SVAL(key.data, 0);
+ break;
+ default:
+ DEBUG(0,("%s: invalid wire handle size: %u\n",
+ __FUNCTION__, key.length));
+ break;
+ }
+
+ return talloc_asprintf(req, "%u", fnum);
+}
+
/*
this pass through macro operates on request contexts, and disables
async calls.
@@ -237,8 +257,8 @@ static void nbench_qfileinfo_send(struct ntvfs_request *req)
{
union smb_fileinfo *info = req->async_states->private_data;
- nbench_log(req, "QUERY_FILE_INFORMATION %d %d %s\n",
- info->generic.in.file.fnum,
+ nbench_log(req, "QUERY_FILE_INFORMATION %s %d %s\n",
+ nbench_ntvfs_handle_string(req, info->generic.in.file.ntvfs),
info->generic.level,
get_nt_error_c_code(req->async_states->status));
@@ -292,11 +312,11 @@ static void nbench_open_send(struct ntvfs_request *req)
if (!NT_STATUS_IS_OK(req->async_states->status)) {
ZERO_STRUCT(io->ntcreatex.out);
}
- nbench_log(req, "NTCreateX \"%s\" 0x%x 0x%x %d %s\n",
+ nbench_log(req, "NTCreateX \"%s\" 0x%x 0x%x %s %s\n",
io->ntcreatex.in.fname,
io->ntcreatex.in.create_options,
io->ntcreatex.in.open_disposition,
- io->ntcreatex.out.file.fnum,
+ nbench_ntvfs_handle_string(req, io->ntcreatex.out.file.ntvfs),
get_nt_error_c_code(req->async_states->status));
break;
@@ -430,8 +450,8 @@ static void nbench_read_send(struct ntvfs_request *req)
if (!NT_STATUS_IS_OK(req->async_states->status)) {
ZERO_STRUCT(rd->readx.out);
}
- nbench_log(req, "ReadX %d %d %d %d %s\n",
- rd->readx.in.file.fnum,
+ nbench_log(req, "ReadX %s %d %d %d %s\n",
+ nbench_ntvfs_handle_string(req, rd->readx.in.file.ntvfs),
(int)rd->readx.in.offset,
rd->readx.in.maxcnt,
rd->readx.out.nread,
@@ -468,8 +488,8 @@ static void nbench_write_send(struct ntvfs_request *req)
if (!NT_STATUS_IS_OK(req->async_states->status)) {
ZERO_STRUCT(wr->writex.out);
}
- nbench_log(req, "WriteX %d %d %d %d %s\n",
- wr->writex.in.file.fnum,
+ nbench_log(req, "WriteX %s %d %d %d %s\n",
+ nbench_ntvfs_handle_string(req, wr->writex.in.file.ntvfs),
(int)wr->writex.in.offset,
wr->writex.in.count,
wr->writex.out.nwritten,
@@ -480,8 +500,8 @@ static void nbench_write_send(struct ntvfs_request *req)
if (!NT_STATUS_IS_OK(req->async_states->status)) {
ZERO_STRUCT(wr->write.out);
}
- nbench_log(req, "Write %d %d %d %d %s\n",
- wr->write.in.file.fnum,
+ nbench_log(req, "Write %s %d %d %d %s\n",
+ nbench_ntvfs_handle_string(req, wr->write.in.file.ntvfs),
wr->write.in.offset,
wr->write.in.count,
wr->write.out.nwritten,
@@ -534,20 +554,20 @@ static NTSTATUS nbench_seek(struct ntvfs_module_context *ntvfs,
static void nbench_flush_send(struct ntvfs_request *req)
{
union smb_flush *io = req->async_states->private_data;
- uint16_t fnum;
switch (io->generic.level) {
case RAW_FLUSH_FLUSH:
- fnum = io->flush.in.file.fnum;
+ nbench_log(req, "Flush %s %s\n",
+ nbench_ntvfs_handle_string(req, io->flush.in.file.ntvfs),
+ get_nt_error_c_code(req->async_states->status));
break;
case RAW_FLUSH_ALL:
- fnum = 0xFFFF;
+ nbench_log(req, "Flush %d %s\n",
+ 0xFFFF,
+ get_nt_error_c_code(req->async_states->status));
break;
}
- nbench_log(req, "Flush %d %s\n",
- fnum, get_nt_error_c_code(req->async_states->status));
-
PASS_THRU_REP_POST(req);
}
@@ -571,8 +591,8 @@ static void nbench_close_send(struct ntvfs_request *req)
switch (io->generic.level) {
case RAW_CLOSE_CLOSE:
- nbench_log(req, "Close %d %s\n",
- io->close.in.file.fnum,
+ nbench_log(req, "Close %s %s\n",
+ nbench_ntvfs_handle_string(req, io->close.in.file.ntvfs),
get_nt_error_c_code(req->async_states->status));
break;
@@ -686,15 +706,15 @@ static void nbench_lock_send(struct ntvfs_request *req)
if (lck->generic.level == RAW_LOCK_LOCKX &&
lck->lockx.in.lock_cnt == 1 &&
lck->lockx.in.ulock_cnt == 0) {
- nbench_log(req, "LockX %d %d %d %s\n",
- lck->lockx.in.file.fnum,
+ nbench_log(req, "LockX %s %d %d %s\n",
+ nbench_ntvfs_handle_string(req, lck->lockx.in.file.ntvfs),
(int)lck->lockx.in.locks[0].offset,
(int)lck->lockx.in.locks[0].count,
get_nt_error_c_code(req->async_states->status));
} else if (lck->generic.level == RAW_LOCK_LOCKX &&
lck->lockx.in.ulock_cnt == 1) {
- nbench_log(req, "UnlockX %d %d %d %s\n",
- lck->lockx.in.file.fnum,
+ nbench_log(req, "UnlockX %s %d %d %s\n",
+ nbench_ntvfs_handle_string(req, lck->lockx.in.file.ntvfs),
(int)lck->lockx.in.locks[0].offset,
(int)lck->lockx.in.locks[0].count,
get_nt_error_c_code(req->async_states->status));
@@ -722,8 +742,8 @@ static void nbench_setfileinfo_send(struct ntvfs_request *req)
{
union smb_setfileinfo *info = req->async_states->private_data;
- nbench_log(req, "SET_FILE_INFORMATION %d %d %s\n",
- info->generic.in.file.fnum,
+ nbench_log(req, "SET_FILE_INFORMATION %s %d %s\n",
+ nbench_ntvfs_handle_string(req, info->generic.in.file.ntvfs),
info->generic.level,
get_nt_error_c_code(req->async_states->status));
diff --git a/source4/ntvfs/ntvfs.h b/source4/ntvfs/ntvfs.h
index 9069e6c2ac..cf541de81e 100644
--- a/source4/ntvfs/ntvfs.h
+++ b/source4/ntvfs/ntvfs.h
@@ -191,7 +191,7 @@ struct ntvfs_context {
struct {
void *private_data;
- NTSTATUS (*handler)(void *private_data, uint16_t fnum, uint8_t level);
+ NTSTATUS (*handler)(void *private_data, struct ntvfs_handle *handle, uint8_t level);
} oplock;
struct {
@@ -199,8 +199,16 @@ struct ntvfs_context {
struct socket_address *(*get_my_addr)(void *private_data, TALLOC_CTX *mem_ctx);
struct socket_address *(*get_peer_addr)(void *private_data, TALLOC_CTX *mem_ctx);
} client;
-};
+ struct {
+ void *private_data;
+ NTSTATUS (*create_new)(void *private_data, struct ntvfs_request *req, struct ntvfs_handle **h);
+ NTSTATUS (*make_valid)(void *private_data, struct ntvfs_handle *h);
+ void (*destroy)(void *private_data, struct ntvfs_handle *h);
+ struct ntvfs_handle *(*search_by_wire_key)(void *private_data, struct ntvfs_request *req, const DATA_BLOB *key);
+ DATA_BLOB (*get_wire_key)(void *private_data, struct ntvfs_handle *handle, TALLOC_CTX *mem_ctx);
+ } handles;
+};
/* a set of flags to control handling of request structures */
#define NTVFS_ASYNC_STATE_ASYNC (1<<1) /* the backend will answer this one later */
@@ -253,6 +261,28 @@ struct ntvfs_request {
/* the system time when the request arrived */
struct timeval request_time;
} statistics;
+
+ struct {
+ void *private_data;
+ } frontend_data;
+};
+
+struct ntvfs_handle {
+ struct ntvfs_context *ctx;
+
+ struct auth_session_info *session_info;
+
+ uint16_t smbpid;
+
+ struct ntvfs_handle_data {
+ struct ntvfs_handle_data *prev, *next;
+ struct ntvfs_module_context *owner;
+ void *private_data;/* this must be a valid talloc pointer */
+ } *backend_data;
+
+ struct {
+ void *private_data;
+ } frontend_data;
};
/* this structure is used by backends to determine the size of some critical types */
@@ -264,6 +294,8 @@ struct ntvfs_critical_sizes {
int sizeof_ntvfs_ops;
int sizeof_ntvfs_async_state;
int sizeof_ntvfs_request;
+ int sizeof_ntvfs_handle;
+ int sizeof_ntvfs_handle_data;
};
#define NTVFS_CURRENT_CRITICAL_SIZES(c) \
@@ -275,6 +307,8 @@ struct ntvfs_critical_sizes {
.sizeof_ntvfs_ops = sizeof(struct ntvfs_ops), \
.sizeof_ntvfs_async_state = sizeof(struct ntvfs_async_state), \
.sizeof_ntvfs_request = sizeof(struct ntvfs_request), \
+ .sizeof_ntvfs_handle = sizeof(struct ntvfs_handle), \
+ .sizeof_ntvfs_handle_data = sizeof(struct ntvfs_handle_data), \
}
struct messaging_context;
diff --git a/source4/ntvfs/ntvfs_generic.c b/source4/ntvfs/ntvfs_generic.c
index b04a3af21e..5058225ceb 100644
--- a/source4/ntvfs/ntvfs_generic.c
+++ b/source4/ntvfs/ntvfs_generic.c
@@ -153,7 +153,7 @@ static NTSTATUS ntvfs_map_open_finish(struct ntvfs_module_context *ntvfs,
switch (io->generic.level) {
case RAW_OPEN_OPEN:
- io->openold.out.file.fnum = io2->generic.out.file.fnum;
+ io->openold.out.file.ntvfs = io2->generic.out.file.ntvfs;
io->openold.out.attrib = io2->generic.out.attrib;
io->openold.out.write_time = nt_time_to_unix(io2->generic.out.write_time);
io->openold.out.size = io2->generic.out.size;
@@ -161,7 +161,7 @@ static NTSTATUS ntvfs_map_open_finish(struct ntvfs_module_context *ntvfs,
break;
case RAW_OPEN_OPENX:
- io->openx.out.file.fnum = io2->generic.out.file.fnum;
+ io->openx.out.file.ntvfs = io2->generic.out.file.ntvfs;
io->openx.out.attrib = io2->generic.out.attrib;
io->openx.out.write_time = nt_time_to_unix(io2->generic.out.write_time);
io->openx.out.size = io2->generic.out.size;
@@ -181,7 +181,7 @@ static NTSTATUS ntvfs_map_open_finish(struct ntvfs_module_context *ntvfs,
break;
case RAW_OPEN_T2OPEN:
- io->t2open.out.file.fnum = io2->generic.out.file.fnum;
+ io->t2open.out.file.ntvfs = io2->generic.out.file.ntvfs;
io->t2open.out.attrib = io2->generic.out.attrib;
io->t2open.out.write_time = nt_time_to_unix(io2->generic.out.write_time);
io->t2open.out.size = io2->generic.out.size;
@@ -194,12 +194,12 @@ static NTSTATUS ntvfs_map_open_finish(struct ntvfs_module_context *ntvfs,
case RAW_OPEN_MKNEW:
case RAW_OPEN_CREATE:
- io->mknew.out.file.fnum = io2->generic.out.file.fnum;
+ io->mknew.out.file.ntvfs= io2->generic.out.file.ntvfs;
write_time = io->mknew.in.write_time;
break;
case RAW_OPEN_CTEMP:
- io->ctemp.out.file.fnum = io2->generic.out.file.fnum;
+ io->ctemp.out.file.ntvfs= io2->generic.out.file.ntvfs;
io->ctemp.out.name = talloc_strdup(req, io2->generic.in.fname +
strlen(io->ctemp.in.directory) + 1);
NT_STATUS_HAVE_NO_MEMORY(io->ctemp.out.name);
@@ -218,7 +218,7 @@ static NTSTATUS ntvfs_map_open_finish(struct ntvfs_module_context *ntvfs,
sf = talloc(req, union smb_setfileinfo);
NT_STATUS_HAVE_NO_MEMORY(sf);
sf->generic.level = RAW_SFILEINFO_STANDARD;
- sf->generic.in.file.fnum = io2->generic.out.file.fnum;
+ sf->generic.in.file.ntvfs = io2->generic.out.file.ntvfs;
sf->standard.in.create_time = 0;
sf->standard.in.write_time = write_time;
sf->standard.in.access_time = 0;
@@ -229,7 +229,7 @@ static NTSTATUS ntvfs_map_open_finish(struct ntvfs_module_context *ntvfs,
sf = talloc(req, union smb_setfileinfo);
NT_STATUS_HAVE_NO_MEMORY(sf);
sf->generic.level = RAW_SFILEINFO_END_OF_FILE_INFORMATION;
- sf->generic.in.file.fnum = io2->generic.out.file.fnum;
+ sf->generic.in.file.ntvfs = io2->generic.out.file.ntvfs;
sf->end_of_file_info.in.size = set_size;
status = ntvfs->ops->setfileinfo(ntvfs, req, sf);
if (NT_STATUS_IS_OK(status)) {
@@ -859,7 +859,7 @@ _PUBLIC_ NTSTATUS ntvfs_map_qfileinfo(struct ntvfs_module_context *ntvfs,
/* ask the backend for the generic info */
info2->generic.level = RAW_FILEINFO_GENERIC;
- info2->generic.in.file.fnum = info->generic.in.file.fnum;
+ info2->generic.in.file.ntvfs= info->generic.in.file.ntvfs;
/* only used by the simple backend, which doesn't do async */
req->async_states->state &= ~NTVFS_ASYNC_STATE_MAY_ASYNC;
@@ -941,7 +941,7 @@ _PUBLIC_ NTSTATUS ntvfs_map_lock(struct ntvfs_module_context *ntvfs,
}
lck2->generic.level = RAW_LOCK_GENERIC;
- lck2->generic.in.file.fnum = lck->lock.in.file.fnum;
+ lck2->generic.in.file.ntvfs= lck->lock.in.file.ntvfs;
lck2->generic.in.mode = 0;
lck2->generic.in.timeout = 0;
lck2->generic.in.locks = locks;
@@ -988,10 +988,10 @@ static NTSTATUS ntvfs_map_write_finish(struct ntvfs_module_context *ntvfs,
return NT_STATUS_NO_MEMORY;
}
- lck->unlock.level = RAW_LOCK_UNLOCK;
- lck->unlock.in.file.fnum= wr->writeunlock.in.file.fnum;
- lck->unlock.in.count = wr->writeunlock.in.count;
- lck->unlock.in.offset = wr->writeunlock.in.offset;
+ lck->unlock.level = RAW_LOCK_UNLOCK;
+ lck->unlock.in.file.ntvfs = wr->writeunlock.in.file.ntvfs;
+ lck->unlock.in.count = wr->writeunlock.in.count;
+ lck->unlock.in.offset = wr->writeunlock.in.offset;
if (lck->unlock.in.count != 0) {
/* do the lock sync for now */
@@ -1011,7 +1011,7 @@ static NTSTATUS ntvfs_map_write_finish(struct ntvfs_module_context *ntvfs,
}
cl->close.level = RAW_CLOSE_CLOSE;
- cl->close.in.file.fnum = wr->writeclose.in.file.fnum;
+ cl->close.in.file.ntvfs = wr->writeclose.in.file.ntvfs;
cl->close.in.write_time = wr->writeclose.in.mtime;
if (wr2->generic.in.count != 0) {
@@ -1062,7 +1062,7 @@ _PUBLIC_ NTSTATUS ntvfs_map_write(struct ntvfs_module_context *ntvfs,
break;
case RAW_WRITE_WRITE:
- wr2->writex.in.file.fnum = wr->write.in.file.fnum;
+ wr2->writex.in.file.ntvfs= wr->write.in.file.ntvfs;
wr2->writex.in.offset = wr->write.in.offset;
wr2->writex.in.wmode = 0;
wr2->writex.in.remaining = wr->write.in.remaining;
@@ -1072,7 +1072,7 @@ _PUBLIC_ NTSTATUS ntvfs_map_write(struct ntvfs_module_context *ntvfs,
break;
case RAW_WRITE_WRITEUNLOCK:
- wr2->writex.in.file.fnum = wr->writeunlock.in.file.fnum;
+ wr2->writex.in.file.ntvfs= wr->writeunlock.in.file.ntvfs;
wr2->writex.in.offset = wr->writeunlock.in.offset;
wr2->writex.in.wmode = 0;
wr2->writex.in.remaining = wr->writeunlock.in.remaining;
@@ -1082,7 +1082,7 @@ _PUBLIC_ NTSTATUS ntvfs_map_write(struct ntvfs_module_context *ntvfs,
break;
case RAW_WRITE_WRITECLOSE:
- wr2->writex.in.file.fnum = wr->writeclose.in.file.fnum;
+ wr2->writex.in.file.ntvfs= wr->writeclose.in.file.ntvfs;
wr2->writex.in.offset = wr->writeclose.in.offset;
wr2->writex.in.wmode = 0;
wr2->writex.in.remaining = 0;
@@ -1092,7 +1092,7 @@ _PUBLIC_ NTSTATUS ntvfs_map_write(struct ntvfs_module_context *ntvfs,
break;
case RAW_WRITE_SPLWRITE:
- wr2->writex.in.file.fnum = wr->splwrite.in.file.fnum;
+ wr2->writex.in.file.ntvfs= wr->splwrite.in.file.ntvfs;
wr2->writex.in.offset = 0;
wr2->writex.in.wmode = 0;
wr2->writex.in.remaining = 0;
@@ -1164,7 +1164,7 @@ _PUBLIC_ NTSTATUS ntvfs_map_read(struct ntvfs_module_context *ntvfs,
break;
case RAW_READ_READ:
- rd2->readx.in.file.fnum = rd->read.in.file.fnum;
+ rd2->readx.in.file.ntvfs= rd->read.in.file.ntvfs;
rd2->readx.in.offset = rd->read.in.offset;
rd2->readx.in.mincnt = rd->read.in.count;
rd2->readx.in.maxcnt = rd->read.in.count;
@@ -1174,7 +1174,7 @@ _PUBLIC_ NTSTATUS ntvfs_map_read(struct ntvfs_module_context *ntvfs,
break;
case RAW_READ_READBRAW:
- rd2->readx.in.file.fnum = rd->readbraw.in.file.fnum;
+ rd2->readx.in.file.ntvfs= rd->readbraw.in.file.ntvfs;
rd2->readx.in.offset = rd->readbraw.in.offset;
rd2->readx.in.mincnt = rd->readbraw.in.mincnt;
rd2->readx.in.maxcnt = rd->readbraw.in.maxcnt;
@@ -1194,13 +1194,13 @@ _PUBLIC_ NTSTATUS ntvfs_map_read(struct ntvfs_module_context *ntvfs,
goto done;
}
lck->lock.level = RAW_LOCK_LOCK;
- lck->lock.in.file.fnum = rd->lockread.in.file.fnum;
+ lck->lock.in.file.ntvfs = rd->lockread.in.file.ntvfs;
lck->lock.in.count = rd->lockread.in.count;
lck->lock.in.offset = rd->lockread.in.offset;
status = ntvfs->ops->lock(ntvfs, req, lck);
req->async_states->state = state;
- rd2->readx.in.file.fnum = rd->lockread.in.file.fnum;
+ rd2->readx.in.file.ntvfs= rd->lockread.in.file.ntvfs;
rd2->readx.in.offset = rd->lockread.in.offset;
rd2->readx.in.mincnt = rd->lockread.in.count;
rd2->readx.in.maxcnt = rd->lockread.in.count;
@@ -1238,7 +1238,7 @@ _PUBLIC_ NTSTATUS ntvfs_map_close(struct ntvfs_module_context *ntvfs,
case RAW_CLOSE_SPLCLOSE:
cl2->close.level = RAW_CLOSE_CLOSE;
- cl2->close.in.file.fnum = cl->splclose.in.file.fnum;
+ cl2->close.in.file.ntvfs= cl->splclose.in.file.ntvfs;
break;
}
diff --git a/source4/ntvfs/ntvfs_interface.c b/source4/ntvfs/ntvfs_interface.c
index c26832d96e..67cbe8df22 100644
--- a/source4/ntvfs/ntvfs_interface.c
+++ b/source4/ntvfs/ntvfs_interface.c
@@ -668,7 +668,7 @@ _PUBLIC_ NTSTATUS ntvfs_next_exit(struct ntvfs_module_context *ntvfs,
/* oplock helpers */
_PUBLIC_ NTSTATUS ntvfs_set_oplock_handler(struct ntvfs_context *ntvfs,
- NTSTATUS (*handler)(void *private_data, uint16_t fnum, uint8_t level),
+ NTSTATUS (*handler)(void *private_data, struct ntvfs_handle *handle, uint8_t level),
void *private_data)
{
ntvfs->oplock.handler = handler;
@@ -677,13 +677,13 @@ _PUBLIC_ NTSTATUS ntvfs_set_oplock_handler(struct ntvfs_context *ntvfs,
}
_PUBLIC_ NTSTATUS ntvfs_send_oplock_break(struct ntvfs_module_context *ntvfs,
- uint16_t fnum, uint8_t level)
+ struct ntvfs_handle *handle, uint8_t level)
{
if (!ntvfs->ctx->oplock.handler) {
return NT_STATUS_OK;
}
- return ntvfs->ctx->oplock.handler(ntvfs->ctx->oplock.private_data, fnum, level);
+ return ntvfs->ctx->oplock.handler(ntvfs->ctx->oplock.private_data, handle, level);
}
/* client connection callback */
diff --git a/source4/ntvfs/ntvfs_util.c b/source4/ntvfs/ntvfs_util.c
index 52f03430ce..de19a9c352 100644
--- a/source4/ntvfs/ntvfs_util.c
+++ b/source4/ntvfs/ntvfs_util.c
@@ -98,3 +98,100 @@ _PUBLIC_ void ntvfs_async_state_pop(struct ntvfs_request *req)
talloc_free(async);
}
+
+_PUBLIC_ NTSTATUS ntvfs_handle_new(struct ntvfs_module_context *ntvfs,
+ struct ntvfs_request *req,
+ struct ntvfs_handle **h)
+{
+ return ntvfs->ctx->handles.create_new(ntvfs->ctx->handles.private_data, req, h);
+}
+
+_PUBLIC_ NTSTATUS ntvfs_handle_set_backend_data(struct ntvfs_handle *h,
+ struct ntvfs_module_context *ntvfs,
+ TALLOC_CTX *private_data)
+{
+ struct ntvfs_handle_data *d;
+ BOOL first_time = h->backend_data?False:True;
+
+ for (d=h->backend_data; d; d = d->next) {
+ if (d->owner != ntvfs) continue;
+ d->private_data = talloc_steal(d, private_data);
+ return NT_STATUS_OK;
+ }
+
+ d = talloc(h, struct ntvfs_handle_data);
+ NT_STATUS_HAVE_NO_MEMORY(d);
+ d->owner = ntvfs;
+ d->private_data = talloc_steal(d, private_data);
+
+ DLIST_ADD(h->backend_data, d);
+
+ if (first_time) {
+ NTSTATUS status;
+ status = h->ctx->handles.make_valid(h->ctx->handles.private_data, h);
+ NT_STATUS_NOT_OK_RETURN(status);
+ }
+
+ return NT_STATUS_OK;
+}
+
+_PUBLIC_ void *ntvfs_handle_get_backend_data(struct ntvfs_handle *h,
+ struct ntvfs_module_context *ntvfs)
+{
+ struct ntvfs_handle_data *d;
+
+ for (d=h->backend_data; d; d = d->next) {
+ if (d->owner != ntvfs) continue;
+ return d->private_data;
+ }
+
+ return NULL;
+}
+
+_PUBLIC_ void ntvfs_handle_remove_backend_data(struct ntvfs_handle *h,
+ struct ntvfs_module_context *ntvfs)
+{
+ struct ntvfs_handle_data *d,*n;
+
+ for (d=h->backend_data; d; d = n) {
+ n = d->next;
+ if (d->owner != ntvfs) continue;
+ DLIST_REMOVE(h->backend_data, d);
+ talloc_free(d);
+ d = NULL;
+ }
+
+ if (h->backend_data) return;
+
+ /* if there's no backend_data anymore, destroy the handle */
+ h->ctx->handles.destroy(h->ctx->handles.private_data, h);
+}
+
+_PUBLIC_ struct ntvfs_handle *ntvfs_handle_search_by_wire_key(struct ntvfs_module_context *ntvfs,
+ struct ntvfs_request *req,
+ const DATA_BLOB *key)
+{
+ return ntvfs->ctx->handles.search_by_wire_key(ntvfs->ctx->handles.private_data, req, key);
+}
+
+_PUBLIC_ DATA_BLOB ntvfs_handle_get_wire_key(struct ntvfs_handle *h, TALLOC_CTX *mem_ctx)
+{
+ return h->ctx->handles.get_wire_key(h->ctx->handles.private_data, h, mem_ctx);
+}
+
+_PUBLIC_ NTSTATUS ntvfs_set_handle_callbacks(struct ntvfs_context *ntvfs,
+ NTSTATUS (*create_new)(void *private_data, struct ntvfs_request *req, struct ntvfs_handle **h),
+ NTSTATUS (*make_valid)(void *private_data, struct ntvfs_handle *h),
+ void (*destroy)(void *private_data, struct ntvfs_handle *h),
+ struct ntvfs_handle *(*search_by_wire_key)(void *private_data, struct ntvfs_request *req, const DATA_BLOB *key),
+ DATA_BLOB (*get_wire_key)(void *private_data, struct ntvfs_handle *handle, TALLOC_CTX *mem_ctx),
+ void *private_data)
+{
+ ntvfs->handles.create_new = create_new;
+ ntvfs->handles.make_valid = make_valid;
+ ntvfs->handles.destroy = destroy;
+ ntvfs->handles.search_by_wire_key = search_by_wire_key;
+ ntvfs->handles.get_wire_key = get_wire_key;
+ ntvfs->handles.private_data = private_data;
+ return NT_STATUS_OK;
+}
diff --git a/source4/ntvfs/posix/pvfs_flush.c b/source4/ntvfs/posix/pvfs_flush.c
index c1d8820c43..7bd973ed4e 100644
--- a/source4/ntvfs/posix/pvfs_flush.c
+++ b/source4/ntvfs/posix/pvfs_flush.c
@@ -48,7 +48,7 @@ NTSTATUS pvfs_flush(struct ntvfs_module_context *ntvfs,
switch (io->generic.level) {
case RAW_FLUSH_FLUSH:
- f = pvfs_find_fd(pvfs, req, io->flush.in.file.fnum);
+ f = pvfs_find_fd(pvfs, req, io->flush.in.file.ntvfs);
if (!f) {
return NT_STATUS_INVALID_HANDLE;
}
diff --git a/source4/ntvfs/posix/pvfs_ioctl.c b/source4/ntvfs/posix/pvfs_ioctl.c
index 829da47a12..417458edf0 100644
--- a/source4/ntvfs/posix/pvfs_ioctl.c
+++ b/source4/ntvfs/posix/pvfs_ioctl.c
@@ -42,7 +42,7 @@ static NTSTATUS pvfs_ntioctl(struct ntvfs_module_context *ntvfs,
struct pvfs_state *pvfs = ntvfs->private_data;
struct pvfs_file *f;
- f = pvfs_find_fd(pvfs, req, io->ntioctl.in.file.fnum);
+ f = pvfs_find_fd(pvfs, req, io->ntioctl.in.file.ntvfs);
if (!f) {
return NT_STATUS_INVALID_HANDLE;
}
diff --git a/source4/ntvfs/posix/pvfs_lock.c b/source4/ntvfs/posix/pvfs_lock.c
index 99b694665d..8dcee5f983 100644
--- a/source4/ntvfs/posix/pvfs_lock.c
+++ b/source4/ntvfs/posix/pvfs_lock.c
@@ -244,7 +244,7 @@ static NTSTATUS pvfs_lock_cancel(struct pvfs_state *pvfs, struct ntvfs_request *
/* check if the lock request matches exactly - you can only cancel with exact matches */
if (p->lck->lockx.in.ulock_cnt == lck->lockx.in.ulock_cnt &&
p->lck->lockx.in.lock_cnt == lck->lockx.in.lock_cnt &&
- p->lck->lockx.in.file.fnum == lck->lockx.in.file.fnum &&
+ p->lck->lockx.in.file.ntvfs== lck->lockx.in.file.ntvfs &&
p->lck->lockx.in.mode == (lck->lockx.in.mode & ~LOCKING_ANDX_CANCEL_LOCK)) {
int i;
@@ -286,7 +286,7 @@ NTSTATUS pvfs_lock(struct ntvfs_module_context *ntvfs,
return ntvfs_map_lock(ntvfs, req, lck);
}
- f = pvfs_find_fd(pvfs, req, lck->lockx.in.file.fnum);
+ f = pvfs_find_fd(pvfs, req, lck->lockx.in.file.ntvfs);
if (!f) {
return NT_STATUS_INVALID_HANDLE;
}
diff --git a/source4/ntvfs/posix/pvfs_notify.c b/source4/ntvfs/posix/pvfs_notify.c
index ea4c0b2bc6..dfe1737060 100644
--- a/source4/ntvfs/posix/pvfs_notify.c
+++ b/source4/ntvfs/posix/pvfs_notify.c
@@ -203,7 +203,7 @@ NTSTATUS pvfs_notify(struct ntvfs_module_context *ntvfs,
NTSTATUS status;
struct notify_pending *pending;
- f = pvfs_find_fd(pvfs, req, info->in.file.fnum);
+ f = pvfs_find_fd(pvfs, req, info->in.file.ntvfs);
if (!f) {
return NT_STATUS_INVALID_HANDLE;
}
diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c
index 3bbf840154..fd382ba1d9 100644
--- a/source4/ntvfs/posix/pvfs_open.c
+++ b/source4/ntvfs/posix/pvfs_open.c
@@ -29,39 +29,28 @@
#include "librpc/gen_ndr/xattr.h"
/*
- create file handles with convenient numbers for sniffers
-*/
-#define PVFS_MIN_FILE_FNUM 0x100
-#define PVFS_MIN_NEW_FNUM 0x200
-#define PVFS_MIN_DIR_FNUM 0x300
-
-/*
find open file handle given fnum
*/
struct pvfs_file *pvfs_find_fd(struct pvfs_state *pvfs,
- struct ntvfs_request *req, uint16_t fnum)
+ struct ntvfs_request *req, struct ntvfs_handle *h)
{
+ void *p;
struct pvfs_file *f;
- f = idr_find(pvfs->files.idtree, fnum);
- if (f == NULL) {
- return NULL;
- }
+ p = ntvfs_handle_get_backend_data(h, pvfs->ntvfs);
+ if (!p) return NULL;
- if (f->fnum != fnum) {
- smb_panic("pvfs_find_fd: idtree_fnum corruption\n");
- }
+ f = talloc_get_type(p, struct pvfs_file);
+ if (!f) return NULL;
if (req->session_info != f->session_info) {
- DEBUG(2,("pvfs_find_fd: attempt to use wrong session for fnum %d\n",
- fnum));
+ DEBUG(2,("pvfs_find_fd: attempt to use wrong session for handle %p\n",h));
return NULL;
}
return f;
}
-
/*
cleanup a open directory handle
*/
@@ -114,8 +103,10 @@ static int pvfs_dir_handle_destructor(void *p)
static int pvfs_dir_fnum_destructor(void *p)
{
struct pvfs_file *f = p;
+
DLIST_REMOVE(f->pvfs->files.list, f);
- idr_remove(f->pvfs->files.idtree, f->fnum);
+ ntvfs_handle_remove_backend_data(f->ntvfs, f->pvfs->ntvfs);
+
return 0;
}
@@ -125,7 +116,7 @@ static int pvfs_dir_fnum_destructor(void *p)
static NTSTATUS pvfs_open_setup_eas_acl(struct pvfs_state *pvfs,
struct ntvfs_request *req,
struct pvfs_filename *name,
- int fd, int fnum,
+ int fd, struct pvfs_file *f,
union smb_open *io)
{
NTSTATUS status;
@@ -150,7 +141,7 @@ static NTSTATUS pvfs_open_setup_eas_acl(struct pvfs_state *pvfs,
* but the user doesn't have SeSecurityPrivilege
* - w2k3 allows it
*/
- set.set_secdesc.in.file.fnum = fnum;
+ set.set_secdesc.in.file.ntvfs = f->ntvfs;
set.set_secdesc.in.secinfo_flags = SECINFO_DACL;
set.set_secdesc.in.sd = io->ntcreatex.in.sec_desc;
@@ -197,7 +188,7 @@ static NTSTATUS pvfs_open_directory(struct pvfs_state *pvfs,
union smb_open *io)
{
struct pvfs_file *f;
- int fnum;
+ struct ntvfs_handle *h;
NTSTATUS status;
uint32_t create_action;
uint32_t access_mask = io->generic.in.access_mask;
@@ -242,7 +233,10 @@ static NTSTATUS pvfs_open_directory(struct pvfs_state *pvfs,
return NT_STATUS_INVALID_PARAMETER;
}
- f = talloc(req, struct pvfs_file);
+ status = ntvfs_handle_new(pvfs->ntvfs, req, &h);
+ NT_STATUS_NOT_OK_RETURN(status);
+
+ f = talloc(h, struct pvfs_file);
if (f == NULL) {
return NT_STATUS_NO_MEMORY;
}
@@ -252,11 +246,6 @@ static NTSTATUS pvfs_open_directory(struct pvfs_state *pvfs,
return NT_STATUS_NO_MEMORY;
}
- fnum = idr_get_new_above(pvfs->files.idtree, f, PVFS_MIN_DIR_FNUM, UINT16_MAX);
- if (fnum == -1) {
- return NT_STATUS_TOO_MANY_OPENED_FILES;
- }
-
if (name->exists) {
/* check the security descriptor */
status = pvfs_access_check(pvfs, req, name, &access_mask);
@@ -264,11 +253,10 @@ static NTSTATUS pvfs_open_directory(struct pvfs_state *pvfs,
status = pvfs_access_check_create(pvfs, req, name, &access_mask);
}
if (!NT_STATUS_IS_OK(status)) {
- idr_remove(pvfs->files.idtree, fnum);
return status;
}
- f->fnum = fnum;
+ f->ntvfs = h;
f->session_info = req->session_info;
f->smbpid = req->smbpid;
f->pvfs = pvfs;
@@ -297,12 +285,10 @@ static NTSTATUS pvfs_open_directory(struct pvfs_state *pvfs,
del_on_close = False;
}
-
if (name->exists) {
/* form the lock context used for opendb locking */
status = pvfs_locking_key(name, f->handle, &f->handle->odb_locking_key);
if (!NT_STATUS_IS_OK(status)) {
- idr_remove(pvfs->files.idtree, f->fnum);
return status;
}
@@ -313,7 +299,6 @@ static NTSTATUS pvfs_open_directory(struct pvfs_state *pvfs,
name->full_name));
/* we were supposed to do a blocking lock, so something
is badly wrong! */
- idr_remove(pvfs->files.idtree, fnum);
return NT_STATUS_INTERNAL_DB_CORRUPTION;
}
@@ -323,7 +308,6 @@ static NTSTATUS pvfs_open_directory(struct pvfs_state *pvfs,
name->full_name, OPLOCK_NONE, NULL);
if (!NT_STATUS_IS_OK(status)) {
- idr_remove(pvfs->files.idtree, f->fnum);
talloc_free(lck);
return status;
}
@@ -342,7 +326,6 @@ static NTSTATUS pvfs_open_directory(struct pvfs_state *pvfs,
mode_t mode = pvfs_fileperms(pvfs, attrib);
if (mkdir(name->full_name, mode) == -1) {
- idr_remove(pvfs->files.idtree, fnum);
return pvfs_map_errno(pvfs,errno);
}
@@ -353,7 +336,7 @@ static NTSTATUS pvfs_open_directory(struct pvfs_state *pvfs,
goto cleanup_delete;
}
- status = pvfs_open_setup_eas_acl(pvfs, req, name, -1, fnum, io);
+ status = pvfs_open_setup_eas_acl(pvfs, req, name, -1, f, io);
if (!NT_STATUS_IS_OK(status)) {
goto cleanup_delete;
}
@@ -361,7 +344,6 @@ static NTSTATUS pvfs_open_directory(struct pvfs_state *pvfs,
/* form the lock context used for opendb locking */
status = pvfs_locking_key(name, f->handle, &f->handle->odb_locking_key);
if (!NT_STATUS_IS_OK(status)) {
- idr_remove(pvfs->files.idtree, f->fnum);
return status;
}
@@ -371,7 +353,6 @@ static NTSTATUS pvfs_open_directory(struct pvfs_state *pvfs,
name->full_name));
/* we were supposed to do a blocking lock, so something
is badly wrong! */
- idr_remove(pvfs->files.idtree, fnum);
return NT_STATUS_INTERNAL_DB_CORRUPTION;
}
@@ -396,15 +377,17 @@ static NTSTATUS pvfs_open_directory(struct pvfs_state *pvfs,
}
if (!name->exists) {
- idr_remove(pvfs->files.idtree, fnum);
return NT_STATUS_OBJECT_NAME_NOT_FOUND;
}
/* the open succeeded, keep this handle permanently */
- talloc_steal(pvfs, f);
+ status = ntvfs_handle_set_backend_data(h, pvfs->ntvfs, f);
+ if (!NT_STATUS_IS_OK(status)) {
+ goto cleanup_delete;
+ }
io->generic.out.oplock_level = OPLOCK_NONE;
- io->generic.out.file.fnum = f->fnum;
+ io->generic.out.file.ntvfs = h;
io->generic.out.create_action = create_action;
io->generic.out.create_time = name->dos.create_time;
io->generic.out.access_time = name->dos.access_time;
@@ -420,7 +403,6 @@ static NTSTATUS pvfs_open_directory(struct pvfs_state *pvfs,
return NT_STATUS_OK;
cleanup_delete:
- idr_remove(pvfs->files.idtree, fnum);
rmdir(name->full_name);
return status;
}
@@ -510,11 +492,11 @@ static int pvfs_handle_destructor(void *p)
*/
static int pvfs_fnum_destructor(void *p)
{
- struct pvfs_file *f = p;
+ struct pvfs_file *f = talloc_get_type(p, struct pvfs_file);
DLIST_REMOVE(f->pvfs->files.list, f);
pvfs_lock_close(f->pvfs, f);
- idr_remove(f->pvfs->files.idtree, f->fnum);
+ ntvfs_handle_remove_backend_data(f->ntvfs, f->pvfs->ntvfs);
return 0;
}
@@ -527,8 +509,8 @@ static int pvfs_fnum_destructor(void *p)
locking space)
*/
static NTSTATUS pvfs_brl_locking_handle(TALLOC_CTX *mem_ctx,
- struct pvfs_filename *name,
- uint16_t fnum,
+ struct pvfs_filename *name,
+ struct ntvfs_handle *ntvfs,
struct brl_handle **_h)
{
DATA_BLOB odb_key, key;
@@ -550,7 +532,7 @@ static NTSTATUS pvfs_brl_locking_handle(TALLOC_CTX *mem_ctx,
data_blob_free(&odb_key);
}
- h = brl_create_handle(mem_ctx, &key, fnum);
+ h = brl_create_handle(mem_ctx, ntvfs, &key);
NT_STATUS_HAVE_NO_MEMORY(h);
*_h = h;
@@ -567,7 +549,8 @@ static NTSTATUS pvfs_create_file(struct pvfs_state *pvfs,
{
struct pvfs_file *f;
NTSTATUS status;
- int flags, fnum, fd;
+ struct ntvfs_handle *h;
+ int flags, fd;
struct odb_lock *lck;
uint32_t create_options = io->generic.in.create_options;
uint32_t share_access = io->generic.in.share_access;
@@ -606,20 +589,14 @@ static NTSTATUS pvfs_create_file(struct pvfs_state *pvfs,
flags = O_RDONLY;
}
- f = talloc(req, struct pvfs_file);
- if (f == NULL) {
- return NT_STATUS_NO_MEMORY;
- }
+ status = ntvfs_handle_new(pvfs->ntvfs, req, &h);
+ NT_STATUS_NOT_OK_RETURN(status);
- f->handle = talloc(f, struct pvfs_file_handle);
- if (f->handle == NULL) {
- return NT_STATUS_NO_MEMORY;
- }
+ f = talloc(h, struct pvfs_file);
+ NT_STATUS_HAVE_NO_MEMORY(f);
- fnum = idr_get_new_above(pvfs->files.idtree, f, PVFS_MIN_NEW_FNUM, UINT16_MAX);
- if (fnum == -1) {
- return NT_STATUS_TOO_MANY_OPENED_FILES;
- }
+ f->handle = talloc(f, struct pvfs_file_handle);
+ NT_STATUS_HAVE_NO_MEMORY(f->handle);
attrib = io->ntcreatex.in.file_attr | FILE_ATTRIBUTE_ARCHIVE;
mode = pvfs_fileperms(pvfs, attrib);
@@ -627,7 +604,6 @@ static NTSTATUS pvfs_create_file(struct pvfs_state *pvfs,
/* create the file */
fd = open(name->full_name, flags | O_CREAT | O_EXCL, mode);
if (fd == -1) {
- idr_remove(pvfs->files.idtree, fnum);
return pvfs_map_errno(pvfs, errno);
}
@@ -637,7 +613,6 @@ static NTSTATUS pvfs_create_file(struct pvfs_state *pvfs,
if (name->stream_name) {
status = pvfs_stream_create(pvfs, name, fd);
if (!NT_STATUS_IS_OK(status)) {
- idr_remove(pvfs->files.idtree, fnum);
close(fd);
return status;
}
@@ -646,7 +621,6 @@ static NTSTATUS pvfs_create_file(struct pvfs_state *pvfs,
/* re-resolve the open fd */
status = pvfs_resolve_name_fd(pvfs, fd, name);
if (!NT_STATUS_IS_OK(status)) {
- idr_remove(pvfs->files.idtree, fnum);
close(fd);
return status;
}
@@ -658,7 +632,7 @@ static NTSTATUS pvfs_create_file(struct pvfs_state *pvfs,
}
- status = pvfs_open_setup_eas_acl(pvfs, req, name, fd, fnum, io);
+ status = pvfs_open_setup_eas_acl(pvfs, req, name, fd, f, io);
if (!NT_STATUS_IS_OK(status)) {
goto cleanup_delete;
}
@@ -670,7 +644,7 @@ static NTSTATUS pvfs_create_file(struct pvfs_state *pvfs,
goto cleanup_delete;
}
- status = pvfs_brl_locking_handle(f, name, fnum, &f->brl_handle);
+ status = pvfs_brl_locking_handle(f, name, h, &f->brl_handle);
if (!NT_STATUS_IS_OK(status)) {
goto cleanup_delete;
}
@@ -708,7 +682,6 @@ static NTSTATUS pvfs_create_file(struct pvfs_state *pvfs,
/* bad news, we must have hit a race - we don't delete the file
here as the most likely scenario is that someone else created
the file at the same time */
- idr_remove(pvfs->files.idtree, fnum);
close(fd);
return status;
}
@@ -717,7 +690,7 @@ static NTSTATUS pvfs_create_file(struct pvfs_state *pvfs,
oplock_granted = OPLOCK_BATCH;
}
- f->fnum = fnum;
+ f->ntvfs = h;
f->session_info = req->session_info;
f->smbpid = req->smbpid;
f->pvfs = pvfs;
@@ -746,7 +719,7 @@ static NTSTATUS pvfs_create_file(struct pvfs_state *pvfs,
talloc_set_destructor(f->handle, pvfs_handle_destructor);
io->generic.out.oplock_level = oplock_granted;
- io->generic.out.file.fnum = f->fnum;
+ io->generic.out.file.ntvfs = f->ntvfs;
io->generic.out.create_action = NTCREATEX_ACTION_CREATED;
io->generic.out.create_time = name->dos.create_time;
io->generic.out.access_time = name->dos.access_time;
@@ -760,7 +733,10 @@ static NTSTATUS pvfs_create_file(struct pvfs_state *pvfs,
io->generic.out.is_directory = 0;
/* success - keep the file handle */
- talloc_steal(pvfs, f);
+ status = ntvfs_handle_set_backend_data(h, pvfs->ntvfs, f);
+ if (!NT_STATUS_IS_OK(status)) {
+ goto cleanup_delete;
+ }
notify_trigger(pvfs->notify_context,
NOTIFY_ACTION_ADDED,
@@ -770,7 +746,6 @@ static NTSTATUS pvfs_create_file(struct pvfs_state *pvfs,
return NT_STATUS_OK;
cleanup_delete:
- idr_remove(pvfs->files.idtree, fnum);
close(fd);
unlink(name->full_name);
return status;
@@ -873,6 +848,7 @@ static NTSTATUS pvfs_open_deny_dos(struct ntvfs_module_context *ntvfs,
struct pvfs_state *pvfs = ntvfs->private_data;
struct pvfs_file *f2;
struct pvfs_filename *name;
+ NTSTATUS status;
/* search for an existing open with the right parameters. Note
the magic ntcreatex options flag, which is set in the
@@ -919,7 +895,7 @@ static NTSTATUS pvfs_open_deny_dos(struct ntvfs_module_context *ntvfs,
name = f->handle->name;
io->generic.out.oplock_level = OPLOCK_NONE;
- io->generic.out.file.fnum = f->fnum;
+ io->generic.out.file.ntvfs = f->ntvfs;
io->generic.out.create_action = NTCREATEX_ACTION_EXISTED;
io->generic.out.create_time = name->dos.create_time;
io->generic.out.access_time = name->dos.access_time;
@@ -931,8 +907,9 @@ static NTSTATUS pvfs_open_deny_dos(struct ntvfs_module_context *ntvfs,
io->generic.out.file_type = FILE_TYPE_DISK;
io->generic.out.ipc_state = 0;
io->generic.out.is_directory = 0;
-
- talloc_steal(f->pvfs, f);
+
+ status = ntvfs_handle_set_backend_data(f->ntvfs, ntvfs, f);
+ NT_STATUS_NOT_OK_RETURN(status);
return NT_STATUS_OK;
}
@@ -1009,8 +986,9 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs,
int flags;
struct pvfs_filename *name;
struct pvfs_file *f;
+ struct ntvfs_handle *h;
NTSTATUS status;
- int fnum, fd;
+ int fd;
struct odb_lock *lck;
uint32_t create_options;
uint32_t share_access;
@@ -1128,7 +1106,10 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs,
return status;
}
- f = talloc(req, struct pvfs_file);
+ status = ntvfs_handle_new(pvfs->ntvfs, req, &h);
+ NT_STATUS_NOT_OK_RETURN(status);
+
+ f = talloc(h, struct pvfs_file);
if (f == NULL) {
return NT_STATUS_NO_MEMORY;
}
@@ -1138,13 +1119,7 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs,
return NT_STATUS_NO_MEMORY;
}
- /* allocate a fnum */
- fnum = idr_get_new_above(pvfs->files.idtree, f, PVFS_MIN_FILE_FNUM, UINT16_MAX);
- if (fnum == -1) {
- return NT_STATUS_TOO_MANY_OPENED_FILES;
- }
-
- f->fnum = fnum;
+ f->ntvfs = h;
f->session_info = req->session_info;
f->smbpid = req->smbpid;
f->pvfs = pvfs;
@@ -1169,13 +1144,11 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs,
opendb locking */
status = pvfs_locking_key(name, f->handle, &f->handle->odb_locking_key);
if (!NT_STATUS_IS_OK(status)) {
- idr_remove(pvfs->files.idtree, f->fnum);
return status;
}
- status = pvfs_brl_locking_handle(f, name, f->fnum, &f->brl_handle);
+ status = pvfs_brl_locking_handle(f, name, h, &f->brl_handle);
if (!NT_STATUS_IS_OK(status)) {
- idr_remove(pvfs->files.idtree, f->fnum);
return status;
}
@@ -1186,7 +1159,6 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs,
name->full_name));
/* we were supposed to do a blocking lock, so something
is badly wrong! */
- idr_remove(pvfs->files.idtree, fnum);
return NT_STATUS_INTERNAL_DB_CORRUPTION;
}
@@ -1288,8 +1260,11 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs,
talloc_free(lck);
+ status = ntvfs_handle_set_backend_data(h, ntvfs, f);
+ NT_STATUS_NOT_OK_RETURN(status);
+
io->generic.out.oplock_level = oplock_granted;
- io->generic.out.file.fnum = f->fnum;
+ io->generic.out.file.ntvfs = h;
io->generic.out.create_action = stream_existed?
NTCREATEX_ACTION_EXISTED:NTCREATEX_ACTION_CREATED;
io->generic.out.create_time = name->dos.create_time;
@@ -1303,9 +1278,6 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs,
io->generic.out.ipc_state = 0;
io->generic.out.is_directory = 0;
- /* success - keep the file handle */
- talloc_steal(f->pvfs, f);
-
return NT_STATUS_OK;
}
@@ -1328,7 +1300,7 @@ NTSTATUS pvfs_close(struct ntvfs_module_context *ntvfs,
return ntvfs_map_close(ntvfs, req, io);
}
- f = pvfs_find_fd(pvfs, req, io->close.in.file.fnum);
+ f = pvfs_find_fd(pvfs, req, io->close.in.file.ntvfs);
if (!f) {
return NT_STATUS_INVALID_HANDLE;
}
diff --git a/source4/ntvfs/posix/pvfs_qfileinfo.c b/source4/ntvfs/posix/pvfs_qfileinfo.c
index e4e69a8289..2d43c5a582 100644
--- a/source4/ntvfs/posix/pvfs_qfileinfo.c
+++ b/source4/ntvfs/posix/pvfs_qfileinfo.c
@@ -336,7 +336,7 @@ NTSTATUS pvfs_qfileinfo(struct ntvfs_module_context *ntvfs,
NTSTATUS status;
uint32_t access_needed;
- f = pvfs_find_fd(pvfs, req, info->generic.in.file.fnum);
+ f = pvfs_find_fd(pvfs, req, info->generic.in.file.ntvfs);
if (!f) {
return NT_STATUS_INVALID_HANDLE;
}
diff --git a/source4/ntvfs/posix/pvfs_read.c b/source4/ntvfs/posix/pvfs_read.c
index 411fbd9c27..13e8264000 100644
--- a/source4/ntvfs/posix/pvfs_read.c
+++ b/source4/ntvfs/posix/pvfs_read.c
@@ -41,7 +41,7 @@ NTSTATUS pvfs_read(struct ntvfs_module_context *ntvfs,
return ntvfs_map_read(ntvfs, req, rd);
}
- f = pvfs_find_fd(pvfs, req, rd->readx.in.file.fnum);
+ f = pvfs_find_fd(pvfs, req, rd->readx.in.file.ntvfs);
if (!f) {
return NT_STATUS_INVALID_HANDLE;
}
diff --git a/source4/ntvfs/posix/pvfs_seek.c b/source4/ntvfs/posix/pvfs_seek.c
index dbfb4e1c3d..7365f33b15 100644
--- a/source4/ntvfs/posix/pvfs_seek.c
+++ b/source4/ntvfs/posix/pvfs_seek.c
@@ -35,7 +35,7 @@ NTSTATUS pvfs_seek(struct ntvfs_module_context *ntvfs,
struct pvfs_file_handle *h;
NTSTATUS status;
- f = pvfs_find_fd(pvfs, req, io->lseek.in.file.fnum);
+ f = pvfs_find_fd(pvfs, req, io->lseek.in.file.ntvfs);
if (!f) {
return NT_STATUS_INVALID_HANDLE;
}
diff --git a/source4/ntvfs/posix/pvfs_setfileinfo.c b/source4/ntvfs/posix/pvfs_setfileinfo.c
index e85f52fc2c..2665b9e5f5 100644
--- a/source4/ntvfs/posix/pvfs_setfileinfo.c
+++ b/source4/ntvfs/posix/pvfs_setfileinfo.c
@@ -262,7 +262,7 @@ NTSTATUS pvfs_setfileinfo(struct ntvfs_module_context *ntvfs,
uint32_t access_needed;
uint32_t change_mask = 0;
- f = pvfs_find_fd(pvfs, req, info->generic.in.file.fnum);
+ f = pvfs_find_fd(pvfs, req, info->generic.in.file.ntvfs);
if (!f) {
return NT_STATUS_INVALID_HANDLE;
}
diff --git a/source4/ntvfs/posix/pvfs_write.c b/source4/ntvfs/posix/pvfs_write.c
index 1da1985550..9f58281919 100644
--- a/source4/ntvfs/posix/pvfs_write.c
+++ b/source4/ntvfs/posix/pvfs_write.c
@@ -40,7 +40,7 @@ NTSTATUS pvfs_write(struct ntvfs_module_context *ntvfs,
return ntvfs_map_write(ntvfs, req, wr);
}
- f = pvfs_find_fd(pvfs, req, wr->writex.in.file.fnum);
+ f = pvfs_find_fd(pvfs, req, wr->writex.in.file.ntvfs);
if (!f) {
return NT_STATUS_INVALID_HANDLE;
}
diff --git a/source4/ntvfs/posix/vfs_posix.c b/source4/ntvfs/posix/vfs_posix.c
index eeee00313b..1682a94ac9 100644
--- a/source4/ntvfs/posix/vfs_posix.c
+++ b/source4/ntvfs/posix/vfs_posix.c
@@ -194,10 +194,6 @@ static NTSTATUS pvfs_connect(struct ntvfs_module_context *ntvfs,
return NT_STATUS_INTERNAL_DB_CORRUPTION;
}
- /* allocate the fnum id -> ptr tree */
- pvfs->files.idtree = idr_init(pvfs);
- NT_STATUS_HAVE_NO_MEMORY(pvfs->files.idtree);
-
/* allocate the search handle -> ptr tree */
pvfs->search.idtree = idr_init(pvfs);
NT_STATUS_HAVE_NO_MEMORY(pvfs->search.idtree);
diff --git a/source4/ntvfs/posix/vfs_posix.h b/source4/ntvfs/posix/vfs_posix.h
index 39481c03b1..63ee3395f8 100644
--- a/source4/ntvfs/posix/vfs_posix.h
+++ b/source4/ntvfs/posix/vfs_posix.h
@@ -63,9 +63,6 @@ struct pvfs_state {
uint32_t alloc_size_rounding;
struct {
- /* an id tree mapping open file handle -> struct pvfs_file */
- struct idr_context *idtree;
-
/* the open files as DLINKLIST */
struct pvfs_file *list;
} files;
@@ -156,7 +153,7 @@ struct pvfs_file_handle {
struct pvfs_file {
struct pvfs_file *next, *prev;
struct pvfs_file_handle *handle;
- uint16_t fnum;
+ struct ntvfs_handle *ntvfs;
struct pvfs_state *pvfs;
diff --git a/source4/ntvfs/simple/svfs.h b/source4/ntvfs/simple/svfs.h
index 74e7b6c452..e5ad3b95d9 100644
--- a/source4/ntvfs/simple/svfs.h
+++ b/source4/ntvfs/simple/svfs.h
@@ -1,5 +1,7 @@
struct svfs_private {
+ struct ntvfs_module_context *ntvfs;
+
/* the base directory */
char *connectpath;
@@ -24,6 +26,7 @@ struct svfs_dir {
struct svfs_file {
struct svfs_file *next, *prev;
int fd;
+ struct ntvfs_handle *handle;
char *name;
};
diff --git a/source4/ntvfs/simple/vfs_simple.c b/source4/ntvfs/simple/vfs_simple.c
index 1698f57aee..e0f0083630 100644
--- a/source4/ntvfs/simple/vfs_simple.c
+++ b/source4/ntvfs/simple/vfs_simple.c
@@ -55,7 +55,8 @@ static NTSTATUS svfs_connect(struct ntvfs_module_context *ntvfs,
int snum = ntvfs->ctx->config.snum;
private = talloc(ntvfs, struct svfs_private);
-
+ NT_STATUS_HAVE_NO_MEMORY(private);
+ private->ntvfs = ntvfs;
private->next_search_handle = 0;
private->connectpath = talloc_strdup(private, lp_pathname(snum));
private->open_files = NULL;
@@ -91,15 +92,18 @@ static NTSTATUS svfs_disconnect(struct ntvfs_module_context *ntvfs)
/*
find open file handle given fd
*/
-static struct svfs_file *find_fd(struct svfs_private *private, int fd)
+static struct svfs_file *find_fd(struct svfs_private *private, struct ntvfs_handle *handle)
{
struct svfs_file *f;
- for (f=private->open_files;f;f=f->next) {
- if (f->fd == fd) {
- return f;
- }
- }
- return NULL;
+ void *p;
+
+ p = ntvfs_handle_get_backend_data(handle, private->ntvfs);
+ if (!p) return NULL;
+
+ f = talloc_get_type(p, struct svfs_file);
+ if (!f) return NULL;
+
+ return f;
}
/*
@@ -282,12 +286,12 @@ static NTSTATUS svfs_qfileinfo(struct ntvfs_module_context *ntvfs,
return ntvfs_map_qfileinfo(ntvfs, req, info);
}
- f = find_fd(private, info->generic.in.file.fnum);
+ f = find_fd(private, info->generic.in.file.ntvfs);
if (!f) {
return NT_STATUS_INVALID_HANDLE;
}
- if (fstat(info->generic.in.file.fnum, &st) == -1) {
+ if (fstat(f->fd, &st) == -1) {
return map_nt_error_from_unix(errno);
}
@@ -308,6 +312,8 @@ static NTSTATUS svfs_open(struct ntvfs_module_context *ntvfs,
struct svfs_file *f;
int create_flags, rdwr_flags;
BOOL readonly;
+ NTSTATUS status;
+ struct ntvfs_handle *handle;
if (io->generic.level != RAW_OPEN_GENERIC) {
return ntvfs_map_open(ntvfs, req, io);
@@ -379,7 +385,10 @@ do_open:
return map_nt_error_from_unix(errno);
}
- f = talloc(ntvfs, struct svfs_file);
+ status = ntvfs_handle_new(ntvfs, req, &handle);
+ NT_STATUS_NOT_OK_RETURN(status);
+
+ f = talloc(handle, struct svfs_file);
NT_STATUS_HAVE_NO_MEMORY(f);
f->fd = fd;
f->name = talloc_strdup(f, unix_path);
@@ -387,13 +396,16 @@ do_open:
DLIST_ADD(private->open_files, f);
+ status = ntvfs_handle_set_backend_data(handle, ntvfs, f);
+ NT_STATUS_NOT_OK_RETURN(status);
+
ZERO_STRUCT(io->generic.out);
unix_to_nt_time(&io->generic.out.create_time, st.st_ctime);
unix_to_nt_time(&io->generic.out.access_time, st.st_atime);
unix_to_nt_time(&io->generic.out.write_time, st.st_mtime);
unix_to_nt_time(&io->generic.out.change_time, st.st_mtime);
- io->generic.out.file.fnum = fd;
+ io->generic.out.file.ntvfs = handle;
io->generic.out.alloc_size = st.st_size;
io->generic.out.size = st.st_size;
io->generic.out.attrib = svfs_unix_to_dos_attrib(st.st_mode);
@@ -483,13 +495,20 @@ static NTSTATUS svfs_copy(struct ntvfs_module_context *ntvfs,
static NTSTATUS svfs_read(struct ntvfs_module_context *ntvfs,
struct ntvfs_request *req, union smb_read *rd)
{
+ struct svfs_private *private = ntvfs->private_data;
+ struct svfs_file *f;
ssize_t ret;
if (rd->generic.level != RAW_READ_READX) {
return NT_STATUS_NOT_SUPPORTED;
}
- ret = pread(rd->readx.in.file.fnum,
+ f = find_fd(private, rd->readx.in.file.ntvfs);
+ if (!f) {
+ return NT_STATUS_INVALID_HANDLE;
+ }
+
+ ret = pread(f->fd,
rd->readx.out.data,
rd->readx.in.maxcnt,
rd->readx.in.offset);
@@ -510,6 +529,8 @@ static NTSTATUS svfs_read(struct ntvfs_module_context *ntvfs,
static NTSTATUS svfs_write(struct ntvfs_module_context *ntvfs,
struct ntvfs_request *req, union smb_write *wr)
{
+ struct svfs_private *private = ntvfs->private_data;
+ struct svfs_file *f;
ssize_t ret;
if (wr->generic.level != RAW_WRITE_WRITEX) {
@@ -518,7 +539,12 @@ static NTSTATUS svfs_write(struct ntvfs_module_context *ntvfs,
CHECK_READ_ONLY(req);
- ret = pwrite(wr->writex.in.file.fnum,
+ f = find_fd(private, wr->writex.in.file.ntvfs);
+ if (!f) {
+ return NT_STATUS_INVALID_HANDLE;
+ }
+
+ ret = pwrite(f->fd,
wr->writex.in.data,
wr->writex.in.count,
wr->writex.in.offset);
@@ -554,7 +580,11 @@ static NTSTATUS svfs_flush(struct ntvfs_module_context *ntvfs,
switch (io->generic.level) {
case RAW_FLUSH_FLUSH:
- fsync(io->flush.in.file.fnum);
+ f = find_fd(private, io->flush.in.file.ntvfs);
+ if (!f) {
+ return NT_STATUS_INVALID_HANDLE;
+ }
+ fsync(f->fd);
return NT_STATUS_OK;
case RAW_FLUSH_ALL:
@@ -582,12 +612,12 @@ static NTSTATUS svfs_close(struct ntvfs_module_context *ntvfs,
return NT_STATUS_INVALID_LEVEL;
}
- f = find_fd(private, io->close.in.file.fnum);
+ f = find_fd(private, io->close.in.file.ntvfs);
if (!f) {
return NT_STATUS_INVALID_HANDLE;
}
- if (close(io->close.in.file.fnum) == -1) {
+ if (close(f->fd) == -1) {
return map_nt_error_from_unix(errno);
}
@@ -662,15 +692,21 @@ static NTSTATUS svfs_setfileinfo(struct ntvfs_module_context *ntvfs,
struct ntvfs_request *req,
union smb_setfileinfo *info)
{
+ struct svfs_private *private = ntvfs->private_data;
+ struct svfs_file *f;
struct utimbuf unix_times;
- int fd;
CHECK_READ_ONLY(req);
-
+
+ f = find_fd(private, info->generic.in.file.ntvfs);
+ if (!f) {
+ return NT_STATUS_INVALID_HANDLE;
+ }
+
switch (info->generic.level) {
case RAW_SFILEINFO_END_OF_FILE_INFO:
case RAW_SFILEINFO_END_OF_FILE_INFORMATION:
- if (ftruncate(info->end_of_file_info.in.file.fnum,
+ if (ftruncate(f->fd,
info->end_of_file_info.in.size) == -1) {
return map_nt_error_from_unix(errno);
}
@@ -678,8 +714,7 @@ static NTSTATUS svfs_setfileinfo(struct ntvfs_module_context *ntvfs,
case RAW_SFILEINFO_SETATTRE:
unix_times.actime = info->setattre.in.access_time;
unix_times.modtime = info->setattre.in.write_time;
- fd = info->setattre.in.file.fnum;
-
+
if (unix_times.actime == 0 && unix_times.modtime == 0) {
break;
}
@@ -690,7 +725,7 @@ static NTSTATUS svfs_setfileinfo(struct ntvfs_module_context *ntvfs,
}
/* Set the date on this file */
- if (svfs_file_utime(fd, &unix_times) != 0) {
+ if (svfs_file_utime(f->fd, &unix_times) != 0) {
return NT_STATUS_ACCESS_DENIED;
}
break;