Deleted Added
sdiff udiff text old ( 190176 ) new ( 190380 )
full compact
1/*-
2 * Copyright (c) 1989, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * This code is derived from software contributed to Berkeley by
6 * Rick Macklem at The University of Guelph.
7 *
8 * Redistribution and use in source and binary forms, with or without

--- 19 unchanged lines hidden (view full) ---

28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 * SUCH DAMAGE.
31 *
32 * @(#)nfs_vnops.c 8.16 (Berkeley) 5/27/95
33 */
34
35#include <sys/cdefs.h>
36__FBSDID("$FreeBSD: head/sys/nfsclient/nfs_vnops.c 190380 2009-03-24 17:14:34Z rwatson $");
37
38/*
39 * vnode op calls for Sun NFS version 2 and 3
40 */
41
42#include "opt_inet.h"
43#include "opt_kdtrace.h"
44
45#include <sys/param.h>
46#include <sys/kernel.h>
47#include <sys/systm.h>
48#include <sys/resourcevar.h>
49#include <sys/proc.h>
50#include <sys/mount.h>
51#include <sys/bio.h>

--- 20 unchanged lines hidden (view full) ---

72
73#include <rpc/rpcclnt.h>
74
75#include <nfs/rpcv2.h>
76#include <nfs/nfsproto.h>
77#include <nfsclient/nfs.h>
78#include <nfsclient/nfsnode.h>
79#include <nfsclient/nfsmount.h>
80#include <nfsclient/nfs_kdtrace.h>
81#include <nfsclient/nfs_lock.h>
82#include <nfs/xdr_subs.h>
83#include <nfsclient/nfsm_subs.h>
84
85#include <net/if.h>
86#include <netinet/in.h>
87#include <netinet/in_var.h>
88#include <netinet/vinet.h>
89
90#include <machine/stdarg.h>
91
92#ifdef KDTRACE_HOOKS
93#include <sys/dtrace_bsd.h>
94
95dtrace_nfsclient_accesscache_flush_probe_func_t
96 dtrace_nfsclient_accesscache_flush_done_probe;
97uint32_t nfsclient_accesscache_flush_done_id;
98
99dtrace_nfsclient_accesscache_get_probe_func_t
100 dtrace_nfsclient_accesscache_get_hit_probe,
101 dtrace_nfsclient_accesscache_get_miss_probe;
102uint32_t nfsclient_accesscache_get_hit_id;
103uint32_t nfsclient_accesscache_get_miss_id;
104
105dtrace_nfsclient_accesscache_load_probe_func_t
106 dtrace_nfsclient_accesscache_load_done_probe;
107uint32_t nfsclient_accesscache_load_done_id;
108#endif /* !KDTRACE_HOOKS */
109
110/* Defs */
111#define TRUE 1
112#define FALSE 0
113
114/*
115 * Ifdef for FreeBSD-current merged buffer cache. It is unfortunate that these
116 * calls are not in getblk() and brelse() so that they would not be necessary
117 * here.

--- 212 unchanged lines hidden (view full) ---

330 if (i == NFS_ACCESSCACHESIZE) {
331 np->n_accesscache[lrupos].uid = cred->cr_uid;
332 np->n_accesscache[lrupos].mode = rmode;
333 np->n_accesscache[lrupos].stamp = time_second;
334 }
335 mtx_unlock(&np->n_mtx);
336 if (retmode != NULL)
337 *retmode = rmode;
338 KDTRACE_NFS_ACCESSCACHE_LOAD_DONE(vp, cred->cr_uid, rmode, 0);
339 }
340 m_freem(mrep);
341nfsmout:
342 KDTRACE_NFS_ACCESSCACHE_LOAD_DONE(vp, cred->cr_uid, 0, error);
343 return (error);
344}
345
346/*
347 * nfs access vnode op.
348 * For nfs version 2, just return ok. File accesses may fail later.
349 * For nfs version 3, use the access rpc to check accessibility. If file modes
350 * are changed on the server, accesses might still fail later.

--- 69 unchanged lines hidden (view full) ---

420 (np->n_accesscache[i].mode & mode) == mode) {
421 nfsstats.accesscache_hits++;
422 gotahit = 1;
423 }
424 break;
425 }
426 }
427 mtx_unlock(&np->n_mtx);
428#ifdef KDTRACE_HOOKS
429 if (gotahit)
430 KDTRACE_NFS_ACCESSCACHE_GET_HIT(vp,
431 ap->a_cred->cr_uid, mode);
432 else
433 KDTRACE_NFS_ACCESSCACHE_GET_MISS(vp,
434 ap->a_cred->cr_uid, mode);
435#endif
436 if (gotahit == 0) {
437 /*
438 * Either a no, or a don't know. Go to the wire.
439 */
440 nfsstats.accesscache_misses++;
441 error = nfs3_access_otw(vp, wmode, ap->a_td, ap->a_cred,
442 &rmode);
443 if (!error) {

--- 77 unchanged lines hidden (view full) ---

521 */
522 mtx_lock(&np->n_mtx);
523 if (np->n_flag & NMODIFIED) {
524 mtx_unlock(&np->n_mtx);
525 error = nfs_vinvalbuf(vp, V_SAVE, ap->a_td, 1);
526 if (error == EINTR || error == EIO)
527 return (error);
528 np->n_attrstamp = 0;
529 KDTRACE_NFS_ATTRCACHE_FLUSH_DONE(vp);
530 if (vp->v_type == VDIR)
531 np->n_direofoffset = 0;
532 error = VOP_GETATTR(vp, &vattr, ap->a_cred);
533 if (error)
534 return (error);
535 mtx_lock(&np->n_mtx);
536 np->n_mtime = vattr.va_mtime;
537 mtx_unlock(&np->n_mtx);
538 } else {
539 struct thread *td = curthread;
540
541 if (np->n_ac_ts_syscalls != td->td_syscalls ||
542 np->n_ac_ts_tid != td->td_tid ||
543 td->td_proc == NULL ||
544 np->n_ac_ts_pid != td->td_proc->p_pid) {
545 np->n_attrstamp = 0;
546 KDTRACE_NFS_ATTRCACHE_FLUSH_DONE(vp);
547 }
548 mtx_unlock(&np->n_mtx);
549 error = VOP_GETATTR(vp, &vattr, ap->a_cred);
550 if (error)
551 return (error);
552 mtx_lock(&np->n_mtx);
553 if (NFS_TIMESPEC_COMPARE(&np->n_mtime, &vattr.va_mtime)) {
554 if (vp->v_type == VDIR)

--- 342 unchanged lines hidden (view full) ---

897 txdr_nfsv2time(&vap->va_mtime, &sp->sa_mtime);
898 }
899 nfsm_request(vp, NFSPROC_SETATTR, curthread, cred);
900 if (v3) {
901 mtx_lock(&np->n_mtx);
902 for (i = 0; i < NFS_ACCESSCACHESIZE; i++)
903 np->n_accesscache[i].stamp = 0;
904 mtx_unlock(&np->n_mtx);
905 KDTRACE_NFS_ACCESSCACHE_FLUSH_DONE(vp);
906 nfsm_wcc_data(vp, wccflag);
907 } else
908 nfsm_loadattr(vp, NULL);
909 m_freem(mrep);
910nfsmout:
911 return (error);
912}
913

--- 537 unchanged lines hidden (view full) ---

1451 vput(newvp);
1452 } else {
1453 if (cnp->cn_flags & MAKEENTRY)
1454 cache_enter(dvp, newvp, cnp);
1455 *vpp = newvp;
1456 }
1457 mtx_lock(&(VTONFS(dvp))->n_mtx);
1458 VTONFS(dvp)->n_flag |= NMODIFIED;
1459 if (!wccflag) {
1460 VTONFS(dvp)->n_attrstamp = 0;
1461 KDTRACE_NFS_ATTRCACHE_FLUSH_DONE(dvp);
1462 }
1463 mtx_unlock(&(VTONFS(dvp))->n_mtx);
1464 return (error);
1465}
1466
1467/*
1468 * nfs mknod vop
1469 * just call nfs_mknodrpc() to do the work.
1470 */

--- 114 unchanged lines hidden (view full) ---

1585 }
1586 if (!error) {
1587 if (cnp->cn_flags & MAKEENTRY)
1588 cache_enter(dvp, newvp, cnp);
1589 *ap->a_vpp = newvp;
1590 }
1591 mtx_lock(&(VTONFS(dvp))->n_mtx);
1592 VTONFS(dvp)->n_flag |= NMODIFIED;
1593 if (!wccflag) {
1594 VTONFS(dvp)->n_attrstamp = 0;
1595 KDTRACE_NFS_ATTRCACHE_FLUSH_DONE(dvp);
1596 }
1597 mtx_unlock(&(VTONFS(dvp))->n_mtx);
1598 return (error);
1599}
1600
1601/*
1602 * nfs file remove call
1603 * To try and make nfs semantics closer to ufs semantics, a file that has
1604 * other processes using the vnode is renamed instead of removed and then

--- 47 unchanged lines hidden (view full) ---

1652 * since the file was in fact removed
1653 * Therefore, we cheat and return success.
1654 */
1655 if (error == ENOENT)
1656 error = 0;
1657 } else if (!np->n_sillyrename)
1658 error = nfs_sillyrename(dvp, vp, cnp);
1659 np->n_attrstamp = 0;
1660 KDTRACE_NFS_ATTRCACHE_FLUSH_DONE(vp);
1661 return (error);
1662}
1663
1664/*
1665 * nfs file remove rpc called from nfs_inactive
1666 */
1667int
1668nfs_removeit(struct sillyrename *sp)

--- 29 unchanged lines hidden (view full) ---

1698 nfsm_strtom(name, namelen, NFS_MAXNAMLEN);
1699 nfsm_request(dvp, NFSPROC_REMOVE, td, cred);
1700 if (v3)
1701 nfsm_wcc_data(dvp, wccflag);
1702 m_freem(mrep);
1703nfsmout:
1704 mtx_lock(&(VTONFS(dvp))->n_mtx);
1705 VTONFS(dvp)->n_flag |= NMODIFIED;
1706 if (!wccflag) {
1707 VTONFS(dvp)->n_attrstamp = 0;
1708 KDTRACE_NFS_ATTRCACHE_FLUSH_DONE(dvp);
1709 }
1710 mtx_unlock(&(VTONFS(dvp))->n_mtx);
1711 return (error);
1712}
1713
1714/*
1715 * nfs file rename call
1716 */
1717static int

--- 128 unchanged lines hidden (view full) ---

1846 m_freem(mrep);
1847nfsmout:
1848 mtx_lock(&(VTONFS(fdvp))->n_mtx);
1849 VTONFS(fdvp)->n_flag |= NMODIFIED;
1850 mtx_unlock(&(VTONFS(fdvp))->n_mtx);
1851 mtx_lock(&(VTONFS(tdvp))->n_mtx);
1852 VTONFS(tdvp)->n_flag |= NMODIFIED;
1853 mtx_unlock(&(VTONFS(tdvp))->n_mtx);
1854 if (!fwccflag) {
1855 VTONFS(fdvp)->n_attrstamp = 0;
1856 KDTRACE_NFS_ATTRCACHE_FLUSH_DONE(fdvp);
1857 }
1858 if (!twccflag) {
1859 VTONFS(tdvp)->n_attrstamp = 0;
1860 KDTRACE_NFS_ATTRCACHE_FLUSH_DONE(tdvp);
1861 }
1862 return (error);
1863}
1864
1865/*
1866 * nfs hard link create call
1867 */
1868static int
1869nfs_link(struct vop_link_args *ap)

--- 31 unchanged lines hidden (view full) ---

1901 nfsm_postop_attr(vp, attrflag);
1902 nfsm_wcc_data(tdvp, wccflag);
1903 }
1904 m_freem(mrep);
1905nfsmout:
1906 mtx_lock(&(VTONFS(tdvp))->n_mtx);
1907 VTONFS(tdvp)->n_flag |= NMODIFIED;
1908 mtx_unlock(&(VTONFS(tdvp))->n_mtx);
1909 if (!attrflag) {
1910 VTONFS(vp)->n_attrstamp = 0;
1911 KDTRACE_NFS_ATTRCACHE_FLUSH_DONE(vp);
1912 }
1913 if (!wccflag) {
1914 VTONFS(tdvp)->n_attrstamp = 0;
1915 KDTRACE_NFS_ATTRCACHE_FLUSH_DONE(tdvp);
1916 }
1917 return (error);
1918}
1919
1920/*
1921 * nfs symbolic link create call
1922 */
1923static int
1924nfs_symlink(struct vop_symlink_args *ap)

--- 68 unchanged lines hidden (view full) ---

1993 if (newvp)
1994 vput(newvp);
1995 } else {
1996 *ap->a_vpp = newvp;
1997 }
1998 mtx_lock(&(VTONFS(dvp))->n_mtx);
1999 VTONFS(dvp)->n_flag |= NMODIFIED;
2000 mtx_unlock(&(VTONFS(dvp))->n_mtx);
2001 if (!wccflag) {
2002 VTONFS(dvp)->n_attrstamp = 0;
2003 KDTRACE_NFS_ATTRCACHE_FLUSH_DONE(dvp);
2004 }
2005 return (error);
2006}
2007
2008/*
2009 * nfs make dir call
2010 */
2011static int
2012nfs_mkdir(struct vop_mkdir_args *ap)

--- 38 unchanged lines hidden (view full) ---

2051 nfsm_mtofh(dvp, newvp, v3, gotvp);
2052 if (v3)
2053 nfsm_wcc_data(dvp, wccflag);
2054 m_freem(mrep);
2055nfsmout:
2056 mtx_lock(&(VTONFS(dvp))->n_mtx);
2057 VTONFS(dvp)->n_flag |= NMODIFIED;
2058 mtx_unlock(&(VTONFS(dvp))->n_mtx);
2059 if (!wccflag) {
2060 VTONFS(dvp)->n_attrstamp = 0;
2061 KDTRACE_NFS_ATTRCACHE_FLUSH_DONE(dvp);
2062 }
2063 if (error == 0 && newvp == NULL) {
2064 error = nfs_lookitup(dvp, cnp->cn_nameptr, len, cnp->cn_cred,
2065 cnp->cn_thread, &np);
2066 if (!error) {
2067 newvp = NFSTOV(np);
2068 if (newvp->v_type != VDIR)
2069 error = EEXIST;
2070 }

--- 32 unchanged lines hidden (view full) ---

2103 nfsm_request(dvp, NFSPROC_RMDIR, cnp->cn_thread, cnp->cn_cred);
2104 if (v3)
2105 nfsm_wcc_data(dvp, wccflag);
2106 m_freem(mrep);
2107nfsmout:
2108 mtx_lock(&(VTONFS(dvp))->n_mtx);
2109 VTONFS(dvp)->n_flag |= NMODIFIED;
2110 mtx_unlock(&(VTONFS(dvp))->n_mtx);
2111 if (!wccflag) {
2112 VTONFS(dvp)->n_attrstamp = 0;
2113 KDTRACE_NFS_ATTRCACHE_FLUSH_DONE(dvp);
2114 }
2115 cache_purge(dvp);
2116 cache_purge(vp);
2117 /*
2118 * Kludge: Map ENOENT => 0 assuming that you have a reply to a retry.
2119 */
2120 if (error == ENOENT)
2121 error = 0;
2122 return (error);

--- 1328 unchanged lines hidden ---