linux/fs/afs/inode.c
<<
>>
Prefs
   1/*
   2 * Copyright (c) 2002 Red Hat, Inc. All rights reserved.
   3 *
   4 * This software may be freely redistributed under the terms of the
   5 * GNU General Public License.
   6 *
   7 * You should have received a copy of the GNU General Public License
   8 * along with this program; if not, write to the Free Software
   9 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  10 *
  11 * Authors: David Woodhouse <dwmw2@infradead.org>
  12 *          David Howells <dhowells@redhat.com>
  13 *
  14 */
  15
  16#include <linux/kernel.h>
  17#include <linux/module.h>
  18#include <linux/init.h>
  19#include <linux/fs.h>
  20#include <linux/pagemap.h>
  21#include <linux/sched.h>
  22#include <linux/mount.h>
  23#include <linux/namei.h>
  24#include "internal.h"
  25
  26struct afs_iget_data {
  27        struct afs_fid          fid;
  28        struct afs_volume       *volume;        /* volume on which resides */
  29};
  30
  31static const struct inode_operations afs_symlink_inode_operations = {
  32        .get_link       = page_get_link,
  33        .listxattr      = afs_listxattr,
  34};
  35
  36/*
  37 * map the AFS file status to the inode member variables
  38 */
  39static int afs_inode_map_status(struct afs_vnode *vnode, struct key *key)
  40{
  41        struct inode *inode = AFS_VNODE_TO_I(vnode);
  42
  43        _debug("FS: ft=%d lk=%d sz=%llu ver=%Lu mod=%hu",
  44               vnode->status.type,
  45               vnode->status.nlink,
  46               (unsigned long long) vnode->status.size,
  47               vnode->status.data_version,
  48               vnode->status.mode);
  49
  50        switch (vnode->status.type) {
  51        case AFS_FTYPE_FILE:
  52                inode->i_mode   = S_IFREG | vnode->status.mode;
  53                inode->i_op     = &afs_file_inode_operations;
  54                inode->i_fop    = &afs_file_operations;
  55                break;
  56        case AFS_FTYPE_DIR:
  57                inode->i_mode   = S_IFDIR | vnode->status.mode;
  58                inode->i_op     = &afs_dir_inode_operations;
  59                inode->i_fop    = &afs_dir_file_operations;
  60                break;
  61        case AFS_FTYPE_SYMLINK:
  62                /* Symlinks with a mode of 0644 are actually mountpoints. */
  63                if ((vnode->status.mode & 0777) == 0644) {
  64                        inode->i_flags |= S_AUTOMOUNT;
  65
  66                        spin_lock(&vnode->lock);
  67                        set_bit(AFS_VNODE_MOUNTPOINT, &vnode->flags);
  68                        spin_unlock(&vnode->lock);
  69
  70                        inode->i_mode   = S_IFDIR | 0555;
  71                        inode->i_op     = &afs_mntpt_inode_operations;
  72                        inode->i_fop    = &afs_mntpt_file_operations;
  73                } else {
  74                        inode->i_mode   = S_IFLNK | vnode->status.mode;
  75                        inode->i_op     = &afs_symlink_inode_operations;
  76                }
  77                inode_nohighmem(inode);
  78                break;
  79        default:
  80                printk("kAFS: AFS vnode with undefined type\n");
  81                return -EBADMSG;
  82        }
  83
  84#ifdef CONFIG_AFS_FSCACHE
  85        if (vnode->status.size != inode->i_size)
  86                fscache_attr_changed(vnode->cache);
  87#endif
  88
  89        set_nlink(inode, vnode->status.nlink);
  90        inode->i_uid            = vnode->status.owner;
  91        inode->i_gid            = vnode->status.group;
  92        inode->i_size           = vnode->status.size;
  93        inode->i_ctime.tv_sec   = vnode->status.mtime_client;
  94        inode->i_ctime.tv_nsec  = 0;
  95        inode->i_atime          = inode->i_mtime = inode->i_ctime;
  96        inode->i_blocks         = 0;
  97        inode->i_generation     = vnode->fid.unique;
  98        inode->i_version        = vnode->status.data_version;
  99        inode->i_mapping->a_ops = &afs_fs_aops;
 100        return 0;
 101}
 102
 103/*
 104 * iget5() comparator
 105 */
 106static int afs_iget5_test(struct inode *inode, void *opaque)
 107{
 108        struct afs_iget_data *data = opaque;
 109
 110        return inode->i_ino == data->fid.vnode &&
 111                inode->i_generation == data->fid.unique;
 112}
 113
 114/*
 115 * iget5() comparator for inode created by autocell operations
 116 *
 117 * These pseudo inodes don't match anything.
 118 */
 119static int afs_iget5_autocell_test(struct inode *inode, void *opaque)
 120{
 121        return 0;
 122}
 123
 124/*
 125 * iget5() inode initialiser
 126 */
 127static int afs_iget5_set(struct inode *inode, void *opaque)
 128{
 129        struct afs_iget_data *data = opaque;
 130        struct afs_vnode *vnode = AFS_FS_I(inode);
 131
 132        inode->i_ino = data->fid.vnode;
 133        inode->i_generation = data->fid.unique;
 134        vnode->fid = data->fid;
 135        vnode->volume = data->volume;
 136
 137        return 0;
 138}
 139
 140/*
 141 * inode retrieval for autocell
 142 */
 143struct inode *afs_iget_autocell(struct inode *dir, const char *dev_name,
 144                                int namesz, struct key *key)
 145{
 146        struct afs_iget_data data;
 147        struct afs_super_info *as;
 148        struct afs_vnode *vnode;
 149        struct super_block *sb;
 150        struct inode *inode;
 151        static atomic_t afs_autocell_ino;
 152
 153        _enter("{%x:%u},%*.*s,",
 154               AFS_FS_I(dir)->fid.vid, AFS_FS_I(dir)->fid.vnode,
 155               namesz, namesz, dev_name ?: "");
 156
 157        sb = dir->i_sb;
 158        as = sb->s_fs_info;
 159        data.volume = as->volume;
 160        data.fid.vid = as->volume->vid;
 161        data.fid.unique = 0;
 162        data.fid.vnode = 0;
 163
 164        inode = iget5_locked(sb, atomic_inc_return(&afs_autocell_ino),
 165                             afs_iget5_autocell_test, afs_iget5_set,
 166                             &data);
 167        if (!inode) {
 168                _leave(" = -ENOMEM");
 169                return ERR_PTR(-ENOMEM);
 170        }
 171
 172        _debug("GOT INODE %p { ino=%lu, vl=%x, vn=%x, u=%x }",
 173               inode, inode->i_ino, data.fid.vid, data.fid.vnode,
 174               data.fid.unique);
 175
 176        vnode = AFS_FS_I(inode);
 177
 178        /* there shouldn't be an existing inode */
 179        BUG_ON(!(inode->i_state & I_NEW));
 180
 181        inode->i_size           = 0;
 182        inode->i_mode           = S_IFDIR | S_IRUGO | S_IXUGO;
 183        inode->i_op             = &afs_autocell_inode_operations;
 184        set_nlink(inode, 2);
 185        inode->i_uid            = GLOBAL_ROOT_UID;
 186        inode->i_gid            = GLOBAL_ROOT_GID;
 187        inode->i_ctime.tv_sec   = get_seconds();
 188        inode->i_ctime.tv_nsec  = 0;
 189        inode->i_atime          = inode->i_mtime = inode->i_ctime;
 190        inode->i_blocks         = 0;
 191        inode->i_version        = 0;
 192        inode->i_generation     = 0;
 193
 194        set_bit(AFS_VNODE_PSEUDODIR, &vnode->flags);
 195        set_bit(AFS_VNODE_MOUNTPOINT, &vnode->flags);
 196        inode->i_flags |= S_AUTOMOUNT | S_NOATIME;
 197        unlock_new_inode(inode);
 198        _leave(" = %p", inode);
 199        return inode;
 200}
 201
 202/*
 203 * inode retrieval
 204 */
 205struct inode *afs_iget(struct super_block *sb, struct key *key,
 206                       struct afs_fid *fid, struct afs_file_status *status,
 207                       struct afs_callback *cb)
 208{
 209        struct afs_iget_data data = { .fid = *fid };
 210        struct afs_super_info *as;
 211        struct afs_vnode *vnode;
 212        struct inode *inode;
 213        int ret;
 214
 215        _enter(",{%x:%u.%u},,", fid->vid, fid->vnode, fid->unique);
 216
 217        as = sb->s_fs_info;
 218        data.volume = as->volume;
 219
 220        inode = iget5_locked(sb, fid->vnode, afs_iget5_test, afs_iget5_set,
 221                             &data);
 222        if (!inode) {
 223                _leave(" = -ENOMEM");
 224                return ERR_PTR(-ENOMEM);
 225        }
 226
 227        _debug("GOT INODE %p { vl=%x vn=%x, u=%x }",
 228               inode, fid->vid, fid->vnode, fid->unique);
 229
 230        vnode = AFS_FS_I(inode);
 231
 232        /* deal with an existing inode */
 233        if (!(inode->i_state & I_NEW)) {
 234                _leave(" = %p", inode);
 235                return inode;
 236        }
 237
 238        if (!status) {
 239                /* it's a remotely extant inode */
 240                set_bit(AFS_VNODE_CB_BROKEN, &vnode->flags);
 241                ret = afs_vnode_fetch_status(vnode, NULL, key);
 242                if (ret < 0)
 243                        goto bad_inode;
 244        } else {
 245                /* it's an inode we just created */
 246                memcpy(&vnode->status, status, sizeof(vnode->status));
 247
 248                if (!cb) {
 249                        /* it's a symlink we just created (the fileserver
 250                         * didn't give us a callback) */
 251                        vnode->cb_version = 0;
 252                        vnode->cb_expiry = 0;
 253                        vnode->cb_type = 0;
 254                        vnode->cb_expires = ktime_get_real_seconds();
 255                } else {
 256                        vnode->cb_version = cb->version;
 257                        vnode->cb_expiry = cb->expiry;
 258                        vnode->cb_type = cb->type;
 259                        vnode->cb_expires = vnode->cb_expiry +
 260                                ktime_get_real_seconds();
 261                }
 262        }
 263
 264        /* set up caching before mapping the status, as map-status reads the
 265         * first page of symlinks to see if they're really mountpoints */
 266        inode->i_size = vnode->status.size;
 267#ifdef CONFIG_AFS_FSCACHE
 268        vnode->cache = fscache_acquire_cookie(vnode->volume->cache,
 269                                              &afs_vnode_cache_index_def,
 270                                              vnode, true);
 271#endif
 272
 273        ret = afs_inode_map_status(vnode, key);
 274        if (ret < 0)
 275                goto bad_inode;
 276
 277        /* success */
 278        clear_bit(AFS_VNODE_UNSET, &vnode->flags);
 279        inode->i_flags |= S_NOATIME;
 280        unlock_new_inode(inode);
 281        _leave(" = %p [CB { v=%u t=%u }]", inode, vnode->cb_version, vnode->cb_type);
 282        return inode;
 283
 284        /* failure */
 285bad_inode:
 286#ifdef CONFIG_AFS_FSCACHE
 287        fscache_relinquish_cookie(vnode->cache, 0);
 288        vnode->cache = NULL;
 289#endif
 290        iget_failed(inode);
 291        _leave(" = %d [bad]", ret);
 292        return ERR_PTR(ret);
 293}
 294
 295/*
 296 * mark the data attached to an inode as obsolete due to a write on the server
 297 * - might also want to ditch all the outstanding writes and dirty pages
 298 */
 299void afs_zap_data(struct afs_vnode *vnode)
 300{
 301        _enter("{%x:%u}", vnode->fid.vid, vnode->fid.vnode);
 302
 303        /* nuke all the non-dirty pages that aren't locked, mapped or being
 304         * written back in a regular file and completely discard the pages in a
 305         * directory or symlink */
 306        if (S_ISREG(vnode->vfs_inode.i_mode))
 307                invalidate_remote_inode(&vnode->vfs_inode);
 308        else
 309                invalidate_inode_pages2(vnode->vfs_inode.i_mapping);
 310}
 311
 312/*
 313 * validate a vnode/inode
 314 * - there are several things we need to check
 315 *   - parent dir data changes (rm, rmdir, rename, mkdir, create, link,
 316 *     symlink)
 317 *   - parent dir metadata changed (security changes)
 318 *   - dentry data changed (write, truncate)
 319 *   - dentry metadata changed (security changes)
 320 */
 321int afs_validate(struct afs_vnode *vnode, struct key *key)
 322{
 323        int ret;
 324
 325        _enter("{v={%x:%u} fl=%lx},%x",
 326               vnode->fid.vid, vnode->fid.vnode, vnode->flags,
 327               key_serial(key));
 328
 329        if (vnode->cb_promised &&
 330            !test_bit(AFS_VNODE_CB_BROKEN, &vnode->flags) &&
 331            !test_bit(AFS_VNODE_MODIFIED, &vnode->flags) &&
 332            !test_bit(AFS_VNODE_ZAP_DATA, &vnode->flags)) {
 333                if (vnode->cb_expires < ktime_get_real_seconds() + 10) {
 334                        _debug("callback expired");
 335                        set_bit(AFS_VNODE_CB_BROKEN, &vnode->flags);
 336                } else {
 337                        goto valid;
 338                }
 339        }
 340
 341        if (test_bit(AFS_VNODE_DELETED, &vnode->flags))
 342                goto valid;
 343
 344        mutex_lock(&vnode->validate_lock);
 345
 346        /* if the promise has expired, we need to check the server again to get
 347         * a new promise - note that if the (parent) directory's metadata was
 348         * changed then the security may be different and we may no longer have
 349         * access */
 350        if (!vnode->cb_promised ||
 351            test_bit(AFS_VNODE_CB_BROKEN, &vnode->flags)) {
 352                _debug("not promised");
 353                ret = afs_vnode_fetch_status(vnode, NULL, key);
 354                if (ret < 0)
 355                        goto error_unlock;
 356                _debug("new promise [fl=%lx]", vnode->flags);
 357        }
 358
 359        if (test_bit(AFS_VNODE_DELETED, &vnode->flags)) {
 360                _debug("file already deleted");
 361                ret = -ESTALE;
 362                goto error_unlock;
 363        }
 364
 365        /* if the vnode's data version number changed then its contents are
 366         * different */
 367        if (test_and_clear_bit(AFS_VNODE_ZAP_DATA, &vnode->flags))
 368                afs_zap_data(vnode);
 369
 370        clear_bit(AFS_VNODE_MODIFIED, &vnode->flags);
 371        mutex_unlock(&vnode->validate_lock);
 372valid:
 373        _leave(" = 0");
 374        return 0;
 375
 376error_unlock:
 377        mutex_unlock(&vnode->validate_lock);
 378        _leave(" = %d", ret);
 379        return ret;
 380}
 381
 382/*
 383 * read the attributes of an inode
 384 */
 385int afs_getattr(const struct path *path, struct kstat *stat,
 386                u32 request_mask, unsigned int query_flags)
 387{
 388        struct inode *inode = d_inode(path->dentry);
 389
 390        _enter("{ ino=%lu v=%u }", inode->i_ino, inode->i_generation);
 391
 392        generic_fillattr(inode, stat);
 393        return 0;
 394}
 395
 396/*
 397 * discard an AFS inode
 398 */
 399int afs_drop_inode(struct inode *inode)
 400{
 401        _enter("");
 402
 403        if (test_bit(AFS_VNODE_PSEUDODIR, &AFS_FS_I(inode)->flags))
 404                return generic_delete_inode(inode);
 405        else
 406                return generic_drop_inode(inode);
 407}
 408
 409/*
 410 * clear an AFS inode
 411 */
 412void afs_evict_inode(struct inode *inode)
 413{
 414        struct afs_permits *permits;
 415        struct afs_vnode *vnode;
 416
 417        vnode = AFS_FS_I(inode);
 418
 419        _enter("{%x:%u.%d} v=%u x=%u t=%u }",
 420               vnode->fid.vid,
 421               vnode->fid.vnode,
 422               vnode->fid.unique,
 423               vnode->cb_version,
 424               vnode->cb_expiry,
 425               vnode->cb_type);
 426
 427        _debug("CLEAR INODE %p", inode);
 428
 429        ASSERTCMP(inode->i_ino, ==, vnode->fid.vnode);
 430
 431        truncate_inode_pages_final(&inode->i_data);
 432        clear_inode(inode);
 433
 434        afs_give_up_callback(vnode);
 435
 436        if (vnode->server) {
 437                spin_lock(&vnode->server->fs_lock);
 438                rb_erase(&vnode->server_rb, &vnode->server->fs_vnodes);
 439                spin_unlock(&vnode->server->fs_lock);
 440                afs_put_server(vnode->server);
 441                vnode->server = NULL;
 442        }
 443
 444        ASSERT(list_empty(&vnode->writebacks));
 445        ASSERT(!vnode->cb_promised);
 446
 447#ifdef CONFIG_AFS_FSCACHE
 448        fscache_relinquish_cookie(vnode->cache, 0);
 449        vnode->cache = NULL;
 450#endif
 451
 452        mutex_lock(&vnode->permits_lock);
 453        permits = vnode->permits;
 454        RCU_INIT_POINTER(vnode->permits, NULL);
 455        mutex_unlock(&vnode->permits_lock);
 456        if (permits)
 457                call_rcu(&permits->rcu, afs_zap_permits);
 458
 459        _leave("");
 460}
 461
 462/*
 463 * set the attributes of an inode
 464 */
 465int afs_setattr(struct dentry *dentry, struct iattr *attr)
 466{
 467        struct afs_vnode *vnode = AFS_FS_I(d_inode(dentry));
 468        struct key *key;
 469        int ret;
 470
 471        _enter("{%x:%u},{n=%pd},%x",
 472               vnode->fid.vid, vnode->fid.vnode, dentry,
 473               attr->ia_valid);
 474
 475        if (!(attr->ia_valid & (ATTR_SIZE | ATTR_MODE | ATTR_UID | ATTR_GID |
 476                                ATTR_MTIME))) {
 477                _leave(" = 0 [unsupported]");
 478                return 0;
 479        }
 480
 481        /* flush any dirty data outstanding on a regular file */
 482        if (S_ISREG(vnode->vfs_inode.i_mode)) {
 483                filemap_write_and_wait(vnode->vfs_inode.i_mapping);
 484                afs_writeback_all(vnode);
 485        }
 486
 487        if (attr->ia_valid & ATTR_FILE) {
 488                key = attr->ia_file->private_data;
 489        } else {
 490                key = afs_request_key(vnode->volume->cell);
 491                if (IS_ERR(key)) {
 492                        ret = PTR_ERR(key);
 493                        goto error;
 494                }
 495        }
 496
 497        ret = afs_vnode_setattr(vnode, key, attr);
 498        if (!(attr->ia_valid & ATTR_FILE))
 499                key_put(key);
 500
 501error:
 502        _leave(" = %d", ret);
 503        return ret;
 504}
 505