Nfs readdir
From Linux NFS
(Difference between revisions)
(6 intermediate revisions not shown) | |||
Line 5: | Line 5: | ||
* path defined in include/linux/path.h | * path defined in include/linux/path.h | ||
* nfs_entry defined in /include/linux/nfs_xdr.h | * nfs_entry defined in /include/linux/nfs_xdr.h | ||
+ | |||
+ | * There is a weakness with the current caching method. Right now, xdr objects are being stored in the cache so reading from the cache requires translating an xdr object into a dentry. This is more natural to use, especially at this point in the kernel. Cache should be array of (cookie, dentry) | ||
+ | |||
* make a new dentry: my_entry | * make a new dentry: my_entry | ||
** set the cookie to the previous file, allocate a file handle and attribute struct, mark that we are not at the end of the file | ** set the cookie to the previous file, allocate a file handle and attribute struct, mark that we are not at the end of the file | ||
- | ** If allocations failed, goto out_alloc_failed | + | ** If allocations failed, goto out_alloc_failed |
+ | |||
+ | |||
+ | * Block silly renames from running | ||
* call nfs_revalidate_mapping (fs/nfs/inode.c) to validate the page cache | * call nfs_revalidate_mapping (fs/nfs/inode.c) to validate the page cache | ||
- | ** if there is an error revalidating the cache, goto out | + | ** if there is an error revalidating the cache, goto out |
+ | ** if the directory has changed (mtime different) then cache can be cleared | ||
+ | |||
* Begin a loop over directory entries | * Begin a loop over directory entries | ||
+ | |||
* while we have not reached the end of the directory file: | * while we have not reached the end of the directory file: | ||
** Search the page cache for the requested page (dir.c: readdir_search_pagecache) | ** Search the page cache for the requested page (dir.c: readdir_search_pagecache) | ||
** if searching results in a bad cookie (EBADCOOKIE), it could mean that we are at the end of the directory or that the file has been deleted | ** if searching results in a bad cookie (EBADCOOKIE), it could mean that we are at the end of the directory or that the file has been deleted | ||
- | *** ask the server | + | *** ask the server for the next file and add to the page cache using filldir (dir.c: uncached_readdir) |
- | *** if the response is good, go to the beginning of the while loop and look up the next entry, otherwise break out of the loop | + | *** if the response is good, go to the beginning of the while loop and look up the next entry, otherwise break out of the loop |
- | ** if | + | ** if the server's response is bigger than the size limit set by the client (ETOOSMALL) and if we are doing a readdir plus |
*** clear the "NFS_INO_ADVISE_RDPLUS" flag contained in the nfs_inode | *** clear the "NFS_INO_ADVISE_RDPLUS" flag contained in the nfs_inode | ||
*** "zap" the cache (invalidate the nfs_inode) | *** "zap" the cache (invalidate the nfs_inode) | ||
- | ** if res indicates any other error, break out of the loop | + | ** if res indicates any other error, break out of the loop |
** add the page to the cache | ** add the page to the cache | ||
*** break out of the loop if there is a problem adding the page to the cache | *** break out of the loop if there is a problem adding the page to the cache | ||
+ | |||
+ | |||
+ | * out: | ||
+ | ** unblock (allow) silly renames | ||
+ | ** set response is non zero, set it equal to zero | ||
+ | |||
+ | |||
+ | * out_alloc_failed: | ||
+ | ** free file handle and attr structs in my_entry | ||
+ | ** print a message stating what is being returned | ||
+ | ** return the response code |
Latest revision as of 20:08, 6 July 2010
nfs_readdir()
- fs/nfs/dir.c
- dentry defined in include/linux/dcache.h
- file defined in include/linux/fs.h
- path defined in include/linux/path.h
- nfs_entry defined in /include/linux/nfs_xdr.h
- There is a weakness with the current caching method. Right now, xdr objects are being stored in the cache so reading from the cache requires translating an xdr object into a dentry. This is more natural to use, especially at this point in the kernel. Cache should be array of (cookie, dentry)
- make a new dentry: my_entry
- set the cookie to the previous file, allocate a file handle and attribute struct, mark that we are not at the end of the file
- If allocations failed, goto out_alloc_failed
- Block silly renames from running
- call nfs_revalidate_mapping (fs/nfs/inode.c) to validate the page cache
- if there is an error revalidating the cache, goto out
- if the directory has changed (mtime different) then cache can be cleared
- Begin a loop over directory entries
- while we have not reached the end of the directory file:
- Search the page cache for the requested page (dir.c: readdir_search_pagecache)
- if searching results in a bad cookie (EBADCOOKIE), it could mean that we are at the end of the directory or that the file has been deleted
- ask the server for the next file and add to the page cache using filldir (dir.c: uncached_readdir)
- if the response is good, go to the beginning of the while loop and look up the next entry, otherwise break out of the loop
- if the server's response is bigger than the size limit set by the client (ETOOSMALL) and if we are doing a readdir plus
- clear the "NFS_INO_ADVISE_RDPLUS" flag contained in the nfs_inode
- "zap" the cache (invalidate the nfs_inode)
- if res indicates any other error, break out of the loop
- add the page to the cache
- break out of the loop if there is a problem adding the page to the cache
- out:
- unblock (allow) silly renames
- set response is non zero, set it equal to zero
- out_alloc_failed:
- free file handle and attr structs in my_entry
- print a message stating what is being returned
- return the response code