1. About NFS client data caching... (BUG ??)
----------------------------------- ^^^^^^^^
If I'm right, cache hits are found by checking the cache slots against inode
numbers (inode->i_ino). But the same inode number may correspond to different
inodes in different superblock (right ?). So, we should integrate the superblock
number (inode->i_dev) in the cache slot and check it when searching for a
cache hit.
(from <linux>/fs/nfs/file.c)
struct read_cache {
int in_use; /* currently in use? */
unsigned long inode_num; /* inode number */
========> unsigned int inode_dev; /* superblock number */
off_t file_pos; /* file position */
int len; /* size of data */
unsigned long time; /* time, this entry was inserted */
char *buf; /* data */
int buf_size; /* size of buffer */
};
static int nfs_file_read(struct inode *inode, ... )
{
...
for (i = 0; i < READ_CACHE_SIZE; i++)
if ((cache[i].inode_num == inode->i_ino)
==================> && (cache[i].inode_dev == inode->i_dev)
&& (cache[i].file_pos <= pos)
&& (cache[i].file_pos + cache[i].len >= pos + count)
&& (abs(jiffies - cache[i].time) < EXPIRE_CACHE))
break;
...
}
2. About NFS client code in general...
--------------------------------------
Single-threaded NFS calling :
- do you really believe that this accounts for a significant part of the
slowdown ?
- Is somebody working on this ? (I have some ideas, and may be I could try to
do something... )
NFS v3 :
- I believe that NFS clients are using the version 2 of NFS. What about the
version 3 ?
3. About VFS __wait_on_inode()
------------------------------
The code is as follows :
static void __wait_on_inode(struct inode * inode)
{
struct wait_queue wait = { current, NULL };
add_wait_queue(&inode->i_wait, &wait);
repeat:
current->state = TASK_UNINTERRUPTIBLE;
if (inode->i_lock) {
schedule();
goto repeat;
}
remove_wait_queue(&inode->i_wait, &wait);
current->state = TASK_RUNNING;
}
This function seems to be very complicated (for me...). What do you think of
the following version (it works just like what it is done in the NFS code) ?
static void __wait_on_inode(struct inode * inode)
{
while (inode->i_lock)
sleep_on( &inode->i_wait );
}
-----------------------------------------------------------------------------------
Bertrand RENUART - renuart@info2.ucl.ac.be
Universite Catholique de Louvain-la-Neuve
Departement d'Ingenierie Informatique
BELGIUM