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

📄 brlock_ctdb.c

📁 samba最新软件
💻 C
📖 第 1 页 / 共 2 页
字号:
			if (nlocks == NULL) {				return CTDB_ERR_NOMEM;			}			call->reply_data->dptr = (uint8_t *)nlocks;			nlocks[ncount] = locks[i];			call->reply_data->dsize += sizeof(struct lock_struct);		}	}	return 0;}/*  send notifications for all pending locks - the file is being closed by this  user*/static int brl_ctdb_notify_all(struct ctdb_call_info *call,				struct lock_struct *locks, int count){	int i;	for (i=0;i<count;i++) {		if (locks->lock_type >= PENDING_READ_LOCK) {			int ret = brl_ctdb_notify_unlock(call, locks, count, &locks[i]);			if (ret != 0) return ret;		}	}	return 0;}/*  send off any messages needed to notify of pending locks that should now retry*/static void brl_ctdb_notify_send(struct brl_context *brl, TDB_DATA *reply_data){	struct lock_struct *locks = (struct lock_struct *)reply_data->dptr;	int i, count = reply_data->dsize / sizeof(struct lock_struct);	for (i=0;i<count;i++) {		messaging_send_ptr(brl->messaging_ctx, locks[i].context.server, 				   MSG_BRL_RETRY, locks[i].notify_ptr);	}}struct ctdb_unlock_req {	uint16_t smbpid;	uint64_t start;	uint64_t size;	struct server_id server;	struct brl_context *brl;	struct ntvfs_handle *ntvfs;};/* Unlock a range of bytes.*/static int brl_ctdb_unlock_func(struct ctdb_call_info *call){	struct ctdb_unlock_req *req = (struct ctdb_unlock_req *)call->call_data->dptr;	TDB_DATA dbuf;	int count, i;	struct lock_struct *locks, *lock;	struct lock_context context;	NTSTATUS status = NT_STATUS_OK;	dbuf = call->record_data;	context.smbpid = req->smbpid;	context.server = req->server;	context.ctx = req->brl;	/* there are existing locks - find a match */	locks = (struct lock_struct *)dbuf.dptr;	count = dbuf.dsize / sizeof(*locks);	for (i=0; i<count; i++) {		lock = &locks[i];		if (brl_ctdb_same_context(&lock->context, &context) &&		    lock->ntvfs == req->ntvfs &&		    lock->start == req->start &&		    lock->size == req->size &&		    lock->lock_type == WRITE_LOCK) {			break;		}	}	if (i < count) goto found;	for (i=0; i<count; i++) {		lock = &locks[i];		if (brl_ctdb_same_context(&lock->context, &context) &&		    lock->ntvfs == req->ntvfs &&		    lock->start == req->start &&		    lock->size == req->size &&		    lock->lock_type < PENDING_READ_LOCK) {			break;		}	}found:	if (i < count) {		struct lock_struct removed_lock = *lock;		call->new_data = talloc(call, TDB_DATA);		if (call->new_data == NULL) {			return CTDB_ERR_NOMEM;		}				call->new_data->dptr = talloc_size(call, dbuf.dsize - sizeof(*lock));		if (call->new_data->dptr == NULL) {			return CTDB_ERR_NOMEM;		}		call->new_data->dsize = dbuf.dsize - sizeof(*lock);				memcpy(call->new_data->dptr, locks, i*sizeof(*lock));		memcpy(call->new_data->dptr+i*sizeof(*lock), locks+i+1,		       (count-(i+1))*sizeof(*lock));				if (count > 1) {			int ret = brl_ctdb_notify_unlock(call, locks, count, &removed_lock);			if (ret != 0) return ret;		}	}	if (i == count) {		/* we didn't find it */		status = NT_STATUS_RANGE_NOT_LOCKED;	}	call->status = NT_STATUS_V(status);	return 0;}/* Unlock a range of bytes.*/static NTSTATUS brl_ctdb_unlock(struct brl_context *brl,				struct brl_handle *brlh, 				uint16_t smbpid,				uint64_t start, uint64_t size){	struct ctdb_call call;	struct ctdb_unlock_req req;	int ret;	call.call_id = FUNC_BRL_UNLOCK;	call.key.dptr = brlh->key.data;	call.key.dsize = brlh->key.length;	call.call_data.dptr = (uint8_t *)&req;	call.call_data.dsize = sizeof(req);	ZERO_STRUCT(req);	req.smbpid = smbpid;	req.start  = start;	req.size   = size;	req.server = brl->server;	req.brl = brl;	req.ntvfs = brlh->ntvfs;			ret = ctdb_call(brl->ctdb_db, &call);	if (ret == -1) {		DEBUG(0,("ctdb_call failed - %s\n", __location__));		return NT_STATUS_INTERNAL_DB_CORRUPTION;	}	brl_ctdb_notify_send(brl, &call.reply_data);	return NT_STATUS(call.status);}struct ctdb_remove_pending_req {	struct server_id server;	void *notify_ptr;};/*  remove a pending lock. This is called when the caller has either  given up trying to establish a lock or when they have succeeded in  getting it. In either case they no longer need to be notified.*/static int brl_ctdb_remove_pending_func(struct ctdb_call_info *call){	struct ctdb_remove_pending_req *req = (struct ctdb_remove_pending_req *)call->call_data->dptr;	TDB_DATA dbuf;	int count, i;	struct lock_struct *locks;	NTSTATUS status = NT_STATUS_OK;	dbuf = call->record_data;	/* there are existing locks - find a match */	locks = (struct lock_struct *)dbuf.dptr;	count = dbuf.dsize / sizeof(*locks);	for (i=0; i<count; i++) {		struct lock_struct *lock = &locks[i];				if (lock->lock_type >= PENDING_READ_LOCK &&		    lock->notify_ptr == req->notify_ptr &&		    cluster_id_equal(&lock->context.server, &req->server)) {			call->new_data = talloc(call, TDB_DATA);			if (call->new_data == NULL) {				return CTDB_ERR_NOMEM;			}			call->new_data->dptr = talloc_size(call, dbuf.dsize - sizeof(*lock));			if (call->new_data->dptr == NULL) {				return CTDB_ERR_NOMEM;			}			call->new_data->dsize = dbuf.dsize - sizeof(*lock);			memcpy(call->new_data->dptr, locks, i*sizeof(*lock));			memcpy(call->new_data->dptr+i*sizeof(*lock), locks+i+1,			       (count-(i+1))*sizeof(*lock));			break;		}	}		if (i == count) {		/* we didn't find it */		status = NT_STATUS_RANGE_NOT_LOCKED;	}	call->status = NT_STATUS_V(status);	return 0;}static NTSTATUS brl_ctdb_remove_pending(struct brl_context *brl,					struct brl_handle *brlh, 					void *notify_ptr){	struct ctdb_call call;	struct ctdb_remove_pending_req req;	int ret;	call.call_id = FUNC_BRL_REMOVE_PENDING;	call.key.dptr = brlh->key.data;	call.key.dsize = brlh->key.length;	call.call_data.dptr = (uint8_t *)&req;	call.call_data.dsize = sizeof(req);	ZERO_STRUCT(req);	req.notify_ptr = notify_ptr;	req.server = brl->server;			ret = ctdb_call(brl->ctdb_db, &call);	if (ret == -1) {		DEBUG(0,("ctdb_call failed - %s\n", __location__));		return NT_STATUS_INTERNAL_DB_CORRUPTION;	}	return NT_STATUS(call.status);}struct ctdb_locktest_req {	uint16_t smbpid;	uint64_t start;	uint64_t size;	enum brl_type lock_type;	struct brl_context *brl;	struct server_id server;	struct ntvfs_handle *ntvfs;};/*  remove a pending lock. This is called when the caller has either  given up trying to establish a lock or when they have succeeded in  getting it. In either case they no longer need to be notified.*/static int brl_ctdb_locktest_func(struct ctdb_call_info *call){	struct ctdb_locktest_req *req = (struct ctdb_locktest_req *)call->call_data->dptr;	TDB_DATA dbuf;	int count, i;	struct lock_struct *locks, lock;	NTSTATUS status = NT_STATUS_OK;	lock.context.smbpid = req->smbpid;	lock.context.server = req->server;	lock.context.ctx = req->brl;	lock.ntvfs = req->ntvfs;	lock.start = req->start;	lock.size = req->size;	lock.lock_type = req->lock_type;	dbuf = call->record_data;	/* there are existing locks - find a match */	locks = (struct lock_struct *)dbuf.dptr;	count = dbuf.dsize / sizeof(*locks);	for (i=0; i<count; i++) {		if (brl_ctdb_conflict_other(&locks[i], &lock)) {			status = NT_STATUS_FILE_LOCK_CONFLICT;			break;		}	}		call->status = NT_STATUS_V(status);	return 0;}/*  Test if we are allowed to perform IO on a region of an open file*/static NTSTATUS brl_ctdb_locktest(struct brl_context *brl,				  struct brl_handle *brlh,				  uint16_t smbpid, 				  uint64_t start, uint64_t size, 				  enum brl_type lock_type){	struct ctdb_call call;	struct ctdb_locktest_req req;	int ret;	call.call_id = FUNC_BRL_LOCKTEST;	call.key.dptr = brlh->key.data;	call.key.dsize = brlh->key.length;	call.call_data.dptr = (uint8_t *)&req;	call.call_data.dsize = sizeof(req);	ZERO_STRUCT(req);	req.smbpid = smbpid;	req.start  = start;	req.size   = size;	req.lock_type = lock_type;	req.server = brl->server;	req.brl = brl;	req.ntvfs = brlh->ntvfs;	ret = ctdb_call(brl->ctdb_db, &call);	if (ret == -1) {		DEBUG(0,("ctdb_call failed - %s\n", __location__));		return NT_STATUS_INTERNAL_DB_CORRUPTION;	}	return NT_STATUS(call.status);}struct ctdb_close_req {	struct brl_context *brl;	struct server_id server;	struct ntvfs_handle *ntvfs;};/*  remove a pending lock. This is called when the caller has either  given up trying to establish a lock or when they have succeeded in  getting it. In either case they no longer need to be notified.*/static int brl_ctdb_close_func(struct ctdb_call_info *call){	struct ctdb_close_req *req = (struct ctdb_close_req *)call->call_data->dptr;	TDB_DATA dbuf;	int count, dcount=0, i;	struct lock_struct *locks;	NTSTATUS status = NT_STATUS_OK;	dbuf = call->record_data;	/* there are existing locks - find a match */	locks = (struct lock_struct *)dbuf.dptr;	count = dbuf.dsize / sizeof(*locks);	for (i=0; i<count; i++) {		struct lock_struct *lock = &locks[i];		if (lock->context.ctx == req->brl &&		    cluster_id_equal(&lock->context.server, &req->server) &&		    lock->ntvfs == req->ntvfs) {			/* found it - delete it */			if (count > 1 && i < count-1) {				memmove(&locks[i], &locks[i+1], 					sizeof(*locks)*((count-1) - i));			}			count--;			i--;			dcount++;		}	}	if (dcount > 0) {		call->new_data = talloc(call, TDB_DATA);		if (call->new_data == NULL) {			return CTDB_ERR_NOMEM;		}		brl_ctdb_notify_all(call, locks, count);				call->new_data->dptr = talloc_size(call, count*sizeof(struct lock_struct));		if (call->new_data->dptr == NULL) {			return CTDB_ERR_NOMEM;		}		call->new_data->dsize = count*sizeof(struct lock_struct);		memcpy(call->new_data->dptr, locks, count*sizeof(struct lock_struct));	}	call->status = NT_STATUS_V(status);	return 0;}/*  Test if we are allowed to perform IO on a region of an open file*/static NTSTATUS brl_ctdb_close(struct brl_context *brl,			       struct brl_handle *brlh){	struct ctdb_call call;	struct ctdb_close_req req;	int ret;	call.call_id = FUNC_BRL_CLOSE;	call.key.dptr = brlh->key.data;	call.key.dsize = brlh->key.length;	call.call_data.dptr = (uint8_t *)&req;	call.call_data.dsize = sizeof(req);	ZERO_STRUCT(req);	req.brl = brl;	req.server = brl->server;	req.ntvfs = brlh->ntvfs;	ret = ctdb_call(brl->ctdb_db, &call);	if (ret == -1) {		DEBUG(0,("ctdb_call failed - %s\n", __location__));		return NT_STATUS_INTERNAL_DB_CORRUPTION;	}	brl_ctdb_notify_send(brl, &call.reply_data);	return NT_STATUS(call.status);}static const struct brlock_ops brlock_tdb_ops = {	.brl_init           = brl_ctdb_init,	.brl_create_handle  = brl_ctdb_create_handle,	.brl_lock           = brl_ctdb_lock,	.brl_unlock         = brl_ctdb_unlock,	.brl_remove_pending = brl_ctdb_remove_pending,	.brl_locktest       = brl_ctdb_locktest,	.brl_close          = brl_ctdb_close};void brl_ctdb_init_ops(void){	struct ctdb_context *ctdb = talloc_get_type(cluster_backend_handle(), 						    struct ctdb_context);	struct ctdb_db_context *ctdb_db;	brl_set_ops(&brlock_tdb_ops);	ctdb_db = ctdb_db_handle(ctdb, "brlock");	if (ctdb_db == NULL) {		DEBUG(0,("Failed to get attached ctdb db handle for brlock\n"));		return;	}	ctdb_set_call(ctdb_db, brl_ctdb_lock_func,  FUNC_BRL_LOCK);	ctdb_set_call(ctdb_db, brl_ctdb_unlock_func,  FUNC_BRL_UNLOCK);	ctdb_set_call(ctdb_db, brl_ctdb_remove_pending_func,  FUNC_BRL_REMOVE_PENDING);	ctdb_set_call(ctdb_db, brl_ctdb_locktest_func,  FUNC_BRL_LOCKTEST);	ctdb_set_call(ctdb_db, brl_ctdb_close_func,  FUNC_BRL_CLOSE);}

⌨️ 快捷键说明

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