+Version 0.68
+------------
+Fix search handle leak on rewind. Fix setuid and gid so that they are
+reflected in the local inode immediately. Cleanup of whitespace
+to make 2.4 and 2.5 versions more consistent.
+
+
Version 0.67
------------
Fix signal sending so that captive thread (cifsd) exits on umount
(which was causing the warning in kmem_cache_free of the request buffers
at rmmod time). This had broken as a sideeffect of the recent global
-kernel change to daemonize
+kernel change to daemonize. Fix memory leak in readdir code which
+showed up in "ls -R" (and applications that did search rewinding).
Version 0.66
------------
unsigned int sign_CIFS_PDUs = 0;
extern int cifs_mount(struct super_block *, struct cifs_sb_info *, char *,
- char *);
+ char *);
extern int cifs_umount(struct super_block *, struct cifs_sb_info *);
void cifs_proc_init(void);
void cifs_proc_clean(void);
cifs_inode->cifsAttrs = 0x20; /* default */
atomic_set(&cifs_inode->inUse, 0);
cifs_inode->time = 0;
- if(oplockEnabled)
- cifs_inode->clientCanCacheAll = 1;
+ if(oplockEnabled) {
+ cifs_inode->clientCanCacheRead = 1;
+ cifs_inode->clientCanCacheAll = 1;
+ }
INIT_LIST_HEAD(&cifs_inode->openFileList);
return &cifs_inode->vfs_inode;
}
printk(KERN_WARNING "CIFS: Unknown mount option %s\n",data);
}
if (vol->UNC == NULL) {
+ if(devname == NULL) {
+ printk(KERN_WARNING "CIFS: Missing UNC name for mount target\n");
+ return 1;
+ }
if (strnlen(devname, 300) < 300) {
vol->UNC = devname;
if (strncmp(vol->UNC, "//", 2) == 0) {
if (ses) {
set_current_state(TASK_INTERRUPTIBLE);
schedule_timeout(HZ / 2);
- /* if ((ses->server) && (ses->server->ssocket)) {
- cFYI(1,("Releasing socket "));
- sock_release(ses->server->ssocket);
- kfree(ses->server);
- } */
}
if (ses)
sesInfoFree(ses);
file->f_pos++;
/* fallthrough */
case 2:
- /* Should we first check if file->private_data is null? */
- rc = CIFSFindFirst(xid, pTcon, full_path, pfindData,
+ /* do not reallocate search handle if rewind */
+ if(file->private_data == NULL) {
+ rc = CIFSFindFirst(xid, pTcon, full_path, pfindData,
&findParms, cifs_sb->local_nls,
&Unicode, &UnixSearch);
- cFYI(1,
- ("Count: %d End: %d ", findParms.SearchCount,
- findParms.EndofSearch));
+ cFYI(1,
+ ("Count: %d End: %d ", findParms.SearchCount,
+ findParms.EndofSearch));
+ } else {
+ cFYI(1,("Search rewinding on %s",full_path));
+ goto readdir_rewind;
+ }
if (rc == 0) {
searchHandle = findParms.SearchHandle;
- file->private_data =
- kmalloc(sizeof (struct cifsFileInfo), GFP_KERNEL);
+ if(file->private_data == NULL)
+ file->private_data =
+ kmalloc(sizeof(struct cifsFileInfo),
+ GFP_KERNEL);
+ else {
+ /* BB close search handle */
+ cFYI(1,("Search rewinding on %s",full_path));
+ }
if (file->private_data) {
memset(file->private_data, 0,
sizeof (struct cifsFileInfo));
rc = 0; /* unless parent directory disappeared - do not return error here (eg Access Denied or no more files) */
}
break;
+readdir_rewind:
default:
+ /* BB rewrite eventually to better handle rewind */
if (file->private_data == NULL) {
rc = -EBADF;
cFYI(1,
/* get new inode */
if (*pinode == NULL) {
*pinode = new_inode(sb);
- cFYI(1, (" Alloc new inode %p ", *pinode));
}
inode = *pinode;
-/* new_inode = iget(parent_dir_inode->i_sb, findData.IndexNumber); */
- /* index number not reliable in response data */
cifsInfo = CIFS_I(inode);
/* get new inode */
if (*pinode == NULL) {
*pinode = new_inode(sb);
- cFYI(1, (" Alloc new inode %p ", *pinode));
}
inode = *pinode;
if (pTcon != cifs_sb_target->tcon) {
return -EXDEV; /* BB actually could be allowed if same server, but
different share. Might eventually add support for this */
- FreeXid(xid);
- }
+ FreeXid(xid);
+ }
fromName = build_path_from_dentry(source_direntry);
toName = build_path_from_dentry(target_direntry);
if (time_before(jiffies, cifsInode->time + HZ)) {
if((S_ISREG(direntry->d_inode->i_mode) == 0) ||
- (direntry->d_inode->i_nlink == 1)) {
+ (direntry->d_inode->i_nlink == 1)) {
if (full_path)
kfree(full_path);
FreeXid(xid);
if ((cifs_sb->tcon->ses->capabilities & CAP_UNIX)
&& (attrs->ia_valid & (ATTR_MODE | ATTR_GID | ATTR_UID)))
- CIFSSMBUnixSetPerms(xid, pTcon, full_path, mode, uid, gid,
+ rc = CIFSSMBUnixSetPerms(xid, pTcon, full_path, mode, uid, gid,
cifs_sb->local_nls);
else { /* BB to be implemented - via Windows security descriptors */
/* CIFSSMBWinSetPerms(xid,pTcon,full_path,mode,uid,gid,cifs_sb->local_nls);*/
rc = CIFSSMBSetTimes(xid, pTcon, full_path, &time_buf,
cifs_sb->local_nls);
}
-/* cifsInode->time = 0; */ /* force revalidate to get attributes when needed */
+ /* do not need local check to inode_check_ok since the server does that */
+ inode_setattr(direntry->d_inode, attrs);
if (full_path)
kfree(full_path);
FreeXid(xid);