summaryrefslogtreecommitdiff
path: root/source4/ntvfs/posix/pvfs_unlink.c
diff options
context:
space:
mode:
Diffstat (limited to 'source4/ntvfs/posix/pvfs_unlink.c')
-rw-r--r--source4/ntvfs/posix/pvfs_unlink.c107
1 files changed, 47 insertions, 60 deletions
diff --git a/source4/ntvfs/posix/pvfs_unlink.c b/source4/ntvfs/posix/pvfs_unlink.c
index ef56d99fb5..bda4014bee 100644
--- a/source4/ntvfs/posix/pvfs_unlink.c
+++ b/source4/ntvfs/posix/pvfs_unlink.c
@@ -25,94 +25,70 @@
/*
- unlink a stream
- */
-static NTSTATUS pvfs_unlink_stream(struct pvfs_state *pvfs,
- struct ntvfs_request *req,
- struct pvfs_filename *name,
- uint16_t attrib)
+ unlink a file
+*/
+static NTSTATUS pvfs_unlink_file(struct pvfs_state *pvfs,
+ struct pvfs_filename *name)
{
NTSTATUS status;
- struct odb_lock *lck;
- if (!name->stream_exists) {
- return NT_STATUS_OBJECT_NAME_NOT_FOUND;
+ if (name->dos.attrib & FILE_ATTRIBUTE_DIRECTORY) {
+ return NT_STATUS_FILE_IS_A_DIRECTORY;
}
- /* make sure its matches the given attributes */
- status = pvfs_match_attrib(pvfs, name, attrib, 0);
- if (!NT_STATUS_IS_OK(status)) {
- return status;
+ if (name->st.st_nlink == 1) {
+ status = pvfs_xattr_unlink_hook(pvfs, name->full_name);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
}
- status = pvfs_can_delete(pvfs, req, name, &lck);
- if (!NT_STATUS_IS_OK(status)) {
- return status;
+ /* finally try the actual unlink */
+ if (unlink(name->full_name) == -1) {
+ status = pvfs_map_errno(pvfs, errno);
}
- return pvfs_stream_delete(pvfs, name, -1);
-}
+ if (NT_STATUS_IS_OK(status)) {
+ notify_trigger(pvfs->notify_context,
+ NOTIFY_ACTION_REMOVED,
+ FILE_NOTIFY_CHANGE_FILE_NAME,
+ name->full_name);
+ }
+ return status;
+}
/*
unlink one file
*/
-static NTSTATUS pvfs_unlink_one(struct pvfs_state *pvfs,
+static NTSTATUS pvfs_unlink_one(struct pvfs_state *pvfs,
struct ntvfs_request *req,
- const char *unix_path,
- const char *fname, uint32_t attrib)
+ union smb_unlink *unl,
+ struct pvfs_filename *name)
{
- struct pvfs_filename *name;
NTSTATUS status;
- struct odb_lock *lck;
-
- /* get a pvfs_filename object */
- status = pvfs_resolve_partial(pvfs, req,
- unix_path, fname, &name);
- if (!NT_STATUS_IS_OK(status)) {
- return status;
- }
/* make sure its matches the given attributes */
- status = pvfs_match_attrib(pvfs, name, attrib, 0);
+ status = pvfs_match_attrib(pvfs, name,
+ unl->unlink.in.attrib, 0);
if (!NT_STATUS_IS_OK(status)) {
- talloc_free(name);
return status;
}
- status = pvfs_can_delete(pvfs, req, name, &lck);
+ status = pvfs_can_delete(pvfs, req, name, NULL);
if (!NT_STATUS_IS_OK(status)) {
- talloc_free(name);
return status;
}
- if (name->dos.attrib & FILE_ATTRIBUTE_DIRECTORY) {
- talloc_free(name);
- return NT_STATUS_FILE_IS_A_DIRECTORY;
- }
-
- if (name->st.st_nlink == 1) {
- status = pvfs_xattr_unlink_hook(pvfs, name->full_name);
- if (!NT_STATUS_IS_OK(status)) {
- return status;
+ if (name->stream_name) {
+ if (!name->stream_exists) {
+ return NT_STATUS_OBJECT_NAME_NOT_FOUND;
}
- }
-
- /* finally try the actual unlink */
- if (unlink(name->full_name) == -1) {
- status = pvfs_map_errno(pvfs, errno);
- }
- if (NT_STATUS_IS_OK(status)) {
- notify_trigger(pvfs->notify_context,
- NOTIFY_ACTION_REMOVED,
- FILE_NOTIFY_CHANGE_FILE_NAME,
- name->full_name);
+ return pvfs_stream_delete(pvfs, name, -1);
}
- talloc_free(name);
-
- return status;
+ return pvfs_unlink_file(pvfs, name);
}
/*
@@ -147,8 +123,8 @@ NTSTATUS pvfs_unlink(struct ntvfs_module_context *ntvfs,
return NT_STATUS_FILE_IS_A_DIRECTORY;
}
- if (name->stream_name) {
- return pvfs_unlink_stream(pvfs, req, name, unl->unlink.in.attrib);
+ if (!name->has_wildcard) {
+ return pvfs_unlink_one(pvfs, req, unl, name);
}
/* get list of matching files */
@@ -158,6 +134,7 @@ NTSTATUS pvfs_unlink(struct ntvfs_module_context *ntvfs,
}
status = NT_STATUS_NO_SUCH_FILE;
+ talloc_free(name);
ofs = 0;
@@ -168,10 +145,20 @@ NTSTATUS pvfs_unlink(struct ntvfs_module_context *ntvfs,
return NT_STATUS_OBJECT_NAME_INVALID;
}
- status = pvfs_unlink_one(pvfs, req, pvfs_list_unix_path(dir), fname, unl->unlink.in.attrib);
+ /* get a pvfs_filename object */
+ status = pvfs_resolve_partial(pvfs, req,
+ pvfs_list_unix_path(dir),
+ fname, &name);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
+ status = pvfs_unlink_one(pvfs, req, unl, name);
if (NT_STATUS_IS_OK(status)) {
total_deleted++;
}
+
+ talloc_free(name);
}
if (total_deleted > 0) {