FreeBSD ZFS
The Zettabyte File System
Data Structures | Defines | Typedefs | Functions | Variables

zfs_ctldir.c File Reference

ZFS control directory (a.k.a. More...

#include <sys/zfs_context.h>
#include <sys/zfs_ctldir.h>
#include <sys/zfs_ioctl.h>
#include <sys/zfs_vfsops.h>
#include <sys/namei.h>
#include <sys/gfs.h>
#include <sys/stat.h>
#include <sys/dmu.h>
#include <sys/dsl_deleg.h>
#include <sys/mount.h>
#include <sys/sunddi.h>
#include "zfs_namecheck.h"
Include dependency graph for zfs_ctldir.c:

Go to the source code of this file.

Data Structures

struct  zfsctl_node
struct  zfsctl_snapdir
struct  zfs_snapentry_t

Defines

#define NROOT_ENTRIES
#define ZFSCTL_INO_SNAP(id)   (id)
 .zfs inode namespace

Typedefs

typedef struct zfsctl_node zfsctl_node_t
typedef struct zfsctl_snapdir zfsctl_snapdir_t

Functions

static int snapentry_compare (const void *a, const void *b)
static vnode_t * zfsctl_mknode_snapdir (vnode_t *pvp)
 Creates vp, which is '.zfs/snapshot' (zfsctl_snapdir_t).
static vnode_t * zfsctl_mknode_shares (vnode_t *)
static vnode_t * zfsctl_snapshot_mknode (vnode_t *pvp, uint64_t objset)
 This creates a GFS node under '.zfs/snapshot' representing each snapshot.
static int zfsctl_unmount_snap (zfs_snapentry_t *, int, cred_t *)
void zfsctl_init (void)
 Initialize the various GFS pieces we'll need to create and manipulate .zfs directories.
void zfsctl_fini (void)
boolean_t zfsctl_is_node (vnode_t *vp)
static ino64_t zfsctl_root_inode_cb (vnode_t *vp, int index)
 Return the inode number associated with the 'snapshot' or 'shares' directory.
void zfsctl_create (zfsvfs_t *zfsvfs)
 Create the '.zfs' directory.
void zfsctl_destroy (zfsvfs_t *zfsvfs)
 Destroy the '.zfs' directory.
vnode_t * zfsctl_root (znode_t *zp)
 Given a root znode, retrieve the associated .zfs directory.
static int zfsctl_common_open (struct vop_open_args *ap)
 Common open routine.
static int zfsctl_common_close (struct vop_close_args *ap)
 Common close routine.
static int zfsctl_common_access (struct vop_access_args *ap)
 Common access routine.
static void zfsctl_common_getattr (vnode_t *vp, vattr_t *vap)
 Common getattr function.
static int zfsctl_common_fid (struct vop_fid_args *ap)
static int zfsctl_shares_fid (struct vop_fid_args *ap)
static int zfsctl_common_reclaim (struct vop_reclaim_args *ap)
static int zfsctl_root_getattr (struct vop_getattr_args *ap)
 Get root directory attributes.
int zfsctl_root_lookup (vnode_t *dvp, char *nm, vnode_t **vpp, pathname_t *pnp, int flags, vnode_t *rdir, cred_t *cr, caller_context_t *ct, int *direntflags, pathname_t *realpnp)
 Special case the handling of "..".
int zfsctl_freebsd_root_lookup (struct vop_lookup_args *ap)
 Special case the handling of "..".
static int zfsctl_snapshot_zname (vnode_t *vp, const char *name, int len, char *zname)
static int zfsctl_snapdir_mkdir (vnode_t *dvp, char *dirname, vattr_t *vap, vnode_t **vpp, cred_t *cr, caller_context_t *cc, int flags, vsecattr_t *vsecp)
 This creates a snapshot under '.zfs/snapshot'.
static int zfsctl_freebsd_snapdir_mkdir (struct vop_mkdir_args *ap)
int zfsctl_snapdir_lookup (struct vop_lookup_args *ap)
 Lookup entry point for the 'snapshot' directory.
int zfsctl_shares_lookup (struct vop_lookup_args *ap)
static int zfsctl_snapdir_readdir_cb (vnode_t *vp, void *dp, int *eofp, offset_t *offp, offset_t *nextp, void *data, int flags)
static int zfsctl_shares_readdir (struct vop_readdir_args *ap)
static int zfsctl_shares_getattr (struct vop_getattr_args *ap)
static int zfsctl_snapdir_getattr (struct vop_getattr_args *ap)
static int zfsctl_snapdir_inactive (struct vop_inactive_args *ap)
static int zfsctl_snapshot_inactive (struct vop_inactive_args *ap)
static int zfsctl_traverse_begin (vnode_t **vpp, int lktype)
static void zfsctl_traverse_end (vnode_t *vp, int err)
static int zfsctl_snapshot_getattr (struct vop_getattr_args *ap)
static int zfsctl_snapshot_fid (struct vop_fid_args *ap)
static int zfsctl_snapshot_lookup (struct vop_lookup_args *ap)
static int zfsctl_snapshot_vptocnp (struct vop_vptocnp_args *ap)
int zfsctl_lookup_objset (vfs_t *vfsp, uint64_t objsetid, zfsvfs_t **zfsvfsp)
int zfsctl_umount_snapshots (vfs_t *vfsp, int fflags, cred_t *cr)
 Unmount any snapshots for the given filesystem.

Variables

static struct vop_vector zfsctl_ops_root
static struct vop_vector zfsctl_ops_snapdir
static struct vop_vector zfsctl_ops_snapshot
 These VP's should never see the light of day.
static struct vop_vector zfsctl_ops_shares
static struct vop_vector zfsctl_ops_shares_dir
static gfs_dirent_t zfsctl_root_entries []
 Root directory elements.

Detailed Description

ZFS control directory (a.k.a.

".zfs")

This directory provides a common location for all ZFS meta-objects. Currently, this is only the 'snapshot' directory, but this may expand in the future. The elements are built using the GFS primitives, as the hierarchy does not actually exist on disk.

For 'snapshot', we don't want to have all snapshots always mounted, because this would take up a huge amount of space in /etc/mnttab. We have three types of objects:

   	ctldir ------> snapshotdir -------> snapshot
                                                |
                                                |
                                                V
                                            mounted fs
 

The 'snapshot' node contains just enough information to lookup '..' and act as a mountpoint for the snapshot. Whenever we lookup a specific snapshot, we perform an automount of the underlying filesystem and return the corresponding vnode.

All mounts are handled automatically by the kernel, but unmounts are (currently) handled from user land. The main reason is that there is no reliable way to auto-unmount the filesystem when it's "no longer in use". When the user unmounts a filesystem, we call zfsctl_unmount(), which unmounts any snapshots within the snapshot directory.

The '.zfs', '.zfs/snapshot', and all directories created under '.zfs/snapshot' (ie: '.zfs/snapshot/<snapname>') are all GFS nodes and share the same vfs_t as the head filesystem (what '.zfs' lives under).

File systems mounted ontop of the GFS nodes '.zfs/snapshot/<snapname>' (ie: snapshots) are ZFS nodes and have their own unique vfs_t. However, vnodes within these mounted on file systems have their v_vfsp fields set to the head filesystem to make NFS happy (see zfsctl_snapdir_lookup()). We VFS_HOLD the head filesystem's vfs_t so that it cannot be freed until all snapshots have been unmounted.

Definition in file zfs_ctldir.c.


Define Documentation

#define NROOT_ENTRIES
Value:
((sizeof (zfsctl_root_entries) / \
    sizeof (gfs_dirent_t)) + 1)

Definition at line 164 of file zfs_ctldir.c.

#define ZFSCTL_INO_SNAP (   id)    (id)

.zfs inode namespace

We need to generate unique inode numbers for all files and directories within the .zfs pseudo-filesystem. We use the following scheme:

ENTRY ZFSCTL_INODE .zfs 1 .zfs/snapshot 2 .zfs/snapshot/<snap> objectid(snap)

Definition at line 482 of file zfs_ctldir.c.


Typedef Documentation

typedef struct zfsctl_node zfsctl_node_t

Function Documentation

static int snapentry_compare ( const void *  a,
const void *  b 
) [static]

Definition at line 104 of file zfs_ctldir.c.

static int zfsctl_common_access ( struct vop_access_args *  ap) [static]

Common access routine.

Disallow writes.

Definition at line 329 of file zfs_ctldir.c.

static int zfsctl_common_close ( struct vop_close_args *  ap) [static]

Common close routine.

Nothing to do here.

Definition at line 319 of file zfs_ctldir.c.

static int zfsctl_common_fid ( struct vop_fid_args *  ap) [static]

Definition at line 387 of file zfs_ctldir.c.

static void zfsctl_common_getattr ( vnode_t *  vp,
vattr_t *  vap 
) [static]

Common getattr function.

Fill in basic information.

Definition at line 358 of file zfs_ctldir.c.

static int zfsctl_common_open ( struct vop_open_args *  ap) [static]

Common open routine.

Disallow any write access.

Definition at line 304 of file zfs_ctldir.c.

static int zfsctl_common_reclaim ( struct vop_reclaim_args *  ap) [static]

Definition at line 452 of file zfs_ctldir.c.

void zfsctl_create ( zfsvfs_t zfsvfs)

Create the '.zfs' directory.

This directory is cached as part of the VFS structure. This results in a hold on the vfs_t. The code in zfs_umount() therefore checks against a vfs_count of 2 instead of 1. This reference is removed when the ctldir is destroyed in the unmount.

Definition at line 243 of file zfs_ctldir.c.

void zfsctl_destroy ( zfsvfs_t zfsvfs)

Destroy the '.zfs' directory.

Only called when the filesystem is unmounted. There might still be more references if we were force unmounted, but only new zfs_inactive() calls can occur and they don't reference .zfs

Definition at line 281 of file zfs_ctldir.c.

void zfsctl_fini ( void  )

Definition at line 182 of file zfs_ctldir.c.

int zfsctl_freebsd_root_lookup ( struct vop_lookup_args *  ap)

Special case the handling of "..".

Definition at line 587 of file zfs_ctldir.c.

static int zfsctl_freebsd_snapdir_mkdir ( struct vop_mkdir_args *  ap) [static]

Definition at line 901 of file zfs_ctldir.c.

void zfsctl_init ( void  )

Initialize the various GFS pieces we'll need to create and manipulate .zfs directories.

This is called from the ZFS init routine, and initializes the vnode ops vectors that we'll be using.

Definition at line 174 of file zfs_ctldir.c.

boolean_t zfsctl_is_node ( vnode_t *  vp)

Definition at line 208 of file zfs_ctldir.c.

int zfsctl_lookup_objset ( vfs_t *  vfsp,
uint64_t  objsetid,
zfsvfs_t **  zfsvfsp 
)

Definition at line 1625 of file zfs_ctldir.c.

vnode_t * zfsctl_mknode_shares ( vnode_t *  pvp) [static]

Definition at line 1236 of file zfs_ctldir.c.

vnode_t * zfsctl_mknode_snapdir ( vnode_t *  pvp) [static]

Creates vp, which is '.zfs/snapshot' (zfsctl_snapdir_t).

This function is the callback to create a GFS vnode for '.zfs/snapshot' when a lookup is performed on .zfs for "snapshot".

Parameters:
pvpthe '.zfs' directory (zfsctl_node_t)

Definition at line 1217 of file zfs_ctldir.c.

vnode_t* zfsctl_root ( znode_t zp)

Given a root znode, retrieve the associated .zfs directory.

Add a hold to the vnode and return it.

Definition at line 292 of file zfs_ctldir.c.

static int zfsctl_root_getattr ( struct vop_getattr_args *  ap) [static]

Get root directory attributes.

Definition at line 489 of file zfs_ctldir.c.

static ino64_t zfsctl_root_inode_cb ( vnode_t *  vp,
int  index 
) [static]

Return the inode number associated with the 'snapshot' or 'shares' directory.

Definition at line 224 of file zfs_ctldir.c.

int zfsctl_root_lookup ( vnode_t *  dvp,
char *  nm,
vnode_t **  vpp,
pathname_t *  pnp,
int  flags,
vnode_t *  rdir,
cred_t *  cr,
caller_context_t *  ct,
int *  direntflags,
pathname_t *  realpnp 
)

Special case the handling of "..".

Definition at line 518 of file zfs_ctldir.c.

static int zfsctl_shares_fid ( struct vop_fid_args *  ap) [static]

Definition at line 423 of file zfs_ctldir.c.

static int zfsctl_shares_getattr ( struct vop_getattr_args *  ap) [static]

Definition at line 1253 of file zfs_ctldir.c.

int zfsctl_shares_lookup ( struct vop_lookup_args *  ap)

Definition at line 1087 of file zfs_ctldir.c.

static int zfsctl_shares_readdir ( struct vop_readdir_args *  ap) [static]

Definition at line 1171 of file zfs_ctldir.c.

static int zfsctl_snapdir_getattr ( struct vop_getattr_args *  ap) [static]

Definition at line 1286 of file zfs_ctldir.c.

static int zfsctl_snapdir_inactive ( struct vop_inactive_args *  ap) [static]

Definition at line 1311 of file zfs_ctldir.c.

int zfsctl_snapdir_lookup ( struct vop_lookup_args *  ap)

Lookup entry point for the 'snapshot' directory.

Try to open the snapshot if it exist, creating the pseudo filesystem vnode as necessary. Perform a mount of the associated dataset on top of the vnode.

Definition at line 923 of file zfs_ctldir.c.

static int zfsctl_snapdir_mkdir ( vnode_t *  dvp,
char *  dirname,
vattr_t *  vap,
vnode_t **  vpp,
cred_t *  cr,
caller_context_t *  cc,
int  flags,
vsecattr_t *  vsecp 
) [static]

This creates a snapshot under '.zfs/snapshot'.

Definition at line 869 of file zfs_ctldir.c.

static int zfsctl_snapdir_readdir_cb ( vnode_t *  vp,
void *  dp,
int *  eofp,
offset_t *  offp,
offset_t *  nextp,
void *  data,
int  flags 
) [static]

Definition at line 1127 of file zfs_ctldir.c.

static int zfsctl_snapshot_fid ( struct vop_fid_args *  ap) [static]

Definition at line 1522 of file zfs_ctldir.c.

static int zfsctl_snapshot_getattr ( struct vop_getattr_args *  ap) [static]

Definition at line 1504 of file zfs_ctldir.c.

static int zfsctl_snapshot_inactive ( struct vop_inactive_args *  ap) [static]

Definition at line 1426 of file zfs_ctldir.c.

static int zfsctl_snapshot_lookup ( struct vop_lookup_args *  ap) [static]

Definition at line 1539 of file zfs_ctldir.c.

static vnode_t * zfsctl_snapshot_mknode ( vnode_t *  pvp,
uint64_t  objset 
) [static]

This creates a GFS node under '.zfs/snapshot' representing each snapshot.

This newly created GFS node is what we mount snapshot vfs_t's ontop of.

Parameters:
pvpthe GFS vnode '.zfs/snapshot'

Definition at line 1410 of file zfs_ctldir.c.

static int zfsctl_snapshot_vptocnp ( struct vop_vptocnp_args *  ap) [static]

Definition at line 1569 of file zfs_ctldir.c.

static int zfsctl_snapshot_zname ( vnode_t *  vp,
const char *  name,
int  len,
char *  zname 
) [static]

Definition at line 632 of file zfs_ctldir.c.

static int zfsctl_traverse_begin ( vnode_t **  vpp,
int  lktype 
) [static]

Definition at line 1483 of file zfs_ctldir.c.

static void zfsctl_traverse_end ( vnode_t *  vp,
int  err 
) [static]

Definition at line 1494 of file zfs_ctldir.c.

int zfsctl_umount_snapshots ( vfs_t *  vfsp,
int  fflags,
cred_t *  cr 
)

Unmount any snapshots for the given filesystem.

This is called from zfs_umount() - if we have a ctldir, then go through and unmount all the snapshots.

Definition at line 1688 of file zfs_ctldir.c.

static int zfsctl_unmount_snap ( zfs_snapentry_t sep,
int  fflags,
cred_t *  cr 
) [static]

Definition at line 647 of file zfs_ctldir.c.


Variable Documentation

static struct vop_vector zfsctl_ops_root [static]
Initial value:
 {
        .vop_default =  &default_vnodeops,
        .vop_open =     zfsctl_common_open,
        .vop_close =    zfsctl_common_close,
        .vop_ioctl =    VOP_EINVAL,
        .vop_getattr =  zfsctl_root_getattr,
        .vop_access =   zfsctl_common_access,
        .vop_readdir =  gfs_vop_readdir,
        .vop_lookup =   zfsctl_freebsd_root_lookup,
        .vop_inactive = gfs_vop_inactive,
        .vop_reclaim =  zfsctl_common_reclaim,



        .vop_fid =      zfsctl_common_fid,
}

Definition at line 130 of file zfs_ctldir.c.

static struct vop_vector zfsctl_ops_shares [static]
Initial value:
 {
        .vop_default =  &default_vnodeops,
        .vop_open =     zfsctl_common_open,
        .vop_close =    zfsctl_common_close,
        .vop_ioctl =    VOP_EINVAL,
        .vop_getattr =  zfsctl_shares_getattr,
        .vop_access =   zfsctl_common_access,
        .vop_readdir =  zfsctl_shares_readdir,
        .vop_lookup =   zfsctl_shares_lookup,
        .vop_inactive = gfs_vop_inactive,
        .vop_reclaim =  zfsctl_common_reclaim,
        .vop_fid =      zfsctl_shares_fid,
}

Definition at line 133 of file zfs_ctldir.c.

struct vop_vector zfsctl_ops_shares_dir [static]

Definition at line 134 of file zfs_ctldir.c.

static struct vop_vector zfsctl_ops_snapdir [static]
Initial value:
 {
        .vop_default =  &default_vnodeops,
        .vop_open =     zfsctl_common_open,
        .vop_close =    zfsctl_common_close,
        .vop_ioctl =    VOP_EINVAL,
        .vop_getattr =  zfsctl_snapdir_getattr,
        .vop_access =   zfsctl_common_access,
        .vop_mkdir =    zfsctl_freebsd_snapdir_mkdir,
        .vop_readdir =  gfs_vop_readdir,
        .vop_lookup =   zfsctl_snapdir_lookup,
        .vop_inactive = zfsctl_snapdir_inactive,
        .vop_reclaim =  zfsctl_common_reclaim,
        .vop_fid =      zfsctl_common_fid,
}

Definition at line 131 of file zfs_ctldir.c.

static struct vop_vector zfsctl_ops_snapshot [static]
Initial value:
 {
        .vop_default =  &default_vnodeops,
        .vop_inactive = zfsctl_snapshot_inactive,
        .vop_lookup =   zfsctl_snapshot_lookup,
        .vop_reclaim =  zfsctl_common_reclaim,
        .vop_getattr =  zfsctl_snapshot_getattr,
        .vop_fid =      zfsctl_snapshot_fid,
        .vop_vptocnp =  zfsctl_snapshot_vptocnp,
}

These VP's should never see the light of day.

They should always be covered.

Definition at line 132 of file zfs_ctldir.c.

gfs_dirent_t zfsctl_root_entries[] [static]
Initial value:
 {
        { "snapshot", zfsctl_mknode_snapdir, GFS_CACHE_VNODE },
        { "shares", zfsctl_mknode_shares, GFS_CACHE_VNODE },
        { NULL }
}

Root directory elements.

We only have two entries snapshot and shares.

Definition at line 157 of file zfs_ctldir.c.

 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines