[CIFS] Fix oops in cifs_unlink. Caused in some cases when renaming over existing, newly created, file.

Samba bugzilla: 2697

Signed-off-by: Steve French (sfrench@us.ibm.com)

+17 -10
+2 -1
fs/cifs/dir.c
··· 392 rc = 0; 393 d_add(direntry, NULL); 394 } else { 395 - cERROR(1,("Error 0x%x or on cifs_get_inode_info in lookup",rc)); 396 /* BB special case check for Access Denied - watch security 397 exposure of returning dir info implicitly via different rc 398 if file exists or not but no access BB */
··· 392 rc = 0; 393 d_add(direntry, NULL); 394 } else { 395 + cERROR(1,("Error 0x%x on cifs_get_inode_info in lookup of %s", 396 + rc,full_path)); 397 /* BB special case check for Access Denied - watch security 398 exposure of returning dir info implicitly via different rc 399 if file exists or not but no access BB */
+15 -9
fs/cifs/inode.c
··· 422 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); 423 424 if (!rc) { 425 - direntry->d_inode->i_nlink--; 426 } else if (rc == -ENOENT) { 427 d_drop(direntry); 428 } else if (rc == -ETXTBSY) { ··· 441 cifs_sb->mnt_cifs_flags & 442 CIFS_MOUNT_MAP_SPECIAL_CHR); 443 CIFSSMBClose(xid, pTcon, netfid); 444 - direntry->d_inode->i_nlink--; 445 } 446 } else if (rc == -EACCES) { 447 /* try only if r/o attribute set in local lookup data? */ ··· 496 cifs_sb->mnt_cifs_flags & 497 CIFS_MOUNT_MAP_SPECIAL_CHR); 498 if (!rc) { 499 - direntry->d_inode->i_nlink--; 500 } else if (rc == -ETXTBSY) { 501 int oplock = FALSE; 502 __u16 netfid; ··· 517 cifs_sb->mnt_cifs_flags & 518 CIFS_MOUNT_MAP_SPECIAL_CHR); 519 CIFSSMBClose(xid, pTcon, netfid); 520 - direntry->d_inode->i_nlink--; 521 } 522 /* BB if rc = -ETXTBUSY goto the rename logic BB */ 523 } 524 } 525 } 526 - cifsInode = CIFS_I(direntry->d_inode); 527 - cifsInode->time = 0; /* will force revalidate to get info when 528 - needed */ 529 - direntry->d_inode->i_ctime = inode->i_ctime = inode->i_mtime = 530 - current_fs_time(inode->i_sb); 531 cifsInode = CIFS_I(inode); 532 cifsInode->time = 0; /* force revalidate of dir as well */ 533
··· 422 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); 423 424 if (!rc) { 425 + if(direntry->d_inode) 426 + direntry->d_inode->i_nlink--; 427 } else if (rc == -ENOENT) { 428 d_drop(direntry); 429 } else if (rc == -ETXTBSY) { ··· 440 cifs_sb->mnt_cifs_flags & 441 CIFS_MOUNT_MAP_SPECIAL_CHR); 442 CIFSSMBClose(xid, pTcon, netfid); 443 + if(direntry->d_inode) 444 + direntry->d_inode->i_nlink--; 445 } 446 } else if (rc == -EACCES) { 447 /* try only if r/o attribute set in local lookup data? */ ··· 494 cifs_sb->mnt_cifs_flags & 495 CIFS_MOUNT_MAP_SPECIAL_CHR); 496 if (!rc) { 497 + if(direntry->d_inode) 498 + direntry->d_inode->i_nlink--; 499 } else if (rc == -ETXTBSY) { 500 int oplock = FALSE; 501 __u16 netfid; ··· 514 cifs_sb->mnt_cifs_flags & 515 CIFS_MOUNT_MAP_SPECIAL_CHR); 516 CIFSSMBClose(xid, pTcon, netfid); 517 + if(direntry->d_inode) 518 + direntry->d_inode->i_nlink--; 519 } 520 /* BB if rc = -ETXTBUSY goto the rename logic BB */ 521 } 522 } 523 } 524 + if(direntry->d_inode) { 525 + cifsInode = CIFS_I(direntry->d_inode); 526 + cifsInode->time = 0; /* will force revalidate to get info 527 + when needed */ 528 + direntry->d_inode->i_ctime = current_fs_time(inode->i_sb); 529 + } 530 + inode->i_ctime = inode->i_mtime = current_fs_time(inode->i_sb); 531 cifsInode = CIFS_I(inode); 532 cifsInode->time = 0; /* force revalidate of dir as well */ 533