tmpfs: ignore tmpfs_set_status() if mount point is read-only.
In particular, this fixes atimes still changing for ro tmpfs. tmpfs_set_status() gains tmpfs_mount * argument. Tested by: pho Sponsored by: The FreeBSD Foundation MFC after: 2 weeks Differential revision: https://reviews.freebsd.org/D19737
This commit is contained in:
parent
ae26575394
commit
e1cdc30faa
@ -437,8 +437,8 @@ void tmpfs_dir_destroy(struct tmpfs_mount *, struct tmpfs_node *);
|
||||
struct tmpfs_dirent * tmpfs_dir_lookup(struct tmpfs_node *node,
|
||||
struct tmpfs_node *f,
|
||||
struct componentname *cnp);
|
||||
int tmpfs_dir_getdents(struct tmpfs_node *, struct uio *, int,
|
||||
u_long *, int *);
|
||||
int tmpfs_dir_getdents(struct tmpfs_mount *, struct tmpfs_node *,
|
||||
struct uio *, int, u_long *, int *);
|
||||
int tmpfs_dir_whiteout_add(struct vnode *, struct componentname *);
|
||||
void tmpfs_dir_whiteout_remove(struct vnode *, struct componentname *);
|
||||
int tmpfs_reg_resize(struct vnode *, off_t, boolean_t);
|
||||
@ -452,7 +452,8 @@ int tmpfs_chtimes(struct vnode *, struct vattr *, struct ucred *cred,
|
||||
void tmpfs_itimes(struct vnode *, const struct timespec *,
|
||||
const struct timespec *);
|
||||
|
||||
void tmpfs_set_status(struct tmpfs_node *node, int status);
|
||||
void tmpfs_set_status(struct tmpfs_mount *tm, struct tmpfs_node *node,
|
||||
int status);
|
||||
void tmpfs_update(struct vnode *);
|
||||
int tmpfs_truncate(struct vnode *, off_t);
|
||||
struct tmpfs_dirent *tmpfs_dir_first(struct tmpfs_node *dnode,
|
||||
|
@ -56,7 +56,8 @@ tmpfs_fifo_close(struct vop_close_args *v)
|
||||
struct tmpfs_node *node;
|
||||
|
||||
node = VP_TO_TMPFS_NODE(v->a_vp);
|
||||
tmpfs_set_status(node, TMPFS_NODE_ACCESSED);
|
||||
tmpfs_set_status(VFS_TO_TMPFS(v->a_vp->v_mount), node,
|
||||
TMPFS_NODE_ACCESSED);
|
||||
tmpfs_update(v->a_vp);
|
||||
return (fifo_specops.vop_close(v));
|
||||
}
|
||||
|
@ -1110,7 +1110,8 @@ tmpfs_dir_destroy(struct tmpfs_mount *tmp, struct tmpfs_node *dnode)
|
||||
* error happens.
|
||||
*/
|
||||
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;
|
||||
struct dirent dent;
|
||||
@ -1130,7 +1131,7 @@ tmpfs_dir_getdotdent(struct tmpfs_node *node, struct uio *uio)
|
||||
else
|
||||
error = uiomove(&dent, dent.d_reclen, uio);
|
||||
|
||||
tmpfs_set_status(node, TMPFS_NODE_ACCESSED);
|
||||
tmpfs_set_status(tm, node, TMPFS_NODE_ACCESSED);
|
||||
|
||||
return (error);
|
||||
}
|
||||
@ -1143,7 +1144,8 @@ tmpfs_dir_getdotdent(struct tmpfs_node *node, struct uio *uio)
|
||||
* error happens.
|
||||
*/
|
||||
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;
|
||||
struct dirent dent;
|
||||
@ -1174,7 +1176,7 @@ tmpfs_dir_getdotdotdent(struct tmpfs_node *node, struct uio *uio)
|
||||
else
|
||||
error = uiomove(&dent, dent.d_reclen, uio);
|
||||
|
||||
tmpfs_set_status(node, TMPFS_NODE_ACCESSED);
|
||||
tmpfs_set_status(tm, node, TMPFS_NODE_ACCESSED);
|
||||
|
||||
return (error);
|
||||
}
|
||||
@ -1187,8 +1189,8 @@ tmpfs_dir_getdotdotdent(struct tmpfs_node *node, struct uio *uio)
|
||||
* error code if another error happens.
|
||||
*/
|
||||
int
|
||||
tmpfs_dir_getdents(struct tmpfs_node *node, struct uio *uio, int maxcookies,
|
||||
u_long *cookies, int *ncookies)
|
||||
tmpfs_dir_getdents(struct tmpfs_mount *tm, struct tmpfs_node *node,
|
||||
struct uio *uio, int maxcookies, u_long *cookies, int *ncookies)
|
||||
{
|
||||
struct tmpfs_dir_cursor dc;
|
||||
struct tmpfs_dirent *de;
|
||||
@ -1209,7 +1211,7 @@ tmpfs_dir_getdents(struct tmpfs_node *node, struct uio *uio, int maxcookies,
|
||||
*/
|
||||
switch (uio->uio_offset) {
|
||||
case TMPFS_DIRCOOKIE_DOT:
|
||||
error = tmpfs_dir_getdotdent(node, uio);
|
||||
error = tmpfs_dir_getdotdent(tm, node, uio);
|
||||
if (error != 0)
|
||||
return (error);
|
||||
uio->uio_offset = TMPFS_DIRCOOKIE_DOTDOT;
|
||||
@ -1217,7 +1219,7 @@ tmpfs_dir_getdents(struct tmpfs_node *node, struct uio *uio, int maxcookies,
|
||||
cookies[(*ncookies)++] = off = uio->uio_offset;
|
||||
/* FALLTHROUGH */
|
||||
case TMPFS_DIRCOOKIE_DOTDOT:
|
||||
error = tmpfs_dir_getdotdotdent(node, uio);
|
||||
error = tmpfs_dir_getdotdotdent(tm, node, uio);
|
||||
if (error != 0)
|
||||
return (error);
|
||||
de = tmpfs_dir_first(node, &dc);
|
||||
@ -1319,7 +1321,7 @@ tmpfs_dir_getdents(struct tmpfs_node *node, struct uio *uio, int maxcookies,
|
||||
node->tn_dir.tn_readdir_lastn = off;
|
||||
node->tn_dir.tn_readdir_lastp = de;
|
||||
|
||||
tmpfs_set_status(node, TMPFS_NODE_ACCESSED);
|
||||
tmpfs_set_status(tm, node, TMPFS_NODE_ACCESSED);
|
||||
return error;
|
||||
}
|
||||
|
||||
@ -1774,10 +1776,10 @@ tmpfs_chtimes(struct vnode *vp, struct vattr *vap,
|
||||
}
|
||||
|
||||
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;
|
||||
TMPFS_NODE_LOCK(node);
|
||||
node->tn_status |= status;
|
||||
|
@ -481,7 +481,7 @@ tmpfs_read(struct vop_read_args *v)
|
||||
if (uio->uio_offset < 0)
|
||||
return (EINVAL);
|
||||
node = VP_TO_TMPFS_NODE(vp);
|
||||
tmpfs_set_status(node, TMPFS_NODE_ACCESSED);
|
||||
tmpfs_set_status(VFS_TO_TMPFS(vp->v_mount), node, TMPFS_NODE_ACCESSED);
|
||||
return (uiomove_object(node->tn_reg.tn_aobj, node->tn_size, uio));
|
||||
}
|
||||
|
||||
@ -1188,18 +1188,22 @@ tmpfs_symlink(struct vop_symlink_args *v)
|
||||
}
|
||||
|
||||
static int
|
||||
tmpfs_readdir(struct vop_readdir_args *v)
|
||||
tmpfs_readdir(struct vop_readdir_args *va)
|
||||
{
|
||||
struct vnode *vp = v->a_vp;
|
||||
struct uio *uio = v->a_uio;
|
||||
int *eofflag = v->a_eofflag;
|
||||
u_long **cookies = v->a_cookies;
|
||||
int *ncookies = v->a_ncookies;
|
||||
|
||||
int error;
|
||||
ssize_t startresid;
|
||||
int maxcookies;
|
||||
struct vnode *vp;
|
||||
struct uio *uio;
|
||||
struct tmpfs_mount *tm;
|
||||
struct tmpfs_node *node;
|
||||
u_long **cookies;
|
||||
int *eofflag, *ncookies;
|
||||
ssize_t startresid;
|
||||
int error, maxcookies;
|
||||
|
||||
vp = va->a_vp;
|
||||
uio = va->a_uio;
|
||||
eofflag = va->a_eofflag;
|
||||
cookies = va->a_cookies;
|
||||
ncookies = va->a_ncookies;
|
||||
|
||||
/* This operation only makes sense on directory nodes. */
|
||||
if (vp->v_type != VDIR)
|
||||
@ -1207,6 +1211,7 @@ tmpfs_readdir(struct vop_readdir_args *v)
|
||||
|
||||
maxcookies = 0;
|
||||
node = VP_TO_TMPFS_DIR(vp);
|
||||
tm = VFS_TO_TMPFS(vp->v_mount);
|
||||
|
||||
startresid = uio->uio_resid;
|
||||
|
||||
@ -1220,9 +1225,9 @@ tmpfs_readdir(struct vop_readdir_args *v)
|
||||
}
|
||||
|
||||
if (cookies == NULL)
|
||||
error = tmpfs_dir_getdents(node, uio, 0, NULL, NULL);
|
||||
error = tmpfs_dir_getdents(tm, node, uio, 0, NULL, NULL);
|
||||
else
|
||||
error = tmpfs_dir_getdents(node, uio, maxcookies, *cookies,
|
||||
error = tmpfs_dir_getdents(tm, node, uio, maxcookies, *cookies,
|
||||
ncookies);
|
||||
|
||||
/* Buffer was filled without hitting EOF. */
|
||||
@ -1258,7 +1263,7 @@ tmpfs_readlink(struct vop_readlink_args *v)
|
||||
|
||||
error = uiomove(node->tn_link, MIN(node->tn_size, uio->uio_resid),
|
||||
uio);
|
||||
tmpfs_set_status(node, TMPFS_NODE_ACCESSED);
|
||||
tmpfs_set_status(VFS_TO_TMPFS(vp->v_mount), node, TMPFS_NODE_ACCESSED);
|
||||
|
||||
return (error);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user