10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
13 *
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
19 *
20 * CDDL HEADER END
21 */
22 /*
23 * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
25 */
26
27 /* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */
28 /* All Rights Reserved */
29
30 #pragma ident "@(#)nfs3_srv.c 1.114 05/12/16 SMI"
31
32 #include <sys/param.h>
33 #include <sys/types.h>
34 #include <sys/systm.h>
35 #include <sys/cred.h>
36 #include <sys/buf.h>
37 #include <sys/vfs.h>
38 #include <sys/vnode.h>
39 #include <sys/uio.h>
40 #include <sys/errno.h>
41 #include <sys/sysmacros.h>
42 #include <sys/statvfs.h>
43 #include <sys/kmem.h>
44 #include <sys/dirent.h>
45 #include <sys/cmn_err.h>
46 #include <sys/debug.h>
47 #include <sys/systeminfo.h>
48 #include <sys/flock.h>
49 #include <sys/nbmlock.h>
50 #include <sys/policy.h>
51
52 #include <rpc/types.h>
53 #include <rpc/auth.h>
54 #include <rpc/svc.h>
55
56 #include <nfs/nfs.h>
57 #include <nfs/export.h>
58
59 #include <sys/strsubr.h>
60
61 /*
62 * These are the interface routines for the server side of the
63 * Network File System. See the NFS version 3 protocol specification
64 * for a description of this interface.
65 */
66
67 #ifdef DEBUG
68 int rfs3_do_pre_op_attr = 1;
69 int rfs3_do_post_op_attr = 1;
70 int rfs3_do_post_op_fh3 = 1;
71 #endif
72
73 static writeverf3 write3verf;
74
75 static int sattr3_to_vattr(sattr3 *, struct vattr *);
76 static int vattr_to_fattr3(struct vattr *, fattr3 *);
77 static int vattr_to_wcc_attr(struct vattr *, wcc_attr *);
78 static void vattr_to_pre_op_attr(struct vattr *, pre_op_attr *);
79 static void vattr_to_wcc_data(struct vattr *, struct vattr *, wcc_data *);
80
832 nbl_end_crit(vp);
833 VN_RELE(vp);
834 resp->status = NFS3_OK;
835 vattr_to_post_op_attr(vap, &resp->resok.file_attributes);
836 resp->resok.count = 0;
837 resp->resok.eof = FALSE;
838 resp->resok.data.data_len = 0;
839 resp->resok.data.data_val = NULL;
840 resp->resok.data.mp = NULL;
841 return;
842 }
843
844 /*
845 * do not allocate memory more the max. allowed
846 * transfer size
847 */
848 if (args->count > rfs3_tsize(req))
849 args->count = rfs3_tsize(req);
850
851 /*
852 * mp will contain the data to be sent out in the read reply.
853 * This will be freed after the reply has been sent out (by the
854 * driver).
855 * Let's roundup the data to a BYTES_PER_XDR_UNIT multiple, so
856 * that the call to xdrmblk_putmblk() never fails.
857 */
858 mp = allocb_wait(RNDUP(args->count), BPRI_MED, STR_NOSIG, &alloc_err);
859 ASSERT(mp != NULL);
860 ASSERT(alloc_err == 0);
861
862 iov.iov_base = (caddr_t)mp->b_datap->db_base;
863 iov.iov_len = args->count;
864 uio.uio_iov = &iov;
865 uio.uio_iovcnt = 1;
866 uio.uio_segflg = UIO_SYSSPACE;
867 uio.uio_extflg = UIO_COPY_CACHED;
868 uio.uio_loffset = args->offset;
869 uio.uio_resid = args->count;
870
871 error = VOP_READ(vp, &uio, 0, cr, NULL);
872
873 if (error) {
874 freeb(mp);
875 goto out;
876 }
877
878 va.va_mask = AT_ALL;
879 error = VOP_GETATTR(vp, &va, 0, cr);
880
881 #ifdef DEBUG
882 if (rfs3_do_post_op_attr) {
883 if (error)
902 * than the benefit.
903 */
904 /*
905 * Force modified metadata out to stable storage.
906 */
907 (void) VOP_FSYNC(vp, FNODSYNC, cr);
908 #endif
909
910 if (in_crit)
911 nbl_end_crit(vp);
912 VN_RELE(vp);
913
914 resp->status = NFS3_OK;
915 vattr_to_post_op_attr(vap, &resp->resok.file_attributes);
916 resp->resok.count = args->count - uio.uio_resid;
917 if (!error && offset + resp->resok.count == va.va_size)
918 resp->resok.eof = TRUE;
919 else
920 resp->resok.eof = FALSE;
921 resp->resok.data.data_len = resp->resok.count;
922 resp->resok.data.data_val = (char *)mp->b_datap->db_base;
923
924 resp->resok.data.mp = mp;
925
926 resp->resok.size = (uint_t)args->count;
927 return;
928
929 out:
930 if (curthread->t_flag & T_WOULDBLOCK) {
931 curthread->t_flag &= ~T_WOULDBLOCK;
932 resp->status = NFS3ERR_JUKEBOX;
933 } else
934 resp->status = puterrno3(error);
935 out1:
936 if (vp != NULL) {
937 if (need_rwunlock)
938 VOP_RWUNLOCK(vp, V_WRITELOCK_FALSE, NULL);
939 if (in_crit)
940 nbl_end_crit(vp);
941 VN_RELE(vp);
942 }
943 vattr_to_post_op_attr(vap, &resp->resfail.file_attributes);
2396 error = EACCES;
2397 } else {
2398 error = VOP_RENAME(fvp, args->from.name, tvp,
2399 args->to.name, cr);
2400 }
2401 nbl_end_crit(srcvp);
2402 }
2403 if (error == 0) {
2404 char *tmp;
2405
2406 /* fix the path name for the renamed file */
2407 mutex_enter(&srcvp->v_lock);
2408 tmp = srcvp->v_path;
2409 srcvp->v_path = NULL;
2410 mutex_exit(&srcvp->v_lock);
2411 vn_setpath(rootdir, tvp, srcvp, args->to.name,
2412 strlen(args->to.name));
2413 if (tmp != NULL)
2414 kmem_free(tmp, strlen(tmp) + 1);
2415 }
2416 VN_RELE(srcvp);
2417 srcvp = NULL;
2418
2419 #ifdef DEBUG
2420 if (rfs3_do_post_op_attr) {
2421 fava.va_mask = AT_ALL;
2422 favap = VOP_GETATTR(fvp, &fava, 0, cr) ? NULL : &fava;
2423 tava.va_mask = AT_ALL;
2424 tavap = VOP_GETATTR(tvp, &tava, 0, cr) ? NULL : &tava;
2425 } else {
2426 favap = NULL;
2427 tavap = NULL;
2428 }
2429 #else
2430 fava.va_mask = AT_ALL;
2431 favap = VOP_GETATTR(fvp, &fava, 0, cr) ? NULL : &fava;
2432 tava.va_mask = AT_ALL;
2433 tavap = VOP_GETATTR(tvp, &tava, 0, cr) ? NULL : &tava;
2434 #endif
2435
3725 * always true because in the past, it wasn't.
3726 */
3727 ASSERT(sizeof (*verfp) <= sizeof (write3verf));
3728 #endif
3729
3730 gethrestime(&now);
3731 verfp = (struct rfs3_verf_overlay *)&write3verf;
3732 verfp->ts = (int)now.tv_sec;
3733 verfp->id = (uint_t)nfs_atoi(hw_serial);
3734
3735 if (verfp->id == 0)
3736 verfp->id = (uint_t)now.tv_nsec;
3737
3738 }
3739
3740 void
3741 rfs3_srvrfini(void)
3742 {
3743 /* Nothing to do */
3744 }
|
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
13 *
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
19 *
20 * CDDL HEADER END
21 */
22 /*
23 * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
25 */
26
27 /* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */
28 /* All Rights Reserved */
29
30 /* Copyright (c) 2006, The Ohio State University. All rights reserved.
31 *
32 * Portions of this source code is developed by the team members of
33 * The Ohio State University's Network-Based Computing Laboratory (NBCL),
34 * headed by Professor Dhabaleswar K. (DK) Panda.
35 *
36 * Acknowledgements to contributions from developors:
37 * Ranjit Noronha: noronha@cse.ohio-state.edu
38 * Lei Chai : chail@cse.ohio-state.edu
39 * Weikuan Yu : yuw@cse.ohio-state.edu
40 *
41 */
42 #pragma ident "@(#)nfs3_srv.c 1.113 05/07/25 SMI"
43
44 #include <sys/param.h>
45 #include <sys/types.h>
46 #include <sys/systm.h>
47 #include <sys/cred.h>
48 #include <sys/buf.h>
49 #include <sys/vfs.h>
50 #include <sys/vnode.h>
51 #include <sys/uio.h>
52 #include <sys/errno.h>
53 #include <sys/sysmacros.h>
54 #include <sys/statvfs.h>
55 #include <sys/kmem.h>
56 #include <sys/dirent.h>
57 #include <sys/cmn_err.h>
58 #include <sys/debug.h>
59 #include <sys/systeminfo.h>
60 #include <sys/flock.h>
61 #include <sys/nbmlock.h>
62 #include <sys/policy.h>
63
64 #include <rpc/types.h>
65 #include <rpc/auth.h>
66 #include <rpc/svc.h>
67
68 #include <nfs/nfs.h>
69 #include <nfs/export.h>
70
71 #include <sys/strsubr.h>
72
73 /* #define RPC_RDMA_INLINE 1 */
74
75 /*
76 * These are the interface routines for the server side of the
77 * Network File System. See the NFS version 3 protocol specification
78 * for a description of this interface.
79 */
80
81 #ifdef DEBUG
82 int rfs3_do_pre_op_attr = 1;
83 int rfs3_do_post_op_attr = 1;
84 int rfs3_do_post_op_fh3 = 1;
85 #endif
86
87 static writeverf3 write3verf;
88
89 static int sattr3_to_vattr(sattr3 *, struct vattr *);
90 static int vattr_to_fattr3(struct vattr *, fattr3 *);
91 static int vattr_to_wcc_attr(struct vattr *, wcc_attr *);
92 static void vattr_to_pre_op_attr(struct vattr *, pre_op_attr *);
93 static void vattr_to_wcc_data(struct vattr *, struct vattr *, wcc_data *);
94
846 nbl_end_crit(vp);
847 VN_RELE(vp);
848 resp->status = NFS3_OK;
849 vattr_to_post_op_attr(vap, &resp->resok.file_attributes);
850 resp->resok.count = 0;
851 resp->resok.eof = FALSE;
852 resp->resok.data.data_len = 0;
853 resp->resok.data.data_val = NULL;
854 resp->resok.data.mp = NULL;
855 return;
856 }
857
858 /*
859 * do not allocate memory more the max. allowed
860 * transfer size
861 */
862 if (args->count > rfs3_tsize(req))
863 args->count = rfs3_tsize(req);
864
865 /*
866 * If we aren't returning READ data w/RDMA_WRITE, then grab
867 * a mblk.
868 */
869 if (SVC_GET_WCHUNK(req->rq_xprt, req, &iov) == FALSE) {
870
871 /*
872 * mp will contain the data to be sent out in the read reply.
873 * This will be freed after the reply has been sent out (by the
874 * driver).
875 * Let's roundup the data to a BYTES_PER_XDR_UNIT multiple, so
876 * that the call to xdrmblk_putmblk() never fails.
877 */
878 mp = allocb_wait(RNDUP(args->count), BPRI_MED, STR_NOSIG,
879 &alloc_err);
880 ASSERT(mp != NULL);
881 ASSERT(alloc_err == 0);
882
883 iov.iov_base = (caddr_t)mp->b_datap->db_base;
884 iov.iov_len = args->count;
885 } else
886 mp = NULL;
887 uio.uio_iov = &iov;
888 uio.uio_iovcnt = 1;
889 uio.uio_segflg = UIO_SYSSPACE;
890 uio.uio_extflg = UIO_COPY_CACHED;
891 uio.uio_loffset = args->offset;
892 uio.uio_resid = args->count;
893
894 error = VOP_READ(vp, &uio, 0, cr, NULL);
895
896 if (error) {
897 freeb(mp);
898 goto out;
899 }
900
901 va.va_mask = AT_ALL;
902 error = VOP_GETATTR(vp, &va, 0, cr);
903
904 #ifdef DEBUG
905 if (rfs3_do_post_op_attr) {
906 if (error)
925 * than the benefit.
926 */
927 /*
928 * Force modified metadata out to stable storage.
929 */
930 (void) VOP_FSYNC(vp, FNODSYNC, cr);
931 #endif
932
933 if (in_crit)
934 nbl_end_crit(vp);
935 VN_RELE(vp);
936
937 resp->status = NFS3_OK;
938 vattr_to_post_op_attr(vap, &resp->resok.file_attributes);
939 resp->resok.count = args->count - uio.uio_resid;
940 if (!error && offset + resp->resok.count == va.va_size)
941 resp->resok.eof = TRUE;
942 else
943 resp->resok.eof = FALSE;
944 resp->resok.data.data_len = resp->resok.count;
945 #ifndef RPC_RDMA_INLINE
946 resp->resok.data.data_val = (caddr_t)iov.iov_base;
947 #else
948 resp->resok.data.data_val = (caddr_t)mp->b_datap->db_base;
949 #endif
950 resp->resok.data.mp = mp;
951
952 resp->resok.size = (uint_t)args->count;
953 return;
954
955 out:
956 if (curthread->t_flag & T_WOULDBLOCK) {
957 curthread->t_flag &= ~T_WOULDBLOCK;
958 resp->status = NFS3ERR_JUKEBOX;
959 } else
960 resp->status = puterrno3(error);
961 out1:
962 if (vp != NULL) {
963 if (need_rwunlock)
964 VOP_RWUNLOCK(vp, V_WRITELOCK_FALSE, NULL);
965 if (in_crit)
966 nbl_end_crit(vp);
967 VN_RELE(vp);
968 }
969 vattr_to_post_op_attr(vap, &resp->resfail.file_attributes);
2422 error = EACCES;
2423 } else {
2424 error = VOP_RENAME(fvp, args->from.name, tvp,
2425 args->to.name, cr);
2426 }
2427 nbl_end_crit(srcvp);
2428 }
2429 if (error == 0) {
2430 char *tmp;
2431
2432 /* fix the path name for the renamed file */
2433 mutex_enter(&srcvp->v_lock);
2434 tmp = srcvp->v_path;
2435 srcvp->v_path = NULL;
2436 mutex_exit(&srcvp->v_lock);
2437 vn_setpath(rootdir, tvp, srcvp, args->to.name,
2438 strlen(args->to.name));
2439 if (tmp != NULL)
2440 kmem_free(tmp, strlen(tmp) + 1);
2441 }
2442
2443 VN_RELE(srcvp);
2444 srcvp = NULL;
2445
2446 #ifdef DEBUG
2447 if (rfs3_do_post_op_attr) {
2448 fava.va_mask = AT_ALL;
2449 favap = VOP_GETATTR(fvp, &fava, 0, cr) ? NULL : &fava;
2450 tava.va_mask = AT_ALL;
2451 tavap = VOP_GETATTR(tvp, &tava, 0, cr) ? NULL : &tava;
2452 } else {
2453 favap = NULL;
2454 tavap = NULL;
2455 }
2456 #else
2457 fava.va_mask = AT_ALL;
2458 favap = VOP_GETATTR(fvp, &fava, 0, cr) ? NULL : &fava;
2459 tava.va_mask = AT_ALL;
2460 tavap = VOP_GETATTR(tvp, &tava, 0, cr) ? NULL : &tava;
2461 #endif
2462
3752 * always true because in the past, it wasn't.
3753 */
3754 ASSERT(sizeof (*verfp) <= sizeof (write3verf));
3755 #endif
3756
3757 gethrestime(&now);
3758 verfp = (struct rfs3_verf_overlay *)&write3verf;
3759 verfp->ts = (int)now.tv_sec;
3760 verfp->id = (uint_t)nfs_atoi(hw_serial);
3761
3762 if (verfp->id == 0)
3763 verfp->id = (uint_t)now.tv_nsec;
3764
3765 }
3766
3767 void
3768 rfs3_srvrfini(void)
3769 {
3770 /* Nothing to do */
3771 }
3772
|