summaryrefslogtreecommitdiff
path: root/source4/ntvfs/posix/pvfs_rename.c
diff options
context:
space:
mode:
authorAndrew Tridgell <tridge@samba.org>2009-01-07 16:46:34 +1100
committerAndrew Tridgell <tridge@samba.org>2009-01-07 16:46:34 +1100
commitc81863e86861bbb00df23b92470631e60314d9d1 (patch)
treede0f3b1bbc4d25fc65638ea0091a882b8fa00e1f /source4/ntvfs/posix/pvfs_rename.c
parent07e01f8405f2bd3f0ee521e8aebf2c647052104f (diff)
downloadsamba-c81863e86861bbb00df23b92470631e60314d9d1.tar.gz
samba-c81863e86861bbb00df23b92470631e60314d9d1.tar.bz2
samba-c81863e86861bbb00df23b92470631e60314d9d1.zip
added support for stream renames in Samba4
This allows the RAW-STREAMS test to work again. We still have some limitations though: - renames of a stream to the default stream doesn't work - delete on close handling between streams and the main file is still broken
Diffstat (limited to 'source4/ntvfs/posix/pvfs_rename.c')
-rw-r--r--source4/ntvfs/posix/pvfs_rename.c60
1 files changed, 59 insertions, 1 deletions
diff --git a/source4/ntvfs/posix/pvfs_rename.c b/source4/ntvfs/posix/pvfs_rename.c
index 475ce3048f..ed90bf3d7b 100644
--- a/source4/ntvfs/posix/pvfs_rename.c
+++ b/source4/ntvfs/posix/pvfs_rename.c
@@ -464,6 +464,59 @@ static NTSTATUS pvfs_rename_mv(struct ntvfs_module_context *ntvfs,
/*
+ rename a stream
+*/
+static NTSTATUS pvfs_rename_stream(struct ntvfs_module_context *ntvfs,
+ struct ntvfs_request *req, union smb_rename *ren,
+ struct pvfs_filename *name1)
+{
+ struct pvfs_state *pvfs = ntvfs->private_data;
+ NTSTATUS status;
+ struct odb_lock *lck = NULL;
+
+ if (name1->has_wildcard) {
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+
+ if (ren->ntrename.in.new_name[0] != ':') {
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+
+ if (!name1->exists) {
+ return NT_STATUS_OBJECT_NAME_NOT_FOUND;
+ }
+
+ if (ren->ntrename.in.flags != RENAME_FLAG_RENAME) {
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+
+ status = pvfs_can_rename(pvfs, req, name1, &lck);
+ /*
+ * on a sharing violation we need to retry when the file is closed by
+ * the other user, or after 1 second
+ * on a non granted oplock we need to retry when the file is closed by
+ * the other user, or after 30 seconds
+ */
+ if ((NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION) ||
+ NT_STATUS_EQUAL(status, NT_STATUS_OPLOCK_NOT_GRANTED)) &&
+ (req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) {
+ return pvfs_rename_setup_retry(pvfs->ntvfs, req, ren, lck, status);
+ }
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
+ status = pvfs_access_check_simple(pvfs, req, name1, SEC_FILE_WRITE_ATTRIBUTE);
+ NT_STATUS_NOT_OK_RETURN(status);
+
+ status = pvfs_stream_rename(pvfs, name1, -1,
+ ren->ntrename.in.new_name+1);
+ NT_STATUS_NOT_OK_RETURN(status);
+
+ return NT_STATUS_OK;
+}
+
+/*
rename a set of files - ntrename interface
*/
static NTSTATUS pvfs_rename_nt(struct ntvfs_module_context *ntvfs,
@@ -486,11 +539,16 @@ static NTSTATUS pvfs_rename_nt(struct ntvfs_module_context *ntvfs,
/* resolve the cifs name to a posix name */
status = pvfs_resolve_name(pvfs, req, ren->ntrename.in.old_name,
- PVFS_RESOLVE_WILDCARD, &name1);
+ PVFS_RESOLVE_WILDCARD | PVFS_RESOLVE_STREAMS, &name1);
if (!NT_STATUS_IS_OK(status)) {
return status;
}
+ if (name1->stream_name) {
+ /* stream renames need to be handled separately */
+ return pvfs_rename_stream(ntvfs, req, ren, name1);
+ }
+
status = pvfs_resolve_name(pvfs, req, ren->ntrename.in.new_name,
PVFS_RESOLVE_WILDCARD, &name2);
if (!NT_STATUS_IS_OK(status)) {