Sdiff nfs3_srv.c


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