lkml.org 
[lkml]   [2004]   [May]   [2]   [last100]   RSS Feed
Views: [more markup]  [less markup]  [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Subject[PATCH] FAT: Fix nfsv2 support (1/4)
    FromOGAWA Hirofumi <>
    DateSun, 02 May 2004 22:08:08 +0900
    Hi,
    
    The ->dentry_to_fh() can use the 20 bytes in the case of NFSv2, but
    fat_dentry_to_fh() requires 24 bytes by my patch.
    
    So nfsd reply the EOPNOTSUPP to nfs client, then nfs client convert
    the unknown error to -EIO.
    
    This patch fixes the problem by pushing the handle data into 20 bytes. 
    
    Please apply.
    -- 
    OGAWA Hirofumi <hirofumi@mail.parknet.co.jp>
    
    
    
     fs/fat/inode.c |   42 ++++++++++++++++++++++++++----------------
     1 files changed, 26 insertions(+), 16 deletions(-)
    diff -puN fs/fat/inode.c~fat_nfsv2-fix fs/fat/inode.c
    --- linux-2.6.6-rc3/fs/fat/inode.c~fat_nfsv2-fix	2004-05-02 19:15:34.000000000 +0900
    +++ linux-2.6.6-rc3-hirofumi/fs/fat/inode.c	2004-05-02 19:15:34.000000000 +0900
    @@ -557,11 +557,13 @@ static int fat_read_root(struct inode *i
      *  0/  i_ino - for fast, reliable lookup if still in the cache
      *  1/  i_generation - to see if i_ino is still valid
      *          bit 0 == 0 iff directory
    - *  2/  i_pos - if ino has changed, but still in cache (hi)
    - *  3/  i_pos - if ino has changed, but still in cache (low)
    - *  4/  i_logstart - to semi-verify inode found at i_location
    - *  5/  parent->i_logstart - maybe used to hunt for the file on disc
    + *  2/  i_pos(8-39) - if ino has changed, but still in cache
    + *  3/  i_pos(4-7)|i_logstart - to semi-verify inode found at i_pos
    + *  4/  i_pos(0-3)|parent->i_logstart - maybe used to hunt for the file on disc
      *
    + * Hack for NFSv2: Maximum FAT entry number is 28bits and maximum
    + * i_pos is 40bits (blocknr(32) + dir offset(8)), so two 4bits
    + * of i_logstart is used to store the directory entry offset.
      */
     
     struct dentry *fat_decode_fh(struct super_block *sb, __u32 *fh,
    @@ -572,7 +574,7 @@ struct dentry *fat_decode_fh(struct supe
     
     	if (fhtype != 3)
     		return ERR_PTR(-ESTALE);
    -	if (len < 6)
    +	if (len < 5)
     		return ERR_PTR(-ESTALE);
     
     	return sb->s_export_op->find_exported_dentry(sb, fh, NULL, acceptable, context);
    @@ -585,13 +587,17 @@ struct dentry *fat_get_dentry(struct sup
     	__u32 *fh = inump;
     
     	inode = iget(sb, fh[0]);
    -	if (!inode || is_bad_inode(inode) ||
    -	    inode->i_generation != fh[1]) {
    -		if (inode) iput(inode);
    +	if (!inode || is_bad_inode(inode) || inode->i_generation != fh[1]) {
    +		if (inode)
    +			iput(inode);
     		inode = NULL;
     	}
     	if (!inode) {
    -		loff_t i_pos = ((loff_t)fh[2] << 32) | fh[3];
    +		loff_t i_pos;
    +		int i_logstart = fh[3] & 0x0fffffff;
    +
    +		i_pos = (loff_t)fh[2] << 8;
    +		i_pos |= ((fh[3] >> 24) & 0xf0) | (fh[4] >> 28);
     
     		/* try 2 - see if i_pos is in F-d-c
     		 * require i_logstart to be the same
    @@ -599,7 +605,7 @@ struct dentry *fat_get_dentry(struct sup
     		 */
     
     		inode = fat_iget(sb, i_pos);
    -		if (inode && MSDOS_I(inode)->i_logstart != fh[4]) {
    +		if (inode && MSDOS_I(inode)->i_logstart != i_logstart) {
     			iput(inode);
     			inode = NULL;
     		}
    @@ -638,17 +644,21 @@ int fat_encode_fh(struct dentry *de, __u
     {
     	int len = *lenp;
     	struct inode *inode =  de->d_inode;
    +	u32 ipos_h, ipos_m, ipos_l;
     	
    -	if (len < 6)
    +	if (len < 5)
     		return 255; /* no room */
    -	*lenp = 6;
    +
    +	ipos_h = MSDOS_I(inode)->i_pos >> 8;
    +	ipos_m = (MSDOS_I(inode)->i_pos & 0xf0) << 24;
    +	ipos_l = (MSDOS_I(inode)->i_pos & 0x0f) << 28;
    +	*lenp = 5;
     	fh[0] = inode->i_ino;
     	fh[1] = inode->i_generation;
    -	fh[2] = (__u32)(MSDOS_I(inode)->i_pos >> 32);
    -	fh[3] = (__u32)MSDOS_I(inode)->i_pos;
    -	fh[4] = MSDOS_I(inode)->i_logstart;
    +	fh[2] = ipos_h;
    +	fh[3] = ipos_m | MSDOS_I(inode)->i_logstart;
     	spin_lock(&de->d_lock);
    -	fh[5] = MSDOS_I(de->d_parent->d_inode)->i_logstart;
    +	fh[4] = ipos_l | MSDOS_I(de->d_parent->d_inode)->i_logstart;
     	spin_unlock(&de->d_lock);
     	return 3;
     }
    _
    -
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at  http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at  http://www.tux.org/lkml/
    
    
    \
     
     \ /
      Last update: 2005-03-22 14:02    [from the cache]
    ©2003-2008