FreeBSD ZFS
The Zettabyte File System
|
#include <sys/pathname.h>
#include <sys/dmu.h>
#include <sys/zfs_znode.h>
Go to the source code of this file.
Defines | |
#define | ZNEW 0x0001 |
entry should not exist | |
#define | ZEXISTS 0x0002 |
entry should exist | |
#define | ZSHARED 0x0004 |
shared access (zfs_dirlook()) | |
#define | ZXATTR 0x0008 |
we want the xattr dir | |
#define | ZRENAMING 0x0010 |
znode is being renamed | |
#define | ZCILOOK 0x0020 |
case-insensitive lookup requested | |
#define | ZCIEXACT 0x0040 |
c-i requires c-s match (rename) | |
#define | ZHAVELOCK 0x0080 |
z_name_lock is already held | |
#define | IS_ROOT_NODE 0x01 |
create a root node | |
#define | IS_XATTR 0x02 |
create an extended attribute node | |
Functions | |
int | zfs_dirent_lock (zfs_dirlock_t **, znode_t *, char *, znode_t **, int, int *, pathname_t *) |
Lock a directory entry. | |
void | zfs_dirent_unlock (zfs_dirlock_t *) |
Unlock this directory entry and wake anyone who was waiting for it. | |
int | zfs_link_create (zfs_dirlock_t *, znode_t *, dmu_tx_t *, int) |
Link zp into dl. | |
int | zfs_link_destroy (zfs_dirlock_t *, znode_t *, dmu_tx_t *, int, boolean_t *) |
Unlink zp from dl, and mark zp for deletion if this was the last link. | |
int | zfs_dirlook (znode_t *, char *, vnode_t **, int, int *, pathname_t *) |
Look up an entry in a directory. | |
void | zfs_mknode (znode_t *, vattr_t *, dmu_tx_t *, cred_t *, uint_t, znode_t **, zfs_acl_ids_t *) |
Create a new DMU object to hold a zfs znode. | |
void | zfs_rmnode (znode_t *) |
void | zfs_dl_name_switch (zfs_dirlock_t *dl, char *new, char **old) |
boolean_t | zfs_dirempty (znode_t *) |
Indicate whether the directory is empty. | |
void | zfs_unlinked_add (znode_t *, dmu_tx_t *) |
unlinked Set (formerly known as the "delete queue") Error Handling | |
void | zfs_unlinked_drain (zfsvfs_t *zfsvfs) |
int | zfs_sticky_remove_access (znode_t *, znode_t *, cred_t *cr) |
Decide whether it is okay to remove within a sticky directory. | |
int | zfs_get_xattrdir (znode_t *, vnode_t **, cred_t *, int) |
Return a znode for the extended attribute directory for zp. | |
int | zfs_make_xattrdir (znode_t *, vattr_t *, vnode_t **, cred_t *) |
#define ZSHARED 0x0004 |
shared access (zfs_dirlook())
boolean_t zfs_dirempty | ( | znode_t * | dzp | ) |
int zfs_dirent_lock | ( | zfs_dirlock_t ** | dlpp, |
znode_t * | dzp, | ||
char * | name, | ||
znode_t ** | zpp, | ||
int | flag, | ||
int * | direntflags, | ||
pathname_t * | realpnp | ||
) |
Lock a directory entry.
A dirlock on <dzp, name> protects that name in dzp's directory zap object. As long as you hold a dirlock, you can assume two things: (1) dzp cannot be reaped, and (2) no other thread can change the zap entry for (i.e. link or unlink) this name.
Input arguments: dzp - znode for directory name - name of entry to lock flag - ZNEW: if the entry already exists, fail with EEXIST. ZEXISTS: if the entry does not exist, fail with ENOENT. ZSHARED: allow concurrent access with other ZSHARED callers. ZXATTR: we want dzp's xattr directory ZCILOOK: On a mixed sensitivity file system, this lookup should be case-insensitive. ZCIEXACT: On a purely case-insensitive file system, this lookup should be case-sensitive. ZRENAMING: we are locking for renaming, force narrow locks ZHAVELOCK: Don't grab the z_name_lock for this call. The current thread already holds it.
Output arguments: zpp - pointer to the znode for the entry (NULL if there isn't one) dlpp - pointer to the dirlock for this entry (NULL on error) direntflags - (case-insensitive lookup only) flags if multiple case-sensitive matches exist in directory realpnp - (case-insensitive lookup only) actual name matched within the directory
Return value: 0 on success or errno on failure.
NOTE: Always checks for, and rejects, '.' and '..'. NOTE: For case-insensitive file systems we take wide locks (see below), but return znode pointers to a single match.
void zfs_dirent_unlock | ( | zfs_dirlock_t * | ) |
int zfs_dirlook | ( | znode_t * | dzp, |
char * | name, | ||
vnode_t ** | vpp, | ||
int | flags, | ||
int * | deflg, | ||
pathname_t * | rpnp | ||
) |
void zfs_dl_name_switch | ( | zfs_dirlock_t * | dl, |
char * | new, | ||
char ** | old | ||
) |
int zfs_get_xattrdir | ( | znode_t * | zp, |
vnode_t ** | xvpp, | ||
cred_t * | cr, | ||
int | flags | ||
) |
Return a znode for the extended attribute directory for zp.
** If the directory does not already exist, it is created **
IN: zp - znode to obtain attribute directory from cr - credentials of caller flags - flags from the VOP_LOOKUP call
OUT: xzpp - pointer to extended attribute znode
RETURN: 0 on success error number on failure
int zfs_link_create | ( | zfs_dirlock_t * | dl, |
znode_t * | zp, | ||
dmu_tx_t * | tx, | ||
int | flag | ||
) |
int zfs_link_destroy | ( | zfs_dirlock_t * | dl, |
znode_t * | zp, | ||
dmu_tx_t * | tx, | ||
int | flag, | ||
boolean_t * | unlinkedp | ||
) |
Unlink zp from dl, and mark zp for deletion if this was the last link.
Can fail if zp is a mount point (EBUSY) or a non-empty directory (EEXIST). If 'unlinkedp' is NULL, we put unlinked znodes on the unlinked list. If it's non-NULL, we use it to indicate whether the znode needs deletion, and it's the caller's job to do it.
int zfs_make_xattrdir | ( | znode_t * | , |
vattr_t * | , | ||
vnode_t ** | , | ||
cred_t * | |||
) |
void zfs_mknode | ( | znode_t * | dzp, |
vattr_t * | vap, | ||
dmu_tx_t * | tx, | ||
cred_t * | cr, | ||
uint_t | flag, | ||
znode_t ** | zpp, | ||
zfs_acl_ids_t * | acl_ids | ||
) |
Create a new DMU object to hold a zfs znode.
[in] | dzp | parent directory for new znode |
[in] | vap | file attributes for new znode |
[in] | tx | dmu transaction id for zap operations |
[in] | cr | credentials of caller |
[in] | flag | flags:
|
[out] | zpp | allocated znode |
Definition at line 786 of file zfs_znode.c.
Decide whether it is okay to remove within a sticky directory.
In sticky directories, write access is not sufficient; you can remove entries from a directory only if:
you own the directory, you own the entry, the entry is a plain file and you have write access, or you are privileged (checked in secpolicy...).
The function returns 0 if remove access is granted.
unlinked Set (formerly known as the "delete queue") Error Handling
When dealing with the unlinked set, we dmu_tx_hold_zap(), but we don't specify the name of the entry that we will be manipulating. We also fib and say that we won't be adding any new entries to the unlinked set, even though we might (this is to lower the minimum file size that can be deleted in a full filesystem). So on the small chance that the nlink list is using a fat zap (ie. has more than 2000 entries), we *may* not pre-read a block that's needed. Therefore it is remotely possible for some of the assertions regarding the unlinked set below to fail due to i/o error. On a nondebug system, this will result in the space being leaked.