}
dentry = file->f_dentry;
+
+ /* FIXME: With nfs exporting we can get a disconnected dentry here.
+ * This can happen if the dcache is dropped on the server while the
+ * client is working, and export ops decodefh returns ESTALE to the
+ * user. It would best to catch this by implementing decodefh
+ * or maybe we could connect the dentry ourselves using getparent?
+ */
+ if (dentry->d_flags & DCACHE_DISCONNECTED) {
+ err = -ESTALE;
+ goto out;
+ }
unionfs_lock_dentry(dentry);
bstart = fbstart(file) = dbstart(dentry);
int interpose_flag;
struct nameidata lowernd; /* TODO: be gentler to the stack */
+ /* FIXME: with nfs exporting, if export ops fails to connect a dentry
+ * and returns ESTALE to the client, we can end up with an inode that
+ * has ibstart -1. This fix only stops the oopsing but the dentry will
+ * become unusable on the client, it will keep getting ESTALE on any
+ * attempt to fix it. The best way to fix this is by implementing
+ * decode_fh and making sure no inode gets left with -1 ibstart
+ */
+ if (dentry->d_inode && ibstart(dentry->d_inode) < 0) {
+ valid = 0;
+ make_bad_inode(dentry->d_inode);
+ d_drop(dentry);
+ goto out;
+ }
+
if (nd)
memcpy(&lowernd, nd, sizeof(struct nameidata));
else