10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22 /*
23 * Copyright 2015 Nexenta Systems, Inc. All rights reserved.
24 */
25
26 /*
27 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
28 * Use is subject to license terms.
29 */
30
31 #include <sys/param.h>
32 #include <sys/types.h>
33 #include <sys/systm.h>
34 #include <sys/cred.h>
35 #include <sys/buf.h>
36 #include <sys/vfs.h>
37 #include <sys/vnode.h>
38 #include <sys/uio.h>
39 #include <sys/errno.h>
40 #include <sys/sysmacros.h>
41 #include <sys/statvfs.h>
42 #include <sys/kmem.h>
43 #include <sys/dirent.h>
44 #include <rpc/types.h>
45 #include <rpc/auth.h>
46 #include <rpc/rpcsec_gss.h>
47 #include <rpc/svc.h>
48 #include <sys/strsubr.h>
49 #include <sys/strsun.h>
757 FATTR4_FILES_AVAIL_MASK |
758 FATTR4_FILES_FREE_MASK |
759 FATTR4_FILES_TOTAL_MASK);
760 rddirattr_error = error;
761 }
762 }
763 if (ar & (FATTR4_MAXFILESIZE_MASK |
764 FATTR4_MAXLINK_MASK |
765 FATTR4_MAXNAME_MASK)) {
766 if (error = rfs4_get_pc_encode(cs->vp,
767 &pce, ar, cs->cr)) {
768 ar &= ~(FATTR4_MAXFILESIZE_MASK |
769 FATTR4_MAXLINK_MASK |
770 FATTR4_MAXNAME_MASK);
771 rddirattr_error = error;
772 }
773 }
774 }
775
776 reencode_attrs:
777 /* encode the BOOLEAN for the existence of the next entry */
778 IXDR_PUT_U_INT32(ptr, true);
779 /* encode the COOKIE for the entry */
780 IXDR_PUT_U_HYPER(ptr, dp->d_off);
781
782 name = nfscmd_convname(ca, cs->exi, dp->d_name,
783 NFSCMD_CONV_OUTBOUND, MAXPATHLEN + 1);
784
785 if (name == NULL) {
786 rddir_next_offset = dp->d_off;
787 continue;
788 }
789 /* Calculate the dirent name length */
790 namelen = strlen(name);
791
792 rndup = RNDUP(namelen) / BYTES_PER_XDR_UNIT;
793
794 /* room for LENGTH + string ? */
795 if ((ptr + (1 + rndup)) > ptr_redzone) {
796 no_space = TRUE;
797 continue;
798 }
799
800 /* encode the LENGTH of the name */
801 IXDR_PUT_U_INT32(ptr, namelen);
802 /* encode the RNDUP FILL first */
803 ptr[rndup - 1] = 0;
804 /* encode the NAME of the entry */
805 bcopy(name, (char *)ptr, namelen);
806 /* now bump the ptr after... */
807 ptr += rndup;
808
809 if (name != dp->d_name)
810 kmem_free(name, MAXPATHLEN + 1);
811
812 /*
813 * Keep checking on the dircount to see if we have
814 * reached the limit; from the RFC, dircount is to be
815 * the XDR encoded limit of the cookie plus name.
816 * So the count is the name, XDR_UNIT of length for
817 * that name and 2 * XDR_UNIT bytes of cookie;
818 * However, use the regular DIRENT64 to match most
819 * client's APIs.
820 */
821 dircount -= DIRENT64_RECLEN(namelen);
822 if (nents != 0 && dircount < 0) {
823 no_space = TRUE;
824 continue;
825 }
826
827 /*
828 * Attributes requested?
829 * Gather up the attribute info and the previous VOP_LOOKUP()
830 * succeeded; if an error occurs on the VOP_GETATTR() then
831 * return just the error (again if it is requested).
832 * Note that the previous VOP_LOOKUP() could have failed
833 * itself which leaves this code without anything for
834 * a VOP_GETATTR().
835 * Also note that the readdir_attr_error is left in the
836 * encoding mask if requested and so is the mounted_on_fileid.
837 */
838 if (ae != 0) {
839 if (!vp) {
840 ae = ar & (FATTR4_RDATTR_ERROR_MASK |
841 FATTR4_MOUNTED_ON_FILEID_MASK);
842 } else {
843 va.va_mask = AT_ALL;
844 rddirattr_error =
845 VOP_GETATTR(vp, &va, 0, cs->cr, NULL);
846 if (rddirattr_error) {
|
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22 /*
23 * Copyright 2015 Nexenta Systems, Inc. All rights reserved.
24 */
25
26 /*
27 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
28 * Use is subject to license terms.
29 */
30 /*
31 * Copyright 2013 Nexenta Systems, Inc. All rights reserved.
32 */
33
34 #include <sys/param.h>
35 #include <sys/types.h>
36 #include <sys/systm.h>
37 #include <sys/cred.h>
38 #include <sys/buf.h>
39 #include <sys/vfs.h>
40 #include <sys/vnode.h>
41 #include <sys/uio.h>
42 #include <sys/errno.h>
43 #include <sys/sysmacros.h>
44 #include <sys/statvfs.h>
45 #include <sys/kmem.h>
46 #include <sys/dirent.h>
47 #include <rpc/types.h>
48 #include <rpc/auth.h>
49 #include <rpc/rpcsec_gss.h>
50 #include <rpc/svc.h>
51 #include <sys/strsubr.h>
52 #include <sys/strsun.h>
760 FATTR4_FILES_AVAIL_MASK |
761 FATTR4_FILES_FREE_MASK |
762 FATTR4_FILES_TOTAL_MASK);
763 rddirattr_error = error;
764 }
765 }
766 if (ar & (FATTR4_MAXFILESIZE_MASK |
767 FATTR4_MAXLINK_MASK |
768 FATTR4_MAXNAME_MASK)) {
769 if (error = rfs4_get_pc_encode(cs->vp,
770 &pce, ar, cs->cr)) {
771 ar &= ~(FATTR4_MAXFILESIZE_MASK |
772 FATTR4_MAXLINK_MASK |
773 FATTR4_MAXNAME_MASK);
774 rddirattr_error = error;
775 }
776 }
777 }
778
779 reencode_attrs:
780 name = nfscmd_convname(ca, cs->exi, dp->d_name,
781 NFSCMD_CONV_OUTBOUND, MAXPATHLEN + 1);
782
783 if (name == NULL) {
784 rddir_next_offset = dp->d_off;
785 continue;
786 }
787 /* Calculate the dirent name length */
788 namelen = strlen(name);
789
790 rndup = RNDUP(namelen) / BYTES_PER_XDR_UNIT;
791
792 /* room for LENGTH + string ? */
793 if ((ptr + (1 + rndup)) > ptr_redzone) {
794 no_space = TRUE;
795 if (name != dp->d_name)
796 kmem_free(name, MAXPATHLEN + 1);
797 continue;
798 }
799
800 /*
801 * Keep checking on the dircount to see if we have
802 * reached the limit; from the RFC, dircount is to be
803 * the XDR encoded limit of the cookie plus name.
804 * So the count is the name, XDR_UNIT of length for
805 * that name and 2 * XDR_UNIT bytes of cookie;
806 * However, use the regular DIRENT64 to match most
807 * client's APIs.
808 */
809 dircount -= DIRENT64_RECLEN(namelen);
810 if (nents != 0 && dircount < 0) {
811 no_space = TRUE;
812 if (name != dp->d_name)
813 kmem_free(name, MAXPATHLEN + 1);
814 continue;
815 }
816
817 /* encode the BOOLEAN for the existence of the next entry */
818 IXDR_PUT_U_INT32(ptr, true);
819 /* encode the COOKIE for the entry */
820 IXDR_PUT_U_HYPER(ptr, dp->d_off);
821
822 /* encode the LENGTH of the name */
823 IXDR_PUT_U_INT32(ptr, namelen);
824 /* encode the RNDUP FILL first */
825 ptr[rndup - 1] = 0;
826 /* encode the NAME of the entry */
827 bcopy(name, (char *)ptr, namelen);
828 /* now bump the ptr after... */
829 ptr += rndup;
830
831 if (name != dp->d_name)
832 kmem_free(name, MAXPATHLEN + 1);
833
834 /*
835 * Attributes requested?
836 * Gather up the attribute info and the previous VOP_LOOKUP()
837 * succeeded; if an error occurs on the VOP_GETATTR() then
838 * return just the error (again if it is requested).
839 * Note that the previous VOP_LOOKUP() could have failed
840 * itself which leaves this code without anything for
841 * a VOP_GETATTR().
842 * Also note that the readdir_attr_error is left in the
843 * encoding mask if requested and so is the mounted_on_fileid.
844 */
845 if (ae != 0) {
846 if (!vp) {
847 ae = ar & (FATTR4_RDATTR_ERROR_MASK |
848 FATTR4_MOUNTED_ON_FILEID_MASK);
849 } else {
850 va.va_mask = AT_ALL;
851 rddirattr_error =
852 VOP_GETATTR(vp, &va, 0, cs->cr, NULL);
853 if (rddirattr_error) {
|