X-Git-Url: http://git.samba.org/samba.git/?a=blobdiff_plain;f=source4%2Fntvfs%2Fposix%2Fpvfs_unlink.c;h=ef56d99fb559a2bca73cd0c477b4df8643389d9d;hb=0479a2f1cbae51fcd8dbdc3c148c808421fb4d25;hp=f29a70600fc324247544798b56d20fcef6dc008b;hpb=50005129ab0a5c5f2422460e6d7c19616e5e1124;p=kai%2Fsamba-autobuild%2F.git diff --git a/source4/ntvfs/posix/pvfs_unlink.c b/source4/ntvfs/posix/pvfs_unlink.c index f29a70600fc..ef56d99fb55 100644 --- a/source4/ntvfs/posix/pvfs_unlink.c +++ b/source4/ntvfs/posix/pvfs_unlink.c @@ -7,7 +7,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -16,21 +16,24 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + along with this program. If not, see . */ #include "includes.h" #include "vfs_posix.h" +#include "system/dir.h" /* unlink a stream */ -static NTSTATUS pvfs_unlink_stream(struct pvfs_state *pvfs, struct pvfs_filename *name, +static NTSTATUS pvfs_unlink_stream(struct pvfs_state *pvfs, + struct ntvfs_request *req, + struct pvfs_filename *name, uint16_t attrib) { NTSTATUS status; + struct odb_lock *lck; if (!name->stream_exists) { return NT_STATUS_OBJECT_NAME_NOT_FOUND; @@ -42,7 +45,7 @@ static NTSTATUS pvfs_unlink_stream(struct pvfs_state *pvfs, struct pvfs_filename return status; } - status = pvfs_can_delete(pvfs, name); + status = pvfs_can_delete(pvfs, req, name, &lck); if (!NT_STATUS_IS_OK(status)) { return status; } @@ -54,15 +57,17 @@ static NTSTATUS pvfs_unlink_stream(struct pvfs_state *pvfs, struct pvfs_filename /* unlink one file */ -static NTSTATUS pvfs_unlink_one(struct pvfs_state *pvfs, TALLOC_CTX *mem_ctx, +static NTSTATUS pvfs_unlink_one(struct pvfs_state *pvfs, + struct ntvfs_request *req, const char *unix_path, const char *fname, uint32_t attrib) { struct pvfs_filename *name; NTSTATUS status; + struct odb_lock *lck; /* get a pvfs_filename object */ - status = pvfs_resolve_partial(pvfs, mem_ctx, + status = pvfs_resolve_partial(pvfs, req, unix_path, fname, &name); if (!NT_STATUS_IS_OK(status)) { return status; @@ -75,7 +80,7 @@ static NTSTATUS pvfs_unlink_one(struct pvfs_state *pvfs, TALLOC_CTX *mem_ctx, return status; } - status = pvfs_can_delete(pvfs, name); + status = pvfs_can_delete(pvfs, req, name, &lck); if (!NT_STATUS_IS_OK(status)) { talloc_free(name); return status; @@ -86,9 +91,11 @@ static NTSTATUS pvfs_unlink_one(struct pvfs_state *pvfs, TALLOC_CTX *mem_ctx, return NT_STATUS_FILE_IS_A_DIRECTORY; } - status = pvfs_xattr_unlink_hook(pvfs, name->full_name); - 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; + } } /* finally try the actual unlink */ @@ -96,6 +103,13 @@ static NTSTATUS pvfs_unlink_one(struct pvfs_state *pvfs, TALLOC_CTX *mem_ctx, 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); + } + talloc_free(name); return status; @@ -106,7 +120,8 @@ static NTSTATUS pvfs_unlink_one(struct pvfs_state *pvfs, TALLOC_CTX *mem_ctx, The name can contain CIFS wildcards, but rarely does (except with OS/2 clients) */ NTSTATUS pvfs_unlink(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, struct smb_unlink *unl) + struct ntvfs_request *req, + union smb_unlink *unl) { struct pvfs_state *pvfs = ntvfs->private_data; struct pvfs_dir *dir; @@ -114,10 +129,10 @@ NTSTATUS pvfs_unlink(struct ntvfs_module_context *ntvfs, uint32_t total_deleted=0; struct pvfs_filename *name; const char *fname; - uint_t ofs; + off_t ofs; /* resolve the cifs name to a posix name */ - status = pvfs_resolve_name(pvfs, req, unl->in.pattern, + status = pvfs_resolve_name(pvfs, req, unl->unlink.in.pattern, PVFS_RESOLVE_WILDCARD | PVFS_RESOLVE_STREAMS, &name); if (!NT_STATUS_IS_OK(status)) { return status; @@ -133,7 +148,7 @@ NTSTATUS pvfs_unlink(struct ntvfs_module_context *ntvfs, } if (name->stream_name) { - return pvfs_unlink_stream(pvfs, name, unl->in.attrib); + return pvfs_unlink_stream(pvfs, req, name, unl->unlink.in.attrib); } /* get list of matching files */ @@ -148,13 +163,12 @@ NTSTATUS pvfs_unlink(struct ntvfs_module_context *ntvfs, while ((fname = pvfs_list_next(dir, &ofs))) { /* this seems to be a special case */ - if ((unl->in.attrib & FILE_ATTRIBUTE_DIRECTORY) && - (strcmp(fname, ".") == 0 || - strcmp(fname, "..") == 0)) { + if ((unl->unlink.in.attrib & FILE_ATTRIBUTE_DIRECTORY) && + (ISDOT(fname) || ISDOTDOT(fname))) { return NT_STATUS_OBJECT_NAME_INVALID; } - status = pvfs_unlink_one(pvfs, req, pvfs_list_unix_path(dir), fname, unl->in.attrib); + status = pvfs_unlink_one(pvfs, req, pvfs_list_unix_path(dir), fname, unl->unlink.in.attrib); if (NT_STATUS_IS_OK(status)) { total_deleted++; }