⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 opendb_tdb.c

📁 samba最新软件
💻 C
📖 第 1 页 / 共 2 页
字号:
		}	}	if (_attrs_only) {		*_attrs_only = attrs_only;	}	return NT_STATUS_OK;}/*  register an open file in the open files database.  The share_access rules are implemented by odb_can_open()  and it's needed to call odb_can_open() before  odb_open_file() otherwise NT_STATUS_INTERNAL_ERROR is returned  Note that the path is only used by the delete on close logic, not  for comparing with other filenames*/static NTSTATUS odb_tdb_open_file(struct odb_lock *lck,				  void *file_handle, const char *path,				  int *fd, bool allow_level_II_oplock,				  uint32_t oplock_level, uint32_t *oplock_granted){	struct odb_context *odb = lck->odb;	if (!lck->can_open.e) {		return NT_STATUS_INTERNAL_ERROR;	}	if (odb->oplocks == false) {		oplock_level = OPLOCK_NONE;	}	if (!oplock_granted) {		oplock_level = OPLOCK_NONE;	}	if (lck->file.path == NULL) {		lck->file.path = talloc_strdup(lck, path);		NT_STATUS_HAVE_NO_MEMORY(lck->file.path);	}	/*	  possibly grant an exclusive, batch or level2 oplock	*/	if (lck->can_open.attrs_only) {		oplock_level	= OPLOCK_NONE;	} else if (oplock_level == OPLOCK_EXCLUSIVE) {		if (lck->file.num_entries == 0) {			oplock_level	= OPLOCK_EXCLUSIVE;		} else if (allow_level_II_oplock) {			oplock_level	= OPLOCK_LEVEL_II;		} else {			oplock_level	= OPLOCK_NONE;		}	} else if (oplock_level == OPLOCK_BATCH) {		if (lck->file.num_entries == 0) {			oplock_level	= OPLOCK_BATCH;		} else if (allow_level_II_oplock) {			oplock_level	= OPLOCK_LEVEL_II;		} else {			oplock_level	= OPLOCK_NONE;		}	} else if (oplock_level == OPLOCK_LEVEL_II) {		oplock_level	= OPLOCK_LEVEL_II;	} else {		oplock_level	= OPLOCK_NONE;	}	lck->can_open.e->file_handle		= file_handle;	lck->can_open.e->fd			= fd;	lck->can_open.e->allow_level_II_oplock	= allow_level_II_oplock;	lck->can_open.e->oplock_level		= oplock_level;	if (odb->lease_ctx && fd) {		NTSTATUS status;		status = sys_lease_setup(odb->lease_ctx, lck->can_open.e);		NT_STATUS_NOT_OK_RETURN(status);	}	if (oplock_granted) {		if (lck->can_open.e->oplock_level == OPLOCK_EXCLUSIVE) {			*oplock_granted	= EXCLUSIVE_OPLOCK_RETURN;		} else if (lck->can_open.e->oplock_level == OPLOCK_BATCH) {			*oplock_granted	= BATCH_OPLOCK_RETURN;		} else if (lck->can_open.e->oplock_level == OPLOCK_LEVEL_II) {			*oplock_granted	= LEVEL_II_OPLOCK_RETURN;		} else {			*oplock_granted	= NO_OPLOCK_RETURN;		}	}	/* it doesn't conflict, so add it to the end */	lck->file.entries = talloc_realloc(lck, lck->file.entries,					   struct opendb_entry,					   lck->file.num_entries+1);	NT_STATUS_HAVE_NO_MEMORY(lck->file.entries);	lck->file.entries[lck->file.num_entries] = *lck->can_open.e;	lck->file.num_entries++;	talloc_free(lck->can_open.e);	lck->can_open.e = NULL;	return odb_push_record(lck, &lck->file);}/*  register a pending open file in the open files database*/static NTSTATUS odb_tdb_open_file_pending(struct odb_lock *lck, void *private){	struct odb_context *odb = lck->odb;	if (lck->file.path == NULL) {		return NT_STATUS_OBJECT_NAME_NOT_FOUND;	}	lck->file.pending = talloc_realloc(lck, lck->file.pending,					   struct opendb_pending,					   lck->file.num_pending+1);	NT_STATUS_HAVE_NO_MEMORY(lck->file.pending);	lck->file.pending[lck->file.num_pending].server = odb->ntvfs_ctx->server_id;	lck->file.pending[lck->file.num_pending].notify_ptr = private;	lck->file.num_pending++;	return odb_push_record(lck, &lck->file);}/*  remove a opendb entry*/static NTSTATUS odb_tdb_close_file(struct odb_lock *lck, void *file_handle,				   const char **_delete_path){	struct odb_context *odb = lck->odb;	const char *delete_path = NULL;	int i;	if (lck->file.path == NULL) {		return NT_STATUS_OBJECT_NAME_NOT_FOUND;	}	/* find the entry, and delete it */	for (i=0;i<lck->file.num_entries;i++) {		if (file_handle == lck->file.entries[i].file_handle &&		    cluster_id_equal(&odb->ntvfs_ctx->server_id, &lck->file.entries[i].server)) {			if (lck->file.entries[i].delete_on_close) {				lck->file.delete_on_close = true;			}			if (odb->lease_ctx && lck->file.entries[i].fd) {				NTSTATUS status;				status = sys_lease_remove(odb->lease_ctx, &lck->file.entries[i]);				NT_STATUS_NOT_OK_RETURN(status);			}			if (i < lck->file.num_entries-1) {				memmove(lck->file.entries+i, lck->file.entries+i+1,					(lck->file.num_entries - (i+1)) *					sizeof(struct opendb_entry));			}			break;		}	}	if (i == lck->file.num_entries) {		return NT_STATUS_UNSUCCESSFUL;	}	/* send any pending notifications, removing them once sent */	for (i=0;i<lck->file.num_pending;i++) {		messaging_send_ptr(odb->ntvfs_ctx->msg_ctx,				   lck->file.pending[i].server,				   MSG_PVFS_RETRY_OPEN,				   lck->file.pending[i].notify_ptr);	}	lck->file.num_pending = 0;	lck->file.num_entries--;	if (lck->file.num_entries == 0 && lck->file.delete_on_close) {		delete_path = lck->file.path;	}	if (_delete_path) {		*_delete_path = delete_path;	}	return odb_push_record(lck, &lck->file);}/*  update the oplock level of the client*/static NTSTATUS odb_tdb_update_oplock(struct odb_lock *lck, void *file_handle,				      uint32_t oplock_level){	struct odb_context *odb = lck->odb;	int i;	if (lck->file.path == NULL) {		return NT_STATUS_OBJECT_NAME_NOT_FOUND;	}	/* find the entry, and update it */	for (i=0;i<lck->file.num_entries;i++) {		if (file_handle == lck->file.entries[i].file_handle &&		    cluster_id_equal(&odb->ntvfs_ctx->server_id, &lck->file.entries[i].server)) {			lck->file.entries[i].oplock_level = oplock_level;			if (odb->lease_ctx && lck->file.entries[i].fd) {				NTSTATUS status;				status = sys_lease_update(odb->lease_ctx, &lck->file.entries[i]);				NT_STATUS_NOT_OK_RETURN(status);			}			break;		}	}	if (i == lck->file.num_entries) {		return NT_STATUS_UNSUCCESSFUL;	}	/* send any pending notifications, removing them once sent */	for (i=0;i<lck->file.num_pending;i++) {		messaging_send_ptr(odb->ntvfs_ctx->msg_ctx,				   lck->file.pending[i].server,				   MSG_PVFS_RETRY_OPEN,				   lck->file.pending[i].notify_ptr);	}	lck->file.num_pending = 0;	return odb_push_record(lck, &lck->file);}/*  send oplocks breaks to none to all level2 holders*/static NTSTATUS odb_tdb_break_oplocks(struct odb_lock *lck){	struct odb_context *odb = lck->odb;	int i;	bool modified = false;	/* see if anyone has an oplock, which we need to break */	for (i=0;i<lck->file.num_entries;i++) {		if (lck->file.entries[i].oplock_level == OPLOCK_LEVEL_II) {			/*			 * there could be multiple level2 oplocks			 * and we just send a break to none to all of them			 * without waiting for a release			 */			odb_oplock_break_send(odb->ntvfs_ctx->msg_ctx,					      &lck->file.entries[i],					      OPLOCK_BREAK_TO_NONE);			lck->file.entries[i].oplock_level = OPLOCK_NONE;			modified = true;		}	}	if (modified) {		return odb_push_record(lck, &lck->file);	}	return NT_STATUS_OK;}/*  remove a pending opendb entry*/static NTSTATUS odb_tdb_remove_pending(struct odb_lock *lck, void *private){	struct odb_context *odb = lck->odb;	int i;	if (lck->file.path == NULL) {		return NT_STATUS_OBJECT_NAME_NOT_FOUND;	}	/* find the entry, and delete it */	for (i=0;i<lck->file.num_pending;i++) {		if (private == lck->file.pending[i].notify_ptr &&		    cluster_id_equal(&odb->ntvfs_ctx->server_id, &lck->file.pending[i].server)) {			if (i < lck->file.num_pending-1) {				memmove(lck->file.pending+i, lck->file.pending+i+1,					(lck->file.num_pending - (i+1)) *					sizeof(struct opendb_pending));			}			break;		}	}	if (i == lck->file.num_pending) {		return NT_STATUS_UNSUCCESSFUL;	}	lck->file.num_pending--;		return odb_push_record(lck, &lck->file);}/*  rename the path in a open file*/static NTSTATUS odb_tdb_rename(struct odb_lock *lck, const char *path){	if (lck->file.path == NULL) {		/* not having the record at all is OK */		return NT_STATUS_OK;	}	lck->file.path = talloc_strdup(lck, path);	NT_STATUS_HAVE_NO_MEMORY(lck->file.path);	return odb_push_record(lck, &lck->file);}/*  get the path of an open file*/static NTSTATUS odb_tdb_get_path(struct odb_lock *lck, const char **path){	*path = NULL;	/* we don't ignore NT_STATUS_OBJECT_NAME_NOT_FOUND here */	if (lck->file.path == NULL) {		return NT_STATUS_OBJECT_NAME_NOT_FOUND;	}	*path = lck->file.path;	return NT_STATUS_OK;}/*  update delete on close flag on an open file*/static NTSTATUS odb_tdb_set_delete_on_close(struct odb_lock *lck, bool del_on_close){	if (lck->file.path == NULL) {		return NT_STATUS_OBJECT_NAME_NOT_FOUND;	}	lck->file.delete_on_close = del_on_close;	return odb_push_record(lck, &lck->file);}/*  return the current value of the delete_on_close bit, and how many  people still have the file open*/static NTSTATUS odb_tdb_get_delete_on_close(struct odb_context *odb, 					    DATA_BLOB *key, bool *del_on_close){	struct odb_lock *lck;	(*del_on_close) = false;	lck = odb_lock(odb, odb, key);	NT_STATUS_HAVE_NO_MEMORY(lck);	(*del_on_close) = lck->file.delete_on_close;	talloc_free(lck);	return NT_STATUS_OK;}/*  determine if a file can be opened with the given share_access,  create_options and access_mask*/static NTSTATUS odb_tdb_can_open(struct odb_lock *lck,				 uint32_t stream_id, uint32_t share_access,				 uint32_t access_mask, bool delete_on_close,				 uint32_t open_disposition, bool break_to_none){	struct odb_context *odb = lck->odb;	NTSTATUS status;	status = odb_tdb_open_can_internal(odb, &lck->file, stream_id,					   share_access, access_mask,					   delete_on_close, open_disposition,					   break_to_none, &lck->can_open.attrs_only);	NT_STATUS_NOT_OK_RETURN(status);	lck->can_open.e	= talloc(lck, struct opendb_entry);	NT_STATUS_HAVE_NO_MEMORY(lck->can_open.e);	lck->can_open.e->server			= odb->ntvfs_ctx->server_id;	lck->can_open.e->file_handle		= NULL;	lck->can_open.e->fd			= NULL;	lck->can_open.e->stream_id		= stream_id;	lck->can_open.e->share_access		= share_access;	lck->can_open.e->access_mask		= access_mask;	lck->can_open.e->delete_on_close	= delete_on_close;	lck->can_open.e->allow_level_II_oplock	= false;	lck->can_open.e->oplock_level		= OPLOCK_NONE;	return NT_STATUS_OK;}static const struct opendb_ops opendb_tdb_ops = {	.odb_init                = odb_tdb_init,	.odb_lock                = odb_tdb_lock,	.odb_get_key             = odb_tdb_get_key,	.odb_open_file           = odb_tdb_open_file,	.odb_open_file_pending   = odb_tdb_open_file_pending,	.odb_close_file          = odb_tdb_close_file,	.odb_remove_pending      = odb_tdb_remove_pending,	.odb_rename              = odb_tdb_rename,	.odb_get_path            = odb_tdb_get_path,	.odb_set_delete_on_close = odb_tdb_set_delete_on_close,	.odb_get_delete_on_close = odb_tdb_get_delete_on_close,	.odb_can_open            = odb_tdb_can_open,	.odb_update_oplock       = odb_tdb_update_oplock,	.odb_break_oplocks       = odb_tdb_break_oplocks};void odb_tdb_init_ops(void){	sys_lease_init();	odb_set_ops(&opendb_tdb_ops);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -