From 4659e8f4a1dc716013e5737b7f997f42cfac81d7 Mon Sep 17 00:00:00 2001 From: Steve French Date: Sun, 23 Feb 2003 04:24:04 -0600 Subject: [PATCH] Fix search handle leak on search rewind. Fix setting of uid and gid in local inode (not just remote) --- fs/cifs/CHANGES | 10 +++++++++- fs/cifs/cifsfs.c | 8 +++++--- fs/cifs/connect.c | 9 ++++----- fs/cifs/file.c | 27 ++++++++++++++++++++------- fs/cifs/inode.c | 15 ++++++--------- 5 files changed, 44 insertions(+), 25 deletions(-) diff --git a/fs/cifs/CHANGES b/fs/cifs/CHANGES index 5370e00efb6ff..b3a48c838e531 100644 --- a/fs/cifs/CHANGES +++ b/fs/cifs/CHANGES @@ -1,9 +1,17 @@ +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 ------------ diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c index f34a321377a2d..08eb846e5d32f 100644 --- a/fs/cifs/cifsfs.c +++ b/fs/cifs/cifsfs.c @@ -54,7 +54,7 @@ unsigned int ntlmv2_support = 0; 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); @@ -178,8 +178,10 @@ cifs_alloc_inode(struct super_block *sb) 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; } diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index 38e936e22c537..6b80297ab2d2f 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c @@ -445,6 +445,10 @@ parse_mount_options(char *options, char *devname, struct smb_vol *vol) 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) { @@ -2288,11 +2292,6 @@ cifs_umount(struct super_block *sb, struct cifs_sb_info *cifs_sb) 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); diff --git a/fs/cifs/file.c b/fs/cifs/file.c index f1707d470700a..20f7cefc148fc 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c @@ -1091,18 +1091,29 @@ cifs_readdir(struct file *file, void *direntry, filldir_t filldir) 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)); @@ -1186,7 +1197,9 @@ cifs_readdir(struct file *file, void *direntry, filldir_t filldir) 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, diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c index 79a0cbf32dcfa..e7b7cb76ca0de 100644 --- a/fs/cifs/inode.c +++ b/fs/cifs/inode.c @@ -86,11 +86,8 @@ cifs_get_inode_info_unix(struct inode **pinode, /* 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); @@ -215,7 +212,6 @@ cifs_get_inode_info(struct inode **pinode, /* get new inode */ if (*pinode == NULL) { *pinode = new_inode(sb); - cFYI(1, (" Alloc new inode %p ", *pinode)); } inode = *pinode; @@ -457,8 +453,8 @@ cifs_rename(struct inode *source_inode, struct dentry *source_direntry, 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); @@ -504,7 +500,7 @@ cifs_revalidate(struct dentry *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); @@ -665,7 +661,7 @@ cifs_setattr(struct dentry *direntry, struct iattr *attrs) 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);*/ @@ -702,8 +698,9 @@ cifs_setattr(struct dentry *direntry, struct iattr *attrs) 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); -- 2.53.0