summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJeremy Allison <jra@samba.org>1998-10-23 03:34:50 +0000
committerJeremy Allison <jra@samba.org>1998-10-23 03:34:50 +0000
commit5e6a7cd99d29d1cf068fc517272559c1cf47ea3a (patch)
tree26f9188c69683491516c6bc3ee4a5e7599552c93
parenta66c56d70e7e663f3a19cbfcc2e704653d8fc9b2 (diff)
downloadsamba-5e6a7cd99d29d1cf068fc517272559c1cf47ea3a.tar.gz
samba-5e6a7cd99d29d1cf068fc517272559c1cf47ea3a.tar.xz
samba-5e6a7cd99d29d1cf068fc517272559c1cf47ea3a.zip
Reasonably large change to give us *exactly* correct NT delete on close semantics.
This was trickier than it looks :-). Check out the new DELETE_ON_CLOSE flag in the share modes and the new code that iterates through all open files on the same device and inode in files.c and trans2.c Also changed the code that modifies share mode entries to take generic function pointers rather than doing a specific thing so this sort of change should be easier in the future. Jeremy.
-rw-r--r--source/include/proto.h5
-rw-r--r--source/include/smb.h15
-rw-r--r--source/locking/locking.c45
-rw-r--r--source/locking/locking_shm.c29
-rw-r--r--source/locking/locking_slow.c59
-rw-r--r--source/smbd/close.c1
-rw-r--r--source/smbd/files.c35
-rw-r--r--source/smbd/open.c23
-rw-r--r--source/smbd/reply.c2
-rw-r--r--source/smbd/trans2.c52
10 files changed, 225 insertions, 41 deletions
diff --git a/source/include/proto.h b/source/include/proto.h
index 9b707adeefb..9c78e840173 100644
--- a/source/include/proto.h
+++ b/source/include/proto.h
@@ -538,7 +538,8 @@ int get_share_modes(connection_struct *conn,
share_mode_entry **shares);
void del_share_mode(int token, files_struct *fsp);
BOOL set_share_mode(int token, files_struct *fsp, uint16 port, uint16 op_type);
-BOOL remove_share_oplock(files_struct *fsp, int token);
+BOOL remove_share_oplock(int token, files_struct *fsp);
+BOOL modify_share_mode(int token, files_struct *fsp, int new_mode);
int share_mode_forall(void (*fn)(share_mode_entry *, char *));
void share_status(FILE *f);
@@ -2147,6 +2148,8 @@ void file_close_conn(connection_struct *conn);
void file_init(void);
void file_close_user(int vuid);
files_struct *file_find_dit(SMB_DEV_T dev, SMB_INO_T inode, struct timeval *tval);
+files_struct *file_find_di_first(SMB_DEV_T dev, SMB_INO_T inode);
+files_struct *file_find_di_next(files_struct *start_fsp);
files_struct *file_find_print(void);
void file_sync_all(connection_struct *conn);
void fd_ptr_free(file_fd_struct *fd_ptr);
diff --git a/source/include/smb.h b/source/include/smb.h
index d71d1cd1eb0..2e27fa195f7 100644
--- a/source/include/smb.h
+++ b/source/include/smb.h
@@ -201,14 +201,19 @@ implemented */
#define GET_DENY_MODE(x) (((x)>>SHARE_MODE_SHIFT) & SHARE_MODE_MASK)
#define SET_DENY_MODE(x) ((x)<<SHARE_MODE_SHIFT)
+/* Sync on open file (not sure if used anymore... ?) */
+#define FILE_SYNC_OPENMODE (1<<14)
+#define GET_FILE_SYNC_OPENMODE(x) (((x) & FILE_SYNC_OPENMODE) ? True : False)
+
/* allow delete on open file mode (used by NT SMB's). */
#define ALLOW_SHARE_DELETE (1<<15)
-#define GET_ALLOW_SHARE_DELETE(x) (((x) & ALLOW_SHARE_DELETE) ? 1 : 0)
+#define GET_ALLOW_SHARE_DELETE(x) (((x) & ALLOW_SHARE_DELETE) ? True : False)
#define SET_ALLOW_SHARE_DELETE(x) ((x) ? ALLOW_SHARE_DELETE : 0)
-/* Sync on open file (not sure if used anymore... ?) */
-#define FILE_SYNC_OPENMODE (1<<14)
-#define GET_FILE_SYNC_OPENMODE(x) (((x) & FILE_SYNC_OPENMODE) ? 1 : 0)
+/* delete on close flag (used by NT SMB's). */
+#define DELETE_ON_CLOSE_FLAG (1<<16)
+#define GET_DELETE_ON_CLOSE_FLAG(x) (((x) & DELETE_ON_CLOSE_FLAG) ? True : False)
+#define SET_DELETE_ON_CLOSE_FLAG(x) ((x) ? DELETE_ON_CLOSE_FLAG : 0)
/* open disposition values */
#define FILE_EXISTS_FAIL 0
@@ -669,7 +674,7 @@ struct share_ops {
int (*get_entries)(connection_struct *, int , SMB_DEV_T , SMB_INO_T , share_mode_entry **);
void (*del_entry)(int , files_struct *);
BOOL (*set_entry)(int, files_struct *, uint16 , uint16 );
- BOOL (*remove_oplock)(files_struct *, int);
+ BOOL (*mod_entry)(int, files_struct *, void (*)(share_mode_entry *, SMB_DEV_T, SMB_INO_T, void *), void *);
int (*forall)(void (*)(share_mode_entry *, char *));
void (*status)(FILE *);
};
diff --git a/source/locking/locking.c b/source/locking/locking.c
index f088720e0a0..b71b7755248 100644
--- a/source/locking/locking.c
+++ b/source/locking/locking.c
@@ -230,11 +230,52 @@ BOOL set_share_mode(int token, files_struct *fsp, uint16 port, uint16 op_type)
}
/*******************************************************************
+ Static function that actually does the work for the generic function
+ below.
+********************************************************************/
+
+static void remove_share_oplock_fn(share_mode_entry *entry, SMB_DEV_T dev, SMB_INO_T inode,
+ void *param)
+{
+ DEBUG(10,("remove_share_oplock_fn: removing oplock info for entry dev=%x ino=%.0f\n",
+ (unsigned int)dev, (double)inode ));
+ /* Delete the oplock info. */
+ entry->op_port = 0;
+ entry->op_type = 0;
+}
+
+/*******************************************************************
Remove an oplock port and mode entry from a share mode.
********************************************************************/
-BOOL remove_share_oplock(files_struct *fsp, int token)
+
+BOOL remove_share_oplock(int token, files_struct *fsp)
+{
+ return share_ops->mod_entry(token, fsp, remove_share_oplock_fn, NULL);
+}
+
+/*******************************************************************
+ Static function that actually does the work for the generic function
+ below.
+********************************************************************/
+
+static void modify_share_mode_fn(share_mode_entry *entry, SMB_DEV_T dev, SMB_INO_T inode,
+ void *param)
+{
+ int new_share_mode = *(int *)param;
+ DEBUG(10,("modify_share_mode_fn: changing share mode info from %x to %x for entry dev=%x ino=%.0f\n",
+ entry->share_mode, new_share_mode, (unsigned int)dev, (double)inode ));
+ /* Change the share mode info. */
+ entry->share_mode = new_share_mode;
+}
+
+/*******************************************************************
+ Modify a share mode on a file. Used by the delete open file code.
+ Return False on fail, True on success.
+********************************************************************/
+
+BOOL modify_share_mode(int token, files_struct *fsp, int new_mode)
{
- return share_ops->remove_oplock(fsp, token);
+ return share_ops->mod_entry(token, fsp, modify_share_mode_fn, (void *)&new_mode);
}
/*******************************************************************
diff --git a/source/locking/locking_shm.c b/source/locking/locking_shm.c
index 1077cf23eb6..375a8b7f109 100644
--- a/source/locking/locking_shm.c
+++ b/source/locking/locking_shm.c
@@ -495,9 +495,12 @@ static BOOL shm_set_share_mode(int token, files_struct *fsp, uint16 port, uint16
}
/*******************************************************************
-Remove an oplock port and mode entry from a share mode.
+ Call a generic modify function for a share mode entry.
********************************************************************/
-static BOOL shm_remove_share_oplock(files_struct *fsp, int token)
+
+static BOOL shm_mod_share_entry(int token, files_struct *fsp,
+ void (*mod_fn)(share_mode_entry *, SMB_DEV_T, SMB_INO_T, void *),
+ void *param)
{
SMB_DEV_T dev;
SMB_INO_T inode;
@@ -518,7 +521,7 @@ static BOOL shm_remove_share_oplock(files_struct *fsp, int token)
if(mode_array[hash_entry] == 0)
{
- DEBUG(0,("PANIC ERROR:remove_share_oplock: hash bucket %d empty\n",
+ DEBUG(0,("PANIC ERROR:modify_share_entry: hash bucket %d empty\n",
hash_entry));
return False;
}
@@ -543,14 +546,14 @@ static BOOL shm_remove_share_oplock(files_struct *fsp, int token)
if(!found)
{
- DEBUG(0,("ERROR:remove_share_oplock: no entry found for dev=%x ino=%.0f\n",
+ DEBUG(0,("ERROR:modify_share_entry: no entry found for dev=%x ino=%.0f\n",
(unsigned int)dev, (double)inode));
return False;
}
if(file_scanner_p->locking_version != LOCKING_VERSION)
{
- DEBUG(0,("ERROR: remove_share_oplock: Deleting old share mode v1=%d dev=%x ino=%.0f\n",
+ DEBUG(0,("ERROR: modify_share_entry: Deleting old share mode v1=%d dev=%x ino=%.0f\n",
file_scanner_p->locking_version, (unsigned int)dev, (double)inode));
if(file_prev_p == file_scanner_p)
@@ -571,9 +574,14 @@ static BOOL shm_remove_share_oplock(files_struct *fsp, int token)
(memcmp(&entry_scanner_p->e.time,
&fsp->open_time,sizeof(struct timeval)) == 0) )
{
- /* Delete the oplock info. */
- entry_scanner_p->e.op_port = 0;
- entry_scanner_p->e.op_type = 0;
+ /*
+ * Call the generic function with the given parameter.
+ */
+
+ DEBUG(5,("modify_share_entry: Calling generic function to modify entry for dev=%x ino=%.0f\n",
+ (unsigned int)dev, (double)inode));
+
+ (*mod_fn)( &entry_scanner_p->e, dev, inode, param);
found = True;
break;
}
@@ -586,7 +594,7 @@ static BOOL shm_remove_share_oplock(files_struct *fsp, int token)
if(!found)
{
- DEBUG(0,("ERROR: remove_share_oplock: No oplock granted. dev=%x ino=%.0f\n",
+ DEBUG(0,("ERROR: modify_share_entry: No entry found for dev=%x ino=%.0f\n",
(unsigned int)dev, (double)inode));
return False;
}
@@ -594,7 +602,6 @@ static BOOL shm_remove_share_oplock(files_struct *fsp, int token)
return True;
}
-
/*******************************************************************
call the specified function on each entry under management by the
share mode system
@@ -670,7 +677,7 @@ static struct share_ops share_ops = {
shm_get_share_modes,
shm_del_share_mode,
shm_set_share_mode,
- shm_remove_share_oplock,
+ shm_mod_share_entry,
shm_share_forall,
shm_share_status,
};
diff --git a/source/locking/locking_slow.c b/source/locking/locking_slow.c
index f2c2d3e9d9a..f1e0fa21496 100644
--- a/source/locking/locking_slow.c
+++ b/source/locking/locking_slow.c
@@ -827,9 +827,12 @@ mode 0x%X pid=%d\n",fname,fsp->share_mode,pid));
}
/*******************************************************************
-Remove an oplock port and mode entry from a share mode.
+ Call a generic modify function for a share mode entry.
********************************************************************/
-static BOOL slow_remove_share_oplock(files_struct *fsp, int token)
+
+static BOOL slow_mod_share_entry(int token, files_struct *fsp,
+ void (*mod_fn)(share_mode_entry *, SMB_DEV_T, SMB_INO_T, void *),
+ void *param)
{
pstring fname;
int fd = (int)token;
@@ -841,20 +844,21 @@ static BOOL slow_remove_share_oplock(files_struct *fsp, int token)
int pid;
BOOL found = False;
BOOL new_file;
+ share_mode_entry entry;
share_name(fsp->conn, fsp->fd_ptr->dev,
fsp->fd_ptr->inode, fname);
if(read_share_file( fsp->conn, fd, fname, &buf, &new_file) != 0)
{
- DEBUG(0,("ERROR: remove_share_oplock: Failed to read share file %s\n",
+ DEBUG(0,("ERROR: slow_mod_share_entry: Failed to read share file %s\n",
fname));
return False;
}
if(new_file == True)
{
- DEBUG(0,("ERROR: remove_share_oplock: share file %s is new (size zero), \
+ DEBUG(0,("ERROR: slow_mod_share_entry: share file %s is new (size zero), \
deleting it.\n", fname));
delete_share_file(fsp->conn, fname);
return False;
@@ -862,13 +866,13 @@ deleting it.\n", fname));
num_entries = IVAL(buf,SMF_NUM_ENTRIES_OFFSET);
- DEBUG(5,("remove_share_oplock: share file %s has %d share mode entries.\n",
+ DEBUG(5,("slow_mod_share_entry: share file %s has %d share mode entries.\n",
fname, num_entries));
/* PARANOIA TEST */
if(num_entries < 0)
{
- DEBUG(0,("PANIC ERROR:remove_share_oplock: num_share_mode_entries < 0 (%d) \
+ DEBUG(0,("PANIC ERROR:slow_mod_share_entry: num_share_mode_entries < 0 (%d) \
for share file %s\n", num_entries, fname));
return False;
}
@@ -876,7 +880,7 @@ for share file %s\n", num_entries, fname));
if(num_entries == 0)
{
/* No entries - just delete the file. */
- DEBUG(0,("remove_share_oplock: share file %s has no share mode entries - deleting.\n",
+ DEBUG(0,("slow_mod_share_entry: share file %s has no share mode entries - deleting.\n",
fname));
if(buf)
free(buf);
@@ -886,10 +890,6 @@ for share file %s\n", num_entries, fname));
pid = getpid();
- /* Go through the entries looking for the particular one
- we have set - remove the oplock settings on it.
- */
-
base = buf + SMF_HEADER_LENGTH + SVAL(buf,SMF_FILENAME_LEN_OFFSET);
for(i = 0; i < num_entries; i++)
@@ -902,18 +902,41 @@ for share file %s\n", num_entries, fname));
(IVAL(p,SME_PID_OFFSET) != pid))
continue;
- DEBUG(5,("remove_share_oplock: clearing oplock on entry number %d (of %d) \
+ DEBUG(5,("slow_mod_share_entry: Calling generic function to modify entry number %d (of %d) \
from the share file %s\n", i, num_entries, fname));
- SSVAL(p,SME_PORT_OFFSET,0);
- SSVAL(p,SME_OPLOCK_TYPE_OFFSET,0);
+ /*
+ * Copy into the share_mode_entry structure and then call
+ * the generic function with the given parameter.
+ */
+
+ entry.pid = IVAL(p,SME_PID_OFFSET);
+ entry.op_port = SVAL(p,SME_PORT_OFFSET);
+ entry.op_type = SVAL(p,SME_OPLOCK_TYPE_OFFSET);
+ entry.share_mode = IVAL(p,SME_SHAREMODE_OFFSET);
+ entry.time.tv_sec = IVAL(p,SME_SEC_OFFSET)
+ entry.time.tv_sec = IVAL(p,SME_USEC_OFFSET);
+
+ (*mod_fn)( &entry, fsp->fd_ptr->dev, fsp->fd_ptr->inode, param);
+
+ /*
+ * Now copy any changes the function made back into the buffer.
+ */
+
+ SIVAL(p,SME_PID_OFFSET, entry.pid)
+ SSVAL(p,SME_PORT_OFFSET,entry.op_port);
+ SSVAL(p,SME_OPLOCK_TYPE_OFFSET,entry.op_type);
+ SIVAL(p,SME_SHAREMODE_OFFSET,entry.share_mode);
+ SIVAL(p,SME_SEC_OFFSET,entry.time.tv_sec)
+ SIVAL(p,SME_USEC_OFFSET,entry.time.tv_sec);
+
found = True;
break;
}
if(!found)
{
- DEBUG(0,("remove_share_oplock: entry not found in share file %s\n", fname));
+ DEBUG(0,("slow_mod_share_entry: entry not found in share file %s\n", fname));
if(buf)
free(buf);
return False;
@@ -922,7 +945,7 @@ from the share file %s\n", i, num_entries, fname));
/* Re-write the file - and truncate it at the correct point. */
if(sys_lseek(fd, (SMB_OFF_T)0, SEEK_SET) != 0)
{
- DEBUG(0,("ERROR: remove_share_oplock: lseek failed to reset to \
+ DEBUG(0,("ERROR: slow_mod_share_entry: lseek failed to reset to \
position 0 for share mode file %s (%s)\n", fname, strerror(errno)));
if(buf)
free(buf);
@@ -932,7 +955,7 @@ position 0 for share mode file %s (%s)\n", fname, strerror(errno)));
fsize = (base - buf) + (SMF_ENTRY_LENGTH*num_entries);
if(write(fd, buf, fsize) != fsize)
{
- DEBUG(0,("ERROR: remove_share_oplock: failed to re-write share \
+ DEBUG(0,("ERROR: slow_mod_share_entry: failed to re-write share \
mode file %s (%s)\n", fname, strerror(errno)));
if(buf)
free(buf);
@@ -1048,7 +1071,7 @@ static struct share_ops share_ops = {
slow_get_share_modes,
slow_del_share_mode,
slow_set_share_mode,
- slow_remove_share_oplock,
+ slow_mod_share_entry,
slow_share_forall,
slow_share_status,
};
diff --git a/source/smbd/close.c b/source/smbd/close.c
index 2dba691a1c2..50ad01f5755 100644
--- a/source/smbd/close.c
+++ b/source/smbd/close.c
@@ -142,6 +142,7 @@ void close_file(files_struct *fsp, BOOL normal_close)
*/
if (normal_close && last_reference && delete_on_close) {
+ DEBUG(5,("close_file: file %s. Delete on close was set - deleting file.\n"));
if(dos_unlink(fsp->fsp_name) != 0)
DEBUG(0,("close_file: file %s. Delete on close was set and unlink failed \
with error %s\n", fsp->fsp_name, strerror(errno) ));
diff --git a/source/smbd/files.c b/source/smbd/files.c
index c369a45bab3..e58c3834a00 100644
--- a/source/smbd/files.c
+++ b/source/smbd/files.c
@@ -277,6 +277,41 @@ files_struct *file_find_dit(SMB_DEV_T dev, SMB_INO_T inode, struct timeval *tval
return NULL;
}
+/****************************************************************************
+ Find the first fsp given a device and inode.
+****************************************************************************/
+
+files_struct *file_find_di_first(SMB_DEV_T dev, SMB_INO_T inode)
+{
+ files_struct *fsp;
+
+ for (fsp=Files;fsp;fsp=fsp->next) {
+ if (fsp->open &&
+ fsp->fd_ptr->dev == dev &&
+ fsp->fd_ptr->inode == inode )
+ return fsp;
+ }
+
+ return NULL;
+}
+
+/****************************************************************************
+ Find the next fsp having the same device and inode.
+****************************************************************************/
+
+files_struct *file_find_di_next(files_struct *start_fsp)
+{
+ files_struct *fsp;
+
+ for (fsp = start_fsp->next;fsp;fsp=fsp->next) {
+ if (fsp->open &&
+ fsp->fd_ptr->dev == start_fsp->fd_ptr->dev &&
+ fsp->fd_ptr->inode == start_fsp->fd_ptr->inode )
+ return fsp;
+ }
+
+ return NULL;
+}
/****************************************************************************
find a fsp that is open for printing
diff --git a/source/smbd/open.c b/source/smbd/open.c
index b6b2ef5bb8a..aac4b02fba3 100644
--- a/source/smbd/open.c
+++ b/source/smbd/open.c
@@ -659,6 +659,26 @@ static int check_share_mode( share_mode_entry *share, int deny_mode,
int old_open_mode = GET_OPEN_MODE(share->share_mode);
int old_deny_mode = GET_DENY_MODE(share->share_mode);
+ /*
+ * Setup the potential error to return.
+ */
+
+ unix_ERR_class = ERRDOS;
+ unix_ERR_code = ERRbadshare;
+
+ /*
+ * Don't allow any open once the delete on close flag has been
+ * set.
+ */
+
+ if(GET_DELETE_ON_CLOSE_FLAG(share->share_mode))
+ {
+ DEBUG(5,("check_share_mode: Failing open on file %s as delete on close flag is set.\n",
+ fname ));
+ unix_ERR_code = ERRnoaccess;
+ return False;
+ }
+
if (old_deny_mode > 4 || old_open_mode > 2)
{
DEBUG(0,("Invalid share mode found (%d,%d,%d) on file %s\n",
@@ -688,6 +708,7 @@ static int check_share_mode( share_mode_entry *share, int deny_mode,
*flags = O_WRONLY;
}
+
return True;
}
@@ -865,8 +886,6 @@ dev = %x, inode = %.0f\n", old_shares[i].op_type, fname, (unsigned int)dev, (dou
free((char *)old_shares);
unlock_share_entry(conn, dev, inode, token);
errno = EACCES;
- unix_ERR_class = ERRDOS;
- unix_ERR_code = ERRbadshare;
return;
}
diff --git a/source/smbd/reply.c b/source/smbd/reply.c
index bc19f1a9313..babdd2056c4 100644
--- a/source/smbd/reply.c
+++ b/source/smbd/reply.c
@@ -3615,7 +3615,7 @@ no oplock granted on this file.\n", fsp->fnum));
/* Remove the oplock flag from the sharemode. */
lock_share_entry(fsp->conn, dev, inode, &token);
- if(remove_share_oplock(fsp, token)==False) {
+ if(remove_share_oplock(token, fsp)==False) {
DEBUG(0,("reply_lockingX: failed to remove share oplock for fnum %d, \
dev = %x, inode = %.0f\n", fsp->fnum, (unsigned int)dev, (double)inode));
diff --git a/source/smbd/trans2.c b/source/smbd/trans2.c
index f8d90cd8718..1c2bdb1ddfa 100644
--- a/source/smbd/trans2.c
+++ b/source/smbd/trans2.c
@@ -1655,14 +1655,64 @@ static int call_trans2setfilepathinfo(connection_struct *conn,
{
if (tran_call == TRANSACT2_SETFILEINFO) {
files_struct *fsp = file_fsp(params,0);
+ BOOL delete_on_close = (CVAL(pdata,0) ? True : False);
+
if(fsp->is_directory)
return(ERROR(ERRDOS,ERRnoaccess));
+
+ /*
+ * We can only set the delete on close flag if
+ * the share mode contained ALLOW_SHARE_DELETE
+ */
+
+ if(!GET_ALLOW_SHARE_DELETE(fsp->share_mode))
+ return(ERROR(ERRDOS,ERRnoaccess));
+
+ /*
+ * If the flag has changed from its previous value then
+ * modify the share mode entry for all files we have open
+ * on this device and inode to tell other smbds we have
+ * changed the delete on close flag.
+ */
+
+ if(GET_DELETE_ON_CLOSE_FLAG(fsp->share_mode) != delete_on_close)
+ {
+ int token;
+ files_struct *iterate_fsp;
+ SMB_DEV_T dev = fsp->fd_ptr->dev;
+ SMB_INO_T inode = fsp->fd_ptr->inode;
+ int new_share_mode = (delete_on_close ?
+ (fsp->share_mode | DELETE_ON_CLOSE_FLAG) :
+ (fsp->share_mode & ~DELETE_ON_CLOSE_FLAG) );
+
+ DEBUG(10,("call_trans2setfilepathinfo: %s delete on close flag for fnum = %d, file %s\n",
+ delete_on_close ? "Adding" : "Removing", fsp->fnum, fsp->fsp_name ));
+
+ if(lock_share_entry(fsp->conn, dev, inode, &token) == False)
+ return(ERROR(ERRDOS,ERRnoaccess));
+
+ /*
+ * Go through all files we have open on the same device and
+ * inode (hanging off the same hash bucket) and set the DELETE_ON_CLOSE_FLAG.
+ */
+
+ for(iterate_fsp = file_find_di_first(dev, inode); iterate_fsp;
+ iterate_fsp = file_find_di_next(iterate_fsp))
+ {
+ if(modify_share_mode(token, iterate_fsp, new_share_mode)==False)
+ DEBUG(0,("call_trans2setfilepathinfo: failed to change delete on close for fnum %d, \
+dev = %x, inode = %.0f\n", fsp->fnum, (unsigned int)dev, (double)inode));
+ }
+
+ unlock_share_entry(fsp->conn, dev, inode, token);
+ }
+
/*
* Set the delete on close flag in the reference
* counted struct. Delete when the last reference
* goes away.
*/
- fsp->fd_ptr->delete_on_close = CVAL(pdata,0);
+ fsp->fd_ptr->delete_on_close = delete_on_close;
} else
return(ERROR(ERRDOS,ERRunknownlevel));
break;