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