]> git.hungrycats.org Git - linux/commitdiff
Fix search handle leak on search rewind. Fix setting of uid
authorSteve French <stevef@steveft21.ltcsamba>
Sun, 23 Feb 2003 10:24:04 +0000 (04:24 -0600)
committerSteve French <stevef@steveft21.ltcsamba>
Sun, 23 Feb 2003 10:24:04 +0000 (04:24 -0600)
and gid in local inode (not just remote)

fs/cifs/CHANGES
fs/cifs/cifsfs.c
fs/cifs/connect.c
fs/cifs/file.c
fs/cifs/inode.c

index 5370e00efb6ffeff7fd8f46135d375ac1ebe2be7..b3a48c838e531b59ec5a8e9922807e9b495781eb 100644 (file)
@@ -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
 ------------
index f34a321377a2d2e9dd100d8ed06b8ce0258effdb..08eb846e5d32fe36bd4fa7d84f1ffb0d873c1a02 100644 (file)
@@ -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;
 }
index 38e936e22c5372e984523fb06ff37d10c2c35873..6b80297ab2d2f9ad35bdf376992685bf46c590a8 100644 (file)
@@ -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);
index f1707d470700a6a48044191693d2666ddb14635f..20f7cefc148fc939c354121171f28d160b5bc5a2 100644 (file)
@@ -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,
index 79a0cbf32dcfaece620dcd2aae4ee79a363aa893..e7b7cb76ca0de8948f4a082a781ed97db366c95a 100644 (file)
@@ -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);