Changeset View
Changeset View
Standalone View
Standalone View
sys/fs/tmpfs/tmpfs_subr.c
Show First 20 Lines • Show All 212 Lines • ▼ Show 20 Lines | if ((mp->mnt_kern_flag & MNTK_UNMOUNT) != 0) { | ||||
* cannot be destroyed until node construction is | * cannot be destroyed until node construction is | ||||
* finished and the parent vnode unlocked. | * finished and the parent vnode unlocked. | ||||
* | * | ||||
* Tmpfs does not need to instantiate new nodes during | * Tmpfs does not need to instantiate new nodes during | ||||
* unmount. | * unmount. | ||||
*/ | */ | ||||
return (EBUSY); | return (EBUSY); | ||||
} | } | ||||
if ((mp->mnt_kern_flag & MNT_RDONLY) != 0) | |||||
return (EROFS); | |||||
nnode = (struct tmpfs_node *)uma_zalloc_arg(tmp->tm_node_pool, tmp, | nnode = (struct tmpfs_node *)uma_zalloc_arg(tmp->tm_node_pool, tmp, | ||||
M_WAITOK); | M_WAITOK); | ||||
/* Generic initialization. */ | /* Generic initialization. */ | ||||
nnode->tn_type = type; | nnode->tn_type = type; | ||||
vfs_timestamp(&nnode->tn_atime); | vfs_timestamp(&nnode->tn_atime); | ||||
nnode->tn_birthtime = nnode->tn_ctime = nnode->tn_mtime = | nnode->tn_birthtime = nnode->tn_ctime = nnode->tn_mtime = | ||||
▲ Show 20 Lines • Show All 874 Lines • ▼ Show 20 Lines | |||||
/* | /* | ||||
* Helper function for tmpfs_readdir. Creates a '.' entry for the given | * Helper function for tmpfs_readdir. Creates a '.' entry for the given | ||||
* directory and returns it in the uio space. The function returns 0 | * directory and returns it in the uio space. The function returns 0 | ||||
* on success, -1 if there was not enough space in the uio structure to | * on success, -1 if there was not enough space in the uio structure to | ||||
* hold the directory entry or an appropriate error code if another | * hold the directory entry or an appropriate error code if another | ||||
* error happens. | * error happens. | ||||
*/ | */ | ||||
static int | static int | ||||
tmpfs_dir_getdotdent(struct tmpfs_node *node, struct uio *uio) | tmpfs_dir_getdotdent(struct tmpfs_mount *tm, struct tmpfs_node *node, | ||||
struct uio *uio) | |||||
{ | { | ||||
int error; | int error; | ||||
struct dirent dent; | struct dirent dent; | ||||
TMPFS_VALIDATE_DIR(node); | TMPFS_VALIDATE_DIR(node); | ||||
MPASS(uio->uio_offset == TMPFS_DIRCOOKIE_DOT); | MPASS(uio->uio_offset == TMPFS_DIRCOOKIE_DOT); | ||||
dent.d_fileno = node->tn_id; | dent.d_fileno = node->tn_id; | ||||
dent.d_type = DT_DIR; | dent.d_type = DT_DIR; | ||||
dent.d_namlen = 1; | dent.d_namlen = 1; | ||||
dent.d_name[0] = '.'; | dent.d_name[0] = '.'; | ||||
dent.d_reclen = GENERIC_DIRSIZ(&dent); | dent.d_reclen = GENERIC_DIRSIZ(&dent); | ||||
dirent_terminate(&dent); | dirent_terminate(&dent); | ||||
if (dent.d_reclen > uio->uio_resid) | if (dent.d_reclen > uio->uio_resid) | ||||
error = EJUSTRETURN; | error = EJUSTRETURN; | ||||
else | else | ||||
error = uiomove(&dent, dent.d_reclen, uio); | error = uiomove(&dent, dent.d_reclen, uio); | ||||
tmpfs_set_status(node, TMPFS_NODE_ACCESSED); | tmpfs_set_status(tm, node, TMPFS_NODE_ACCESSED); | ||||
return (error); | return (error); | ||||
} | } | ||||
/* | /* | ||||
* Helper function for tmpfs_readdir. Creates a '..' entry for the given | * Helper function for tmpfs_readdir. Creates a '..' entry for the given | ||||
* directory and returns it in the uio space. The function returns 0 | * directory and returns it in the uio space. The function returns 0 | ||||
* on success, -1 if there was not enough space in the uio structure to | * on success, -1 if there was not enough space in the uio structure to | ||||
* hold the directory entry or an appropriate error code if another | * hold the directory entry or an appropriate error code if another | ||||
* error happens. | * error happens. | ||||
*/ | */ | ||||
static int | static int | ||||
tmpfs_dir_getdotdotdent(struct tmpfs_node *node, struct uio *uio) | tmpfs_dir_getdotdotdent(struct tmpfs_mount *tm, struct tmpfs_node *node, | ||||
struct uio *uio) | |||||
{ | { | ||||
int error; | int error; | ||||
struct dirent dent; | struct dirent dent; | ||||
TMPFS_VALIDATE_DIR(node); | TMPFS_VALIDATE_DIR(node); | ||||
MPASS(uio->uio_offset == TMPFS_DIRCOOKIE_DOTDOT); | MPASS(uio->uio_offset == TMPFS_DIRCOOKIE_DOTDOT); | ||||
/* | /* | ||||
Show All 14 Lines | tmpfs_dir_getdotdotdent(struct tmpfs_mount *tm, struct tmpfs_node *node, | ||||
dent.d_reclen = GENERIC_DIRSIZ(&dent); | dent.d_reclen = GENERIC_DIRSIZ(&dent); | ||||
dirent_terminate(&dent); | dirent_terminate(&dent); | ||||
if (dent.d_reclen > uio->uio_resid) | if (dent.d_reclen > uio->uio_resid) | ||||
error = EJUSTRETURN; | error = EJUSTRETURN; | ||||
else | else | ||||
error = uiomove(&dent, dent.d_reclen, uio); | error = uiomove(&dent, dent.d_reclen, uio); | ||||
tmpfs_set_status(node, TMPFS_NODE_ACCESSED); | tmpfs_set_status(tm, node, TMPFS_NODE_ACCESSED); | ||||
return (error); | return (error); | ||||
} | } | ||||
/* | /* | ||||
* Helper function for tmpfs_readdir. Returns as much directory entries | * Helper function for tmpfs_readdir. Returns as much directory entries | ||||
* as can fit in the uio space. The read starts at uio->uio_offset. | * as can fit in the uio space. The read starts at uio->uio_offset. | ||||
* The function returns 0 on success, -1 if there was not enough space | * The function returns 0 on success, -1 if there was not enough space | ||||
* in the uio structure to hold the directory entry or an appropriate | * in the uio structure to hold the directory entry or an appropriate | ||||
* error code if another error happens. | * error code if another error happens. | ||||
*/ | */ | ||||
int | int | ||||
tmpfs_dir_getdents(struct tmpfs_node *node, struct uio *uio, int maxcookies, | tmpfs_dir_getdents(struct tmpfs_mount *tm, struct tmpfs_node *node, | ||||
u_long *cookies, int *ncookies) | struct uio *uio, int maxcookies, u_long *cookies, int *ncookies) | ||||
{ | { | ||||
struct tmpfs_dir_cursor dc; | struct tmpfs_dir_cursor dc; | ||||
struct tmpfs_dirent *de; | struct tmpfs_dirent *de; | ||||
off_t off; | off_t off; | ||||
int error; | int error; | ||||
TMPFS_VALIDATE_DIR(node); | TMPFS_VALIDATE_DIR(node); | ||||
off = 0; | off = 0; | ||||
/* | /* | ||||
* Lookup the node from the current offset. The starting offset of | * Lookup the node from the current offset. The starting offset of | ||||
* 0 will lookup both '.' and '..', and then the first real entry, | * 0 will lookup both '.' and '..', and then the first real entry, | ||||
* or EOF if there are none. Then find all entries for the dir that | * or EOF if there are none. Then find all entries for the dir that | ||||
* fit into the buffer. Once no more entries are found (de == NULL), | * fit into the buffer. Once no more entries are found (de == NULL), | ||||
* the offset is set to TMPFS_DIRCOOKIE_EOF, which will cause the next | * the offset is set to TMPFS_DIRCOOKIE_EOF, which will cause the next | ||||
* call to return 0. | * call to return 0. | ||||
*/ | */ | ||||
switch (uio->uio_offset) { | switch (uio->uio_offset) { | ||||
case TMPFS_DIRCOOKIE_DOT: | case TMPFS_DIRCOOKIE_DOT: | ||||
error = tmpfs_dir_getdotdent(node, uio); | error = tmpfs_dir_getdotdent(tm, node, uio); | ||||
if (error != 0) | if (error != 0) | ||||
return (error); | return (error); | ||||
uio->uio_offset = TMPFS_DIRCOOKIE_DOTDOT; | uio->uio_offset = TMPFS_DIRCOOKIE_DOTDOT; | ||||
if (cookies != NULL) | if (cookies != NULL) | ||||
cookies[(*ncookies)++] = off = uio->uio_offset; | cookies[(*ncookies)++] = off = uio->uio_offset; | ||||
/* FALLTHROUGH */ | /* FALLTHROUGH */ | ||||
case TMPFS_DIRCOOKIE_DOTDOT: | case TMPFS_DIRCOOKIE_DOTDOT: | ||||
error = tmpfs_dir_getdotdotdent(node, uio); | error = tmpfs_dir_getdotdotdent(tm, node, uio); | ||||
if (error != 0) | if (error != 0) | ||||
return (error); | return (error); | ||||
de = tmpfs_dir_first(node, &dc); | de = tmpfs_dir_first(node, &dc); | ||||
uio->uio_offset = tmpfs_dirent_cookie(de); | uio->uio_offset = tmpfs_dirent_cookie(de); | ||||
if (cookies != NULL) | if (cookies != NULL) | ||||
cookies[(*ncookies)++] = off = uio->uio_offset; | cookies[(*ncookies)++] = off = uio->uio_offset; | ||||
/* EOF. */ | /* EOF. */ | ||||
if (de == NULL) | if (de == NULL) | ||||
▲ Show 20 Lines • Show All 85 Lines • ▼ Show 20 Lines | tmpfs_dir_getdents(struct tmpfs_mount *tm, struct tmpfs_node *node, | ||||
if (cookies == NULL) | if (cookies == NULL) | ||||
off = tmpfs_dirent_cookie(de); | off = tmpfs_dirent_cookie(de); | ||||
/* Update the offset and cache. */ | /* Update the offset and cache. */ | ||||
uio->uio_offset = off; | uio->uio_offset = off; | ||||
node->tn_dir.tn_readdir_lastn = off; | node->tn_dir.tn_readdir_lastn = off; | ||||
node->tn_dir.tn_readdir_lastp = de; | node->tn_dir.tn_readdir_lastp = de; | ||||
tmpfs_set_status(node, TMPFS_NODE_ACCESSED); | tmpfs_set_status(tm, node, TMPFS_NODE_ACCESSED); | ||||
return error; | return error; | ||||
} | } | ||||
int | int | ||||
tmpfs_dir_whiteout_add(struct vnode *dvp, struct componentname *cnp) | tmpfs_dir_whiteout_add(struct vnode *dvp, struct componentname *cnp) | ||||
{ | { | ||||
struct tmpfs_dirent *de; | struct tmpfs_dirent *de; | ||||
int error; | int error; | ||||
▲ Show 20 Lines • Show All 438 Lines • ▼ Show 20 Lines | tmpfs_chtimes(struct vnode *vp, struct vattr *vap, | ||||
if (vap->va_birthtime.tv_sec != VNOVAL) | if (vap->va_birthtime.tv_sec != VNOVAL) | ||||
node->tn_birthtime = vap->va_birthtime; | node->tn_birthtime = vap->va_birthtime; | ||||
ASSERT_VOP_ELOCKED(vp, "chtimes2"); | ASSERT_VOP_ELOCKED(vp, "chtimes2"); | ||||
return (0); | return (0); | ||||
} | } | ||||
void | void | ||||
tmpfs_set_status(struct tmpfs_node *node, int status) | tmpfs_set_status(struct tmpfs_mount *tm, struct tmpfs_node *node, int status) | ||||
{ | { | ||||
if ((node->tn_status & status) == status) | if ((node->tn_status & status) == status || tm->tm_ronly) | ||||
return; | return; | ||||
TMPFS_NODE_LOCK(node); | TMPFS_NODE_LOCK(node); | ||||
node->tn_status |= status; | node->tn_status |= status; | ||||
TMPFS_NODE_UNLOCK(node); | TMPFS_NODE_UNLOCK(node); | ||||
} | } | ||||
/* Sync timestamps */ | /* Sync timestamps */ | ||||
void | void | ||||
▲ Show 20 Lines • Show All 84 Lines • Show Last 20 Lines |