linux/fs/cifs/inode.c
<<
>>
Prefs
   1/*
   2 *   fs/cifs/inode.c
   3 *
   4 *   Copyright (C) International Business Machines  Corp., 2002,2010
   5 *   Author(s): Steve French (sfrench@us.ibm.com)
   6 *
   7 *   This library is free software; you can redistribute it and/or modify
   8 *   it under the terms of the GNU Lesser General Public License as published
   9 *   by the Free Software Foundation; either version 2.1 of the License, or
  10 *   (at your option) any later version.
  11 *
  12 *   This library is distributed in the hope that it will be useful,
  13 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
  14 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
  15 *   the GNU Lesser General Public License for more details.
  16 *
  17 *   You should have received a copy of the GNU Lesser General Public License
  18 *   along with this library; if not, write to the Free Software
  19 *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  20 */
  21#include <linux/fs.h>
  22#include <linux/stat.h>
  23#include <linux/slab.h>
  24#include <linux/pagemap.h>
  25#include <asm/div64.h>
  26#include "cifsfs.h"
  27#include "cifspdu.h"
  28#include "cifsglob.h"
  29#include "cifsproto.h"
  30#include "cifs_debug.h"
  31#include "cifs_fs_sb.h"
  32#include "fscache.h"
  33
  34
  35static void cifs_set_ops(struct inode *inode)
  36{
  37        struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
  38
  39        switch (inode->i_mode & S_IFMT) {
  40        case S_IFREG:
  41                inode->i_op = &cifs_file_inode_ops;
  42                if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO) {
  43                        if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL)
  44                                inode->i_fop = &cifs_file_direct_nobrl_ops;
  45                        else
  46                                inode->i_fop = &cifs_file_direct_ops;
  47                } else if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_STRICT_IO) {
  48                        if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL)
  49                                inode->i_fop = &cifs_file_strict_nobrl_ops;
  50                        else
  51                                inode->i_fop = &cifs_file_strict_ops;
  52                } else if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL)
  53                        inode->i_fop = &cifs_file_nobrl_ops;
  54                else { /* not direct, send byte range locks */
  55                        inode->i_fop = &cifs_file_ops;
  56                }
  57
  58                /* check if server can support readpages */
  59                if (cifs_sb_master_tcon(cifs_sb)->ses->server->maxBuf <
  60                                PAGE_CACHE_SIZE + MAX_CIFS_HDR_SIZE)
  61                        inode->i_data.a_ops = &cifs_addr_ops_smallbuf;
  62                else
  63                        inode->i_data.a_ops = &cifs_addr_ops;
  64                break;
  65        case S_IFDIR:
  66#ifdef CONFIG_CIFS_DFS_UPCALL
  67                if (IS_AUTOMOUNT(inode)) {
  68                        inode->i_op = &cifs_dfs_referral_inode_operations;
  69                } else {
  70#else /* NO DFS support, treat as a directory */
  71                {
  72#endif
  73                        inode->i_op = &cifs_dir_inode_ops;
  74                        inode->i_fop = &cifs_dir_ops;
  75                }
  76                break;
  77        case S_IFLNK:
  78                inode->i_op = &cifs_symlink_inode_ops;
  79                break;
  80        default:
  81                init_special_inode(inode, inode->i_mode, inode->i_rdev);
  82                break;
  83        }
  84}
  85
  86/* check inode attributes against fattr. If they don't match, tag the
  87 * inode for cache invalidation
  88 */
  89static void
  90cifs_revalidate_cache(struct inode *inode, struct cifs_fattr *fattr)
  91{
  92        struct cifsInodeInfo *cifs_i = CIFS_I(inode);
  93
  94        cFYI(1, "%s: revalidating inode %llu", __func__, cifs_i->uniqueid);
  95
  96        if (inode->i_state & I_NEW) {
  97                cFYI(1, "%s: inode %llu is new", __func__, cifs_i->uniqueid);
  98                return;
  99        }
 100
 101        /* don't bother with revalidation if we have an oplock */
 102        if (cifs_i->clientCanCacheRead) {
 103                cFYI(1, "%s: inode %llu is oplocked", __func__,
 104                         cifs_i->uniqueid);
 105                return;
 106        }
 107
 108         /* revalidate if mtime or size have changed */
 109        if (timespec_equal(&inode->i_mtime, &fattr->cf_mtime) &&
 110            cifs_i->server_eof == fattr->cf_eof) {
 111                cFYI(1, "%s: inode %llu is unchanged", __func__,
 112                         cifs_i->uniqueid);
 113                return;
 114        }
 115
 116        cFYI(1, "%s: invalidating inode %llu mapping", __func__,
 117                 cifs_i->uniqueid);
 118        cifs_i->invalid_mapping = true;
 119}
 120
 121/* populate an inode with info from a cifs_fattr struct */
 122void
 123cifs_fattr_to_inode(struct inode *inode, struct cifs_fattr *fattr)
 124{
 125        struct cifsInodeInfo *cifs_i = CIFS_I(inode);
 126        struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
 127        unsigned long oldtime = cifs_i->time;
 128
 129        cifs_revalidate_cache(inode, fattr);
 130
 131        inode->i_atime = fattr->cf_atime;
 132        inode->i_mtime = fattr->cf_mtime;
 133        inode->i_ctime = fattr->cf_ctime;
 134        inode->i_rdev = fattr->cf_rdev;
 135        inode->i_nlink = fattr->cf_nlink;
 136        inode->i_uid = fattr->cf_uid;
 137        inode->i_gid = fattr->cf_gid;
 138
 139        /* if dynperm is set, don't clobber existing mode */
 140        if (inode->i_state & I_NEW ||
 141            !(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DYNPERM))
 142                inode->i_mode = fattr->cf_mode;
 143
 144        cifs_i->cifsAttrs = fattr->cf_cifsattrs;
 145
 146        if (fattr->cf_flags & CIFS_FATTR_NEED_REVAL)
 147                cifs_i->time = 0;
 148        else
 149                cifs_i->time = jiffies;
 150
 151        cFYI(1, "inode 0x%p old_time=%ld new_time=%ld", inode,
 152                 oldtime, cifs_i->time);
 153
 154        cifs_i->delete_pending = fattr->cf_flags & CIFS_FATTR_DELETE_PENDING;
 155
 156        cifs_i->server_eof = fattr->cf_eof;
 157        /*
 158         * Can't safely change the file size here if the client is writing to
 159         * it due to potential races.
 160         */
 161        spin_lock(&inode->i_lock);
 162        if (is_size_safe_to_change(cifs_i, fattr->cf_eof)) {
 163                i_size_write(inode, fattr->cf_eof);
 164
 165                /*
 166                 * i_blocks is not related to (i_size / i_blksize),
 167                 * but instead 512 byte (2**9) size is required for
 168                 * calculating num blocks.
 169                 */
 170                inode->i_blocks = (512 - 1 + fattr->cf_bytes) >> 9;
 171        }
 172        spin_unlock(&inode->i_lock);
 173
 174        if (fattr->cf_flags & CIFS_FATTR_DFS_REFERRAL)
 175                inode->i_flags |= S_AUTOMOUNT;
 176        cifs_set_ops(inode);
 177}
 178
 179void
 180cifs_fill_uniqueid(struct super_block *sb, struct cifs_fattr *fattr)
 181{
 182        struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
 183
 184        if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM)
 185                return;
 186
 187        fattr->cf_uniqueid = iunique(sb, ROOT_I);
 188}
 189
 190/* Fill a cifs_fattr struct with info from FILE_UNIX_BASIC_INFO. */
 191void
 192cifs_unix_basic_to_fattr(struct cifs_fattr *fattr, FILE_UNIX_BASIC_INFO *info,
 193                         struct cifs_sb_info *cifs_sb)
 194{
 195        memset(fattr, 0, sizeof(*fattr));
 196        fattr->cf_uniqueid = le64_to_cpu(info->UniqueId);
 197        fattr->cf_bytes = le64_to_cpu(info->NumOfBytes);
 198        fattr->cf_eof = le64_to_cpu(info->EndOfFile);
 199
 200        fattr->cf_atime = cifs_NTtimeToUnix(info->LastAccessTime);
 201        fattr->cf_mtime = cifs_NTtimeToUnix(info->LastModificationTime);
 202        fattr->cf_ctime = cifs_NTtimeToUnix(info->LastStatusChange);
 203        fattr->cf_mode = le64_to_cpu(info->Permissions);
 204
 205        /*
 206         * Since we set the inode type below we need to mask off
 207         * to avoid strange results if bits set above.
 208         */
 209        fattr->cf_mode &= ~S_IFMT;
 210        switch (le32_to_cpu(info->Type)) {
 211        case UNIX_FILE:
 212                fattr->cf_mode |= S_IFREG;
 213                fattr->cf_dtype = DT_REG;
 214                break;
 215        case UNIX_SYMLINK:
 216                fattr->cf_mode |= S_IFLNK;
 217                fattr->cf_dtype = DT_LNK;
 218                break;
 219        case UNIX_DIR:
 220                fattr->cf_mode |= S_IFDIR;
 221                fattr->cf_dtype = DT_DIR;
 222                break;
 223        case UNIX_CHARDEV:
 224                fattr->cf_mode |= S_IFCHR;
 225                fattr->cf_dtype = DT_CHR;
 226                fattr->cf_rdev = MKDEV(le64_to_cpu(info->DevMajor),
 227                                       le64_to_cpu(info->DevMinor) & MINORMASK);
 228                break;
 229        case UNIX_BLOCKDEV:
 230                fattr->cf_mode |= S_IFBLK;
 231                fattr->cf_dtype = DT_BLK;
 232                fattr->cf_rdev = MKDEV(le64_to_cpu(info->DevMajor),
 233                                       le64_to_cpu(info->DevMinor) & MINORMASK);
 234                break;
 235        case UNIX_FIFO:
 236                fattr->cf_mode |= S_IFIFO;
 237                fattr->cf_dtype = DT_FIFO;
 238                break;
 239        case UNIX_SOCKET:
 240                fattr->cf_mode |= S_IFSOCK;
 241                fattr->cf_dtype = DT_SOCK;
 242                break;
 243        default:
 244                /* safest to call it a file if we do not know */
 245                fattr->cf_mode |= S_IFREG;
 246                fattr->cf_dtype = DT_REG;
 247                cFYI(1, "unknown type %d", le32_to_cpu(info->Type));
 248                break;
 249        }
 250
 251        if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_UID)
 252                fattr->cf_uid = cifs_sb->mnt_uid;
 253        else
 254                fattr->cf_uid = le64_to_cpu(info->Uid);
 255
 256        if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_GID)
 257                fattr->cf_gid = cifs_sb->mnt_gid;
 258        else
 259                fattr->cf_gid = le64_to_cpu(info->Gid);
 260
 261        fattr->cf_nlink = le64_to_cpu(info->Nlinks);
 262}
 263
 264/*
 265 * Fill a cifs_fattr struct with fake inode info.
 266 *
 267 * Needed to setup cifs_fattr data for the directory which is the
 268 * junction to the new submount (ie to setup the fake directory
 269 * which represents a DFS referral).
 270 */
 271static void
 272cifs_create_dfs_fattr(struct cifs_fattr *fattr, struct super_block *sb)
 273{
 274        struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
 275
 276        cFYI(1, "creating fake fattr for DFS referral");
 277
 278        memset(fattr, 0, sizeof(*fattr));
 279        fattr->cf_mode = S_IFDIR | S_IXUGO | S_IRWXU;
 280        fattr->cf_uid = cifs_sb->mnt_uid;
 281        fattr->cf_gid = cifs_sb->mnt_gid;
 282        fattr->cf_atime = CURRENT_TIME;
 283        fattr->cf_ctime = CURRENT_TIME;
 284        fattr->cf_mtime = CURRENT_TIME;
 285        fattr->cf_nlink = 2;
 286        fattr->cf_flags |= CIFS_FATTR_DFS_REFERRAL;
 287}
 288
 289int cifs_get_file_info_unix(struct file *filp)
 290{
 291        int rc;
 292        int xid;
 293        FILE_UNIX_BASIC_INFO find_data;
 294        struct cifs_fattr fattr;
 295        struct inode *inode = filp->f_path.dentry->d_inode;
 296        struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
 297        struct cifsFileInfo *cfile = filp->private_data;
 298        struct cifsTconInfo *tcon = tlink_tcon(cfile->tlink);
 299
 300        xid = GetXid();
 301        rc = CIFSSMBUnixQFileInfo(xid, tcon, cfile->netfid, &find_data);
 302        if (!rc) {
 303                cifs_unix_basic_to_fattr(&fattr, &find_data, cifs_sb);
 304        } else if (rc == -EREMOTE) {
 305                cifs_create_dfs_fattr(&fattr, inode->i_sb);
 306                rc = 0;
 307        }
 308
 309        cifs_fattr_to_inode(inode, &fattr);
 310        FreeXid(xid);
 311        return rc;
 312}
 313
 314int cifs_get_inode_info_unix(struct inode **pinode,
 315                             const unsigned char *full_path,
 316                             struct super_block *sb, int xid)
 317{
 318        int rc;
 319        FILE_UNIX_BASIC_INFO find_data;
 320        struct cifs_fattr fattr;
 321        struct cifsTconInfo *tcon;
 322        struct tcon_link *tlink;
 323        struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
 324
 325        cFYI(1, "Getting info on %s", full_path);
 326
 327        tlink = cifs_sb_tlink(cifs_sb);
 328        if (IS_ERR(tlink))
 329                return PTR_ERR(tlink);
 330        tcon = tlink_tcon(tlink);
 331
 332        /* could have done a find first instead but this returns more info */
 333        rc = CIFSSMBUnixQPathInfo(xid, tcon, full_path, &find_data,
 334                                  cifs_sb->local_nls, cifs_sb->mnt_cifs_flags &
 335                                        CIFS_MOUNT_MAP_SPECIAL_CHR);
 336        cifs_put_tlink(tlink);
 337
 338        if (!rc) {
 339                cifs_unix_basic_to_fattr(&fattr, &find_data, cifs_sb);
 340        } else if (rc == -EREMOTE) {
 341                cifs_create_dfs_fattr(&fattr, sb);
 342                rc = 0;
 343        } else {
 344                return rc;
 345        }
 346
 347        /* check for Minshall+French symlinks */
 348        if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MF_SYMLINKS) {
 349                int tmprc = CIFSCheckMFSymlink(&fattr, full_path, cifs_sb, xid);
 350                if (tmprc)
 351                        cFYI(1, "CIFSCheckMFSymlink: %d", tmprc);
 352        }
 353
 354        if (*pinode == NULL) {
 355                /* get new inode */
 356                cifs_fill_uniqueid(sb, &fattr);
 357                *pinode = cifs_iget(sb, &fattr);
 358                if (!*pinode)
 359                        rc = -ENOMEM;
 360        } else {
 361                /* we already have inode, update it */
 362                cifs_fattr_to_inode(*pinode, &fattr);
 363        }
 364
 365        return rc;
 366}
 367
 368static int
 369cifs_sfu_type(struct cifs_fattr *fattr, const unsigned char *path,
 370              struct cifs_sb_info *cifs_sb, int xid)
 371{
 372        int rc;
 373        int oplock = 0;
 374        __u16 netfid;
 375        struct tcon_link *tlink;
 376        struct cifsTconInfo *tcon;
 377        char buf[24];
 378        unsigned int bytes_read;
 379        char *pbuf;
 380
 381        pbuf = buf;
 382
 383        fattr->cf_mode &= ~S_IFMT;
 384
 385        if (fattr->cf_eof == 0) {
 386                fattr->cf_mode |= S_IFIFO;
 387                fattr->cf_dtype = DT_FIFO;
 388                return 0;
 389        } else if (fattr->cf_eof < 8) {
 390                fattr->cf_mode |= S_IFREG;
 391                fattr->cf_dtype = DT_REG;
 392                return -EINVAL;  /* EOPNOTSUPP? */
 393        }
 394
 395        tlink = cifs_sb_tlink(cifs_sb);
 396        if (IS_ERR(tlink))
 397                return PTR_ERR(tlink);
 398        tcon = tlink_tcon(tlink);
 399
 400        rc = CIFSSMBOpen(xid, tcon, path, FILE_OPEN, GENERIC_READ,
 401                         CREATE_NOT_DIR, &netfid, &oplock, NULL,
 402                         cifs_sb->local_nls,
 403                         cifs_sb->mnt_cifs_flags &
 404                                CIFS_MOUNT_MAP_SPECIAL_CHR);
 405        if (rc == 0) {
 406                int buf_type = CIFS_NO_BUFFER;
 407                        /* Read header */
 408                rc = CIFSSMBRead(xid, tcon, netfid,
 409                                 24 /* length */, 0 /* offset */,
 410                                 &bytes_read, &pbuf, &buf_type);
 411                if ((rc == 0) && (bytes_read >= 8)) {
 412                        if (memcmp("IntxBLK", pbuf, 8) == 0) {
 413                                cFYI(1, "Block device");
 414                                fattr->cf_mode |= S_IFBLK;
 415                                fattr->cf_dtype = DT_BLK;
 416                                if (bytes_read == 24) {
 417                                        /* we have enough to decode dev num */
 418                                        __u64 mjr; /* major */
 419                                        __u64 mnr; /* minor */
 420                                        mjr = le64_to_cpu(*(__le64 *)(pbuf+8));
 421                                        mnr = le64_to_cpu(*(__le64 *)(pbuf+16));
 422                                        fattr->cf_rdev = MKDEV(mjr, mnr);
 423                                }
 424                        } else if (memcmp("IntxCHR", pbuf, 8) == 0) {
 425                                cFYI(1, "Char device");
 426                                fattr->cf_mode |= S_IFCHR;
 427                                fattr->cf_dtype = DT_CHR;
 428                                if (bytes_read == 24) {
 429                                        /* we have enough to decode dev num */
 430                                        __u64 mjr; /* major */
 431                                        __u64 mnr; /* minor */
 432                                        mjr = le64_to_cpu(*(__le64 *)(pbuf+8));
 433                                        mnr = le64_to_cpu(*(__le64 *)(pbuf+16));
 434                                        fattr->cf_rdev = MKDEV(mjr, mnr);
 435                                }
 436                        } else if (memcmp("IntxLNK", pbuf, 7) == 0) {
 437                                cFYI(1, "Symlink");
 438                                fattr->cf_mode |= S_IFLNK;
 439                                fattr->cf_dtype = DT_LNK;
 440                        } else {
 441                                fattr->cf_mode |= S_IFREG; /* file? */
 442                                fattr->cf_dtype = DT_REG;
 443                                rc = -EOPNOTSUPP;
 444                        }
 445                } else {
 446                        fattr->cf_mode |= S_IFREG; /* then it is a file */
 447                        fattr->cf_dtype = DT_REG;
 448                        rc = -EOPNOTSUPP; /* or some unknown SFU type */
 449                }
 450                CIFSSMBClose(xid, tcon, netfid);
 451        }
 452        cifs_put_tlink(tlink);
 453        return rc;
 454}
 455
 456#define SFBITS_MASK (S_ISVTX | S_ISGID | S_ISUID)  /* SETFILEBITS valid bits */
 457
 458/*
 459 * Fetch mode bits as provided by SFU.
 460 *
 461 * FIXME: Doesn't this clobber the type bit we got from cifs_sfu_type ?
 462 */
 463static int cifs_sfu_mode(struct cifs_fattr *fattr, const unsigned char *path,
 464                         struct cifs_sb_info *cifs_sb, int xid)
 465{
 466#ifdef CONFIG_CIFS_XATTR
 467        ssize_t rc;
 468        char ea_value[4];
 469        __u32 mode;
 470        struct tcon_link *tlink;
 471        struct cifsTconInfo *tcon;
 472
 473        tlink = cifs_sb_tlink(cifs_sb);
 474        if (IS_ERR(tlink))
 475                return PTR_ERR(tlink);
 476        tcon = tlink_tcon(tlink);
 477
 478        rc = CIFSSMBQAllEAs(xid, tcon, path, "SETFILEBITS",
 479                            ea_value, 4 /* size of buf */, cifs_sb->local_nls,
 480                            cifs_sb->mnt_cifs_flags &
 481                                CIFS_MOUNT_MAP_SPECIAL_CHR);
 482        cifs_put_tlink(tlink);
 483        if (rc < 0)
 484                return (int)rc;
 485        else if (rc > 3) {
 486                mode = le32_to_cpu(*((__le32 *)ea_value));
 487                fattr->cf_mode &= ~SFBITS_MASK;
 488                cFYI(1, "special bits 0%o org mode 0%o", mode,
 489                         fattr->cf_mode);
 490                fattr->cf_mode = (mode & SFBITS_MASK) | fattr->cf_mode;
 491                cFYI(1, "special mode bits 0%o", mode);
 492        }
 493
 494        return 0;
 495#else
 496        return -EOPNOTSUPP;
 497#endif
 498}
 499
 500/* Fill a cifs_fattr struct with info from FILE_ALL_INFO */
 501static void
 502cifs_all_info_to_fattr(struct cifs_fattr *fattr, FILE_ALL_INFO *info,
 503                       struct cifs_sb_info *cifs_sb, bool adjust_tz)
 504{
 505        struct cifsTconInfo *tcon = cifs_sb_master_tcon(cifs_sb);
 506
 507        memset(fattr, 0, sizeof(*fattr));
 508        fattr->cf_cifsattrs = le32_to_cpu(info->Attributes);
 509        if (info->DeletePending)
 510                fattr->cf_flags |= CIFS_FATTR_DELETE_PENDING;
 511
 512        if (info->LastAccessTime)
 513                fattr->cf_atime = cifs_NTtimeToUnix(info->LastAccessTime);
 514        else
 515                fattr->cf_atime = CURRENT_TIME;
 516
 517        fattr->cf_ctime = cifs_NTtimeToUnix(info->ChangeTime);
 518        fattr->cf_mtime = cifs_NTtimeToUnix(info->LastWriteTime);
 519
 520        if (adjust_tz) {
 521                fattr->cf_ctime.tv_sec += tcon->ses->server->timeAdj;
 522                fattr->cf_mtime.tv_sec += tcon->ses->server->timeAdj;
 523        }
 524
 525        fattr->cf_eof = le64_to_cpu(info->EndOfFile);
 526        fattr->cf_bytes = le64_to_cpu(info->AllocationSize);
 527        fattr->cf_createtime = le64_to_cpu(info->CreationTime);
 528
 529        if (fattr->cf_cifsattrs & ATTR_DIRECTORY) {
 530                fattr->cf_mode = S_IFDIR | cifs_sb->mnt_dir_mode;
 531                fattr->cf_dtype = DT_DIR;
 532        } else {
 533                fattr->cf_mode = S_IFREG | cifs_sb->mnt_file_mode;
 534                fattr->cf_dtype = DT_REG;
 535
 536                /* clear write bits if ATTR_READONLY is set */
 537                if (fattr->cf_cifsattrs & ATTR_READONLY)
 538                        fattr->cf_mode &= ~(S_IWUGO);
 539        }
 540
 541        fattr->cf_nlink = le32_to_cpu(info->NumberOfLinks);
 542
 543        fattr->cf_uid = cifs_sb->mnt_uid;
 544        fattr->cf_gid = cifs_sb->mnt_gid;
 545}
 546
 547int cifs_get_file_info(struct file *filp)
 548{
 549        int rc;
 550        int xid;
 551        FILE_ALL_INFO find_data;
 552        struct cifs_fattr fattr;
 553        struct inode *inode = filp->f_path.dentry->d_inode;
 554        struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
 555        struct cifsFileInfo *cfile = filp->private_data;
 556        struct cifsTconInfo *tcon = tlink_tcon(cfile->tlink);
 557
 558        xid = GetXid();
 559        rc = CIFSSMBQFileInfo(xid, tcon, cfile->netfid, &find_data);
 560        if (rc == -EOPNOTSUPP || rc == -EINVAL) {
 561                /*
 562                 * FIXME: legacy server -- fall back to path-based call?
 563                 * for now, just skip revalidating and mark inode for
 564                 * immediate reval.
 565                 */
 566                rc = 0;
 567                CIFS_I(inode)->time = 0;
 568                goto cgfi_exit;
 569        } else if (rc == -EREMOTE) {
 570                cifs_create_dfs_fattr(&fattr, inode->i_sb);
 571                rc = 0;
 572        } else if (rc)
 573                goto cgfi_exit;
 574
 575        /*
 576         * don't bother with SFU junk here -- just mark inode as needing
 577         * revalidation.
 578         */
 579        cifs_all_info_to_fattr(&fattr, &find_data, cifs_sb, false);
 580        fattr.cf_uniqueid = CIFS_I(inode)->uniqueid;
 581        fattr.cf_flags |= CIFS_FATTR_NEED_REVAL;
 582        cifs_fattr_to_inode(inode, &fattr);
 583cgfi_exit:
 584        FreeXid(xid);
 585        return rc;
 586}
 587
 588int cifs_get_inode_info(struct inode **pinode,
 589        const unsigned char *full_path, FILE_ALL_INFO *pfindData,
 590        struct super_block *sb, int xid, const __u16 *pfid)
 591{
 592        int rc = 0, tmprc;
 593        struct cifsTconInfo *pTcon;
 594        struct tcon_link *tlink;
 595        struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
 596        char *buf = NULL;
 597        bool adjustTZ = false;
 598        struct cifs_fattr fattr;
 599
 600        tlink = cifs_sb_tlink(cifs_sb);
 601        if (IS_ERR(tlink))
 602                return PTR_ERR(tlink);
 603        pTcon = tlink_tcon(tlink);
 604
 605        cFYI(1, "Getting info on %s", full_path);
 606
 607        if ((pfindData == NULL) && (*pinode != NULL)) {
 608                if (CIFS_I(*pinode)->clientCanCacheRead) {
 609                        cFYI(1, "No need to revalidate cached inode sizes");
 610                        goto cgii_exit;
 611                }
 612        }
 613
 614        /* if file info not passed in then get it from server */
 615        if (pfindData == NULL) {
 616                buf = kmalloc(sizeof(FILE_ALL_INFO), GFP_KERNEL);
 617                if (buf == NULL) {
 618                        rc = -ENOMEM;
 619                        goto cgii_exit;
 620                }
 621                pfindData = (FILE_ALL_INFO *)buf;
 622
 623                /* could do find first instead but this returns more info */
 624                rc = CIFSSMBQPathInfo(xid, pTcon, full_path, pfindData,
 625                              0 /* not legacy */,
 626                              cifs_sb->local_nls, cifs_sb->mnt_cifs_flags &
 627                                CIFS_MOUNT_MAP_SPECIAL_CHR);
 628                /* BB optimize code so we do not make the above call
 629                when server claims no NT SMB support and the above call
 630                failed at least once - set flag in tcon or mount */
 631                if ((rc == -EOPNOTSUPP) || (rc == -EINVAL)) {
 632                        rc = SMBQueryInformation(xid, pTcon, full_path,
 633                                        pfindData, cifs_sb->local_nls,
 634                                        cifs_sb->mnt_cifs_flags &
 635                                          CIFS_MOUNT_MAP_SPECIAL_CHR);
 636                        adjustTZ = true;
 637                }
 638        }
 639
 640        if (!rc) {
 641                cifs_all_info_to_fattr(&fattr, (FILE_ALL_INFO *) pfindData,
 642                                       cifs_sb, adjustTZ);
 643        } else if (rc == -EREMOTE) {
 644                cifs_create_dfs_fattr(&fattr, sb);
 645                rc = 0;
 646        } else {
 647                goto cgii_exit;
 648        }
 649
 650        /*
 651         * If an inode wasn't passed in, then get the inode number
 652         *
 653         * Is an i_ino of zero legal? Can we use that to check if the server
 654         * supports returning inode numbers?  Are there other sanity checks we
 655         * can use to ensure that the server is really filling in that field?
 656         *
 657         * We can not use the IndexNumber field by default from Windows or
 658         * Samba (in ALL_INFO buf) but we can request it explicitly. The SNIA
 659         * CIFS spec claims that this value is unique within the scope of a
 660         * share, and the windows docs hint that it's actually unique
 661         * per-machine.
 662         *
 663         * There may be higher info levels that work but are there Windows
 664         * server or network appliances for which IndexNumber field is not
 665         * guaranteed unique?
 666         */
 667        if (*pinode == NULL) {
 668                if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) {
 669                        int rc1 = 0;
 670
 671                        rc1 = CIFSGetSrvInodeNumber(xid, pTcon,
 672                                        full_path, &fattr.cf_uniqueid,
 673                                        cifs_sb->local_nls,
 674                                        cifs_sb->mnt_cifs_flags &
 675                                                CIFS_MOUNT_MAP_SPECIAL_CHR);
 676                        if (rc1 || !fattr.cf_uniqueid) {
 677                                cFYI(1, "GetSrvInodeNum rc %d", rc1);
 678                                fattr.cf_uniqueid = iunique(sb, ROOT_I);
 679                                cifs_autodisable_serverino(cifs_sb);
 680                        }
 681                } else {
 682                        fattr.cf_uniqueid = iunique(sb, ROOT_I);
 683                }
 684        } else {
 685                fattr.cf_uniqueid = CIFS_I(*pinode)->uniqueid;
 686        }
 687
 688        /* query for SFU type info if supported and needed */
 689        if (fattr.cf_cifsattrs & ATTR_SYSTEM &&
 690            cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) {
 691                tmprc = cifs_sfu_type(&fattr, full_path, cifs_sb, xid);
 692                if (tmprc)
 693                        cFYI(1, "cifs_sfu_type failed: %d", tmprc);
 694        }
 695
 696#ifdef CONFIG_CIFS_ACL
 697        /* fill in 0777 bits from ACL */
 698        if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) {
 699                rc = cifs_acl_to_fattr(cifs_sb, &fattr, *pinode, full_path,
 700                                                pfid);
 701                if (rc) {
 702                        cFYI(1, "%s: Getting ACL failed with error: %d",
 703                                __func__, rc);
 704                        goto cgii_exit;
 705                }
 706        }
 707#endif /* CONFIG_CIFS_ACL */
 708
 709        /* fill in remaining high mode bits e.g. SUID, VTX */
 710        if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL)
 711                cifs_sfu_mode(&fattr, full_path, cifs_sb, xid);
 712
 713        /* check for Minshall+French symlinks */
 714        if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MF_SYMLINKS) {
 715                tmprc = CIFSCheckMFSymlink(&fattr, full_path, cifs_sb, xid);
 716                if (tmprc)
 717                        cFYI(1, "CIFSCheckMFSymlink: %d", tmprc);
 718        }
 719
 720        if (!*pinode) {
 721                *pinode = cifs_iget(sb, &fattr);
 722                if (!*pinode)
 723                        rc = -ENOMEM;
 724        } else {
 725                cifs_fattr_to_inode(*pinode, &fattr);
 726        }
 727
 728cgii_exit:
 729        kfree(buf);
 730        cifs_put_tlink(tlink);
 731        return rc;
 732}
 733
 734static const struct inode_operations cifs_ipc_inode_ops = {
 735        .lookup = cifs_lookup,
 736};
 737
 738char *cifs_build_path_to_root(struct cifs_sb_info *cifs_sb,
 739                                struct cifsTconInfo *tcon)
 740{
 741        int pplen = cifs_sb->prepathlen;
 742        int dfsplen;
 743        char *full_path = NULL;
 744
 745        /* if no prefix path, simply set path to the root of share to "" */
 746        if (pplen == 0) {
 747                full_path = kmalloc(1, GFP_KERNEL);
 748                if (full_path)
 749                        full_path[0] = 0;
 750                return full_path;
 751        }
 752
 753        if (tcon->Flags & SMB_SHARE_IS_IN_DFS)
 754                dfsplen = strnlen(tcon->treeName, MAX_TREE_SIZE + 1);
 755        else
 756                dfsplen = 0;
 757
 758        full_path = kmalloc(dfsplen + pplen + 1, GFP_KERNEL);
 759        if (full_path == NULL)
 760                return full_path;
 761
 762        if (dfsplen) {
 763                strncpy(full_path, tcon->treeName, dfsplen);
 764                /* switch slash direction in prepath depending on whether
 765                 * windows or posix style path names
 766                 */
 767                if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS) {
 768                        int i;
 769                        for (i = 0; i < dfsplen; i++) {
 770                                if (full_path[i] == '\\')
 771                                        full_path[i] = '/';
 772                        }
 773                }
 774        }
 775        strncpy(full_path + dfsplen, cifs_sb->prepath, pplen);
 776        full_path[dfsplen + pplen] = 0; /* add trailing null */
 777        return full_path;
 778}
 779
 780static int
 781cifs_find_inode(struct inode *inode, void *opaque)
 782{
 783        struct cifs_fattr *fattr = (struct cifs_fattr *) opaque;
 784
 785        /* don't match inode with different uniqueid */
 786        if (CIFS_I(inode)->uniqueid != fattr->cf_uniqueid)
 787                return 0;
 788
 789        /* use createtime like an i_generation field */
 790        if (CIFS_I(inode)->createtime != fattr->cf_createtime)
 791                return 0;
 792
 793        /* don't match inode of different type */
 794        if ((inode->i_mode & S_IFMT) != (fattr->cf_mode & S_IFMT))
 795                return 0;
 796
 797        /* if it's not a directory or has no dentries, then flag it */
 798        if (S_ISDIR(inode->i_mode) && !list_empty(&inode->i_dentry))
 799                fattr->cf_flags |= CIFS_FATTR_INO_COLLISION;
 800
 801        return 1;
 802}
 803
 804static int
 805cifs_init_inode(struct inode *inode, void *opaque)
 806{
 807        struct cifs_fattr *fattr = (struct cifs_fattr *) opaque;
 808
 809        CIFS_I(inode)->uniqueid = fattr->cf_uniqueid;
 810        CIFS_I(inode)->createtime = fattr->cf_createtime;
 811        return 0;
 812}
 813
 814/*
 815 * walk dentry list for an inode and report whether it has aliases that
 816 * are hashed. We use this to determine if a directory inode can actually
 817 * be used.
 818 */
 819static bool
 820inode_has_hashed_dentries(struct inode *inode)
 821{
 822        struct dentry *dentry;
 823
 824        spin_lock(&inode->i_lock);
 825        list_for_each_entry(dentry, &inode->i_dentry, d_alias) {
 826                if (!d_unhashed(dentry) || IS_ROOT(dentry)) {
 827                        spin_unlock(&inode->i_lock);
 828                        return true;
 829                }
 830        }
 831        spin_unlock(&inode->i_lock);
 832        return false;
 833}
 834
 835/* Given fattrs, get a corresponding inode */
 836struct inode *
 837cifs_iget(struct super_block *sb, struct cifs_fattr *fattr)
 838{
 839        unsigned long hash;
 840        struct inode *inode;
 841
 842retry_iget5_locked:
 843        cFYI(1, "looking for uniqueid=%llu", fattr->cf_uniqueid);
 844
 845        /* hash down to 32-bits on 32-bit arch */
 846        hash = cifs_uniqueid_to_ino_t(fattr->cf_uniqueid);
 847
 848        inode = iget5_locked(sb, hash, cifs_find_inode, cifs_init_inode, fattr);
 849        if (inode) {
 850                /* was there a potentially problematic inode collision? */
 851                if (fattr->cf_flags & CIFS_FATTR_INO_COLLISION) {
 852                        fattr->cf_flags &= ~CIFS_FATTR_INO_COLLISION;
 853
 854                        if (inode_has_hashed_dentries(inode)) {
 855                                cifs_autodisable_serverino(CIFS_SB(sb));
 856                                iput(inode);
 857                                fattr->cf_uniqueid = iunique(sb, ROOT_I);
 858                                goto retry_iget5_locked;
 859                        }
 860                }
 861
 862                cifs_fattr_to_inode(inode, fattr);
 863                if (sb->s_flags & MS_NOATIME)
 864                        inode->i_flags |= S_NOATIME | S_NOCMTIME;
 865                if (inode->i_state & I_NEW) {
 866                        inode->i_ino = hash;
 867                        if (S_ISREG(inode->i_mode))
 868                                inode->i_data.backing_dev_info = sb->s_bdi;
 869#ifdef CONFIG_CIFS_FSCACHE
 870                        /* initialize per-inode cache cookie pointer */
 871                        CIFS_I(inode)->fscache = NULL;
 872#endif
 873                        unlock_new_inode(inode);
 874                }
 875        }
 876
 877        return inode;
 878}
 879
 880/* gets root inode */
 881struct inode *cifs_root_iget(struct super_block *sb, unsigned long ino)
 882{
 883        int xid;
 884        struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
 885        struct inode *inode = NULL;
 886        long rc;
 887        char *full_path;
 888        struct cifsTconInfo *tcon = cifs_sb_master_tcon(cifs_sb);
 889
 890        full_path = cifs_build_path_to_root(cifs_sb, tcon);
 891        if (full_path == NULL)
 892                return ERR_PTR(-ENOMEM);
 893
 894        xid = GetXid();
 895        if (tcon->unix_ext)
 896                rc = cifs_get_inode_info_unix(&inode, full_path, sb, xid);
 897        else
 898                rc = cifs_get_inode_info(&inode, full_path, NULL, sb,
 899                                                xid, NULL);
 900
 901        if (!inode) {
 902                inode = ERR_PTR(rc);
 903                goto out;
 904        }
 905
 906#ifdef CONFIG_CIFS_FSCACHE
 907        /* populate tcon->resource_id */
 908        tcon->resource_id = CIFS_I(inode)->uniqueid;
 909#endif
 910
 911        if (rc && tcon->ipc) {
 912                cFYI(1, "ipc connection - fake read inode");
 913                inode->i_mode |= S_IFDIR;
 914                inode->i_nlink = 2;
 915                inode->i_op = &cifs_ipc_inode_ops;
 916                inode->i_fop = &simple_dir_operations;
 917                inode->i_uid = cifs_sb->mnt_uid;
 918                inode->i_gid = cifs_sb->mnt_gid;
 919        } else if (rc) {
 920                iget_failed(inode);
 921                inode = ERR_PTR(rc);
 922        }
 923
 924out:
 925        kfree(full_path);
 926        /* can not call macro FreeXid here since in a void func
 927         * TODO: This is no longer true
 928         */
 929        _FreeXid(xid);
 930        return inode;
 931}
 932
 933static int
 934cifs_set_file_info(struct inode *inode, struct iattr *attrs, int xid,
 935                    char *full_path, __u32 dosattr)
 936{
 937        int rc;
 938        int oplock = 0;
 939        __u16 netfid;
 940        __u32 netpid;
 941        bool set_time = false;
 942        struct cifsFileInfo *open_file;
 943        struct cifsInodeInfo *cifsInode = CIFS_I(inode);
 944        struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
 945        struct tcon_link *tlink = NULL;
 946        struct cifsTconInfo *pTcon;
 947        FILE_BASIC_INFO info_buf;
 948
 949        if (attrs == NULL)
 950                return -EINVAL;
 951
 952        if (attrs->ia_valid & ATTR_ATIME) {
 953                set_time = true;
 954                info_buf.LastAccessTime =
 955                        cpu_to_le64(cifs_UnixTimeToNT(attrs->ia_atime));
 956        } else
 957                info_buf.LastAccessTime = 0;
 958
 959        if (attrs->ia_valid & ATTR_MTIME) {
 960                set_time = true;
 961                info_buf.LastWriteTime =
 962                    cpu_to_le64(cifs_UnixTimeToNT(attrs->ia_mtime));
 963        } else
 964                info_buf.LastWriteTime = 0;
 965
 966        /*
 967         * Samba throws this field away, but windows may actually use it.
 968         * Do not set ctime unless other time stamps are changed explicitly
 969         * (i.e. by utimes()) since we would then have a mix of client and
 970         * server times.
 971         */
 972        if (set_time && (attrs->ia_valid & ATTR_CTIME)) {
 973                cFYI(1, "CIFS - CTIME changed");
 974                info_buf.ChangeTime =
 975                    cpu_to_le64(cifs_UnixTimeToNT(attrs->ia_ctime));
 976        } else
 977                info_buf.ChangeTime = 0;
 978
 979        info_buf.CreationTime = 0;      /* don't change */
 980        info_buf.Attributes = cpu_to_le32(dosattr);
 981
 982        /*
 983         * If the file is already open for write, just use that fileid
 984         */
 985        open_file = find_writable_file(cifsInode, true);
 986        if (open_file) {
 987                netfid = open_file->netfid;
 988                netpid = open_file->pid;
 989                pTcon = tlink_tcon(open_file->tlink);
 990                goto set_via_filehandle;
 991        }
 992
 993        tlink = cifs_sb_tlink(cifs_sb);
 994        if (IS_ERR(tlink)) {
 995                rc = PTR_ERR(tlink);
 996                tlink = NULL;
 997                goto out;
 998        }
 999        pTcon = tlink_tcon(tlink);
1000
1001        /*
1002         * NT4 apparently returns success on this call, but it doesn't
1003         * really work.
1004         */
1005        if (!(pTcon->ses->flags & CIFS_SES_NT4)) {
1006                rc = CIFSSMBSetPathInfo(xid, pTcon, full_path,
1007                                     &info_buf, cifs_sb->local_nls,
1008                                     cifs_sb->mnt_cifs_flags &
1009                                        CIFS_MOUNT_MAP_SPECIAL_CHR);
1010                if (rc == 0) {
1011                        cifsInode->cifsAttrs = dosattr;
1012                        goto out;
1013                } else if (rc != -EOPNOTSUPP && rc != -EINVAL)
1014                        goto out;
1015        }
1016
1017        cFYI(1, "calling SetFileInfo since SetPathInfo for "
1018                 "times not supported by this server");
1019        rc = CIFSSMBOpen(xid, pTcon, full_path, FILE_OPEN,
1020                         SYNCHRONIZE | FILE_WRITE_ATTRIBUTES,
1021                         CREATE_NOT_DIR, &netfid, &oplock,
1022                         NULL, cifs_sb->local_nls,
1023                         cifs_sb->mnt_cifs_flags &
1024                                CIFS_MOUNT_MAP_SPECIAL_CHR);
1025
1026        if (rc != 0) {
1027                if (rc == -EIO)
1028                        rc = -EINVAL;
1029                goto out;
1030        }
1031
1032        netpid = current->tgid;
1033
1034set_via_filehandle:
1035        rc = CIFSSMBSetFileInfo(xid, pTcon, &info_buf, netfid, netpid);
1036        if (!rc)
1037                cifsInode->cifsAttrs = dosattr;
1038
1039        if (open_file == NULL)
1040                CIFSSMBClose(xid, pTcon, netfid);
1041        else
1042                cifsFileInfo_put(open_file);
1043out:
1044        if (tlink != NULL)
1045                cifs_put_tlink(tlink);
1046        return rc;
1047}
1048
1049/*
1050 * open the given file (if it isn't already), set the DELETE_ON_CLOSE bit
1051 * and rename it to a random name that hopefully won't conflict with
1052 * anything else.
1053 */
1054static int
1055cifs_rename_pending_delete(char *full_path, struct dentry *dentry, int xid)
1056{
1057        int oplock = 0;
1058        int rc;
1059        __u16 netfid;
1060        struct inode *inode = dentry->d_inode;
1061        struct cifsInodeInfo *cifsInode = CIFS_I(inode);
1062        struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
1063        struct tcon_link *tlink;
1064        struct cifsTconInfo *tcon;
1065        __u32 dosattr, origattr;
1066        FILE_BASIC_INFO *info_buf = NULL;
1067
1068        tlink = cifs_sb_tlink(cifs_sb);
1069        if (IS_ERR(tlink))
1070                return PTR_ERR(tlink);
1071        tcon = tlink_tcon(tlink);
1072
1073        rc = CIFSSMBOpen(xid, tcon, full_path, FILE_OPEN,
1074                         DELETE|FILE_WRITE_ATTRIBUTES, CREATE_NOT_DIR,
1075                         &netfid, &oplock, NULL, cifs_sb->local_nls,
1076                         cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
1077        if (rc != 0)
1078                goto out;
1079
1080        origattr = cifsInode->cifsAttrs;
1081        if (origattr == 0)
1082                origattr |= ATTR_NORMAL;
1083
1084        dosattr = origattr & ~ATTR_READONLY;
1085        if (dosattr == 0)
1086                dosattr |= ATTR_NORMAL;
1087        dosattr |= ATTR_HIDDEN;
1088
1089        /* set ATTR_HIDDEN and clear ATTR_READONLY, but only if needed */
1090        if (dosattr != origattr) {
1091                info_buf = kzalloc(sizeof(*info_buf), GFP_KERNEL);
1092                if (info_buf == NULL) {
1093                        rc = -ENOMEM;
1094                        goto out_close;
1095                }
1096                info_buf->Attributes = cpu_to_le32(dosattr);
1097                rc = CIFSSMBSetFileInfo(xid, tcon, info_buf, netfid,
1098                                        current->tgid);
1099                /* although we would like to mark the file hidden
1100                   if that fails we will still try to rename it */
1101                if (rc != 0)
1102                        cifsInode->cifsAttrs = dosattr;
1103                else
1104                        dosattr = origattr; /* since not able to change them */
1105        }
1106
1107        /* rename the file */
1108        rc = CIFSSMBRenameOpenFile(xid, tcon, netfid, NULL, cifs_sb->local_nls,
1109                                   cifs_sb->mnt_cifs_flags &
1110                                            CIFS_MOUNT_MAP_SPECIAL_CHR);
1111        if (rc != 0) {
1112                rc = -ETXTBSY;
1113                goto undo_setattr;
1114        }
1115
1116        /* try to set DELETE_ON_CLOSE */
1117        if (!cifsInode->delete_pending) {
1118                rc = CIFSSMBSetFileDisposition(xid, tcon, true, netfid,
1119                                               current->tgid);
1120                /*
1121                 * some samba versions return -ENOENT when we try to set the
1122                 * file disposition here. Likely a samba bug, but work around
1123                 * it for now. This means that some cifsXXX files may hang
1124                 * around after they shouldn't.
1125                 *
1126                 * BB: remove this hack after more servers have the fix
1127                 */
1128                if (rc == -ENOENT)
1129                        rc = 0;
1130                else if (rc != 0) {
1131                        rc = -ETXTBSY;
1132                        goto undo_rename;
1133                }
1134                cifsInode->delete_pending = true;
1135        }
1136
1137out_close:
1138        CIFSSMBClose(xid, tcon, netfid);
1139out:
1140        kfree(info_buf);
1141        cifs_put_tlink(tlink);
1142        return rc;
1143
1144        /*
1145         * reset everything back to the original state. Don't bother
1146         * dealing with errors here since we can't do anything about
1147         * them anyway.
1148         */
1149undo_rename:
1150        CIFSSMBRenameOpenFile(xid, tcon, netfid, dentry->d_name.name,
1151                                cifs_sb->local_nls, cifs_sb->mnt_cifs_flags &
1152                                            CIFS_MOUNT_MAP_SPECIAL_CHR);
1153undo_setattr:
1154        if (dosattr != origattr) {
1155                info_buf->Attributes = cpu_to_le32(origattr);
1156                if (!CIFSSMBSetFileInfo(xid, tcon, info_buf, netfid,
1157                                        current->tgid))
1158                        cifsInode->cifsAttrs = origattr;
1159        }
1160
1161        goto out_close;
1162}
1163
1164
1165/*
1166 * If dentry->d_inode is null (usually meaning the cached dentry
1167 * is a negative dentry) then we would attempt a standard SMB delete, but
1168 * if that fails we can not attempt the fall back mechanisms on EACCESS
1169 * but will return the EACCESS to the caller. Note that the VFS does not call
1170 * unlink on negative dentries currently.
1171 */
1172int cifs_unlink(struct inode *dir, struct dentry *dentry)
1173{
1174        int rc = 0;
1175        int xid;
1176        char *full_path = NULL;
1177        struct inode *inode = dentry->d_inode;
1178        struct cifsInodeInfo *cifs_inode;
1179        struct super_block *sb = dir->i_sb;
1180        struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
1181        struct tcon_link *tlink;
1182        struct cifsTconInfo *tcon;
1183        struct iattr *attrs = NULL;
1184        __u32 dosattr = 0, origattr = 0;
1185
1186        cFYI(1, "cifs_unlink, dir=0x%p, dentry=0x%p", dir, dentry);
1187
1188        tlink = cifs_sb_tlink(cifs_sb);
1189        if (IS_ERR(tlink))
1190                return PTR_ERR(tlink);
1191        tcon = tlink_tcon(tlink);
1192
1193        xid = GetXid();
1194
1195        /* Unlink can be called from rename so we can not take the
1196         * sb->s_vfs_rename_mutex here */
1197        full_path = build_path_from_dentry(dentry);
1198        if (full_path == NULL) {
1199                rc = -ENOMEM;
1200                goto unlink_out;
1201        }
1202
1203        if ((tcon->ses->capabilities & CAP_UNIX) &&
1204                (CIFS_UNIX_POSIX_PATH_OPS_CAP &
1205                        le64_to_cpu(tcon->fsUnixInfo.Capability))) {
1206                rc = CIFSPOSIXDelFile(xid, tcon, full_path,
1207                        SMB_POSIX_UNLINK_FILE_TARGET, cifs_sb->local_nls,
1208                        cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
1209                cFYI(1, "posix del rc %d", rc);
1210                if ((rc == 0) || (rc == -ENOENT))
1211                        goto psx_del_no_retry;
1212        }
1213
1214retry_std_delete:
1215        rc = CIFSSMBDelFile(xid, tcon, full_path, cifs_sb->local_nls,
1216                        cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
1217
1218psx_del_no_retry:
1219        if (!rc) {
1220                if (inode)
1221                        drop_nlink(inode);
1222        } else if (rc == -ENOENT) {
1223                d_drop(dentry);
1224        } else if (rc == -ETXTBSY) {
1225                rc = cifs_rename_pending_delete(full_path, dentry, xid);
1226                if (rc == 0)
1227                        drop_nlink(inode);
1228        } else if ((rc == -EACCES) && (dosattr == 0) && inode) {
1229                attrs = kzalloc(sizeof(*attrs), GFP_KERNEL);
1230                if (attrs == NULL) {
1231                        rc = -ENOMEM;
1232                        goto out_reval;
1233                }
1234
1235                /* try to reset dos attributes */
1236                cifs_inode = CIFS_I(inode);
1237                origattr = cifs_inode->cifsAttrs;
1238                if (origattr == 0)
1239                        origattr |= ATTR_NORMAL;
1240                dosattr = origattr & ~ATTR_READONLY;
1241                if (dosattr == 0)
1242                        dosattr |= ATTR_NORMAL;
1243                dosattr |= ATTR_HIDDEN;
1244
1245                rc = cifs_set_file_info(inode, attrs, xid, full_path, dosattr);
1246                if (rc != 0)
1247                        goto out_reval;
1248
1249                goto retry_std_delete;
1250        }
1251
1252        /* undo the setattr if we errored out and it's needed */
1253        if (rc != 0 && dosattr != 0)
1254                cifs_set_file_info(inode, attrs, xid, full_path, origattr);
1255
1256out_reval:
1257        if (inode) {
1258                cifs_inode = CIFS_I(inode);
1259                cifs_inode->time = 0;   /* will force revalidate to get info
1260                                           when needed */
1261                inode->i_ctime = current_fs_time(sb);
1262        }
1263        dir->i_ctime = dir->i_mtime = current_fs_time(sb);
1264        cifs_inode = CIFS_I(dir);
1265        CIFS_I(dir)->time = 0;  /* force revalidate of dir as well */
1266unlink_out:
1267        kfree(full_path);
1268        kfree(attrs);
1269        FreeXid(xid);
1270        cifs_put_tlink(tlink);
1271        return rc;
1272}
1273
1274int cifs_mkdir(struct inode *inode, struct dentry *direntry, int mode)
1275{
1276        int rc = 0, tmprc;
1277        int xid;
1278        struct cifs_sb_info *cifs_sb;
1279        struct tcon_link *tlink;
1280        struct cifsTconInfo *pTcon;
1281        char *full_path = NULL;
1282        struct inode *newinode = NULL;
1283        struct cifs_fattr fattr;
1284
1285        cFYI(1, "In cifs_mkdir, mode = 0x%x inode = 0x%p", mode, inode);
1286
1287        cifs_sb = CIFS_SB(inode->i_sb);
1288        tlink = cifs_sb_tlink(cifs_sb);
1289        if (IS_ERR(tlink))
1290                return PTR_ERR(tlink);
1291        pTcon = tlink_tcon(tlink);
1292
1293        xid = GetXid();
1294
1295        full_path = build_path_from_dentry(direntry);
1296        if (full_path == NULL) {
1297                rc = -ENOMEM;
1298                goto mkdir_out;
1299        }
1300
1301        if ((pTcon->ses->capabilities & CAP_UNIX) &&
1302                (CIFS_UNIX_POSIX_PATH_OPS_CAP &
1303                        le64_to_cpu(pTcon->fsUnixInfo.Capability))) {
1304                u32 oplock = 0;
1305                FILE_UNIX_BASIC_INFO *pInfo =
1306                        kzalloc(sizeof(FILE_UNIX_BASIC_INFO), GFP_KERNEL);
1307                if (pInfo == NULL) {
1308                        rc = -ENOMEM;
1309                        goto mkdir_out;
1310                }
1311
1312                mode &= ~current_umask();
1313                rc = CIFSPOSIXCreate(xid, pTcon, SMB_O_DIRECTORY | SMB_O_CREAT,
1314                                mode, NULL /* netfid */, pInfo, &oplock,
1315                                full_path, cifs_sb->local_nls,
1316                                cifs_sb->mnt_cifs_flags &
1317                                        CIFS_MOUNT_MAP_SPECIAL_CHR);
1318                if (rc == -EOPNOTSUPP) {
1319                        kfree(pInfo);
1320                        goto mkdir_retry_old;
1321                } else if (rc) {
1322                        cFYI(1, "posix mkdir returned 0x%x", rc);
1323                        d_drop(direntry);
1324                } else {
1325                        if (pInfo->Type == cpu_to_le32(-1)) {
1326                                /* no return info, go query for it */
1327                                kfree(pInfo);
1328                                goto mkdir_get_info;
1329                        }
1330/*BB check (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID ) to see if need
1331        to set uid/gid */
1332                        inc_nlink(inode);
1333
1334                        cifs_unix_basic_to_fattr(&fattr, pInfo, cifs_sb);
1335                        cifs_fill_uniqueid(inode->i_sb, &fattr);
1336                        newinode = cifs_iget(inode->i_sb, &fattr);
1337                        if (!newinode) {
1338                                kfree(pInfo);
1339                                goto mkdir_get_info;
1340                        }
1341
1342                        d_instantiate(direntry, newinode);
1343
1344#ifdef CONFIG_CIFS_DEBUG2
1345                        cFYI(1, "instantiated dentry %p %s to inode %p",
1346                                direntry, direntry->d_name.name, newinode);
1347
1348                        if (newinode->i_nlink != 2)
1349                                cFYI(1, "unexpected number of links %d",
1350                                        newinode->i_nlink);
1351#endif
1352                }
1353                kfree(pInfo);
1354                goto mkdir_out;
1355        }
1356mkdir_retry_old:
1357        /* BB add setting the equivalent of mode via CreateX w/ACLs */
1358        rc = CIFSSMBMkDir(xid, pTcon, full_path, cifs_sb->local_nls,
1359                          cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
1360        if (rc) {
1361                cFYI(1, "cifs_mkdir returned 0x%x", rc);
1362                d_drop(direntry);
1363        } else {
1364mkdir_get_info:
1365                inc_nlink(inode);
1366                if (pTcon->unix_ext)
1367                        rc = cifs_get_inode_info_unix(&newinode, full_path,
1368                                                      inode->i_sb, xid);
1369                else
1370                        rc = cifs_get_inode_info(&newinode, full_path, NULL,
1371                                                 inode->i_sb, xid, NULL);
1372
1373                d_instantiate(direntry, newinode);
1374                 /* setting nlink not necessary except in cases where we
1375                  * failed to get it from the server or was set bogus */
1376                if ((direntry->d_inode) && (direntry->d_inode->i_nlink < 2))
1377                                direntry->d_inode->i_nlink = 2;
1378
1379                mode &= ~current_umask();
1380                /* must turn on setgid bit if parent dir has it */
1381                if (inode->i_mode & S_ISGID)
1382                        mode |= S_ISGID;
1383
1384                if (pTcon->unix_ext) {
1385                        struct cifs_unix_set_info_args args = {
1386                                .mode   = mode,
1387                                .ctime  = NO_CHANGE_64,
1388                                .atime  = NO_CHANGE_64,
1389                                .mtime  = NO_CHANGE_64,
1390                                .device = 0,
1391                        };
1392                        if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) {
1393                                args.uid = (__u64)current_fsuid();
1394                                if (inode->i_mode & S_ISGID)
1395                                        args.gid = (__u64)inode->i_gid;
1396                                else
1397                                        args.gid = (__u64)current_fsgid();
1398                        } else {
1399                                args.uid = NO_CHANGE_64;
1400                                args.gid = NO_CHANGE_64;
1401                        }
1402                        CIFSSMBUnixSetPathInfo(xid, pTcon, full_path, &args,
1403                                               cifs_sb->local_nls,
1404                                               cifs_sb->mnt_cifs_flags &
1405                                                CIFS_MOUNT_MAP_SPECIAL_CHR);
1406                } else {
1407                        if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) &&
1408                            (mode & S_IWUGO) == 0) {
1409                                FILE_BASIC_INFO pInfo;
1410                                struct cifsInodeInfo *cifsInode;
1411                                u32 dosattrs;
1412
1413                                memset(&pInfo, 0, sizeof(pInfo));
1414                                cifsInode = CIFS_I(newinode);
1415                                dosattrs = cifsInode->cifsAttrs|ATTR_READONLY;
1416                                pInfo.Attributes = cpu_to_le32(dosattrs);
1417                                tmprc = CIFSSMBSetPathInfo(xid, pTcon,
1418                                                full_path, &pInfo,
1419                                                cifs_sb->local_nls,
1420                                                cifs_sb->mnt_cifs_flags &
1421                                                CIFS_MOUNT_MAP_SPECIAL_CHR);
1422                                if (tmprc == 0)
1423                                        cifsInode->cifsAttrs = dosattrs;
1424                        }
1425                        if (direntry->d_inode) {
1426                                if (cifs_sb->mnt_cifs_flags &
1427                                     CIFS_MOUNT_DYNPERM)
1428                                        direntry->d_inode->i_mode =
1429                                                (mode | S_IFDIR);
1430
1431                                if (cifs_sb->mnt_cifs_flags &
1432                                     CIFS_MOUNT_SET_UID) {
1433                                        direntry->d_inode->i_uid =
1434                                                current_fsuid();
1435                                        if (inode->i_mode & S_ISGID)
1436                                                direntry->d_inode->i_gid =
1437                                                        inode->i_gid;
1438                                        else
1439                                                direntry->d_inode->i_gid =
1440                                                        current_fsgid();
1441                                }
1442                        }
1443                }
1444        }
1445mkdir_out:
1446        kfree(full_path);
1447        FreeXid(xid);
1448        cifs_put_tlink(tlink);
1449        return rc;
1450}
1451
1452int cifs_rmdir(struct inode *inode, struct dentry *direntry)
1453{
1454        int rc = 0;
1455        int xid;
1456        struct cifs_sb_info *cifs_sb;
1457        struct tcon_link *tlink;
1458        struct cifsTconInfo *pTcon;
1459        char *full_path = NULL;
1460        struct cifsInodeInfo *cifsInode;
1461
1462        cFYI(1, "cifs_rmdir, inode = 0x%p", inode);
1463
1464        xid = GetXid();
1465
1466        full_path = build_path_from_dentry(direntry);
1467        if (full_path == NULL) {
1468                rc = -ENOMEM;
1469                goto rmdir_exit;
1470        }
1471
1472        cifs_sb = CIFS_SB(inode->i_sb);
1473        tlink = cifs_sb_tlink(cifs_sb);
1474        if (IS_ERR(tlink)) {
1475                rc = PTR_ERR(tlink);
1476                goto rmdir_exit;
1477        }
1478        pTcon = tlink_tcon(tlink);
1479
1480        rc = CIFSSMBRmDir(xid, pTcon, full_path, cifs_sb->local_nls,
1481                          cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
1482        cifs_put_tlink(tlink);
1483
1484        if (!rc) {
1485                drop_nlink(inode);
1486                spin_lock(&direntry->d_inode->i_lock);
1487                i_size_write(direntry->d_inode, 0);
1488                clear_nlink(direntry->d_inode);
1489                spin_unlock(&direntry->d_inode->i_lock);
1490        }
1491
1492        cifsInode = CIFS_I(direntry->d_inode);
1493        cifsInode->time = 0;    /* force revalidate to go get info when
1494                                   needed */
1495
1496        cifsInode = CIFS_I(inode);
1497        cifsInode->time = 0;    /* force revalidate to get parent dir info
1498                                   since cached search results now invalid */
1499
1500        direntry->d_inode->i_ctime = inode->i_ctime = inode->i_mtime =
1501                current_fs_time(inode->i_sb);
1502
1503rmdir_exit:
1504        kfree(full_path);
1505        FreeXid(xid);
1506        return rc;
1507}
1508
1509static int
1510cifs_do_rename(int xid, struct dentry *from_dentry, const char *fromPath,
1511                struct dentry *to_dentry, const char *toPath)
1512{
1513        struct cifs_sb_info *cifs_sb = CIFS_SB(from_dentry->d_sb);
1514        struct tcon_link *tlink;
1515        struct cifsTconInfo *pTcon;
1516        __u16 srcfid;
1517        int oplock, rc;
1518
1519        tlink = cifs_sb_tlink(cifs_sb);
1520        if (IS_ERR(tlink))
1521                return PTR_ERR(tlink);
1522        pTcon = tlink_tcon(tlink);
1523
1524        /* try path-based rename first */
1525        rc = CIFSSMBRename(xid, pTcon, fromPath, toPath, cifs_sb->local_nls,
1526                           cifs_sb->mnt_cifs_flags &
1527                                CIFS_MOUNT_MAP_SPECIAL_CHR);
1528
1529        /*
1530         * don't bother with rename by filehandle unless file is busy and
1531         * source Note that cross directory moves do not work with
1532         * rename by filehandle to various Windows servers.
1533         */
1534        if (rc == 0 || rc != -ETXTBSY)
1535                goto do_rename_exit;
1536
1537        /* open-file renames don't work across directories */
1538        if (to_dentry->d_parent != from_dentry->d_parent)
1539                goto do_rename_exit;
1540
1541        /* open the file to be renamed -- we need DELETE perms */
1542        rc = CIFSSMBOpen(xid, pTcon, fromPath, FILE_OPEN, DELETE,
1543                         CREATE_NOT_DIR, &srcfid, &oplock, NULL,
1544                         cifs_sb->local_nls, cifs_sb->mnt_cifs_flags &
1545                                CIFS_MOUNT_MAP_SPECIAL_CHR);
1546
1547        if (rc == 0) {
1548                rc = CIFSSMBRenameOpenFile(xid, pTcon, srcfid,
1549                                (const char *) to_dentry->d_name.name,
1550                                cifs_sb->local_nls, cifs_sb->mnt_cifs_flags &
1551                                        CIFS_MOUNT_MAP_SPECIAL_CHR);
1552
1553                CIFSSMBClose(xid, pTcon, srcfid);
1554        }
1555do_rename_exit:
1556        cifs_put_tlink(tlink);
1557        return rc;
1558}
1559
1560int cifs_rename(struct inode *source_dir, struct dentry *source_dentry,
1561        struct inode *target_dir, struct dentry *target_dentry)
1562{
1563        char *fromName = NULL;
1564        char *toName = NULL;
1565        struct cifs_sb_info *cifs_sb;
1566        struct tcon_link *tlink;
1567        struct cifsTconInfo *tcon;
1568        FILE_UNIX_BASIC_INFO *info_buf_source = NULL;
1569        FILE_UNIX_BASIC_INFO *info_buf_target;
1570        int xid, rc, tmprc;
1571
1572        cifs_sb = CIFS_SB(source_dir->i_sb);
1573        tlink = cifs_sb_tlink(cifs_sb);
1574        if (IS_ERR(tlink))
1575                return PTR_ERR(tlink);
1576        tcon = tlink_tcon(tlink);
1577
1578        xid = GetXid();
1579
1580        /*
1581         * we already have the rename sem so we do not need to
1582         * grab it again here to protect the path integrity
1583         */
1584        fromName = build_path_from_dentry(source_dentry);
1585        if (fromName == NULL) {
1586                rc = -ENOMEM;
1587                goto cifs_rename_exit;
1588        }
1589
1590        toName = build_path_from_dentry(target_dentry);
1591        if (toName == NULL) {
1592                rc = -ENOMEM;
1593                goto cifs_rename_exit;
1594        }
1595
1596        rc = cifs_do_rename(xid, source_dentry, fromName,
1597                            target_dentry, toName);
1598
1599        if (rc == -EEXIST && tcon->unix_ext) {
1600                /*
1601                 * Are src and dst hardlinks of same inode? We can
1602                 * only tell with unix extensions enabled
1603                 */
1604                info_buf_source =
1605                        kmalloc(2 * sizeof(FILE_UNIX_BASIC_INFO),
1606                                        GFP_KERNEL);
1607                if (info_buf_source == NULL) {
1608                        rc = -ENOMEM;
1609                        goto cifs_rename_exit;
1610                }
1611
1612                info_buf_target = info_buf_source + 1;
1613                tmprc = CIFSSMBUnixQPathInfo(xid, tcon, fromName,
1614                                        info_buf_source,
1615                                        cifs_sb->local_nls,
1616                                        cifs_sb->mnt_cifs_flags &
1617                                        CIFS_MOUNT_MAP_SPECIAL_CHR);
1618                if (tmprc != 0)
1619                        goto unlink_target;
1620
1621                tmprc = CIFSSMBUnixQPathInfo(xid, tcon, toName,
1622                                        info_buf_target,
1623                                        cifs_sb->local_nls,
1624                                        cifs_sb->mnt_cifs_flags &
1625                                        CIFS_MOUNT_MAP_SPECIAL_CHR);
1626
1627                if (tmprc == 0 && (info_buf_source->UniqueId ==
1628                                   info_buf_target->UniqueId)) {
1629                        /* same file, POSIX says that this is a noop */
1630                        rc = 0;
1631                        goto cifs_rename_exit;
1632                }
1633        } /* else ... BB we could add the same check for Windows by
1634                     checking the UniqueId via FILE_INTERNAL_INFO */
1635
1636unlink_target:
1637        /* Try unlinking the target dentry if it's not negative */
1638        if (target_dentry->d_inode && (rc == -EACCES || rc == -EEXIST)) {
1639                tmprc = cifs_unlink(target_dir, target_dentry);
1640                if (tmprc)
1641                        goto cifs_rename_exit;
1642
1643                rc = cifs_do_rename(xid, source_dentry, fromName,
1644                                    target_dentry, toName);
1645        }
1646
1647cifs_rename_exit:
1648        kfree(info_buf_source);
1649        kfree(fromName);
1650        kfree(toName);
1651        FreeXid(xid);
1652        cifs_put_tlink(tlink);
1653        return rc;
1654}
1655
1656static bool
1657cifs_inode_needs_reval(struct inode *inode)
1658{
1659        struct cifsInodeInfo *cifs_i = CIFS_I(inode);
1660        struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
1661
1662        if (cifs_i->clientCanCacheRead)
1663                return false;
1664
1665        if (!lookupCacheEnabled)
1666                return true;
1667
1668        if (cifs_i->time == 0)
1669                return true;
1670
1671        if (!time_in_range(jiffies, cifs_i->time,
1672                                cifs_i->time + cifs_sb->actimeo))
1673                return true;
1674
1675        /* hardlinked files w/ noserverino get "special" treatment */
1676        if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) &&
1677            S_ISREG(inode->i_mode) && inode->i_nlink != 1)
1678                return true;
1679
1680        return false;
1681}
1682
1683/*
1684 * Zap the cache. Called when invalid_mapping flag is set.
1685 */
1686void
1687cifs_invalidate_mapping(struct inode *inode)
1688{
1689        int rc;
1690        struct cifsInodeInfo *cifs_i = CIFS_I(inode);
1691
1692        cifs_i->invalid_mapping = false;
1693
1694        /* write back any cached data */
1695        if (inode->i_mapping && inode->i_mapping->nrpages != 0) {
1696                rc = filemap_write_and_wait(inode->i_mapping);
1697                mapping_set_error(inode->i_mapping, rc);
1698        }
1699        invalidate_remote_inode(inode);
1700        cifs_fscache_reset_inode_cookie(inode);
1701}
1702
1703int cifs_revalidate_file(struct file *filp)
1704{
1705        int rc = 0;
1706        struct inode *inode = filp->f_path.dentry->d_inode;
1707        struct cifsFileInfo *cfile = (struct cifsFileInfo *) filp->private_data;
1708
1709        if (!cifs_inode_needs_reval(inode))
1710                goto check_inval;
1711
1712        if (tlink_tcon(cfile->tlink)->unix_ext)
1713                rc = cifs_get_file_info_unix(filp);
1714        else
1715                rc = cifs_get_file_info(filp);
1716
1717check_inval:
1718        if (CIFS_I(inode)->invalid_mapping)
1719                cifs_invalidate_mapping(inode);
1720
1721        return rc;
1722}
1723
1724/* revalidate a dentry's inode attributes */
1725int cifs_revalidate_dentry(struct dentry *dentry)
1726{
1727        int xid;
1728        int rc = 0;
1729        char *full_path = NULL;
1730        struct inode *inode = dentry->d_inode;
1731        struct super_block *sb = dentry->d_sb;
1732
1733        if (inode == NULL)
1734                return -ENOENT;
1735
1736        xid = GetXid();
1737
1738        if (!cifs_inode_needs_reval(inode))
1739                goto check_inval;
1740
1741        /* can not safely grab the rename sem here if rename calls revalidate
1742           since that would deadlock */
1743        full_path = build_path_from_dentry(dentry);
1744        if (full_path == NULL) {
1745                rc = -ENOMEM;
1746                goto check_inval;
1747        }
1748
1749        cFYI(1, "Revalidate: %s inode 0x%p count %d dentry: 0x%p d_time %ld "
1750                 "jiffies %ld", full_path, inode, inode->i_count.counter,
1751                 dentry, dentry->d_time, jiffies);
1752
1753        if (cifs_sb_master_tcon(CIFS_SB(sb))->unix_ext)
1754                rc = cifs_get_inode_info_unix(&inode, full_path, sb, xid);
1755        else
1756                rc = cifs_get_inode_info(&inode, full_path, NULL, sb,
1757                                         xid, NULL);
1758
1759check_inval:
1760        if (CIFS_I(inode)->invalid_mapping)
1761                cifs_invalidate_mapping(inode);
1762
1763        kfree(full_path);
1764        FreeXid(xid);
1765        return rc;
1766}
1767
1768int cifs_getattr(struct vfsmount *mnt, struct dentry *dentry,
1769                 struct kstat *stat)
1770{
1771        struct cifs_sb_info *cifs_sb = CIFS_SB(dentry->d_sb);
1772        struct cifsTconInfo *tcon = cifs_sb_master_tcon(cifs_sb);
1773        int err = cifs_revalidate_dentry(dentry);
1774
1775        if (!err) {
1776                generic_fillattr(dentry->d_inode, stat);
1777                stat->blksize = CIFS_MAX_MSGSIZE;
1778                stat->ino = CIFS_I(dentry->d_inode)->uniqueid;
1779
1780                /*
1781                 * If on a multiuser mount without unix extensions, and the
1782                 * admin hasn't overridden them, set the ownership to the
1783                 * fsuid/fsgid of the current process.
1784                 */
1785                if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MULTIUSER) &&
1786                    !tcon->unix_ext) {
1787                        if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_UID))
1788                                stat->uid = current_fsuid();
1789                        if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_GID))
1790                                stat->gid = current_fsgid();
1791                }
1792        }
1793        return err;
1794}
1795
1796static int cifs_truncate_page(struct address_space *mapping, loff_t from)
1797{
1798        pgoff_t index = from >> PAGE_CACHE_SHIFT;
1799        unsigned offset = from & (PAGE_CACHE_SIZE - 1);
1800        struct page *page;
1801        int rc = 0;
1802
1803        page = grab_cache_page(mapping, index);
1804        if (!page)
1805                return -ENOMEM;
1806
1807        zero_user_segment(page, offset, PAGE_CACHE_SIZE);
1808        unlock_page(page);
1809        page_cache_release(page);
1810        return rc;
1811}
1812
1813static void cifs_setsize(struct inode *inode, loff_t offset)
1814{
1815        loff_t oldsize;
1816
1817        spin_lock(&inode->i_lock);
1818        oldsize = inode->i_size;
1819        i_size_write(inode, offset);
1820        spin_unlock(&inode->i_lock);
1821
1822        truncate_pagecache(inode, oldsize, offset);
1823}
1824
1825static int
1826cifs_set_file_size(struct inode *inode, struct iattr *attrs,
1827                   int xid, char *full_path)
1828{
1829        int rc;
1830        struct cifsFileInfo *open_file;
1831        struct cifsInodeInfo *cifsInode = CIFS_I(inode);
1832        struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
1833        struct tcon_link *tlink = NULL;
1834        struct cifsTconInfo *pTcon = NULL;
1835
1836        /*
1837         * To avoid spurious oplock breaks from server, in the case of
1838         * inodes that we already have open, avoid doing path based
1839         * setting of file size if we can do it by handle.
1840         * This keeps our caching token (oplock) and avoids timeouts
1841         * when the local oplock break takes longer to flush
1842         * writebehind data than the SMB timeout for the SetPathInfo
1843         * request would allow
1844         */
1845        open_file = find_writable_file(cifsInode, true);
1846        if (open_file) {
1847                __u16 nfid = open_file->netfid;
1848                __u32 npid = open_file->pid;
1849                pTcon = tlink_tcon(open_file->tlink);
1850                rc = CIFSSMBSetFileSize(xid, pTcon, attrs->ia_size, nfid,
1851                                        npid, false);
1852                cifsFileInfo_put(open_file);
1853                cFYI(1, "SetFSize for attrs rc = %d", rc);
1854                if ((rc == -EINVAL) || (rc == -EOPNOTSUPP)) {
1855                        unsigned int bytes_written;
1856                        rc = CIFSSMBWrite(xid, pTcon, nfid, 0, attrs->ia_size,
1857                                          &bytes_written, NULL, NULL, 1);
1858                        cFYI(1, "Wrt seteof rc %d", rc);
1859                }
1860        } else
1861                rc = -EINVAL;
1862
1863        if (rc != 0) {
1864                if (pTcon == NULL) {
1865                        tlink = cifs_sb_tlink(cifs_sb);
1866                        if (IS_ERR(tlink))
1867                                return PTR_ERR(tlink);
1868                        pTcon = tlink_tcon(tlink);
1869                }
1870
1871                /* Set file size by pathname rather than by handle
1872                   either because no valid, writeable file handle for
1873                   it was found or because there was an error setting
1874                   it by handle */
1875                rc = CIFSSMBSetEOF(xid, pTcon, full_path, attrs->ia_size,
1876                                   false, cifs_sb->local_nls,
1877                                   cifs_sb->mnt_cifs_flags &
1878                                        CIFS_MOUNT_MAP_SPECIAL_CHR);
1879                cFYI(1, "SetEOF by path (setattrs) rc = %d", rc);
1880                if ((rc == -EINVAL) || (rc == -EOPNOTSUPP)) {
1881                        __u16 netfid;
1882                        int oplock = 0;
1883
1884                        rc = SMBLegacyOpen(xid, pTcon, full_path,
1885                                FILE_OPEN, GENERIC_WRITE,
1886                                CREATE_NOT_DIR, &netfid, &oplock, NULL,
1887                                cifs_sb->local_nls,
1888                                cifs_sb->mnt_cifs_flags &
1889                                        CIFS_MOUNT_MAP_SPECIAL_CHR);
1890                        if (rc == 0) {
1891                                unsigned int bytes_written;
1892                                rc = CIFSSMBWrite(xid, pTcon, netfid, 0,
1893                                                  attrs->ia_size,
1894                                                  &bytes_written, NULL,
1895                                                  NULL, 1);
1896                                cFYI(1, "wrt seteof rc %d", rc);
1897                                CIFSSMBClose(xid, pTcon, netfid);
1898                        }
1899                }
1900                if (tlink)
1901                        cifs_put_tlink(tlink);
1902        }
1903
1904        if (rc == 0) {
1905                cifsInode->server_eof = attrs->ia_size;
1906                cifs_setsize(inode, attrs->ia_size);
1907                cifs_truncate_page(inode->i_mapping, inode->i_size);
1908        }
1909
1910        return rc;
1911}
1912
1913static int
1914cifs_setattr_unix(struct dentry *direntry, struct iattr *attrs)
1915{
1916        int rc;
1917        int xid;
1918        char *full_path = NULL;
1919        struct inode *inode = direntry->d_inode;
1920        struct cifsInodeInfo *cifsInode = CIFS_I(inode);
1921        struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
1922        struct tcon_link *tlink;
1923        struct cifsTconInfo *pTcon;
1924        struct cifs_unix_set_info_args *args = NULL;
1925        struct cifsFileInfo *open_file;
1926
1927        cFYI(1, "setattr_unix on file %s attrs->ia_valid=0x%x",
1928                 direntry->d_name.name, attrs->ia_valid);
1929
1930        xid = GetXid();
1931
1932        if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_PERM)
1933                attrs->ia_valid |= ATTR_FORCE;
1934
1935        rc = inode_change_ok(inode, attrs);
1936        if (rc < 0)
1937                goto out;
1938
1939        full_path = build_path_from_dentry(direntry);
1940        if (full_path == NULL) {
1941                rc = -ENOMEM;
1942                goto out;
1943        }
1944
1945        /*
1946         * Attempt to flush data before changing attributes. We need to do
1947         * this for ATTR_SIZE and ATTR_MTIME for sure, and if we change the
1948         * ownership or mode then we may also need to do this. Here, we take
1949         * the safe way out and just do the flush on all setattr requests. If
1950         * the flush returns error, store it to report later and continue.
1951         *
1952         * BB: This should be smarter. Why bother flushing pages that
1953         * will be truncated anyway? Also, should we error out here if
1954         * the flush returns error?
1955         */
1956        rc = filemap_write_and_wait(inode->i_mapping);
1957        mapping_set_error(inode->i_mapping, rc);
1958        rc = 0;
1959
1960        if (attrs->ia_valid & ATTR_SIZE) {
1961                rc = cifs_set_file_size(inode, attrs, xid, full_path);
1962                if (rc != 0)
1963                        goto out;
1964        }
1965
1966        /* skip mode change if it's just for clearing setuid/setgid */
1967        if (attrs->ia_valid & (ATTR_KILL_SUID|ATTR_KILL_SGID))
1968                attrs->ia_valid &= ~ATTR_MODE;
1969
1970        args = kmalloc(sizeof(*args), GFP_KERNEL);
1971        if (args == NULL) {
1972                rc = -ENOMEM;
1973                goto out;
1974        }
1975
1976        /* set up the struct */
1977        if (attrs->ia_valid & ATTR_MODE)
1978                args->mode = attrs->ia_mode;
1979        else
1980                args->mode = NO_CHANGE_64;
1981
1982        if (attrs->ia_valid & ATTR_UID)
1983                args->uid = attrs->ia_uid;
1984        else
1985                args->uid = NO_CHANGE_64;
1986
1987        if (attrs->ia_valid & ATTR_GID)
1988                args->gid = attrs->ia_gid;
1989        else
1990                args->gid = NO_CHANGE_64;
1991
1992        if (attrs->ia_valid & ATTR_ATIME)
1993                args->atime = cifs_UnixTimeToNT(attrs->ia_atime);
1994        else
1995                args->atime = NO_CHANGE_64;
1996
1997        if (attrs->ia_valid & ATTR_MTIME)
1998                args->mtime = cifs_UnixTimeToNT(attrs->ia_mtime);
1999        else
2000                args->mtime = NO_CHANGE_64;
2001
2002        if (attrs->ia_valid & ATTR_CTIME)
2003                args->ctime = cifs_UnixTimeToNT(attrs->ia_ctime);
2004        else
2005                args->ctime = NO_CHANGE_64;
2006
2007        args->device = 0;
2008        open_file = find_writable_file(cifsInode, true);
2009        if (open_file) {
2010                u16 nfid = open_file->netfid;
2011                u32 npid = open_file->pid;
2012                pTcon = tlink_tcon(open_file->tlink);
2013                rc = CIFSSMBUnixSetFileInfo(xid, pTcon, args, nfid, npid);
2014                cifsFileInfo_put(open_file);
2015        } else {
2016                tlink = cifs_sb_tlink(cifs_sb);
2017                if (IS_ERR(tlink)) {
2018                        rc = PTR_ERR(tlink);
2019                        goto out;
2020                }
2021                pTcon = tlink_tcon(tlink);
2022                rc = CIFSSMBUnixSetPathInfo(xid, pTcon, full_path, args,
2023                                    cifs_sb->local_nls,
2024                                    cifs_sb->mnt_cifs_flags &
2025                                        CIFS_MOUNT_MAP_SPECIAL_CHR);
2026                cifs_put_tlink(tlink);
2027        }
2028
2029        if (rc)
2030                goto out;
2031
2032        if ((attrs->ia_valid & ATTR_SIZE) &&
2033            attrs->ia_size != i_size_read(inode))
2034                truncate_setsize(inode, attrs->ia_size);
2035
2036        setattr_copy(inode, attrs);
2037        mark_inode_dirty(inode);
2038
2039        /* force revalidate when any of these times are set since some
2040           of the fs types (eg ext3, fat) do not have fine enough
2041           time granularity to match protocol, and we do not have a
2042           a way (yet) to query the server fs's time granularity (and
2043           whether it rounds times down).
2044        */
2045        if (attrs->ia_valid & (ATTR_MTIME | ATTR_CTIME))
2046                cifsInode->time = 0;
2047out:
2048        kfree(args);
2049        kfree(full_path);
2050        FreeXid(xid);
2051        return rc;
2052}
2053
2054static int
2055cifs_setattr_nounix(struct dentry *direntry, struct iattr *attrs)
2056{
2057        int xid;
2058        struct inode *inode = direntry->d_inode;
2059        struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
2060        struct cifsInodeInfo *cifsInode = CIFS_I(inode);
2061        char *full_path = NULL;
2062        int rc = -EACCES;
2063        __u32 dosattr = 0;
2064        __u64 mode = NO_CHANGE_64;
2065
2066        xid = GetXid();
2067
2068        cFYI(1, "setattr on file %s attrs->iavalid 0x%x",
2069                 direntry->d_name.name, attrs->ia_valid);
2070
2071        if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_PERM)
2072                attrs->ia_valid |= ATTR_FORCE;
2073
2074        rc = inode_change_ok(inode, attrs);
2075        if (rc < 0) {
2076                FreeXid(xid);
2077                return rc;
2078        }
2079
2080        full_path = build_path_from_dentry(direntry);
2081        if (full_path == NULL) {
2082                rc = -ENOMEM;
2083                FreeXid(xid);
2084                return rc;
2085        }
2086
2087        /*
2088         * Attempt to flush data before changing attributes. We need to do
2089         * this for ATTR_SIZE and ATTR_MTIME for sure, and if we change the
2090         * ownership or mode then we may also need to do this. Here, we take
2091         * the safe way out and just do the flush on all setattr requests. If
2092         * the flush returns error, store it to report later and continue.
2093         *
2094         * BB: This should be smarter. Why bother flushing pages that
2095         * will be truncated anyway? Also, should we error out here if
2096         * the flush returns error?
2097         */
2098        rc = filemap_write_and_wait(inode->i_mapping);
2099        mapping_set_error(inode->i_mapping, rc);
2100        rc = 0;
2101
2102        if (attrs->ia_valid & ATTR_SIZE) {
2103                rc = cifs_set_file_size(inode, attrs, xid, full_path);
2104                if (rc != 0)
2105                        goto cifs_setattr_exit;
2106        }
2107
2108        /*
2109         * Without unix extensions we can't send ownership changes to the
2110         * server, so silently ignore them. This is consistent with how
2111         * local DOS/Windows filesystems behave (VFAT, NTFS, etc). With
2112         * CIFSACL support + proper Windows to Unix idmapping, we may be
2113         * able to support this in the future.
2114         */
2115        if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID))
2116                attrs->ia_valid &= ~(ATTR_UID | ATTR_GID);
2117
2118        /* skip mode change if it's just for clearing setuid/setgid */
2119        if (attrs->ia_valid & (ATTR_KILL_SUID|ATTR_KILL_SGID))
2120                attrs->ia_valid &= ~ATTR_MODE;
2121
2122        if (attrs->ia_valid & ATTR_MODE) {
2123                cFYI(1, "Mode changed to 0%o", attrs->ia_mode);
2124                mode = attrs->ia_mode;
2125        }
2126
2127        if (attrs->ia_valid & ATTR_MODE) {
2128                rc = 0;
2129#ifdef CONFIG_CIFS_ACL
2130                if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) {
2131                        rc = mode_to_cifs_acl(inode, full_path, mode);
2132                        if (rc) {
2133                                cFYI(1, "%s: Setting ACL failed with error: %d",
2134                                        __func__, rc);
2135                                goto cifs_setattr_exit;
2136                        }
2137                } else
2138#endif /* CONFIG_CIFS_ACL */
2139                if (((mode & S_IWUGO) == 0) &&
2140                    (cifsInode->cifsAttrs & ATTR_READONLY) == 0) {
2141
2142                        dosattr = cifsInode->cifsAttrs | ATTR_READONLY;
2143
2144                        /* fix up mode if we're not using dynperm */
2145                        if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DYNPERM) == 0)
2146                                attrs->ia_mode = inode->i_mode & ~S_IWUGO;
2147                } else if ((mode & S_IWUGO) &&
2148                           (cifsInode->cifsAttrs & ATTR_READONLY)) {
2149
2150                        dosattr = cifsInode->cifsAttrs & ~ATTR_READONLY;
2151                        /* Attributes of 0 are ignored */
2152                        if (dosattr == 0)
2153                                dosattr |= ATTR_NORMAL;
2154
2155                        /* reset local inode permissions to normal */
2156                        if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DYNPERM)) {
2157                                attrs->ia_mode &= ~(S_IALLUGO);
2158                                if (S_ISDIR(inode->i_mode))
2159                                        attrs->ia_mode |=
2160                                                cifs_sb->mnt_dir_mode;
2161                                else
2162                                        attrs->ia_mode |=
2163                                                cifs_sb->mnt_file_mode;
2164                        }
2165                } else if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DYNPERM)) {
2166                        /* ignore mode change - ATTR_READONLY hasn't changed */
2167                        attrs->ia_valid &= ~ATTR_MODE;
2168                }
2169        }
2170
2171        if (attrs->ia_valid & (ATTR_MTIME|ATTR_ATIME|ATTR_CTIME) ||
2172            ((attrs->ia_valid & ATTR_MODE) && dosattr)) {
2173                rc = cifs_set_file_info(inode, attrs, xid, full_path, dosattr);
2174                /* BB: check for rc = -EOPNOTSUPP and switch to legacy mode */
2175
2176                /* Even if error on time set, no sense failing the call if
2177                the server would set the time to a reasonable value anyway,
2178                and this check ensures that we are not being called from
2179                sys_utimes in which case we ought to fail the call back to
2180                the user when the server rejects the call */
2181                if ((rc) && (attrs->ia_valid &
2182                                (ATTR_MODE | ATTR_GID | ATTR_UID | ATTR_SIZE)))
2183                        rc = 0;
2184        }
2185
2186        /* do not need local check to inode_check_ok since the server does
2187           that */
2188        if (rc)
2189                goto cifs_setattr_exit;
2190
2191        if ((attrs->ia_valid & ATTR_SIZE) &&
2192            attrs->ia_size != i_size_read(inode))
2193                truncate_setsize(inode, attrs->ia_size);
2194
2195        setattr_copy(inode, attrs);
2196        mark_inode_dirty(inode);
2197
2198cifs_setattr_exit:
2199        kfree(full_path);
2200        FreeXid(xid);
2201        return rc;
2202}
2203
2204int
2205cifs_setattr(struct dentry *direntry, struct iattr *attrs)
2206{
2207        struct inode *inode = direntry->d_inode;
2208        struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
2209        struct cifsTconInfo *pTcon = cifs_sb_master_tcon(cifs_sb);
2210
2211        if (pTcon->unix_ext)
2212                return cifs_setattr_unix(direntry, attrs);
2213
2214        return cifs_setattr_nounix(direntry, attrs);
2215
2216        /* BB: add cifs_setattr_legacy for really old servers */
2217}
2218
2219#if 0
2220void cifs_delete_inode(struct inode *inode)
2221{
2222        cFYI(1, "In cifs_delete_inode, inode = 0x%p", inode);
2223        /* may have to add back in if and when safe distributed caching of
2224           directories added e.g. via FindNotify */
2225}
2226#endif
2227