ll_set_lock_data(ll_i2sbi(inode)->ll_md_exp, inode, it,
&bits);
- if (bits & MDS_INODELOCK_LOOKUP) {
- if (!ll_d_setup(de, true))
- RETURN(-ENOMEM);
- d_lustre_revalidate(de);
- if (S_ISDIR(inode->i_mode)) {
- struct dentry *parent = dget_parent(de);
-
- ll_update_dir_depth_dmv(d_inode(parent), de);
- dput(parent);
- }
+ if ((bits & MDS_INODELOCK_LOOKUP) &&
+ !d_lustre_invalid(de) && S_ISDIR(inode->i_mode)) {
+ struct dentry *parent = dget_parent(de);
+
+ ll_update_dir_depth_dmv(d_inode(parent), de);
+ dput(parent);
}
RETURN(rc);
if (!rc && itp->it_lock_mode) {
__u64 bits = 0;
- /* If we got a lock back and it has a LOOKUP bit set,
- * make sure the dentry is marked as valid so we can find it.
- * We don't need to care about actual hashing since other bits
- * of kernel will deal with that later.
- */
- ll_set_lock_data(sbi->ll_md_exp, de->d_inode, itp, &bits);
- if (bits & MDS_INODELOCK_LOOKUP)
- d_lustre_revalidate(de);
-
/* if DoM bit returned along with LAYOUT bit then there
* can be read-on-open data returned.
*/
+ ll_set_lock_data(sbi->ll_md_exp, de->d_inode, itp, &bits);
if (bits & MDS_INODELOCK_DOM && bits & MDS_INODELOCK_LAYOUT)
ll_dom_finish_open(de->d_inode, req);
}
/* open may not fetch LOOKUP lock, update dir depth and default LMV
* anyway.
*/
- if (!rc && S_ISDIR(de->d_inode->i_mode))
+ if (!rc && !d_lustre_invalid(de) && S_ISDIR(de->d_inode->i_mode))
ll_update_dir_depth_dmv(parent->d_inode, de);
out:
struct md_op_data *op_data;
const char *name = NULL;
size_t namelen = 0;
+ int flags = 0;
int rc = 0;
ENTRY;
CDEBUG(D_VFSTRACE, "VFS Op:inode="DFID"(%p),name=%s\n",
PFID(ll_inode2fid(inode)), inode, dentry->d_name.name);
- if (exp_connect_flags2(exp) & OBD_CONNECT2_GETATTR_PFID) {
+ /* Call getattr by fid */
+ if ((exp_connect_flags2(exp) & OBD_CONNECT2_GETATTR_PFID) &&
+ !d_lustre_invalid(dentry)) {
+ flags = MF_GETATTR_BY_FID;
parent = dget_parent(dentry);
dir = d_inode(parent);
name = dentry->d_name.name;
if (IS_ERR(op_data))
RETURN(PTR_ERR(op_data));
- /* Call getattr by fid */
- if (exp_connect_flags2(exp) & OBD_CONNECT2_GETATTR_PFID)
- op_data->op_flags = MF_GETATTR_BY_FID;
+ op_data->op_flags |= flags;
rc = md_intent_lock(exp, op_data, &oit, &req, &ll_md_blocking_ast, 0);
ll_finish_md_op_data(op_data);
if (rc < 0) {
}
run_test 31r "open-rename(replace) race"
+test_31s() {
+ local pid ls_str
+
+ mkdir_on_mdt0 $DIR/$tdir
+ touch $DIR/$tdir/$tfile || error "touch $tdir/$tfile failed"
+ ( cd $DIR/$tdir; tail -f $tfile || $MULTIOP . Dc) & pid=$!
+
+ stack_trap "pkill -P $pid 2> /dev/null" ERR
+
+ mv $DIR2/$tdir $DIR2/$tdir.old || error "mv $tdir $tdir.old failed"
+ mkdir_on_mdt0 $DIR2/$tdir || error "mkdir $DIR2/$tdir failed"
+ mv $DIR2/$tdir.old $DIR2/$tdir/ || error "mv $tdir.old $tdir/ failed"
+
+ pkill -P $pid || error "fail to stop $pid"
+ wait $pid
+
+ ls_str="$(ls $DIR/$tdir)" || error "ls $DIR/$tdir failed"
+ [[ "$ls_str" == "$tdir.old" ]] ||
+ error "invalid dentry $DIR/$tdir: $ls_str != $tdir.old"
+}
+run_test 31s "open should not revalidate invalid dentry"
+
+test_31t() {
+ local pid i i_new
+
+ touch $DIR/$tfile || error "touch $tfile failed"
+
+ $MULTIOP $DIR/$tfile o_Sc & pid=$!
+ stack_trap "kill $pid 2> /dev/null" ERR
+ sleep 1
+
+ mv $DIR2/$tfile $DIR2/$tfile.old || error "mv $tfile $tfile.old failed"
+ touch $DIR2/$tfile || error "touch $tfile failed"
+ i_new=$(stat -c "%i" $DIR2/$tfile) || error "stat $tfile failed"
+
+ kill -SIGUSR1 $pid || error "fail to stop $pid"
+ wait $pid
+
+ i=$(stat -c "%i" $DIR/$tfile) || error "stat $tfile failed"
+ (( i == i_new )) ||
+ error "invalid dentry $DIR/$tfile, not updated (inode: $i != $i_new)"
+}
+run_test 31t "getattr should not revalidate invalid dentry"
+
test_32b() { # bug 11270
remote_ost_nodsh && skip "remote OST with nodsh" && return