linux/fs/afs/file.c
<<
>>
Prefs
   1/* AFS filesystem file handling
   2 *
   3 * Copyright (C) 2002, 2007 Red Hat, Inc. All Rights Reserved.
   4 * Written by David Howells (dhowells@redhat.com)
   5 *
   6 * This program is free software; you can redistribute it and/or
   7 * modify it under the terms of the GNU General Public License
   8 * as published by the Free Software Foundation; either version
   9 * 2 of the License, or (at your option) any later version.
  10 */
  11
  12#include <linux/kernel.h>
  13#include <linux/module.h>
  14#include <linux/init.h>
  15#include <linux/fs.h>
  16#include <linux/pagemap.h>
  17#include <linux/writeback.h>
  18#include <linux/gfp.h>
  19#include "internal.h"
  20
  21static int afs_readpage(struct file *file, struct page *page);
  22static void afs_invalidatepage(struct page *page, unsigned int offset,
  23                               unsigned int length);
  24static int afs_releasepage(struct page *page, gfp_t gfp_flags);
  25static int afs_launder_page(struct page *page);
  26
  27static int afs_readpages(struct file *filp, struct address_space *mapping,
  28                         struct list_head *pages, unsigned nr_pages);
  29
  30const struct file_operations afs_file_operations = {
  31        .open           = afs_open,
  32        .release        = afs_release,
  33        .llseek         = generic_file_llseek,
  34        .read_iter      = generic_file_read_iter,
  35        .write_iter     = afs_file_write,
  36        .mmap           = generic_file_readonly_mmap,
  37        .splice_read    = generic_file_splice_read,
  38        .fsync          = afs_fsync,
  39        .lock           = afs_lock,
  40        .flock          = afs_flock,
  41};
  42
  43const struct inode_operations afs_file_inode_operations = {
  44        .getattr        = afs_getattr,
  45        .setattr        = afs_setattr,
  46        .permission     = afs_permission,
  47};
  48
  49const struct address_space_operations afs_fs_aops = {
  50        .readpage       = afs_readpage,
  51        .readpages      = afs_readpages,
  52        .set_page_dirty = afs_set_page_dirty,
  53        .launder_page   = afs_launder_page,
  54        .releasepage    = afs_releasepage,
  55        .invalidatepage = afs_invalidatepage,
  56        .write_begin    = afs_write_begin,
  57        .write_end      = afs_write_end,
  58        .writepage      = afs_writepage,
  59        .writepages     = afs_writepages,
  60};
  61
  62/*
  63 * open an AFS file or directory and attach a key to it
  64 */
  65int afs_open(struct inode *inode, struct file *file)
  66{
  67        struct afs_vnode *vnode = AFS_FS_I(inode);
  68        struct key *key;
  69        int ret;
  70
  71        _enter("{%x:%u},", vnode->fid.vid, vnode->fid.vnode);
  72
  73        key = afs_request_key(vnode->volume->cell);
  74        if (IS_ERR(key)) {
  75                _leave(" = %ld [key]", PTR_ERR(key));
  76                return PTR_ERR(key);
  77        }
  78
  79        ret = afs_validate(vnode, key);
  80        if (ret < 0) {
  81                _leave(" = %d [val]", ret);
  82                return ret;
  83        }
  84
  85        file->private_data = key;
  86        _leave(" = 0");
  87        return 0;
  88}
  89
  90/*
  91 * release an AFS file or directory and discard its key
  92 */
  93int afs_release(struct inode *inode, struct file *file)
  94{
  95        struct afs_vnode *vnode = AFS_FS_I(inode);
  96
  97        _enter("{%x:%u},", vnode->fid.vid, vnode->fid.vnode);
  98
  99        key_put(file->private_data);
 100        _leave(" = 0");
 101        return 0;
 102}
 103
 104#ifdef CONFIG_AFS_FSCACHE
 105/*
 106 * deal with notification that a page was read from the cache
 107 */
 108static void afs_file_readpage_read_complete(struct page *page,
 109                                            void *data,
 110                                            int error)
 111{
 112        _enter("%p,%p,%d", page, data, error);
 113
 114        /* if the read completes with an error, we just unlock the page and let
 115         * the VM reissue the readpage */
 116        if (!error)
 117                SetPageUptodate(page);
 118        unlock_page(page);
 119}
 120#endif
 121
 122/*
 123 * read page from file, directory or symlink, given a key to use
 124 */
 125int afs_page_filler(void *data, struct page *page)
 126{
 127        struct inode *inode = page->mapping->host;
 128        struct afs_vnode *vnode = AFS_FS_I(inode);
 129        struct key *key = data;
 130        size_t len;
 131        off_t offset;
 132        int ret;
 133
 134        _enter("{%x},{%lu},{%lu}", key_serial(key), inode->i_ino, page->index);
 135
 136        BUG_ON(!PageLocked(page));
 137
 138        ret = -ESTALE;
 139        if (test_bit(AFS_VNODE_DELETED, &vnode->flags))
 140                goto error;
 141
 142        /* is it cached? */
 143#ifdef CONFIG_AFS_FSCACHE
 144        ret = fscache_read_or_alloc_page(vnode->cache,
 145                                         page,
 146                                         afs_file_readpage_read_complete,
 147                                         NULL,
 148                                         GFP_KERNEL);
 149#else
 150        ret = -ENOBUFS;
 151#endif
 152        switch (ret) {
 153                /* read BIO submitted (page in cache) */
 154        case 0:
 155                break;
 156
 157                /* page not yet cached */
 158        case -ENODATA:
 159                _debug("cache said ENODATA");
 160                goto go_on;
 161
 162                /* page will not be cached */
 163        case -ENOBUFS:
 164                _debug("cache said ENOBUFS");
 165        default:
 166        go_on:
 167                offset = page->index << PAGE_SHIFT;
 168                len = min_t(size_t, i_size_read(inode) - offset, PAGE_SIZE);
 169
 170                /* read the contents of the file from the server into the
 171                 * page */
 172                ret = afs_vnode_fetch_data(vnode, key, offset, len, page);
 173                if (ret < 0) {
 174                        if (ret == -ENOENT) {
 175                                _debug("got NOENT from server"
 176                                       " - marking file deleted and stale");
 177                                set_bit(AFS_VNODE_DELETED, &vnode->flags);
 178                                ret = -ESTALE;
 179                        }
 180
 181#ifdef CONFIG_AFS_FSCACHE
 182                        fscache_uncache_page(vnode->cache, page);
 183#endif
 184                        BUG_ON(PageFsCache(page));
 185                        goto error;
 186                }
 187
 188                SetPageUptodate(page);
 189
 190                /* send the page to the cache */
 191#ifdef CONFIG_AFS_FSCACHE
 192                if (PageFsCache(page) &&
 193                    fscache_write_page(vnode->cache, page, GFP_KERNEL) != 0) {
 194                        fscache_uncache_page(vnode->cache, page);
 195                        BUG_ON(PageFsCache(page));
 196                }
 197#endif
 198                unlock_page(page);
 199        }
 200
 201        _leave(" = 0");
 202        return 0;
 203
 204error:
 205        SetPageError(page);
 206        unlock_page(page);
 207        _leave(" = %d", ret);
 208        return ret;
 209}
 210
 211/*
 212 * read page from file, directory or symlink, given a file to nominate the key
 213 * to be used
 214 */
 215static int afs_readpage(struct file *file, struct page *page)
 216{
 217        struct key *key;
 218        int ret;
 219
 220        if (file) {
 221                key = file->private_data;
 222                ASSERT(key != NULL);
 223                ret = afs_page_filler(key, page);
 224        } else {
 225                struct inode *inode = page->mapping->host;
 226                key = afs_request_key(AFS_FS_S(inode->i_sb)->volume->cell);
 227                if (IS_ERR(key)) {
 228                        ret = PTR_ERR(key);
 229                } else {
 230                        ret = afs_page_filler(key, page);
 231                        key_put(key);
 232                }
 233        }
 234        return ret;
 235}
 236
 237/*
 238 * read a set of pages
 239 */
 240static int afs_readpages(struct file *file, struct address_space *mapping,
 241                         struct list_head *pages, unsigned nr_pages)
 242{
 243        struct key *key = file->private_data;
 244        struct afs_vnode *vnode;
 245        int ret = 0;
 246
 247        _enter("{%d},{%lu},,%d",
 248               key_serial(key), mapping->host->i_ino, nr_pages);
 249
 250        ASSERT(key != NULL);
 251
 252        vnode = AFS_FS_I(mapping->host);
 253        if (test_bit(AFS_VNODE_DELETED, &vnode->flags)) {
 254                _leave(" = -ESTALE");
 255                return -ESTALE;
 256        }
 257
 258        /* attempt to read as many of the pages as possible */
 259#ifdef CONFIG_AFS_FSCACHE
 260        ret = fscache_read_or_alloc_pages(vnode->cache,
 261                                          mapping,
 262                                          pages,
 263                                          &nr_pages,
 264                                          afs_file_readpage_read_complete,
 265                                          NULL,
 266                                          mapping_gfp_mask(mapping));
 267#else
 268        ret = -ENOBUFS;
 269#endif
 270
 271        switch (ret) {
 272                /* all pages are being read from the cache */
 273        case 0:
 274                BUG_ON(!list_empty(pages));
 275                BUG_ON(nr_pages != 0);
 276                _leave(" = 0 [reading all]");
 277                return 0;
 278
 279                /* there were pages that couldn't be read from the cache */
 280        case -ENODATA:
 281        case -ENOBUFS:
 282                break;
 283
 284                /* other error */
 285        default:
 286                _leave(" = %d", ret);
 287                return ret;
 288        }
 289
 290        /* load the missing pages from the network */
 291        ret = read_cache_pages(mapping, pages, afs_page_filler, key);
 292
 293        _leave(" = %d [netting]", ret);
 294        return ret;
 295}
 296
 297/*
 298 * write back a dirty page
 299 */
 300static int afs_launder_page(struct page *page)
 301{
 302        _enter("{%lu}", page->index);
 303
 304        return 0;
 305}
 306
 307/*
 308 * invalidate part or all of a page
 309 * - release a page and clean up its private data if offset is 0 (indicating
 310 *   the entire page)
 311 */
 312static void afs_invalidatepage(struct page *page, unsigned int offset,
 313                               unsigned int length)
 314{
 315        struct afs_writeback *wb = (struct afs_writeback *) page_private(page);
 316
 317        _enter("{%lu},%u,%u", page->index, offset, length);
 318
 319        BUG_ON(!PageLocked(page));
 320
 321        /* we clean up only if the entire page is being invalidated */
 322        if (offset == 0 && length == PAGE_SIZE) {
 323#ifdef CONFIG_AFS_FSCACHE
 324                if (PageFsCache(page)) {
 325                        struct afs_vnode *vnode = AFS_FS_I(page->mapping->host);
 326                        fscache_wait_on_page_write(vnode->cache, page);
 327                        fscache_uncache_page(vnode->cache, page);
 328                }
 329#endif
 330
 331                if (PagePrivate(page)) {
 332                        if (wb && !PageWriteback(page)) {
 333                                set_page_private(page, 0);
 334                                afs_put_writeback(wb);
 335                        }
 336
 337                        if (!page_private(page))
 338                                ClearPagePrivate(page);
 339                }
 340        }
 341
 342        _leave("");
 343}
 344
 345/*
 346 * release a page and clean up its private state if it's not busy
 347 * - return true if the page can now be released, false if not
 348 */
 349static int afs_releasepage(struct page *page, gfp_t gfp_flags)
 350{
 351        struct afs_writeback *wb = (struct afs_writeback *) page_private(page);
 352        struct afs_vnode *vnode = AFS_FS_I(page->mapping->host);
 353
 354        _enter("{{%x:%u}[%lu],%lx},%x",
 355               vnode->fid.vid, vnode->fid.vnode, page->index, page->flags,
 356               gfp_flags);
 357
 358        /* deny if page is being written to the cache and the caller hasn't
 359         * elected to wait */
 360#ifdef CONFIG_AFS_FSCACHE
 361        if (!fscache_maybe_release_page(vnode->cache, page, gfp_flags)) {
 362                _leave(" = F [cache busy]");
 363                return 0;
 364        }
 365#endif
 366
 367        if (PagePrivate(page)) {
 368                if (wb) {
 369                        set_page_private(page, 0);
 370                        afs_put_writeback(wb);
 371                }
 372                ClearPagePrivate(page);
 373        }
 374
 375        /* indicate that the page can be released */
 376        _leave(" = T");
 377        return 1;
 378}
 379