diff options
Diffstat (limited to 'source3/locking')
-rw-r--r-- | source3/locking/locking.c | 120 | ||||
-rw-r--r-- | source3/locking/posix.c | 38 |
2 files changed, 90 insertions, 68 deletions
diff --git a/source3/locking/locking.c b/source3/locking/locking.c index 3c5ab63b4a..5bcf7f2eda 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -3,6 +3,7 @@ Locking functions Copyright (C) Andrew Tridgell 1992-2000 Copyright (C) Jeremy Allison 1992-2000 + Copyright (C) Volker Lendecke 2005 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -46,7 +47,10 @@ static TDB_CONTEXT *deferred_open_tdb; struct locking_data { union { - int num_share_mode_entries; + struct { + int num_share_mode_entries; + BOOL delete_on_close; + } s; share_mode_entry dummy; /* Needed for alignment. */ } u; /* the following two entries are implicit @@ -432,10 +436,14 @@ char *share_mode_str(int num, share_mode_entry *e) { static pstring share_str; - slprintf(share_str, sizeof(share_str)-1, "share_mode_entry[%d]: \ -pid = %lu, share_mode = 0x%x, desired_access = 0x%x, port = 0x%x, type= 0x%x, file_id = %lu, dev = 0x%x, inode = %.0f", - num, (unsigned long)e->pid, e->share_mode, (unsigned int)e->desired_access, e->op_port, e->op_type, e->share_file_id, - (unsigned int)e->dev, (double)e->inode ); + slprintf(share_str, sizeof(share_str)-1, "share_mode_entry[%d]: " + "pid = %lu, share_access = 0x%x, private_options = 0x%x, " + "access_mask = 0x%x, port = 0x%x, type= 0x%x, file_id = %lu, " + "dev = 0x%x, inode = %.0f", + num, (unsigned long)e->pid, + e->share_access, e->private_options, + e->access_mask, e->op_port, e->op_type, e->share_file_id, + (unsigned int)e->dev, (double)e->inode ); return share_str; } @@ -446,7 +454,7 @@ pid = %lu, share_mode = 0x%x, desired_access = 0x%x, port = 0x%x, type= 0x%x, fi static void print_share_mode_table(struct locking_data *data) { - int num_share_modes = data->u.num_share_mode_entries; + int num_share_modes = data->u.s.num_share_mode_entries; share_mode_entry *shares = (share_mode_entry *)(data + 1); int i; @@ -460,9 +468,9 @@ static void print_share_mode_table(struct locking_data *data) Get all share mode entries for a dev/inode pair. ********************************************************************/ -int get_share_modes(connection_struct *conn, - SMB_DEV_T dev, SMB_INO_T inode, - share_mode_entry **pp_shares) +int get_share_modes(SMB_DEV_T dev, SMB_INO_T inode, + share_mode_entry **pp_shares, + BOOL *delete_on_close) { TDB_DATA dbuf; struct locking_data *data; @@ -470,13 +478,18 @@ int get_share_modes(connection_struct *conn, share_mode_entry *shares = NULL; TDB_DATA key = locking_key(dev, inode); *pp_shares = NULL; + *delete_on_close = False; dbuf = tdb_fetch(tdb, key); if (!dbuf.dptr) return 0; data = (struct locking_data *)dbuf.dptr; - num_share_modes = data->u.num_share_mode_entries; + + *delete_on_close = data->u.s.delete_on_close; + DEBUG(10, ("get_share_modes: delete_on_close: %d\n", + *delete_on_close)); + num_share_modes = data->u.s.num_share_mode_entries; if(num_share_modes) { pstring fname; int i; @@ -515,7 +528,7 @@ int get_share_modes(connection_struct *conn, /* Did we delete any ? If so, re-store in tdb. */ if (del_count) { - data->u.num_share_mode_entries = num_share_modes; + data->u.s.num_share_mode_entries = num_share_modes; if (num_share_modes) { memcpy(dbuf.dptr + sizeof(*data), shares, @@ -527,7 +540,7 @@ int get_share_modes(connection_struct *conn, /* The record has shrunk a bit */ dbuf.dsize -= del_count * sizeof(share_mode_entry); - if (data->u.num_share_mode_entries == 0) { + if (data->u.s.num_share_mode_entries == 0) { if (tdb_delete(tdb, key) == -1) { SAFE_FREE(shares); SAFE_FREE(dbuf.dptr); @@ -548,6 +561,15 @@ int get_share_modes(connection_struct *conn, return num_share_modes; } +BOOL get_delete_on_close_flag(SMB_DEV_T dev, SMB_INO_T inode) +{ + share_mode_entry *shares; + BOOL result; + get_share_modes(dev, inode, &shares, &result); + SAFE_FREE(shares); + return result; +} + /******************************************************************* Fill a share mode entry. ********************************************************************/ @@ -559,8 +581,9 @@ static void fill_share_mode(char *p, files_struct *fsp, uint16 port, uint16 op_t memset(e, '\0', sizeof(share_mode_entry)); e->pid = sys_getpid(); - e->share_mode = fsp->share_mode; - e->desired_access = fsp->desired_access; + e->share_access = fsp->share_access; + e->private_options = fsp->fh->private_options; + e->access_mask = fsp->access_mask; e->op_port = port; e->op_type = op_type; memcpy(x, &fsp->open_time, sizeof(struct timeval)); @@ -581,16 +604,17 @@ BOOL share_modes_identical( share_mode_entry *e1, share_mode_entry *e2) e1->share_file_id == e2->share_file_id && e1->dev == e2->dev && e1->inode == e2->inode && - (e1->share_mode & ~DELETE_ON_CLOSE_FLAG) != (e2->share_mode & ~DELETE_ON_CLOSE_FLAG)) { - DEBUG(0,("PANIC: share_modes_identical: share_mode missmatch (e1 = %u, e2 = %u). Logic error.\n", - (unsigned int)(e1->share_mode & ~DELETE_ON_CLOSE_FLAG), - (unsigned int)(e2->share_mode & ~DELETE_ON_CLOSE_FLAG) )); + (e1->share_access) != (e2->share_access)) { + DEBUG(0,("PANIC: share_modes_identical: share_mode " + "mismatch (e1 = 0x%x, e2 = 0x%x). Logic error.\n", + (unsigned int)e1->share_access, + (unsigned int)e2->share_access )); smb_panic("PANIC: share_modes_identical logic error.\n"); } #endif return (e1->pid == e2->pid && - (e1->share_mode & ~DELETE_ON_CLOSE_FLAG) == (e2->share_mode & ~DELETE_ON_CLOSE_FLAG) && + (e1->share_access) == (e2->share_access) && e1->dev == e2->dev && e1->inode == e2->inode && e1->share_file_id == e2->share_file_id ); @@ -602,8 +626,9 @@ BOOL share_modes_identical( share_mode_entry *e1, share_mode_entry *e2) Ignore if no entry deleted. ********************************************************************/ -ssize_t del_share_entry( SMB_DEV_T dev, SMB_INO_T inode, - share_mode_entry *entry, share_mode_entry **ppse) +ssize_t del_share_entry(SMB_DEV_T dev, SMB_INO_T inode, + share_mode_entry *entry, share_mode_entry **ppse, + BOOL *delete_on_close) { TDB_DATA dbuf; struct locking_data *data; @@ -621,6 +646,7 @@ ssize_t del_share_entry( SMB_DEV_T dev, SMB_INO_T inode, return -1; data = (struct locking_data *)dbuf.dptr; + *delete_on_close = data->u.s.delete_on_close; shares = (share_mode_entry *)(dbuf.dptr + sizeof(*data)); /* @@ -629,15 +655,15 @@ ssize_t del_share_entry( SMB_DEV_T dev, SMB_INO_T inode, * from the record. */ - DEBUG(10,("del_share_entry: num_share_modes = %d\n", data->u.num_share_mode_entries )); + DEBUG(10,("del_share_entry: num_share_modes = %d\n", data->u.s.num_share_mode_entries )); - for (i=0;i<data->u.num_share_mode_entries;) { + for (i=0;i<data->u.s.num_share_mode_entries;) { if (share_modes_identical(&shares[i], entry)) { DEBUG(10,("del_share_entry: deleted %s\n", share_mode_str(i, &shares[i]) )); if (ppse) *ppse = memdup(&shares[i], sizeof(*shares)); - data->u.num_share_mode_entries--; + data->u.s.num_share_mode_entries--; if ((dbuf.dsize - (sizeof(*data) + (i+1)*sizeof(*shares))) > 0) { memmove(&shares[i], &shares[i+1], dbuf.dsize - (sizeof(*data) + (i+1)*sizeof(*shares))); @@ -655,10 +681,10 @@ ssize_t del_share_entry( SMB_DEV_T dev, SMB_INO_T inode, /* the record may have shrunk a bit */ dbuf.dsize -= del_count * sizeof(*shares); - count = (ssize_t)data->u.num_share_mode_entries; + count = (ssize_t)data->u.s.num_share_mode_entries; /* store it back in the database */ - if (data->u.num_share_mode_entries == 0) { + if (data->u.s.num_share_mode_entries == 0) { if (tdb_delete(tdb, key) == -1) count = -1; } else { @@ -677,7 +703,8 @@ ssize_t del_share_entry( SMB_DEV_T dev, SMB_INO_T inode, of entries left, and a memdup'ed copy of the entry deleted. ********************************************************************/ -ssize_t del_share_mode(files_struct *fsp, share_mode_entry **ppse) +ssize_t del_share_mode(files_struct *fsp, share_mode_entry **ppse, + BOOL *delete_on_close) { share_mode_entry entry; @@ -686,7 +713,8 @@ ssize_t del_share_mode(files_struct *fsp, share_mode_entry **ppse) */ fill_share_mode((char *)&entry, fsp, 0, 0); - return del_share_entry(fsp->dev, fsp->inode, &entry, ppse); + return del_share_entry(fsp->dev, fsp->inode, &entry, ppse, + delete_on_close); } /******************************************************************* @@ -718,7 +746,8 @@ BOOL set_share_mode(files_struct *fsp, uint16 port, uint16 op_type) if (!p) return False; data = (struct locking_data *)p; - data->u.num_share_mode_entries = 1; + ZERO_STRUCT(data->u); /* Keep valgrind happy */ + data->u.s.num_share_mode_entries = 1; DEBUG(10,("set_share_mode: creating entry for file %s. num_share_modes = 1\n", fsp->fsp_name )); @@ -740,10 +769,10 @@ BOOL set_share_mode(files_struct *fsp, uint16 port, uint16 op_type) /* we're adding to an existing entry - this is a bit fiddly */ data = (struct locking_data *)dbuf.dptr; - data->u.num_share_mode_entries++; + data->u.s.num_share_mode_entries++; DEBUG(10,("set_share_mode: adding entry for file %s. new num_share_modes = %d\n", - fsp->fsp_name, data->u.num_share_mode_entries )); + fsp->fsp_name, data->u.s.num_share_mode_entries )); size = dbuf.dsize + sizeof(share_mode_entry); p = SMB_MALLOC(size); @@ -790,7 +819,7 @@ static BOOL mod_share_mode( SMB_DEV_T dev, SMB_INO_T inode, share_mode_entry *en shares = (share_mode_entry *)(dbuf.dptr + sizeof(*data)); /* find any with our pid and call the supplied function */ - for (i=0;i<data->u.num_share_mode_entries;i++) { + for (i=0;i<data->u.s.num_share_mode_entries;i++) { if (share_modes_identical(entry, &shares[i])) { mod_fn(&shares[i], dev, inode, param); need_store=True; @@ -799,7 +828,7 @@ static BOOL mod_share_mode( SMB_DEV_T dev, SMB_INO_T inode, share_mode_entry *en /* if the mod fn was called then store it back */ if (need_store) { - if (data->u.num_share_mode_entries == 0) { + if (data->u.s.num_share_mode_entries == 0) { if (tdb_delete(tdb, key) == -1) ret = False; } else { @@ -877,8 +906,7 @@ BOOL modify_delete_flag( SMB_DEV_T dev, SMB_INO_T inode, BOOL delete_on_close) { TDB_DATA dbuf; struct locking_data *data; - int i; - share_mode_entry *shares; + BOOL res; TDB_DATA key = locking_key(dev, inode); /* read in the existing share modes */ @@ -887,25 +915,14 @@ BOOL modify_delete_flag( SMB_DEV_T dev, SMB_INO_T inode, BOOL delete_on_close) return False; data = (struct locking_data *)dbuf.dptr; - shares = (share_mode_entry *)(dbuf.dptr + sizeof(*data)); /* Set/Unset the delete on close element. */ - for (i=0;i<data->u.num_share_mode_entries;i++,shares++) { - shares->share_mode = (delete_on_close ? - (shares->share_mode | DELETE_ON_CLOSE_FLAG) : - (shares->share_mode & ~DELETE_ON_CLOSE_FLAG) ); - } + data->u.s.delete_on_close = delete_on_close; - /* store it back */ - if (data->u.num_share_mode_entries) { - if (tdb_store(tdb, key, dbuf, TDB_REPLACE)==-1) { - SAFE_FREE(dbuf.dptr); - return False; - } - } + res = (tdb_store(tdb, key, dbuf, TDB_REPLACE)!=-1); SAFE_FREE(dbuf.dptr); - return True; + return res; } /******************************************************************* @@ -1200,6 +1217,7 @@ BOOL add_deferred_open(uint16 mid, struct timeval *ptv, SMB_DEV_T dev, SMB_INO_T if (!p) return False; data = (struct deferred_open_data *)p; + ZERO_STRUCT(data->u.dummy); /* Keep valgrind happy */ data->u.num_deferred_open_entries = 1; DEBUG(10,("add_deferred_open: creating entry for file %s. num_deferred_open_entries = 1\n", @@ -1268,9 +1286,9 @@ static int traverse_fn(TDB_CONTEXT *the_tdb, TDB_DATA kbuf, TDB_DATA dbuf, data = (struct locking_data *)dbuf.dptr; shares = (share_mode_entry *)(dbuf.dptr + sizeof(*data)); - name = dbuf.dptr + sizeof(*data) + data->u.num_share_mode_entries*sizeof(*shares); + name = dbuf.dptr + sizeof(*data) + data->u.s.num_share_mode_entries*sizeof(*shares); - for (i=0;i<data->u.num_share_mode_entries;i++) { + for (i=0;i<data->u.s.num_share_mode_entries;i++) { traverse_callback(&shares[i], name); } return 0; diff --git a/source3/locking/posix.c b/source3/locking/posix.c index 218c441028..c63992adc5 100644 --- a/source3/locking/posix.c +++ b/source3/locking/posix.c @@ -114,7 +114,7 @@ static BOOL add_fd_to_close_entry(files_struct *fsp) } else dbuf.dptr = tp; - memcpy(dbuf.dptr + dbuf.dsize, &fsp->fd, sizeof(int)); + memcpy(dbuf.dptr + dbuf.dsize, &fsp->fh->fd, sizeof(int)); dbuf.dsize += sizeof(int); if (tdb_store(posix_pending_close_tdb, kbuf, dbuf, TDB_REPLACE) == -1) { @@ -209,8 +209,8 @@ int fd_close_posix(struct connection_struct *conn, files_struct *fsp) /* * No POSIX to worry about, just close. */ - ret = SMB_VFS_CLOSE(fsp,fsp->fd); - fsp->fd = -1; + ret = SMB_VFS_CLOSE(fsp,fsp->fh->fd); + fsp->fh->fd = -1; return ret; } @@ -227,7 +227,7 @@ int fd_close_posix(struct connection_struct *conn, files_struct *fsp) */ for (i = 0; i < count; i++) { - if (entries[i].fd != fsp->fd) { + if (entries[i].fd != fsp->fh->fd) { locks_on_other_fds = True; break; } @@ -237,7 +237,7 @@ int fd_close_posix(struct connection_struct *conn, files_struct *fsp) /* * There are outstanding locks on this dev/inode pair on other fds. - * Add our fd to the pending close tdb and set fsp->fd to -1. + * Add our fd to the pending close tdb and set fsp->fh->fd to -1. */ if (!add_fd_to_close_entry(fsp)) { @@ -246,7 +246,7 @@ int fd_close_posix(struct connection_struct *conn, files_struct *fsp) } SAFE_FREE(entries); - fsp->fd = -1; + fsp->fh->fd = -1; return 0; } @@ -282,14 +282,14 @@ int fd_close_posix(struct connection_struct *conn, files_struct *fsp) * Finally close the fd associated with this fsp. */ - ret = SMB_VFS_CLOSE(fsp,fsp->fd); + ret = SMB_VFS_CLOSE(fsp,fsp->fh->fd); if (saved_errno != 0) { errno = saved_errno; ret = -1; } - fsp->fd = -1; + fsp->fh->fd = -1; return ret; } @@ -371,7 +371,7 @@ static BOOL add_posix_lock_entry(files_struct *fsp, SMB_OFF_T start, SMB_OFF_T s * Add new record. */ - pl.fd = fsp->fd; + pl.fd = fsp->fh->fd; pl.start = start; pl.size = size; pl.lock_type = lock_type; @@ -455,7 +455,7 @@ static int delete_posix_lock_entry(files_struct *fsp, SMB_OFF_T start, SMB_OFF_T for (i=0; i<count; i++) { struct posix_lock *entry = &locks[i]; - if (entry->fd == fsp->fd && + if (entry->fd == fsp->fh->fd && entry->start == start && entry->size == size) { @@ -490,7 +490,7 @@ static int delete_posix_lock_entry(files_struct *fsp, SMB_OFF_T start, SMB_OFF_T for (i = 0; i < count; i++) { struct posix_lock *entry = &locks[i]; - if (fsp->fd == entry->fd && + if (fsp->fh->fd == entry->fd && does_lock_overlap( start, size, entry->start, entry->size)) num_overlapping_records++; } @@ -524,13 +524,17 @@ static int map_posix_lock_type( files_struct *fsp, enum brl_type lock_type) */ DEBUG(10,("map_posix_lock_type: Downgrading write lock to read due to read-only file.\n")); return F_RDLCK; - } else if((lock_type == READ_LOCK) && !fsp->can_read) { + } +#if 0 + /* We no longer open files write-only. */ + else if((lock_type == READ_LOCK) && !fsp->can_read) { /* * Ditto for read locks on write only files. */ DEBUG(10,("map_posix_lock_type: Changing read lock to write due to write-only file.\n")); return F_WRLCK; } +#endif /* * This return should be the most normal, as we attempt @@ -652,9 +656,9 @@ static BOOL posix_fcntl_lock(files_struct *fsp, int op, SMB_OFF_T offset, SMB_OF { int ret; - DEBUG(8,("posix_fcntl_lock %d %d %.0f %.0f %d\n",fsp->fd,op,(double)offset,(double)count,type)); + DEBUG(8,("posix_fcntl_lock %d %d %.0f %.0f %d\n",fsp->fh->fd,op,(double)offset,(double)count,type)); - ret = SMB_VFS_LOCK(fsp,fsp->fd,op,offset,count,type); + ret = SMB_VFS_LOCK(fsp,fsp->fh->fd,op,offset,count,type); if (!ret && ((errno == EFBIG) || (errno == ENOLCK) || (errno == EINVAL))) { @@ -678,7 +682,7 @@ static BOOL posix_fcntl_lock(files_struct *fsp, int op, SMB_OFF_T offset, SMB_OF DEBUG(0,("Count greater than 31 bits - retrying with 31 bit truncated length.\n")); errno = 0; count &= 0x7fffffff; - ret = SMB_VFS_LOCK(fsp,fsp->fd,op,offset,count,type); + ret = SMB_VFS_LOCK(fsp,fsp->fh->fd,op,offset,count,type); } } @@ -1247,7 +1251,7 @@ void posix_locking_close_file(files_struct *fsp) } for (i = 0; i < count; i++) { - if (entries[i].fd != fsp->fd ) + if (entries[i].fd != fsp->fh->fd ) break; dump_entry(&entries[i]); @@ -1269,7 +1273,7 @@ void posix_locking_close_file(files_struct *fsp) for (i = 0; i < count; i++) { struct posix_lock *pl = &entries[i]; - if (pl->fd == fsp->fd) + if (pl->fd == fsp->fh->fd) release_posix_lock(fsp, (SMB_BIG_UINT)pl->start, (SMB_BIG_UINT)pl->size ); } SAFE_FREE(entries); |