NTSTATUS query_lock(files_struct *fsp, uint32 *psmbpid, SMB_BIG_UINT *pcount, SMB_BIG_UINT *poffset, enum brl_type *plock_type, enum brl_flavour lock_flav) { struct byte_range_lock *br_lck = NULL; NTSTATUS status = NT_STATUS_LOCK_NOT_GRANTED; if (!fsp->can_lock) { return fsp->is_directory ? NT_STATUS_INVALID_DEVICE_REQUEST : NT_STATUS_INVALID_HANDLE; } if (!lp_locking(fsp->conn->params)) { return NT_STATUS_OK; } br_lck = brl_get_locks_readonly(NULL, fsp); if (!br_lck) { return NT_STATUS_NO_MEMORY; } status = brl_lockquery(br_lck, psmbpid, procid_self(), poffset, pcount, plock_type, lock_flav); TALLOC_FREE(br_lck); return status; }
void locking_close_file(struct messaging_context *msg_ctx, files_struct *fsp, enum file_close_type close_type) { struct byte_range_lock *br_lck; if (!lp_locking(fsp->conn->params)) { return; } /* If we have not outstanding locks or pending * locks then we don't need to look in the lock db. */ if (fsp->current_lock_count == 0) { return; } br_lck = brl_get_locks(talloc_tos(),fsp); if (br_lck) { cancel_pending_lock_requests_by_fid(fsp, br_lck, close_type); brl_close_fnum(msg_ctx, br_lck); TALLOC_FREE(br_lck); } }
BOOL is_locked(uint16 smbpid, files_struct * fsp, struct vfs_connection_struct *conn, SMB_BIG_UINT count, SMB_BIG_UINT offset, enum brl_type lock_type) { int snum = conn->snum; BOOL ret; if (count == 0) return (False); if (!lp_locking(snum) || !lp_strict_locking(snum)) return (False); ret = !brl_locktest(fsp->sbuf.st_dev, fsp->sbuf.st_ino, fsp->fnum, smbpid, sys_getpid(), conn->snum, offset, count, lock_type); /* * There is no lock held by an SMB daemon, check to * see if there is a POSIX lock from a UNIX or NFS process. */ if (!ret && lp_posix_locking(snum)) ret = is_posix_locked(fsp, offset, count, lock_type); return ret; }
struct byte_range_lock *do_lock(files_struct *fsp, uint32 lock_pid, SMB_BIG_UINT count, SMB_BIG_UINT offset, enum brl_type lock_type, enum brl_flavour lock_flav, BOOL blocking_lock, NTSTATUS *perr, uint32 *plock_pid) { struct byte_range_lock *br_lck = NULL; if (!fsp->can_lock) { *perr = fsp->is_directory ? NT_STATUS_INVALID_DEVICE_REQUEST : NT_STATUS_INVALID_HANDLE; return NULL; } if (!lp_locking(fsp->conn->params)) { *perr = NT_STATUS_OK; return NULL; } /* NOTE! 0 byte long ranges ARE allowed and should be stored */ DEBUG(10,("do_lock: lock flavour %s lock type %s start=%.0f len=%.0f requested for fnum %d file %s\n", lock_flav_name(lock_flav), lock_type_name(lock_type), (double)offset, (double)count, fsp->fnum, fsp->fsp_name )); br_lck = brl_get_locks(NULL, fsp); if (!br_lck) { *perr = NT_STATUS_NO_MEMORY; return NULL; } *perr = brl_lock(br_lck, lock_pid, procid_self(), offset, count, lock_type, lock_flav, blocking_lock, plock_pid); if (lock_flav == WINDOWS_LOCK && fsp->current_lock_count != NO_LOCKING_COUNT) { /* blocking ie. pending, locks also count here, * as this is an efficiency counter to avoid checking * the lock db. on close. JRA. */ fsp->current_lock_count++; } else { /* Notice that this has had a POSIX lock request. * We can't count locks after this so forget them. */ fsp->current_lock_count = NO_LOCKING_COUNT; } return br_lck; }
NTSTATUS query_lock(files_struct *fsp, uint16 *psmbpid, SMB_BIG_UINT *pcount, SMB_BIG_UINT *poffset, enum brl_type *plock_type, enum brl_flavour lock_flav) { struct byte_range_lock *br_lck = NULL; NTSTATUS status = NT_STATUS_LOCK_NOT_GRANTED; if (!OPEN_FSP(fsp) || !fsp->can_lock) { return NT_STATUS_INVALID_HANDLE; } if (!lp_locking(SNUM(fsp->conn))) { return NT_STATUS_OK; } br_lck = brl_get_locks(fsp); if (!br_lck) { return NT_STATUS_NO_MEMORY; } status = brl_lockquery(br_lck, psmbpid, procid_self(), poffset, pcount, plock_type, lock_flav); byte_range_lock_destructor(br_lck); return status; }
NTSTATUS query_lock(files_struct *fsp, uint64_t *psmblctx, uint64_t *pcount, uint64_t *poffset, enum brl_type *plock_type, enum brl_flavour lock_flav) { struct byte_range_lock *br_lck = NULL; if (!fsp->can_lock) { return fsp->is_directory ? NT_STATUS_INVALID_DEVICE_REQUEST : NT_STATUS_INVALID_HANDLE; } if (!lp_locking(fsp->conn->params)) { return NT_STATUS_OK; } br_lck = brl_get_locks_readonly(fsp); if (!br_lck) { return NT_STATUS_NO_MEMORY; } return brl_lockquery(br_lck, psmblctx, messaging_server_id(fsp->conn->sconn->msg_ctx), poffset, pcount, plock_type, lock_flav); }
NTSTATUS do_lock_cancel(files_struct *fsp, uint32 lock_pid, SMB_BIG_UINT count, SMB_BIG_UINT offset, enum brl_flavour lock_flav) { BOOL ok = False; struct byte_range_lock *br_lck = NULL; if (!fsp->can_lock) { return fsp->is_directory ? NT_STATUS_INVALID_DEVICE_REQUEST : NT_STATUS_INVALID_HANDLE; } if (!lp_locking(fsp->conn->params)) { return NT_STATUS_DOS(ERRDOS, ERRcancelviolation); } DEBUG(10,("do_lock_cancel: cancel start=%.0f len=%.0f requested for fnum %d file %s\n", (double)offset, (double)count, fsp->fnum, fsp->fsp_name )); br_lck = brl_get_locks(NULL, fsp); if (!br_lck) { return NT_STATUS_NO_MEMORY; } ok = brl_lock_cancel(br_lck, lock_pid, procid_self(), offset, count, lock_flav); TALLOC_FREE(br_lck); if (!ok) { DEBUG(10,("do_lock_cancel: returning ERRcancelviolation.\n" )); return NT_STATUS_DOS(ERRDOS, ERRcancelviolation); } if (lock_flav == WINDOWS_LOCK && fsp->current_lock_count != NO_LOCKING_COUNT) { SMB_ASSERT(fsp->current_lock_count > 0); fsp->current_lock_count--; } return NT_STATUS_OK; }
NTSTATUS do_lock_cancel(files_struct *fsp, uint64 smblctx, uint64_t count, uint64_t offset, enum brl_flavour lock_flav, struct blocking_lock_record *blr) { bool ok = False; struct byte_range_lock *br_lck = NULL; if (!fsp->can_lock) { return fsp->is_directory ? NT_STATUS_INVALID_DEVICE_REQUEST : NT_STATUS_INVALID_HANDLE; } if (!lp_locking(fsp->conn->params)) { return NT_STATUS_DOS(ERRDOS, ERRcancelviolation); } DEBUG(10,("do_lock_cancel: cancel start=%.0f len=%.0f requested for %s file %s\n", (double)offset, (double)count, fsp_fnum_dbg(fsp), fsp_str_dbg(fsp))); br_lck = brl_get_locks(talloc_tos(), fsp); if (!br_lck) { return NT_STATUS_NO_MEMORY; } ok = brl_lock_cancel(br_lck, smblctx, messaging_server_id(fsp->conn->sconn->msg_ctx), offset, count, lock_flav, blr); TALLOC_FREE(br_lck); if (!ok) { DEBUG(10,("do_lock_cancel: returning ERRcancelviolation.\n" )); return NT_STATUS_DOS(ERRDOS, ERRcancelviolation); } decrement_current_lock_count(fsp, lock_flav); return NT_STATUS_OK; }
NTSTATUS do_unlock(struct messaging_context *msg_ctx, files_struct *fsp, uint64_t smblctx, uint64_t count, uint64_t offset, enum brl_flavour lock_flav) { bool ok = False; struct byte_range_lock *br_lck = NULL; if (!fsp->can_lock) { return fsp->is_directory ? NT_STATUS_INVALID_DEVICE_REQUEST : NT_STATUS_INVALID_HANDLE; } if (!lp_locking(fsp->conn->params)) { return NT_STATUS_OK; } DEBUG(10,("do_unlock: unlock start=%.0f len=%.0f requested for %s file %s\n", (double)offset, (double)count, fsp_fnum_dbg(fsp), fsp_str_dbg(fsp))); br_lck = brl_get_locks(talloc_tos(), fsp); if (!br_lck) { return NT_STATUS_NO_MEMORY; } ok = brl_unlock(msg_ctx, br_lck, smblctx, messaging_server_id(fsp->conn->sconn->msg_ctx), offset, count, lock_flav); TALLOC_FREE(br_lck); if (!ok) { DEBUG(10,("do_unlock: returning ERRlock.\n" )); return NT_STATUS_RANGE_NOT_LOCKED; } decrement_current_lock_count(fsp, lock_flav); return NT_STATUS_OK; }
BOOL do_unlock(uint16 smbpid, files_struct * fsp, struct vfs_connection_struct *conn, SMB_BIG_UINT count, SMB_BIG_UINT offset, uint32 *err) { BOOL ok = False; if (!lp_locking(conn->snum)) return (True); if (!OPEN_FSP(fsp) || !fsp->can_lock || (fsp->conn != conn)) { *err = NT_STATUS_NOT_LOCKED; return False; } DEBUG(10, ("do_unlock: unlock start=%.0f len=%.0f requested for file %s\n", (double)offset, (double)count, smbstrA(fsp->fsp_name))); /* * Remove the existing lock record from the tdb lockdb * before looking at POSIX locks. If this record doesn't * match then don't bother looking to remove POSIX locks. */ ok = brl_unlock(fsp->sbuf.st_dev, fsp->sbuf.st_ino, fsp->fnum, smbpid, sys_getpid(), conn->snum, offset, count); if (!ok) { DEBUG(10, ("do_unlock: returning ERRlock.\n")); *err = NT_STATUS_RANGE_NOT_LOCKED; return False; } if (!lp_posix_locking(conn->snum)) return True; (void)release_posix_lock(fsp, offset, count); return True; /* Did unlock */ }
static NTSTATUS do_lock(files_struct *fsp,connection_struct *conn, uint16 lock_pid, SMB_BIG_UINT count,SMB_BIG_UINT offset,enum brl_type lock_type) { NTSTATUS status; if (!lp_locking(SNUM(conn))) return NT_STATUS_OK; /* NOTE! 0 byte long ranges ARE allowed and should be stored */ DEBUG(10,("do_lock: lock type %s start=%.0f len=%.0f requested for file %s\n", lock_type_name(lock_type), (double)offset, (double)count, fsp->fsp_name )); if (OPEN_FSP(fsp) && fsp->can_lock && (fsp->conn == conn)) { status = brl_lock(fsp->dev, fsp->inode, fsp->fnum, lock_pid, sys_getpid(), conn->cnum, offset, count, lock_type); if (NT_STATUS_IS_OK(status) && lp_posix_locking(SNUM(conn))) { /* * Try and get a POSIX lock on this range. * Note that this is ok if it is a read lock * overlapping on a different fd. JRA. */ if (!set_posix_lock(fsp, offset, count, lock_type)) { status = NT_STATUS_LOCK_NOT_GRANTED; /* * We failed to map - we must now remove the brl * lock entry. */ (void)brl_unlock(fsp->dev, fsp->inode, fsp->fnum, lock_pid, sys_getpid(), conn->cnum, offset, count, False); } } } return status; }
NTSTATUS do_lock(files_struct *fsp, uint16 lock_pid, SMB_BIG_UINT count, SMB_BIG_UINT offset, enum brl_type lock_type, enum brl_flavour lock_flav, BOOL *my_lock_ctx) { struct byte_range_lock *br_lck = NULL; NTSTATUS status = NT_STATUS_LOCK_NOT_GRANTED; if (!OPEN_FSP(fsp) || !fsp->can_lock) { return NT_STATUS_INVALID_HANDLE; } if (!lp_locking(SNUM(fsp->conn))) { return NT_STATUS_OK; } /* NOTE! 0 byte long ranges ARE allowed and should be stored */ DEBUG(10,("do_lock: lock flavour %s lock type %s start=%.0f len=%.0f requested for fnum %d file %s\n", lock_flav_name(lock_flav), lock_type_name(lock_type), (double)offset, (double)count, fsp->fnum, fsp->fsp_name )); br_lck = brl_get_locks(fsp); if (!br_lck) { return NT_STATUS_NO_MEMORY; } status = brl_lock(br_lck, lock_pid, procid_self(), offset, count, lock_type, lock_flav, my_lock_ctx); byte_range_lock_destructor(br_lck); return status; }
NTSTATUS do_unlock(files_struct *fsp, uint16 lock_pid, SMB_BIG_UINT count, SMB_BIG_UINT offset, enum brl_flavour lock_flav) { BOOL ok = False; struct byte_range_lock *br_lck = NULL; if (!lp_locking(SNUM(fsp->conn))) { return NT_STATUS_OK; } if (!OPEN_FSP(fsp) || !fsp->can_lock) { return NT_STATUS_INVALID_HANDLE; } DEBUG(10,("do_unlock: unlock start=%.0f len=%.0f requested for fnum %d file %s\n", (double)offset, (double)count, fsp->fnum, fsp->fsp_name )); br_lck = brl_get_locks(fsp); if (!br_lck) { return NT_STATUS_NO_MEMORY; } ok = brl_unlock(br_lck, lock_pid, procid_self(), offset, count, lock_flav); byte_range_lock_destructor(br_lck); if (!ok) { DEBUG(10,("do_unlock: returning ERRlock.\n" )); return NT_STATUS_RANGE_NOT_LOCKED; } return NT_STATUS_OK; }
void locking_close_file(files_struct *fsp) { pid_t pid = sys_getpid(); if (!lp_locking(SNUM(fsp->conn))) return; /* * Just release all the brl locks, no need to release individually. */ brl_close(fsp->dev, fsp->inode, pid, fsp->conn->cnum, fsp->fnum); if(lp_posix_locking(SNUM(fsp->conn))) { /* * Release all the POSIX locks. */ posix_locking_close_file(fsp); } }
void locking_close_file(files_struct *fsp) { struct byte_range_lock *br_lck; if (!lp_locking(fsp->conn->params)) { return; } /* If we have not outstanding locks or pending * locks then we don't need to look in the lock db. */ if (fsp->current_lock_count == 0) { return; } br_lck = brl_get_locks(NULL,fsp); if (br_lck) { cancel_pending_lock_requests_by_fid(fsp, br_lck); brl_close_fnum(br_lck); TALLOC_FREE(br_lck); } }
NTSTATUS do_unlock(files_struct *fsp,connection_struct *conn, uint16 lock_pid, SMB_BIG_UINT count,SMB_BIG_UINT offset) { BOOL ok = False; if (!lp_locking(SNUM(conn))) return NT_STATUS_OK; if (!OPEN_FSP(fsp) || !fsp->can_lock || (fsp->conn != conn)) { return NT_STATUS_INVALID_HANDLE; } DEBUG(10,("do_unlock: unlock start=%.0f len=%.0f requested for file %s\n", (double)offset, (double)count, fsp->fsp_name )); /* * Remove the existing lock record from the tdb lockdb * before looking at POSIX locks. If this record doesn't * match then don't bother looking to remove POSIX locks. */ ok = brl_unlock(fsp->dev, fsp->inode, fsp->fnum, lock_pid, sys_getpid(), conn->cnum, offset, count, False); if (!ok) { DEBUG(10,("do_unlock: returning ERRlock.\n" )); return NT_STATUS_RANGE_NOT_LOCKED; } if (!lp_posix_locking(SNUM(conn))) return NT_STATUS_OK; (void)release_posix_lock(fsp, offset, count); return NT_STATUS_OK; }
BOOL is_locked(files_struct *fsp,connection_struct *conn, SMB_BIG_UINT count,SMB_BIG_UINT offset, enum brl_type lock_type, BOOL check_self) { int snum = SNUM(conn); BOOL ret; if (count == 0) return(False); if (!lp_locking(snum) || !lp_strict_locking(snum)) return(False); ret = !brl_locktest(fsp->dev, fsp->inode, fsp->fnum, global_smbpid, sys_getpid(), conn->cnum, offset, count, lock_type, check_self); DEBUG(10,("is_locked: brl start=%.0f len=%.0f %s for file %s\n", (double)offset, (double)count, ret ? "locked" : "unlocked", fsp->fsp_name )); /* * There is no lock held by an SMB daemon, check to * see if there is a POSIX lock from a UNIX or NFS process. */ if(!ret && lp_posix_locking(snum)) { ret = is_posix_locked(fsp, offset, count, lock_type); DEBUG(10,("is_locked: posix start=%.0f len=%.0f %s for file %s\n", (double)offset, (double)count, ret ? "locked" : "unlocked", fsp->fsp_name )); } return ret; }
void locking_close_file(files_struct *fsp) { struct byte_range_lock *br_lck; struct process_id pid = procid_self(); if (!lp_locking(SNUM(fsp->conn))) return; /* * Just release all the brl locks, no need to release individually. */ br_lck = brl_get_locks(fsp); if (br_lck) { brl_close_fnum(br_lck, pid); byte_range_lock_destructor(br_lck); } if(lp_posix_locking(SNUM(fsp->conn))) { /* Release all the POSIX locks.*/ posix_locking_close_file(fsp); } }
struct byte_range_lock *do_lock(struct messaging_context *msg_ctx, files_struct *fsp, uint64_t smblctx, uint64_t count, uint64_t offset, enum brl_type lock_type, enum brl_flavour lock_flav, bool blocking_lock, NTSTATUS *perr, uint64_t *psmblctx, struct blocking_lock_record *blr) { struct byte_range_lock *br_lck = NULL; /* silently return ok on print files as we don't do locking there */ if (fsp->print_file) { *perr = NT_STATUS_OK; return NULL; } if (!fsp->can_lock) { *perr = fsp->is_directory ? NT_STATUS_INVALID_DEVICE_REQUEST : NT_STATUS_INVALID_HANDLE; return NULL; } if (!lp_locking(fsp->conn->params)) { *perr = NT_STATUS_OK; return NULL; } /* NOTE! 0 byte long ranges ARE allowed and should be stored */ DEBUG(10,("do_lock: lock flavour %s lock type %s start=%.0f len=%.0f " "blocking_lock=%s requested for %s file %s\n", lock_flav_name(lock_flav), lock_type_name(lock_type), (double)offset, (double)count, blocking_lock ? "true" : "false", fsp_fnum_dbg(fsp), fsp_str_dbg(fsp))); br_lck = brl_get_locks(talloc_tos(), fsp); if (!br_lck) { *perr = NT_STATUS_NO_MEMORY; return NULL; } *perr = brl_lock(msg_ctx, br_lck, smblctx, messaging_server_id(fsp->conn->sconn->msg_ctx), offset, count, lock_type, lock_flav, blocking_lock, psmblctx, blr); DEBUG(10, ("do_lock: returning status=%s\n", nt_errstr(*perr))); increment_current_lock_count(fsp, lock_flav); return br_lck; }
BOOL do_lock(uint16 smbpid, files_struct * fsp, struct vfs_connection_struct *conn, SMB_BIG_UINT count, SMB_BIG_UINT offset, enum brl_type lock_type, uint32 *err) { BOOL ok = False; if (!lp_locking(conn->snum)) return (True); if (count == 0) { *err = NT_STATUS_ACCESS_DENIED; return False; } DEBUG(10, ("do_lock: lock type %s start=%.0f len=%.0f requested for file %s\n", lock_type_name(lock_type), (double)offset, (double)count, smbstrA(fsp->fsp_name))); if (OPEN_FSP(fsp) && fsp->can_lock && (fsp->conn == conn)) { ok = brl_lock(fsp->sbuf.st_dev, fsp->sbuf.st_ino, fsp->fnum, smbpid, sys_getpid(), conn->snum, offset, count, lock_type); if (ok && lp_posix_locking(conn->snum)) { /* * Try and get a POSIX lock on this range. * Note that this is ok if it is a read lock * overlapping on a different fd. JRA. */ ok = set_posix_lock(fsp, offset, count, lock_type); if (!ok) { /* * We failed to map - we must now remove the brl * lock entry. */ (void)brl_unlock(fsp->sbuf.st_dev, fsp->sbuf.st_ino, fsp->fnum, smbpid, sys_getpid(), conn->snum, offset, count); } } } if (!ok) { *err = NT_STATUS_LOCK_NOT_GRANTED; return False; } return True; /* Got lock */ }
bool strict_lock_default(files_struct *fsp, struct lock_struct *plock) { int strict_locking = lp_strict_locking(fsp->conn->params); bool ret = False; if (plock->size == 0) { return True; } if (!lp_locking(fsp->conn->params) || !strict_locking) { return True; } if (strict_locking == Auto) { if (EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type) && (plock->lock_type == READ_LOCK || plock->lock_type == WRITE_LOCK)) { DEBUG(10,("is_locked: optimisation - exclusive oplock on file %s\n", fsp_str_dbg(fsp))); ret = True; } else if ((fsp->oplock_type == LEVEL_II_OPLOCK) && (plock->lock_type == READ_LOCK)) { DEBUG(10,("is_locked: optimisation - level II oplock on file %s\n", fsp_str_dbg(fsp))); ret = True; } else { struct byte_range_lock *br_lck; br_lck = brl_get_locks_readonly(fsp); if (!br_lck) { return True; } ret = brl_locktest(br_lck, plock->context.smblctx, plock->context.pid, plock->start, plock->size, plock->lock_type, plock->lock_flav); } } else { struct byte_range_lock *br_lck; br_lck = brl_get_locks_readonly(fsp); if (!br_lck) { return True; } ret = brl_locktest(br_lck, plock->context.smblctx, plock->context.pid, plock->start, plock->size, plock->lock_type, plock->lock_flav); } DEBUG(10,("strict_lock_default: flavour = %s brl start=%.0f " "len=%.0f %s for fnum %llu file %s\n", lock_flav_name(plock->lock_flav), (double)plock->start, (double)plock->size, ret ? "unlocked" : "locked", (unsigned long long)plock->fnum, fsp_str_dbg(fsp))); return ret; }
BOOL is_locked(files_struct *fsp, SMB_BIG_UINT count, SMB_BIG_UINT offset, enum brl_type lock_type) { int snum = SNUM(fsp->conn); int strict_locking = lp_strict_locking(snum); enum brl_flavour lock_flav = lp_posix_cifsu_locktype(); BOOL ret = True; if (count == 0) { return False; } if (!lp_locking(snum) || !strict_locking) { return False; } if (strict_locking == Auto) { if (EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type) && (lock_type == READ_LOCK || lock_type == WRITE_LOCK)) { DEBUG(10,("is_locked: optimisation - exclusive oplock on file %s\n", fsp->fsp_name )); ret = False; } else if ((fsp->oplock_type == LEVEL_II_OPLOCK) && (lock_type == READ_LOCK)) { DEBUG(10,("is_locked: optimisation - level II oplock on file %s\n", fsp->fsp_name )); ret = False; } else { struct byte_range_lock *br_lck = brl_get_locks(fsp); if (!br_lck) { return False; } ret = !brl_locktest(br_lck, global_smbpid, procid_self(), offset, count, lock_type, lock_flav); byte_range_lock_destructor(br_lck); } } else { struct byte_range_lock *br_lck = brl_get_locks(fsp); if (!br_lck) { return False; } ret = !brl_locktest(br_lck, global_smbpid, procid_self(), offset, count, lock_type, lock_flav); byte_range_lock_destructor(br_lck); } DEBUG(10,("is_locked: flavour = %s brl start=%.0f len=%.0f %s for fnum %d file %s\n", lock_flav_name(lock_flav), (double)offset, (double)count, ret ? "locked" : "unlocked", fsp->fnum, fsp->fsp_name )); return ret; }
int fd_close_posix(struct files_struct *fsp) { int saved_errno = 0; int ret; int *fd_array = NULL; size_t count, i; if (!lp_locking(fsp->conn->params) || !lp_posix_locking(fsp->conn->params)) { /* * No locking or POSIX to worry about or we want POSIX semantics * which will lose all locks on all fd's open on this dev/inode, * just close. */ return close(fsp->fh->fd); } if (get_windows_lock_ref_count(fsp)) { /* * There are outstanding locks on this dev/inode pair on * other fds. Add our fd to the pending close tdb and set * fsp->fh->fd to -1. */ add_fd_to_close_entry(fsp); return 0; } /* * No outstanding locks. Get the pending close fd's * from the tdb and close them all. */ count = get_posix_pending_close_entries(talloc_tos(), fsp, &fd_array); if (count) { DEBUG(10,("fd_close_posix: doing close on %u fd's.\n", (unsigned int)count)); for(i = 0; i < count; i++) { if (close(fd_array[i]) == -1) { saved_errno = errno; } } /* * Delete all fd's stored in the tdb * for this dev/inode pair. */ delete_close_entries(fsp); } TALLOC_FREE(fd_array); /* Don't need a lock ref count on this dev/ino anymore. */ delete_windows_lock_ref_count(fsp); /* * Finally close the fd associated with this fsp. */ ret = close(fsp->fh->fd); if (ret == 0 && saved_errno != 0) { errno = saved_errno; ret = -1; } return ret; }