[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