lkml.org 
[lkml]   [2016]   [May]   [30]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 4.4 13/86] remove directory incorrectly tries to set delete on close on non-empty directories
    Date
    4.4-stable review patch.  If anyone has any objections, please let me know.

    ------------------

    From: Steve French <smfrench@gmail.com>

    commit 897fba1172d637d344f009d700f7eb8a1fa262f1 upstream.

    Wrong return code was being returned on SMB3 rmdir of
    non-empty directory.

    For SMB3 (unlike for cifs), we attempt to delete a directory by
    set of delete on close flag on the open. Windows clients set
    this flag via a set info (SET_FILE_DISPOSITION to set this flag)
    which properly checks if the directory is empty.

    With this patch on smb3 mounts we correctly return
    "DIRECTORY NOT EMPTY"
    on attempts to remove a non-empty directory.

    Signed-off-by: Steve French <steve.french@primarydata.com>
    Acked-by: Sachin Prabhu <sprabhu@redhat.com>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

    ---
    fs/cifs/smb2glob.h | 1 +
    fs/cifs/smb2inode.c | 8 ++++++--
    fs/cifs/smb2pdu.c | 16 ++++++++++++++++
    fs/cifs/smb2proto.h | 2 ++
    4 files changed, 25 insertions(+), 2 deletions(-)

    --- a/fs/cifs/smb2glob.h
    +++ b/fs/cifs/smb2glob.h
    @@ -44,6 +44,7 @@
    #define SMB2_OP_DELETE 7
    #define SMB2_OP_HARDLINK 8
    #define SMB2_OP_SET_EOF 9
    +#define SMB2_OP_RMDIR 10

    /* Used when constructing chained read requests. */
    #define CHAINED_REQUEST 1
    --- a/fs/cifs/smb2inode.c
    +++ b/fs/cifs/smb2inode.c
    @@ -80,6 +80,10 @@ smb2_open_op_close(const unsigned int xi
    * SMB2_open() call.
    */
    break;
    + case SMB2_OP_RMDIR:
    + tmprc = SMB2_rmdir(xid, tcon, fid.persistent_fid,
    + fid.volatile_fid);
    + break;
    case SMB2_OP_RENAME:
    tmprc = SMB2_rename(xid, tcon, fid.persistent_fid,
    fid.volatile_fid, (__le16 *)data);
    @@ -191,8 +195,8 @@ smb2_rmdir(const unsigned int xid, struc
    struct cifs_sb_info *cifs_sb)
    {
    return smb2_open_op_close(xid, tcon, cifs_sb, name, DELETE, FILE_OPEN,
    - CREATE_NOT_FILE | CREATE_DELETE_ON_CLOSE,
    - NULL, SMB2_OP_DELETE);
    + CREATE_NOT_FILE,
    + NULL, SMB2_OP_RMDIR);
    }

    int
    --- a/fs/cifs/smb2pdu.c
    +++ b/fs/cifs/smb2pdu.c
    @@ -2577,6 +2577,22 @@ SMB2_rename(const unsigned int xid, stru
    }

    int
    +SMB2_rmdir(const unsigned int xid, struct cifs_tcon *tcon,
    + u64 persistent_fid, u64 volatile_fid)
    +{
    + __u8 delete_pending = 1;
    + void *data;
    + unsigned int size;
    +
    + data = &delete_pending;
    + size = 1; /* sizeof __u8 */
    +
    + return send_set_info(xid, tcon, persistent_fid, volatile_fid,
    + current->tgid, FILE_DISPOSITION_INFORMATION, 1, &data,
    + &size);
    +}
    +
    +int
    SMB2_set_hardlink(const unsigned int xid, struct cifs_tcon *tcon,
    u64 persistent_fid, u64 volatile_fid, __le16 *target_file)
    {
    --- a/fs/cifs/smb2proto.h
    +++ b/fs/cifs/smb2proto.h
    @@ -140,6 +140,8 @@ extern int SMB2_query_directory(const un
    extern int SMB2_rename(const unsigned int xid, struct cifs_tcon *tcon,
    u64 persistent_fid, u64 volatile_fid,
    __le16 *target_file);
    +extern int SMB2_rmdir(const unsigned int xid, struct cifs_tcon *tcon,
    + u64 persistent_fid, u64 volatile_fid);
    extern int SMB2_set_hardlink(const unsigned int xid, struct cifs_tcon *tcon,
    u64 persistent_fid, u64 volatile_fid,
    __le16 *target_file);

    \
     
     \ /
      Last update: 2016-05-31 00:21    [W:4.173 / U:0.312 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site