From 2db915e06564b42bf7ebfa526b1af2e42e591590 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 7 Nov 2004 10:05:35 +0000 Subject: r3595: - fixed a talloc_free ordering problem on cleanup with pending requests - added initial support for MODE_INFORMATION in setfileinfo (I have no idea what "mode information" on a file is - it takes a value of 0, 2, 4 or 6. What could it be?) (This used to be commit e53ec2f6b68e1d19149c36ea8fcd25a204db38fb) --- source4/ntvfs/posix/pvfs_lock.c | 2 +- source4/ntvfs/posix/pvfs_open.c | 10 ++++++++++ source4/ntvfs/posix/pvfs_setfileinfo.c | 31 +++++++++++++++++++++++++++++++ source4/ntvfs/posix/pvfs_wait.c | 6 +----- source4/ntvfs/posix/vfs_posix.h | 3 +++ 5 files changed, 46 insertions(+), 6 deletions(-) (limited to 'source4/ntvfs/posix') diff --git a/source4/ntvfs/posix/pvfs_lock.c b/source4/ntvfs/posix/pvfs_lock.c index 446ff1f30b..c8fc6c2de3 100644 --- a/source4/ntvfs/posix/pvfs_lock.c +++ b/source4/ntvfs/posix/pvfs_lock.c @@ -295,7 +295,7 @@ NTSTATUS pvfs_lock(struct ntvfs_module_context *ntvfs, if (lck->lockx.in.timeout != 0 && (req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) { - pending = talloc_p(req, struct pvfs_pending_lock); + pending = talloc_p(f, struct pvfs_pending_lock); if (pending == NULL) { return NT_STATUS_NO_MEMORY; } diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c index f30d53d51a..1a25f57df1 100644 --- a/source4/ntvfs/posix/pvfs_open.c +++ b/source4/ntvfs/posix/pvfs_open.c @@ -142,6 +142,7 @@ static NTSTATUS pvfs_open_directory(struct pvfs_state *pvfs, f->share_access = io->generic.in.share_access; f->seek_offset = 0; f->position = 0; + f->mode = 0; DLIST_ADD(pvfs->open_files, f); @@ -362,6 +363,7 @@ static NTSTATUS pvfs_create_file(struct pvfs_state *pvfs, } status = odb_open_file(lck, fnum, share_access, create_options, access_mask); + talloc_free(lck); if (!NT_STATUS_IS_OK(status)) { /* bad news, we must have hit a race */ idr_remove(pvfs->idtree_fnum, fnum); @@ -382,6 +384,7 @@ static NTSTATUS pvfs_create_file(struct pvfs_state *pvfs, f->access_mask = access_mask; f->seek_offset = 0; f->position = 0; + f->mode = 0; f->have_opendb_entry = True; DLIST_ADD(pvfs->open_files, f); @@ -433,6 +436,7 @@ static int pvfs_retry_destructor(void *ptr) if (lck != NULL) { odb_remove_pending(lck, r); } + talloc_free(lck); } return 0; } @@ -768,6 +772,7 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs, } if (!NT_STATUS_IS_OK(status)) { + talloc_free(lck); return status; } @@ -776,6 +781,7 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs, /* do the actual open */ fd = open(f->name->full_name, flags); if (fd == -1) { + talloc_free(lck); return pvfs_map_errno(f->pvfs, errno); } @@ -784,6 +790,7 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs, /* re-resolve the open fd */ status = pvfs_resolve_name_fd(f->pvfs, fd, f->name); if (!NT_STATUS_IS_OK(status)) { + talloc_free(lck); return status; } @@ -793,15 +800,18 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs, uint32_t attrib = io->ntcreatex.in.file_attr | FILE_ATTRIBUTE_ARCHIVE; mode_t mode = pvfs_fileperms(pvfs, attrib); if (fchmod(fd, mode) == -1) { + talloc_free(lck); return map_nt_error_from_unix(errno); } name->dos.attrib = attrib; status = pvfs_dosattrib_save(pvfs, name, fd); if (!NT_STATUS_IS_OK(status)) { + talloc_free(lck); return status; } } + talloc_free(lck); io->generic.out.oplock_level = NO_OPLOCK; io->generic.out.fnum = f->fnum; diff --git a/source4/ntvfs/posix/pvfs_setfileinfo.c b/source4/ntvfs/posix/pvfs_setfileinfo.c index 22997be94d..15b7f168f2 100644 --- a/source4/ntvfs/posix/pvfs_setfileinfo.c +++ b/source4/ntvfs/posix/pvfs_setfileinfo.c @@ -171,6 +171,9 @@ NTSTATUS pvfs_setfileinfo(struct ntvfs_module_context *ntvfs, case RAW_SFILEINFO_ALLOCATION_INFO: case RAW_SFILEINFO_ALLOCATION_INFORMATION: newstats.dos.alloc_size = info->allocation_info.in.alloc_size; + if (newstats.dos.alloc_size < newstats.st.st_size) { + newstats.st.st_size = newstats.dos.alloc_size; + } break; case RAW_SFILEINFO_END_OF_FILE_INFO: @@ -182,6 +185,17 @@ NTSTATUS pvfs_setfileinfo(struct ntvfs_module_context *ntvfs, f->position = info->position_information.in.position; break; + case RAW_SFILEINFO_MODE_INFORMATION: + /* this one is a puzzle */ + if (info->mode_information.in.mode != 0 && + info->mode_information.in.mode != 2 && + info->mode_information.in.mode != 4 && + info->mode_information.in.mode != 6) { + return NT_STATUS_INVALID_PARAMETER; + } + f->mode = info->mode_information.in.mode; + break; + default: return NT_STATUS_INVALID_LEVEL; } @@ -310,7 +324,15 @@ NTSTATUS pvfs_setpathinfo(struct ntvfs_module_context *ntvfs, case RAW_SFILEINFO_ALLOCATION_INFO: case RAW_SFILEINFO_ALLOCATION_INFORMATION: + if (info->allocation_info.in.alloc_size > newstats.dos.alloc_size) { + /* strange. Increasing the allocation size via setpathinfo + should be silently ignored */ + break; + } newstats.dos.alloc_size = info->allocation_info.in.alloc_size; + if (newstats.dos.alloc_size < newstats.st.st_size) { + newstats.st.st_size = newstats.dos.alloc_size; + } break; case RAW_SFILEINFO_END_OF_FILE_INFO: @@ -318,6 +340,15 @@ NTSTATUS pvfs_setpathinfo(struct ntvfs_module_context *ntvfs, newstats.st.st_size = info->end_of_file_info.in.size; break; + case RAW_SFILEINFO_MODE_INFORMATION: + if (info->mode_information.in.mode != 0 && + info->mode_information.in.mode != 2 && + info->mode_information.in.mode != 4 && + info->mode_information.in.mode != 6) { + return NT_STATUS_INVALID_PARAMETER; + } + return NT_STATUS_OK; + case RAW_SFILEINFO_DISPOSITION_INFO: case RAW_SFILEINFO_DISPOSITION_INFORMATION: case RAW_SFILEINFO_POSITION_INFORMATION: diff --git a/source4/ntvfs/posix/pvfs_wait.c b/source4/ntvfs/posix/pvfs_wait.c index a226918877..968f659421 100644 --- a/source4/ntvfs/posix/pvfs_wait.c +++ b/source4/ntvfs/posix/pvfs_wait.c @@ -137,7 +137,7 @@ static int pvfs_wait_destructor(void *ptr) pwait->msg_ctx = pvfs->tcon->smb_conn->connection->messaging_ctx; pwait->ev = req->tcon->smb_conn->connection->event.ctx; pwait->msg_type = msg_type; - pwait->req = req; + pwait->req = talloc_reference(pwait, req); pwait->pvfs = pvfs; /* setup a timer */ @@ -162,10 +162,6 @@ static int pvfs_wait_destructor(void *ptr) /* make sure we cleanup the timer and message handler */ talloc_set_destructor(pwait, pvfs_wait_destructor); - /* make sure that on a disconnect the request is not destroyed - before pvfs */ - talloc_steal(pvfs, req); - return pwait; } diff --git a/source4/ntvfs/posix/vfs_posix.h b/source4/ntvfs/posix/vfs_posix.h index 64b9a0d653..91940e6355 100644 --- a/source4/ntvfs/posix/vfs_posix.h +++ b/source4/ntvfs/posix/vfs_posix.h @@ -116,6 +116,9 @@ struct pvfs_file { uint32_t share_access; uint32_t access_mask; + /* this is set by the mode_information level. What does it do? */ + uint32_t mode; + /* yes, we need 2 independent positions ... */ uint64_t seek_offset; uint64_t position; -- cgit