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

Jeff Layton jlayton at redhat.com
Wed Sep 17 01:49:51 GMT 2008


On Tue, 16 Sep 2008 20:33:49 -0500
"Steve French" <smfrench at gmail.com> wrote:

> Does this work with NT4?
> 

Good question. I haven't tested it against NT4. Guess this gives me a
good reason to get a NT4 host set up. :)


> 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
> _______________________________________________
> linux-cifs-client mailing list
> linux-cifs-client at lists.samba.org
> https://lists.samba.org/mailman/listinfo/linux-cifs-client
> 


-- 
Jeff Layton <jlayton at redhat.com>


More information about the linux-cifs-client mailing list