diff options
author | Steve French <stevef@stevef95> | 2005-05-17 14:16:18 -0400 |
---|---|---|
committer | Steve French <stevef@stevef95> | 2005-05-17 14:16:18 -0400 |
commit | b2aeb9d565be5ef00fb9f921c6d2459c74d90cdf (patch) | |
tree | e7adab50ce6a13ef5ceb0fbb3d1208ae63523dc9 /fs/cifs/inode.c | |
parent | 67594feb4b68074d8807f5566536e06db9130679 (diff) |
[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)
Diffstat (limited to 'fs/cifs/inode.c')
-rw-r--r-- | fs/cifs/inode.c | 24 |
1 files changed, 15 insertions, 9 deletions
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c index 670947288262..b8b78cbb34c9 100644 --- a/fs/cifs/inode.c +++ b/fs/cifs/inode.c | |||
@@ -422,7 +422,8 @@ int cifs_unlink(struct inode *inode, struct dentry *direntry) | |||
422 | cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); | 422 | cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); |
423 | 423 | ||
424 | if (!rc) { | 424 | if (!rc) { |
425 | direntry->d_inode->i_nlink--; | 425 | if(direntry->d_inode) |
426 | direntry->d_inode->i_nlink--; | ||
426 | } else if (rc == -ENOENT) { | 427 | } else if (rc == -ENOENT) { |
427 | d_drop(direntry); | 428 | d_drop(direntry); |
428 | } else if (rc == -ETXTBSY) { | 429 | } else if (rc == -ETXTBSY) { |
@@ -440,7 +441,8 @@ int cifs_unlink(struct inode *inode, struct dentry *direntry) | |||
440 | cifs_sb->mnt_cifs_flags & | 441 | cifs_sb->mnt_cifs_flags & |
441 | CIFS_MOUNT_MAP_SPECIAL_CHR); | 442 | CIFS_MOUNT_MAP_SPECIAL_CHR); |
442 | CIFSSMBClose(xid, pTcon, netfid); | 443 | CIFSSMBClose(xid, pTcon, netfid); |
443 | direntry->d_inode->i_nlink--; | 444 | if(direntry->d_inode) |
445 | direntry->d_inode->i_nlink--; | ||
444 | } | 446 | } |
445 | } else if (rc == -EACCES) { | 447 | } else if (rc == -EACCES) { |
446 | /* try only if r/o attribute set in local lookup data? */ | 448 | /* try only if r/o attribute set in local lookup data? */ |
@@ -494,7 +496,8 @@ int cifs_unlink(struct inode *inode, struct dentry *direntry) | |||
494 | cifs_sb->mnt_cifs_flags & | 496 | cifs_sb->mnt_cifs_flags & |
495 | CIFS_MOUNT_MAP_SPECIAL_CHR); | 497 | CIFS_MOUNT_MAP_SPECIAL_CHR); |
496 | if (!rc) { | 498 | if (!rc) { |
497 | direntry->d_inode->i_nlink--; | 499 | if(direntry->d_inode) |
500 | direntry->d_inode->i_nlink--; | ||
498 | } else if (rc == -ETXTBSY) { | 501 | } else if (rc == -ETXTBSY) { |
499 | int oplock = FALSE; | 502 | int oplock = FALSE; |
500 | __u16 netfid; | 503 | __u16 netfid; |
@@ -514,17 +517,20 @@ int cifs_unlink(struct inode *inode, struct dentry *direntry) | |||
514 | cifs_sb->mnt_cifs_flags & | 517 | cifs_sb->mnt_cifs_flags & |
515 | CIFS_MOUNT_MAP_SPECIAL_CHR); | 518 | CIFS_MOUNT_MAP_SPECIAL_CHR); |
516 | CIFSSMBClose(xid, pTcon, netfid); | 519 | CIFSSMBClose(xid, pTcon, netfid); |
517 | direntry->d_inode->i_nlink--; | 520 | if(direntry->d_inode) |
521 | direntry->d_inode->i_nlink--; | ||
518 | } | 522 | } |
519 | /* BB if rc = -ETXTBUSY goto the rename logic BB */ | 523 | /* BB if rc = -ETXTBUSY goto the rename logic BB */ |
520 | } | 524 | } |
521 | } | 525 | } |
522 | } | 526 | } |
523 | cifsInode = CIFS_I(direntry->d_inode); | 527 | if(direntry->d_inode) { |
524 | cifsInode->time = 0; /* will force revalidate to get info when | 528 | cifsInode = CIFS_I(direntry->d_inode); |
525 | needed */ | 529 | cifsInode->time = 0; /* will force revalidate to get info |
526 | direntry->d_inode->i_ctime = inode->i_ctime = inode->i_mtime = | 530 | when needed */ |
527 | current_fs_time(inode->i_sb); | 531 | direntry->d_inode->i_ctime = current_fs_time(inode->i_sb); |
532 | } | ||
533 | inode->i_ctime = inode->i_mtime = current_fs_time(inode->i_sb); | ||
528 | cifsInode = CIFS_I(inode); | 534 | cifsInode = CIFS_I(inode); |
529 | cifsInode->time = 0; /* force revalidate of dir as well */ | 535 | cifsInode->time = 0; /* force revalidate of dir as well */ |
530 | 536 | ||