Fix d_find_alias brokenness
Subsystems (3)
A message that is not in the archive (sent off-list or not yet received): 20041112105449.24459.patches@notabene
PATCH 1/1 Fix d_find_alias brokenness
Hi Andrew,
it wold be great if this could get into 2.6.10 as it fixed a very noticable
problem with knfsd.
Thanks,
NeilBrown
### Comments for Changeset
A recent change to d_alloc_anon was a little broken, and needs a small change to d_find_alias to fix it.
Without this, a dcache flush on the server can cause stale file handles on the client.
### Diffstat output
./fs/dcache.c | 16 ++++++++++------ 1 files changed, 10 insertions(+), 6 deletions(-)
fs/dcache.c renamed from fs/dcache.c~current~ +10 -6
@@ -279,14 +279,18 @@ struct dentry * dget_locked(struct dentr/** * d_find_alias - grab a hashed alias of inode * @inode: inode in question +* @want_discon: flag, used by d_splice_alias, to request +* that only a DISCONNECTED alias be returned. * -* If inode has a hashed alias - acquire the reference to alias and -* return it. Otherwise return NULL. Notice that if inode is a directory -* there can be only one alias and it can be unhashed only if it has -* no children. +* If inode has a hashed alias, or is a directory and has any alias, +* acquire the reference to alias and return it. Otherwise return NULL. +* Notice that if inode is a directory there can be only one alias and +* it can be unhashed only if it has no children, or if it is the root +* of a filesystem. * * If the inode has a DCACHE_DISCONNECTED alias, then prefer -* any other hashed alias over that one. +* any other hashed alias over that one unless @want_discon is set, +* in which case only return a DCACHE_DISCONNECTED alias. */ static struct dentry *__d_find_alias (struct inode *inode,int want_discon)
@@ -301,7 +305,7 @@ static struct dentry * __d_find_alias(st next = tmp->next;prefetch (next); alias = list_entry(tmp, struct dentry, d_alias); -if (!d_unhashed (alias)) { +if (S_ISDIR (inode->i_mode) || !d_unhashed (alias)) {if (alias->d_flags &DCACHE_DISCONNECTED ) discon_alias = alias;else if (!want_discon) {
-------------------------------------------------------
This SF.Net email is sponsored by:
Sybase ASE Linux Express Edition - download now for FREE LinuxWorld Reader's Choice Award Winner for best database on Linux.
http://ads.osdn.com/?ad_id=5588&alloc_id=12065&op=click
_______________________________________________
NFS maillist - [email protected]
https://lists.sourceforge.net/lists/listinfo/nfs
A message that is not in the archive (sent off-list or not yet received): [email protected]
Quoted 3 lines · On Thursday November 11, [email protected] wrote:
Could I trouble you for a more complete description? Which was the offending change, and in what way was it broken?
10 weeks ago,
http://linux.bkbits.com:8080/linux-2.5/cset@415b3380pxf4sB97gM8ujLqDxi6GfQ
The patch was mostly right, and fixed a real problem, but missed a bit.
It passed the job of checking if an inode had a current alias off to d_find_alias instead of open-coding it in d_alloc_anon. However there is one case where d_alloc_anon would not return the right dentry. That case being when the inode was for the root of the filesystem.
The root is a special case because it is not hashed. All other dentries that are not hashed are quite un-interesting: There are "unlinked" but not yet closed. The root of a filesystem is unhashed, but is interesting.
Allowing d_find_alias to return an unhashed alias for a directory solves this problem. It is safe because callers of d_find_alias on a directory inode either have a name for the inode already (so finding an unlinked directory by mistake is impossible) or will soon be looking for a name and will drop the dentry if a name is not found.
NeilBrown
-------------------------------------------------------
This SF.Net email is sponsored by:
Sybase ASE Linux Express Edition - download now for FREE LinuxWorld Reader's Choice Award Winner for best database on Linux.
http://ads.osdn.com/?ad_id=5588&alloc_id=12065&op=click
_______________________________________________
NFS maillist - [email protected]
https://lists.sourceforge.net/lists/listinfo/nfs