2005-04-17 02:20:36 +04:00
/*
* linux / fs / nfs / symlink . c
*
* Copyright ( C ) 1992 Rick Sladkey
*
* Optimization changes Copyright ( C ) 1994 Florian La Roche
*
* Jun 7 1999 , cache symlink lookups in the page cache . - DaveM
*
* nfs symlink handling code
*/
# include <linux/time.h>
# include <linux/errno.h>
# include <linux/sunrpc/clnt.h>
# include <linux/nfs.h>
# include <linux/nfs2.h>
# include <linux/nfs_fs.h>
# include <linux/pagemap.h>
# include <linux/stat.h>
# include <linux/mm.h>
# include <linux/slab.h>
# include <linux/string.h>
# include <linux/namei.h>
/* Symlink caching in the page cache is even more simplistic
* and straight - forward than readdir caching .
*/
static int nfs_symlink_filler ( struct inode * inode , struct page * page )
{
int error ;
2005-08-20 05:02:56 +04:00
error = NFS_PROTO ( inode ) - > readlink ( inode , page , 0 , PAGE_SIZE ) ;
2005-04-17 02:20:36 +04:00
if ( error < 0 )
goto error ;
SetPageUptodate ( page ) ;
unlock_page ( page ) ;
return 0 ;
error :
SetPageError ( page ) ;
unlock_page ( page ) ;
return - EIO ;
}
2005-08-20 05:02:56 +04:00
static void * nfs_follow_link ( struct dentry * dentry , struct nameidata * nd )
2005-04-17 02:20:36 +04:00
{
struct inode * inode = dentry - > d_inode ;
struct page * page ;
2007-01-24 22:54:55 +03:00
void * err ;
err = ERR_PTR ( nfs_revalidate_mapping_nolock ( inode , inode - > i_mapping ) ) ;
2005-04-17 02:20:36 +04:00
if ( err )
goto read_failed ;
page = read_cache_page ( & inode - > i_data , 0 ,
( filler_t * ) nfs_symlink_filler , inode ) ;
if ( IS_ERR ( page ) ) {
err = page ;
goto read_failed ;
}
2005-08-20 05:02:56 +04:00
nd_set_link ( nd , kmap ( page ) ) ;
return page ;
2005-04-17 02:20:36 +04:00
read_failed :
nd_set_link ( nd , err ) ;
2005-08-20 05:02:56 +04:00
return NULL ;
2005-04-17 02:20:36 +04:00
}
/*
* symlinks can ' t do much . . .
*/
2007-02-12 11:55:39 +03:00
const struct inode_operations nfs_symlink_inode_operations = {
2005-04-17 02:20:36 +04:00
. readlink = generic_readlink ,
. follow_link = nfs_follow_link ,
2006-06-25 13:41:28 +04:00
. put_link = page_put_link ,
2005-04-17 02:20:36 +04:00
. getattr = nfs_getattr ,
. setattr = nfs_setattr ,
} ;