cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

symlink.c (1895B)


      1// SPDX-License-Identifier: GPL-2.0
      2/*
      3 *  linux/fs/nfs/symlink.c
      4 *
      5 *  Copyright (C) 1992  Rick Sladkey
      6 *
      7 *  Optimization changes Copyright (C) 1994 Florian La Roche
      8 *
      9 *  Jun 7 1999, cache symlink lookups in the page cache.  -DaveM
     10 *
     11 *  nfs symlink handling code
     12 */
     13
     14#include <linux/time.h>
     15#include <linux/errno.h>
     16#include <linux/sunrpc/clnt.h>
     17#include <linux/nfs.h>
     18#include <linux/nfs2.h>
     19#include <linux/nfs_fs.h>
     20#include <linux/pagemap.h>
     21#include <linux/stat.h>
     22#include <linux/mm.h>
     23#include <linux/string.h>
     24
     25/* Symlink caching in the page cache is even more simplistic
     26 * and straight-forward than readdir caching.
     27 */
     28
     29static int nfs_symlink_filler(struct file *file, struct folio *folio)
     30{
     31	struct inode *inode = folio->mapping->host;
     32	int error;
     33
     34	error = NFS_PROTO(inode)->readlink(inode, &folio->page, 0, PAGE_SIZE);
     35	if (error < 0)
     36		goto error;
     37	folio_mark_uptodate(folio);
     38	folio_unlock(folio);
     39	return 0;
     40
     41error:
     42	folio_set_error(folio);
     43	folio_unlock(folio);
     44	return -EIO;
     45}
     46
     47static const char *nfs_get_link(struct dentry *dentry,
     48				struct inode *inode,
     49				struct delayed_call *done)
     50{
     51	struct page *page;
     52	void *err;
     53
     54	if (!dentry) {
     55		err = ERR_PTR(nfs_revalidate_mapping_rcu(inode));
     56		if (err)
     57			return err;
     58		page = find_get_page(inode->i_mapping, 0);
     59		if (!page)
     60			return ERR_PTR(-ECHILD);
     61		if (!PageUptodate(page)) {
     62			put_page(page);
     63			return ERR_PTR(-ECHILD);
     64		}
     65	} else {
     66		err = ERR_PTR(nfs_revalidate_mapping(inode, inode->i_mapping));
     67		if (err)
     68			return err;
     69		page = read_cache_page(&inode->i_data, 0, nfs_symlink_filler,
     70				NULL);
     71		if (IS_ERR(page))
     72			return ERR_CAST(page);
     73	}
     74	set_delayed_call(done, page_put_link, page);
     75	return page_address(page);
     76}
     77
     78/*
     79 * symlinks can't do much...
     80 */
     81const struct inode_operations nfs_symlink_inode_operations = {
     82	.get_link	= nfs_get_link,
     83	.getattr	= nfs_getattr,
     84	.setattr	= nfs_setattr,
     85};