diff options
Diffstat (limited to 'fs/cifs')
-rw-r--r-- | fs/cifs/cifsproto.h | 2 | ||||
-rw-r--r-- | fs/cifs/cifssmb.c | 55 | ||||
-rw-r--r-- | fs/cifs/inode.c | 9 |
3 files changed, 64 insertions, 2 deletions
diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h index a729d083e6f4..014f26c7864f 100644 --- a/fs/cifs/cifsproto.h +++ b/fs/cifs/cifsproto.h | |||
@@ -179,6 +179,8 @@ extern int CIFSSMBSetPathInfo(const int xid, struct cifsTconInfo *tcon, | |||
179 | extern int CIFSSMBSetFileInfo(const int xid, struct cifsTconInfo *tcon, | 179 | extern int CIFSSMBSetFileInfo(const int xid, struct cifsTconInfo *tcon, |
180 | const FILE_BASIC_INFO *data, __u16 fid, | 180 | const FILE_BASIC_INFO *data, __u16 fid, |
181 | __u32 pid_of_opener); | 181 | __u32 pid_of_opener); |
182 | extern int CIFSSMBSetFileDisposition(const int xid, struct cifsTconInfo *tcon, | ||
183 | bool delete_file, __u16 fid, __u32 pid_of_opener); | ||
182 | #if 0 | 184 | #if 0 |
183 | extern int CIFSSMBSetAttrLegacy(int xid, struct cifsTconInfo *tcon, | 185 | extern int CIFSSMBSetAttrLegacy(int xid, struct cifsTconInfo *tcon, |
184 | char *fileName, __u16 dos_attributes, | 186 | char *fileName, __u16 dos_attributes, |
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c index 994de7c90474..7b365842bfa1 100644 --- a/fs/cifs/cifssmb.c +++ b/fs/cifs/cifssmb.c | |||
@@ -4876,6 +4876,61 @@ CIFSSMBSetFileInfo(const int xid, struct cifsTconInfo *tcon, | |||
4876 | return rc; | 4876 | return rc; |
4877 | } | 4877 | } |
4878 | 4878 | ||
4879 | int | ||
4880 | CIFSSMBSetFileDisposition(const int xid, struct cifsTconInfo *tcon, | ||
4881 | bool delete_file, __u16 fid, __u32 pid_of_opener) | ||
4882 | { | ||
4883 | struct smb_com_transaction2_sfi_req *pSMB = NULL; | ||
4884 | char *data_offset; | ||
4885 | int rc = 0; | ||
4886 | __u16 params, param_offset, offset, byte_count, count; | ||
4887 | |||
4888 | cFYI(1, ("Set File Disposition (via SetFileInfo)")); | ||
4889 | rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB); | ||
4890 | |||
4891 | if (rc) | ||
4892 | return rc; | ||
4893 | |||
4894 | pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener); | ||
4895 | pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16)); | ||
4896 | |||
4897 | params = 6; | ||
4898 | pSMB->MaxSetupCount = 0; | ||
4899 | pSMB->Reserved = 0; | ||
4900 | pSMB->Flags = 0; | ||
4901 | pSMB->Timeout = 0; | ||
4902 | pSMB->Reserved2 = 0; | ||
4903 | param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4; | ||
4904 | offset = param_offset + params; | ||
4905 | |||
4906 | data_offset = (char *) (&pSMB->hdr.Protocol) + offset; | ||
4907 | |||
4908 | count = 1; | ||
4909 | pSMB->MaxParameterCount = cpu_to_le16(2); | ||
4910 | /* BB find max SMB PDU from sess */ | ||
4911 | pSMB->MaxDataCount = cpu_to_le16(1000); | ||
4912 | pSMB->SetupCount = 1; | ||
4913 | pSMB->Reserved3 = 0; | ||
4914 | pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION); | ||
4915 | byte_count = 3 /* pad */ + params + count; | ||
4916 | pSMB->DataCount = cpu_to_le16(count); | ||
4917 | pSMB->ParameterCount = cpu_to_le16(params); | ||
4918 | pSMB->TotalDataCount = pSMB->DataCount; | ||
4919 | pSMB->TotalParameterCount = pSMB->ParameterCount; | ||
4920 | pSMB->ParameterOffset = cpu_to_le16(param_offset); | ||
4921 | pSMB->DataOffset = cpu_to_le16(offset); | ||
4922 | pSMB->Fid = fid; | ||
4923 | pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_DISPOSITION_INFO); | ||
4924 | pSMB->Reserved4 = 0; | ||
4925 | pSMB->hdr.smb_buf_length += byte_count; | ||
4926 | pSMB->ByteCount = cpu_to_le16(byte_count); | ||
4927 | *data_offset = delete_file ? 1 : 0; | ||
4928 | rc = SendReceiveNoRsp(xid, tcon->ses, (struct smb_hdr *) pSMB, 0); | ||
4929 | if (rc) | ||
4930 | cFYI(1, ("Send error in SetFileDisposition = %d", rc)); | ||
4931 | |||
4932 | return rc; | ||
4933 | } | ||
4879 | 4934 | ||
4880 | int | 4935 | int |
4881 | CIFSSMBSetPathInfo(const int xid, struct cifsTconInfo *tcon, | 4936 | CIFSSMBSetPathInfo(const int xid, struct cifsTconInfo *tcon, |
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c index 660aac81160a..954b670f1687 100644 --- a/fs/cifs/inode.c +++ b/fs/cifs/inode.c | |||
@@ -778,8 +778,7 @@ cifs_rename_pending_delete(char *full_path, struct inode *inode, int xid) | |||
778 | FILE_BASIC_INFO *info_buf; | 778 | FILE_BASIC_INFO *info_buf; |
779 | 779 | ||
780 | rc = CIFSSMBOpen(xid, tcon, full_path, FILE_OPEN, | 780 | rc = CIFSSMBOpen(xid, tcon, full_path, FILE_OPEN, |
781 | DELETE|FILE_WRITE_ATTRIBUTES, | 781 | DELETE|FILE_WRITE_ATTRIBUTES, CREATE_NOT_DIR, |
782 | CREATE_NOT_DIR|CREATE_DELETE_ON_CLOSE, | ||
783 | &netfid, &oplock, NULL, cifs_sb->local_nls, | 782 | &netfid, &oplock, NULL, cifs_sb->local_nls, |
784 | cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); | 783 | cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); |
785 | if (rc != 0) | 784 | if (rc != 0) |
@@ -807,6 +806,12 @@ cifs_rename_pending_delete(char *full_path, struct inode *inode, int xid) | |||
807 | rc = CIFSSMBRenameOpenFile(xid, tcon, netfid, NULL, cifs_sb->local_nls, | 806 | rc = CIFSSMBRenameOpenFile(xid, tcon, netfid, NULL, cifs_sb->local_nls, |
808 | cifs_sb->mnt_cifs_flags & | 807 | cifs_sb->mnt_cifs_flags & |
809 | CIFS_MOUNT_MAP_SPECIAL_CHR); | 808 | CIFS_MOUNT_MAP_SPECIAL_CHR); |
809 | if (rc != 0) | ||
810 | goto out_close; | ||
811 | |||
812 | /* set DELETE_ON_CLOSE */ | ||
813 | rc = CIFSSMBSetFileDisposition(xid, tcon, true, netfid, current->tgid); | ||
814 | |||
810 | out_close: | 815 | out_close: |
811 | CIFSSMBClose(xid, tcon, netfid); | 816 | CIFSSMBClose(xid, tcon, netfid); |
812 | out: | 817 | out: |