The revalidating dentry may be stale (other client recreated this
file), so the statahead inode can be different from dentry inode.
Return -ESTALE instead of LASSERT here.
And for this kind of dentry, it shouldn't be revalidated, but dropped
and re-lookup. To achieve this, if ll_statahead_enter() fails to get
a valid dentry, and the return value is not 0 or -EAGAIN,
ll_revalidate_it() should return 0 directly, and let VFS calls
.lookup to get a new dentry.
Signed-off-by: Lai Siyao <laisiyao@whamcloud.com>
Change-Id: I3eae450069a59d18d138d0cf7538a225e6d6deb8
Reviewed-on: http://review.whamcloud.com/2492
Reviewed-by: Fan Yong <yong.fan@whamcloud.com>
Reviewed-by: Peng Tao <tao.peng@emc.com>
Tested-by: Hudson
Tested-by: Maloo <whamcloud.maloo@gmail.com>
Reviewed-by: Oleg Drokin <green@whamcloud.com>
rc = ll_statahead_enter(parent, &de, 0);
if (rc == 1)
goto mark;
rc = ll_statahead_enter(parent, &de, 0);
if (rc == 1)
goto mark;
+ else if (rc != -EAGAIN && rc != 0)
+ GOTO(out, rc = 0);
struct ll_dentry_data *ldd;
if (ll_i2sbi(dir)->ll_sa_max == 0)
struct ll_dentry_data *ldd;
if (ll_i2sbi(dir)->ll_sa_max == 0)
lli = ll_i2info(dir);
/* not the same process, don't statahead */
lli = ll_i2info(dir);
/* not the same process, don't statahead */
lld = ll_d2d(*dentryp);
if (unlikely(lld == NULL))
ll_dops_init(*dentryp, 1, 1);
lld = ll_d2d(*dentryp);
if (unlikely(lld == NULL))
ll_dops_init(*dentryp, 1, 1);
+ } else if ((*dentryp)->d_inode != inode) {
+ /* revalidate, but inode is recreated */
+ CDEBUG(D_READA,
+ "stale dentry %.*s inode %lu/%u, "
+ "statahead inode %lu/%u\n",
+ (*dentryp)->d_name.len,
+ (*dentryp)->d_name.name,
+ (*dentryp)->d_inode->i_ino,
+ (*dentryp)->d_inode->i_generation,
+ inode->i_ino,
+ inode->i_generation);
+ ll_sai_unplug(sai, entry);
+ RETURN(-ESTALE);
- LASSERT((*dentryp)->d_inode == inode);
-
ll_dentry_rehash(*dentryp, 0);
iput(inode);
}
ll_dentry_rehash(*dentryp, 0);
iput(inode);
}
/*
* We don't stat-ahead for the first dirent since we are already in
/*
* We don't stat-ahead for the first dirent since we are already in
- * lookup, and -EEXIST also indicates that this is the first dirent.