[linux-cifs-client] Re: [PATCH 4/4] cifs: add function to set file disposition

Steve French smfrench at gmail.com
Wed Sep 17 01:33:49 GMT 2008


Does this work with NT4?

On Tue, Sep 16, 2008 at 1:05 PM, Jeff Layton <jlayton at redhat.com> wrote:
> 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 at redhat.com>
> ---
>  fs/cifs/cifsproto.h |    2 +
>  fs/cifs/cifssmb.c   |   55 +++++++++++++++++++++++++++++++++++++++++++++++++++
>  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 bee053f..0cff7fe 100644
> --- a/fs/cifs/cifsproto.h
> +++ b/fs/cifs/cifsproto.h
> @@ -179,6 +179,8 @@ extern int CIFSSMBSetPathInfo(const int xid, struct cifsTconInfo *tcon,
>  extern int CIFSSMBSetFileInfo(const int xid, struct cifsTconInfo *tcon,
>                        const FILE_BASIC_INFO *data, __u16 fid,
>                        __u32 pid_of_opener);
> +extern int CIFSSMBSetFileDisposition(const int xid, struct cifsTconInfo *tcon,
> +                       bool delete_file, __u16 fid, __u32 pid_of_opener);
>  #if 0
>  extern int CIFSSMBSetAttrLegacy(int xid, struct cifsTconInfo *tcon,
>                        char *fileName, __u16 dos_attributes,
> diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c
> index 3d68e28..7504d15 100644
> --- a/fs/cifs/cifssmb.c
> +++ b/fs/cifs/cifssmb.c
> @@ -4876,6 +4876,61 @@ CIFSSMBSetFileInfo(const int xid, struct cifsTconInfo *tcon,
>        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
>  CIFSSMBSetPathInfo(const int xid, struct cifsTconInfo *tcon,
> diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c
> index 03fde14..2f508a3 100644
> --- a/fs/cifs/inode.c
> +++ b/fs/cifs/inode.c
> @@ -685,8 +685,7 @@ cifs_silly_rename(char *full_path, struct inode *inode, int xid)
>        FILE_BASIC_INFO *info_buf;
>
>        rc = CIFSSMBOpen(xid, tcon, full_path, FILE_OPEN,
> -                        DELETE|FILE_WRITE_ATTRIBUTES,
> -                        CREATE_NOT_DIR|CREATE_DELETE_ON_CLOSE,
> +                        DELETE|FILE_WRITE_ATTRIBUTES, CREATE_NOT_DIR,
>                         &netfid, &oplock, NULL, cifs_sb->local_nls,
>                         cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
>        if (rc != 0)
> @@ -714,6 +713,12 @@ cifs_silly_rename(char *full_path, struct inode *inode, int xid)
>        rc = CIFSSMBRenameOpenFile(xid, tcon, netfid, NULL, cifs_sb->local_nls,
>                                   cifs_sb->mnt_cifs_flags &
>                                            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:
>        CIFSSMBClose(xid, tcon, netfid);
>  out:
> --
> 1.5.5.1
>
>



-- 
Thanks,

Steve


More information about the linux-cifs-client mailing list