locking/locking.c

説明を見る。
00001 /* 
00002    Unix SMB/CIFS implementation.
00003    Locking functions
00004    Copyright (C) Andrew Tridgell 1992-2000
00005    Copyright (C) Jeremy Allison 1992-2006
00006    Copyright (C) Volker Lendecke 2005
00007    
00008    This program is free software; you can redistribute it and/or modify
00009    it under the terms of the GNU General Public License as published by
00010    the Free Software Foundation; either version 2 of the License, or
00011    (at your option) any later version.
00012    
00013    This program is distributed in the hope that it will be useful,
00014    but WITHOUT ANY WARRANTY; without even the implied warranty of
00015    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016    GNU General Public License for more details.
00017    
00018    You should have received a copy of the GNU General Public License
00019    along with this program; if not, write to the Free Software
00020    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00021 
00022    Revision History:
00023 
00024    12 aug 96: Erik.Devriendt@te6.siemens.be
00025    added support for shared memory implementation of share mode locking
00026 
00027    May 1997. Jeremy Allison (jallison@whistle.com). Modified share mode
00028    locking to deal with multiple share modes per open file.
00029 
00030    September 1997. Jeremy Allison (jallison@whistle.com). Added oplock
00031    support.
00032 
00033    rewrtten completely to use new tdb code. Tridge, Dec '99
00034 
00035    Added POSIX locking support. Jeremy Allison (jeremy@valinux.com), Apr. 2000.
00036    Added Unix Extensions POSIX locking support. Jeremy Allison Mar 2006.
00037 */
00038 
00039 #include "includes.h"
00040 
00041 #undef DBGC_CLASS
00042 #define DBGC_CLASS DBGC_LOCKING
00043 
00044 #define NO_LOCKING_COUNT (-1)
00045 
00046 /* the locking database handle */
00047 static TDB_CONTEXT *tdb;
00048 
00049 /****************************************************************************
00050  Debugging aids :-).
00051 ****************************************************************************/
00052 
00053 const char *lock_type_name(enum brl_type lock_type)
00054 {
00055         switch (lock_type) {
00056                 case READ_LOCK:
00057                         return "READ";
00058                 case WRITE_LOCK:
00059                         return "WRITE";
00060                 case PENDING_READ_LOCK:
00061                         return "PENDING_READ";
00062                 case PENDING_WRITE_LOCK:
00063                         return "PENDING_WRITE";
00064                 default:
00065                         return "other";
00066         }
00067 }
00068 
00069 const char *lock_flav_name(enum brl_flavour lock_flav)
00070 {
00071         return (lock_flav == WINDOWS_LOCK) ? "WINDOWS_LOCK" : "POSIX_LOCK";
00072 }
00073 
00074 /****************************************************************************
00075  Utility function called to see if a file region is locked.
00076  Called in the read/write codepath.
00077 ****************************************************************************/
00078 
00079 BOOL is_locked(files_struct *fsp,
00080                 uint32 smbpid,
00081                 SMB_BIG_UINT count,
00082                 SMB_BIG_UINT offset, 
00083                 enum brl_type lock_type)
00084 {
00085         int strict_locking = lp_strict_locking(fsp->conn->params);
00086         enum brl_flavour lock_flav = lp_posix_cifsu_locktype(fsp);
00087         BOOL ret = True;
00088         
00089         if (count == 0) {
00090                 return False;
00091         }
00092 
00093         if (!lp_locking(fsp->conn->params) || !strict_locking) {
00094                 return False;
00095         }
00096 
00097         if (strict_locking == Auto) {
00098                 if  (EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type) && (lock_type == READ_LOCK || lock_type == WRITE_LOCK)) {
00099                         DEBUG(10,("is_locked: optimisation - exclusive oplock on file %s\n", fsp->fsp_name ));
00100                         ret = False;
00101                 } else if ((fsp->oplock_type == LEVEL_II_OPLOCK) &&
00102                            (lock_type == READ_LOCK)) {
00103                         DEBUG(10,("is_locked: optimisation - level II oplock on file %s\n", fsp->fsp_name ));
00104                         ret = False;
00105                 } else {
00106                         struct byte_range_lock *br_lck = brl_get_locks_readonly(NULL, fsp);
00107                         if (!br_lck) {
00108                                 return False;
00109                         }
00110                         ret = !brl_locktest(br_lck,
00111                                         smbpid,
00112                                         procid_self(),
00113                                         offset,
00114                                         count,
00115                                         lock_type,
00116                                         lock_flav);
00117                         TALLOC_FREE(br_lck);
00118                 }
00119         } else {
00120                 struct byte_range_lock *br_lck = brl_get_locks_readonly(NULL, fsp);
00121                 if (!br_lck) {
00122                         return False;
00123                 }
00124                 ret = !brl_locktest(br_lck,
00125                                 smbpid,
00126                                 procid_self(),
00127                                 offset,
00128                                 count,
00129                                 lock_type,
00130                                 lock_flav);
00131                 TALLOC_FREE(br_lck);
00132         }
00133 
00134         DEBUG(10,("is_locked: flavour = %s brl start=%.0f len=%.0f %s for fnum %d file %s\n",
00135                         lock_flav_name(lock_flav),
00136                         (double)offset, (double)count, ret ? "locked" : "unlocked",
00137                         fsp->fnum, fsp->fsp_name ));
00138 
00139         return ret;
00140 }
00141 
00142 /****************************************************************************
00143  Find out if a lock could be granted - return who is blocking us if we can't.
00144 ****************************************************************************/
00145 
00146 NTSTATUS query_lock(files_struct *fsp,
00147                         uint32 *psmbpid,
00148                         SMB_BIG_UINT *pcount,
00149                         SMB_BIG_UINT *poffset,
00150                         enum brl_type *plock_type,
00151                         enum brl_flavour lock_flav)
00152 {
00153         struct byte_range_lock *br_lck = NULL;
00154         NTSTATUS status = NT_STATUS_LOCK_NOT_GRANTED;
00155 
00156         if (!fsp->can_lock) {
00157                 return fsp->is_directory ? NT_STATUS_INVALID_DEVICE_REQUEST : NT_STATUS_INVALID_HANDLE;
00158         }
00159 
00160         if (!lp_locking(fsp->conn->params)) {
00161                 return NT_STATUS_OK;
00162         }
00163 
00164         br_lck = brl_get_locks_readonly(NULL, fsp);
00165         if (!br_lck) {
00166                 return NT_STATUS_NO_MEMORY;
00167         }
00168 
00169         status = brl_lockquery(br_lck,
00170                         psmbpid,
00171                         procid_self(),
00172                         poffset,
00173                         pcount,
00174                         plock_type,
00175                         lock_flav);
00176 
00177         TALLOC_FREE(br_lck);
00178         return status;
00179 }
00180 
00181 /****************************************************************************
00182  Utility function called by locking requests.
00183 ****************************************************************************/
00184 
00185 struct byte_range_lock *do_lock(files_struct *fsp,
00186                         uint32 lock_pid,
00187                         SMB_BIG_UINT count,
00188                         SMB_BIG_UINT offset,
00189                         enum brl_type lock_type,
00190                         enum brl_flavour lock_flav,
00191                         BOOL blocking_lock,
00192                         NTSTATUS *perr,
00193                         uint32 *plock_pid)
00194 {
00195         struct byte_range_lock *br_lck = NULL;
00196 
00197         if (!fsp->can_lock) {
00198                 *perr = fsp->is_directory ? NT_STATUS_INVALID_DEVICE_REQUEST : NT_STATUS_INVALID_HANDLE;
00199                 return NULL;
00200         }
00201 
00202         if (!lp_locking(fsp->conn->params)) {
00203                 *perr = NT_STATUS_OK;
00204                 return NULL;
00205         }
00206 
00207         /* NOTE! 0 byte long ranges ARE allowed and should be stored  */
00208 
00209         DEBUG(10,("do_lock: lock flavour %s lock type %s start=%.0f len=%.0f requested for fnum %d file %s\n",
00210                 lock_flav_name(lock_flav), lock_type_name(lock_type),
00211                 (double)offset, (double)count, fsp->fnum, fsp->fsp_name ));
00212 
00213         br_lck = brl_get_locks(NULL, fsp);
00214         if (!br_lck) {
00215                 *perr = NT_STATUS_NO_MEMORY;
00216                 return NULL;
00217         }
00218 
00219         *perr = brl_lock(br_lck,
00220                         lock_pid,
00221                         procid_self(),
00222                         offset,
00223                         count, 
00224                         lock_type,
00225                         lock_flav,
00226                         blocking_lock,
00227                         plock_pid);
00228 
00229         if (lock_flav == WINDOWS_LOCK &&
00230                         fsp->current_lock_count != NO_LOCKING_COUNT) {
00231                 /* blocking ie. pending, locks also count here,
00232                  * as this is an efficiency counter to avoid checking
00233                  * the lock db. on close. JRA. */
00234 
00235                 fsp->current_lock_count++;
00236         } else {
00237                 /* Notice that this has had a POSIX lock request.
00238                  * We can't count locks after this so forget them.
00239                  */
00240                 fsp->current_lock_count = NO_LOCKING_COUNT;
00241         }
00242 
00243         return br_lck;
00244 }
00245 
00246 /****************************************************************************
00247  Utility function called by unlocking requests.
00248 ****************************************************************************/
00249 
00250 NTSTATUS do_unlock(files_struct *fsp,
00251                         uint32 lock_pid,
00252                         SMB_BIG_UINT count,
00253                         SMB_BIG_UINT offset,
00254                         enum brl_flavour lock_flav)
00255 {
00256         BOOL ok = False;
00257         struct byte_range_lock *br_lck = NULL;
00258         
00259         if (!fsp->can_lock) {
00260                 return fsp->is_directory ? NT_STATUS_INVALID_DEVICE_REQUEST : NT_STATUS_INVALID_HANDLE;
00261         }
00262         
00263         if (!lp_locking(fsp->conn->params)) {
00264                 return NT_STATUS_OK;
00265         }
00266         
00267         DEBUG(10,("do_unlock: unlock start=%.0f len=%.0f requested for fnum %d file %s\n",
00268                   (double)offset, (double)count, fsp->fnum, fsp->fsp_name ));
00269 
00270         br_lck = brl_get_locks(NULL, fsp);
00271         if (!br_lck) {
00272                 return NT_STATUS_NO_MEMORY;
00273         }
00274 
00275         ok = brl_unlock(br_lck,
00276                         lock_pid,
00277                         procid_self(),
00278                         offset,
00279                         count,
00280                         lock_flav);
00281    
00282         TALLOC_FREE(br_lck);
00283 
00284         if (!ok) {
00285                 DEBUG(10,("do_unlock: returning ERRlock.\n" ));
00286                 return NT_STATUS_RANGE_NOT_LOCKED;
00287         }
00288 
00289         if (lock_flav == WINDOWS_LOCK &&
00290                         fsp->current_lock_count != NO_LOCKING_COUNT) {
00291                 SMB_ASSERT(fsp->current_lock_count > 0);
00292                 fsp->current_lock_count--;
00293         }
00294 
00295         return NT_STATUS_OK;
00296 }
00297 
00298 /****************************************************************************
00299  Cancel any pending blocked locks.
00300 ****************************************************************************/
00301 
00302 NTSTATUS do_lock_cancel(files_struct *fsp,
00303                         uint32 lock_pid,
00304                         SMB_BIG_UINT count,
00305                         SMB_BIG_UINT offset,
00306                         enum brl_flavour lock_flav)
00307 {
00308         BOOL ok = False;
00309         struct byte_range_lock *br_lck = NULL;
00310         
00311         if (!fsp->can_lock) {
00312                 return fsp->is_directory ?
00313                         NT_STATUS_INVALID_DEVICE_REQUEST : NT_STATUS_INVALID_HANDLE;
00314         }
00315         
00316         if (!lp_locking(fsp->conn->params)) {
00317                 return NT_STATUS_DOS(ERRDOS, ERRcancelviolation);
00318         }
00319 
00320         DEBUG(10,("do_lock_cancel: cancel start=%.0f len=%.0f requested for fnum %d file %s\n",
00321                   (double)offset, (double)count, fsp->fnum, fsp->fsp_name ));
00322 
00323         br_lck = brl_get_locks(NULL, fsp);
00324         if (!br_lck) {
00325                 return NT_STATUS_NO_MEMORY;
00326         }
00327 
00328         ok = brl_lock_cancel(br_lck,
00329                         lock_pid,
00330                         procid_self(),
00331                         offset,
00332                         count,
00333                         lock_flav);
00334    
00335         TALLOC_FREE(br_lck);
00336 
00337         if (!ok) {
00338                 DEBUG(10,("do_lock_cancel: returning ERRcancelviolation.\n" ));
00339                 return NT_STATUS_DOS(ERRDOS, ERRcancelviolation);
00340         }
00341 
00342         if (lock_flav == WINDOWS_LOCK &&
00343                         fsp->current_lock_count != NO_LOCKING_COUNT) {
00344                 SMB_ASSERT(fsp->current_lock_count > 0);
00345                 fsp->current_lock_count--;
00346         }
00347 
00348         return NT_STATUS_OK;
00349 }
00350 
00351 /****************************************************************************
00352  Remove any locks on this fd. Called from file_close().
00353 ****************************************************************************/
00354 
00355 void locking_close_file(files_struct *fsp)
00356 {
00357         struct byte_range_lock *br_lck;
00358 
00359         if (!lp_locking(fsp->conn->params)) {
00360                 return;
00361         }
00362 
00363         /* If we have not outstanding locks or pending
00364          * locks then we don't need to look in the lock db.
00365          */
00366 
00367         if (fsp->current_lock_count == 0) {
00368                 return;
00369         }
00370 
00371         br_lck = brl_get_locks(NULL,fsp);
00372 
00373         if (br_lck) {
00374                 cancel_pending_lock_requests_by_fid(fsp, br_lck);
00375                 brl_close_fnum(br_lck);
00376                 TALLOC_FREE(br_lck);
00377         }
00378 }
00379 
00380 /****************************************************************************
00381  Initialise the locking functions.
00382 ****************************************************************************/
00383 
00384 static int open_read_only;
00385 
00386 BOOL locking_init(int read_only)
00387 {
00388         brl_init(read_only);
00389 
00390         if (tdb)
00391                 return True;
00392 
00393         tdb = tdb_open_log(lock_path("locking.tdb"), 
00394                         lp_open_files_db_hash_size(),
00395                         TDB_DEFAULT|(read_only?0x0:TDB_CLEAR_IF_FIRST), 
00396                         read_only?O_RDONLY:O_RDWR|O_CREAT,
00397                         0644);
00398 
00399         if (!tdb) {
00400                 DEBUG(0,("ERROR: Failed to initialise locking database\n"));
00401                 return False;
00402         }
00403 
00404         /* Activate the per-hashchain freelist */
00405         tdb_set_max_dead(tdb, 5);
00406 
00407         if (!posix_locking_init(read_only))
00408                 return False;
00409 
00410         open_read_only = read_only;
00411 
00412         return True;
00413 }
00414 
00415 /*******************************************************************
00416  Deinitialize the share_mode management.
00417 ******************************************************************/
00418 
00419 BOOL locking_end(void)
00420 {
00421         BOOL ret = True;
00422 
00423         brl_shutdown(open_read_only);
00424         if (tdb) {
00425                 if (tdb_close(tdb) != 0)
00426                         ret = False;
00427         }
00428 
00429         return ret;
00430 }
00431 
00432 /*******************************************************************
00433  Form a static locking key for a dev/inode pair.
00434 ******************************************************************/
00435 
00436 /* key and data records in the tdb locking database */
00437 struct locking_key {
00438         SMB_DEV_T dev;
00439         SMB_INO_T ino;
00440 };
00441 
00442 /*******************************************************************
00443  Form a static locking key for a dev/inode pair.
00444 ******************************************************************/
00445 
00446 static TDB_DATA locking_key(SMB_DEV_T dev, SMB_INO_T inode)
00447 {
00448         static struct locking_key key;
00449         TDB_DATA kbuf;
00450 
00451         memset(&key, '\0', sizeof(key));
00452         key.dev = dev;
00453         key.ino = inode;
00454         kbuf.dptr = (char *)&key;
00455         kbuf.dsize = sizeof(key);
00456         return kbuf;
00457 }
00458 
00459 /*******************************************************************
00460  Print out a share mode.
00461 ********************************************************************/
00462 
00463 char *share_mode_str(int num, struct share_mode_entry *e)
00464 {
00465         static pstring share_str;
00466 
00467         slprintf(share_str, sizeof(share_str)-1, "share_mode_entry[%d]: %s "
00468                  "pid = %s, share_access = 0x%x, private_options = 0x%x, "
00469                  "access_mask = 0x%x, mid = 0x%x, type= 0x%x, file_id = %lu, "
00470                  "uid = %u, flags = %u, dev = 0x%x, inode = %.0f",
00471                  num,
00472                  e->op_type == UNUSED_SHARE_MODE_ENTRY ? "UNUSED" : "",
00473                  procid_str_static(&e->pid),
00474                  e->share_access, e->private_options,
00475                  e->access_mask, e->op_mid, e->op_type, e->share_file_id,
00476                  (unsigned int)e->uid, (unsigned int)e->flags,
00477                  (unsigned int)e->dev, (double)e->inode );
00478 
00479         return share_str;
00480 }
00481 
00482 /*******************************************************************
00483  Print out a share mode table.
00484 ********************************************************************/
00485 
00486 static void print_share_mode_table(struct locking_data *data)
00487 {
00488         int num_share_modes = data->u.s.num_share_mode_entries;
00489         struct share_mode_entry *shares =
00490                 (struct share_mode_entry *)(data + 1);
00491         int i;
00492 
00493         for (i = 0; i < num_share_modes; i++) {
00494                 struct share_mode_entry entry;
00495 
00496                 memcpy(&entry, &shares[i], sizeof(struct share_mode_entry));
00497                 DEBUG(10,("print_share_mode_table: %s\n",
00498                           share_mode_str(i, &entry)));
00499         }
00500 }
00501 
00502 /*******************************************************************
00503  Get all share mode entries for a dev/inode pair.
00504 ********************************************************************/
00505 
00506 static BOOL parse_share_modes(TDB_DATA dbuf, struct share_mode_lock *lck)
00507 {
00508         struct locking_data *data;
00509         int i;
00510 
00511         if (dbuf.dsize < sizeof(struct locking_data)) {
00512                 smb_panic("PANIC: parse_share_modes: buffer too short.\n");
00513         }
00514 
00515         data = (struct locking_data *)dbuf.dptr;
00516 
00517         lck->delete_on_close = data->u.s.delete_on_close;
00518         lck->num_share_modes = data->u.s.num_share_mode_entries;
00519 
00520         DEBUG(10, ("parse_share_modes: delete_on_close: %d, "
00521                    "num_share_modes: %d\n",
00522                 lck->delete_on_close,
00523                 lck->num_share_modes));
00524 
00525         if ((lck->num_share_modes < 0) || (lck->num_share_modes > 1000000)) {
00526                 DEBUG(0, ("invalid number of share modes: %d\n",
00527                           lck->num_share_modes));
00528                 smb_panic("PANIC: invalid number of share modes");
00529         }
00530 
00531         lck->share_modes = NULL;
00532         
00533         if (lck->num_share_modes != 0) {
00534 
00535                 if (dbuf.dsize < (sizeof(struct locking_data) +
00536                                   (lck->num_share_modes *
00537                                    sizeof(struct share_mode_entry)))) {
00538                         smb_panic("PANIC: parse_share_modes: buffer too short.\n");
00539                 }
00540                                   
00541                 lck->share_modes = (struct share_mode_entry *)
00542                         TALLOC_MEMDUP(lck, dbuf.dptr+sizeof(*data),
00543                                       lck->num_share_modes *
00544                                       sizeof(struct share_mode_entry));
00545 
00546                 if (lck->share_modes == NULL) {
00547                         smb_panic("talloc failed\n");
00548                 }
00549         }
00550 
00551         /* Get any delete token. */
00552         if (data->u.s.delete_token_size) {
00553                 char *p = dbuf.dptr + sizeof(*data) +
00554                                 (lck->num_share_modes *
00555                                 sizeof(struct share_mode_entry));
00556 
00557                 if ((data->u.s.delete_token_size < sizeof(uid_t) + sizeof(gid_t)) ||
00558                                 ((data->u.s.delete_token_size - sizeof(uid_t)) % sizeof(gid_t)) != 0) {
00559                         DEBUG(0, ("parse_share_modes: invalid token size %d\n",
00560                                 data->u.s.delete_token_size));
00561                         smb_panic("parse_share_modes: invalid token size\n");
00562                 }
00563 
00564                 lck->delete_token = TALLOC_P(lck, UNIX_USER_TOKEN);
00565                 if (!lck->delete_token) {
00566                         smb_panic("talloc failed\n");
00567                 }
00568 
00569                 /* Copy out the uid and gid. */
00570                 memcpy(&lck->delete_token->uid, p, sizeof(uid_t));
00571                 p += sizeof(uid_t);
00572                 memcpy(&lck->delete_token->gid, p, sizeof(gid_t));
00573                 p += sizeof(gid_t);
00574 
00575                 /* Any supplementary groups ? */
00576                 lck->delete_token->ngroups = (data->u.s.delete_token_size > (sizeof(uid_t) + sizeof(gid_t))) ?
00577                                         ((data->u.s.delete_token_size -
00578                                                 (sizeof(uid_t) + sizeof(gid_t)))/sizeof(gid_t)) : 0;
00579 
00580                 if (lck->delete_token->ngroups) {
00581                         /* Make this a talloc child of lck->delete_token. */
00582                         lck->delete_token->groups = TALLOC_ARRAY(lck->delete_token, gid_t,
00583                                                         lck->delete_token->ngroups);
00584                         if (!lck->delete_token) {
00585                                 smb_panic("talloc failed\n");
00586                         }
00587 
00588                         for (i = 0; i < lck->delete_token->ngroups; i++) {
00589                                 memcpy(&lck->delete_token->groups[i], p, sizeof(gid_t));
00590                                 p += sizeof(gid_t);
00591                         }
00592                 }
00593 
00594         } else {
00595                 lck->delete_token = NULL;
00596         }
00597 
00598         /* Save off the associated service path and filename. */
00599         lck->servicepath = talloc_strdup(lck, dbuf.dptr + sizeof(*data) +
00600                                         (lck->num_share_modes *
00601                                         sizeof(struct share_mode_entry)) +
00602                                         data->u.s.delete_token_size );
00603         if (lck->servicepath == NULL) {
00604                 smb_panic("talloc_strdup failed\n");
00605         }
00606 
00607         lck->filename = talloc_strdup(lck, dbuf.dptr + sizeof(*data) +
00608                                         (lck->num_share_modes *
00609                                         sizeof(struct share_mode_entry)) +
00610                                         data->u.s.delete_token_size +
00611                                         strlen(lck->servicepath) + 1 );
00612         if (lck->filename == NULL) {
00613                 smb_panic("talloc_strdup failed\n");
00614         }
00615 
00616         /*
00617          * Ensure that each entry has a real process attached.
00618          */
00619 
00620         for (i = 0; i < lck->num_share_modes; i++) {
00621                 struct share_mode_entry *entry_p = &lck->share_modes[i];
00622                 DEBUG(10,("parse_share_modes: %s\n",
00623                           share_mode_str(i, entry_p) ));
00624                 if (!process_exists(entry_p->pid)) {
00625                         DEBUG(10,("parse_share_modes: deleted %s\n",
00626                                   share_mode_str(i, entry_p) ));
00627                         entry_p->op_type = UNUSED_SHARE_MODE_ENTRY;
00628                         lck->modified = True;
00629                 }
00630         }
00631 
00632         return True;
00633 }
00634 
00635 static TDB_DATA unparse_share_modes(struct share_mode_lock *lck)
00636 {
00637         TDB_DATA result;
00638         int num_valid = 0;
00639         int i;
00640         struct locking_data *data;
00641         ssize_t offset;
00642         ssize_t sp_len;
00643         uint32 delete_token_size;
00644 
00645         result.dptr = NULL;
00646         result.dsize = 0;
00647 
00648         for (i=0; i<lck->num_share_modes; i++) {
00649                 if (!is_unused_share_mode_entry(&lck->share_modes[i])) {
00650                         num_valid += 1;
00651                 }
00652         }
00653 
00654         if (num_valid == 0) {
00655                 return result;
00656         }
00657 
00658         sp_len = strlen(lck->servicepath);
00659         delete_token_size = (lck->delete_token ?
00660                         (sizeof(uid_t) + sizeof(gid_t) + (lck->delete_token->ngroups*sizeof(gid_t))) : 0);
00661 
00662         result.dsize = sizeof(*data) +
00663                 lck->num_share_modes * sizeof(struct share_mode_entry) +
00664                 delete_token_size +
00665                 sp_len + 1 +
00666                 strlen(lck->filename) + 1;
00667         result.dptr = TALLOC_ARRAY(lck, char, result.dsize);
00668 
00669         if (result.dptr == NULL) {
00670                 smb_panic("talloc failed\n");
00671         }
00672 
00673         data = (struct locking_data *)result.dptr;
00674         ZERO_STRUCTP(data);
00675         data->u.s.num_share_mode_entries = lck->num_share_modes;
00676         data->u.s.delete_on_close = lck->delete_on_close;
00677         data->u.s.delete_token_size = delete_token_size;
00678         DEBUG(10, ("unparse_share_modes: del: %d, tok = %u, num: %d\n",
00679                 data->u.s.delete_on_close,
00680                 (unsigned int)data->u.s.delete_token_size,
00681                 data->u.s.num_share_mode_entries));
00682         memcpy(result.dptr + sizeof(*data), lck->share_modes,
00683                sizeof(struct share_mode_entry)*lck->num_share_modes);
00684         offset = sizeof(*data) +
00685                 sizeof(struct share_mode_entry)*lck->num_share_modes;
00686 
00687         /* Store any delete on close token. */
00688         if (lck->delete_token) {
00689                 char *p = result.dptr + offset;
00690 
00691                 memcpy(p, &lck->delete_token->uid, sizeof(uid_t));
00692                 p += sizeof(uid_t);
00693 
00694                 memcpy(p, &lck->delete_token->gid, sizeof(gid_t));
00695                 p += sizeof(gid_t);
00696 
00697                 for (i = 0; i < lck->delete_token->ngroups; i++) {
00698                         memcpy(p, &lck->delete_token->groups[i], sizeof(gid_t));
00699                         p += sizeof(gid_t);
00700                 }
00701                 offset = p - result.dptr;
00702         }
00703 
00704         safe_strcpy(result.dptr + offset, lck->servicepath,
00705                     result.dsize - offset - 1);
00706         offset += sp_len + 1;
00707         safe_strcpy(result.dptr + offset, lck->filename,
00708                     result.dsize - offset - 1);
00709 
00710         if (DEBUGLEVEL >= 10) {
00711                 print_share_mode_table(data);
00712         }
00713 
00714         return result;
00715 }
00716 
00717 static int share_mode_lock_destructor(struct share_mode_lock *lck)
00718 {
00719         TDB_DATA key = locking_key(lck->dev, lck->ino);
00720         TDB_DATA data;
00721 
00722         if (!lck->modified) {
00723                 goto done;
00724         }
00725 
00726         data = unparse_share_modes(lck);
00727 
00728         if (data.dptr == NULL) {
00729                 if (!lck->fresh) {
00730                         /* There has been an entry before, delete it */
00731                         if (tdb_delete(tdb, key) == -1) {
00732                                 smb_panic("Could not delete share entry\n");
00733                         }
00734                 }
00735                 goto done;
00736         }
00737 
00738         if (tdb_store(tdb, key, data, TDB_REPLACE) == -1) {
00739                 smb_panic("Could not store share mode entry\n");
00740         }
00741 
00742  done:
00743         tdb_chainunlock(tdb, key);
00744 
00745         return 0;
00746 }
00747 
00748 struct share_mode_lock *get_share_mode_lock(TALLOC_CTX *mem_ctx,
00749                                                 SMB_DEV_T dev, SMB_INO_T ino,
00750                                                 const char *servicepath,
00751                                                 const char *fname)
00752 {
00753         struct share_mode_lock *lck;
00754         TDB_DATA key = locking_key(dev, ino);
00755         TDB_DATA data;
00756 
00757         lck = TALLOC_P(mem_ctx, struct share_mode_lock);
00758         if (lck == NULL) {
00759                 DEBUG(0, ("talloc failed\n"));
00760                 return NULL;
00761         }
00762 
00763         /* Ensure we set every field here as the destructor must be
00764            valid even if parse_share_modes fails. */
00765 
00766         lck->servicepath = NULL;
00767         lck->filename = NULL;
00768         lck->dev = dev;
00769         lck->ino = ino;
00770         lck->num_share_modes = 0;
00771         lck->share_modes = NULL;
00772         lck->delete_token = NULL;
00773         lck->delete_on_close = False;
00774         lck->fresh = False;
00775         lck->modified = False;
00776 
00777         if (tdb_chainlock(tdb, key) != 0) {
00778                 DEBUG(3, ("Could not lock share entry\n"));
00779                 TALLOC_FREE(lck);
00780                 return NULL;
00781         }
00782 
00783         /* We must set the destructor immediately after the chainlock
00784            ensure the lock is cleaned up on any of the error return
00785            paths below. */
00786 
00787         talloc_set_destructor(lck, share_mode_lock_destructor);
00788 
00789         data = tdb_fetch(tdb, key);
00790         lck->fresh = (data.dptr == NULL);
00791 
00792         if (lck->fresh) {
00793 
00794                 if (fname == NULL || servicepath == NULL) {
00795                         TALLOC_FREE(lck);
00796                         return NULL;
00797                 }
00798                 lck->filename = talloc_strdup(lck, fname);
00799                 lck->servicepath = talloc_strdup(lck, servicepath);
00800                 if (lck->filename == NULL || lck->servicepath == NULL) {
00801                         DEBUG(0, ("talloc failed\n"));
00802                         TALLOC_FREE(lck);
00803                         return NULL;
00804                 }
00805         } else {
00806                 if (!parse_share_modes(data, lck)) {
00807                         DEBUG(0, ("Could not parse share modes\n"));
00808                         TALLOC_FREE(lck);
00809                         SAFE_FREE(data.dptr);
00810                         return NULL;
00811                 }
00812         }
00813 
00814         SAFE_FREE(data.dptr);
00815 
00816         return lck;
00817 }
00818 
00819 /*******************************************************************
00820  Sets the service name and filename for rename.
00821  At this point we emit "file renamed" messages to all
00822  process id's that have this file open.
00823  Based on an initial code idea from SATOH Fumiyasu <fumiya@samba.gr.jp>
00824 ********************************************************************/
00825 
00826 BOOL rename_share_filename(struct share_mode_lock *lck,
00827                         const char *servicepath,
00828                         const char *newname)
00829 {
00830         size_t sp_len;
00831         size_t fn_len;
00832         size_t msg_len;
00833         char *frm = NULL;
00834         int i;
00835 
00836         if (!lck) {
00837                 return False;
00838         }
00839 
00840         DEBUG(10, ("rename_share_filename: servicepath %s newname %s\n",
00841                 servicepath, newname));
00842 
00843         /*
00844          * rename_internal_fsp() and rename_internals() add './' to
00845          * head of newname if newname does not contain a '/'.
00846          */
00847         while (newname[0] && newname[1] && newname[0] == '.' && newname[1] == '/') {
00848                 newname += 2;
00849         }
00850 
00851         lck->servicepath = talloc_strdup(lck, servicepath);
00852         lck->filename = talloc_strdup(lck, newname);
00853         if (lck->filename == NULL || lck->servicepath == NULL) {
00854                 DEBUG(0, ("rename_share_filename: talloc failed\n"));
00855                 return False;
00856         }
00857         lck->modified = True;
00858 
00859         sp_len = strlen(lck->servicepath);
00860         fn_len = strlen(lck->filename);
00861 
00862         msg_len = MSG_FILE_RENAMED_MIN_SIZE + sp_len + 1 + fn_len + 1;
00863 
00864         /* Set up the name changed message. */
00865         frm = TALLOC_ARRAY(lck, char, msg_len);
00866         if (!frm) {
00867                 return False;
00868         }
00869 
00870         SDEV_T_VAL(frm,0,lck->dev);
00871         SINO_T_VAL(frm,8,lck->ino);
00872 
00873         DEBUG(10,("rename_share_filename: msg_len = %u\n", (unsigned int)msg_len ));
00874 
00875         safe_strcpy(&frm[16], lck->servicepath, sp_len);
00876         safe_strcpy(&frm[16 + sp_len + 1], lck->filename, fn_len);
00877 
00878         /* Send the messages. */
00879         for (i=0; i<lck->num_share_modes; i++) {
00880                 struct share_mode_entry *se = &lck->share_modes[i];
00881                 if (!is_valid_share_mode_entry(se)) {
00882                         continue;
00883                 }
00884                 /* But not to ourselves... */
00885                 if (procid_is_me(&se->pid)) {
00886                         continue;
00887                 }
00888 
00889                 DEBUG(10,("rename_share_filename: sending rename message to pid %s "
00890                         "dev %x, inode  %.0f sharepath %s newname %s\n",
00891                         procid_str_static(&se->pid),
00892                         (unsigned int)lck->dev, (double)lck->ino,
00893                         lck->servicepath, lck->filename ));
00894 
00895                 message_send_pid(se->pid, MSG_SMB_FILE_RENAME,
00896                                 frm, msg_len, True);
00897         }
00898 
00899         return True;
00900 }
00901 
00902 static int pull_delete_on_close_flag(TDB_DATA key, TDB_DATA dbuf,
00903                                      void *private_data)
00904 {
00905         BOOL *result = (BOOL *)private_data;
00906         struct locking_data *data;
00907 
00908         if (dbuf.dsize < sizeof(struct locking_data)) {
00909                 smb_panic("PANIC: parse_share_modes: buffer too short.\n");
00910         }
00911 
00912         data = (struct locking_data *)dbuf.dptr;
00913 
00914         *result = data->u.s.delete_on_close;
00915         return 0;
00916 }
00917 
00918 BOOL get_delete_on_close_flag(SMB_DEV_T dev, SMB_INO_T inode)
00919 {
00920         TDB_DATA key = locking_key(dev, inode);
00921         BOOL result = False;
00922 
00923         tdb_parse_record(tdb, key, pull_delete_on_close_flag,
00924                          (void *)&result);
00925         return result;
00926 }
00927 
00928 BOOL is_valid_share_mode_entry(const struct share_mode_entry *e)
00929 {
00930         int num_props = 0;
00931 
00932         if (e->op_type == UNUSED_SHARE_MODE_ENTRY) {
00933                 /* cope with dead entries from the process not
00934                    existing. These should not be considered valid,
00935                    otherwise we end up doing zero timeout sharing
00936                    violation */
00937                 return False;
00938         }
00939 
00940         num_props += ((e->op_type == NO_OPLOCK) ? 1 : 0);
00941         num_props += (EXCLUSIVE_OPLOCK_TYPE(e->op_type) ? 1 : 0);
00942         num_props += (LEVEL_II_OPLOCK_TYPE(e->op_type) ? 1 : 0);
00943 
00944         SMB_ASSERT(num_props <= 1);
00945         return (num_props != 0);
00946 }
00947 
00948 BOOL is_deferred_open_entry(const struct share_mode_entry *e)
00949 {
00950         return (e->op_type == DEFERRED_OPEN_ENTRY);
00951 }
00952 
00953 BOOL is_unused_share_mode_entry(const struct share_mode_entry *e)
00954 {
00955         return (e->op_type == UNUSED_SHARE_MODE_ENTRY);
00956 }
00957 
00958 /*******************************************************************
00959  Fill a share mode entry.
00960 ********************************************************************/
00961 
00962 static void fill_share_mode_entry(struct share_mode_entry *e,
00963                                   files_struct *fsp,
00964                                   uid_t uid, uint16 mid, uint16 op_type)
00965 {
00966         ZERO_STRUCTP(e);
00967         e->pid = procid_self();
00968         e->share_access = fsp->share_access;
00969         e->private_options = fsp->fh->private_options;
00970         e->access_mask = fsp->access_mask;
00971         e->op_mid = mid;
00972         e->op_type = op_type;
00973         e->time.tv_sec = fsp->open_time.tv_sec;
00974         e->time.tv_usec = fsp->open_time.tv_usec;
00975         e->dev = fsp->dev;
00976         e->inode = fsp->inode;
00977         e->share_file_id = fsp->fh->file_id;
00978         e->uid = (uint32)uid;
00979         e->flags = fsp->posix_open ? SHARE_MODE_FLAG_POSIX_OPEN : 0;
00980 }
00981 
00982 static void fill_deferred_open_entry(struct share_mode_entry *e,
00983                                      const struct timeval request_time,
00984                                      SMB_DEV_T dev, SMB_INO_T ino, uint16 mid)
00985 {
00986         ZERO_STRUCTP(e);
00987         e->pid = procid_self();
00988         e->op_mid = mid;
00989         e->op_type = DEFERRED_OPEN_ENTRY;
00990         e->time.tv_sec = request_time.tv_sec;
00991         e->time.tv_usec = request_time.tv_usec;
00992         e->dev = dev;
00993         e->inode = ino;
00994         e->uid = (uint32)-1;
00995         e->flags = 0;
00996 }
00997 
00998 static void add_share_mode_entry(struct share_mode_lock *lck,
00999                                  const struct share_mode_entry *entry)
01000 {
01001         int i;
01002 
01003         for (i=0; i<lck->num_share_modes; i++) {
01004                 struct share_mode_entry *e = &lck->share_modes[i];
01005                 if (is_unused_share_mode_entry(e)) {
01006                         *e = *entry;
01007                         break;
01008                 }
01009         }
01010 
01011         if (i == lck->num_share_modes) {
01012                 /* No unused entry found */
01013                 ADD_TO_ARRAY(lck, struct share_mode_entry, *entry,
01014                              &lck->share_modes, &lck->num_share_modes);
01015         }
01016         lck->modified = True;
01017 }
01018 
01019 void set_share_mode(struct share_mode_lock *lck, files_struct *fsp,
01020                         uid_t uid, uint16 mid, uint16 op_type, BOOL initial_delete_on_close_allowed)
01021 {
01022         struct share_mode_entry entry;
01023         fill_share_mode_entry(&entry, fsp, uid, mid, op_type);
01024         if (initial_delete_on_close_allowed) {
01025                 entry.flags |= SHARE_MODE_ALLOW_INITIAL_DELETE_ON_CLOSE;
01026         }
01027         add_share_mode_entry(lck, &entry);
01028 }
01029 
01030 void add_deferred_open(struct share_mode_lock *lck, uint16 mid,
01031                        struct timeval request_time,
01032                        SMB_DEV_T dev, SMB_INO_T ino)
01033 {
01034         struct share_mode_entry entry;
01035         fill_deferred_open_entry(&entry, request_time, dev, ino, mid);
01036         add_share_mode_entry(lck, &entry);
01037 }
01038 
01039 /*******************************************************************
01040  Check if two share mode entries are identical, ignoring oplock 
01041  and mid info and desired_access. (Removed paranoia test - it's
01042  not automatically a logic error if they are identical. JRA.)
01043 ********************************************************************/
01044 
01045 static BOOL share_modes_identical(struct share_mode_entry *e1,
01046                                   struct share_mode_entry *e2)
01047 {
01048         /* We used to check for e1->share_access == e2->share_access here
01049            as well as the other fields but 2 different DOS or FCB opens
01050            sharing the same share mode entry may validly differ in
01051            fsp->share_access field. */
01052 
01053         return (procid_equal(&e1->pid, &e2->pid) &&
01054                 e1->dev == e2->dev &&
01055                 e1->inode == e2->inode &&
01056                 e1->share_file_id == e2->share_file_id );
01057 }
01058 
01059 static BOOL deferred_open_identical(struct share_mode_entry *e1,
01060                                     struct share_mode_entry *e2)
01061 {
01062         return (procid_equal(&e1->pid, &e2->pid) &&
01063                 (e1->op_mid == e2->op_mid) &&
01064                 (e1->dev == e2->dev) &&
01065                 (e1->inode == e2->inode));
01066 }
01067 
01068 static struct share_mode_entry *find_share_mode_entry(struct share_mode_lock *lck,
01069                                                       struct share_mode_entry *entry)
01070 {
01071         int i;
01072 
01073         for (i=0; i<lck->num_share_modes; i++) {
01074                 struct share_mode_entry *e = &lck->share_modes[i];
01075                 if (is_valid_share_mode_entry(entry) &&
01076                     is_valid_share_mode_entry(e) &&
01077                     share_modes_identical(e, entry)) {
01078                         return e;
01079                 }
01080                 if (is_deferred_open_entry(entry) &&
01081                     is_deferred_open_entry(e) &&
01082                     deferred_open_identical(e, entry)) {
01083                         return e;
01084                 }
01085         }
01086         return NULL;
01087 }
01088 
01089 /*******************************************************************
01090  Del the share mode of a file for this process. Return the number of
01091  entries left.
01092 ********************************************************************/
01093 
01094 BOOL del_share_mode(struct share_mode_lock *lck, files_struct *fsp)
01095 {
01096         struct share_mode_entry entry, *e;
01097 
01098         /* Don't care about the pid owner being correct here - just a search. */
01099         fill_share_mode_entry(&entry, fsp, (uid_t)-1, 0, NO_OPLOCK);
01100 
01101         e = find_share_mode_entry(lck, &entry);
01102         if (e == NULL) {
01103                 return False;
01104         }
01105 
01106         e->op_type = UNUSED_SHARE_MODE_ENTRY;
01107         lck->modified = True;
01108         return True;
01109 }
01110 
01111 void del_deferred_open_entry(struct share_mode_lock *lck, uint16 mid)
01112 {
01113         struct share_mode_entry entry, *e;
01114 
01115         fill_deferred_open_entry(&entry, timeval_zero(),
01116                                  lck->dev, lck->ino, mid);
01117 
01118         e = find_share_mode_entry(lck, &entry);
01119         if (e == NULL) {
01120                 return;
01121         }
01122 
01123         e->op_type = UNUSED_SHARE_MODE_ENTRY;
01124         lck->modified = True;
01125 }
01126 
01127 /*******************************************************************
01128  Remove an oplock mid and mode entry from a share mode.
01129 ********************************************************************/
01130 
01131 BOOL remove_share_oplock(struct share_mode_lock *lck, files_struct *fsp)
01132 {
01133         struct share_mode_entry entry, *e;
01134 
01135         /* Don't care about the pid owner being correct here - just a search. */
01136         fill_share_mode_entry(&entry, fsp, (uid_t)-1, 0, NO_OPLOCK);
01137 
01138         e = find_share_mode_entry(lck, &entry);
01139         if (e == NULL) {
01140                 return False;
01141         }
01142 
01143         e->op_mid = 0;
01144         e->op_type = NO_OPLOCK;
01145         lck->modified = True;
01146         return True;
01147 }
01148 
01149 /*******************************************************************
01150  Downgrade a oplock type from exclusive to level II.
01151 ********************************************************************/
01152 
01153 BOOL downgrade_share_oplock(struct share_mode_lock *lck, files_struct *fsp)
01154 {
01155         struct share_mode_entry entry, *e;
01156 
01157         /* Don't care about the pid owner being correct here - just a search. */
01158         fill_share_mode_entry(&entry, fsp, (uid_t)-1, 0, NO_OPLOCK);
01159 
01160         e = find_share_mode_entry(lck, &entry);
01161         if (e == NULL) {
01162                 return False;
01163         }
01164 
01165         e->op_type = LEVEL_II_OPLOCK;
01166         lck->modified = True;
01167         return True;
01168 }
01169 
01170 /****************************************************************************
01171  Deal with the internal needs of setting the delete on close flag. Note that
01172  as the tdb locking is recursive, it is safe to call this from within 
01173  open_file_ntcreate. JRA.
01174 ****************************************************************************/
01175 
01176 NTSTATUS can_set_delete_on_close(files_struct *fsp, BOOL delete_on_close,
01177                                  uint32 dosmode)
01178 {
01179         if (!delete_on_close) {
01180                 return NT_STATUS_OK;
01181         }
01182 
01183         /*
01184          * Only allow delete on close for writable files.
01185          */
01186 
01187         if ((dosmode & aRONLY) &&
01188             !lp_delete_readonly(SNUM(fsp->conn))) {
01189                 DEBUG(10,("can_set_delete_on_close: file %s delete on close "
01190                           "flag set but file attribute is readonly.\n",
01191                           fsp->fsp_name ));
01192                 return NT_STATUS_CANNOT_DELETE;
01193         }
01194 
01195         /*
01196          * Only allow delete on close for writable shares.
01197          */
01198 
01199         if (!CAN_WRITE(fsp->conn)) {
01200                 DEBUG(10,("can_set_delete_on_close: file %s delete on "
01201                           "close flag set but write access denied on share.\n",
01202                           fsp->fsp_name ));
01203                 return NT_STATUS_ACCESS_DENIED;
01204         }
01205 
01206         /*
01207          * Only allow delete on close for files/directories opened with delete
01208          * intent.
01209          */
01210 
01211         if (!(fsp->access_mask & DELETE_ACCESS)) {
01212                 DEBUG(10,("can_set_delete_on_close: file %s delete on "
01213                           "close flag set but delete access denied.\n",
01214                           fsp->fsp_name ));
01215                 return NT_STATUS_ACCESS_DENIED;
01216         }
01217 
01218         /* Don't allow delete on close for non-empty directories. */
01219         if (fsp->is_directory) {
01220                 return can_delete_directory(fsp->conn, fsp->fsp_name);
01221         }
01222 
01223         return NT_STATUS_OK;
01224 }
01225 
01226 /****************************************************************************
01227  Do we have an open file handle that created this entry ?
01228 ****************************************************************************/
01229 
01230 BOOL can_set_initial_delete_on_close(const struct share_mode_lock *lck)
01231 {
01232         int i;
01233 
01234         for (i=0; i<lck->num_share_modes; i++) {
01235                 if (lck->share_modes[i].flags & SHARE_MODE_ALLOW_INITIAL_DELETE_ON_CLOSE) {
01236                         return True;
01237                 }
01238         }
01239         return False;
01240 }
01241 
01242 /*************************************************************************
01243  Return a talloced copy of a UNIX_USER_TOKEN. NULL on fail.
01244  (Should this be in locking.c.... ?).
01245 *************************************************************************/
01246 
01247 static UNIX_USER_TOKEN *copy_unix_token(TALLOC_CTX *ctx, UNIX_USER_TOKEN *tok)
01248 {
01249         UNIX_USER_TOKEN *cpy;
01250 
01251         if (tok == NULL) {
01252                 return NULL;
01253         }
01254 
01255         cpy = TALLOC_P(ctx, UNIX_USER_TOKEN);
01256         if (!cpy) {
01257                 return NULL;
01258         }
01259 
01260         cpy->uid = tok->uid;
01261         cpy->gid = tok->gid;
01262         cpy->ngroups = tok->ngroups;
01263         if (tok->ngroups) {
01264                 /* Make this a talloc child of cpy. */
01265                 cpy->groups = TALLOC_ARRAY(cpy, gid_t, tok->ngroups);
01266                 if (!cpy->groups) {
01267                         return NULL;
01268                 }
01269                 memcpy(cpy->groups, tok->groups, tok->ngroups * sizeof(gid_t));
01270         }
01271         return cpy;
01272 }
01273 
01274 /****************************************************************************
01275  Replace the delete on close token.
01276 ****************************************************************************/
01277 
01278 void set_delete_on_close_token(struct share_mode_lock *lck, UNIX_USER_TOKEN *tok)
01279 {
01280         /* Ensure there's no token. */
01281         if (lck->delete_token) {
01282                 TALLOC_FREE(lck->delete_token); /* Also deletes groups... */
01283                 lck->delete_token = NULL;
01284         }
01285 
01286         /* Copy the new token (can be NULL). */
01287         lck->delete_token = copy_unix_token(lck, tok);
01288         lck->modified = True;
01289 }
01290 
01291 /****************************************************************************
01292  Sets the delete on close flag over all share modes on this file.
01293  Modify the share mode entry for all files open
01294  on this device and inode to tell other smbds we have
01295  changed the delete on close flag. This will be noticed
01296  in the close code, the last closer will delete the file
01297  if flag is set.
01298  This makes a copy of any UNIX_USER_TOKEN into the
01299  lck entry. This function is used when the lock is already granted.
01300 ****************************************************************************/
01301 
01302 void set_delete_on_close_lck(struct share_mode_lock *lck, BOOL delete_on_close, UNIX_USER_TOKEN *tok)
01303 {
01304         if (lck->delete_on_close != delete_on_close) {
01305                 set_delete_on_close_token(lck, tok);
01306                 lck->delete_on_close = delete_on_close;
01307                 if (delete_on_close) {
01308                         SMB_ASSERT(lck->delete_token != NULL);
01309                 }
01310                 lck->modified = True;
01311         }
01312 }
01313 
01314 BOOL set_delete_on_close(files_struct *fsp, BOOL delete_on_close, UNIX_USER_TOKEN *tok)
01315 {
01316         struct share_mode_lock *lck;
01317         
01318         DEBUG(10,("set_delete_on_close: %s delete on close flag for "
01319                   "fnum = %d, file %s\n",
01320                   delete_on_close ? "Adding" : "Removing", fsp->fnum,
01321                   fsp->fsp_name ));
01322 
01323         if (fsp->is_stat) {
01324                 return True;
01325         }
01326 
01327         lck = get_share_mode_lock(NULL, fsp->dev, fsp->inode, NULL, NULL);
01328         if (lck == NULL) {
01329                 return False;
01330         }
01331 
01332         set_delete_on_close_lck(lck, delete_on_close, tok);
01333 
01334         if (fsp->is_directory) {
01335                 send_stat_cache_delete_message(fsp->fsp_name);
01336         }
01337 
01338         TALLOC_FREE(lck);
01339         return True;
01340 }
01341 
01342 /****************************************************************************
01343  Sets the allow initial delete on close flag for this share mode.
01344 ****************************************************************************/
01345 
01346 BOOL set_allow_initial_delete_on_close(struct share_mode_lock *lck, files_struct *fsp, BOOL delete_on_close)
01347 {
01348         struct share_mode_entry entry, *e;
01349 
01350         /* Don't care about the pid owner being correct here - just a search. */
01351         fill_share_mode_entry(&entry, fsp, (uid_t)-1, 0, NO_OPLOCK);
01352 
01353         e = find_share_mode_entry(lck, &entry);
01354         if (e == NULL) {
01355                 return False;
01356         }
01357 
01358         if (delete_on_close) {
01359                 e->flags |= SHARE_MODE_ALLOW_INITIAL_DELETE_ON_CLOSE;
01360         } else {
01361                 e->flags &= ~SHARE_MODE_ALLOW_INITIAL_DELETE_ON_CLOSE;
01362         }
01363         lck->modified = True;
01364         return True;
01365 }
01366 
01367 struct forall_state {
01368         void (*fn)(const struct share_mode_entry *entry,
01369                    const char *sharepath,
01370                    const char *fname,
01371                    void *private_data);
01372         void *private_data;
01373 };
01374 
01375 static int traverse_fn(TDB_CONTEXT *the_tdb, TDB_DATA kbuf, TDB_DATA dbuf, 
01376                        void *_state)
01377 {
01378         struct forall_state *state = (struct forall_state *)_state;
01379         struct locking_data *data;
01380         struct share_mode_entry *shares;
01381         const char *sharepath;
01382         const char *fname;
01383         int i;
01384 
01385         /* Ensure this is a locking_key record. */
01386         if (kbuf.dsize != sizeof(struct locking_key))
01387                 return 0;
01388 
01389         data = (struct locking_data *)dbuf.dptr;
01390         shares = (struct share_mode_entry *)(dbuf.dptr + sizeof(*data));
01391         sharepath = dbuf.dptr + sizeof(*data) +
01392                 data->u.s.num_share_mode_entries*sizeof(*shares) +
01393                 data->u.s.delete_token_size;
01394         fname = dbuf.dptr + sizeof(*data) +
01395                 data->u.s.num_share_mode_entries*sizeof(*shares) +
01396                 data->u.s.delete_token_size +
01397                 strlen(sharepath) + 1;
01398 
01399         for (i=0;i<data->u.s.num_share_mode_entries;i++) {
01400                 state->fn(&shares[i], sharepath, fname,
01401                           state->private_data);
01402         }
01403         return 0;
01404 }
01405 
01406 /*******************************************************************
01407  Call the specified function on each entry under management by the
01408  share mode system.
01409 ********************************************************************/
01410 
01411 int share_mode_forall(void (*fn)(const struct share_mode_entry *, const char *,
01412                                  const char *, void *),
01413                       void *private_data)
01414 {
01415         struct forall_state state;
01416 
01417         if (tdb == NULL)
01418                 return 0;
01419 
01420         state.fn = fn;
01421         state.private_data = private_data;
01422 
01423         return tdb_traverse(tdb, traverse_fn, (void *)&state);
01424 }

Sambaに対してSat Aug 29 21:23:06 2009に生成されました。  doxygen 1.4.7