linux/fs/cifs/smb2inode.c
<<
>>
Prefs
   1/*
   2 *   fs/cifs/smb2inode.c
   3 *
   4 *   Copyright (C) International Business Machines  Corp., 2002, 2011
   5 *                 Etersoft, 2012
   6 *   Author(s): Pavel Shilovsky (pshilovsky@samba.org),
   7 *              Steve French (sfrench@us.ibm.com)
   8 *
   9 *   This library is free software; you can redistribute it and/or modify
  10 *   it under the terms of the GNU Lesser General Public License as published
  11 *   by the Free Software Foundation; either version 2.1 of the License, or
  12 *   (at your option) any later version.
  13 *
  14 *   This library is distributed in the hope that it will be useful,
  15 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
  16 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
  17 *   the GNU Lesser General Public License for more details.
  18 *
  19 *   You should have received a copy of the GNU Lesser General Public License
  20 *   along with this library; if not, write to the Free Software
  21 *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  22 */
  23#include <linux/fs.h>
  24#include <linux/stat.h>
  25#include <linux/slab.h>
  26#include <linux/pagemap.h>
  27#include <asm/div64.h>
  28#include "cifsfs.h"
  29#include "cifspdu.h"
  30#include "cifsglob.h"
  31#include "cifsproto.h"
  32#include "cifs_debug.h"
  33#include "cifs_fs_sb.h"
  34#include "cifs_unicode.h"
  35#include "fscache.h"
  36#include "smb2glob.h"
  37#include "smb2pdu.h"
  38#include "smb2proto.h"
  39
  40static int
  41smb2_open_op_close(const unsigned int xid, struct cifs_tcon *tcon,
  42                   struct cifs_sb_info *cifs_sb, const char *full_path,
  43                   __u32 desired_access, __u32 create_disposition,
  44                   __u32 file_attributes, __u32 create_options,
  45                   void *data, int command)
  46{
  47        int rc, tmprc = 0;
  48        u64 persistent_fid, volatile_fid;
  49        __le16 *utf16_path;
  50
  51        utf16_path = cifs_convert_path_to_utf16(full_path, cifs_sb);
  52        if (!utf16_path)
  53                return -ENOMEM;
  54
  55        rc = SMB2_open(xid, tcon, utf16_path, &persistent_fid, &volatile_fid,
  56                       desired_access, create_disposition, file_attributes,
  57                       create_options);
  58        if (rc) {
  59                kfree(utf16_path);
  60                return rc;
  61        }
  62
  63        switch (command) {
  64        case SMB2_OP_DELETE:
  65                break;
  66        case SMB2_OP_QUERY_INFO:
  67                tmprc = SMB2_query_info(xid, tcon, persistent_fid,
  68                                        volatile_fid,
  69                                        (struct smb2_file_all_info *)data);
  70                break;
  71        case SMB2_OP_MKDIR:
  72                /*
  73                 * Directories are created through parameters in the
  74                 * SMB2_open() call.
  75                 */
  76                break;
  77        default:
  78                cERROR(1, "Invalid command");
  79                break;
  80        }
  81
  82        rc = SMB2_close(xid, tcon, persistent_fid, volatile_fid);
  83        if (tmprc)
  84                rc = tmprc;
  85        kfree(utf16_path);
  86        return rc;
  87}
  88
  89static void
  90move_smb2_info_to_cifs(FILE_ALL_INFO *dst, struct smb2_file_all_info *src)
  91{
  92        memcpy(dst, src, (size_t)(&src->CurrentByteOffset) - (size_t)src);
  93        dst->CurrentByteOffset = src->CurrentByteOffset;
  94        dst->Mode = src->Mode;
  95        dst->AlignmentRequirement = src->AlignmentRequirement;
  96        dst->IndexNumber1 = 0; /* we don't use it */
  97}
  98
  99int
 100smb2_query_path_info(const unsigned int xid, struct cifs_tcon *tcon,
 101                     struct cifs_sb_info *cifs_sb, const char *full_path,
 102                     FILE_ALL_INFO *data, bool *adjust_tz)
 103{
 104        int rc;
 105        struct smb2_file_all_info *smb2_data;
 106
 107        *adjust_tz = false;
 108
 109        smb2_data = kzalloc(sizeof(struct smb2_file_all_info) + MAX_NAME * 2,
 110                            GFP_KERNEL);
 111        if (smb2_data == NULL)
 112                return -ENOMEM;
 113
 114        rc = smb2_open_op_close(xid, tcon, cifs_sb, full_path,
 115                                FILE_READ_ATTRIBUTES, FILE_OPEN, 0, 0,
 116                                smb2_data, SMB2_OP_QUERY_INFO);
 117        if (rc)
 118                goto out;
 119
 120        move_smb2_info_to_cifs(data, smb2_data);
 121out:
 122        kfree(smb2_data);
 123        return rc;
 124}
 125
 126int
 127smb2_mkdir(const unsigned int xid, struct cifs_tcon *tcon, const char *name,
 128           struct cifs_sb_info *cifs_sb)
 129{
 130        return smb2_open_op_close(xid, tcon, cifs_sb, name,
 131                                  FILE_WRITE_ATTRIBUTES, FILE_CREATE, 0,
 132                                  CREATE_NOT_FILE, NULL, SMB2_OP_MKDIR);
 133}
 134
 135void
 136smb2_mkdir_setinfo(struct inode *inode, const char *name,
 137                   struct cifs_sb_info *cifs_sb, struct cifs_tcon *tcon,
 138                   const unsigned int xid)
 139{
 140        FILE_BASIC_INFO data;
 141        struct cifsInodeInfo *cifs_i;
 142        u32 dosattrs;
 143        int tmprc;
 144
 145        memset(&data, 0, sizeof(data));
 146        cifs_i = CIFS_I(inode);
 147        dosattrs = cifs_i->cifsAttrs | ATTR_READONLY;
 148        data.Attributes = cpu_to_le32(dosattrs);
 149        tmprc = smb2_open_op_close(xid, tcon, cifs_sb, name,
 150                                   FILE_WRITE_ATTRIBUTES, FILE_CREATE, 0,
 151                                   CREATE_NOT_FILE, &data, SMB2_OP_SET_INFO);
 152        if (tmprc == 0)
 153                cifs_i->cifsAttrs = dosattrs;
 154}
 155
 156int
 157smb2_rmdir(const unsigned int xid, struct cifs_tcon *tcon, const char *name,
 158           struct cifs_sb_info *cifs_sb)
 159{
 160        return smb2_open_op_close(xid, tcon, cifs_sb, name, DELETE, FILE_OPEN,
 161                                  0, CREATE_NOT_FILE | CREATE_DELETE_ON_CLOSE,
 162                                  NULL, SMB2_OP_DELETE);
 163}
 164
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.