~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Linux Cross Reference
Linux/fs/nfs/symlink.c

Version: ~ [ 2.4.0 ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  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/malloc.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         void *buffer = kmap(page);
 33         int error;
 34 
 35         /* We place the length at the beginning of the page,
 36          * in host byte order, followed by the string.  The
 37          * XDR response verification will NULL terminate it.
 38          */
 39         lock_kernel();
 40         error = NFS_PROTO(inode)->readlink(inode, buffer,
 41                                            PAGE_CACHE_SIZE - sizeof(u32)-4);
 42         unlock_kernel();
 43         if (error < 0)
 44                 goto error;
 45         SetPageUptodate(page);
 46         kunmap(page);
 47         UnlockPage(page);
 48         return 0;
 49 
 50 error:
 51         SetPageError(page);
 52         kunmap(page);
 53         UnlockPage(page);
 54         return -EIO;
 55 }
 56 
 57 static char *nfs_getlink(struct inode *inode, struct page **ppage)
 58 {
 59         struct page *page;
 60         u32 *p;
 61 
 62         /* Caller revalidated the directory inode already. */
 63         page = read_cache_page(&inode->i_data, 0,
 64                                 (filler_t *)nfs_symlink_filler, inode);
 65         if (IS_ERR(page))
 66                 goto read_failed;
 67         if (!Page_Uptodate(page))
 68                 goto getlink_read_error;
 69         *ppage = page;
 70         p = kmap(page);
 71         return (char*)(p+1);
 72                 
 73 getlink_read_error:
 74         page_cache_release(page);
 75         return ERR_PTR(-EIO);
 76 read_failed:
 77         return (char*)page;
 78 }
 79 
 80 static int nfs_readlink(struct dentry *dentry, char *buffer, int buflen)
 81 {
 82         struct inode *inode = dentry->d_inode;
 83         struct page *page = NULL;
 84         int res = vfs_readlink(dentry,buffer,buflen,nfs_getlink(inode,&page));
 85         if (page) {
 86                 kunmap(page);
 87                 page_cache_release(page);
 88         }
 89         return res;
 90 }
 91 
 92 static int nfs_follow_link(struct dentry *dentry, struct nameidata *nd)
 93 {
 94         struct inode *inode = dentry->d_inode;
 95         struct page *page = NULL;
 96         int res = vfs_follow_link(nd, nfs_getlink(inode,&page));
 97         if (page) {
 98                 kunmap(page);
 99                 page_cache_release(page);
100         }
101         return res;
102 }
103 
104 /*
105  * symlinks can't do much...
106  */
107 struct inode_operations nfs_symlink_inode_operations = {
108         readlink:       nfs_readlink,
109         follow_link:    nfs_follow_link,
110         revalidate:     nfs_revalidate,
111         setattr:        nfs_notify_change,
112 };
113 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.