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

📄 brlock.c

📁 samba-3.0.22.tar.gz 编译smb服务器的源码
💻 C
📖 第 1 页 / 共 2 页
字号:
	tdb_chainlock(tdb, kbuf);	dbuf = tdb_fetch(tdb, kbuf);	lock.context.smbpid = smbpid;	lock.context.pid = pid;	lock.context.tid = tid;	lock.start = start;	lock.size = size;	lock.fnum = fnum;	lock.lock_type = lock_type;	if (dbuf.dptr) {		/* there are existing locks - make sure they don't conflict */		locks = (struct lock_struct *)dbuf.dptr;		count = dbuf.dsize / sizeof(*locks);		for (i=0; i<count; i++) {			if (brl_conflict(&locks[i], &lock)) {				status = brl_lock_failed(&lock);;				/* Did we block ourselves ? */				if (brl_same_context(&locks[i].context, &lock.context))					*my_lock_ctx = True;				goto fail;			}#if ZERO_ZERO			if (lock.start == 0 && lock.size == 0 && 			    locks[i].size == 0) {				break;			}#endif		}	}	/* no conflicts - add it to the list of locks */	tp = SMB_REALLOC(dbuf.dptr, dbuf.dsize + sizeof(*locks));	if (!tp) {		status = NT_STATUS_NO_MEMORY;		goto fail;	} else {		dbuf.dptr = tp;	}	memcpy(dbuf.dptr + dbuf.dsize, &lock, sizeof(lock));	dbuf.dsize += sizeof(lock);#if ZERO_ZERO	/* sort the lock list */	qsort(dbuf.dptr, dbuf.dsize/sizeof(lock), sizeof(lock), lock_compare);#endif	if (tdb_store(tdb, kbuf, dbuf, TDB_REPLACE) != 0) {		status = NT_STATUS_INTERNAL_DB_CORRUPTION;		goto fail;	}	SAFE_FREE(dbuf.dptr);	tdb_chainunlock(tdb, kbuf);	return NT_STATUS_OK; fail:	SAFE_FREE(dbuf.dptr);	tdb_chainunlock(tdb, kbuf);	return status;}/**************************************************************************** Check if an unlock overlaps a pending lock.****************************************************************************/static BOOL brl_pending_overlap(struct lock_struct *lock, struct lock_struct *pend_lock){	if ((lock->start <= pend_lock->start) && (lock->start + lock->size > pend_lock->start))		return True;	if ((lock->start >= pend_lock->start) && (lock->start <= pend_lock->start + pend_lock->size))		return True;	return False;}/**************************************************************************** Unlock a range of bytes.****************************************************************************/BOOL brl_unlock(SMB_DEV_T dev, SMB_INO_T ino, int fnum,		uint16 smbpid, struct process_id pid, uint16 tid,		br_off start, br_off size,		BOOL remove_pending_locks_only,		void (*pre_unlock_fn)(void *),		void *pre_unlock_data){	TDB_DATA kbuf, dbuf;	int count, i, j;	struct lock_struct *locks;	struct lock_context context;	kbuf = locking_key(dev,ino);	dbuf.dptr = NULL;	tdb_chainlock(tdb, kbuf);	dbuf = tdb_fetch(tdb, kbuf);	if (!dbuf.dptr) {		DEBUG(10,("brl_unlock: tdb_fetch failed !\n"));		goto fail;	}	context.smbpid = smbpid;	context.pid = pid;	context.tid = tid;	/* there are existing locks - find a match */	locks = (struct lock_struct *)dbuf.dptr;	count = dbuf.dsize / sizeof(*locks);#if ZERO_ZERO	for (i=0; i<count; i++) {		struct lock_struct *lock = &locks[i];		if (lock->lock_type == WRITE_LOCK &&		    brl_same_context(&lock->context, &context) &&		    lock->fnum == fnum &&		    lock->start == start &&		    lock->size == size) {			if (pre_unlock_fn)				(*pre_unlock_fn)(pre_unlock_data);			/* found it - delete it */			if (count == 1) {				tdb_delete(tdb, kbuf);			} else {				if (i < count-1) {					memmove(&locks[i], &locks[i+1], 						sizeof(*locks)*((count-1) - i));				}				dbuf.dsize -= sizeof(*locks);				tdb_store(tdb, kbuf, dbuf, TDB_REPLACE);			}			SAFE_FREE(dbuf.dptr);			tdb_chainunlock(tdb, kbuf);			return True;		}	}#endif	locks = (struct lock_struct *)dbuf.dptr;	count = dbuf.dsize / sizeof(*locks);	for (i=0; i<count; i++) {		struct lock_struct *lock = &locks[i];		if (brl_same_context(&lock->context, &context) &&				lock->fnum == fnum &&				lock->start == start &&				lock->size == size) {			if (remove_pending_locks_only && lock->lock_type != PENDING_LOCK)				continue;			if (lock->lock_type != PENDING_LOCK) {				/* Do any POSIX unlocks needed. */				if (pre_unlock_fn)					(*pre_unlock_fn)(pre_unlock_data);				/* Send unlock messages to any pending waiters that overlap. */				for (j=0; j<count; j++) {					struct lock_struct *pend_lock = &locks[j];					/* Ignore non-pending locks. */					if (pend_lock->lock_type != PENDING_LOCK)						continue;					/* We could send specific lock info here... */					if (brl_pending_overlap(lock, pend_lock)) {						DEBUG(10,("brl_unlock: sending unlock message to pid %s\n",									procid_str_static(&pend_lock->context.pid )));						message_send_pid(pend_lock->context.pid,								MSG_SMB_UNLOCK,								NULL, 0, True);					}				}			}			/* found it - delete it */			if (count == 1) {				tdb_delete(tdb, kbuf);			} else {				if (i < count-1) {					memmove(&locks[i], &locks[i+1], 						sizeof(*locks)*((count-1) - i));				}				dbuf.dsize -= sizeof(*locks);				tdb_store(tdb, kbuf, dbuf, TDB_REPLACE);			}			SAFE_FREE(dbuf.dptr);			tdb_chainunlock(tdb, kbuf);			return True;		}	}	/* we didn't find it */ fail:	SAFE_FREE(dbuf.dptr);	tdb_chainunlock(tdb, kbuf);	return False;}/**************************************************************************** Test if we could add a lock if we wanted to.****************************************************************************/BOOL brl_locktest(SMB_DEV_T dev, SMB_INO_T ino, int fnum,		  uint16 smbpid, struct process_id pid, uint16 tid,		  br_off start, br_off size, 		  enum brl_type lock_type){	TDB_DATA kbuf, dbuf;	int count, i;	struct lock_struct lock, *locks;	kbuf = locking_key(dev,ino);	dbuf.dptr = NULL;	dbuf = tdb_fetch(tdb, kbuf);	lock.context.smbpid = smbpid;	lock.context.pid = pid;	lock.context.tid = tid;	lock.start = start;	lock.size = size;	lock.fnum = fnum;	lock.lock_type = lock_type;	if (dbuf.dptr) {		/* there are existing locks - make sure they don't conflict */		locks = (struct lock_struct *)dbuf.dptr;		count = dbuf.dsize / sizeof(*locks);		for (i=0; i<count; i++) {			/*			 * Our own locks don't conflict.			 */			if (brl_conflict_other(&locks[i], &lock))				goto fail;		}	}	/* no conflicts - we could have added it */	SAFE_FREE(dbuf.dptr);	return True; fail:	SAFE_FREE(dbuf.dptr);	return False;}/**************************************************************************** Remove any locks associated with a open file.****************************************************************************/void brl_close(SMB_DEV_T dev, SMB_INO_T ino, struct process_id pid, int tid, int fnum){	TDB_DATA kbuf, dbuf;	int count, i, j, dcount=0;	struct lock_struct *locks;	kbuf = locking_key(dev,ino);	dbuf.dptr = NULL;	tdb_chainlock(tdb, kbuf);	dbuf = tdb_fetch(tdb, kbuf);	if (!dbuf.dptr) goto fail;	/* there are existing locks - remove any for this fnum */	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.tid == tid &&		    procid_equal(&lock->context.pid, &pid) &&		    lock->fnum == fnum) {			/* Send unlock messages to any pending waiters that overlap. */			for (j=0; j<count; j++) {				struct lock_struct *pend_lock = &locks[j];				/* Ignore our own or non-pending locks. */				if (pend_lock->lock_type != PENDING_LOCK)					continue;				if (pend_lock->context.tid == tid &&				    procid_equal(&pend_lock->context.pid, &pid) &&				    pend_lock->fnum == fnum)					continue;				/* We could send specific lock info here... */				if (brl_pending_overlap(lock, pend_lock))					message_send_pid(pend_lock->context.pid,							MSG_SMB_UNLOCK,							NULL, 0, True);			}			/* 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 (count == 0) {		tdb_delete(tdb, kbuf);	} else if (count < (dbuf.dsize / sizeof(*locks))) {		dbuf.dsize -= dcount * sizeof(*locks);		tdb_store(tdb, kbuf, dbuf, TDB_REPLACE);	}	/* we didn't find it */ fail:	SAFE_FREE(dbuf.dptr);	tdb_chainunlock(tdb, kbuf);}/**************************************************************************** Traverse the whole database with this function, calling traverse_callback on each lock.****************************************************************************/static int traverse_fn(TDB_CONTEXT *ttdb, TDB_DATA kbuf, TDB_DATA dbuf, void *state){	struct lock_struct *locks;	struct lock_key *key;	int i;	BRLOCK_FN(traverse_callback) = (BRLOCK_FN_CAST())state;	locks = (struct lock_struct *)dbuf.dptr;	key = (struct lock_key *)kbuf.dptr;	for (i=0;i<dbuf.dsize/sizeof(*locks);i++) {		traverse_callback(key->device, key->inode,				  locks[i].context.pid,				  locks[i].lock_type,				  locks[i].start,				  locks[i].size);	}	return 0;}/******************************************************************* Call the specified function on each lock in the database.********************************************************************/int brl_forall(BRLOCK_FN(fn)){	if (!tdb) return 0;	return tdb_traverse(tdb, traverse_fn, (void *)fn);}

⌨️ 快捷键说明

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