2005-04-17 02:20:36 +04:00
/*
* linux / fs / affs / symlink . c
*
* 1995 Hans - Joachim Widmaier - Modified for affs .
*
* Copyright ( C ) 1991 , 1992 Linus Torvalds
*
* affs symlink handling code
*/
# include "affs.h"
static int affs_symlink_readpage ( struct file * file , struct page * page )
{
struct buffer_head * bh ;
struct inode * inode = page - > mapping - > host ;
char * link = kmap ( page ) ;
struct slink_front * lf ;
int err ;
int i , j ;
char c ;
char lc ;
pr_debug ( " AFFS: follow_link(ino=%lu) \n " , inode - > i_ino ) ;
err = - EIO ;
bh = affs_bread ( inode - > i_sb , inode - > i_ino ) ;
if ( ! bh )
goto fail ;
i = 0 ;
j = 0 ;
lf = ( struct slink_front * ) bh - > b_data ;
lc = 0 ;
if ( strchr ( lf - > symname , ' : ' ) ) { /* Handle assign or volume name */
2010-01-24 08:04:07 +03:00
struct affs_sb_info * sbi = AFFS_SB ( inode - > i_sb ) ;
char * pf ;
spin_lock ( & sbi - > symlink_lock ) ;
pf = sbi - > s_prefix ? sbi - > s_prefix : " / " ;
2005-04-17 02:20:36 +04:00
while ( i < 1023 & & ( c = pf [ i ] ) )
link [ i + + ] = c ;
2010-01-24 08:04:07 +03:00
spin_unlock ( & sbi - > symlink_lock ) ;
2005-04-17 02:20:36 +04:00
while ( i < 1023 & & lf - > symname [ j ] ! = ' : ' )
link [ i + + ] = lf - > symname [ j + + ] ;
if ( i < 1023 )
link [ i + + ] = ' / ' ;
j + + ;
lc = ' / ' ;
}
while ( i < 1023 & & ( c = lf - > symname [ j ] ) ) {
if ( c = = ' / ' & & lc = = ' / ' & & i < 1020 ) { /* parent dir */
link [ i + + ] = ' . ' ;
link [ i + + ] = ' . ' ;
}
link [ i + + ] = c ;
lc = c ;
j + + ;
}
link [ i ] = ' \0 ' ;
affs_brelse ( bh ) ;
SetPageUptodate ( page ) ;
kunmap ( page ) ;
unlock_page ( page ) ;
return 0 ;
fail :
SetPageError ( page ) ;
kunmap ( page ) ;
unlock_page ( page ) ;
return err ;
}
2006-06-28 15:26:44 +04:00
const struct address_space_operations affs_symlink_aops = {
2005-04-17 02:20:36 +04:00
. readpage = affs_symlink_readpage ,
} ;
2007-02-12 11:55:38 +03:00
const struct inode_operations affs_symlink_inode_operations = {
2005-04-17 02:20:36 +04:00
. readlink = generic_readlink ,
. follow_link = page_follow_link_light ,
. put_link = page_put_link ,
. setattr = affs_notify_change ,
} ;