From c4ef5c43a1f327fe27b857d1c79159b1bfd16208 Mon Sep 17 00:00:00 2001 From: Christos Zoulas Date: Tue, 6 Jan 2009 19:13:23 +0000 Subject: [PATCH] add the rest of the udf glue. --- ChangeLog | 4 + Makefile.am | 2 + amd/am_ops.c | 3 + amd/amd.h | 9 ++ amd/ops_udf.c | 270 +++++++++++++++++++++++++++++++++++++++ configure.in | 31 ++++- include/am_compat.h | 20 +++ include/am_defs.h | 7 + include/mount_headers1.h | 4 + 9 files changed, 349 insertions(+), 1 deletion(-) create mode 100644 amd/ops_udf.c diff --git a/ChangeLog b/ChangeLog index 95b7f8b..a5c2fb1 100644 --- a/ChangeLog +++ b/ChangeLog @@ -7,6 +7,10 @@ * fix incompatibilities with new m4 and new autoconf. + * add UDF filesystem support. + + * fix NetBSD nfs file handle detection. + 2009-01-02 Christos Zoulas * add nocasetrans, nojoliet, rrcaseins for cd9660 filesystems diff --git a/Makefile.am b/Makefile.am index 7a074b4..03fe581 100644 --- a/Makefile.am +++ b/Makefile.am @@ -118,6 +118,7 @@ EXTRA_DIST_M4 = \ m4/macros/struct_mnttab.m4 \ m4/macros/struct_nfs_args.m4 \ m4/macros/struct_nfs_fh.m4 \ + m4/macros/struct_nfs_fh3.m4 \ m4/macros/struct_nfs_gfs_mount.m4 \ m4/macros/try_compile_anyfs.m4 \ m4/macros/try_compile_nfs.m4 \ @@ -126,6 +127,7 @@ EXTRA_DIST_M4 = \ m4/macros/type_autofs_args.m4 \ m4/macros/type_cachefs_args.m4 \ m4/macros/type_cdfs_args.m4 \ + m4/macros/type_udf_args.m4 \ m4/macros/type_efs_args.m4 \ m4/macros/type_lofs_args.m4 \ m4/macros/type_mfs_args.m4 \ diff --git a/amd/am_ops.c b/amd/am_ops.c index 7714592..9f3bff5 100644 --- a/amd/am_ops.c +++ b/amd/am_ops.c @@ -123,6 +123,9 @@ static am_ops *vops[] = #ifdef HAVE_FS_UMAPFS /* FILL IN */ /* uid/gid mapping F/S */ #endif /* HAVE_FS_UMAPFS */ +#ifdef HAVE_FS_UDF + &udf_ops, /* UDF F/S */ +#endif /* HAVE_FS_UDF */ /* * These 4 should be last, in the order: diff --git a/amd/amd.h b/amd/amd.h index c9724af..5e4b28d 100644 --- a/amd/amd.h +++ b/amd/amd.h @@ -724,6 +724,15 @@ extern am_ops cdfs_ops; extern am_ops pcfs_ops; #endif /* HAVE_FS_PCFS */ +/* + * UDF File System + * Many systems can't support this, and in any case most of the + * functionality is available with program FS. + */ +#ifdef HAVE_FS_UDF +extern am_ops udf_ops; +#endif /* HAVE_FS_UDF */ + /* * Caching File System (Solaris) */ diff --git a/amd/ops_udf.c b/amd/ops_udf.c new file mode 100644 index 0000000..35c7a1d --- /dev/null +++ b/amd/ops_udf.c @@ -0,0 +1,270 @@ +/* $NetBSD: ops_pcfs.c,v 1.1.1.1 2008/09/19 20:07:16 christos Exp $ */ + +/* + * Copyright (c) 1997-2007 Erez Zadok + * Copyright (c) 1990 Jan-Simon Pendry + * Copyright (c) 1990 Imperial College of Science, Technology & Medicine + * Copyright (c) 1990 The Regents of the University of California. + * All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Jan-Simon Pendry at Imperial College, London. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgment: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * + * File: am-utils/amd/ops_udf.c + * + */ + +/* + * UDF file system + */ + +#ifdef HAVE_CONFIG_H +# include +#endif /* HAVE_CONFIG_H */ +#include +#include + +/* forward definitions */ +static char *udf_match(am_opts *fo); +static int udf_mount(am_node *am, mntfs *mf); +static int udf_umount(am_node *am, mntfs *mf); + +/* + * Ops structure + */ +am_ops udf_ops = +{ + "udf", + udf_match, + 0, /* udf_init */ + udf_mount, + udf_umount, + amfs_error_lookup_child, + amfs_error_mount_child, + amfs_error_readdir, + 0, /* udf_readlink */ + 0, /* udf_mounted */ + 0, /* udf_umounted */ + amfs_generic_find_srvr, + 0, /* udf_get_wchan */ + FS_MKMNT | FS_UBACKGROUND | FS_AMQINFO, /* nfs_fs_flags */ +#ifdef HAVE_FS_AUTOFS + AUTOFS_UDF_FS_FLAGS, +#endif /* HAVE_FS_AUTOFS */ +}; + +static int +a_num(const char *s, const char *id_type) +{ + int id; + char *ep; + + id = strtol(s, &ep, 0); + if (*ep || s == ep || id < 0) { + plog(XLOG_ERROR, "mount_udf: unknown %s: %s", id_type, s); + return 0; + } + return id; +} + +static gid_t +a_gid(const char *s, const char *id_type) +{ + struct group *gr; + + if ((gr = getgrnam(s)) != NULL) + return gr->gr_gid; + return a_num(s, id_type); +} + +static uid_t +a_uid(const char *s, const char *id_type) +{ + struct passwd *pw; + + if ((pw = getpwnam(s)) != NULL) + return pw->pw_uid; + return a_num(s, id_type); +} + +/* + * UDF needs remote filesystem. + */ +static char * +udf_match(am_opts *fo) +{ + + if (!fo->opt_dev) { + plog(XLOG_USER, "udf: no source device specified"); + return 0; + } + dlog("UDF: mounting device \"%s\" on \"%s\"", fo->opt_dev, fo->opt_fs); + + /* + * Determine magic cookie to put in mtab + */ + return strdup(fo->opt_dev); +} + +static int +mount_udf(char *mntdir, char *fs_name, char *opts, int on_autofs) +{ + udf_args_t udf_args; + mntent_t mnt; + int flags; + char *str; + uid_t uid_nobody; + gid_t gid_nobody; + +#if defined(HAVE_UDF_ARGS_T_NOBODY_UID) || defined(HAVE_UDF_ARGS_T_ANON_UID) + uid_nobody = a_uid("nobody", "user"); + if (uid_nobody == 0) { + plog(XLOG_ERROR, "mount_udf: invalid uid for nobody"); + return EPERM; + } +#endif /* defined(HAVE_UDF_ARGS_T_NOBODY_UID) || defined(HAVE_UDF_ARGS_T_ANON_UID) */ + +#if defined(HAVE_UDF_ARGS_T_NOBODY_GID) || defined(HAVE_UDF_ARGS_T_ANON_GID) + gid_nobody = a_gid("nobody", "group"); + if (gid_nobody == 0) { + plog(XLOG_ERROR, "mount_udf: invalid gid for nobody"); + return EPERM; + } +#endif /* defined(HAVE_UDF_ARGS_T_NOBODY_GID) || defined(HAVE_UDF_ARGS_T_ANON_GID) */ + + /* + * Figure out the name of the file system type. + */ + MTYPE_TYPE type = MOUNT_TYPE_UDF; + + memset((voidp) &udf_args, 0, sizeof(udf_args)); /* Paranoid */ + + /* + * Fill in the mount structure + */ + memset((voidp)&mnt, 0, sizeof(mnt)); + mnt.mnt_dir = mntdir; + mnt.mnt_fsname = fs_name; + mnt.mnt_type = MNTTAB_TYPE_UDF; + mnt.mnt_opts = opts; + + flags = compute_mount_flags(&mnt); + +#ifdef HAVE_UDF_ARGS_T_UDFMFLAGS +# if defined(MNT2_UDF_OPT_CLOSESESSION) && defined(MNTTAB_OPT_CLOSESESSION) + if (amu_hasmntopt(&mnt, MNTTAB_OPT_CLOSESESSION)) + udf_args.udfmflags |= MNT2_UDF_OPT_CLOSESESSION; +# endif /* defined(MNT2_UDF_OPT_CLOSESESSION) && defined(MNTTAB_OPT_CLOSESESSION) */ +#endif /* HAVE_UDF_ARGS_T_UDFMFLAGS */ + +#ifdef HAVE_UDF_ARGS_T_NOBODY_UID + udf_args.nobody_uid = uid_nobody; +#endif /* HAVE_UDF_ARGS_T_NOBODY_UID */ + +#ifdef HAVE_UDF_ARGS_T_NOBODY_GID + udf_args.nobody_gid = gid_nobody; +#endif /* HAVE_UDF_ARGS_T_NOBODY_GID */ + +#ifdef HAVE_UDF_ARGS_T_ANON_UID + udf_args.anon_uid = uid_nobody; /* default to nobody */ + if ((str = hasmntstr(&mnt, MNTTAB_OPT_USER)) != NULL) { + udf_args.anon_uid = a_uid(str, MNTTAB_OPT_USER); + XFREE(str); + } +#endif /* HAVE_UDF_ARGS_T_ANON_UID */ + +#ifdef HAVE_UDF_ARGS_T_ANON_GID + udf_args.anon_gid = gid_nobody; /* default to nobody */ + if ((str = hasmntstr(&mnt, MNTTAB_OPT_GROUP)) != NULL) { + udf_args.anon_gid = a_gid(str, MNTTAB_OPT_GROUP); + XFREE(str); + } +#endif /* HAVE_UDF_ARGS_T_ANON_GID */ + +#ifdef HAVE_UDF_ARGS_T_GMTOFF + udf_args.gmtoff = 0; + if ((str = hasmntstr(&mnt, MNTTAB_OPT_GMTOFF)) != NULL) { + udf_args.gmtoff = a_num(str, MNTTAB_OPT_GMTOFF); + XFREE(str); + } +#endif /* HAVE_UDF_ARGS_T_GMTOFF */ + +#ifdef HAVE_UDF_ARGS_T_SESSIONNR + udf_args.sessionnr = 0; + if ((str = hasmntstr(&mnt, MNTTAB_OPT_SESSIONNR)) != NULL) { + udf_args.sessionnr = a_num(str, MNTTAB_OPT_SESSIONNR); + XFREE(str); + } +#endif /* HAVE_UDF_ARGS_T_SESSIONNR */ + +#ifdef HAVE_UDF_ARGS_T_VERSION +# ifdef UDFMNT_VERSION + udf_args.version = UDFMNT_VERSION; +# endif /* UDFMNT_VERSION */ +#endif /* HAVE_UDF_ARGS_T_VERSION */ + +#ifdef HAVE_UFS_ARGS_T_FSPEC + udf_args.fspec = fs_name; +#endif /* HAVE_UFS_ARGS_T_FSPEC */ + + /* + * Call generic mount routine + */ + return mount_fs(&mnt, flags, (caddr_t)&udf_args, 0, type, 0, NULL, + mnttab_file_name, on_autofs); +} + +static int +udf_mount(am_node *am, mntfs *mf) +{ + int on_autofs; + int error; + + on_autofs = mf->mf_flags & MFF_ON_AUTOFS; + error = mount_udf(mf->mf_mount, mf->mf_info, mf->mf_mopts, on_autofs); + if (error) { + errno = error; + plog(XLOG_ERROR, "mount_udf: %m"); + return error; + } + return 0; +} + + +static int +udf_umount(am_node *am, mntfs *mf) +{ + int unmount_flags; + + unmount_flags = (mf->mf_flags & MFF_ON_AUTOFS) ? AMU_UMOUNT_AUTOFS : 0; + return UMOUNT_FS(mf->mf_mount, mnttab_file_name, unmount_flags); +} diff --git a/configure.in b/configure.in index 71a60d0..af09c83 100644 --- a/configure.in +++ b/configure.in @@ -55,7 +55,7 @@ AH_BOTTOM([ dnl dnl AC_CONFIG_AUX_DIR(m4) AC_PREREQ(2.52) -AC_REVISION($Revision: 1.132 $) +AC_REVISION($Revision: 1.133 $) AC_COPYRIGHT([Copyright (c) 1997-2007 Erez Zadok]) dnl find out system type AC_MSG_NOTICE(*** SYSTEM TYPES ***) @@ -433,6 +433,7 @@ AC_CHECK_HEADERS( \ bsd/rpc/rpc.h \ cdfs/cdfsmount.h \ cdfs/cdfs_mount.h \ + fs/udf/udf_mount.h \ db1/ndbm.h \ fs/efs/efs_mount.h \ fs/msdosfs/msdosfsmount.h \ @@ -624,6 +625,9 @@ AC_CHECK_HEADERS([ \ #ifdef HAVE_RPC_RPC_H # include #endif /* HAVE_RPC_RPC_H */ +#ifdef HAVE_NFS_RPCV2_H +# include +#endif /* HAVE_NFS_RPCV2_H */ ]) AC_CHECK_HEADERS([ \ linux/auto_fs.h \ @@ -769,6 +773,7 @@ fi dnl ----------------------------------------------------------------------- AMU_STRUCT_FIELD_NFS_FH AMU_STRUCT_NFS_FH +AMU_STRUCT_NFS_FH3 AMU_CHECK_FS_MNTENT(nfs3) dnl ====================================================================== @@ -807,6 +812,7 @@ AMU_TYPE_SVC_IN_ARG AMU_TYPE_AUTOFS_ARGS AMU_TYPE_CACHEFS_ARGS AMU_TYPE_CDFS_ARGS +AMU_TYPE_UDF_ARGS AMU_TYPE_LOFS_ARGS AMU_TYPE_MFS_ARGS AMU_TYPE_PCFS_ARGS @@ -910,6 +916,16 @@ AMU_CHECK_FIELD(cdfs_args_t.iso_flags) AMU_CHECK_FIELD(cdfs_args_t.iso_pgthresh) AMU_CHECK_FIELD(cdfs_args_t.norrip) AMU_CHECK_FIELD(cdfs_args_t.ssector) +AMU_CHECK_FIELD(udf_args_t.version) +AMU_CHECK_FIELD(udf_args_t.fspec) +AMU_CHECK_FIELD(udf_args_t.sessionnr) +AMU_CHECK_FIELD(udf_args_t.udfmflags) +AMU_CHECK_FIELD(udf_args_t.gmtoff) +AMU_CHECK_FIELD(udf_args_t.anon_uid) +AMU_CHECK_FIELD(udf_args_t.anon_gid) +AMU_CHECK_FIELD(udf_args_t.nobody_uid) +AMU_CHECK_FIELD(udf_args_t.nobody_gid) +AMU_CHECK_FIELD(udf_args_t.sector_size) AMU_CHECK_FIELD(pcfs_args_t.dirmask) AMU_CHECK_FIELD(pcfs_args_t.dsttime) AMU_CHECK_FIELD(pcfs_args_t.fspec) @@ -999,6 +1015,7 @@ dnl check for filesystem existence if MNTTYPE_ exists, then if dnl MOUNT_, then MNT_, then in /proc/filesystems, and getvfsbyname() AMU_CHECK_FS_MNTENT(autofs) AMU_CHECK_FS_MNTENT(cdfs hsfs cd9660 iso9660 isofs cdrom, cdfs) +AMU_CHECK_FS_MNTENT(udf) AMU_CHECK_FS_MNTENT(cache) AMU_CHECK_FS_MNTENT(lofs lo, lofs) AMU_CHECK_FS_MNTENT(mfs) @@ -1025,6 +1042,7 @@ AMU_CHECK_FS_MNTENT(umap umapfs, umapfs) dnl check for filesystem existence if their headers exist dnl AMU_CHECK_FS_HEADERS(cfs.h, cfs) AMU_CHECK_FS_HEADERS(hsfs/hsfs.h, cdfs) +AMU_CHECK_FS_HEADERS(fs/udf/udf_mount.h, udf) AMU_CHECK_FS_HEADERS(tmpfs/tmp.h, tmpfs) AMU_CHECK_FS_HEADERS(fs/tmpfs/tmpfs_args.h, tmpfs) AMU_CHECK_FS_HEADERS(fs/efs/efs_mount.h, efs) @@ -1063,6 +1081,7 @@ AMU_CHECK_MOUNT_TYPE(ext3 ext2 ffs ufs 4.2 4.3 4.4 efs xfs jfs ultrix, ufs) AMU_CHECK_MOUNT_TYPE(xfs) AMU_CHECK_MOUNT_TYPE(efs) AMU_CHECK_MOUNT_TYPE(cdfs hsfs cd9660 iso9660 isofs cdrom, cdfs) +AMU_CHECK_MOUNT_TYPE(udf) AMU_CHECK_MOUNT_TYPE(vfat pcfs pc msdos msdosfs fat, pcfs) AMU_CHECK_MOUNT_TYPE(mfs) AMU_CHECK_MOUNT_TYPE(tmpfs tmp, tmpfs) @@ -1086,6 +1105,7 @@ AMU_CHECK_MNTTAB_TYPE(ext3 ext2 ffs ufs 4.2 4.3 4.4 efs xfs jfs ultrix, ufs) AMU_CHECK_MNTTAB_TYPE(xfs) AMU_CHECK_MNTTAB_TYPE(efs) AMU_CHECK_MNTTAB_TYPE(cdfs hsfs cd9660 iso9660 isofs cdrom, cdfs) +AMU_CHECK_MNTTAB_TYPE(udf) AMU_CHECK_MNTTAB_TYPE(vfat pcfs pc msdos msdosfs fat, pcfs) AMU_CHECK_MNTTAB_TYPE(mfs) AMU_CHECK_MNTTAB_TYPE(tmpfs tmp, tmpfs) @@ -1273,6 +1293,15 @@ AMU_CHECK_MNT2_CDFS_OPTS(\ ) dnl ====================================================================== +dnl ###################################################################### +dnl UDF-specific mount(2) options (hex numbers) like M_* +AC_MSG_NOTICE(*** UDF-SPECIFIC MOUNT(2) OPTIONS ***) +dnl if found, defines MNT2_UDF_OPT_* +AMU_CHECK_MNT2_UDF_OPTS(\ + closesession \ + ) +dnl ====================================================================== + dnl ###################################################################### dnl PCFS-specific mount(2) options (hex numbers) like M_* AC_MSG_NOTICE(*** PCFS-SPECIFIC MOUNT(2) OPTIONS ***) diff --git a/include/am_compat.h b/include/am_compat.h index e3a06dd..031994f 100644 --- a/include/am_compat.h +++ b/include/am_compat.h @@ -193,6 +193,12 @@ # define MNTTAB_OPT_RRCASEINS "rrcaseins" #endif /* defined(MNT2_CDFS_OPT_RRCASEINS) && !defined(MNTTAB_OPT_RRCASEINS) */ +/* + * Complete MNTTAB_OPT_* options based on MNT2_UDF_OPT_* mount options. + */ +#if defined(MNT2_UDF_OPT_CLOSESESSION) && !defined(MNTTAB_OPT_CLOSESESSION) +# define MNTTAB_OPT_CLOSESESSION "closesession" +#endif /* defined(MNT2_UDF_OPT_CLOSESESSION) && !defined(MNTTAB_OPT_CLOSESESSION) */ /* * Complete MNTTAB_OPT_* options based on MNT2_PCFS_OPT_* mount options. @@ -335,6 +341,20 @@ # define MNTTAB_OPT_DIRMASK "dirmask" #endif /* not MNTTAB_OPT_DIRMASK */ +/* useful for udf mounts */ +#ifndef MNTTAB_OPT_USER +# define MNTTAB_OPT_USER "user" +#endif /* not MNTTAB_OPT_USER */ +#ifndef MNTTAB_OPT_GROUP +# define MNTTAB_OPT_GROUP "group" +#endif /* not MNTTAB_OPT_GROUP */ +#ifndef MNTTAB_OPT_GMTOFF +# define MNTTAB_OPT_GMTOFF "gmtoff" +#endif /* not MNTTAB_OPT_GMTOFF */ +#ifndef MNTTAB_OPT_SESSIONNR +# define MNTTAB_OPT_SESSIONNR "sessionnr" +#endif /* not MNTTAB_OPT_SESSIONNR */ + /* * Incomplete filesystem definitions (sunos4, irix6, solaris2) */ diff --git a/include/am_defs.h b/include/am_defs.h index f8ad24d..ecdf2a7 100644 --- a/include/am_defs.h +++ b/include/am_defs.h @@ -965,6 +965,13 @@ struct sockaddr_dl; # include #endif /* HAVE_ISOFS_CD9660_CD9660_MOUNT_H */ +/* + * Actions to take if exists. + */ +#ifdef HAVE_FS_UDF_UDF_MOUNT_H +# include +#endif /* HAVE_FS_UDF_UDF_MOUNT_H */ + /* * Actions to take if exists. */ diff --git a/include/mount_headers1.h b/include/mount_headers1.h index cdf700f..750641b 100644 --- a/include/mount_headers1.h +++ b/include/mount_headers1.h @@ -192,6 +192,10 @@ # include #endif /* HAVE_ISOFS_CD9660_CD9660_MOUNT_H */ +#ifdef HAVE_FS_UDF_UDF_MOUNT_H +# include +#endif /* HAVE_FS_UDF_UDF_MOUNT_H */ + #ifdef HAVE_SYS_FS_PC_FS_H # include #endif /* HAVE_SYS_FS_PC_FS_H */ -- 2.43.0