diff options
Diffstat (limited to 'sys/fs/smbfs/smbfs_vnops.c')
| -rw-r--r-- | sys/fs/smbfs/smbfs_vnops.c | 25 |
1 files changed, 24 insertions, 1 deletions
diff --git a/sys/fs/smbfs/smbfs_vnops.c b/sys/fs/smbfs/smbfs_vnops.c index e9fc5a8cfeed..c6e031f4858c 100644 --- a/sys/fs/smbfs/smbfs_vnops.c +++ b/sys/fs/smbfs/smbfs_vnops.c @@ -538,6 +538,8 @@ smbfs_remove(ap) return EPERM; smb_makescred(&scred, cnp->cn_thread, cnp->cn_cred); error = smbfs_smb_delete(np, &scred); + if (error == 0) + np->n_flag |= NGONE; cache_purge(vp); return error; } @@ -604,6 +606,7 @@ smbfs_rename(ap) error = smbfs_smb_delete(VTOSMB(tvp), &scred); if (error) goto out_cacherem; + VTOSMB(fvp)->n_flag |= NGONE; } error = smbfs_smb_rename(VTOSMB(fvp), VTOSMB(tdvp), tcnp->cn_nameptr, tcnp->cn_namelen, &scred); @@ -739,6 +742,8 @@ smbfs_rmdir(ap) smb_makescred(&scred, cnp->cn_thread, cnp->cn_cred); error = smbfs_smb_rmdir(np, &scred); + if (error == 0) + np->n_flag |= NGONE; dnp->n_flag |= NMODIFIED; smbfs_attr_cacheremove(dvp); /* cache_purge(dvp);*/ @@ -1096,6 +1101,7 @@ smbfs_lookup(ap) int nameiop = cnp->cn_nameiop; int nmlen = cnp->cn_namelen; int lockparent, wantparent, error, islastcn, isdot; + int killit; SMBVDEBUG("\n"); cnp->cn_flags &= ~PDIRUNLOCK; @@ -1165,8 +1171,23 @@ smbfs_lookup(ap) } } if (!error) { + killit = 0; if (vpid == vp->v_id) { - if (!VOP_GETATTR(vp, &vattr, cnp->cn_cred, td) + error = VOP_GETATTR(vp, &vattr, cnp->cn_cred, td); + /* + * If the file type on the server is inconsistent + * with what it was when we created the vnode, + * kill the bogus vnode now and fall through to + * the code below to create a new one with the + * right type. + */ + if (error == 0 && + ((vp->v_type == VDIR && + (VTOSMB(vp)->n_dosattr & SMB_FA_DIR) == 0) || + (vp->v_type == VREG && + (VTOSMB(vp)->n_dosattr & SMB_FA_DIR) != 0))) + killit = 1; + else if (error == 0 /* && vattr.va_ctime.tv_sec == VTOSMB(vp)->n_ctime*/) { if (nameiop != LOOKUP && islastcn) cnp->cn_flags |= SAVENAME; @@ -1176,6 +1197,8 @@ smbfs_lookup(ap) cache_purge(vp); } vput(vp); + if (killit) + vgone(vp); if (lockparent && dvp != vp && islastcn) VOP_UNLOCK(dvp, 0, td); } |
