Ignore:
Timestamp:
Nov 14, 2012, 12:59:34 PM (13 years ago)
Author:
Silvan Scherrer
Message:

Samba Server: update vendor to 3.6.0

File:
1 edited

Legend:

Unmodified
Added
Removed
  • vendor/current/source3/locking/brlock.c

    r414 r740  
    2626
    2727#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"
    2834
    2935#undef DBGC_CLASS
     
    4248static void print_lock_struct(unsigned int i, struct lock_struct *pls)
    4349{
    44         DEBUG(10,("[%u]: smbpid = %u, tid = %u, pid = %s, ",
     50        DEBUG(10,("[%u]: smblctx = %llu, tid = %u, pid = %s, ",
    4551                        i,
    46                         (unsigned int)pls->context.smbpid,
     52                        (unsigned long long)pls->context.smblctx,
    4753                        (unsigned int)pls->context.tid,
    4854                        procid_str(talloc_tos(), &pls->context.pid) ));
     
    6470{
    6571        return (procid_equal(&ctx1->pid, &ctx2->pid) &&
    66                 (ctx1->smbpid == ctx2->smbpid) &&
     72                (ctx1->smblctx == ctx2->smblctx) &&
    6773                (ctx1->tid == ctx2->tid));
    6874}
     
    271277        }
    272278
    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;
    274280
    275281        if (!lp_clustering()) {
     
    333339        SMB_ASSERT(plock->lock_type != UNLOCK_LOCK);
    334340
     341        if ((plock->start + plock->size - 1 < plock->start) &&
     342                        plock->size != 0) {
     343                return NT_STATUS_INVALID_LOCK_RANGE;
     344        }
     345
    335346        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 
    341347                /* Do any Windows or POSIX locks conflict ? */
    342348                if (brl_conflict(&locks[i], plock)) {
    343349                        /* Remember who blocked us. */
    344                         plock->context.smbpid = locks[i].context.smbpid;
     350                        plock->context.smblctx = locks[i].context.smblctx;
    345351                        return brl_lock_failed(fsp,plock,blocking_lock);
    346352                }
     
    373379
    374380                        /* We don't know who blocked us. */
    375                         plock->context.smbpid = 0xFFFFFFFF;
     381                        plock->context.smblctx = 0xFFFFFFFFFFFFFFFFLL;
    376382
    377383                        if (errno_ret == EACCES || errno_ret == EAGAIN) {
     
    716722
    717723        /* 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) {
    720725                return NT_STATUS_INVALID_PARAMETER;
    721726        }
     
    748753                                SAFE_FREE(tp);
    749754                                /* Remember who blocked us. */
    750                                 plock->context.smbpid = curr_lock->context.smbpid;
     755                                plock->context.smblctx = curr_lock->context.smblctx;
    751756                                return NT_STATUS_FILE_LOCK_CONFLICT;
    752757                        }
     
    763768                                SAFE_FREE(tp);
    764769                                /* Remember who blocked us. */
    765                                 plock->context.smbpid = curr_lock->context.smbpid;
     770                                plock->context.smblctx = curr_lock->context.smblctx;
    766771                                return NT_STATUS_FILE_LOCK_CONFLICT;
    767772                        }
     
    823828
    824829                        /* We don't know who blocked us. */
    825                         plock->context.smbpid = 0xFFFFFFFF;
     830                        plock->context.smblctx = 0xFFFFFFFFFFFFFFFFLL;
    826831
    827832                        if (errno_ret == EACCES || errno_ret == EAGAIN) {
     
    903908NTSTATUS brl_lock(struct messaging_context *msg_ctx,
    904909                struct byte_range_lock *br_lck,
    905                 uint32 smbpid,
     910                uint64_t smblctx,
    906911                struct server_id pid,
    907912                br_off start,
     
    910915                enum brl_flavour lock_flav,
    911916                bool blocking_lock,
    912                 uint32 *psmbpid,
     917                uint64_t *psmblctx,
    913918                struct blocking_lock_record *blr)
    914919{
     
    927932#endif
    928933
    929         lock.context.smbpid = smbpid;
     934        lock.context.smblctx = smblctx;
    930935        lock.context.pid = pid;
    931936        lock.context.tid = br_lck->fsp->conn->cnum;
     
    945950#if ZERO_ZERO
    946951        /* 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);
    948953#endif
    949954
    950955        /* If we're returning an error, return who blocked us. */
    951         if (!NT_STATUS_IS_OK(ret) && psmbpid) {
    952                 *psmbpid = lock.context.smbpid;
     956        if (!NT_STATUS_IS_OK(ret) && psmblctx) {
     957                *psmblctx = lock.context.smblctx;
    953958        }
    954959        return ret;
     
    9971002        for (i = 0; i < br_lck->num_locks; i++) {
    9981003                struct lock_struct *lock = &locks[i];
     1004
     1005                if (IS_PENDING_LOCK(lock->lock_type)) {
     1006                        continue;
     1007                }
    9991008
    10001009                /* Only remove our own locks that match in start, size, and flavour. */
     
    12321241bool brl_unlock(struct messaging_context *msg_ctx,
    12331242                struct byte_range_lock *br_lck,
    1234                 uint32 smbpid,
     1243                uint64_t smblctx,
    12351244                struct server_id pid,
    12361245                br_off start,
     
    12401249        struct lock_struct lock;
    12411250
    1242         lock.context.smbpid = smbpid;
     1251        lock.context.smblctx = smblctx;
    12431252        lock.context.pid = pid;
    12441253        lock.context.tid = br_lck->fsp->conn->cnum;
     
    12631272
    12641273bool brl_locktest(struct byte_range_lock *br_lck,
    1265                 uint32 smbpid,
     1274                uint64_t smblctx,
    12661275                struct server_id pid,
    12671276                br_off start,
     
    12761285        files_struct *fsp = br_lck->fsp;
    12771286
    1278         lock.context.smbpid = smbpid;
     1287        lock.context.smblctx = smblctx;
    12791288        lock.context.pid = pid;
    12801289        lock.context.tid = br_lck->fsp->conn->cnum;
     
    13211330
    13221331NTSTATUS brl_lockquery(struct byte_range_lock *br_lck,
    1323                 uint32 *psmbpid,
     1332                uint64_t *psmblctx,
    13241333                struct server_id pid,
    13251334                br_off *pstart,
     
    13331342        files_struct *fsp = br_lck->fsp;
    13341343
    1335         lock.context.smbpid = *psmbpid;
     1344        lock.context.smblctx = *psmblctx;
    13361345        lock.context.pid = pid;
    13371346        lock.context.tid = br_lck->fsp->conn->cnum;
     
    13541363
    13551364                if (conflict) {
    1356                         *psmbpid = exlock->context.smbpid;
     1365                        *psmblctx = exlock->context.smblctx;
    13571366                        *pstart = exlock->start;
    13581367                        *psize = exlock->size;
     
    13751384
    13761385                if (ret) {
    1377                         /* Hmmm. No clue what to set smbpid to - use -1. */
    1378                         *psmbpid = 0xFFFF;
     1386                        /* Hmmm. No clue what to set smblctx to - use -1. */
     1387                        *psmblctx = 0xFFFFFFFFFFFFFFFFLL;
    13791388                        return NT_STATUS_LOCK_NOT_GRANTED;
    13801389                }
     
    13981407****************************************************************************/
    13991408bool brl_lock_cancel(struct byte_range_lock *br_lck,
    1400                 uint32 smbpid,
     1409                uint64_t smblctx,
    14011410                struct server_id pid,
    14021411                br_off start,
     
    14081417        struct lock_struct lock;
    14091418
    1410         lock.context.smbpid = smbpid;
     1419        lock.context.smblctx = smblctx;
    14111420        lock.context.pid = pid;
    14121421        lock.context.tid = br_lck->fsp->conn->cnum;
     
    14771486        uint16 tid = fsp->conn->cnum;
    14781487        int fnum = fsp->fnum;
    1479         unsigned int i, j, dcount=0;
    1480         int num_deleted_windows_locks = 0;
     1488        unsigned int i;
    14811489        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");
    14971499                        }
    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                }
    16091519        }
    16101520}
     
    16211531        for (i = 0; i < *pnum_entries; i++) {
    16221532                struct lock_struct *lock_data = &locks[i];
    1623                 if (!process_exists(lock_data->context.pid)) {
     1533                if (!serverid_exists(&lock_data->context.pid)) {
    16241534                        /* This process no longer exists - mark this
    16251535                           entry as invalid by zeroing it. */
     
    16431553                        for (i = 0; i < *pnum_entries; i++) {
    16441554                                struct lock_struct *lock_data = &locks[i];
    1645                                 if (lock_data->context.smbpid &&
     1555                                if (lock_data->context.smblctx &&
    16461556                                                lock_data->context.tid) {
    16471557                                        /* Valid (nonzero) entry - copy it. */
     
    17571667********************************************************************/
    17581668
    1759 static int byte_range_lock_destructor(struct byte_range_lock *br_lck)
     1669static void byte_range_lock_flush(struct byte_range_lock *br_lck)
    17601670{
    17611671        if (br_lck->read_only) {
     
    17921702 done:
    17931703
     1704        br_lck->read_only = true;
     1705        br_lck->modified = false;
     1706
     1707        TALLOC_FREE(br_lck->record);
     1708}
     1709
     1710static int byte_range_lock_destructor(struct byte_range_lock *br_lck)
     1711{
     1712        byte_range_lock_flush(br_lck);
    17941713        SAFE_FREE(br_lck->lock_data);
    1795         TALLOC_FREE(br_lck->record);
    17961714        return 0;
    17971715}
     
    18081726        TDB_DATA key, data;
    18091727        struct byte_range_lock *br_lck = TALLOC_P(mem_ctx, struct byte_range_lock);
     1728        bool do_read_only = read_only;
    18101729
    18111730        if (br_lck == NULL) {
     
    18241743                /* We must be read/write to clean
    18251744                   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) {
    18301749                if (brlock_db->fetch(brlock_db, br_lck, key, &data) == -1) {
    18311750                        DEBUG(3, ("Could not fetch byte range lock record\n"));
     
    18341753                }
    18351754                br_lck->record = NULL;
    1836         }
    1837         else {
     1755        } else {
    18381756                br_lck->record = brlock_db->fetch_locked(brlock_db, br_lck, key);
    18391757
     
    18471765        }
    18481766
    1849         br_lck->read_only = read_only;
     1767        br_lck->read_only = do_read_only;
    18501768        br_lck->lock_data = NULL;
    18511769
     
    18991817                }
    19001818        }
     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
    19011828        return br_lck;
    19021829}
     
    19231850        TALLOC_FREE(fsp->brlock_rec);
    19241851
    1925         br_lock = brl_get_locks_internal(talloc_tos(), fsp, false);
     1852        br_lock = brl_get_locks_internal(talloc_tos(), fsp, true);
    19261853        if (br_lock == NULL) {
    19271854                return NULL;
     
    19291856        fsp->brlock_seqnum = brlock_db->get_seqnum(brlock_db);
    19301857
    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
    19481860        return fsp->brlock_rec;
    1949 fail:
    1950         TALLOC_FREE(br_lock);
    1951         TALLOC_FREE(fsp->brlock_rec);
    1952         return NULL;
    19531861}
    19541862
     
    20301938        }
    20311939
    2032         qsort(state->pids, state->num_pids, sizeof(state->pids[0]),
    2033               compare_procids);
     1940        TYPESAFE_QSORT(state->pids, state->num_pids, compare_procids);
    20341941
    20351942        ZERO_STRUCT(last_pid);
Note: See TracChangeset for help on using the changeset viewer.