From 62e58ea7180e265ffe79b998e7488f20909d3fa0 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 24 Oct 2004 14:18:03 +0000 Subject: r3161: pvfs now passes the RAW-SEEK test (This used to be commit a953d4a42c8fa3fe930c319d5157fc406a1035da) --- source4/ntvfs/posix/config.mk | 1 + source4/ntvfs/posix/pvfs_open.c | 6 +++ source4/ntvfs/posix/pvfs_qfileinfo.c | 6 ++- source4/ntvfs/posix/pvfs_read.c | 2 + source4/ntvfs/posix/pvfs_seek.c | 62 +++++++++++++++++++++++++++++++ source4/ntvfs/posix/pvfs_setfileinfo.c | 67 ++++++++++++++++++++++++++++++++++ source4/ntvfs/posix/pvfs_write.c | 2 + source4/ntvfs/posix/vfs_posix.c | 20 ---------- source4/ntvfs/posix/vfs_posix.h | 4 ++ 9 files changed, 149 insertions(+), 21 deletions(-) create mode 100644 source4/ntvfs/posix/pvfs_seek.c (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/config.mk b/source4/ntvfs/posix/config.mk index 0d6f295097..8d28bd5a44 100644 --- a/source4/ntvfs/posix/config.mk +++ b/source4/ntvfs/posix/config.mk @@ -22,6 +22,7 @@ ADD_OBJ_FILES = \ ntvfs/posix/pvfs_shortname.o \ ntvfs/posix/pvfs_lock.o \ ntvfs/posix/pvfs_wait.o \ + ntvfs/posix/pvfs_seek.o \ ntvfs/common/opendb.o \ ntvfs/common/brlock.o # End MODULE ntvfs_posix diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c index 44a09fe25d..e587ebbf95 100644 --- a/source4/ntvfs/posix/pvfs_open.c +++ b/source4/ntvfs/posix/pvfs_open.c @@ -137,6 +137,8 @@ static NTSTATUS pvfs_open_directory(struct pvfs_state *pvfs, f->locking_key = data_blob(NULL, 0); f->create_options = io->generic.in.create_options; f->share_access = io->generic.in.share_access; + f->seek_offset = 0; + f->position = 0; DLIST_ADD(pvfs->open_files, f); @@ -354,6 +356,8 @@ static NTSTATUS pvfs_create_file(struct pvfs_state *pvfs, f->create_options = io->generic.in.create_options; f->share_access = io->generic.in.share_access; f->access_mask = io->generic.in.access_mask; + f->seek_offset = 0; + f->position = 0; DLIST_ADD(pvfs->open_files, f); @@ -548,6 +552,8 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs, f->create_options = io->generic.in.create_options; f->share_access = io->generic.in.share_access; f->access_mask = io->generic.in.access_mask; + f->seek_offset = 0; + f->position = 0; DLIST_ADD(pvfs->open_files, f); diff --git a/source4/ntvfs/posix/pvfs_qfileinfo.c b/source4/ntvfs/posix/pvfs_qfileinfo.c index 78d0983bf6..1a6ff0ae26 100644 --- a/source4/ntvfs/posix/pvfs_qfileinfo.c +++ b/source4/ntvfs/posix/pvfs_qfileinfo.c @@ -127,5 +127,9 @@ NTSTATUS pvfs_qfileinfo(struct ntvfs_module_context *ntvfs, return status; } - return pvfs_map_fileinfo(pvfs, req, f->name, info); + status = pvfs_map_fileinfo(pvfs, req, f->name, info); + + info->generic.out.position = f->position; + + return status; } diff --git a/source4/ntvfs/posix/pvfs_read.c b/source4/ntvfs/posix/pvfs_read.c index 530fb82798..eb821d1f31 100644 --- a/source4/ntvfs/posix/pvfs_read.c +++ b/source4/ntvfs/posix/pvfs_read.c @@ -67,6 +67,8 @@ NTSTATUS pvfs_read(struct ntvfs_module_context *ntvfs, return pvfs_map_errno(pvfs, errno); } + f->position = f->seek_offset = rd->readx.in.offset + ret; + rd->readx.out.nread = ret; rd->readx.out.remaining = 0; /* should fill this in? */ rd->readx.out.compaction_mode = 0; diff --git a/source4/ntvfs/posix/pvfs_seek.c b/source4/ntvfs/posix/pvfs_seek.c new file mode 100644 index 0000000000..f965e584ee --- /dev/null +++ b/source4/ntvfs/posix/pvfs_seek.c @@ -0,0 +1,62 @@ +/* + Unix SMB/CIFS implementation. + + POSIX NTVFS backend - seek + + Copyright (C) Andrew Tridgell 2004 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "include/includes.h" +#include "vfs_posix.h" + +/* + seek in a file +*/ +NTSTATUS pvfs_seek(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, struct smb_seek *io) +{ + struct pvfs_state *pvfs = ntvfs->private_data; + struct pvfs_file *f; + NTSTATUS status; + + f = pvfs_find_fd(pvfs, req, io->in.fnum); + if (!f) { + return NT_STATUS_INVALID_HANDLE; + } + + status = NT_STATUS_OK; + + switch (io->in.mode) { + case SEEK_MODE_START: + f->seek_offset = io->in.offset; + break; + + case SEEK_MODE_CURRENT: + f->seek_offset += io->in.offset; + break; + + case SEEK_MODE_END: + status = pvfs_resolve_name_fd(pvfs, f->fd, f->name); + f->seek_offset = f->name->st.st_size + io->in.offset; + break; + } + + io->out.offset = f->seek_offset; + + return status; +} + diff --git a/source4/ntvfs/posix/pvfs_setfileinfo.c b/source4/ntvfs/posix/pvfs_setfileinfo.c index 74b0ed85c5..42ee8a971c 100644 --- a/source4/ntvfs/posix/pvfs_setfileinfo.c +++ b/source4/ntvfs/posix/pvfs_setfileinfo.c @@ -80,7 +80,74 @@ NTSTATUS pvfs_setfileinfo(struct ntvfs_module_context *ntvfs, create_options &= ~NTCREATEX_OPTIONS_DELETE_ON_CLOSE; } return pvfs_change_create_options(pvfs, req, f, create_options); + + case RAW_SFILEINFO_POSITION_INFORMATION: + f->position = info->position_information.in.position; + break; } return NT_STATUS_OK; } + + +/* + set info on a pathname +*/ +NTSTATUS pvfs_setpathinfo(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, union smb_setfileinfo *info) +{ + struct pvfs_state *pvfs = ntvfs->private_data; + struct pvfs_filename *name; + NTSTATUS status; + struct utimbuf unix_times; + + /* resolve the cifs name to a posix name */ + status = pvfs_resolve_name(pvfs, req, info->generic.file.fname, + PVFS_RESOLVE_NO_WILDCARD, &name); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + if (!name->exists) { + return NT_STATUS_OBJECT_NAME_NOT_FOUND; + } + + switch (info->generic.level) { + case RAW_SFILEINFO_END_OF_FILE_INFO: + case RAW_SFILEINFO_END_OF_FILE_INFORMATION: + if (truncate(name->full_name, + info->end_of_file_info.in.size) == -1) { + return pvfs_map_errno(pvfs, errno); + } + break; + + case RAW_SFILEINFO_SETATTRE: + unix_times.actime = info->setattre.in.access_time; + unix_times.modtime = info->setattre.in.write_time; + + if (unix_times.actime == 0 && unix_times.modtime == 0) { + break; + } + + /* set modify time = to access time if modify time was 0 */ + if (unix_times.actime != 0 && unix_times.modtime == 0) { + unix_times.modtime = unix_times.actime; + } + + /* Set the date on this file */ + if (utime(name->full_name, &unix_times) == -1) { + return NT_STATUS_ACCESS_DENIED; + } + break; + + case RAW_SFILEINFO_DISPOSITION_INFO: + case RAW_SFILEINFO_DISPOSITION_INFORMATION: + return NT_STATUS_INVALID_PARAMETER; + + case RAW_SFILEINFO_POSITION_INFORMATION: + return NT_STATUS_OK; + } + + return NT_STATUS_INVALID_LEVEL; +} + diff --git a/source4/ntvfs/posix/pvfs_write.c b/source4/ntvfs/posix/pvfs_write.c index a7b7084a08..7ab1d340bd 100644 --- a/source4/ntvfs/posix/pvfs_write.c +++ b/source4/ntvfs/posix/pvfs_write.c @@ -67,6 +67,8 @@ NTSTATUS pvfs_write(struct ntvfs_module_context *ntvfs, if (ret == -1) { return map_nt_error_from_unix(errno); } + + f->seek_offset = wr->writex.in.offset + ret; wr->writex.out.nwritten = ret; wr->writex.out.remaining = 0; /* should fill this in? */ diff --git a/source4/ntvfs/posix/vfs_posix.c b/source4/ntvfs/posix/vfs_posix.c index 383dbf7a16..64f0e09f59 100644 --- a/source4/ntvfs/posix/vfs_posix.c +++ b/source4/ntvfs/posix/vfs_posix.c @@ -179,26 +179,6 @@ static NTSTATUS pvfs_copy(struct ntvfs_module_context *ntvfs, return NT_STATUS_NOT_SUPPORTED; } -/* - seek in a file -*/ -static NTSTATUS pvfs_seek(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, struct smb_seek *io) -{ - DEBUG(0,("pvfs_seek not implemented\n")); - return NT_STATUS_NOT_SUPPORTED; -} - -/* - set info on a pathname -*/ -static NTSTATUS pvfs_setpathinfo(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, union smb_setfileinfo *st) -{ - DEBUG(0,("pvfs_setpathinfo not implemented\n")); - return NT_STATUS_NOT_SUPPORTED; -} - /* return print queue info */ diff --git a/source4/ntvfs/posix/vfs_posix.h b/source4/ntvfs/posix/vfs_posix.h index 0bd01f5377..d4c0b19974 100644 --- a/source4/ntvfs/posix/vfs_posix.h +++ b/source4/ntvfs/posix/vfs_posix.h @@ -125,6 +125,10 @@ struct pvfs_file { uint32_t create_options; uint32_t share_access; uint32_t access_mask; + + /* yes, we need 2 independent positions ... */ + uint64_t seek_offset; + uint64_t position; }; -- cgit