Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 1 Oct 2001 15:27:28 -0700 (PDT)
From:      Wencheng Chai <wchai@prismedia.com>
To:        freebsd-gnats-submit@FreeBSD.org
Subject:   kern/30971: NFS client modification time resolution is not high enough, which may cause client side cache inconsistent
Message-ID:  <200110012227.f91MRSJ44207@freefall.freebsd.org>

next in thread | raw e-mail | index | archive | help

>Number:         30971
>Category:       kern
>Synopsis:       NFS client modification time resolution is not high enough, which may cause client side cache inconsistent
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          change-request
>Submitter-Id:   current-users
>Arrival-Date:   Mon Oct 01 15:30:00 PDT 2001
>Closed-Date:
>Last-Modified:
>Originator:     Wencheng Chai
>Release:        4.1 release
>Organization:
PRISMedia Networks Inc.
>Environment:
>Description:
The NFS client side stores the value of va_mtime only in total number 
of seconds(va_mtime.tv_sec), even the server sends the mtime in term of
seconds and nanoseconds.
>How-To-Repeat:
Two NFS clients mounted from the same exported FS,
Type "touch file1" and "touch file2" from different 
clients simultaneously, then type "ls -l" from the 
first client, the output of "ls" only shows file1.
>Fix:
*** /usr/src/sys/nfs/nfs_bio.c  Tue Aug 21 12:39:09 2001
--- nfs_bio.c   Wed Sep 12 03:45:03 2001
***************
*** 394,410 ****
                        if (error)
                                return (error);
                        np->n_mtime = vattr.va_mtime.tv_sec;
                } else {
                        error = VOP_GETATTR(vp, &vattr, cred, p);
                        if (error)
                                return (error);
!                       if (np->n_mtime != vattr.va_mtime.tv_sec) {
                                if (vp->v_type == VDIR)
                                        nfs_invaldir(vp);
                                error = nfs_vinvalbuf(vp, V_SAVE, cred, p, 1);
                                if (error)
                                        return (error);
                                np->n_mtime = vattr.va_mtime.tv_sec;
                        }
                }
        }
--- 394,415 ----
                        if (error)
                                return (error);
                        np->n_mtime = vattr.va_mtime.tv_sec;
+                       np->n_vattr.va_mtime.tv_sec = vattr.va_mtime.tv_sec;
+                       np->n_vattr.va_mtime.tv_nsec = vattr.va_mtime.tv_nsec;
                } else {
                        error = VOP_GETATTR(vp, &vattr, cred, p);
                        if (error)
                                return (error);
!                       if ((np->n_vattr.va_mtime.tv_sec != vattr.va_mtime.tv_se
c)||((np->n_vattr.va_mtime.tv_sec == vattr.va_mtime.tv_sec)&&(np->n_vattr.va_mti
me.tv_nsec != vattr.va_mtime.tv_nsec))) {
                                if (vp->v_type == VDIR)
                                        nfs_invaldir(vp);
                                error = nfs_vinvalbuf(vp, V_SAVE, cred, p, 1);
                                if (error)
                                        return (error);
                                np->n_mtime = vattr.va_mtime.tv_sec;
+                               np->n_vattr.va_mtime.tv_sec = vattr.va_mtime.tv_
sec;
+                               np->n_vattr.va_mtime.tv_nsec = vattr.va_mtime.tv
_nsec;
+
                        }
                }
        }

======================================================================

*** /usr/src/sys/nfs/nfs_subs.c Sat Feb 12 19:32:06 2000
--- nfs_subs.c  Wed Sep 12 03:46:13 2001
***************
*** 1285,1290 ****
--- 1285,1292 ----
                        addaliasu(vp, rdev);
                }
                np->n_mtime = mtime.tv_sec;
+               np->n_vattr.va_mtime.tv_sec = mtime.tv_sec;
+               np->n_vattr.va_mtime.tv_nsec = mtime.tv_nsec;
        }
        vap = &np->n_vattr;
        vap->va_type = vtyp;
***************
*** 1303,1308 ****
--- 1305,1311 ----
                    fp->fa3_fileid.nfsuquad[1]);
                fxdr_nfsv3time(&fp->fa3_atime, &vap->va_atime);
                fxdr_nfsv3time(&fp->fa3_ctime, &vap->va_ctime);
+               fxdr_nfsv3time(&fp->fa3_mtime, &vap->va_mtime);
                vap->va_flags = 0;
                vap->va_filerev = 0;
        } else {
***************
*** 1315,1320 ****
--- 1318,1324 ----
                    * NFS_FABLKSIZE;
                vap->va_fileid = fxdr_unsigned(int32_t, fp->fa2_fileid);
                fxdr_nfsv2time(&fp->fa2_atime, &vap->va_atime);
+               fxdr_nfsv2time(&fp->fa2_mtime, &vap->va_mtime);
                vap->va_flags = 0;
                vap->va_ctime.tv_sec = fxdr_unsigned(u_int32_t,
                    fp->fa2_ctime.nfsv2_sec);

======================================================================
*** /usr/src/sys/nfs/nfs_vnops.c        Tue Aug 21 12:39:09 2001
--- nfs_vnops.c Wed Sep 12 03:48:46 2001
***************
*** 507,523 ****
                        if (error)
                                return (error);
                        np->n_mtime = vattr.va_mtime.tv_sec;
                } else {
                        error = VOP_GETATTR(vp, &vattr, ap->a_cred, ap->a_p);
                        if (error)
                                return (error);
!                       if (np->n_mtime != vattr.va_mtime.tv_sec) {
                                if (vp->v_type == VDIR)
                                        np->n_direofoffset = 0;
                                if ((error = nfs_vinvalbuf(vp, V_SAVE,
                                        ap->a_cred, ap->a_p, 1)) == EINTR)
                                        return (error);
                                np->n_mtime = vattr.va_mtime.tv_sec;
                        }
                }
        }
--- 507,528 ----
                        if (error)
                                return (error);
                        np->n_mtime = vattr.va_mtime.tv_sec;
+                       np->n_vattr.va_mtime.tv_sec = vattr.va_mtime.tv_sec;
+                       np->n_vattr.va_mtime.tv_nsec = vattr.va_mtime.tv_nsec;
                } else {
                        error = VOP_GETATTR(vp, &vattr, ap->a_cred, ap->a_p);
                        if (error)
                                return (error);
!                       if ((np->n_vattr.va_mtime.tv_sec != vattr.va_mtime.tv_se
c)||((np->n_vattr.va_mtime.tv_sec == vattr.va_mtime.tv_sec)&&(np->n_vattr.va_mti
me.tv_nsec != vattr.va_mtime.tv_nsec))) {
!
                                if (vp->v_type == VDIR)
                                        np->n_direofoffset = 0;
                                if ((error = nfs_vinvalbuf(vp, V_SAVE,
                                        ap->a_cred, ap->a_p, 1)) == EINTR)
                                        return (error);
                                np->n_mtime = vattr.va_mtime.tv_sec;
+                               np->n_vattr.va_mtime.tv_sec = vattr.va_mtime.tv_
sec;
+                               np->n_vattr.va_mtime.tv_nsec = vattr.va_mtime.tv
_nsec;
                        }
                }
        }
***************
*** 1260,1266 ****
                        }
                } else
                    nfsm_loadattr(vp, (struct vattr *)0);
!               if (wccflag)
                    VTONFS(vp)->n_mtime = VTONFS(vp)->n_vattr.va_mtime.tv_sec;
                m_freem(mrep);
                if (error)
--- 1265,1271 ----
                        }
                } else
                    nfsm_loadattr(vp, (struct vattr *)0);
!               if (wccflag)
                    VTONFS(vp)->n_mtime = VTONFS(vp)->n_vattr.va_mtime.tv_sec;
                m_freem(mrep);
                if (error)
***************
*** 2064,2071 ****
                                nfsstats.direofcache_hits++;
                                return (0);
                        }
!               } else if (VOP_GETATTR(vp, &vattr, ap->a_cred, uio->uio_procp) =
= 0 &&
!                       np->n_mtime == vattr.va_mtime.tv_sec) {
                        nfsstats.direofcache_hits++;
                        return (0);
                }
--- 2069,2075 ----
                                nfsstats.direofcache_hits++;
                                return (0);
                        }
!               } else if ((VOP_GETATTR(vp, &vattr, ap->a_cred, uio->uio_procp)
== 0) &&((np->n_vattr.va_mtime.tv_sec != vattr.va_mtime.tv_sec)||((np->n_vattr.v
a_mtime.tv_sec == vattr.va_mtime.tv_sec)&&(np->n_vattr.va_mtime.tv_nsec != vattr
.va_mtime.tv_nsec)))) {
                        nfsstats.direofcache_hits++;
                        return (0);
                }

======================================================================






>Release-Note:
>Audit-Trail:
>Unformatted:

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-bugs" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200110012227.f91MRSJ44207>