]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
[CIFS] Fix oops in cifs_unlink. Caused in some cases when renaming over existing,
authorSteve French <stevef@stevef95>
Tue, 17 May 2005 18:16:18 +0000 (13:16 -0500)
committerSteve French <stevef@stevef95>
Tue, 17 May 2005 18:16:18 +0000 (13:16 -0500)
newly created, file.

Samba bugzilla: 2697

Signed-off-by: Steve French (sfrench@us.ibm.com)
fs/cifs/dir.c
fs/cifs/inode.c

index e3137aa48cdd6a4f4dbc5df53f03deab774f84ee..3f3538d4a1fad105c0a776ef5f6d6e18fef0ff6c 100644 (file)
@@ -392,7 +392,8 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry, struct name
                rc = 0;
                d_add(direntry, NULL);
        } else {
-               cERROR(1,("Error 0x%x or on cifs_get_inode_info in lookup",rc));
+               cERROR(1,("Error 0x%x on cifs_get_inode_info in lookup of %s",
+                          rc,full_path));
                /* BB special case check for Access Denied - watch security 
                exposure of returning dir info implicitly via different rc 
                if file exists or not but no access BB */
index 670947288262c099a0f32ecffd3e4ca110ad9eb4..b8b78cbb34c97f304a1b5ac9f03b773f7d1073f5 100644 (file)
@@ -422,7 +422,8 @@ int cifs_unlink(struct inode *inode, struct dentry *direntry)
                        cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
 
        if (!rc) {
-               direntry->d_inode->i_nlink--;
+               if(direntry->d_inode)
+                       direntry->d_inode->i_nlink--;
        } else if (rc == -ENOENT) {
                d_drop(direntry);
        } else if (rc == -ETXTBSY) {
@@ -440,7 +441,8 @@ int cifs_unlink(struct inode *inode, struct dentry *direntry)
                                              cifs_sb->mnt_cifs_flags & 
                                                CIFS_MOUNT_MAP_SPECIAL_CHR);
                        CIFSSMBClose(xid, pTcon, netfid);
-                       direntry->d_inode->i_nlink--;
+                       if(direntry->d_inode)
+                               direntry->d_inode->i_nlink--;
                }
        } else if (rc == -EACCES) {
                /* try only if r/o attribute set in local lookup data? */
@@ -494,7 +496,8 @@ int cifs_unlink(struct inode *inode, struct dentry *direntry)
                                            cifs_sb->mnt_cifs_flags & 
                                                CIFS_MOUNT_MAP_SPECIAL_CHR);
                        if (!rc) {
-                               direntry->d_inode->i_nlink--;
+                               if(direntry->d_inode)
+                                       direntry->d_inode->i_nlink--;
                        } else if (rc == -ETXTBSY) {
                                int oplock = FALSE;
                                __u16 netfid;
@@ -514,17 +517,20 @@ int cifs_unlink(struct inode *inode, struct dentry *direntry)
                                                cifs_sb->mnt_cifs_flags &
                                                    CIFS_MOUNT_MAP_SPECIAL_CHR);
                                        CIFSSMBClose(xid, pTcon, netfid);
-                                       direntry->d_inode->i_nlink--;
+                                       if(direntry->d_inode)
+                                               direntry->d_inode->i_nlink--;
                                }
                        /* BB if rc = -ETXTBUSY goto the rename logic BB */
                        }
                }
        }
-       cifsInode = CIFS_I(direntry->d_inode);
-       cifsInode->time = 0;    /* will force revalidate to get info when
-                                  needed */
-       direntry->d_inode->i_ctime = inode->i_ctime = inode->i_mtime =
-               current_fs_time(inode->i_sb);
+       if(direntry->d_inode) {
+               cifsInode = CIFS_I(direntry->d_inode);
+               cifsInode->time = 0;    /* will force revalidate to get info
+                                          when needed */
+               direntry->d_inode->i_ctime = current_fs_time(inode->i_sb);
+       }
+       inode->i_ctime = inode->i_mtime = current_fs_time(inode->i_sb);
        cifsInode = CIFS_I(inode);
        cifsInode->time = 0;    /* force revalidate of dir as well */