/* unlink one file */ static NTSTATUS pvfs_unlink_one(struct pvfs_state *pvfs, struct ntvfs_request *req, union smb_unlink *unl, struct pvfs_filename *name) { NTSTATUS status; struct odb_lock *lck = NULL; /* make sure its matches the given attributes */ status = pvfs_match_attrib(pvfs, name, unl->unlink.in.attrib, 0); if (!NT_STATUS_IS_OK(status)) { return status; } status = pvfs_can_delete(pvfs, req, name, &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_unlink_setup_retry(pvfs->ntvfs, req, unl, lck, status); } if (!NT_STATUS_IS_OK(status)) { return status; } if (name->stream_name) { if (!name->stream_exists) { return NT_STATUS_OBJECT_NAME_NOT_FOUND; } return pvfs_stream_delete(pvfs, name, -1); } return pvfs_unlink_file(pvfs, name); }
/* destroy a struct pvfs_file_handle */ 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; status = pvfs_dosattrib_load(h->pvfs, h->name, h->fd); if (NT_STATUS_IS_OK(status)) { h->name->dos.flags &= ~XATTR_ATTRIB_FLAG_STICKY_WRITE_TIME; pvfs_dosattrib_save(h->pvfs, h->name, h->fd); } } if ((h->create_options & NTCREATEX_OPTIONS_DELETE_ON_CLOSE) && h->name->stream_name) { NTSTATUS status; status = pvfs_stream_delete(h->pvfs, h->name, h->fd); if (!NT_STATUS_IS_OK(status)) { DEBUG(0,("Failed to delete stream '%s' on close of '%s'\n", h->name->stream_name, h->name->full_name)); } } if (h->fd != -1) { if (close(h->fd) != 0) { DEBUG(0,("pvfs_handle_destructor: close(%d) failed for %s - %s\n", h->fd, h->name->full_name, strerror(errno))); } h->fd = -1; } 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 (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; lck = odb_lock(h, h->pvfs->odb_context, &h->odb_locking_key); if (lck == NULL) { DEBUG(0,("Unable to lock opendb for close\n")); return 0; } status = odb_close_file(lck, h); if (!NT_STATUS_IS_OK(status)) { DEBUG(0,("Unable to remove opendb entry for '%s' - %s\n", h->name->full_name, nt_errstr(status))); } talloc_free(lck); } return 0; }