Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys Implement a genfs_rename abstraction.



details:   https://anonhg.NetBSD.org/src/rev/448f71e94cc6
branches:  trunk
changeset: 779183:448f71e94cc6
user:      riastradh <riastradh%NetBSD.org@localhost>
date:      Tue May 08 23:53:26 2012 +0000

description:
Implement a genfs_rename abstraction.

First major step in incrementally adapting all the file systems to a
saner rename VOP protocol.

diffstat:

 sys/conf/files                            |     3 +-
 sys/miscfs/genfs/genfs.h                  |    70 +-
 sys/miscfs/genfs/genfs_rename.c           |  1154 +++++++++++++++++++++++++++++
 sys/rump/librump/rumpvfs/Makefile.rumpvfs |     4 +-
 4 files changed, 1227 insertions(+), 4 deletions(-)

diffs (truncated from 1280 to 300 lines):

diff -r a9c43390389e -r 448f71e94cc6 sys/conf/files
--- a/sys/conf/files    Tue May 08 14:28:55 2012 +0000
+++ b/sys/conf/files    Tue May 08 23:53:26 2012 +0000
@@ -1,4 +1,4 @@
-#      $NetBSD: files,v 1.1049 2012/05/05 19:15:10 rmind Exp $
+#      $NetBSD: files,v 1.1050 2012/05/08 23:53:26 riastradh Exp $
 #      @(#)files.newconf       7.5 (Berkeley) 5/10/93
 
 version        20100430
@@ -1625,6 +1625,7 @@
 file   miscfs/deadfs/dead_vnops.c
 file   miscfs/fifofs/fifo_vnops.c
 file   miscfs/genfs/genfs_io.c
+file   miscfs/genfs/genfs_rename.c
 file   miscfs/genfs/genfs_vfsops.c
 file   miscfs/genfs/genfs_vnops.c
 file   miscfs/genfs/layer_subr.c       nullfs | overlay | umapfs
diff -r a9c43390389e -r 448f71e94cc6 sys/miscfs/genfs/genfs.h
--- a/sys/miscfs/genfs/genfs.h  Tue May 08 14:28:55 2012 +0000
+++ b/sys/miscfs/genfs/genfs.h  Tue May 08 23:53:26 2012 +0000
@@ -1,9 +1,13 @@
-/*     $NetBSD: genfs.h,v 1.29 2012/03/13 18:40:57 elad Exp $  */
+/*     $NetBSD: genfs.h,v 1.30 2012/05/08 23:53:26 riastradh Exp $     */
 
 #ifndef        _MISCFS_GENFS_GENFS_H_
 #define        _MISCFS_GENFS_GENFS_H_
 
 #include <sys/vnode.h>
+#include <sys/types.h>
+
+struct componentname;
+struct mount;
 
 int    genfs_badop(void *);
 int    genfs_nullop(void *);
@@ -47,4 +51,68 @@
 int    genfs_can_sticky(kauth_cred_t, uid_t, uid_t);
 int    genfs_can_extattr(kauth_cred_t, int, vnode_t *, const char *);
 
+/*
+ * Rename is complicated.  Sorry.
+ */
+
+struct genfs_rename_ops;
+
+
+int    genfs_insane_rename(void *,
+           int (*)(struct vnode *, struct componentname *,
+               struct vnode *, struct componentname *,
+               kauth_cred_t, bool));
+int    genfs_sane_rename(const struct genfs_rename_ops *,
+           struct vnode *, struct componentname *, void *,
+           struct vnode *, struct componentname *, void *,
+           kauth_cred_t, bool);
+
+void   genfs_rename_knote(struct vnode *, struct vnode *, struct vnode *,
+           struct vnode *, bool);
+void   genfs_rename_cache_purge(struct vnode *, struct vnode *, struct vnode *,
+           struct vnode *);
+
+int    genfs_ufslike_rename_check_possible(unsigned long, unsigned long,
+           unsigned long, unsigned long, bool,
+           unsigned long, unsigned long);
+int    genfs_ufslike_rename_check_permitted(kauth_cred_t,
+           struct vnode *, mode_t, uid_t,
+           struct vnode *, uid_t,
+           struct vnode *, mode_t, uid_t,
+           struct vnode *, uid_t);
+int    genfs_ufslike_remove_check_possible(unsigned long, unsigned long,
+           unsigned long, unsigned long);
+int    genfs_ufslike_remove_check_permitted(kauth_cred_t,
+           struct vnode *, mode_t, uid_t,
+           struct vnode *, uid_t);
+
+struct genfs_rename_ops {
+       bool (*gro_directory_empty_p)(struct mount *mp, kauth_cred_t cred,
+           struct vnode *vp, struct vnode *dvp);
+       int (*gro_rename_check_possible)(struct mount *mp,
+           struct vnode *fdvp, struct vnode *fvp,
+           struct vnode *tdvp, struct vnode *tvp);
+       int (*gro_rename_check_permitted)(struct mount *mp, kauth_cred_t cred,
+           struct vnode *fdvp, struct vnode *fvp,
+           struct vnode *tdvp, struct vnode *tvp);
+       int (*gro_remove_check_possible)(struct mount *mp,
+           struct vnode *dvp, struct vnode *vp);
+       int (*gro_remove_check_permitted)(struct mount *mp, kauth_cred_t cred,
+           struct vnode *dvp, struct vnode *vp);
+       int (*gro_rename)(struct mount *mp, kauth_cred_t cred,
+           struct vnode *fdvp, struct componentname *fcnp,
+           void *fde, struct vnode *fvp,
+           struct vnode *tdvp, struct componentname *tcnp,
+           void *tde, struct vnode *tvp);
+       int (*gro_remove)(struct mount *mp, kauth_cred_t cred,
+           struct vnode *dvp, struct componentname *cnp, void *de,
+           struct vnode *vp);
+       int (*gro_lookup)(struct mount *mp, struct vnode *dvp,
+           struct componentname *cnp, void *fde_ret, struct vnode **vp_ret);
+       int (*gro_genealogy)(struct mount *mp, kauth_cred_t cred,
+           struct vnode *fdvp, struct vnode *tdvp,
+           struct vnode **intermediate_node_ret);
+       int (*gro_lock_directory)(struct mount *mp, struct vnode *vp);
+};
+
 #endif /* !_MISCFS_GENFS_GENFS_H_ */
diff -r a9c43390389e -r 448f71e94cc6 sys/miscfs/genfs/genfs_rename.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/sys/miscfs/genfs/genfs_rename.c   Tue May 08 23:53:26 2012 +0000
@@ -0,0 +1,1154 @@
+/*     $NetBSD: genfs_rename.c,v 1.1 2012/05/08 23:53:26 riastradh Exp $       */
+
+/*-
+ * Copyright (c) 2012 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Taylor R Campbell.
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
+ */
+
+/*
+ * Generic rename abstraction.
+ *
+ * Rename is unbelievably hairy.  Try to use this if you can --
+ * otherwise you are practically guaranteed to get it wrong.
+ */
+
+#include <sys/cdefs.h>
+__KERNEL_RCSID(0, "$NetBSD: genfs_rename.c,v 1.1 2012/05/08 23:53:26 riastradh Exp $");
+
+#include <sys/param.h>
+#include <sys/kauth.h>
+#include <sys/mount.h>
+#include <sys/namei.h>
+#include <sys/stat.h>
+#include <sys/vnode.h>
+#include <sys/types.h>
+
+#include <miscfs/genfs/genfs.h>
+
+/*
+ * Sample copypasta for implementing VOP_RENAME via genfs_rename.
+ * Don't change this template without carefully considering whether
+ * every other file system that already uses it needs to change too.
+ * That way, once we have changed all the file systems to use it, we
+ * can easily replace mumblefs_rename by mumblefs_sane_rename and
+ * eliminate the insane API altogether.
+ */
+
+/* begin sample copypasta */
+#if 0
+
+static const struct genfs_rename_ops mumblefs_genfs_rename_ops;
+
+/*
+ * mumblefs_sane_rename: The hairiest vop, with the saner API.
+ *
+ * Arguments:
+ *
+ * . fdvp (from directory vnode),
+ * . fcnp (from component name),
+ * . tdvp (to directory vnode),
+ * . tcnp (to component name),
+ * . cred (credentials structure), and
+ * . posixly_correct (flag for behaviour if target & source link same file).
+ *
+ * fdvp and tdvp may be the same, and must be referenced and unlocked.
+ */
+static int
+mumblefs_sane_rename(
+    struct vnode *fdvp, struct componentname *fcnp,
+    struct vnode *tdvp, struct componentname *tcnp,
+    kauth_cred_t cred, bool posixly_correct)
+{
+       struct mumblefs_lookup_results fulr, tulr;
+
+       return genfs_sane_rename(&mumblefs_genfs_rename_ops,
+           fdvp, fcnp, &fulr, tdvp, tcnp, &tulr,
+           cred, posixly_correct);
+}
+
+/*
+ * mumblefs_rename: The hairiest vop, with the insanest API.  Defer to
+ * genfs_insane_rename immediately.
+ */
+int
+mumblefs_rename(void *v)
+{
+
+       return genfs_insane_rename(v, &mumblefs_sane_rename);
+}
+
+#endif
+/* end sample copypasta */
+
+/*
+ * Forward declarations
+ */
+
+static int genfs_rename_enter(const struct genfs_rename_ops *, struct mount *,
+    kauth_cred_t,
+    struct vnode *, struct componentname *, void *, struct vnode **,
+    struct vnode *, struct componentname *, void *, struct vnode **);
+static int genfs_rename_enter_common(const struct genfs_rename_ops *,
+    struct mount *, kauth_cred_t, struct vnode *,
+    struct componentname *, void *, struct vnode **,
+    struct componentname *, void *, struct vnode **);
+static int genfs_rename_enter_separate(const struct genfs_rename_ops *,
+    struct mount *, kauth_cred_t,
+    struct vnode *, struct componentname *, void *, struct vnode **,
+    struct vnode *, struct componentname *, void *, struct vnode **);
+static int genfs_rename_lock(const struct genfs_rename_ops *, struct mount *,
+    kauth_cred_t, int, int, int,
+    struct vnode *, struct componentname *, bool, void *, struct vnode **,
+    struct vnode *, struct componentname *, bool, void *, struct vnode **);
+static void genfs_rename_exit(const struct genfs_rename_ops *, struct mount *,
+    struct vnode *, struct vnode *,
+    struct vnode *, struct vnode *);
+static int genfs_rename_remove(const struct genfs_rename_ops *, struct mount *,
+    kauth_cred_t,
+    struct vnode *, struct componentname *, void *, struct vnode *);
+
+/*
+ * genfs_insane_rename: Generic implementation of the insane API for
+ * the rename vop.
+ *
+ * Arguments:
+ *
+ * . fdvp (from directory vnode),
+ * . fvp (from vnode),
+ * . fcnp (from component name),
+ * . tdvp (to directory vnode),
+ * . tvp (to vnode, or NULL), and
+ * . tcnp (to component name).
+ *
+ * Any pair of vnode parameters may have the same vnode.
+ *
+ * On entry,
+ *
+ * . fdvp, fvp, tdvp, and tvp are referenced,
+ * . fdvp and fvp are unlocked, and
+ * . tdvp and tvp (if nonnull) are locked.
+ *
+ * On exit,
+ *
+ * . fdvp, fvp, tdvp, and tvp (if nonnull) are unreferenced, and
+ * . tdvp and tvp (if nonnull) are unlocked.
+ */
+int
+genfs_insane_rename(void *v,
+    int (*sane_rename)(struct vnode *fdvp, struct componentname *fcnp,
+       struct vnode *tdvp, struct componentname *tcnp,
+       kauth_cred_t cred, bool posixly_correct))
+{
+       struct vop_rename_args  /* {
+               struct vnode *a_fdvp;
+               struct vnode *a_fvp;
+               struct componentname *a_fcnp;
+               struct vnode *a_tdvp;
+               struct vnode *a_tvp;
+               struct componentname *a_tcnp;
+       } */ *ap = v;
+       struct vnode *fdvp = ap->a_fdvp;
+       struct vnode *fvp = ap->a_fvp;
+       struct componentname *fcnp = ap->a_fcnp;
+       struct vnode *tdvp = ap->a_tdvp;
+       struct vnode *tvp = ap->a_tvp;
+       struct componentname *tcnp = ap->a_tcnp;
+       kauth_cred_t cred;
+       int error;
+
+       KASSERT(fdvp != NULL);
+       KASSERT(fvp != NULL);
+       KASSERT(fcnp != NULL);
+       KASSERT(fcnp->cn_nameptr != NULL);
+       KASSERT(tdvp != NULL);
+       KASSERT(tcnp != NULL);
+       KASSERT(fcnp->cn_nameptr != NULL);
+       /* KASSERT(VOP_ISLOCKED(fdvp) != LK_EXCLUSIVE); */
+       /* KASSERT(VOP_ISLOCKED(fvp) != LK_EXCLUSIVE); */
+       KASSERT(VOP_ISLOCKED(tdvp) == LK_EXCLUSIVE);



Home | Main Index | Thread Index | Old Index