The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/fs/nfs/symlink.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*
    2  *  linux/fs/nfs/symlink.c
    3  *
    4  *  Copyright (C) 1992  Rick Sladkey
    5  *
    6  *  Optimization changes Copyright (C) 1994 Florian La Roche
    7  *
    8  *  Jun 7 1999, cache symlink lookups in the page cache.  -DaveM
    9  *
   10  *  nfs symlink handling code
   11  */
   12 
   13 #define NFS_NEED_XDR_TYPES
   14 #include <linux/sched.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/slab.h>
   24 #include <linux/string.h>
   25 #include <linux/smp_lock.h>
   26 
   27 /* Symlink caching in the page cache is even more simplistic
   28  * and straight-forward than readdir caching.
   29  */
   30 static int nfs_symlink_filler(struct inode *inode, struct page *page)
   31 {
   32         int error;
   33 
   34         /* We place the length at the beginning of the page,
   35          * in host byte order, followed by the string.  The
   36          * XDR response verification will NULL terminate it.
   37          */
   38         lock_kernel();
   39         error = NFS_PROTO(inode)->readlink(inode, page);
   40         unlock_kernel();
   41         if (error < 0)
   42                 goto error;
   43         SetPageUptodate(page);
   44         UnlockPage(page);
   45         return 0;
   46 
   47 error:
   48         SetPageError(page);
   49         UnlockPage(page);
   50         return -EIO;
   51 }
   52 
   53 static char *nfs_getlink(struct inode *inode, struct page **ppage)
   54 {
   55         struct page *page;
   56         u32 *p;
   57 
   58         /* Caller revalidated the directory inode already. */
   59         page = read_cache_page(&inode->i_data, 0,
   60                                 (filler_t *)nfs_symlink_filler, inode);
   61         if (IS_ERR(page))
   62                 goto read_failed;
   63         if (!Page_Uptodate(page))
   64                 goto getlink_read_error;
   65         *ppage = page;
   66         p = kmap(page);
   67         return (char*)(p+1);
   68                 
   69 getlink_read_error:
   70         page_cache_release(page);
   71         return ERR_PTR(-EIO);
   72 read_failed:
   73         return (char*)page;
   74 }
   75 
   76 static int nfs_readlink(struct dentry *dentry, char *buffer, int buflen)
   77 {
   78         struct inode *inode = dentry->d_inode;
   79         struct page *page = NULL;
   80         int res = vfs_readlink(dentry,buffer,buflen,nfs_getlink(inode,&page));
   81         if (page) {
   82                 kunmap(page);
   83                 page_cache_release(page);
   84         }
   85         return res;
   86 }
   87 
   88 static int nfs_follow_link(struct dentry *dentry, struct nameidata *nd)
   89 {
   90         struct inode *inode = dentry->d_inode;
   91         struct page *page = NULL;
   92         int res = vfs_follow_link(nd, nfs_getlink(inode,&page));
   93         if (page) {
   94                 kunmap(page);
   95                 page_cache_release(page);
   96         }
   97         return res;
   98 }
   99 
  100 /*
  101  * symlinks can't do much...
  102  */
  103 struct inode_operations nfs_symlink_inode_operations = {
  104         readlink:       nfs_readlink,
  105         follow_link:    nfs_follow_link,
  106         revalidate:     nfs_revalidate,
  107         setattr:        nfs_notify_change,
  108 };

Cache object: 4d2db865eb6006e87ac3225d5d042c8b


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.