Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 26140
b: refs/heads/master
c: 6080823
h: refs/heads/master
v: v3
  • Loading branch information
Steve French committed Apr 22, 2006
1 parent 11a8431 commit 97afd1d
Show file tree
Hide file tree
Showing 8 changed files with 75 additions and 37 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 45af7a0f2ebad1304cab956e15f0b37318226fcd
refs/heads/master: 60808233f374aebba26488d06a5f25443f6763c3
6 changes: 5 additions & 1 deletion trunk/fs/cifs/CHANGES
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
Version 1.42
------------
Fix slow oplock break when mounted to different servers at the same time and
the tids match and we try to find matching fid on wrong server.
the tids match and we try to find matching fid on wrong server. Fix read
looping when signing required by server (2.6.16 kernel only). Fix readdir
vs. rename race which could cause each to hang. Return . and .. even
if server does not. Allow searches to skip first three entries and
begin at any location. Fix oops in find_writeable_file.

Version 1.41
------------
Expand Down
8 changes: 8 additions & 0 deletions trunk/fs/cifs/README
Original file line number Diff line number Diff line change
Expand Up @@ -511,6 +511,14 @@ LinuxExtensionsEnabled If set to one then the client will attempt to
support and want to map the uid and gid fields
to values supplied at mount (rather than the
actual values, then set this to zero. (default 1)
Experimental When set to 1 used to enable certain experimental
features (currently enables multipage writes
when signing is enabled, the multipage write
performance enhancement was disabled when
signing turned on in case buffer was modified
just before it was sent, also this flag will
be used to use the new experimental sessionsetup
code).

These experimental features and tracing can be enabled by changing flags in
/proc/fs/cifs (after the cifs module has been installed or built into the
Expand Down
2 changes: 1 addition & 1 deletion trunk/fs/cifs/cifssmb.c
Original file line number Diff line number Diff line change
Expand Up @@ -3119,7 +3119,7 @@ CIFSFindFirst(const int xid, struct cifsTconInfo *tcon,
psrch_inf->endOfSearch = FALSE;

psrch_inf->entries_in_buffer = le16_to_cpu(parms->SearchCount);
psrch_inf->index_of_last_entry =
psrch_inf->index_of_last_entry = 2 /* skip . and .. */ +
psrch_inf->entries_in_buffer;
*pnetfid = parms->SearchHandle;
} else {
Expand Down
5 changes: 4 additions & 1 deletion trunk/fs/cifs/connect.c
Original file line number Diff line number Diff line change
Expand Up @@ -3447,7 +3447,10 @@ int cifs_setup_session(unsigned int xid, struct cifsSesInfo *pSesInfo,
pSesInfo->server->secMode,
pSesInfo->server->capabilities,
pSesInfo->server->timeZone));
if (extended_security
if(experimEnabled > 1)
rc = CIFS_SessSetup(xid, pSesInfo, CIFS_NTLM /* type */,
&ntlmv2_flag, nls_info);
else if (extended_security
&& (pSesInfo->capabilities & CAP_EXTENDED_SECURITY)
&& (pSesInfo->server->secType == NTLMSSP)) {
cFYI(1, ("New style sesssetup"));
Expand Down
32 changes: 20 additions & 12 deletions trunk/fs/cifs/file.c
Original file line number Diff line number Diff line change
Expand Up @@ -904,8 +904,7 @@ static ssize_t cifs_write(struct file *file, const char *write_data,
if (rc != 0)
break;
}
/* BB FIXME We can not sign across two buffers yet */
if((pTcon->ses->server->secMode &
if(experimEnabled || (pTcon->ses->server->secMode &
(SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) == 0) {
struct kvec iov[2];
unsigned int len;
Expand All @@ -921,13 +920,13 @@ static ssize_t cifs_write(struct file *file, const char *write_data,
*poffset, &bytes_written,
iov, 1, long_op);
} else
/* BB FIXME fixup indentation of line below */
rc = CIFSSMBWrite(xid, pTcon,
open_file->netfid,
min_t(const int, cifs_sb->wsize,
write_size - total_written),
*poffset, &bytes_written,
write_data + total_written, NULL, long_op);
rc = CIFSSMBWrite(xid, pTcon,
open_file->netfid,
min_t(const int, cifs_sb->wsize,
write_size - total_written),
*poffset, &bytes_written,
write_data + total_written,
NULL, long_op);
}
if (rc || (bytes_written == 0)) {
if (total_written)
Expand Down Expand Up @@ -966,6 +965,16 @@ struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *cifs_inode)
struct cifsFileInfo *open_file;
int rc;

/* Having a null inode here (because mapping->host was set to zero by
the VFS or MM) should not happen but we had reports of on oops (due to
it being zero) during stress testcases so we need to check for it */

if(cifs_inode == NULL) {
cERROR(1,("Null inode passed to cifs_writeable_file"));
dump_stack();
return NULL;
}

read_lock(&GlobalSMBSeslock);
list_for_each_entry(open_file, &cifs_inode->openFileList, flist) {
if (open_file->closePend)
Expand Down Expand Up @@ -1091,12 +1100,11 @@ static int cifs_writepages(struct address_space *mapping,
if (cifs_sb->wsize < PAGE_CACHE_SIZE)
return generic_writepages(mapping, wbc);

/* BB FIXME we do not have code to sign across multiple buffers yet,
so go to older writepage style write which we can sign if needed */
if((cifs_sb->tcon->ses) && (cifs_sb->tcon->ses->server))
if(cifs_sb->tcon->ses->server->secMode &
(SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
return generic_writepages(mapping, wbc);
if(!experimEnabled)
return generic_writepages(mapping, wbc);

/*
* BB: Is this meaningful for a non-block-device file system?
Expand Down
14 changes: 14 additions & 0 deletions trunk/fs/cifs/ntlmssp.c
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,20 @@ CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses, const int type,
}


/* copy session key */

/* if Unicode, align strings to two byte boundary */

/* copy user name */ /* BB Do we need to special case null user name? */

/* copy domain name */

/* copy Linux version */

/* copy network operating system name */

/* update bcc and smb buffer length */

/* rc = SendReceive2(xid, ses, iov, num_iovecs, &resp_buf_type, 0); */
/* SMB request buf freed in SendReceive2 */

Expand Down
43 changes: 22 additions & 21 deletions trunk/fs/cifs/readdir.c
Original file line number Diff line number Diff line change
Expand Up @@ -590,6 +590,13 @@ static int find_cifs_entry(const int xid, struct cifsTconInfo *pTcon,
first_entry_in_buffer =
cifsFile->srch_inf.index_of_last_entry -
cifsFile->srch_inf.entries_in_buffer;

/* if first entry in buf is zero then is first buffer
in search response data which means it is likely . and ..
will be in this buffer, although some servers do not return
. and .. for the root of a drive and for those we need
to start two entries earlier */

/* dump_cifs_file_struct(file, "In fce ");*/
if(((index_to_find < cifsFile->srch_inf.index_of_last_entry) &&
is_dir_changed(file)) ||
Expand Down Expand Up @@ -632,23 +639,14 @@ static int find_cifs_entry(const int xid, struct cifsTconInfo *pTcon,
char * end_of_smb = cifsFile->srch_inf.ntwrk_buf_start +
smbCalcSize((struct smb_hdr *)
cifsFile->srch_inf.ntwrk_buf_start);

current_entry = cifsFile->srch_inf.srch_entries_start;
first_entry_in_buffer = cifsFile->srch_inf.index_of_last_entry
- cifsFile->srch_inf.entries_in_buffer;
pos_in_buf = index_to_find - first_entry_in_buffer;
cFYI(1,("found entry - pos_in_buf %d",pos_in_buf));
current_entry = cifsFile->srch_inf.srch_entries_start;
for(i=0;(i<(pos_in_buf)) && (current_entry != NULL);i++) {
/* go entry by entry figuring out which is first */
/* if( . or ..)
skip */
rc = cifs_entry_is_dot(current_entry,cifsFile);
if(rc == 1) /* is . or .. so skip */ {
cFYI(1,("Entry is .")); /* BB removeme BB */
/* continue; */
} else if (rc == 2 ) {
cFYI(1,("Entry is ..")); /* BB removeme BB */
/* continue; */
}
current_entry = nxt_dir_entry(current_entry,end_of_smb);
}
if((current_entry == NULL) && (i < pos_in_buf)) {
Expand Down Expand Up @@ -768,6 +766,11 @@ static int cifs_filldir(char *pfindEntry, struct file *file,
if(file->f_dentry == NULL)
return -ENOENT;

rc = cifs_entry_is_dot(pfindEntry,cifsF);
/* skip . and .. since we added them first */
if(rc != 0)
return 0;

cifs_sb = CIFS_SB(file->f_dentry->d_sb);

qstring.name = scratch_buf;
Expand Down Expand Up @@ -896,22 +899,22 @@ int cifs_readdir(struct file *file, void *direntry, filldir_t filldir)

switch ((int) file->f_pos) {
case 0:
/*if (filldir(direntry, ".", 1, file->f_pos,
if (filldir(direntry, ".", 1, file->f_pos,
file->f_dentry->d_inode->i_ino, DT_DIR) < 0) {
cERROR(1, ("Filldir for current dir failed "));
cERROR(1, ("Filldir for current dir failed"));
rc = -ENOMEM;
break;
}
file->f_pos++; */
file->f_pos++;
case 1:
/* if (filldir(direntry, "..", 2, file->f_pos,
if (filldir(direntry, "..", 2, file->f_pos,
file->f_dentry->d_parent->d_inode->i_ino, DT_DIR) < 0) {
cERROR(1, ("Filldir for parent dir failed "));
rc = -ENOMEM;
break;
}
file->f_pos++; */
case 2:
file->f_pos++;
default:
/* 1) If search is active,
is in current search buffer?
if it before then restart search
Expand All @@ -925,7 +928,6 @@ int cifs_readdir(struct file *file, void *direntry, filldir_t filldir)
return rc;
}
}
default:
if(file->private_data == NULL) {
rc = -EINVAL;
FreeXid(xid);
Expand All @@ -945,8 +947,6 @@ int cifs_readdir(struct file *file, void *direntry, filldir_t filldir)
kfree(cifsFile->search_resume_name);
cifsFile->search_resume_name = NULL; */

/* BB account for . and .. in f_pos as special case */

rc = find_cifs_entry(xid,pTcon, file,
&current_entry,&num_to_fill);
if(rc) {
Expand Down Expand Up @@ -975,7 +975,8 @@ int cifs_readdir(struct file *file, void *direntry, filldir_t filldir)
num_to_fill, i));
break;
}

/* if buggy server returns . and .. late do
we want to check for that here? */
rc = cifs_filldir(current_entry, file,
filldir, direntry,tmp_buf);
file->f_pos++;
Expand Down

0 comments on commit 97afd1d

Please sign in to comment.