diff options
Diffstat (limited to 'source4/ntvfs/posix')
-rw-r--r-- | source4/ntvfs/posix/pvfs_open.c | 95 | ||||
-rw-r--r-- | source4/ntvfs/posix/pvfs_qfileinfo.c | 8 | ||||
-rw-r--r-- | source4/ntvfs/posix/pvfs_rename.c | 131 | ||||
-rw-r--r-- | source4/ntvfs/posix/pvfs_resolve.c | 100 | ||||
-rw-r--r-- | source4/ntvfs/posix/pvfs_setfileinfo.c | 31 | ||||
-rw-r--r-- | source4/ntvfs/posix/pvfs_xattr.c | 2 |
6 files changed, 277 insertions, 90 deletions
diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c index a01352f60c..adf4c1ac18 100644 --- a/source4/ntvfs/posix/pvfs_open.c +++ b/source4/ntvfs/posix/pvfs_open.c @@ -50,29 +50,10 @@ struct pvfs_file *pvfs_find_fd(struct pvfs_state *pvfs, */ static int pvfs_dir_handle_destructor(struct pvfs_file_handle *h) { - int open_count; - char *path = NULL; - - if (h->name->stream_name == NULL && - pvfs_delete_on_close_set(h->pvfs, h, &open_count, &path) && - open_count == 1) { - NTSTATUS status; - status = pvfs_xattr_unlink_hook(h->pvfs, path); - if (!NT_STATUS_IS_OK(status)) { - DEBUG(0,("Warning: xattr unlink hook failed for '%s' - %s\n", - path, nt_errstr(status))); - } - if (rmdir(path) != 0) { - DEBUG(0,("pvfs_dir_handle_destructor: failed to rmdir '%s' - %s\n", - path, strerror(errno))); - } - } - - talloc_free(path); - if (h->have_opendb_entry) { struct odb_lock *lck; NTSTATUS status; + const char *delete_path = NULL; lck = odb_lock(h, h->pvfs->odb_context, &h->odb_locking_key); if (lck == NULL) { @@ -80,12 +61,24 @@ static int pvfs_dir_handle_destructor(struct pvfs_file_handle *h) return 0; } - status = odb_close_file(lck, h); + status = odb_close_file(lck, h, &delete_path); if (!NT_STATUS_IS_OK(status)) { - DEBUG(0,("Unable to remove opendb entry for '%s' - %s\n", + DEBUG(0,("Unable to remove opendb entry for '%s' - %s\n", h->name->full_name, nt_errstr(status))); } + if (h->name->stream_name == NULL && delete_path) { + status = pvfs_xattr_unlink_hook(h->pvfs, delete_path); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(0,("Warning: xattr unlink hook failed for '%s' - %s\n", + delete_path, nt_errstr(status))); + } + if (rmdir(delete_path) != 0) { + DEBUG(0,("pvfs_dir_handle_destructor: failed to rmdir '%s' - %s\n", + delete_path, strerror(errno))); + } + } + talloc_free(lck); } @@ -151,8 +144,8 @@ static NTSTATUS pvfs_open_setup_eas_acl(struct pvfs_state *pvfs, form the lock context used for opendb locking. Note that we must zero here to take account of possible padding on some architectures */ -static NTSTATUS pvfs_locking_key(struct pvfs_filename *name, - TALLOC_CTX *mem_ctx, DATA_BLOB *key) +NTSTATUS pvfs_locking_key(struct pvfs_filename *name, + TALLOC_CTX *mem_ctx, DATA_BLOB *key) { struct { dev_t device; @@ -410,9 +403,6 @@ cleanup_delete: */ static int pvfs_handle_destructor(struct pvfs_file_handle *h) { - int open_count; - char *path = NULL; - /* the write time is no longer sticky */ if (h->sticky_write_time) { NTSTATUS status; @@ -441,32 +431,10 @@ static int pvfs_handle_destructor(struct pvfs_file_handle *h) h->fd = -1; } - if (h->name->stream_name == NULL && - h->open_completed && - pvfs_delete_on_close_set(h->pvfs, h, &open_count, &path) && - open_count == 1) { - NTSTATUS status; - status = pvfs_xattr_unlink_hook(h->pvfs, path); - if (!NT_STATUS_IS_OK(status)) { - DEBUG(0,("Warning: xattr unlink hook failed for '%s' - %s\n", - path, nt_errstr(status))); - } - if (unlink(path) != 0) { - DEBUG(0,("pvfs_close: failed to delete '%s' - %s\n", - path, strerror(errno))); - } else { - notify_trigger(h->pvfs->notify_context, - NOTIFY_ACTION_REMOVED, - FILE_NOTIFY_CHANGE_FILE_NAME, - path); - } - } - - talloc_free(path); - if (h->have_opendb_entry) { struct odb_lock *lck; NTSTATUS status; + const char *delete_path = NULL; lck = odb_lock(h, h->pvfs->odb_context, &h->odb_locking_key); if (lck == NULL) { @@ -474,12 +442,30 @@ static int pvfs_handle_destructor(struct pvfs_file_handle *h) return 0; } - status = odb_close_file(lck, h); + status = odb_close_file(lck, h, &delete_path); if (!NT_STATUS_IS_OK(status)) { DEBUG(0,("Unable to remove opendb entry for '%s' - %s\n", h->name->full_name, nt_errstr(status))); } + if (h->name->stream_name == NULL && + h->open_completed && delete_path) { + status = pvfs_xattr_unlink_hook(h->pvfs, delete_path); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(0,("Warning: xattr unlink hook failed for '%s' - %s\n", + delete_path, nt_errstr(status))); + } + if (unlink(delete_path) != 0) { + DEBUG(0,("pvfs_close: failed to delete '%s' - %s\n", + delete_path, strerror(errno))); + } else { + notify_trigger(h->pvfs->notify_context, + NOTIFY_ACTION_REMOVED, + FILE_NOTIFY_CHANGE_FILE_NAME, + delete_path); + } + } + talloc_free(lck); } @@ -574,7 +560,7 @@ static NTSTATUS pvfs_create_file(struct pvfs_state *pvfs, status = pvfs_locking_key(parent, req, &locking_key); NT_STATUS_NOT_OK_RETURN(status); status = odb_get_delete_on_close(pvfs->odb_context, &locking_key, - &del_on_close, NULL, NULL); + &del_on_close); NT_STATUS_NOT_OK_RETURN(status); if (del_on_close) { return NT_STATUS_DELETE_PENDING; @@ -1738,14 +1724,13 @@ NTSTATUS pvfs_can_stat(struct pvfs_state *pvfs, /* determine if delete on close is set on */ -bool pvfs_delete_on_close_set(struct pvfs_state *pvfs, struct pvfs_file_handle *h, - int *open_count, char **path) +bool pvfs_delete_on_close_set(struct pvfs_state *pvfs, struct pvfs_file_handle *h) { NTSTATUS status; bool del_on_close; status = odb_get_delete_on_close(pvfs->odb_context, &h->odb_locking_key, - &del_on_close, open_count, path); + &del_on_close); if (!NT_STATUS_IS_OK(status)) { DEBUG(1,("WARNING: unable to determine delete on close status for open file\n")); return false; diff --git a/source4/ntvfs/posix/pvfs_qfileinfo.c b/source4/ntvfs/posix/pvfs_qfileinfo.c index 8d23d707a4..6bc21e5e3e 100644 --- a/source4/ntvfs/posix/pvfs_qfileinfo.c +++ b/source4/ntvfs/posix/pvfs_qfileinfo.c @@ -368,7 +368,7 @@ NTSTATUS pvfs_qfileinfo(struct ntvfs_module_context *ntvfs, } /* update the file information */ - status = pvfs_resolve_name_fd(pvfs, h->fd, h->name); + status = pvfs_resolve_name_handle(pvfs, h); if (!NT_STATUS_IS_OK(status)) { return status; } @@ -380,7 +380,7 @@ NTSTATUS pvfs_qfileinfo(struct ntvfs_module_context *ntvfs, switch (info->generic.level) { case RAW_FILEINFO_STANDARD_INFO: case RAW_FILEINFO_STANDARD_INFORMATION: - if (pvfs_delete_on_close_set(pvfs, h, NULL, NULL)) { + if (pvfs_delete_on_close_set(pvfs, h)) { info->standard_info.out.delete_pending = 1; info->standard_info.out.nlink--; } @@ -388,7 +388,7 @@ NTSTATUS pvfs_qfileinfo(struct ntvfs_module_context *ntvfs, case RAW_FILEINFO_ALL_INFO: case RAW_FILEINFO_ALL_INFORMATION: - if (pvfs_delete_on_close_set(pvfs, h, NULL, NULL)) { + if (pvfs_delete_on_close_set(pvfs, h)) { info->all_info.out.delete_pending = 1; info->all_info.out.nlink--; } @@ -407,7 +407,7 @@ NTSTATUS pvfs_qfileinfo(struct ntvfs_module_context *ntvfs, break; case RAW_FILEINFO_SMB2_ALL_INFORMATION: - if (pvfs_delete_on_close_set(pvfs, h, NULL, NULL)) { + if (pvfs_delete_on_close_set(pvfs, h)) { info->all_info2.out.delete_pending = 1; info->all_info2.out.nlink--; } diff --git a/source4/ntvfs/posix/pvfs_rename.c b/source4/ntvfs/posix/pvfs_rename.c index 5693e79314..29b2d03005 100644 --- a/source4/ntvfs/posix/pvfs_rename.c +++ b/source4/ntvfs/posix/pvfs_rename.c @@ -28,16 +28,22 @@ /* do a file rename, and send any notify triggers */ -NTSTATUS pvfs_do_rename(struct pvfs_state *pvfs, const struct pvfs_filename *name1, +NTSTATUS pvfs_do_rename(struct pvfs_state *pvfs, + struct odb_lock *lck, + const struct pvfs_filename *name1, const char *name2) { const char *r1, *r2; uint32_t mask; + NTSTATUS status; if (rename(name1->full_name, name2) == -1) { return pvfs_map_errno(pvfs, errno); } + status = odb_rename(lck, name2); + NT_STATUS_NOT_OK_RETURN(status); + if (name1->dos.attrib & FILE_ATTRIBUTE_DIRECTORY) { mask = FILE_NOTIFY_CHANGE_DIR_NAME; } else { @@ -134,12 +140,12 @@ static const char *pvfs_resolve_wildcard_component(TALLOC_CTX *mem_ctx, resolve a wildcard rename pattern. */ static const char *pvfs_resolve_wildcard(TALLOC_CTX *mem_ctx, + struct smb_iconv_convenience *iconv_convenience, const char *fname, const char *pattern) { const char *base1, *base2; const char *ext1, *ext2; - struct smb_iconv_convenience *iconv_convenience = lp_iconv_convenience(global_loadparm); char *p; /* break into base part plus extension */ @@ -181,6 +187,84 @@ static const char *pvfs_resolve_wildcard(TALLOC_CTX *mem_ctx, } /* + retry an rename after a sharing violation +*/ +static void pvfs_retry_rename(struct pvfs_odb_retry *r, + struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, + void *_io, + void *private_data, + enum pvfs_wait_notice reason) +{ + union smb_rename *io = talloc_get_type(_io, union smb_rename); + NTSTATUS status = NT_STATUS_INTERNAL_ERROR; + + talloc_free(r); + + switch (reason) { + case PVFS_WAIT_CANCEL: +/*TODO*/ + status = NT_STATUS_CANCELLED; + break; + case PVFS_WAIT_TIMEOUT: + /* if it timed out, then give the failure + immediately */ +/*TODO*/ + status = NT_STATUS_SHARING_VIOLATION; + break; + case PVFS_WAIT_EVENT: + + /* try the open again, which could trigger another retry setup + if it wants to, so we have to unmark the async flag so we + will know if it does a second async reply */ + req->async_states->state &= ~NTVFS_ASYNC_STATE_ASYNC; + + status = pvfs_rename(ntvfs, req, io); + if (req->async_states->state & NTVFS_ASYNC_STATE_ASYNC) { + /* the 2nd try also replied async, so we don't send + the reply yet */ + return; + } + + /* re-mark it async, just in case someone up the chain does + paranoid checking */ + req->async_states->state |= NTVFS_ASYNC_STATE_ASYNC; + break; + } + + /* send the reply up the chain */ + req->async_states->status = status; + req->async_states->send_fn(req); +} + +/* + setup for a rename retry after a sharing violation + or a non granted oplock +*/ +static NTSTATUS pvfs_rename_setup_retry(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, + union smb_rename *io, + struct odb_lock *lck, + NTSTATUS status) +{ + struct pvfs_state *pvfs = ntvfs->private_data; + struct timeval end_time; + + if (NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION)) { + end_time = timeval_add(&req->statistics.request_time, + 0, pvfs->sharing_violation_delay); + } else if (NT_STATUS_EQUAL(status, NT_STATUS_OPLOCK_NOT_GRANTED)) { + end_time = timeval_add(&req->statistics.request_time, + pvfs->oplock_break_timeout, 0); + } else { + return NT_STATUS_INTERNAL_ERROR; + } + + return pvfs_odb_retry_setup(ntvfs, req, lck, end_time, io, NULL, + pvfs_retry_rename); +} + +/* rename one file from a wildcard set */ static NTSTATUS pvfs_rename_one(struct pvfs_state *pvfs, @@ -196,7 +280,7 @@ static NTSTATUS pvfs_rename_one(struct pvfs_state *pvfs, NTSTATUS status; /* resolve the wildcard pattern for this name */ - fname2 = pvfs_resolve_wildcard(mem_ctx, fname1, fname2); + fname2 = pvfs_resolve_wildcard(mem_ctx, lp_iconv_convenience(pvfs->ntvfs->ctx->lp_ctx), fname1, fname2); if (fname2 == NULL) { return NT_STATUS_NO_MEMORY; } @@ -237,11 +321,7 @@ static NTSTATUS pvfs_rename_one(struct pvfs_state *pvfs, return NT_STATUS_NO_MEMORY; } - status = pvfs_do_rename(pvfs, name1, fname2); - - if (NT_STATUS_IS_OK(status)) { - status = odb_rename(lck, fname2); - } + status = pvfs_do_rename(pvfs, lck, name1, fname2); failed: talloc_free(mem_ctx); @@ -354,14 +434,25 @@ static NTSTATUS pvfs_rename_mv(struct ntvfs_module_context *ntvfs, } 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)) { - talloc_free(lck); return status; } - status = pvfs_do_rename(pvfs, name1, name2->full_name); - if (NT_STATUS_IS_OK(status)) { - status = odb_rename(lck, name2->full_name); + status = pvfs_do_rename(pvfs, lck, name1, name2->full_name); + if (!NT_STATUS_IS_OK(status)) { + return status; } return NT_STATUS_OK; @@ -377,6 +468,7 @@ static NTSTATUS pvfs_rename_nt(struct ntvfs_module_context *ntvfs, struct pvfs_state *pvfs = ntvfs->private_data; NTSTATUS status; struct pvfs_filename *name1, *name2; + struct odb_lock *lck = NULL; switch (ren->ntrename.in.flags) { case RENAME_FLAG_RENAME: @@ -422,7 +514,18 @@ static NTSTATUS pvfs_rename_nt(struct ntvfs_module_context *ntvfs, return status; } - status = pvfs_can_rename(pvfs, req, name1, NULL); + 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; } @@ -431,7 +534,7 @@ static NTSTATUS pvfs_rename_nt(struct ntvfs_module_context *ntvfs, case RENAME_FLAG_RENAME: status = pvfs_access_check_parent(pvfs, req, name2, SEC_DIR_ADD_FILE); NT_STATUS_NOT_OK_RETURN(status); - status = pvfs_do_rename(pvfs, name1, name2->full_name); + status = pvfs_do_rename(pvfs, lck, name1, name2->full_name); NT_STATUS_NOT_OK_RETURN(status); break; diff --git a/source4/ntvfs/posix/pvfs_resolve.c b/source4/ntvfs/posix/pvfs_resolve.c index cf74816391..325bc74f8f 100644 --- a/source4/ntvfs/posix/pvfs_resolve.c +++ b/source4/ntvfs/posix/pvfs_resolve.c @@ -265,8 +265,15 @@ static NTSTATUS pvfs_unix_path(struct pvfs_state *pvfs, const char *cifs_name, of a name */ return NT_STATUS_ILLEGAL_CHARACTER; } - if (p > p_start && p[1] == 0) { - *p = 0; + if (p > p_start && (p[1] == '\\' || p[1] == '\0')) { + /* see if it is definately a "\\" or + * a trailing "\". If it is then fail here, + * and let the next layer up try again after + * pvfs_reduce_name() if it wants to. This is + * much more efficient on average than always + * scanning for these separately + */ + return NT_STATUS_OBJECT_PATH_SYNTAX_BAD; } else { *p = '/'; } @@ -329,14 +336,15 @@ static NTSTATUS pvfs_unix_path(struct pvfs_state *pvfs, const char *cifs_name, reduce a name that contains .. components or repeated \ separators return NULL if it can't be reduced */ -static NTSTATUS pvfs_reduce_name(TALLOC_CTX *mem_ctx, const char **fname, uint_t flags) +static NTSTATUS pvfs_reduce_name(TALLOC_CTX *mem_ctx, + struct smb_iconv_convenience *iconv_convenience, + const char **fname, uint_t flags) { codepoint_t c; size_t c_size, len; int i, num_components, err_count; char **components; char *p, *s, *ret; - struct smb_iconv_convenience *iconv_convenience = lp_iconv_convenience(global_loadparm); s = talloc_strdup(mem_ctx, *fname); if (s == NULL) return NT_STATUS_NO_MEMORY; @@ -398,7 +406,7 @@ static NTSTATUS pvfs_reduce_name(TALLOC_CTX *mem_ctx, const char **fname, uint_t if (ISDOTDOT(components[i])) { if (i < 1) return NT_STATUS_OBJECT_PATH_SYNTAX_BAD; memmove(&components[i-1], &components[i+1], - sizeof(char *)*(num_components-(i+1))); + sizeof(char *)*(num_components-i)); i -= 2; continue; } @@ -471,7 +479,7 @@ NTSTATUS pvfs_resolve_name(struct pvfs_state *pvfs, TALLOC_CTX *mem_ctx, if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_PATH_SYNTAX_BAD)) { /* it might contain .. components which need to be reduced */ - status = pvfs_reduce_name(*name, &cifs_name, flags); + status = pvfs_reduce_name(*name, lp_iconv_convenience(pvfs->ntvfs->ctx->lp_ctx), &cifs_name, flags); if (!NT_STATUS_IS_OK(status)) { return status; } @@ -615,6 +623,86 @@ NTSTATUS pvfs_resolve_name_fd(struct pvfs_state *pvfs, int fd, return pvfs_fill_dos_info(pvfs, name, fd); } +/* + fill in the pvfs_filename info for an open file, given the current + info for a (possibly) non-open file. This is used by places that need + to update the pvfs_filename stat information, and the path + after a possible rename on a different handle. +*/ +NTSTATUS pvfs_resolve_name_handle(struct pvfs_state *pvfs, + struct pvfs_file_handle *h) +{ + NTSTATUS status; + + if (h->have_opendb_entry) { + struct odb_lock *lck; + const char *name = NULL; + + lck = odb_lock(h, h->pvfs->odb_context, &h->odb_locking_key); + if (lck == NULL) { + DEBUG(0,("%s: failed to lock file '%s' in opendb\n", + __FUNCTION__, h->name->full_name)); + /* we were supposed to do a blocking lock, so something + is badly wrong! */ + return NT_STATUS_INTERNAL_DB_CORRUPTION; + } + + status = odb_get_path(lck, &name); + if (NT_STATUS_IS_OK(status)) { + /* + * This relies an the fact that + * renames of open files are only + * allowed by setpathinfo() and setfileinfo() + * and there're only renames within the same + * directory supported + */ + if (strcmp(h->name->full_name, name) != 0) { + const char *orig_dir; + const char *new_file; + const char *new_orig; + char *delim; + + delim = strrchr(name, '/'); + if (!delim) { + talloc_free(lck); + return NT_STATUS_INTERNAL_ERROR; + } + + new_file = delim + 1; + delim = strrchr(h->name->original_name, '\\'); + if (delim) { + delim[0] = '\0'; + orig_dir = h->name->original_name; + new_orig = talloc_asprintf(h->name, "%s\\%s", + orig_dir, new_file); + if (!new_orig) { + talloc_free(lck); + return NT_STATUS_NO_MEMORY; + } + } else { + new_orig = talloc_strdup(h->name, new_file); + if (!new_orig) { + talloc_free(lck); + return NT_STATUS_NO_MEMORY; + } + } + + talloc_free(h->name->original_name); + talloc_free(h->name->full_name); + h->name->full_name = talloc_steal(h->name, name); + h->name->original_name = new_orig; + } + } + + talloc_free(lck); + } + + status = pvfs_resolve_name_fd(pvfs, h->fd, h->name); + NT_STATUS_NOT_OK_RETURN(status); + + return NT_STATUS_OK; +} + /* resolve the parent of a given name diff --git a/source4/ntvfs/posix/pvfs_setfileinfo.c b/source4/ntvfs/posix/pvfs_setfileinfo.c index da1e31e639..ad47fe90c9 100644 --- a/source4/ntvfs/posix/pvfs_setfileinfo.c +++ b/source4/ntvfs/posix/pvfs_setfileinfo.c @@ -82,11 +82,13 @@ static uint32_t pvfs_setfileinfo_access(union smb_setfileinfo *info) static NTSTATUS pvfs_setfileinfo_rename(struct pvfs_state *pvfs, struct ntvfs_request *req, struct pvfs_filename *name, + DATA_BLOB *odb_locking_key, union smb_setfileinfo *info) { NTSTATUS status; struct pvfs_filename *name2; char *new_name, *p; + struct odb_lock *lck = NULL; /* renames are only allowed within a directory */ if (strchr_m(info->rename_information.in.new_name, '\\') && @@ -94,11 +96,6 @@ static NTSTATUS pvfs_setfileinfo_rename(struct pvfs_state *pvfs, return NT_STATUS_NOT_SUPPORTED; } - if (name->dos.attrib & FILE_ATTRIBUTE_DIRECTORY) { - /* don't allow this for now */ - return NT_STATUS_FILE_IS_A_DIRECTORY; - } - /* don't allow stream renames for now */ if (name->stream_name) { return NT_STATUS_INVALID_PARAMETER; @@ -168,7 +165,15 @@ static NTSTATUS pvfs_setfileinfo_rename(struct pvfs_state *pvfs, return status; } - status = pvfs_do_rename(pvfs, name, name2->full_name); + lck = odb_lock(req, pvfs->odb_context, odb_locking_key); + if (lck == NULL) { + DEBUG(0,("Unable to lock opendb for can_stat\n")); + return NT_STATUS_INTERNAL_DB_CORRUPTION; + } + + status = pvfs_do_rename(pvfs, lck, name, name2->full_name); + talloc_free(lck); + NT_STATUS_NOT_OK_RETURN(status); if (NT_STATUS_IS_OK(status)) { name->full_name = talloc_steal(name, name2->full_name); name->original_name = talloc_steal(name, name2->original_name); @@ -289,7 +294,7 @@ NTSTATUS pvfs_setfileinfo(struct ntvfs_module_context *ntvfs, } /* update the file information */ - status = pvfs_resolve_name_fd(pvfs, h->fd, h->name); + status = pvfs_resolve_name_handle(pvfs, h); if (!NT_STATUS_IS_OK(status)) { return status; } @@ -391,7 +396,8 @@ NTSTATUS pvfs_setfileinfo(struct ntvfs_module_context *ntvfs, case RAW_SFILEINFO_RENAME_INFORMATION: case RAW_SFILEINFO_RENAME_INFORMATION_SMB2: - return pvfs_setfileinfo_rename(pvfs, req, h->name, + return pvfs_setfileinfo_rename(pvfs, req, h->name, + &h->odb_locking_key, info); case RAW_SFILEINFO_SEC_DESC: @@ -565,6 +571,7 @@ NTSTATUS pvfs_setpathinfo(struct ntvfs_module_context *ntvfs, uint32_t access_needed; uint32_t change_mask = 0; struct odb_lock *lck = NULL; + DATA_BLOB odb_locking_key; /* resolve the cifs name to a posix name */ status = pvfs_resolve_name(pvfs, req, info->generic.in.file.path, @@ -696,8 +703,12 @@ NTSTATUS pvfs_setpathinfo(struct ntvfs_module_context *ntvfs, case RAW_SFILEINFO_RENAME_INFORMATION: case RAW_SFILEINFO_RENAME_INFORMATION_SMB2: - return pvfs_setfileinfo_rename(pvfs, req, name, - info); + status = pvfs_locking_key(name, name, &odb_locking_key); + NT_STATUS_NOT_OK_RETURN(status); + status = pvfs_setfileinfo_rename(pvfs, req, name, + &odb_locking_key, info); + NT_STATUS_NOT_OK_RETURN(status); + return NT_STATUS_OK; case RAW_SFILEINFO_DISPOSITION_INFO: case RAW_SFILEINFO_DISPOSITION_INFORMATION: diff --git a/source4/ntvfs/posix/pvfs_xattr.c b/source4/ntvfs/posix/pvfs_xattr.c index 39090bf702..b66d252a45 100644 --- a/source4/ntvfs/posix/pvfs_xattr.c +++ b/source4/ntvfs/posix/pvfs_xattr.c @@ -140,7 +140,7 @@ _PUBLIC_ NTSTATUS pvfs_xattr_ndr_save(struct pvfs_state *pvfs, NTSTATUS status; enum ndr_err_code ndr_err; - ndr_err = ndr_push_struct_blob(&blob, mem_ctx, lp_iconv_convenience(global_loadparm), p, (ndr_push_flags_fn_t)push_fn); + ndr_err = ndr_push_struct_blob(&blob, mem_ctx, lp_iconv_convenience(pvfs->ntvfs->ctx->lp_ctx), p, (ndr_push_flags_fn_t)push_fn); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { talloc_free(mem_ctx); return ndr_map_error2ntstatus(ndr_err); |