aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/cifs/cifsfs.h2
-rw-r--r--fs/cifs/inode.c90
2 files changed, 42 insertions, 50 deletions
diff --git a/fs/cifs/cifsfs.h b/fs/cifs/cifsfs.h
index 135c965c4137..f7b4a5cd837b 100644
--- a/fs/cifs/cifsfs.h
+++ b/fs/cifs/cifsfs.h
@@ -41,7 +41,7 @@ extern int cifs_create(struct inode *, struct dentry *, int,
41 struct nameidata *); 41 struct nameidata *);
42extern struct dentry *cifs_lookup(struct inode *, struct dentry *, 42extern struct dentry *cifs_lookup(struct inode *, struct dentry *,
43 struct nameidata *); 43 struct nameidata *);
44extern int cifs_unlink(struct inode *, struct dentry *); 44extern int cifs_unlink(struct inode *dir, struct dentry *dentry);
45extern int cifs_hardlink(struct dentry *, struct inode *, struct dentry *); 45extern int cifs_hardlink(struct dentry *, struct inode *, struct dentry *);
46extern int cifs_mknod(struct inode *, struct dentry *, int, dev_t); 46extern int cifs_mknod(struct inode *, struct dentry *, int, dev_t);
47extern int cifs_mkdir(struct inode *, struct dentry *, int); 47extern int cifs_mkdir(struct inode *, struct dentry *, int);
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c
index 9c548f110102..511c52616794 100644
--- a/fs/cifs/inode.c
+++ b/fs/cifs/inode.c
@@ -665,40 +665,34 @@ struct inode *cifs_iget(struct super_block *sb, unsigned long ino)
665 return inode; 665 return inode;
666} 666}
667 667
668int cifs_unlink(struct inode *inode, struct dentry *direntry) 668int cifs_unlink(struct inode *dir, struct dentry *dentry)
669{ 669{
670 int rc = 0; 670 int rc = 0;
671 int xid; 671 int xid;
672 struct cifs_sb_info *cifs_sb;
673 struct cifsTconInfo *pTcon;
674 char *full_path = NULL; 672 char *full_path = NULL;
673 struct inode *inode = dentry->d_inode;
675 struct cifsInodeInfo *cifsInode; 674 struct cifsInodeInfo *cifsInode;
675 struct super_block *sb = dir->i_sb;
676 struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
677 struct cifsTconInfo *tcon = cifs_sb->tcon;
676 FILE_BASIC_INFO *pinfo_buf; 678 FILE_BASIC_INFO *pinfo_buf;
677 679
678 cFYI(1, ("cifs_unlink, inode = 0x%p", inode)); 680 cFYI(1, ("cifs_unlink, dir=0x%p, dentry=0x%p", dir, dentry));
679 681
680 xid = GetXid(); 682 xid = GetXid();
681 683
682 if (inode) 684 /* Unlink can be called from rename so we can not take the
683 cifs_sb = CIFS_SB(inode->i_sb); 685 * sb->s_vfs_rename_mutex here */
684 else 686 full_path = build_path_from_dentry(dentry);
685 cifs_sb = CIFS_SB(direntry->d_sb);
686 pTcon = cifs_sb->tcon;
687
688 /* Unlink can be called from rename so we can not grab the sem here
689 since we deadlock otherwise */
690/* mutex_lock(&direntry->d_sb->s_vfs_rename_mutex);*/
691 full_path = build_path_from_dentry(direntry);
692/* mutex_unlock(&direntry->d_sb->s_vfs_rename_mutex);*/
693 if (full_path == NULL) { 687 if (full_path == NULL) {
694 FreeXid(xid); 688 FreeXid(xid);
695 return -ENOMEM; 689 return -ENOMEM;
696 } 690 }
697 691
698 if ((pTcon->ses->capabilities & CAP_UNIX) && 692 if ((tcon->ses->capabilities & CAP_UNIX) &&
699 (CIFS_UNIX_POSIX_PATH_OPS_CAP & 693 (CIFS_UNIX_POSIX_PATH_OPS_CAP &
700 le64_to_cpu(pTcon->fsUnixInfo.Capability))) { 694 le64_to_cpu(tcon->fsUnixInfo.Capability))) {
701 rc = CIFSPOSIXDelFile(xid, pTcon, full_path, 695 rc = CIFSPOSIXDelFile(xid, tcon, full_path,
702 SMB_POSIX_UNLINK_FILE_TARGET, cifs_sb->local_nls, 696 SMB_POSIX_UNLINK_FILE_TARGET, cifs_sb->local_nls,
703 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); 697 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
704 cFYI(1, ("posix del rc %d", rc)); 698 cFYI(1, ("posix del rc %d", rc));
@@ -706,31 +700,31 @@ int cifs_unlink(struct inode *inode, struct dentry *direntry)
706 goto psx_del_no_retry; 700 goto psx_del_no_retry;
707 } 701 }
708 702
709 rc = CIFSSMBDelFile(xid, pTcon, full_path, cifs_sb->local_nls, 703 rc = CIFSSMBDelFile(xid, tcon, full_path, cifs_sb->local_nls,
710 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); 704 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
711psx_del_no_retry: 705psx_del_no_retry:
712 if (!rc) { 706 if (!rc) {
713 if (direntry->d_inode) 707 if (inode)
714 drop_nlink(direntry->d_inode); 708 drop_nlink(inode);
715 } else if (rc == -ENOENT) { 709 } else if (rc == -ENOENT) {
716 d_drop(direntry); 710 d_drop(dentry);
717 } else if (rc == -ETXTBSY) { 711 } else if (rc == -ETXTBSY) {
718 int oplock = 0; 712 int oplock = 0;
719 __u16 netfid; 713 __u16 netfid;
720 714
721 rc = CIFSSMBOpen(xid, pTcon, full_path, FILE_OPEN, DELETE, 715 rc = CIFSSMBOpen(xid, tcon, full_path, FILE_OPEN, DELETE,
722 CREATE_NOT_DIR | CREATE_DELETE_ON_CLOSE, 716 CREATE_NOT_DIR | CREATE_DELETE_ON_CLOSE,
723 &netfid, &oplock, NULL, cifs_sb->local_nls, 717 &netfid, &oplock, NULL, cifs_sb->local_nls,
724 cifs_sb->mnt_cifs_flags & 718 cifs_sb->mnt_cifs_flags &
725 CIFS_MOUNT_MAP_SPECIAL_CHR); 719 CIFS_MOUNT_MAP_SPECIAL_CHR);
726 if (rc == 0) { 720 if (rc == 0) {
727 CIFSSMBRenameOpenFile(xid, pTcon, netfid, NULL, 721 CIFSSMBRenameOpenFile(xid, tcon, netfid, NULL,
728 cifs_sb->local_nls, 722 cifs_sb->local_nls,
729 cifs_sb->mnt_cifs_flags & 723 cifs_sb->mnt_cifs_flags &
730 CIFS_MOUNT_MAP_SPECIAL_CHR); 724 CIFS_MOUNT_MAP_SPECIAL_CHR);
731 CIFSSMBClose(xid, pTcon, netfid); 725 CIFSSMBClose(xid, tcon, netfid);
732 if (direntry->d_inode) 726 if (inode)
733 drop_nlink(direntry->d_inode); 727 drop_nlink(inode);
734 } 728 }
735 } else if (rc == -EACCES) { 729 } else if (rc == -EACCES) {
736 /* try only if r/o attribute set in local lookup data? */ 730 /* try only if r/o attribute set in local lookup data? */
@@ -738,8 +732,8 @@ psx_del_no_retry:
738 if (pinfo_buf) { 732 if (pinfo_buf) {
739 /* ATTRS set to normal clears r/o bit */ 733 /* ATTRS set to normal clears r/o bit */
740 pinfo_buf->Attributes = cpu_to_le32(ATTR_NORMAL); 734 pinfo_buf->Attributes = cpu_to_le32(ATTR_NORMAL);
741 if (!(pTcon->ses->flags & CIFS_SES_NT4)) 735 if (!(tcon->ses->flags & CIFS_SES_NT4))
742 rc = CIFSSMBSetPathInfo(xid, pTcon, full_path, 736 rc = CIFSSMBSetPathInfo(xid, tcon, full_path,
743 pinfo_buf, 737 pinfo_buf,
744 cifs_sb->local_nls, 738 cifs_sb->local_nls,
745 cifs_sb->mnt_cifs_flags & 739 cifs_sb->mnt_cifs_flags &
@@ -750,7 +744,7 @@ psx_del_no_retry:
750 if (rc == -EOPNOTSUPP) { 744 if (rc == -EOPNOTSUPP) {
751 int oplock = 0; 745 int oplock = 0;
752 __u16 netfid; 746 __u16 netfid;
753 /* rc = CIFSSMBSetAttrLegacy(xid, pTcon, 747 /* rc = CIFSSMBSetAttrLegacy(xid, tcon,
754 full_path, 748 full_path,
755 (__u16)ATTR_NORMAL, 749 (__u16)ATTR_NORMAL,
756 cifs_sb->local_nls); 750 cifs_sb->local_nls);
@@ -761,7 +755,7 @@ psx_del_no_retry:
761 755
762 /* BB could scan to see if we already have it open 756 /* BB could scan to see if we already have it open
763 and pass in pid of opener to function */ 757 and pass in pid of opener to function */
764 rc = CIFSSMBOpen(xid, pTcon, full_path, 758 rc = CIFSSMBOpen(xid, tcon, full_path,
765 FILE_OPEN, SYNCHRONIZE | 759 FILE_OPEN, SYNCHRONIZE |
766 FILE_WRITE_ATTRIBUTES, 0, 760 FILE_WRITE_ATTRIBUTES, 0,
767 &netfid, &oplock, NULL, 761 &netfid, &oplock, NULL,
@@ -769,28 +763,28 @@ psx_del_no_retry:
769 cifs_sb->mnt_cifs_flags & 763 cifs_sb->mnt_cifs_flags &
770 CIFS_MOUNT_MAP_SPECIAL_CHR); 764 CIFS_MOUNT_MAP_SPECIAL_CHR);
771 if (rc == 0) { 765 if (rc == 0) {
772 rc = CIFSSMBSetFileInfo(xid, pTcon, 766 rc = CIFSSMBSetFileInfo(xid, tcon,
773 pinfo_buf, 767 pinfo_buf,
774 netfid, 768 netfid,
775 current->tgid); 769 current->tgid);
776 CIFSSMBClose(xid, pTcon, netfid); 770 CIFSSMBClose(xid, tcon, netfid);
777 } 771 }
778 } 772 }
779 kfree(pinfo_buf); 773 kfree(pinfo_buf);
780 } 774 }
781 if (rc == 0) { 775 if (rc == 0) {
782 rc = CIFSSMBDelFile(xid, pTcon, full_path, 776 rc = CIFSSMBDelFile(xid, tcon, full_path,
783 cifs_sb->local_nls, 777 cifs_sb->local_nls,
784 cifs_sb->mnt_cifs_flags & 778 cifs_sb->mnt_cifs_flags &
785 CIFS_MOUNT_MAP_SPECIAL_CHR); 779 CIFS_MOUNT_MAP_SPECIAL_CHR);
786 if (!rc) { 780 if (!rc) {
787 if (direntry->d_inode) 781 if (inode)
788 drop_nlink(direntry->d_inode); 782 drop_nlink(inode);
789 } else if (rc == -ETXTBSY) { 783 } else if (rc == -ETXTBSY) {
790 int oplock = 0; 784 int oplock = 0;
791 __u16 netfid; 785 __u16 netfid;
792 786
793 rc = CIFSSMBOpen(xid, pTcon, full_path, 787 rc = CIFSSMBOpen(xid, tcon, full_path,
794 FILE_OPEN, DELETE, 788 FILE_OPEN, DELETE,
795 CREATE_NOT_DIR | 789 CREATE_NOT_DIR |
796 CREATE_DELETE_ON_CLOSE, 790 CREATE_DELETE_ON_CLOSE,
@@ -799,30 +793,28 @@ psx_del_no_retry:
799 cifs_sb->mnt_cifs_flags & 793 cifs_sb->mnt_cifs_flags &
800 CIFS_MOUNT_MAP_SPECIAL_CHR); 794 CIFS_MOUNT_MAP_SPECIAL_CHR);
801 if (rc == 0) { 795 if (rc == 0) {
802 CIFSSMBRenameOpenFile(xid, pTcon, 796 CIFSSMBRenameOpenFile(xid, tcon,
803 netfid, NULL, 797 netfid, NULL,
804 cifs_sb->local_nls, 798 cifs_sb->local_nls,
805 cifs_sb->mnt_cifs_flags & 799 cifs_sb->mnt_cifs_flags &
806 CIFS_MOUNT_MAP_SPECIAL_CHR); 800 CIFS_MOUNT_MAP_SPECIAL_CHR);
807 CIFSSMBClose(xid, pTcon, netfid); 801 CIFSSMBClose(xid, tcon, netfid);
808 if (direntry->d_inode) 802 if (inode)
809 drop_nlink(direntry->d_inode); 803 drop_nlink(inode);
810 } 804 }
811 /* BB if rc = -ETXTBUSY goto the rename logic BB */ 805 /* BB if rc = -ETXTBUSY goto the rename logic BB */
812 } 806 }
813 } 807 }
814 } 808 }
815 if (direntry->d_inode) {
816 cifsInode = CIFS_I(direntry->d_inode);
817 cifsInode->time = 0; /* will force revalidate to get info
818 when needed */
819 direntry->d_inode->i_ctime = current_fs_time(inode->i_sb);
820 }
821 if (inode) { 809 if (inode) {
822 inode->i_ctime = inode->i_mtime = current_fs_time(inode->i_sb);
823 cifsInode = CIFS_I(inode); 810 cifsInode = CIFS_I(inode);
824 cifsInode->time = 0; /* force revalidate of dir as well */ 811 cifsInode->time = 0; /* will force revalidate to get info
812 when needed */
813 inode->i_ctime = current_fs_time(sb);
825 } 814 }
815 dir->i_ctime = dir->i_mtime = current_fs_time(sb);
816 cifsInode = CIFS_I(dir);
817 cifsInode->time = 0; /* force revalidate of dir as well */
826 818
827 kfree(full_path); 819 kfree(full_path);
828 FreeXid(xid); 820 FreeXid(xid);