summaryrefslogtreecommitdiff
path: root/source4/ntvfs
diff options
context:
space:
mode:
authorAndrew Tridgell <tridge@samba.org>2004-11-07 10:05:35 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 13:05:37 -0500
commit2db915e06564b42bf7ebfa526b1af2e42e591590 (patch)
treea6cb2c29dcdc0278f8afd5b2ed9bdff9dce73d00 /source4/ntvfs
parent5f608f23d32003456ebeed0ef6afdfd3f40aea25 (diff)
downloadsamba-2db915e06564b42bf7ebfa526b1af2e42e591590.tar.gz
samba-2db915e06564b42bf7ebfa526b1af2e42e591590.tar.bz2
samba-2db915e06564b42bf7ebfa526b1af2e42e591590.zip
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)
Diffstat (limited to 'source4/ntvfs')
-rw-r--r--source4/ntvfs/posix/pvfs_lock.c2
-rw-r--r--source4/ntvfs/posix/pvfs_open.c10
-rw-r--r--source4/ntvfs/posix/pvfs_setfileinfo.c31
-rw-r--r--source4/ntvfs/posix/pvfs_wait.c6
-rw-r--r--source4/ntvfs/posix/vfs_posix.h3
5 files changed, 46 insertions, 6 deletions
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;