Changeset 740 for vendor/current/source3/locking
- Timestamp:
- Nov 14, 2012, 12:59:34 PM (13 years ago)
- Location:
- vendor/current/source3/locking
- Files:
-
- 1 added
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
vendor/current/source3/locking/brlock.c
r414 r740 26 26 27 27 #include "includes.h" 28 #include "system/filesys.h" 29 #include "locking/proto.h" 30 #include "smbd/globals.h" 31 #include "dbwrap.h" 32 #include "serverid.h" 33 #include "messages.h" 28 34 29 35 #undef DBGC_CLASS … … 42 48 static void print_lock_struct(unsigned int i, struct lock_struct *pls) 43 49 { 44 DEBUG(10,("[%u]: smb pid = %u, tid = %u, pid = %s, ",50 DEBUG(10,("[%u]: smblctx = %llu, tid = %u, pid = %s, ", 45 51 i, 46 (unsigned int)pls->context.smbpid,52 (unsigned long long)pls->context.smblctx, 47 53 (unsigned int)pls->context.tid, 48 54 procid_str(talloc_tos(), &pls->context.pid) )); … … 64 70 { 65 71 return (procid_equal(&ctx1->pid, &ctx2->pid) && 66 (ctx1->smb pid == ctx2->smbpid) &&72 (ctx1->smblctx == ctx2->smblctx) && 67 73 (ctx1->tid == ctx2->tid)); 68 74 } … … 271 277 } 272 278 273 tdb_flags = TDB_DEFAULT|TDB_VOLATILE|TDB_CLEAR_IF_FIRST ;279 tdb_flags = TDB_DEFAULT|TDB_VOLATILE|TDB_CLEAR_IF_FIRST|TDB_INCOMPATIBLE_HASH; 274 280 275 281 if (!lp_clustering()) { … … 333 339 SMB_ASSERT(plock->lock_type != UNLOCK_LOCK); 334 340 341 if ((plock->start + plock->size - 1 < plock->start) && 342 plock->size != 0) { 343 return NT_STATUS_INVALID_LOCK_RANGE; 344 } 345 335 346 for (i=0; i < br_lck->num_locks; i++) { 336 if (locks[i].start + locks[i].size < locks[i].start) {337 /* 64-bit wrap. Error. */338 return NT_STATUS_INVALID_LOCK_RANGE;339 }340 341 347 /* Do any Windows or POSIX locks conflict ? */ 342 348 if (brl_conflict(&locks[i], plock)) { 343 349 /* Remember who blocked us. */ 344 plock->context.smb pid = locks[i].context.smbpid;350 plock->context.smblctx = locks[i].context.smblctx; 345 351 return brl_lock_failed(fsp,plock,blocking_lock); 346 352 } … … 373 379 374 380 /* We don't know who blocked us. */ 375 plock->context.smb pid = 0xFFFFFFFF;381 plock->context.smblctx = 0xFFFFFFFFFFFFFFFFLL; 376 382 377 383 if (errno_ret == EACCES || errno_ret == EAGAIN) { … … 716 722 717 723 /* Don't allow 64-bit lock wrap. */ 718 if (plock->start + plock->size < plock->start || 719 plock->start + plock->size < plock->size) { 724 if (plock->start + plock->size - 1 < plock->start) { 720 725 return NT_STATUS_INVALID_PARAMETER; 721 726 } … … 748 753 SAFE_FREE(tp); 749 754 /* Remember who blocked us. */ 750 plock->context.smb pid = curr_lock->context.smbpid;755 plock->context.smblctx = curr_lock->context.smblctx; 751 756 return NT_STATUS_FILE_LOCK_CONFLICT; 752 757 } … … 763 768 SAFE_FREE(tp); 764 769 /* Remember who blocked us. */ 765 plock->context.smb pid = curr_lock->context.smbpid;770 plock->context.smblctx = curr_lock->context.smblctx; 766 771 return NT_STATUS_FILE_LOCK_CONFLICT; 767 772 } … … 823 828 824 829 /* We don't know who blocked us. */ 825 plock->context.smb pid = 0xFFFFFFFF;830 plock->context.smblctx = 0xFFFFFFFFFFFFFFFFLL; 826 831 827 832 if (errno_ret == EACCES || errno_ret == EAGAIN) { … … 903 908 NTSTATUS brl_lock(struct messaging_context *msg_ctx, 904 909 struct byte_range_lock *br_lck, 905 uint 32 smbpid,910 uint64_t smblctx, 906 911 struct server_id pid, 907 912 br_off start, … … 910 915 enum brl_flavour lock_flav, 911 916 bool blocking_lock, 912 uint 32 *psmbpid,917 uint64_t *psmblctx, 913 918 struct blocking_lock_record *blr) 914 919 { … … 927 932 #endif 928 933 929 lock.context.smb pid = smbpid;934 lock.context.smblctx = smblctx; 930 935 lock.context.pid = pid; 931 936 lock.context.tid = br_lck->fsp->conn->cnum; … … 945 950 #if ZERO_ZERO 946 951 /* sort the lock list */ 947 qsort(br_lck->lock_data, (size_t)br_lck->num_locks, sizeof(lock), lock_compare);952 TYPESAFE_QSORT(br_lck->lock_data, (size_t)br_lck->num_locks, lock_compare); 948 953 #endif 949 954 950 955 /* If we're returning an error, return who blocked us. */ 951 if (!NT_STATUS_IS_OK(ret) && psmb pid) {952 *psmb pid = lock.context.smbpid;956 if (!NT_STATUS_IS_OK(ret) && psmblctx) { 957 *psmblctx = lock.context.smblctx; 953 958 } 954 959 return ret; … … 997 1002 for (i = 0; i < br_lck->num_locks; i++) { 998 1003 struct lock_struct *lock = &locks[i]; 1004 1005 if (IS_PENDING_LOCK(lock->lock_type)) { 1006 continue; 1007 } 999 1008 1000 1009 /* Only remove our own locks that match in start, size, and flavour. */ … … 1232 1241 bool brl_unlock(struct messaging_context *msg_ctx, 1233 1242 struct byte_range_lock *br_lck, 1234 uint 32 smbpid,1243 uint64_t smblctx, 1235 1244 struct server_id pid, 1236 1245 br_off start, … … 1240 1249 struct lock_struct lock; 1241 1250 1242 lock.context.smb pid = smbpid;1251 lock.context.smblctx = smblctx; 1243 1252 lock.context.pid = pid; 1244 1253 lock.context.tid = br_lck->fsp->conn->cnum; … … 1263 1272 1264 1273 bool brl_locktest(struct byte_range_lock *br_lck, 1265 uint 32 smbpid,1274 uint64_t smblctx, 1266 1275 struct server_id pid, 1267 1276 br_off start, … … 1276 1285 files_struct *fsp = br_lck->fsp; 1277 1286 1278 lock.context.smb pid = smbpid;1287 lock.context.smblctx = smblctx; 1279 1288 lock.context.pid = pid; 1280 1289 lock.context.tid = br_lck->fsp->conn->cnum; … … 1321 1330 1322 1331 NTSTATUS brl_lockquery(struct byte_range_lock *br_lck, 1323 uint 32 *psmbpid,1332 uint64_t *psmblctx, 1324 1333 struct server_id pid, 1325 1334 br_off *pstart, … … 1333 1342 files_struct *fsp = br_lck->fsp; 1334 1343 1335 lock.context.smb pid = *psmbpid;1344 lock.context.smblctx = *psmblctx; 1336 1345 lock.context.pid = pid; 1337 1346 lock.context.tid = br_lck->fsp->conn->cnum; … … 1354 1363 1355 1364 if (conflict) { 1356 *psmb pid = exlock->context.smbpid;1365 *psmblctx = exlock->context.smblctx; 1357 1366 *pstart = exlock->start; 1358 1367 *psize = exlock->size; … … 1375 1384 1376 1385 if (ret) { 1377 /* Hmmm. No clue what to set smb pidto - use -1. */1378 *psmb pid = 0xFFFF;1386 /* Hmmm. No clue what to set smblctx to - use -1. */ 1387 *psmblctx = 0xFFFFFFFFFFFFFFFFLL; 1379 1388 return NT_STATUS_LOCK_NOT_GRANTED; 1380 1389 } … … 1398 1407 ****************************************************************************/ 1399 1408 bool brl_lock_cancel(struct byte_range_lock *br_lck, 1400 uint 32 smbpid,1409 uint64_t smblctx, 1401 1410 struct server_id pid, 1402 1411 br_off start, … … 1408 1417 struct lock_struct lock; 1409 1418 1410 lock.context.smb pid = smbpid;1419 lock.context.smblctx = smblctx; 1411 1420 lock.context.pid = pid; 1412 1421 lock.context.tid = br_lck->fsp->conn->cnum; … … 1477 1486 uint16 tid = fsp->conn->cnum; 1478 1487 int fnum = fsp->fnum; 1479 unsigned int i, j, dcount=0; 1480 int num_deleted_windows_locks = 0; 1488 unsigned int i; 1481 1489 struct lock_struct *locks = br_lck->lock_data; 1482 struct server_id pid = procid_self(); 1483 bool unlock_individually = False; 1484 bool posix_level2_contention_ended = false; 1485 1486 if(lp_posix_locking(fsp->conn->params)) { 1487 1488 /* Check if there are any Windows locks associated with this dev/ino 1489 pair that are not this fnum. If so we need to call unlock on each 1490 one in order to release the system POSIX locks correctly. */ 1491 1492 for (i=0; i < br_lck->num_locks; i++) { 1493 struct lock_struct *lock = &locks[i]; 1494 1495 if (!procid_equal(&lock->context.pid, &pid)) { 1496 continue; 1490 struct server_id pid = sconn_server_id(fsp->conn->sconn); 1491 struct lock_struct *locks_copy; 1492 unsigned int num_locks_copy; 1493 1494 /* Copy the current lock array. */ 1495 if (br_lck->num_locks) { 1496 locks_copy = (struct lock_struct *)TALLOC_MEMDUP(br_lck, locks, br_lck->num_locks * sizeof(struct lock_struct)); 1497 if (!locks_copy) { 1498 smb_panic("brl_close_fnum: talloc failed"); 1497 1499 } 1498 1499 if (lock->lock_type != READ_LOCK && lock->lock_type != WRITE_LOCK) { 1500 continue; /* Ignore pending. */ 1501 } 1502 1503 if (lock->context.tid != tid || lock->fnum != fnum) { 1504 unlock_individually = True; 1505 break; 1506 } 1507 } 1508 1509 if (unlock_individually) { 1510 struct lock_struct *locks_copy; 1511 unsigned int num_locks_copy; 1512 1513 /* Copy the current lock array. */ 1514 if (br_lck->num_locks) { 1515 locks_copy = (struct lock_struct *)TALLOC_MEMDUP(br_lck, locks, br_lck->num_locks * sizeof(struct lock_struct)); 1516 if (!locks_copy) { 1517 smb_panic("brl_close_fnum: talloc failed"); 1518 } 1519 } else { 1520 locks_copy = NULL; 1521 } 1522 1523 num_locks_copy = br_lck->num_locks; 1524 1525 for (i=0; i < num_locks_copy; i++) { 1526 struct lock_struct *lock = &locks_copy[i]; 1527 1528 if (lock->context.tid == tid && procid_equal(&lock->context.pid, &pid) && 1529 (lock->fnum == fnum)) { 1530 brl_unlock(msg_ctx, 1531 br_lck, 1532 lock->context.smbpid, 1533 pid, 1534 lock->start, 1535 lock->size, 1536 lock->lock_flav); 1537 } 1538 } 1539 return; 1540 } 1541 } 1542 1543 /* We can bulk delete - any POSIX locks will be removed when the fd closes. */ 1544 1545 /* Remove any existing locks for this fnum (or any fnum if they're POSIX). */ 1546 1547 for (i=0; i < br_lck->num_locks; i++) { 1548 struct lock_struct *lock = &locks[i]; 1549 bool del_this_lock = False; 1550 1551 if (lock->context.tid == tid && procid_equal(&lock->context.pid, &pid)) { 1552 if ((lock->lock_flav == WINDOWS_LOCK) && (lock->fnum == fnum)) { 1553 del_this_lock = True; 1554 num_deleted_windows_locks++; 1555 contend_level2_oplocks_end(br_lck->fsp, 1556 LEVEL2_CONTEND_WINDOWS_BRL); 1557 } else if (lock->lock_flav == POSIX_LOCK) { 1558 del_this_lock = True; 1559 1560 /* Only end level2 contention once for posix */ 1561 if (!posix_level2_contention_ended) { 1562 posix_level2_contention_ended = true; 1563 contend_level2_oplocks_end(br_lck->fsp, 1564 LEVEL2_CONTEND_POSIX_BRL); 1565 } 1566 } 1567 } 1568 1569 if (del_this_lock) { 1570 /* Send unlock messages to any pending waiters that overlap. */ 1571 for (j=0; j < br_lck->num_locks; j++) { 1572 struct lock_struct *pend_lock = &locks[j]; 1573 1574 /* Ignore our own or non-pending locks. */ 1575 if (!IS_PENDING_LOCK(pend_lock->lock_type)) { 1576 continue; 1577 } 1578 1579 /* Optimisation - don't send to this fnum as we're 1580 closing it. */ 1581 if (pend_lock->context.tid == tid && 1582 procid_equal(&pend_lock->context.pid, &pid) && 1583 pend_lock->fnum == fnum) { 1584 continue; 1585 } 1586 1587 /* We could send specific lock info here... */ 1588 if (brl_pending_overlap(lock, pend_lock)) { 1589 messaging_send(msg_ctx, pend_lock->context.pid, 1590 MSG_SMB_UNLOCK, &data_blob_null); 1591 } 1592 } 1593 1594 /* found it - delete it */ 1595 if (br_lck->num_locks > 1 && i < br_lck->num_locks - 1) { 1596 memmove(&locks[i], &locks[i+1], 1597 sizeof(*locks)*((br_lck->num_locks-1) - i)); 1598 } 1599 br_lck->num_locks--; 1600 br_lck->modified = True; 1601 i--; 1602 dcount++; 1603 } 1604 } 1605 1606 if(lp_posix_locking(fsp->conn->params) && num_deleted_windows_locks) { 1607 /* Reduce the Windows lock POSIX reference count on this dev/ino pair. */ 1608 reduce_windows_lock_ref_count(fsp, num_deleted_windows_locks); 1500 } else { 1501 locks_copy = NULL; 1502 } 1503 1504 num_locks_copy = br_lck->num_locks; 1505 1506 for (i=0; i < num_locks_copy; i++) { 1507 struct lock_struct *lock = &locks_copy[i]; 1508 1509 if (lock->context.tid == tid && procid_equal(&lock->context.pid, &pid) && 1510 (lock->fnum == fnum)) { 1511 brl_unlock(msg_ctx, 1512 br_lck, 1513 lock->context.smblctx, 1514 pid, 1515 lock->start, 1516 lock->size, 1517 lock->lock_flav); 1518 } 1609 1519 } 1610 1520 } … … 1621 1531 for (i = 0; i < *pnum_entries; i++) { 1622 1532 struct lock_struct *lock_data = &locks[i]; 1623 if (! process_exists(lock_data->context.pid)) {1533 if (!serverid_exists(&lock_data->context.pid)) { 1624 1534 /* This process no longer exists - mark this 1625 1535 entry as invalid by zeroing it. */ … … 1643 1553 for (i = 0; i < *pnum_entries; i++) { 1644 1554 struct lock_struct *lock_data = &locks[i]; 1645 if (lock_data->context.smb pid&&1555 if (lock_data->context.smblctx && 1646 1556 lock_data->context.tid) { 1647 1557 /* Valid (nonzero) entry - copy it. */ … … 1757 1667 ********************************************************************/ 1758 1668 1759 static int byte_range_lock_destructor(struct byte_range_lock *br_lck)1669 static void byte_range_lock_flush(struct byte_range_lock *br_lck) 1760 1670 { 1761 1671 if (br_lck->read_only) { … … 1792 1702 done: 1793 1703 1704 br_lck->read_only = true; 1705 br_lck->modified = false; 1706 1707 TALLOC_FREE(br_lck->record); 1708 } 1709 1710 static int byte_range_lock_destructor(struct byte_range_lock *br_lck) 1711 { 1712 byte_range_lock_flush(br_lck); 1794 1713 SAFE_FREE(br_lck->lock_data); 1795 TALLOC_FREE(br_lck->record);1796 1714 return 0; 1797 1715 } … … 1808 1726 TDB_DATA key, data; 1809 1727 struct byte_range_lock *br_lck = TALLOC_P(mem_ctx, struct byte_range_lock); 1728 bool do_read_only = read_only; 1810 1729 1811 1730 if (br_lck == NULL) { … … 1824 1743 /* We must be read/write to clean 1825 1744 the dead entries. */ 1826 read_only = False;1827 } 1828 1829 if ( read_only) {1745 do_read_only = false; 1746 } 1747 1748 if (do_read_only) { 1830 1749 if (brlock_db->fetch(brlock_db, br_lck, key, &data) == -1) { 1831 1750 DEBUG(3, ("Could not fetch byte range lock record\n")); … … 1834 1753 } 1835 1754 br_lck->record = NULL; 1836 } 1837 else { 1755 } else { 1838 1756 br_lck->record = brlock_db->fetch_locked(brlock_db, br_lck, key); 1839 1757 … … 1847 1765 } 1848 1766 1849 br_lck->read_only = read_only;1767 br_lck->read_only = do_read_only; 1850 1768 br_lck->lock_data = NULL; 1851 1769 … … 1899 1817 } 1900 1818 } 1819 1820 if (do_read_only != read_only) { 1821 /* 1822 * this stores the record and gets rid of 1823 * the write lock that is needed for a cleanup 1824 */ 1825 byte_range_lock_flush(br_lck); 1826 } 1827 1901 1828 return br_lck; 1902 1829 } … … 1923 1850 TALLOC_FREE(fsp->brlock_rec); 1924 1851 1925 br_lock = brl_get_locks_internal(talloc_tos(), fsp, false);1852 br_lock = brl_get_locks_internal(talloc_tos(), fsp, true); 1926 1853 if (br_lock == NULL) { 1927 1854 return NULL; … … 1929 1856 fsp->brlock_seqnum = brlock_db->get_seqnum(brlock_db); 1930 1857 1931 fsp->brlock_rec = talloc_zero(fsp, struct byte_range_lock); 1932 if (fsp->brlock_rec == NULL) { 1933 goto fail; 1934 } 1935 fsp->brlock_rec->fsp = fsp; 1936 fsp->brlock_rec->num_locks = br_lock->num_locks; 1937 fsp->brlock_rec->read_only = true; 1938 fsp->brlock_rec->key = br_lock->key; 1939 1940 fsp->brlock_rec->lock_data = (struct lock_struct *) 1941 talloc_memdup(fsp->brlock_rec, br_lock->lock_data, 1942 sizeof(struct lock_struct) * br_lock->num_locks); 1943 if (fsp->brlock_rec->lock_data == NULL) { 1944 goto fail; 1945 } 1946 1947 TALLOC_FREE(br_lock); 1858 fsp->brlock_rec = talloc_move(fsp, &br_lock); 1859 1948 1860 return fsp->brlock_rec; 1949 fail:1950 TALLOC_FREE(br_lock);1951 TALLOC_FREE(fsp->brlock_rec);1952 return NULL;1953 1861 } 1954 1862 … … 2030 1938 } 2031 1939 2032 qsort(state->pids, state->num_pids, sizeof(state->pids[0]), 2033 compare_procids); 1940 TYPESAFE_QSORT(state->pids, state->num_pids, compare_procids); 2034 1941 2035 1942 ZERO_STRUCT(last_pid); -
vendor/current/source3/locking/locking.c
r414 r740 37 37 38 38 #include "includes.h" 39 #include "system/filesys.h" 40 #include "locking/proto.h" 41 #include "smbd/globals.h" 42 #include "dbwrap.h" 43 #include "../libcli/security/security.h" 44 #include "serverid.h" 45 #include "messages.h" 46 #include "util_tdb.h" 39 47 40 48 #undef DBGC_CLASS … … 77 85 78 86 void init_strict_lock_struct(files_struct *fsp, 79 uint 32 smbpid,87 uint64_t smblctx, 80 88 br_off start, 81 89 br_off size, … … 85 93 SMB_ASSERT(lock_type == READ_LOCK || lock_type == WRITE_LOCK); 86 94 87 plock->context.smb pid = smbpid;95 plock->context.smblctx = smblctx; 88 96 plock->context.tid = fsp->conn->cnum; 89 plock->context.pid = procid_self();97 plock->context.pid = sconn_server_id(fsp->conn->sconn); 90 98 plock->start = start; 91 99 plock->size = size; … … 124 132 } 125 133 ret = brl_locktest(br_lck, 126 plock->context.smb pid,134 plock->context.smblctx, 127 135 plock->context.pid, 128 136 plock->start, … … 139 147 } 140 148 ret = brl_locktest(br_lck, 141 plock->context.smb pid,149 plock->context.smblctx, 142 150 plock->context.pid, 143 151 plock->start, … … 166 174 167 175 NTSTATUS query_lock(files_struct *fsp, 168 uint 32 *psmbpid,176 uint64_t *psmblctx, 169 177 uint64_t *pcount, 170 178 uint64_t *poffset, … … 188 196 189 197 return brl_lockquery(br_lck, 190 psmb pid,191 procid_self(),198 psmblctx, 199 sconn_server_id(fsp->conn->sconn), 192 200 poffset, 193 201 pcount, … … 230 238 struct byte_range_lock *do_lock(struct messaging_context *msg_ctx, 231 239 files_struct *fsp, 232 uint 32 lock_pid,240 uint64_t smblctx, 233 241 uint64_t count, 234 242 uint64_t offset, … … 237 245 bool blocking_lock, 238 246 NTSTATUS *perr, 239 uint 32 *plock_pid,247 uint64_t *psmblctx, 240 248 struct blocking_lock_record *blr) 241 249 { 242 250 struct byte_range_lock *br_lck = NULL; 251 252 /* silently return ok on print files as we don't do locking there */ 253 if (fsp->print_file) { 254 *perr = NT_STATUS_OK; 255 return NULL; 256 } 243 257 244 258 if (!fsp->can_lock) { … … 268 282 *perr = brl_lock(msg_ctx, 269 283 br_lck, 270 lock_pid,271 procid_self(),284 smblctx, 285 sconn_server_id(fsp->conn->sconn), 272 286 offset, 273 count, 287 count, 274 288 lock_type, 275 289 lock_flav, 276 290 blocking_lock, 277 p lock_pid,291 psmblctx, 278 292 blr); 279 293 … … 290 304 NTSTATUS do_unlock(struct messaging_context *msg_ctx, 291 305 files_struct *fsp, 292 uint 32 lock_pid,306 uint64_t smblctx, 293 307 uint64_t count, 294 308 uint64_t offset, … … 317 331 ok = brl_unlock(msg_ctx, 318 332 br_lck, 319 lock_pid,320 procid_self(),333 smblctx, 334 sconn_server_id(fsp->conn->sconn), 321 335 offset, 322 336 count, … … 339 353 340 354 NTSTATUS do_lock_cancel(files_struct *fsp, 341 uint 32 lock_pid,355 uint64 smblctx, 342 356 uint64_t count, 343 357 uint64_t offset, … … 367 381 368 382 ok = brl_lock_cancel(br_lck, 369 lock_pid,370 procid_self(),383 smblctx, 384 sconn_server_id(fsp->conn->sconn), 371 385 offset, 372 386 count, … … 390 404 391 405 void locking_close_file(struct messaging_context *msg_ctx, 392 files_struct *fsp) 406 files_struct *fsp, 407 enum file_close_type close_type) 393 408 { 394 409 struct byte_range_lock *br_lck; … … 409 424 410 425 if (br_lck) { 411 cancel_pending_lock_requests_by_fid(fsp, br_lck );426 cancel_pending_lock_requests_by_fid(fsp, br_lck, close_type); 412 427 brl_close_fnum(msg_ctx, br_lck); 413 428 TALLOC_FREE(br_lck); … … 428 443 lock_db = db_open(NULL, lock_path("locking.tdb"), 429 444 lp_open_files_db_hash_size(), 430 TDB_DEFAULT|TDB_VOLATILE|TDB_CLEAR_IF_FIRST ,445 TDB_DEFAULT|TDB_VOLATILE|TDB_CLEAR_IF_FIRST|TDB_INCOMPATIBLE_HASH, 431 446 read_only?O_RDONLY:O_RDWR|O_CREAT, 0644); 432 447 … … 481 496 return talloc_asprintf(ctx, "share_mode_entry[%d]: %s " 482 497 "pid = %s, share_access = 0x%x, private_options = 0x%x, " 483 "access_mask = 0x%x, mid = 0x% x, type= 0x%x, gen_id = %lu, "484 "uid = %u, flags = %u, file_id %s ",498 "access_mask = 0x%x, mid = 0x%llx, type= 0x%x, gen_id = %lu, " 499 "uid = %u, flags = %u, file_id %s, name_hash = 0x%x", 485 500 num, 486 501 e->op_type == UNUSED_SHARE_MODE_ENTRY ? "UNUSED" : "", 487 502 procid_str_static(&e->pid), 488 503 e->share_access, e->private_options, 489 e->access_mask, e->op_mid, e->op_type, e->share_file_id, 504 e->access_mask, (unsigned long long)e->op_mid, 505 e->op_type, e->share_file_id, 490 506 (unsigned int)e->uid, (unsigned int)e->flags, 491 file_id_string_tos(&e->id)); 507 file_id_string_tos(&e->id), 508 (unsigned int)e->name_hash); 492 509 } 493 510 … … 521 538 } 522 539 540 static int parse_delete_tokens_list(struct share_mode_lock *lck, 541 struct locking_data *pdata, 542 const TDB_DATA dbuf) 543 { 544 uint8_t *p = dbuf.dptr + sizeof(struct locking_data) + 545 (lck->num_share_modes * 546 sizeof(struct share_mode_entry)); 547 uint8_t *end_ptr = dbuf.dptr + (dbuf.dsize - 2); 548 int delete_tokens_size = 0; 549 int i; 550 551 lck->delete_tokens = NULL; 552 553 for (i = 0; i < pdata->u.s.num_delete_token_entries; i++) { 554 uint32_t token_len; 555 struct delete_token_list *pdtl; 556 557 if (end_ptr - p < (sizeof(uint32_t) + sizeof(uint32_t) + 558 sizeof(uid_t) + sizeof(gid_t))) { 559 DEBUG(0,("parse_delete_tokens_list: " 560 "corrupt token list (%u)", 561 (unsigned int)(end_ptr - p))); 562 smb_panic("corrupt token list"); 563 return -1; 564 } 565 566 memcpy(&token_len, p, sizeof(token_len)); 567 delete_tokens_size += token_len; 568 569 if (p + token_len > end_ptr || token_len < sizeof(token_len) + 570 sizeof(pdtl->name_hash) + 571 sizeof(uid_t) + 572 sizeof(gid_t)) { 573 DEBUG(0,("parse_delete_tokens_list: " 574 "invalid token length (%u)\n", 575 (unsigned int)token_len )); 576 smb_panic("invalid token length"); 577 return -1; 578 } 579 580 p += sizeof(token_len); 581 582 pdtl = TALLOC_ZERO_P(lck, struct delete_token_list); 583 if (pdtl == NULL) { 584 DEBUG(0,("parse_delete_tokens_list: talloc failed")); 585 return -1; 586 } 587 /* Copy out the name_hash. */ 588 memcpy(&pdtl->name_hash, p, sizeof(pdtl->name_hash)); 589 p += sizeof(pdtl->name_hash); 590 591 pdtl->delete_token = TALLOC_ZERO_P(pdtl, struct security_unix_token); 592 if (pdtl->delete_token == NULL) { 593 DEBUG(0,("parse_delete_tokens_list: talloc failed")); 594 return -1; 595 } 596 597 /* Copy out the uid and gid. */ 598 memcpy(&pdtl->delete_token->uid, p, sizeof(uid_t)); 599 p += sizeof(uid_t); 600 memcpy(&pdtl->delete_token->gid, p, sizeof(gid_t)); 601 p += sizeof(gid_t); 602 603 token_len -= (sizeof(token_len) + sizeof(pdtl->name_hash) + 604 sizeof(uid_t) + sizeof(gid_t)); 605 606 /* Any supplementary groups ? */ 607 if (token_len) { 608 int j; 609 610 if (token_len % sizeof(gid_t) != 0) { 611 DEBUG(0,("parse_delete_tokens_list: " 612 "corrupt group list (%u)", 613 (unsigned int)(token_len % sizeof(gid_t)) )); 614 smb_panic("corrupt group list"); 615 return -1; 616 } 617 618 pdtl->delete_token->ngroups = token_len / sizeof(gid_t); 619 pdtl->delete_token->groups = TALLOC_ARRAY(pdtl->delete_token, gid_t, 620 pdtl->delete_token->ngroups); 621 if (pdtl->delete_token->groups == NULL) { 622 DEBUG(0,("parse_delete_tokens_list: talloc failed")); 623 return -1; 624 } 625 626 for (j = 0; j < pdtl->delete_token->ngroups; j++) { 627 memcpy(&pdtl->delete_token->groups[j], p, sizeof(gid_t)); 628 p += sizeof(gid_t); 629 } 630 } 631 /* Add to the list. */ 632 DLIST_ADD(lck->delete_tokens, pdtl); 633 } 634 635 return delete_tokens_size; 636 } 637 523 638 /******************************************************************* 524 639 Get all share mode entries for a dev/inode pair. … … 528 643 { 529 644 struct locking_data data; 645 int delete_tokens_size; 530 646 int i; 531 647 … … 536 652 memcpy(&data, dbuf.dptr, sizeof(data)); 537 653 538 lck->delete_on_close = data.u.s.delete_on_close;539 654 lck->old_write_time = data.u.s.old_write_time; 540 655 lck->changed_write_time = data.u.s.changed_write_time; 541 656 lck->num_share_modes = data.u.s.num_share_mode_entries; 542 657 543 DEBUG(10, ("parse_share_modes: delete_on_close: %d, owrt: %s, " 544 "cwrt: %s, tok: %u, num_share_modes: %d\n", 545 lck->delete_on_close, 658 DEBUG(10, ("parse_share_modes: owrt: %s, " 659 "cwrt: %s, ntok: %u, num_share_modes: %d\n", 546 660 timestring(talloc_tos(), 547 661 convert_timespec_to_time_t(lck->old_write_time)), … … 549 663 convert_timespec_to_time_t( 550 664 lck->changed_write_time)), 551 (unsigned int)data.u.s. delete_token_size,665 (unsigned int)data.u.s.num_delete_token_entries, 552 666 lck->num_share_modes)); 553 667 … … 579 693 } 580 694 581 /* Get any delete token. */ 582 if (data.u.s.delete_token_size) { 583 uint8 *p = dbuf.dptr + sizeof(struct locking_data) + 584 (lck->num_share_modes * 585 sizeof(struct share_mode_entry)); 586 587 if ((data.u.s.delete_token_size < sizeof(uid_t) + sizeof(gid_t)) || 588 ((data.u.s.delete_token_size - sizeof(uid_t)) % sizeof(gid_t)) != 0) { 589 DEBUG(0, ("parse_share_modes: invalid token size %d\n", 590 data.u.s.delete_token_size)); 591 smb_panic("parse_share_modes: invalid token size"); 592 } 593 594 lck->delete_token = TALLOC_P(lck, UNIX_USER_TOKEN); 595 if (!lck->delete_token) { 596 smb_panic("parse_share_modes: talloc failed"); 597 } 598 599 /* Copy out the uid and gid. */ 600 memcpy(&lck->delete_token->uid, p, sizeof(uid_t)); 601 p += sizeof(uid_t); 602 memcpy(&lck->delete_token->gid, p, sizeof(gid_t)); 603 p += sizeof(gid_t); 604 605 /* Any supplementary groups ? */ 606 lck->delete_token->ngroups = (data.u.s.delete_token_size > (sizeof(uid_t) + sizeof(gid_t))) ? 607 ((data.u.s.delete_token_size - 608 (sizeof(uid_t) + sizeof(gid_t)))/sizeof(gid_t)) : 0; 609 610 if (lck->delete_token->ngroups) { 611 /* Make this a talloc child of lck->delete_token. */ 612 lck->delete_token->groups = TALLOC_ARRAY(lck->delete_token, gid_t, 613 lck->delete_token->ngroups); 614 if (!lck->delete_token) { 615 smb_panic("parse_share_modes: talloc failed"); 616 } 617 618 for (i = 0; i < lck->delete_token->ngroups; i++) { 619 memcpy(&lck->delete_token->groups[i], p, sizeof(gid_t)); 620 p += sizeof(gid_t); 621 } 622 } 623 624 } else { 625 lck->delete_token = NULL; 695 /* Get any delete tokens. */ 696 delete_tokens_size = parse_delete_tokens_list(lck, &data, dbuf); 697 if (delete_tokens_size < 0) { 698 smb_panic("parse_share_modes: parse_delete_tokens_list failed"); 626 699 } 627 700 … … 629 702 lck->servicepath = (const char *)dbuf.dptr + sizeof(struct locking_data) + 630 703 (lck->num_share_modes * sizeof(struct share_mode_entry)) + 631 d ata.u.s.delete_token_size;704 delete_tokens_size; 632 705 633 706 lck->base_name = (const char *)dbuf.dptr + sizeof(struct locking_data) + 634 707 (lck->num_share_modes * sizeof(struct share_mode_entry)) + 635 d ata.u.s.delete_token_size +708 delete_tokens_size + 636 709 strlen(lck->servicepath) + 1; 637 710 638 711 lck->stream_name = (const char *)dbuf.dptr + sizeof(struct locking_data) + 639 712 (lck->num_share_modes * sizeof(struct share_mode_entry)) + 640 d ata.u.s.delete_token_size +713 delete_tokens_size + 641 714 strlen(lck->servicepath) + 1 + 642 715 strlen(lck->base_name) + 1; … … 654 727 DEBUG(10,("parse_share_modes: %s\n", 655 728 str ? str : "")); 656 if (! process_exists(entry_p->pid)) {729 if (!serverid_exists(&entry_p->pid)) { 657 730 DEBUG(10,("parse_share_modes: deleted %s\n", 658 731 str ? str : "")); … … 674 747 ssize_t offset; 675 748 ssize_t sp_len, bn_len, sn_len; 676 uint32 delete_token_size; 749 uint32_t delete_tokens_size = 0; 750 struct delete_token_list *pdtl = NULL; 751 uint32_t num_delete_token_entries = 0; 677 752 678 753 result.dptr = NULL; … … 693 768 sn_len = lck->stream_name != NULL ? strlen(lck->stream_name) : 0; 694 769 695 delete_token_size = (lck->delete_token ? 696 (sizeof(uid_t) + sizeof(gid_t) + (lck->delete_token->ngroups*sizeof(gid_t))) : 0); 770 for (pdtl = lck->delete_tokens; pdtl; pdtl = pdtl->next) { 771 num_delete_token_entries++; 772 delete_tokens_size += (sizeof(uint32_t) + 773 sizeof(uint32_t) + 774 sizeof(uid_t) + 775 sizeof(gid_t) + 776 pdtl->delete_token->ngroups*sizeof(gid_t)); 777 } 697 778 698 779 result.dsize = sizeof(*data) + 699 780 lck->num_share_modes * sizeof(struct share_mode_entry) + 700 delete_token _size +781 delete_tokens_size + 701 782 sp_len + 1 + 702 783 bn_len + 1 + … … 711 792 ZERO_STRUCTP(data); 712 793 data->u.s.num_share_mode_entries = lck->num_share_modes; 713 data->u.s.delete_on_close = lck->delete_on_close;714 794 data->u.s.old_write_time = lck->old_write_time; 715 795 data->u.s.changed_write_time = lck->changed_write_time; 716 data->u.s. delete_token_size = delete_token_size;717 718 DEBUG(10,("unparse_share_modes: del: %d, owrt: %s cwrt: %s,tok: %u, "719 "num: %d\n", data->u.s.delete_on_close,796 data->u.s.num_delete_token_entries = num_delete_token_entries; 797 798 DEBUG(10,("unparse_share_modes: owrt: %s cwrt: %s, ntok: %u, " 799 "num: %d\n", 720 800 timestring(talloc_tos(), 721 801 convert_timespec_to_time_t(lck->old_write_time)), … … 723 803 convert_timespec_to_time_t( 724 804 lck->changed_write_time)), 725 (unsigned int)data->u.s. delete_token_size,805 (unsigned int)data->u.s.num_delete_token_entries, 726 806 data->u.s.num_share_mode_entries)); 727 807 … … 731 811 sizeof(struct share_mode_entry)*lck->num_share_modes; 732 812 733 /* Store any delete on close token. */ 734 if (lck->delete_token) { 735 uint8 *p = result.dptr + offset; 736 737 memcpy(p, &lck->delete_token->uid, sizeof(uid_t)); 813 /* Store any delete on close tokens. */ 814 for (pdtl = lck->delete_tokens; pdtl; pdtl = pdtl->next) { 815 struct security_unix_token *pdt = pdtl->delete_token; 816 uint32_t token_size = sizeof(uint32_t) + 817 sizeof(uint32_t) + 818 sizeof(uid_t) + 819 sizeof(gid_t) + 820 (pdt->ngroups * sizeof(gid_t)); 821 uint8_t *p = result.dptr + offset; 822 823 memcpy(p, &token_size, sizeof(uint32_t)); 824 p += sizeof(uint32_t); 825 826 memcpy(p, &pdtl->name_hash, sizeof(uint32_t)); 827 p += sizeof(uint32_t); 828 829 memcpy(p, &pdt->uid, sizeof(uid_t)); 738 830 p += sizeof(uid_t); 739 831 740 memcpy(p, & lck->delete_token->gid, sizeof(gid_t));832 memcpy(p, &pdt->gid, sizeof(gid_t)); 741 833 p += sizeof(gid_t); 742 834 743 for (i = 0; i < lck->delete_token->ngroups; i++) {744 memcpy(p, & lck->delete_token->groups[i], sizeof(gid_t));835 for (i = 0; i < pdt->ngroups; i++) { 836 memcpy(p, &pdt->groups[i], sizeof(gid_t)); 745 837 p += sizeof(gid_t); 746 838 } 747 offset = p - result.dptr;839 offset += token_size; 748 840 } 749 841 … … 832 924 lck->num_share_modes = 0; 833 925 lck->share_modes = NULL; 834 lck->delete_token = NULL; 835 lck->delete_on_close = False; 926 lck->delete_tokens = NULL; 836 927 ZERO_STRUCT(lck->old_write_time); 837 928 ZERO_STRUCT(lck->changed_write_time); … … 942 1033 struct share_mode_lock *lck, 943 1034 const char *servicepath, 1035 uint32_t orig_name_hash, 1036 uint32_t new_name_hash, 944 1037 const struct smb_filename *smb_fname_dst) 945 1038 { … … 1007 1100 continue; 1008 1101 } 1102 1103 /* If this is a hardlink to the inode 1104 with a different name, skip this. */ 1105 if (se->name_hash != orig_name_hash) { 1106 continue; 1107 } 1108 1109 se->name_hash = new_name_hash; 1110 1009 1111 /* But not to ourselves... */ 1010 1112 if (procid_is_me(&se->pid)) { … … 1028 1130 1029 1131 void get_file_infos(struct file_id id, 1132 uint32_t name_hash, 1030 1133 bool *delete_on_close, 1031 1134 struct timespec *write_time) … … 1046 1149 1047 1150 if (delete_on_close) { 1048 *delete_on_close = lck->delete_on_close;1151 *delete_on_close = is_delete_on_close_set(lck, name_hash); 1049 1152 } 1050 1153 … … 1099 1202 static void fill_share_mode_entry(struct share_mode_entry *e, 1100 1203 files_struct *fsp, 1101 uid_t uid, uint 16mid, uint16 op_type)1204 uid_t uid, uint64_t mid, uint16 op_type) 1102 1205 { 1103 1206 ZERO_STRUCTP(e); 1104 e->pid = procid_self();1207 e->pid = sconn_server_id(fsp->conn->sconn); 1105 1208 e->share_access = fsp->share_access; 1106 1209 e->private_options = fsp->fh->private_options; … … 1114 1217 e->uid = (uint32)uid; 1115 1218 e->flags = fsp->posix_open ? SHARE_MODE_FLAG_POSIX_OPEN : 0; 1219 e->name_hash = fsp->name_hash; 1116 1220 } 1117 1221 1118 1222 static void fill_deferred_open_entry(struct share_mode_entry *e, 1119 1223 const struct timeval request_time, 1120 struct file_id id, uint16 mid) 1224 struct file_id id, 1225 struct server_id pid, 1226 uint64_t mid) 1121 1227 { 1122 1228 ZERO_STRUCTP(e); 1123 e->pid = p rocid_self();1229 e->pid = pid; 1124 1230 e->op_mid = mid; 1125 1231 e->op_type = DEFERRED_OPEN_ENTRY; … … 1153 1259 1154 1260 void set_share_mode(struct share_mode_lock *lck, files_struct *fsp, 1155 uid_t uid, uint 16mid, uint16 op_type)1261 uid_t uid, uint64_t mid, uint16 op_type) 1156 1262 { 1157 1263 struct share_mode_entry entry; … … 1160 1266 } 1161 1267 1162 void add_deferred_open(struct share_mode_lock *lck, uint 16mid,1268 void add_deferred_open(struct share_mode_lock *lck, uint64_t mid, 1163 1269 struct timeval request_time, 1164 struct file_id id)1270 struct server_id pid, struct file_id id) 1165 1271 { 1166 1272 struct share_mode_entry entry; 1167 fill_deferred_open_entry(&entry, request_time, id, mid);1273 fill_deferred_open_entry(&entry, request_time, id, pid, mid); 1168 1274 add_share_mode_entry(lck, &entry); 1169 1275 } … … 1239 1345 } 1240 1346 1241 void del_deferred_open_entry(struct share_mode_lock *lck, uint16 mid) 1347 void del_deferred_open_entry(struct share_mode_lock *lck, uint64_t mid, 1348 struct server_id pid) 1242 1349 { 1243 1350 struct share_mode_entry entry, *e; 1244 1351 1245 1352 fill_deferred_open_entry(&entry, timeval_zero(), 1246 lck->id, mid);1353 lck->id, pid, mid); 1247 1354 1248 1355 e = find_share_mode_entry(lck, &entry); … … 1271 1378 } 1272 1379 1273 e->op_mid = 0; 1274 if (EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) { 1380 if (EXCLUSIVE_OPLOCK_TYPE(e->op_type)) { 1275 1381 /* 1276 1382 * Going from exclusive or batch, … … 1278 1384 * first. 1279 1385 */ 1386 if (!EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) { 1387 smb_panic("remove_share_oplock: logic error"); 1388 } 1280 1389 e->op_type = FAKE_LEVEL_II_OPLOCK; 1281 1390 } else { … … 1317 1426 */ 1318 1427 1319 if ((dosmode & aRONLY) &&1428 if ((dosmode & FILE_ATTRIBUTE_READONLY) && 1320 1429 !lp_delete_readonly(SNUM(fsp->conn))) { 1321 1430 DEBUG(10,("can_set_delete_on_close: file %s delete on close " … … 1359 1468 1360 1469 /************************************************************************* 1361 Return a talloced copy of a UNIX_USER_TOKEN. NULL on fail.1470 Return a talloced copy of a struct security_unix_token. NULL on fail. 1362 1471 (Should this be in locking.c.... ?). 1363 1472 *************************************************************************/ 1364 1473 1365 static UNIX_USER_TOKEN *copy_unix_token(TALLOC_CTX *ctx, const UNIX_USER_TOKEN *tok) 1366 { 1367 UNIX_USER_TOKEN *cpy; 1368 1369 if (tok == NULL) { 1370 return NULL; 1371 } 1372 1373 cpy = TALLOC_P(ctx, UNIX_USER_TOKEN); 1474 static struct security_unix_token *copy_unix_token(TALLOC_CTX *ctx, const struct security_unix_token *tok) 1475 { 1476 struct security_unix_token *cpy; 1477 1478 cpy = TALLOC_P(ctx, struct security_unix_token); 1374 1479 if (!cpy) { 1375 1480 return NULL; … … 1391 1496 1392 1497 /**************************************************************************** 1393 Replace thedelete on close token.1498 Adds a delete on close token. 1394 1499 ****************************************************************************/ 1395 1500 1396 void set_delete_on_close_token(struct share_mode_lock *lck, const UNIX_USER_TOKEN *tok) 1397 { 1398 TALLOC_FREE(lck->delete_token); /* Also deletes groups... */ 1399 1400 /* Copy the new token (can be NULL). */ 1401 lck->delete_token = copy_unix_token(lck, tok); 1402 lck->modified = True; 1501 static bool add_delete_on_close_token(struct share_mode_lock *lck, 1502 uint32_t name_hash, 1503 const struct security_unix_token *tok) 1504 { 1505 struct delete_token_list *dtl; 1506 1507 dtl = TALLOC_ZERO_P(lck, struct delete_token_list); 1508 if (dtl == NULL) { 1509 return false; 1510 } 1511 1512 dtl->name_hash = name_hash; 1513 dtl->delete_token = copy_unix_token(lck, tok); 1514 if (dtl->delete_token == NULL) { 1515 TALLOC_FREE(dtl); 1516 return false; 1517 } 1518 DLIST_ADD(lck->delete_tokens, dtl); 1519 lck->modified = true; 1520 return true; 1403 1521 } 1404 1522 … … 1410 1528 in the close code, the last closer will delete the file 1411 1529 if flag is set. 1412 This makes a copy of any UNIX_USER_TOKENinto the1530 This makes a copy of any struct security_unix_token into the 1413 1531 lck entry. This function is used when the lock is already granted. 1414 1532 ****************************************************************************/ 1415 1533 1416 void set_delete_on_close_lck(struct share_mode_lock *lck, bool delete_on_close, const UNIX_USER_TOKEN *tok) 1417 { 1418 if (lck->delete_on_close != delete_on_close) { 1419 set_delete_on_close_token(lck, tok); 1420 lck->delete_on_close = delete_on_close; 1421 if (delete_on_close) { 1422 SMB_ASSERT(lck->delete_token != NULL); 1423 } 1424 lck->modified = True; 1425 } 1426 } 1427 1428 bool set_delete_on_close(files_struct *fsp, bool delete_on_close, const UNIX_USER_TOKEN *tok) 1429 { 1430 UNIX_USER_TOKEN *tok_copy = NULL; 1534 void set_delete_on_close_lck(files_struct *fsp, 1535 struct share_mode_lock *lck, 1536 bool delete_on_close, 1537 const struct security_unix_token *tok) 1538 { 1539 struct delete_token_list *dtl; 1540 bool ret; 1541 1542 if (delete_on_close) { 1543 SMB_ASSERT(tok != NULL); 1544 } else { 1545 SMB_ASSERT(tok == NULL); 1546 } 1547 1548 for (dtl = lck->delete_tokens; dtl; dtl = dtl->next) { 1549 if (dtl->name_hash == fsp->name_hash) { 1550 lck->modified = true; 1551 if (delete_on_close == false) { 1552 /* Delete this entry. */ 1553 DLIST_REMOVE(lck->delete_tokens, dtl); 1554 TALLOC_FREE(dtl); 1555 return; 1556 } 1557 /* Replace this token with the 1558 given tok. */ 1559 TALLOC_FREE(dtl->delete_token); 1560 dtl->delete_token = copy_unix_token(dtl, tok); 1561 SMB_ASSERT(dtl->delete_token != NULL); 1562 } 1563 } 1564 1565 if (!delete_on_close) { 1566 /* Nothing to delete - not found. */ 1567 return; 1568 } 1569 1570 ret = add_delete_on_close_token(lck, fsp->name_hash, tok); 1571 SMB_ASSERT(ret); 1572 } 1573 1574 bool set_delete_on_close(files_struct *fsp, bool delete_on_close, const struct security_unix_token *tok) 1575 { 1431 1576 struct share_mode_lock *lck; 1432 1577 … … 1442 1587 } 1443 1588 1444 if (fsp->conn->admin_user) { 1445 tok_copy = copy_unix_token(lck, tok); 1446 if (tok_copy == NULL) { 1447 TALLOC_FREE(lck); 1448 return false; 1449 } 1450 tok_copy->uid = (uid_t)0; 1451 tok = tok_copy; 1452 } 1453 1454 set_delete_on_close_lck(lck, delete_on_close, tok); 1589 set_delete_on_close_lck(fsp, lck, delete_on_close, 1590 delete_on_close ? tok : NULL); 1455 1591 1456 1592 if (fsp->is_directory) { 1457 1593 SMB_ASSERT(!is_ntfs_stream_smb_fname(fsp->fsp_name)); 1458 send_stat_cache_delete_message(fsp->fsp_name->base_name); 1594 send_stat_cache_delete_message(fsp->conn->sconn->msg_ctx, 1595 fsp->fsp_name->base_name); 1459 1596 } 1460 1597 … … 1464 1601 1465 1602 return True; 1603 } 1604 1605 const struct security_unix_token *get_delete_on_close_token(struct share_mode_lock *lck, uint32_t name_hash) 1606 { 1607 struct delete_token_list *dtl; 1608 1609 DEBUG(10,("get_delete_on_close_token: name_hash = 0x%x\n", 1610 (unsigned int)name_hash )); 1611 1612 for (dtl = lck->delete_tokens; dtl; dtl = dtl->next) { 1613 DEBUG(10,("get_delete_on_close_token: dtl->name_hash = 0x%x\n", 1614 (unsigned int)dtl->name_hash )); 1615 if (dtl->name_hash == name_hash) { 1616 return dtl->delete_token; 1617 } 1618 } 1619 return NULL; 1620 } 1621 1622 bool is_delete_on_close_set(struct share_mode_lock *lck, uint32_t name_hash) 1623 { 1624 return (get_delete_on_close_token(lck, name_hash) != NULL); 1466 1625 } 1467 1626 … … 1528 1687 const char *sharepath; 1529 1688 const char *fname; 1689 const char *del_tokens; 1690 uint32_t total_del_token_size = 0; 1530 1691 int i; 1531 1692 … … 1536 1697 data = (struct locking_data *)rec->value.dptr; 1537 1698 shares = (struct share_mode_entry *)(rec->value.dptr + sizeof(*data)); 1699 del_tokens = (const char *)rec->value.dptr + sizeof(*data) + 1700 data->u.s.num_share_mode_entries*sizeof(*shares); 1701 1702 for (i = 0; i < data->u.s.num_delete_token_entries; i++) { 1703 uint32_t del_token_size; 1704 memcpy(&del_token_size, del_tokens, sizeof(uint32_t)); 1705 total_del_token_size += del_token_size; 1706 del_tokens += del_token_size; 1707 } 1708 1538 1709 sharepath = (const char *)rec->value.dptr + sizeof(*data) + 1539 1710 data->u.s.num_share_mode_entries*sizeof(*shares) + 1540 data->u.s.delete_token_size;1711 total_del_token_size; 1541 1712 fname = (const char *)rec->value.dptr + sizeof(*data) + 1542 1713 data->u.s.num_share_mode_entries*sizeof(*shares) + 1543 data->u.s.delete_token_size +1714 total_del_token_size + 1544 1715 strlen(sharepath) + 1; 1545 1716 -
vendor/current/source3/locking/posix.c
r414 r740 23 23 24 24 #include "includes.h" 25 #include "system/filesys.h" 26 #include "locking/proto.h" 27 #include "dbwrap.h" 28 #include "util_tdb.h" 25 29 26 30 #undef DBGC_CLASS … … 909 913 /* 910 914 * Add into the dlink list after the l_curr point - NOT at lhead. 911 * Note we can't use DLINK_ADD here as this inserts at the head of the given list.912 915 */ 913 914 l_new->prev = l_curr; 915 l_new->next = l_curr->next; 916 l_curr->next = l_new; 916 DLIST_ADD_AFTER(lhead, l_new, l_curr); 917 917 918 918 /* And move after the link we added. */
Note:
See TracChangeset
for help on using the changeset viewer.