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>
This commit is contained in:
parent
7c9c3760b3
commit
6d22f09896
@ -179,6 +179,8 @@ extern int CIFSSMBSetPathInfo(const int xid, struct cifsTconInfo *tcon,
|
|||||||
extern int CIFSSMBSetFileInfo(const int xid, struct cifsTconInfo *tcon,
|
extern int CIFSSMBSetFileInfo(const int xid, struct cifsTconInfo *tcon,
|
||||||
const FILE_BASIC_INFO *data, __u16 fid,
|
const FILE_BASIC_INFO *data, __u16 fid,
|
||||||
__u32 pid_of_opener);
|
__u32 pid_of_opener);
|
||||||
|
extern int CIFSSMBSetFileDisposition(const int xid, struct cifsTconInfo *tcon,
|
||||||
|
bool delete_file, __u16 fid, __u32 pid_of_opener);
|
||||||
#if 0
|
#if 0
|
||||||
extern int CIFSSMBSetAttrLegacy(int xid, struct cifsTconInfo *tcon,
|
extern int CIFSSMBSetAttrLegacy(int xid, struct cifsTconInfo *tcon,
|
||||||
char *fileName, __u16 dos_attributes,
|
char *fileName, __u16 dos_attributes,
|
||||||
|
@ -4876,6 +4876,61 @@ CIFSSMBSetFileInfo(const int xid, struct cifsTconInfo *tcon,
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
CIFSSMBSetFileDisposition(const int xid, struct cifsTconInfo *tcon,
|
||||||
|
bool delete_file, __u16 fid, __u32 pid_of_opener)
|
||||||
|
{
|
||||||
|
struct smb_com_transaction2_sfi_req *pSMB = NULL;
|
||||||
|
char *data_offset;
|
||||||
|
int rc = 0;
|
||||||
|
__u16 params, param_offset, offset, byte_count, count;
|
||||||
|
|
||||||
|
cFYI(1, ("Set File Disposition (via SetFileInfo)"));
|
||||||
|
rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
|
||||||
|
|
||||||
|
if (rc)
|
||||||
|
return rc;
|
||||||
|
|
||||||
|
pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener);
|
||||||
|
pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16));
|
||||||
|
|
||||||
|
params = 6;
|
||||||
|
pSMB->MaxSetupCount = 0;
|
||||||
|
pSMB->Reserved = 0;
|
||||||
|
pSMB->Flags = 0;
|
||||||
|
pSMB->Timeout = 0;
|
||||||
|
pSMB->Reserved2 = 0;
|
||||||
|
param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
|
||||||
|
offset = param_offset + params;
|
||||||
|
|
||||||
|
data_offset = (char *) (&pSMB->hdr.Protocol) + offset;
|
||||||
|
|
||||||
|
count = 1;
|
||||||
|
pSMB->MaxParameterCount = cpu_to_le16(2);
|
||||||
|
/* BB find max SMB PDU from sess */
|
||||||
|
pSMB->MaxDataCount = cpu_to_le16(1000);
|
||||||
|
pSMB->SetupCount = 1;
|
||||||
|
pSMB->Reserved3 = 0;
|
||||||
|
pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
|
||||||
|
byte_count = 3 /* pad */ + params + count;
|
||||||
|
pSMB->DataCount = cpu_to_le16(count);
|
||||||
|
pSMB->ParameterCount = cpu_to_le16(params);
|
||||||
|
pSMB->TotalDataCount = pSMB->DataCount;
|
||||||
|
pSMB->TotalParameterCount = pSMB->ParameterCount;
|
||||||
|
pSMB->ParameterOffset = cpu_to_le16(param_offset);
|
||||||
|
pSMB->DataOffset = cpu_to_le16(offset);
|
||||||
|
pSMB->Fid = fid;
|
||||||
|
pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_DISPOSITION_INFO);
|
||||||
|
pSMB->Reserved4 = 0;
|
||||||
|
pSMB->hdr.smb_buf_length += byte_count;
|
||||||
|
pSMB->ByteCount = cpu_to_le16(byte_count);
|
||||||
|
*data_offset = delete_file ? 1 : 0;
|
||||||
|
rc = SendReceiveNoRsp(xid, tcon->ses, (struct smb_hdr *) pSMB, 0);
|
||||||
|
if (rc)
|
||||||
|
cFYI(1, ("Send error in SetFileDisposition = %d", rc));
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
CIFSSMBSetPathInfo(const int xid, struct cifsTconInfo *tcon,
|
CIFSSMBSetPathInfo(const int xid, struct cifsTconInfo *tcon,
|
||||||
|
@ -778,8 +778,7 @@ cifs_rename_pending_delete(char *full_path, struct inode *inode, int xid)
|
|||||||
FILE_BASIC_INFO *info_buf;
|
FILE_BASIC_INFO *info_buf;
|
||||||
|
|
||||||
rc = CIFSSMBOpen(xid, tcon, full_path, FILE_OPEN,
|
rc = CIFSSMBOpen(xid, tcon, full_path, FILE_OPEN,
|
||||||
DELETE|FILE_WRITE_ATTRIBUTES,
|
DELETE|FILE_WRITE_ATTRIBUTES, CREATE_NOT_DIR,
|
||||||
CREATE_NOT_DIR|CREATE_DELETE_ON_CLOSE,
|
|
||||||
&netfid, &oplock, NULL, cifs_sb->local_nls,
|
&netfid, &oplock, NULL, cifs_sb->local_nls,
|
||||||
cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
|
cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
|
||||||
if (rc != 0)
|
if (rc != 0)
|
||||||
@ -807,6 +806,12 @@ cifs_rename_pending_delete(char *full_path, struct inode *inode, int xid)
|
|||||||
rc = CIFSSMBRenameOpenFile(xid, tcon, netfid, NULL, cifs_sb->local_nls,
|
rc = CIFSSMBRenameOpenFile(xid, tcon, netfid, NULL, cifs_sb->local_nls,
|
||||||
cifs_sb->mnt_cifs_flags &
|
cifs_sb->mnt_cifs_flags &
|
||||||
CIFS_MOUNT_MAP_SPECIAL_CHR);
|
CIFS_MOUNT_MAP_SPECIAL_CHR);
|
||||||
|
if (rc != 0)
|
||||||
|
goto out_close;
|
||||||
|
|
||||||
|
/* set DELETE_ON_CLOSE */
|
||||||
|
rc = CIFSSMBSetFileDisposition(xid, tcon, true, netfid, current->tgid);
|
||||||
|
|
||||||
out_close:
|
out_close:
|
||||||
CIFSSMBClose(xid, tcon, netfid);
|
CIFSSMBClose(xid, tcon, netfid);
|
||||||
out:
|
out:
|
||||||
|
Loading…
Reference in New Issue
Block a user