Commit 84ebf85c authored by Steve French's avatar Steve French Committed by Steve French

Fix an incorrect mapping of open flags to cifs open disposition. Fix blocking...

Fix an incorrect mapping of open flags to cifs open disposition.  Fix blocking byte range locks.  These fix breakages that were notice running lock tests 1 and 7 of the connectathon posix file api tests
parent 9f6f16d0
...@@ -63,6 +63,7 @@ void mark_open_files_invalid(struct cifsTconInfo * pTcon) ...@@ -63,6 +63,7 @@ void mark_open_files_invalid(struct cifsTconInfo * pTcon)
} }
} }
write_unlock(&GlobalSMBSeslock); write_unlock(&GlobalSMBSeslock);
/* BB Add call to invalidate_inodes(sb) for all superblocks mounted to this tcon */
} }
int int
...@@ -746,7 +747,7 @@ CIFSSMBLock(const int xid, struct cifsTconInfo *tcon, ...@@ -746,7 +747,7 @@ CIFSSMBLock(const int xid, struct cifsTconInfo *tcon,
int timeout = 0; int timeout = 0;
__u64 temp; __u64 temp;
cFYI(1, ("In CIFSSMBLock")); cFYI(1, ("In CIFSSMBLock - timeout %d numLock %d",waitFlag,numLock));
rc = smb_init(SMB_COM_LOCKING_ANDX, 8, tcon, (void **) &pSMB, rc = smb_init(SMB_COM_LOCKING_ANDX, 8, tcon, (void **) &pSMB,
(void **) &pSMBr); (void **) &pSMBr);
if (rc) if (rc)
...@@ -758,6 +759,10 @@ CIFSSMBLock(const int xid, struct cifsTconInfo *tcon, ...@@ -758,6 +759,10 @@ CIFSSMBLock(const int xid, struct cifsTconInfo *tcon,
pSMB->NumberOfLocks = cpu_to_le32(numLock); pSMB->NumberOfLocks = cpu_to_le32(numLock);
pSMB->NumberOfUnlocks = cpu_to_le32(numUnlock); pSMB->NumberOfUnlocks = cpu_to_le32(numUnlock);
if(waitFlag)
pSMB->Timeout = 3; /* blocking - do time out */
else
pSMB->Timeout = 0;
pSMB->LockType = lockType; pSMB->LockType = lockType;
pSMB->AndXCommand = 0xFF; /* none */ pSMB->AndXCommand = 0xFF; /* none */
pSMB->Fid = smb_file_id; /* netfid stays le */ pSMB->Fid = smb_file_id; /* netfid stays le */
......
...@@ -147,7 +147,7 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode, ...@@ -147,7 +147,7 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
cFYI(1,("In create for inode %p dentry->inode %p nd flags = 0x%x for %s",inode, direntry->d_inode, nd->flags,full_path)); cFYI(1,("In create for inode %p dentry->inode %p nd flags = 0x%x for %s",inode, direntry->d_inode, nd->flags,full_path));
if ((nd->intent.open.flags & O_ACCMODE) == O_RDONLY) if ((nd->intent.open.flags & O_ACCMODE) == O_RDONLY)
desiredAccess = GENERIC_READ; desiredAccess = GENERIC_READ;
else if ((nd->intent.open.flags & O_ACCMODE) == O_WRONLY) else if ((nd->intent.open.flags & O_ACCMODE) == O_WRONLY)
desiredAccess = GENERIC_WRITE; desiredAccess = GENERIC_WRITE;
else if ((nd->intent.open.flags & O_ACCMODE) == O_RDWR) else if ((nd->intent.open.flags & O_ACCMODE) == O_RDWR)
...@@ -283,19 +283,19 @@ int cifs_mknod(struct inode *inode, struct dentry *direntry, int mode, dev_t dev ...@@ -283,19 +283,19 @@ int cifs_mknod(struct inode *inode, struct dentry *direntry, int mode, dev_t dev
full_path, mode, current->euid, current->egid, full_path, mode, current->euid, current->egid,
device_number, cifs_sb->local_nls); device_number, cifs_sb->local_nls);
if(!rc) { if(!rc) {
rc = cifs_get_inode_info_unix(&newinode, full_path, rc = cifs_get_inode_info_unix(&newinode, full_path,
inode->i_sb); inode->i_sb);
direntry->d_op = &cifs_dentry_ops; direntry->d_op = &cifs_dentry_ops;
if(rc == 0) if(rc == 0)
d_instantiate(direntry, newinode); d_instantiate(direntry, newinode);
} }
} }
if (full_path) if (full_path)
kfree(full_path); kfree(full_path);
FreeXid(xid); FreeXid(xid);
return rc; return rc;
} }
......
...@@ -47,7 +47,7 @@ cifs_open(struct inode *inode, struct file *file) ...@@ -47,7 +47,7 @@ cifs_open(struct inode *inode, struct file *file)
struct list_head * tmp; struct list_head * tmp;
char *full_path = NULL; char *full_path = NULL;
int desiredAccess = 0x20197; int desiredAccess = 0x20197;
int disposition = FILE_OPEN; int disposition;
__u16 netfid; __u16 netfid;
FILE_ALL_INFO * buf = NULL; FILE_ALL_INFO * buf = NULL;
...@@ -57,27 +57,27 @@ cifs_open(struct inode *inode, struct file *file) ...@@ -57,27 +57,27 @@ cifs_open(struct inode *inode, struct file *file)
pTcon = cifs_sb->tcon; pTcon = cifs_sb->tcon;
if (file->f_flags & O_CREAT) { if (file->f_flags & O_CREAT) {
/* search inode for this file and fill in file->private_data = */ /* search inode for this file and fill in file->private_data = */
pCifsInode = CIFS_I(file->f_dentry->d_inode); pCifsInode = CIFS_I(file->f_dentry->d_inode);
read_lock(&GlobalSMBSeslock); read_lock(&GlobalSMBSeslock);
list_for_each(tmp, &pCifsInode->openFileList) { list_for_each(tmp, &pCifsInode->openFileList) {
pCifsFile = list_entry(tmp,struct cifsFileInfo, flist); pCifsFile = list_entry(tmp,struct cifsFileInfo, flist);
if((pCifsFile->pfile == NULL)&& (pCifsFile->pid = current->pid)){ if((pCifsFile->pfile == NULL)&& (pCifsFile->pid = current->pid)){
/* set mode ?? */ /* set mode ?? */
pCifsFile->pfile = file; /* needed for writepage */ pCifsFile->pfile = file; /* needed for writepage */
file->private_data = pCifsFile; file->private_data = pCifsFile;
break; break;
}
}
read_unlock(&GlobalSMBSeslock);
if(file->private_data != NULL) {
rc = 0;
FreeXid(xid);
return rc;
} else {
if(file->f_flags & O_EXCL)
cERROR(1,("could not find file instance for new file %p ",file));
} }
}
read_unlock(&GlobalSMBSeslock);
if(file->private_data != NULL) {
rc = 0;
FreeXid(xid);
return rc;
} else {
if(file->f_flags & O_EXCL)
cERROR(1,("could not find file instance for new file %p ",file));
}
} }
full_path = build_path_from_dentry(file->f_dentry); full_path = build_path_from_dentry(file->f_dentry);
...@@ -90,26 +90,38 @@ cifs_open(struct inode *inode, struct file *file) ...@@ -90,26 +90,38 @@ cifs_open(struct inode *inode, struct file *file)
else if ((file->f_flags & O_ACCMODE) == O_RDWR) else if ((file->f_flags & O_ACCMODE) == O_RDWR)
desiredAccess = GENERIC_ALL; desiredAccess = GENERIC_ALL;
/* BB check other flags carefully to find equivalent NTCreateX flags */ /*********************************************************************
* open flag mapping table:
/* *
#define O_CREAT 0100 * POSIX Flag CIFS Disposition
#define O_EXCL 0200 * ---------- ----------------
#define O_NOCTTY 0400 * O_CREAT FILE_OPEN_IF
#define O_TRUNC 01000 * O_CREAT | O_EXCL FILE_CREATE
#define O_APPEND 02000 * O_CREAT | O_TRUNC FILE_OVERWRITE_IF
#define O_NONBLOCK 04000 * O_TRUNC FILE_OVERWRITE
#define O_NDELAY O_NONBLOCK * none of the above FILE_OPEN
#define O_SYNC 010000 *
#define FASYNC 020000 * Note that there is not a direct match between disposition
#define O_DIRECT 040000 * FILE_SUPERSEDE (ie create whether or not file exists although
#define O_LARGEFILE 0100000 * O_CREAT | O_TRUNC is similar but truncates the existing
#define O_DIRECTORY 0200000 * file rather than creating a new file as FILE_SUPERSEDE does
#define O_NOFOLLOW 0400000 * (which uses the attributes / metadata passed in on open call)
#define O_ATOMICLOOKUP 01000000 */ *?
*? O_SYNC is a reasonable match to CIFS writethrough flag
if (file->f_flags & O_CREAT) *? and the read write flags match reasonably. O_LARGEFILE
disposition = FILE_OVERWRITE; *? is irrelevant because largefile support is always used
*? by this client. Flags O_APPEND, O_DIRECT, O_DIRECTORY,
* O_FASYNC, O_NOFOLLOW, O_NONBLOCK need further investigation
*********************************************************************/
if((file->f_flags & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL))
disposition = FILE_CREATE;
else if((file->f_flags & (O_CREAT | O_TRUNC)) == (O_CREAT | O_TRUNC))
disposition = FILE_OVERWRITE_IF;
else if((file->f_flags & O_CREAT) == O_CREAT)
disposition = FILE_OPEN_IF;
else
disposition = FILE_OPEN;
if (oplockEnabled) if (oplockEnabled)
oplock = REQ_OPLOCK; oplock = REQ_OPLOCK;
...@@ -121,7 +133,7 @@ cifs_open(struct inode *inode, struct file *file) ...@@ -121,7 +133,7 @@ cifs_open(struct inode *inode, struct file *file)
/* Also refresh inode by passing in file_info buf returned by SMBOpen /* Also refresh inode by passing in file_info buf returned by SMBOpen
and calling get_inode_info with returned buf (at least and calling get_inode_info with returned buf (at least
helps non-Unix server case */ helps non-Unix server case */
buf = kmalloc(sizeof(FILE_ALL_INFO),GFP_KERNEL); buf = kmalloc(sizeof(FILE_ALL_INFO),GFP_KERNEL);
if(buf==0) { if(buf==0) {
if (full_path) if (full_path)
kfree(full_path); kfree(full_path);
...@@ -390,6 +402,7 @@ cifs_lock(struct file *file, int cmd, struct file_lock *pfLock) ...@@ -390,6 +402,7 @@ cifs_lock(struct file *file, int cmd, struct file_lock *pfLock)
__u32 numLock = 0; __u32 numLock = 0;
__u32 numUnlock = 0; __u32 numUnlock = 0;
__u64 length; __u64 length;
int wait_flag = FALSE;
struct cifs_sb_info *cifs_sb; struct cifs_sb_info *cifs_sb;
struct cifsTconInfo *pTcon; struct cifsTconInfo *pTcon;
length = 1 + pfLock->fl_end - pfLock->fl_start; length = 1 + pfLock->fl_end - pfLock->fl_start;
...@@ -407,14 +420,16 @@ cifs_lock(struct file *file, int cmd, struct file_lock *pfLock) ...@@ -407,14 +420,16 @@ cifs_lock(struct file *file, int cmd, struct file_lock *pfLock)
cFYI(1, ("Posix ")); cFYI(1, ("Posix "));
if (pfLock->fl_flags & FL_FLOCK) if (pfLock->fl_flags & FL_FLOCK)
cFYI(1, ("Flock ")); cFYI(1, ("Flock "));
if (pfLock->fl_flags & FL_SLEEP) if (pfLock->fl_flags & FL_SLEEP) {
cFYI(1, ("Blocking lock ")); cFYI(1, ("Blocking lock "));
wait_flag = TRUE;
}
if (pfLock->fl_flags & FL_ACCESS) if (pfLock->fl_flags & FL_ACCESS)
cFYI(1, ("Process suspended by mandatory locking ")); cFYI(1, ("Process suspended by mandatory locking - not implemented yet "));
if (pfLock->fl_flags & FL_LEASE) if (pfLock->fl_flags & FL_LEASE)
cFYI(1, ("Lease on file ")); cFYI(1, ("Lease on file - not implemented yet"));
if (pfLock->fl_flags & 0xFFD0) if (pfLock->fl_flags & (~(FL_POSIX | FL_FLOCK | FL_SLEEP | FL_ACCESS | FL_LEASE)))
cFYI(1, ("Unknown lock flags ")); cFYI(1, ("Unknown lock flags 0x%x",pfLock->fl_flags));
if (pfLock->fl_type == F_WRLCK) { if (pfLock->fl_type == F_WRLCK) {
cFYI(1, ("F_WRLCK ")); cFYI(1, ("F_WRLCK "));
...@@ -462,7 +477,7 @@ cifs_lock(struct file *file, int cmd, struct file_lock *pfLock) ...@@ -462,7 +477,7 @@ cifs_lock(struct file *file, int cmd, struct file_lock *pfLock)
pfLock->fl_type = F_UNLCK; pfLock->fl_type = F_UNLCK;
if (rc != 0) if (rc != 0)
cERROR(1, cERROR(1,
("Error unlocking previously locked range %d during test of lock ", ("Error unlocking previously locked range %d during test of lock ",
rc)); rc));
rc = 0; rc = 0;
...@@ -479,7 +494,7 @@ cifs_lock(struct file *file, int cmd, struct file_lock *pfLock) ...@@ -479,7 +494,7 @@ cifs_lock(struct file *file, int cmd, struct file_lock *pfLock)
((struct cifsFileInfo *) file->private_data)-> ((struct cifsFileInfo *) file->private_data)->
netfid, length, netfid, length,
pfLock->fl_start, numUnlock, numLock, lockType, pfLock->fl_start, numUnlock, numLock, lockType,
0 /* wait flag */ ); wait_flag);
FreeXid(xid); FreeXid(xid);
return rc; return rc;
} }
......
...@@ -222,12 +222,14 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses, ...@@ -222,12 +222,14 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses,
up(&ses->server->tcpSem); up(&ses->server->tcpSem);
if (long_op == -1) if (long_op == -1)
goto cifs_no_response_exit; goto cifs_no_response_exit;
if (long_op > 1) /* writes past end of file can take looooong time */ else if (long_op == 2) /* writes past end of file can take looooong time */
timeout = 300 * HZ; timeout = 300 * HZ;
else if (long_op == 1) else if (long_op == 1)
timeout = 45 * HZ; /* should be greater than timeout = 45 * HZ; /* should be greater than
servers oplock break timeout (about 43 seconds) */ servers oplock break timeout (about 43 seconds) */
else else if (long_op > 2) {
timeout = MAX_SCHEDULE_TIMEOUT;
} else
timeout = 15 * HZ; timeout = 15 * HZ;
/* wait for 15 seconds or until woken up due to response arriving or /* wait for 15 seconds or until woken up due to response arriving or
due to last connection to this server being unmounted */ due to last connection to this server being unmounted */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment