aboutsummaryrefslogtreecommitdiffstats
path: root/fs/cifs
diff options
context:
space:
mode:
authorJeff Layton <jlayton@redhat.com>2008-09-23 11:48:35 -0400
committerSteve French <sfrench@us.ibm.com>2008-09-23 13:39:28 -0400
commit6d22f09896c0d62c003ffa25fff25323e3ed608b (patch)
treeae324f22f3e2f4a4b5e5b7bf5f4f6d84e4f95ee0 /fs/cifs
parent7c9c3760b3a5ae87ee4d661703b6d5de3999fe46 (diff)
cifs: add function to set file disposition
cifs: add function to set file disposition The proper way to set the delete on close bit on an already existing file is to use SET_FILE_INFO with an infolevel of SMB_FILE_DISPOSITION_INFO. Add a function to do that and have the silly-rename code use it. Signed-off-by: Jeff Layton <jlayton@redhat.com> Signed-off-by: Steve French <sfrench@us.ibm.com>
Diffstat (limited to 'fs/cifs')
-rw-r--r--fs/cifs/cifsproto.h2
-rw-r--r--fs/cifs/cifssmb.c55
-rw-r--r--fs/cifs/inode.c9
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,
179extern int CIFSSMBSetFileInfo(const int xid, struct cifsTconInfo *tcon, 179extern 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);
182extern int CIFSSMBSetFileDisposition(const int xid, struct cifsTconInfo *tcon,
183 bool delete_file, __u16 fid, __u32 pid_of_opener);
182#if 0 184#if 0
183extern int CIFSSMBSetAttrLegacy(int xid, struct cifsTconInfo *tcon, 185extern 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
4879int
4880CIFSSMBSetFileDisposition(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
4880int 4935int
4881CIFSSMBSetPathInfo(const int xid, struct cifsTconInfo *tcon, 4936CIFSSMBSetPathInfo(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
810out_close: 815out_close:
811 CIFSSMBClose(xid, tcon, netfid); 816 CIFSSMBClose(xid, tcon, netfid);
812out: 817out: