mirror of
https://github.com/samba-team/samba.git
synced 2025-01-12 09:18:10 +03:00
Ok - this is the 'expose 64 bit to the clients' checkin.
I have tested it by creating a 'holey' 20GB file - checking that it shows up correctl in the NT file view (it does) and am busily copying it to NULL: on the NT box. All good so far.... :-). Also implemented NT 'delete on close' semantics. Jeremy.
This commit is contained in:
parent
36544fe547
commit
1654faee80
@ -576,6 +576,7 @@ typedef struct files_struct
|
||||
BOOL granted_oplock;
|
||||
BOOL sent_oplock_break;
|
||||
BOOL is_directory;
|
||||
BOOL delete_on_close;
|
||||
char *fsp_name;
|
||||
} files_struct;
|
||||
|
||||
|
@ -222,7 +222,7 @@ static void reply_lockingX_error(blocking_lock_record *blr, int eclass, int32 ec
|
||||
offset = (((SMB_OFF_T) IVAL(data,SMB_LARGE_LKOFF_OFFSET_HIGH(i))) << 32) |
|
||||
((SMB_OFF_T) IVAL(data,SMB_LARGE_LKOFF_OFFSET_LOW(i)));
|
||||
}
|
||||
#endif
|
||||
#endif /* LARGE_SMB_OFF_T */
|
||||
do_unlock(fsp,conn,count,offset,&dummy1,&dummy2);
|
||||
}
|
||||
|
||||
@ -412,7 +412,7 @@ static BOOL process_lockingX(blocking_lock_record *blr)
|
||||
offset = (((SMB_OFF_T) IVAL(data,SMB_LARGE_LKOFF_OFFSET_HIGH(blr->lock_num))) << 32) |
|
||||
((SMB_OFF_T) IVAL(data,SMB_LARGE_LKOFF_OFFSET_LOW(blr->lock_num)));
|
||||
}
|
||||
#endif
|
||||
#endif /* LARGE_SMB_OFF_T */
|
||||
errno = 0;
|
||||
if(!do_lock(fsp,conn,count,offset, ((locktype & 1) ? F_RDLCK : F_WRLCK),
|
||||
&eclass, &ecode))
|
||||
|
@ -102,6 +102,7 @@ void close_file(files_struct *fsp, BOOL normal_close)
|
||||
SMB_DEV_T dev = fsp->fd_ptr->dev;
|
||||
SMB_INO_T inode = fsp->fd_ptr->inode;
|
||||
int token;
|
||||
BOOL last_reference = False;
|
||||
connection_struct *conn = fsp->conn;
|
||||
|
||||
remove_pending_lock_requests_by_fid(fsp);
|
||||
@ -118,7 +119,9 @@ void close_file(files_struct *fsp, BOOL normal_close)
|
||||
}
|
||||
|
||||
if(fd_attempt_close(fsp->fd_ptr) == 0)
|
||||
fsp->fd_ptr = NULL;
|
||||
last_reference = True;
|
||||
|
||||
fsp->fd_ptr = NULL;
|
||||
|
||||
if (lp_share_modes(SNUM(conn)))
|
||||
unlock_share_entry(conn, dev, inode, token);
|
||||
@ -132,6 +135,17 @@ void close_file(files_struct *fsp, BOOL normal_close)
|
||||
check_magic(fsp,conn);
|
||||
}
|
||||
|
||||
/*
|
||||
* NT can set delete_on_close of the last open
|
||||
* reference to a file.
|
||||
*/
|
||||
|
||||
if (normal_close && last_reference && fsp->delete_on_close) {
|
||||
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) ));
|
||||
}
|
||||
|
||||
if(fsp->granted_oplock == True)
|
||||
global_oplocks_open--;
|
||||
|
||||
|
@ -157,11 +157,15 @@ static int reply_nt1(char *outbuf)
|
||||
{
|
||||
/* dual names + lock_and_read + nt SMBs + remote API calls */
|
||||
int capabilities = CAP_NT_FIND|CAP_LOCK_AND_READ|
|
||||
(lp_nt_smb_support() ? CAP_NT_SMBS | CAP_RPC_REMOTE_APIS : 0);
|
||||
(lp_nt_smb_support() ? CAP_NT_SMBS | CAP_RPC_REMOTE_APIS : 0) |
|
||||
#ifdef LARGE_SMB_OFF_T
|
||||
(sizeof(SMB_OFF_T) == 8 ? CAP_LARGE_FILES : 0);
|
||||
#else
|
||||
0;
|
||||
#endif
|
||||
|
||||
/*
|
||||
other valid capabilities which we may support at some time...
|
||||
CAP_LARGE_FILES|
|
||||
CAP_LARGE_READX|CAP_STATUS32|CAP_LEVEL_II_OPLOCKS;
|
||||
*/
|
||||
|
||||
|
@ -507,6 +507,7 @@ static void open_file(files_struct *fsp,connection_struct *conn,
|
||||
fsp->granted_oplock = False;
|
||||
fsp->sent_oplock_break = False;
|
||||
fsp->is_directory = False;
|
||||
fsp->delete_on_close = False;
|
||||
fsp->conn = conn;
|
||||
/*
|
||||
* Note that the file name here is the *untranslated* name
|
||||
|
@ -2006,14 +2006,14 @@ int reply_read_and_X(connection_struct *conn, char *inbuf,char *outbuf,int lengt
|
||||
set_message(outbuf,12,0,True);
|
||||
data = smb_buf(outbuf);
|
||||
|
||||
#ifdef LARGE_SMB_INO_T
|
||||
#ifdef LARGE_SMB_OFF_T
|
||||
if(SVAL(inbuf,smb_wct) == 12) {
|
||||
/*
|
||||
* This is a large offset (64 bit) read.
|
||||
*/
|
||||
startpos |= (((SMB_OFF_T)IVAL(inbuf,smb_vwv10)) << 32);
|
||||
}
|
||||
#endif /* LARGE_SMB_INO_T */
|
||||
#endif /* LARGE_SMB_OFF_T */
|
||||
|
||||
if (is_locked(fsp,conn,smb_maxcnt,startpos, F_RDLCK))
|
||||
return(ERROR(ERRDOS,ERRlock));
|
||||
@ -2264,14 +2264,14 @@ int reply_write_and_X(connection_struct *conn, char *inbuf,char *outbuf,int leng
|
||||
|
||||
data = smb_base(inbuf) + smb_doff;
|
||||
|
||||
#ifdef LLARGE_SMB_INO_T
|
||||
#ifdef LLARGE_SMB_OFF_T
|
||||
if(SVAL(inbuf,smb_wct) == 14) {
|
||||
/*
|
||||
* This is a large offset (64 bit) write.
|
||||
*/
|
||||
startpos |= (((SMB_OFF_T)IVAL(inbuf,smb_vwv12)) << 32);
|
||||
}
|
||||
#endif /* LARGE_SMB_INO_T */
|
||||
#endif /* LARGE_SMB_OFF_T */
|
||||
|
||||
if (is_locked(fsp,conn,numtowrite,startpos, F_WRLCK))
|
||||
return(ERROR(ERRDOS,ERRlock));
|
||||
@ -2408,8 +2408,8 @@ int reply_close(connection_struct *conn,
|
||||
* We can only use CHECK_FSP if we know it's not a directory.
|
||||
*/
|
||||
|
||||
if(!(fsp && fsp->open && fsp->is_directory))
|
||||
CHECK_FSP(fsp,conn);
|
||||
if(!fsp || !fsp->open || (fsp->conn != conn))
|
||||
return(ERROR(ERRDOS,ERRbadfid));
|
||||
|
||||
if(HAS_CACHED_ERROR(fsp)) {
|
||||
eclass = fsp->wbmpx_ptr->wr_errclass;
|
||||
@ -3631,7 +3631,7 @@ dev = %x, inode = %.0f\n", fsp->fnum, (unsigned int)dev, (double)inode));
|
||||
offset = (((SMB_OFF_T) IVAL(data,SMB_LARGE_LKOFF_OFFSET_HIGH(i))) << 32) |
|
||||
((SMB_OFF_T) IVAL(data,SMB_LARGE_LKOFF_OFFSET_LOW(i)));
|
||||
}
|
||||
#endif
|
||||
#endif /* LARGE_SMB_OFF_T */
|
||||
|
||||
DEBUG(10,("reply_lockingX: unlock start=%.0f, len=%.0f for file %s\n",
|
||||
(double)offset, (double)count, fsp->fsp_name ));
|
||||
@ -3661,8 +3661,8 @@ dev = %x, inode = %.0f\n", fsp->fnum, (unsigned int)dev, (double)inode));
|
||||
offset = (((SMB_OFF_T) IVAL(data,SMB_LARGE_LKOFF_OFFSET_HIGH(i))) << 32) |
|
||||
((SMB_OFF_T) IVAL(data,SMB_LARGE_LKOFF_OFFSET_LOW(i)));
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* LARGE_SMB_OFF_T */
|
||||
|
||||
DEBUG(10,("reply_lockingX: lock start=%.0f, len=%.0f for file %s\n",
|
||||
(double)offset, (double)count, fsp->fsp_name ));
|
||||
|
||||
@ -3696,7 +3696,7 @@ dev = %x, inode = %.0f\n", fsp->fnum, (unsigned int)dev, (double)inode));
|
||||
offset = (((SMB_OFF_T) IVAL(data,SMB_LARGE_LKOFF_OFFSET_HIGH(i))) << 32) |
|
||||
((SMB_OFF_T) IVAL(data,SMB_LARGE_LKOFF_OFFSET_LOW(i)));
|
||||
}
|
||||
#endif
|
||||
#endif /* LARGE_SMB_OFF_T */
|
||||
|
||||
do_unlock(fsp,conn,count,offset,&dummy1,&dummy2);
|
||||
}
|
||||
|
@ -415,8 +415,8 @@ static int get_lanman2_dir_entry(connection_struct *conn,
|
||||
{
|
||||
case 1:
|
||||
if(requires_resume_key) {
|
||||
SIVAL(p,0,reskey);
|
||||
p += 4;
|
||||
SIVAL(p,0,reskey);
|
||||
p += 4;
|
||||
}
|
||||
put_dos_date2(p,l1_fdateCreation,cdate);
|
||||
put_dos_date2(p,l1_fdateLastAccess,adate);
|
||||
@ -433,8 +433,8 @@ static int get_lanman2_dir_entry(connection_struct *conn,
|
||||
case 2:
|
||||
/* info_level 2 */
|
||||
if(requires_resume_key) {
|
||||
SIVAL(p,0,reskey);
|
||||
p += 4;
|
||||
SIVAL(p,0,reskey);
|
||||
p += 4;
|
||||
}
|
||||
put_dos_date2(p,l2_fdateCreation,cdate);
|
||||
put_dos_date2(p,l2_fdateLastAccess,adate);
|
||||
@ -466,8 +466,8 @@ static int get_lanman2_dir_entry(connection_struct *conn,
|
||||
|
||||
case 4:
|
||||
if(requires_resume_key) {
|
||||
SIVAL(p,0,reskey);
|
||||
p += 4;
|
||||
SIVAL(p,0,reskey);
|
||||
p += 4;
|
||||
}
|
||||
SIVAL(p,0,33+strlen(fname)+1);
|
||||
put_dos_date2(p,4,cdate);
|
||||
@ -492,17 +492,22 @@ static int get_lanman2_dir_entry(connection_struct *conn,
|
||||
put_long_date(p,adate); p += 8;
|
||||
put_long_date(p,mdate); p += 8;
|
||||
put_long_date(p,mdate); p += 8;
|
||||
SIVAL(p,0,size); p += 8;
|
||||
SIVAL(p,0,size); p += 8;
|
||||
SIVAL(p,0,size);
|
||||
SIVAL(p,8,size);
|
||||
#ifdef LARGE_SMB_OFF_T
|
||||
SIVAL(p,4,size >> 32);
|
||||
SIVAL(p,12,size >> 32);
|
||||
#endif /* LARGE_SMB_OFF_T */
|
||||
p += 16;
|
||||
SIVAL(p,0,nt_extmode); p += 4;
|
||||
SIVAL(p,0,strlen(fname)); p += 4;
|
||||
SIVAL(p,0,0); p += 4;
|
||||
if (!was_8_3) {
|
||||
pstrcpy(p+2,fname);
|
||||
if (!name_map_mangle(p+2,True,SNUM(conn)))
|
||||
(p+2)[12] = 0;
|
||||
pstrcpy(p+2,fname);
|
||||
if (!name_map_mangle(p+2,True,SNUM(conn)))
|
||||
(p+2)[12] = 0;
|
||||
} else
|
||||
*(p+2) = 0;
|
||||
*(p+2) = 0;
|
||||
strupper(p+2);
|
||||
SSVAL(p,0,strlen(p+2));
|
||||
p += 2 + 24;
|
||||
@ -520,8 +525,13 @@ static int get_lanman2_dir_entry(connection_struct *conn,
|
||||
put_long_date(p,adate); p += 8;
|
||||
put_long_date(p,mdate); p += 8;
|
||||
put_long_date(p,mdate); p += 8;
|
||||
SIVAL(p,0,size); p += 8;
|
||||
SIVAL(p,0,size); p += 8;
|
||||
SIVAL(p,0,size);
|
||||
SIVAL(p,8,size);
|
||||
#ifdef LARGE_SMB_OFF_T
|
||||
SIVAL(p,4,size >> 32);
|
||||
SIVAL(p,12,size >> 32);
|
||||
#endif /* LARGE_SMB_OFF_T */
|
||||
p += 16;
|
||||
SIVAL(p,0,nt_extmode); p += 4;
|
||||
SIVAL(p,0,strlen(fname)); p += 4;
|
||||
pstrcpy(p,fname);
|
||||
@ -538,8 +548,13 @@ static int get_lanman2_dir_entry(connection_struct *conn,
|
||||
put_long_date(p,adate); p += 8;
|
||||
put_long_date(p,mdate); p += 8;
|
||||
put_long_date(p,mdate); p += 8;
|
||||
SIVAL(p,0,size); p += 8;
|
||||
SIVAL(p,0,size); p += 8;
|
||||
SIVAL(p,0,size);
|
||||
SIVAL(p,8,size);
|
||||
#ifdef LARGE_SMB_OFF_T
|
||||
SIVAL(p,4,size >> 32);
|
||||
SIVAL(p,12,size >> 32);
|
||||
#endif /* LARGE_SMB_OFF_T */
|
||||
p += 16;
|
||||
SIVAL(p,0,nt_extmode); p += 4;
|
||||
SIVAL(p,0,strlen(fname)); p += 4;
|
||||
SIVAL(p,0,0); p += 4;
|
||||
@ -1055,6 +1070,7 @@ resume_key = %d resume name = %s continue=%d level = %d\n",
|
||||
/****************************************************************************
|
||||
reply to a TRANS2_QFSINFO (query filesystem info)
|
||||
****************************************************************************/
|
||||
|
||||
static int call_trans2qfsinfo(connection_struct *conn,
|
||||
char *inbuf, char *outbuf,
|
||||
int length, int bufsize,
|
||||
@ -1329,6 +1345,10 @@ static int call_trans2qfilepathinfo(connection_struct *conn,
|
||||
data_size = 22;
|
||||
SIVAL(pdata,0,size);
|
||||
SIVAL(pdata,8,size);
|
||||
#ifdef LARGE_SMB_OFF_T
|
||||
SIVAL(pdata,4,size>>32);
|
||||
SIVAL(pdata,12,size>>32);
|
||||
#endif /* LARGE_SMB_OFF_T */
|
||||
SIVAL(pdata,16,sbuf.st_nlink);
|
||||
CVAL(pdata,20) = 0;
|
||||
CVAL(pdata,21) = (mode&aDIR)?1:0;
|
||||
@ -1367,6 +1387,9 @@ static int call_trans2qfilepathinfo(connection_struct *conn,
|
||||
case SMB_QUERY_FILE_END_OF_FILEINFO:
|
||||
data_size = 8;
|
||||
SIVAL(pdata,0,size);
|
||||
#ifdef LARGE_SMB_OFF_T
|
||||
SIVAL(pdata,4,size >> 32);
|
||||
#endif /* LARGE_SMB_OFF_T */
|
||||
break;
|
||||
|
||||
case SMB_QUERY_FILE_ALL_INFO:
|
||||
@ -1378,6 +1401,10 @@ static int call_trans2qfilepathinfo(connection_struct *conn,
|
||||
pdata += 40;
|
||||
SIVAL(pdata,0,size);
|
||||
SIVAL(pdata,8,size);
|
||||
#ifdef LARGE_SMB_OFF_T
|
||||
SIVAL(pdata,4,size >> 32);
|
||||
SIVAL(pdata,12,size >> 32);
|
||||
#endif /* LARGE_SMB_OFF_T */
|
||||
SIVAL(pdata,16,sbuf.st_nlink);
|
||||
CVAL(pdata,20) = 0;
|
||||
CVAL(pdata,21) = (mode&aDIR)?1:0;
|
||||
@ -1385,9 +1412,9 @@ static int call_trans2qfilepathinfo(connection_struct *conn,
|
||||
pdata += 8; /* index number */
|
||||
pdata += 4; /* EA info */
|
||||
if (mode & aRONLY)
|
||||
SIVAL(pdata,0,0xA9);
|
||||
SIVAL(pdata,0,0xA9);
|
||||
else
|
||||
SIVAL(pdata,0,0xd01BF);
|
||||
SIVAL(pdata,0,0xd01BF);
|
||||
pdata += 4;
|
||||
SIVAL(pdata,0,pos); /* current offset */
|
||||
pdata += 8;
|
||||
@ -1566,16 +1593,39 @@ static int call_trans2setfilepathinfo(connection_struct *conn,
|
||||
|
||||
case SMB_SET_FILE_END_OF_FILE_INFO:
|
||||
{
|
||||
size = IVAL(pdata,0);
|
||||
#ifdef LARGE_SMB_OFF_T
|
||||
size |= (((SMB_OFF_T)IVAL(pdata,4)) << 32);
|
||||
#else /* LARGE_SMB_OFF_T */
|
||||
if (IVAL(pdata,4) != 0) /* more than 32 bits? */
|
||||
return(ERROR(ERRDOS,ERRunknownlevel));
|
||||
size = IVAL(pdata,0);
|
||||
#endif /* LARGE_SMB_OFF_T */
|
||||
break;
|
||||
}
|
||||
|
||||
case SMB_SET_FILE_ALLOCATION_INFO:
|
||||
break; /* We don't need to do anything for this call. */
|
||||
|
||||
case SMB_SET_FILE_DISPOSITION_INFO: /* not supported yet */
|
||||
case SMB_SET_FILE_DISPOSITION_INFO: /* Set delete on close for open file. */
|
||||
{
|
||||
if (tran_call == TRANSACT2_SETFILEINFO) {
|
||||
files_struct *fsp = file_fsp(params,0);
|
||||
if(fsp->is_directory)
|
||||
return(ERROR(ERRDOS,ERRnoaccess));
|
||||
/*
|
||||
* TODO - check here is this means set
|
||||
* this flag bit on all open files that
|
||||
* reference this particular dev/inode pair.
|
||||
* If so we'll need to search the open
|
||||
* file entries here and set this flag on
|
||||
* all of them that match. JRA.
|
||||
*/
|
||||
fsp->delete_on_close = CVAL(pdata,0);
|
||||
} else
|
||||
return(ERROR(ERRDOS,ERRunknownlevel));
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
return(ERROR(ERRDOS,ERRunknownlevel));
|
||||
|
Loading…
Reference in New Issue
Block a user