linux/fs/9p/vfs_inode_dotl.c
<<
>>
Prefs
   1/*
   2 *  linux/fs/9p/vfs_inode_dotl.c
   3 *
   4 * This file contains vfs inode ops for the 9P2000.L protocol.
   5 *
   6 *  Copyright (C) 2004 by Eric Van Hensbergen <ericvh@gmail.com>
   7 *  Copyright (C) 2002 by Ron Minnich <rminnich@lanl.gov>
   8 *
   9 *  This program is free software; you can redistribute it and/or modify
  10 *  it under the terms of the GNU General Public License version 2
  11 *  as published by the Free Software Foundation.
  12 *
  13 *  This program is distributed in the hope that it will be useful,
  14 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  15 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16 *  GNU General Public License for more details.
  17 *
  18 *  You should have received a copy of the GNU General Public License
  19 *  along with this program; if not, write to:
  20 *  Free Software Foundation
  21 *  51 Franklin Street, Fifth Floor
  22 *  Boston, MA  02111-1301  USA
  23 *
  24 */
  25
  26#include <linux/module.h>
  27#include <linux/errno.h>
  28#include <linux/fs.h>
  29#include <linux/file.h>
  30#include <linux/pagemap.h>
  31#include <linux/stat.h>
  32#include <linux/string.h>
  33#include <linux/inet.h>
  34#include <linux/namei.h>
  35#include <linux/idr.h>
  36#include <linux/sched.h>
  37#include <linux/slab.h>
  38#include <linux/xattr.h>
  39#include <linux/posix_acl.h>
  40#include <net/9p/9p.h>
  41#include <net/9p/client.h>
  42
  43#include "v9fs.h"
  44#include "v9fs_vfs.h"
  45#include "fid.h"
  46#include "cache.h"
  47#include "xattr.h"
  48#include "acl.h"
  49
  50static int
  51v9fs_vfs_mknod_dotl(struct inode *dir, struct dentry *dentry, umode_t omode,
  52                    dev_t rdev);
  53
  54/**
  55 * v9fs_get_fsgid_for_create - Helper function to get the gid for creating a
  56 * new file system object. This checks the S_ISGID to determine the owning
  57 * group of the new file system object.
  58 */
  59
  60static kgid_t v9fs_get_fsgid_for_create(struct inode *dir_inode)
  61{
  62        BUG_ON(dir_inode == NULL);
  63
  64        if (dir_inode->i_mode & S_ISGID) {
  65                /* set_gid bit is set.*/
  66                return dir_inode->i_gid;
  67        }
  68        return current_fsgid();
  69}
  70
  71static int v9fs_test_inode_dotl(struct inode *inode, void *data)
  72{
  73        struct v9fs_inode *v9inode = V9FS_I(inode);
  74        struct p9_stat_dotl *st = (struct p9_stat_dotl *)data;
  75
  76        /* don't match inode of different type */
  77        if ((inode->i_mode & S_IFMT) != (st->st_mode & S_IFMT))
  78                return 0;
  79
  80        if (inode->i_generation != st->st_gen)
  81                return 0;
  82
  83        /* compare qid details */
  84        if (memcmp(&v9inode->qid.version,
  85                   &st->qid.version, sizeof(v9inode->qid.version)))
  86                return 0;
  87
  88        if (v9inode->qid.type != st->qid.type)
  89                return 0;
  90        return 1;
  91}
  92
  93/* Always get a new inode */
  94static int v9fs_test_new_inode_dotl(struct inode *inode, void *data)
  95{
  96        return 0;
  97}
  98
  99static int v9fs_set_inode_dotl(struct inode *inode,  void *data)
 100{
 101        struct v9fs_inode *v9inode = V9FS_I(inode);
 102        struct p9_stat_dotl *st = (struct p9_stat_dotl *)data;
 103
 104        memcpy(&v9inode->qid, &st->qid, sizeof(st->qid));
 105        inode->i_generation = st->st_gen;
 106        return 0;
 107}
 108
 109static struct inode *v9fs_qid_iget_dotl(struct super_block *sb,
 110                                        struct p9_qid *qid,
 111                                        struct p9_fid *fid,
 112                                        struct p9_stat_dotl *st,
 113                                        int new)
 114{
 115        int retval;
 116        unsigned long i_ino;
 117        struct inode *inode;
 118        struct v9fs_session_info *v9ses = sb->s_fs_info;
 119        int (*test)(struct inode *, void *);
 120
 121        if (new)
 122                test = v9fs_test_new_inode_dotl;
 123        else
 124                test = v9fs_test_inode_dotl;
 125
 126        i_ino = v9fs_qid2ino(qid);
 127        inode = iget5_locked(sb, i_ino, test, v9fs_set_inode_dotl, st);
 128        if (!inode)
 129                return ERR_PTR(-ENOMEM);
 130        if (!(inode->i_state & I_NEW))
 131                return inode;
 132        /*
 133         * initialize the inode with the stat info
 134         * FIXME!! we may need support for stale inodes
 135         * later.
 136         */
 137        inode->i_ino = i_ino;
 138        retval = v9fs_init_inode(v9ses, inode,
 139                                 st->st_mode, new_decode_dev(st->st_rdev));
 140        if (retval)
 141                goto error;
 142
 143        v9fs_stat2inode_dotl(st, inode);
 144        v9fs_cache_inode_get_cookie(inode);
 145        retval = v9fs_get_acl(inode, fid);
 146        if (retval)
 147                goto error;
 148
 149        unlock_new_inode(inode);
 150        return inode;
 151error:
 152        iget_failed(inode);
 153        return ERR_PTR(retval);
 154
 155}
 156
 157struct inode *
 158v9fs_inode_from_fid_dotl(struct v9fs_session_info *v9ses, struct p9_fid *fid,
 159                         struct super_block *sb, int new)
 160{
 161        struct p9_stat_dotl *st;
 162        struct inode *inode = NULL;
 163
 164        st = p9_client_getattr_dotl(fid, P9_STATS_BASIC | P9_STATS_GEN);
 165        if (IS_ERR(st))
 166                return ERR_CAST(st);
 167
 168        inode = v9fs_qid_iget_dotl(sb, &st->qid, fid, st, new);
 169        kfree(st);
 170        return inode;
 171}
 172
 173struct dotl_openflag_map {
 174        int open_flag;
 175        int dotl_flag;
 176};
 177
 178static int v9fs_mapped_dotl_flags(int flags)
 179{
 180        int i;
 181        int rflags = 0;
 182        struct dotl_openflag_map dotl_oflag_map[] = {
 183                { O_CREAT,      P9_DOTL_CREATE },
 184                { O_EXCL,       P9_DOTL_EXCL },
 185                { O_NOCTTY,     P9_DOTL_NOCTTY },
 186                { O_APPEND,     P9_DOTL_APPEND },
 187                { O_NONBLOCK,   P9_DOTL_NONBLOCK },
 188                { O_DSYNC,      P9_DOTL_DSYNC },
 189                { FASYNC,       P9_DOTL_FASYNC },
 190                { O_DIRECT,     P9_DOTL_DIRECT },
 191                { O_LARGEFILE,  P9_DOTL_LARGEFILE },
 192                { O_DIRECTORY,  P9_DOTL_DIRECTORY },
 193                { O_NOFOLLOW,   P9_DOTL_NOFOLLOW },
 194                { O_NOATIME,    P9_DOTL_NOATIME },
 195                { O_CLOEXEC,    P9_DOTL_CLOEXEC },
 196                { O_SYNC,       P9_DOTL_SYNC},
 197        };
 198        for (i = 0; i < ARRAY_SIZE(dotl_oflag_map); i++) {
 199                if (flags & dotl_oflag_map[i].open_flag)
 200                        rflags |= dotl_oflag_map[i].dotl_flag;
 201        }
 202        return rflags;
 203}
 204
 205/**
 206 * v9fs_open_to_dotl_flags- convert Linux specific open flags to
 207 * plan 9 open flag.
 208 * @flags: flags to convert
 209 */
 210int v9fs_open_to_dotl_flags(int flags)
 211{
 212        int rflags = 0;
 213
 214        /*
 215         * We have same bits for P9_DOTL_READONLY, P9_DOTL_WRONLY
 216         * and P9_DOTL_NOACCESS
 217         */
 218        rflags |= flags & O_ACCMODE;
 219        rflags |= v9fs_mapped_dotl_flags(flags);
 220
 221        return rflags;
 222}
 223
 224/**
 225 * v9fs_vfs_create_dotl - VFS hook to create files for 9P2000.L protocol.
 226 * @dir: directory inode that is being created
 227 * @dentry:  dentry that is being deleted
 228 * @omode: create permissions
 229 *
 230 */
 231
 232static int
 233v9fs_vfs_create_dotl(struct inode *dir, struct dentry *dentry, umode_t omode,
 234                bool excl)
 235{
 236        return v9fs_vfs_mknod_dotl(dir, dentry, omode, 0);
 237}
 238
 239static int
 240v9fs_vfs_atomic_open_dotl(struct inode *dir, struct dentry *dentry,
 241                          struct file *file, unsigned flags, umode_t omode,
 242                          int *opened)
 243{
 244        int err = 0;
 245        kgid_t gid;
 246        umode_t mode;
 247        const unsigned char *name = NULL;
 248        struct p9_qid qid;
 249        struct inode *inode;
 250        struct p9_fid *fid = NULL;
 251        struct v9fs_inode *v9inode;
 252        struct p9_fid *dfid, *ofid, *inode_fid;
 253        struct v9fs_session_info *v9ses;
 254        struct posix_acl *pacl = NULL, *dacl = NULL;
 255        struct dentry *res = NULL;
 256
 257        if (d_in_lookup(dentry)) {
 258                res = v9fs_vfs_lookup(dir, dentry, 0);
 259                if (IS_ERR(res))
 260                        return PTR_ERR(res);
 261
 262                if (res)
 263                        dentry = res;
 264        }
 265
 266        /* Only creates */
 267        if (!(flags & O_CREAT) || d_really_is_positive(dentry))
 268                return  finish_no_open(file, res);
 269
 270        v9ses = v9fs_inode2v9ses(dir);
 271
 272        name = dentry->d_name.name;
 273        p9_debug(P9_DEBUG_VFS, "name:%s flags:0x%x mode:0x%hx\n",
 274                 name, flags, omode);
 275
 276        dfid = v9fs_parent_fid(dentry);
 277        if (IS_ERR(dfid)) {
 278                err = PTR_ERR(dfid);
 279                p9_debug(P9_DEBUG_VFS, "fid lookup failed %d\n", err);
 280                goto out;
 281        }
 282
 283        /* clone a fid to use for creation */
 284        ofid = clone_fid(dfid);
 285        if (IS_ERR(ofid)) {
 286                err = PTR_ERR(ofid);
 287                p9_debug(P9_DEBUG_VFS, "p9_client_walk failed %d\n", err);
 288                goto out;
 289        }
 290
 291        gid = v9fs_get_fsgid_for_create(dir);
 292
 293        mode = omode;
 294        /* Update mode based on ACL value */
 295        err = v9fs_acl_mode(dir, &mode, &dacl, &pacl);
 296        if (err) {
 297                p9_debug(P9_DEBUG_VFS, "Failed to get acl values in creat %d\n",
 298                         err);
 299                goto error;
 300        }
 301        err = p9_client_create_dotl(ofid, name, v9fs_open_to_dotl_flags(flags),
 302                                    mode, gid, &qid);
 303        if (err < 0) {
 304                p9_debug(P9_DEBUG_VFS, "p9_client_open_dotl failed in creat %d\n",
 305                         err);
 306                goto error;
 307        }
 308        v9fs_invalidate_inode_attr(dir);
 309
 310        /* instantiate inode and assign the unopened fid to the dentry */
 311        fid = p9_client_walk(dfid, 1, &name, 1);
 312        if (IS_ERR(fid)) {
 313                err = PTR_ERR(fid);
 314                p9_debug(P9_DEBUG_VFS, "p9_client_walk failed %d\n", err);
 315                fid = NULL;
 316                goto error;
 317        }
 318        inode = v9fs_get_new_inode_from_fid(v9ses, fid, dir->i_sb);
 319        if (IS_ERR(inode)) {
 320                err = PTR_ERR(inode);
 321                p9_debug(P9_DEBUG_VFS, "inode creation failed %d\n", err);
 322                goto error;
 323        }
 324        /* Now set the ACL based on the default value */
 325        v9fs_set_create_acl(inode, fid, dacl, pacl);
 326
 327        v9fs_fid_add(dentry, fid);
 328        d_instantiate(dentry, inode);
 329
 330        v9inode = V9FS_I(inode);
 331        mutex_lock(&v9inode->v_mutex);
 332        if ((v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE) &&
 333            !v9inode->writeback_fid &&
 334            ((flags & O_ACCMODE) != O_RDONLY)) {
 335                /*
 336                 * clone a fid and add it to writeback_fid
 337                 * we do it during open time instead of
 338                 * page dirty time via write_begin/page_mkwrite
 339                 * because we want write after unlink usecase
 340                 * to work.
 341                 */
 342                inode_fid = v9fs_writeback_fid(dentry);
 343                if (IS_ERR(inode_fid)) {
 344                        err = PTR_ERR(inode_fid);
 345                        mutex_unlock(&v9inode->v_mutex);
 346                        goto err_clunk_old_fid;
 347                }
 348                v9inode->writeback_fid = (void *) inode_fid;
 349        }
 350        mutex_unlock(&v9inode->v_mutex);
 351        /* Since we are opening a file, assign the open fid to the file */
 352        err = finish_open(file, dentry, generic_file_open, opened);
 353        if (err)
 354                goto err_clunk_old_fid;
 355        file->private_data = ofid;
 356        if (v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE)
 357                v9fs_cache_inode_set_cookie(inode, file);
 358        *opened |= FILE_CREATED;
 359out:
 360        v9fs_put_acl(dacl, pacl);
 361        dput(res);
 362        return err;
 363
 364error:
 365        if (fid)
 366                p9_client_clunk(fid);
 367err_clunk_old_fid:
 368        if (ofid)
 369                p9_client_clunk(ofid);
 370        goto out;
 371}
 372
 373/**
 374 * v9fs_vfs_mkdir_dotl - VFS mkdir hook to create a directory
 375 * @dir:  inode that is being unlinked
 376 * @dentry: dentry that is being unlinked
 377 * @omode: mode for new directory
 378 *
 379 */
 380
 381static int v9fs_vfs_mkdir_dotl(struct inode *dir,
 382                               struct dentry *dentry, umode_t omode)
 383{
 384        int err;
 385        struct v9fs_session_info *v9ses;
 386        struct p9_fid *fid = NULL, *dfid = NULL;
 387        kgid_t gid;
 388        const unsigned char *name;
 389        umode_t mode;
 390        struct inode *inode;
 391        struct p9_qid qid;
 392        struct posix_acl *dacl = NULL, *pacl = NULL;
 393
 394        p9_debug(P9_DEBUG_VFS, "name %pd\n", dentry);
 395        err = 0;
 396        v9ses = v9fs_inode2v9ses(dir);
 397
 398        omode |= S_IFDIR;
 399        if (dir->i_mode & S_ISGID)
 400                omode |= S_ISGID;
 401
 402        dfid = v9fs_parent_fid(dentry);
 403        if (IS_ERR(dfid)) {
 404                err = PTR_ERR(dfid);
 405                p9_debug(P9_DEBUG_VFS, "fid lookup failed %d\n", err);
 406                dfid = NULL;
 407                goto error;
 408        }
 409
 410        gid = v9fs_get_fsgid_for_create(dir);
 411        mode = omode;
 412        /* Update mode based on ACL value */
 413        err = v9fs_acl_mode(dir, &mode, &dacl, &pacl);
 414        if (err) {
 415                p9_debug(P9_DEBUG_VFS, "Failed to get acl values in mkdir %d\n",
 416                         err);
 417                goto error;
 418        }
 419        name = dentry->d_name.name;
 420        err = p9_client_mkdir_dotl(dfid, name, mode, gid, &qid);
 421        if (err < 0)
 422                goto error;
 423
 424        fid = p9_client_walk(dfid, 1, &name, 1);
 425        if (IS_ERR(fid)) {
 426                err = PTR_ERR(fid);
 427                p9_debug(P9_DEBUG_VFS, "p9_client_walk failed %d\n",
 428                         err);
 429                fid = NULL;
 430                goto error;
 431        }
 432
 433        /* instantiate inode and assign the unopened fid to the dentry */
 434        if (v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE) {
 435                inode = v9fs_get_new_inode_from_fid(v9ses, fid, dir->i_sb);
 436                if (IS_ERR(inode)) {
 437                        err = PTR_ERR(inode);
 438                        p9_debug(P9_DEBUG_VFS, "inode creation failed %d\n",
 439                                 err);
 440                        goto error;
 441                }
 442                v9fs_fid_add(dentry, fid);
 443                v9fs_set_create_acl(inode, fid, dacl, pacl);
 444                d_instantiate(dentry, inode);
 445                fid = NULL;
 446                err = 0;
 447        } else {
 448                /*
 449                 * Not in cached mode. No need to populate
 450                 * inode with stat. We need to get an inode
 451                 * so that we can set the acl with dentry
 452                 */
 453                inode = v9fs_get_inode(dir->i_sb, mode, 0);
 454                if (IS_ERR(inode)) {
 455                        err = PTR_ERR(inode);
 456                        goto error;
 457                }
 458                v9fs_set_create_acl(inode, fid, dacl, pacl);
 459                d_instantiate(dentry, inode);
 460        }
 461        inc_nlink(dir);
 462        v9fs_invalidate_inode_attr(dir);
 463error:
 464        if (fid)
 465                p9_client_clunk(fid);
 466        v9fs_put_acl(dacl, pacl);
 467        return err;
 468}
 469
 470static int
 471v9fs_vfs_getattr_dotl(const struct path *path, struct kstat *stat,
 472                 u32 request_mask, unsigned int flags)
 473{
 474        struct dentry *dentry = path->dentry;
 475        struct v9fs_session_info *v9ses;
 476        struct p9_fid *fid;
 477        struct p9_stat_dotl *st;
 478
 479        p9_debug(P9_DEBUG_VFS, "dentry: %p\n", dentry);
 480        v9ses = v9fs_dentry2v9ses(dentry);
 481        if (v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE) {
 482                generic_fillattr(d_inode(dentry), stat);
 483                return 0;
 484        }
 485        fid = v9fs_fid_lookup(dentry);
 486        if (IS_ERR(fid))
 487                return PTR_ERR(fid);
 488
 489        /* Ask for all the fields in stat structure. Server will return
 490         * whatever it supports
 491         */
 492
 493        st = p9_client_getattr_dotl(fid, P9_STATS_ALL);
 494        if (IS_ERR(st))
 495                return PTR_ERR(st);
 496
 497        v9fs_stat2inode_dotl(st, d_inode(dentry));
 498        generic_fillattr(d_inode(dentry), stat);
 499        /* Change block size to what the server returned */
 500        stat->blksize = st->st_blksize;
 501
 502        kfree(st);
 503        return 0;
 504}
 505
 506/*
 507 * Attribute flags.
 508 */
 509#define P9_ATTR_MODE            (1 << 0)
 510#define P9_ATTR_UID             (1 << 1)
 511#define P9_ATTR_GID             (1 << 2)
 512#define P9_ATTR_SIZE            (1 << 3)
 513#define P9_ATTR_ATIME           (1 << 4)
 514#define P9_ATTR_MTIME           (1 << 5)
 515#define P9_ATTR_CTIME           (1 << 6)
 516#define P9_ATTR_ATIME_SET       (1 << 7)
 517#define P9_ATTR_MTIME_SET       (1 << 8)
 518
 519struct dotl_iattr_map {
 520        int iattr_valid;
 521        int p9_iattr_valid;
 522};
 523
 524static int v9fs_mapped_iattr_valid(int iattr_valid)
 525{
 526        int i;
 527        int p9_iattr_valid = 0;
 528        struct dotl_iattr_map dotl_iattr_map[] = {
 529                { ATTR_MODE,            P9_ATTR_MODE },
 530                { ATTR_UID,             P9_ATTR_UID },
 531                { ATTR_GID,             P9_ATTR_GID },
 532                { ATTR_SIZE,            P9_ATTR_SIZE },
 533                { ATTR_ATIME,           P9_ATTR_ATIME },
 534                { ATTR_MTIME,           P9_ATTR_MTIME },
 535                { ATTR_CTIME,           P9_ATTR_CTIME },
 536                { ATTR_ATIME_SET,       P9_ATTR_ATIME_SET },
 537                { ATTR_MTIME_SET,       P9_ATTR_MTIME_SET },
 538        };
 539        for (i = 0; i < ARRAY_SIZE(dotl_iattr_map); i++) {
 540                if (iattr_valid & dotl_iattr_map[i].iattr_valid)
 541                        p9_iattr_valid |= dotl_iattr_map[i].p9_iattr_valid;
 542        }
 543        return p9_iattr_valid;
 544}
 545
 546/**
 547 * v9fs_vfs_setattr_dotl - set file metadata
 548 * @dentry: file whose metadata to set
 549 * @iattr: metadata assignment structure
 550 *
 551 */
 552
 553int v9fs_vfs_setattr_dotl(struct dentry *dentry, struct iattr *iattr)
 554{
 555        int retval;
 556        struct p9_fid *fid;
 557        struct p9_iattr_dotl p9attr;
 558        struct inode *inode = d_inode(dentry);
 559
 560        p9_debug(P9_DEBUG_VFS, "\n");
 561
 562        retval = setattr_prepare(dentry, iattr);
 563        if (retval)
 564                return retval;
 565
 566        p9attr.valid = v9fs_mapped_iattr_valid(iattr->ia_valid);
 567        p9attr.mode = iattr->ia_mode;
 568        p9attr.uid = iattr->ia_uid;
 569        p9attr.gid = iattr->ia_gid;
 570        p9attr.size = iattr->ia_size;
 571        p9attr.atime_sec = iattr->ia_atime.tv_sec;
 572        p9attr.atime_nsec = iattr->ia_atime.tv_nsec;
 573        p9attr.mtime_sec = iattr->ia_mtime.tv_sec;
 574        p9attr.mtime_nsec = iattr->ia_mtime.tv_nsec;
 575
 576        fid = v9fs_fid_lookup(dentry);
 577        if (IS_ERR(fid))
 578                return PTR_ERR(fid);
 579
 580        /* Write all dirty data */
 581        if (S_ISREG(inode->i_mode))
 582                filemap_write_and_wait(inode->i_mapping);
 583
 584        retval = p9_client_setattr(fid, &p9attr);
 585        if (retval < 0)
 586                return retval;
 587
 588        if ((iattr->ia_valid & ATTR_SIZE) &&
 589            iattr->ia_size != i_size_read(inode))
 590                truncate_setsize(inode, iattr->ia_size);
 591
 592        v9fs_invalidate_inode_attr(inode);
 593        setattr_copy(inode, iattr);
 594        mark_inode_dirty(inode);
 595        if (iattr->ia_valid & ATTR_MODE) {
 596                /* We also want to update ACL when we update mode bits */
 597                retval = v9fs_acl_chmod(inode, fid);
 598                if (retval < 0)
 599                        return retval;
 600        }
 601        return 0;
 602}
 603
 604/**
 605 * v9fs_stat2inode_dotl - populate an inode structure with stat info
 606 * @stat: stat structure
 607 * @inode: inode to populate
 608 *
 609 */
 610
 611void
 612v9fs_stat2inode_dotl(struct p9_stat_dotl *stat, struct inode *inode)
 613{
 614        umode_t mode;
 615        struct v9fs_inode *v9inode = V9FS_I(inode);
 616
 617        if ((stat->st_result_mask & P9_STATS_BASIC) == P9_STATS_BASIC) {
 618                inode->i_atime.tv_sec = stat->st_atime_sec;
 619                inode->i_atime.tv_nsec = stat->st_atime_nsec;
 620                inode->i_mtime.tv_sec = stat->st_mtime_sec;
 621                inode->i_mtime.tv_nsec = stat->st_mtime_nsec;
 622                inode->i_ctime.tv_sec = stat->st_ctime_sec;
 623                inode->i_ctime.tv_nsec = stat->st_ctime_nsec;
 624                inode->i_uid = stat->st_uid;
 625                inode->i_gid = stat->st_gid;
 626                set_nlink(inode, stat->st_nlink);
 627
 628                mode = stat->st_mode & S_IALLUGO;
 629                mode |= inode->i_mode & ~S_IALLUGO;
 630                inode->i_mode = mode;
 631
 632                i_size_write(inode, stat->st_size);
 633                inode->i_blocks = stat->st_blocks;
 634        } else {
 635                if (stat->st_result_mask & P9_STATS_ATIME) {
 636                        inode->i_atime.tv_sec = stat->st_atime_sec;
 637                        inode->i_atime.tv_nsec = stat->st_atime_nsec;
 638                }
 639                if (stat->st_result_mask & P9_STATS_MTIME) {
 640                        inode->i_mtime.tv_sec = stat->st_mtime_sec;
 641                        inode->i_mtime.tv_nsec = stat->st_mtime_nsec;
 642                }
 643                if (stat->st_result_mask & P9_STATS_CTIME) {
 644                        inode->i_ctime.tv_sec = stat->st_ctime_sec;
 645                        inode->i_ctime.tv_nsec = stat->st_ctime_nsec;
 646                }
 647                if (stat->st_result_mask & P9_STATS_UID)
 648                        inode->i_uid = stat->st_uid;
 649                if (stat->st_result_mask & P9_STATS_GID)
 650                        inode->i_gid = stat->st_gid;
 651                if (stat->st_result_mask & P9_STATS_NLINK)
 652                        set_nlink(inode, stat->st_nlink);
 653                if (stat->st_result_mask & P9_STATS_MODE) {
 654                        inode->i_mode = stat->st_mode;
 655                        if ((S_ISBLK(inode->i_mode)) ||
 656                                                (S_ISCHR(inode->i_mode)))
 657                                init_special_inode(inode, inode->i_mode,
 658                                                                inode->i_rdev);
 659                }
 660                if (stat->st_result_mask & P9_STATS_RDEV)
 661                        inode->i_rdev = new_decode_dev(stat->st_rdev);
 662                if (stat->st_result_mask & P9_STATS_SIZE)
 663                        i_size_write(inode, stat->st_size);
 664                if (stat->st_result_mask & P9_STATS_BLOCKS)
 665                        inode->i_blocks = stat->st_blocks;
 666        }
 667        if (stat->st_result_mask & P9_STATS_GEN)
 668                inode->i_generation = stat->st_gen;
 669
 670        /* Currently we don't support P9_STATS_BTIME and P9_STATS_DATA_VERSION
 671         * because the inode structure does not have fields for them.
 672         */
 673        v9inode->cache_validity &= ~V9FS_INO_INVALID_ATTR;
 674}
 675
 676static int
 677v9fs_vfs_symlink_dotl(struct inode *dir, struct dentry *dentry,
 678                const char *symname)
 679{
 680        int err;
 681        kgid_t gid;
 682        const unsigned char *name;
 683        struct p9_qid qid;
 684        struct inode *inode;
 685        struct p9_fid *dfid;
 686        struct p9_fid *fid = NULL;
 687        struct v9fs_session_info *v9ses;
 688
 689        name = dentry->d_name.name;
 690        p9_debug(P9_DEBUG_VFS, "%lu,%s,%s\n", dir->i_ino, name, symname);
 691        v9ses = v9fs_inode2v9ses(dir);
 692
 693        dfid = v9fs_parent_fid(dentry);
 694        if (IS_ERR(dfid)) {
 695                err = PTR_ERR(dfid);
 696                p9_debug(P9_DEBUG_VFS, "fid lookup failed %d\n", err);
 697                return err;
 698        }
 699
 700        gid = v9fs_get_fsgid_for_create(dir);
 701
 702        /* Server doesn't alter fid on TSYMLINK. Hence no need to clone it. */
 703        err = p9_client_symlink(dfid, name, symname, gid, &qid);
 704
 705        if (err < 0) {
 706                p9_debug(P9_DEBUG_VFS, "p9_client_symlink failed %d\n", err);
 707                goto error;
 708        }
 709
 710        v9fs_invalidate_inode_attr(dir);
 711        if (v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE) {
 712                /* Now walk from the parent so we can get an unopened fid. */
 713                fid = p9_client_walk(dfid, 1, &name, 1);
 714                if (IS_ERR(fid)) {
 715                        err = PTR_ERR(fid);
 716                        p9_debug(P9_DEBUG_VFS, "p9_client_walk failed %d\n",
 717                                 err);
 718                        fid = NULL;
 719                        goto error;
 720                }
 721
 722                /* instantiate inode and assign the unopened fid to dentry */
 723                inode = v9fs_get_new_inode_from_fid(v9ses, fid, dir->i_sb);
 724                if (IS_ERR(inode)) {
 725                        err = PTR_ERR(inode);
 726                        p9_debug(P9_DEBUG_VFS, "inode creation failed %d\n",
 727                                 err);
 728                        goto error;
 729                }
 730                v9fs_fid_add(dentry, fid);
 731                d_instantiate(dentry, inode);
 732                fid = NULL;
 733                err = 0;
 734        } else {
 735                /* Not in cached mode. No need to populate inode with stat */
 736                inode = v9fs_get_inode(dir->i_sb, S_IFLNK, 0);
 737                if (IS_ERR(inode)) {
 738                        err = PTR_ERR(inode);
 739                        goto error;
 740                }
 741                d_instantiate(dentry, inode);
 742        }
 743
 744error:
 745        if (fid)
 746                p9_client_clunk(fid);
 747
 748        return err;
 749}
 750
 751/**
 752 * v9fs_vfs_link_dotl - create a hardlink for dotl
 753 * @old_dentry: dentry for file to link to
 754 * @dir: inode destination for new link
 755 * @dentry: dentry for link
 756 *
 757 */
 758
 759static int
 760v9fs_vfs_link_dotl(struct dentry *old_dentry, struct inode *dir,
 761                struct dentry *dentry)
 762{
 763        int err;
 764        struct p9_fid *dfid, *oldfid;
 765        struct v9fs_session_info *v9ses;
 766
 767        p9_debug(P9_DEBUG_VFS, "dir ino: %lu, old_name: %pd, new_name: %pd\n",
 768                 dir->i_ino, old_dentry, dentry);
 769
 770        v9ses = v9fs_inode2v9ses(dir);
 771        dfid = v9fs_parent_fid(dentry);
 772        if (IS_ERR(dfid))
 773                return PTR_ERR(dfid);
 774
 775        oldfid = v9fs_fid_lookup(old_dentry);
 776        if (IS_ERR(oldfid))
 777                return PTR_ERR(oldfid);
 778
 779        err = p9_client_link(dfid, oldfid, dentry->d_name.name);
 780
 781        if (err < 0) {
 782                p9_debug(P9_DEBUG_VFS, "p9_client_link failed %d\n", err);
 783                return err;
 784        }
 785
 786        v9fs_invalidate_inode_attr(dir);
 787        if (v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE) {
 788                /* Get the latest stat info from server. */
 789                struct p9_fid *fid;
 790                fid = v9fs_fid_lookup(old_dentry);
 791                if (IS_ERR(fid))
 792                        return PTR_ERR(fid);
 793
 794                v9fs_refresh_inode_dotl(fid, d_inode(old_dentry));
 795        }
 796        ihold(d_inode(old_dentry));
 797        d_instantiate(dentry, d_inode(old_dentry));
 798
 799        return err;
 800}
 801
 802/**
 803 * v9fs_vfs_mknod_dotl - create a special file
 804 * @dir: inode destination for new link
 805 * @dentry: dentry for file
 806 * @omode: mode for creation
 807 * @rdev: device associated with special file
 808 *
 809 */
 810static int
 811v9fs_vfs_mknod_dotl(struct inode *dir, struct dentry *dentry, umode_t omode,
 812                dev_t rdev)
 813{
 814        int err;
 815        kgid_t gid;
 816        const unsigned char *name;
 817        umode_t mode;
 818        struct v9fs_session_info *v9ses;
 819        struct p9_fid *fid = NULL, *dfid = NULL;
 820        struct inode *inode;
 821        struct p9_qid qid;
 822        struct posix_acl *dacl = NULL, *pacl = NULL;
 823
 824        p9_debug(P9_DEBUG_VFS, " %lu,%pd mode: %hx MAJOR: %u MINOR: %u\n",
 825                 dir->i_ino, dentry, omode,
 826                 MAJOR(rdev), MINOR(rdev));
 827
 828        v9ses = v9fs_inode2v9ses(dir);
 829        dfid = v9fs_parent_fid(dentry);
 830        if (IS_ERR(dfid)) {
 831                err = PTR_ERR(dfid);
 832                p9_debug(P9_DEBUG_VFS, "fid lookup failed %d\n", err);
 833                dfid = NULL;
 834                goto error;
 835        }
 836
 837        gid = v9fs_get_fsgid_for_create(dir);
 838        mode = omode;
 839        /* Update mode based on ACL value */
 840        err = v9fs_acl_mode(dir, &mode, &dacl, &pacl);
 841        if (err) {
 842                p9_debug(P9_DEBUG_VFS, "Failed to get acl values in mknod %d\n",
 843                         err);
 844                goto error;
 845        }
 846        name = dentry->d_name.name;
 847
 848        err = p9_client_mknod_dotl(dfid, name, mode, rdev, gid, &qid);
 849        if (err < 0)
 850                goto error;
 851
 852        v9fs_invalidate_inode_attr(dir);
 853        fid = p9_client_walk(dfid, 1, &name, 1);
 854        if (IS_ERR(fid)) {
 855                err = PTR_ERR(fid);
 856                p9_debug(P9_DEBUG_VFS, "p9_client_walk failed %d\n",
 857                         err);
 858                fid = NULL;
 859                goto error;
 860        }
 861
 862        /* instantiate inode and assign the unopened fid to the dentry */
 863        if (v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE) {
 864                inode = v9fs_get_new_inode_from_fid(v9ses, fid, dir->i_sb);
 865                if (IS_ERR(inode)) {
 866                        err = PTR_ERR(inode);
 867                        p9_debug(P9_DEBUG_VFS, "inode creation failed %d\n",
 868                                 err);
 869                        goto error;
 870                }
 871                v9fs_set_create_acl(inode, fid, dacl, pacl);
 872                v9fs_fid_add(dentry, fid);
 873                d_instantiate(dentry, inode);
 874                fid = NULL;
 875                err = 0;
 876        } else {
 877                /*
 878                 * Not in cached mode. No need to populate inode with stat.
 879                 * socket syscall returns a fd, so we need instantiate
 880                 */
 881                inode = v9fs_get_inode(dir->i_sb, mode, rdev);
 882                if (IS_ERR(inode)) {
 883                        err = PTR_ERR(inode);
 884                        goto error;
 885                }
 886                v9fs_set_create_acl(inode, fid, dacl, pacl);
 887                d_instantiate(dentry, inode);
 888        }
 889error:
 890        if (fid)
 891                p9_client_clunk(fid);
 892        v9fs_put_acl(dacl, pacl);
 893        return err;
 894}
 895
 896/**
 897 * v9fs_vfs_get_link_dotl - follow a symlink path
 898 * @dentry: dentry for symlink
 899 * @inode: inode for symlink
 900 * @done: destructor for return value
 901 */
 902
 903static const char *
 904v9fs_vfs_get_link_dotl(struct dentry *dentry,
 905                       struct inode *inode,
 906                       struct delayed_call *done)
 907{
 908        struct p9_fid *fid;
 909        char *target;
 910        int retval;
 911
 912        if (!dentry)
 913                return ERR_PTR(-ECHILD);
 914
 915        p9_debug(P9_DEBUG_VFS, "%pd\n", dentry);
 916
 917        fid = v9fs_fid_lookup(dentry);
 918        if (IS_ERR(fid))
 919                return ERR_CAST(fid);
 920        retval = p9_client_readlink(fid, &target);
 921        if (retval)
 922                return ERR_PTR(retval);
 923        set_delayed_call(done, kfree_link, target);
 924        return target;
 925}
 926
 927int v9fs_refresh_inode_dotl(struct p9_fid *fid, struct inode *inode)
 928{
 929        loff_t i_size;
 930        struct p9_stat_dotl *st;
 931        struct v9fs_session_info *v9ses;
 932
 933        v9ses = v9fs_inode2v9ses(inode);
 934        st = p9_client_getattr_dotl(fid, P9_STATS_ALL);
 935        if (IS_ERR(st))
 936                return PTR_ERR(st);
 937        /*
 938         * Don't update inode if the file type is different
 939         */
 940        if ((inode->i_mode & S_IFMT) != (st->st_mode & S_IFMT))
 941                goto out;
 942
 943        spin_lock(&inode->i_lock);
 944        /*
 945         * We don't want to refresh inode->i_size,
 946         * because we may have cached data
 947         */
 948        i_size = inode->i_size;
 949        v9fs_stat2inode_dotl(st, inode);
 950        if (v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE)
 951                inode->i_size = i_size;
 952        spin_unlock(&inode->i_lock);
 953out:
 954        kfree(st);
 955        return 0;
 956}
 957
 958const struct inode_operations v9fs_dir_inode_operations_dotl = {
 959        .create = v9fs_vfs_create_dotl,
 960        .atomic_open = v9fs_vfs_atomic_open_dotl,
 961        .lookup = v9fs_vfs_lookup,
 962        .link = v9fs_vfs_link_dotl,
 963        .symlink = v9fs_vfs_symlink_dotl,
 964        .unlink = v9fs_vfs_unlink,
 965        .mkdir = v9fs_vfs_mkdir_dotl,
 966        .rmdir = v9fs_vfs_rmdir,
 967        .mknod = v9fs_vfs_mknod_dotl,
 968        .rename = v9fs_vfs_rename,
 969        .getattr = v9fs_vfs_getattr_dotl,
 970        .setattr = v9fs_vfs_setattr_dotl,
 971        .listxattr = v9fs_listxattr,
 972        .get_acl = v9fs_iop_get_acl,
 973};
 974
 975const struct inode_operations v9fs_file_inode_operations_dotl = {
 976        .getattr = v9fs_vfs_getattr_dotl,
 977        .setattr = v9fs_vfs_setattr_dotl,
 978        .listxattr = v9fs_listxattr,
 979        .get_acl = v9fs_iop_get_acl,
 980};
 981
 982const struct inode_operations v9fs_symlink_inode_operations_dotl = {
 983        .get_link = v9fs_vfs_get_link_dotl,
 984        .getattr = v9fs_vfs_getattr_dotl,
 985        .setattr = v9fs_vfs_setattr_dotl,
 986        .listxattr = v9fs_listxattr,
 987};
 988