Deleted Added
full compact
tmpfs_subr.c (341074) tmpfs_subr.c (346286)
1/* $NetBSD: tmpfs_subr.c,v 1.35 2007/07/09 21:10:50 ad Exp $ */
2
3/*-
4 * Copyright (c) 2005 The NetBSD Foundation, Inc.
5 * All rights reserved.
6 *
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Julio M. Merino Vidal, developed as part of Google's Summer of Code

--- 20 unchanged lines hidden (view full) ---

29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 * POSSIBILITY OF SUCH DAMAGE.
31 */
32
33/*
34 * Efficient memory file system supporting functions.
35 */
36#include <sys/cdefs.h>
1/* $NetBSD: tmpfs_subr.c,v 1.35 2007/07/09 21:10:50 ad Exp $ */
2
3/*-
4 * Copyright (c) 2005 The NetBSD Foundation, Inc.
5 * All rights reserved.
6 *
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Julio M. Merino Vidal, developed as part of Google's Summer of Code

--- 20 unchanged lines hidden (view full) ---

29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 * POSSIBILITY OF SUCH DAMAGE.
31 */
32
33/*
34 * Efficient memory file system supporting functions.
35 */
36#include <sys/cdefs.h>
37__FBSDID("$FreeBSD: stable/11/sys/fs/tmpfs/tmpfs_subr.c 341074 2018-11-27 16:51:18Z markj $");
37__FBSDID("$FreeBSD: stable/11/sys/fs/tmpfs/tmpfs_subr.c 346286 2019-04-16 17:43:14Z kib $");
38
39#include <sys/param.h>
40#include <sys/systm.h>
41#include <sys/dirent.h>
42#include <sys/fnv_hash.h>
43#include <sys/lock.h>
44#include <sys/namei.h>
45#include <sys/priv.h>

--- 162 unchanged lines hidden (view full) ---

208 * cannot be destroyed until node construction is
209 * finished and the parent vnode unlocked.
210 *
211 * Tmpfs does not need to instantiate new nodes during
212 * unmount.
213 */
214 return (EBUSY);
215 }
38
39#include <sys/param.h>
40#include <sys/systm.h>
41#include <sys/dirent.h>
42#include <sys/fnv_hash.h>
43#include <sys/lock.h>
44#include <sys/namei.h>
45#include <sys/priv.h>

--- 162 unchanged lines hidden (view full) ---

208 * cannot be destroyed until node construction is
209 * finished and the parent vnode unlocked.
210 *
211 * Tmpfs does not need to instantiate new nodes during
212 * unmount.
213 */
214 return (EBUSY);
215 }
216 if ((mp->mnt_kern_flag & MNT_RDONLY) != 0)
217 return (EROFS);
216
217 nnode = (struct tmpfs_node *)uma_zalloc_arg(tmp->tm_node_pool, tmp,
218 M_WAITOK);
219
220 /* Generic initialization. */
221 nnode->tn_type = type;
222 vfs_timestamp(&nnode->tn_atime);
223 nnode->tn_birthtime = nnode->tn_ctime = nnode->tn_mtime =

--- 875 unchanged lines hidden (view full) ---

1099/*
1100 * Helper function for tmpfs_readdir. Creates a '.' entry for the given
1101 * directory and returns it in the uio space. The function returns 0
1102 * on success, -1 if there was not enough space in the uio structure to
1103 * hold the directory entry or an appropriate error code if another
1104 * error happens.
1105 */
1106static int
218
219 nnode = (struct tmpfs_node *)uma_zalloc_arg(tmp->tm_node_pool, tmp,
220 M_WAITOK);
221
222 /* Generic initialization. */
223 nnode->tn_type = type;
224 vfs_timestamp(&nnode->tn_atime);
225 nnode->tn_birthtime = nnode->tn_ctime = nnode->tn_mtime =

--- 875 unchanged lines hidden (view full) ---

1101/*
1102 * Helper function for tmpfs_readdir. Creates a '.' entry for the given
1103 * directory and returns it in the uio space. The function returns 0
1104 * on success, -1 if there was not enough space in the uio structure to
1105 * hold the directory entry or an appropriate error code if another
1106 * error happens.
1107 */
1108static int
1107tmpfs_dir_getdotdent(struct tmpfs_node *node, struct uio *uio)
1109tmpfs_dir_getdotdent(struct tmpfs_mount *tm, struct tmpfs_node *node,
1110 struct uio *uio)
1108{
1109 int error;
1110 struct dirent dent;
1111
1112 TMPFS_VALIDATE_DIR(node);
1113 MPASS(uio->uio_offset == TMPFS_DIRCOOKIE_DOT);
1114
1115 dent.d_fileno = node->tn_id;
1116 dent.d_type = DT_DIR;
1117 dent.d_namlen = 1;
1118 dent.d_name[0] = '.';
1119 dent.d_reclen = GENERIC_DIRSIZ(&dent);
1120 dirent_terminate(&dent);
1121
1122 if (dent.d_reclen > uio->uio_resid)
1123 error = EJUSTRETURN;
1124 else
1125 error = uiomove(&dent, dent.d_reclen, uio);
1126
1111{
1112 int error;
1113 struct dirent dent;
1114
1115 TMPFS_VALIDATE_DIR(node);
1116 MPASS(uio->uio_offset == TMPFS_DIRCOOKIE_DOT);
1117
1118 dent.d_fileno = node->tn_id;
1119 dent.d_type = DT_DIR;
1120 dent.d_namlen = 1;
1121 dent.d_name[0] = '.';
1122 dent.d_reclen = GENERIC_DIRSIZ(&dent);
1123 dirent_terminate(&dent);
1124
1125 if (dent.d_reclen > uio->uio_resid)
1126 error = EJUSTRETURN;
1127 else
1128 error = uiomove(&dent, dent.d_reclen, uio);
1129
1127 tmpfs_set_status(node, TMPFS_NODE_ACCESSED);
1130 tmpfs_set_status(tm, node, TMPFS_NODE_ACCESSED);
1128
1129 return (error);
1130}
1131
1132/*
1133 * Helper function for tmpfs_readdir. Creates a '..' entry for the given
1134 * directory and returns it in the uio space. The function returns 0
1135 * on success, -1 if there was not enough space in the uio structure to
1136 * hold the directory entry or an appropriate error code if another
1137 * error happens.
1138 */
1139static int
1131
1132 return (error);
1133}
1134
1135/*
1136 * Helper function for tmpfs_readdir. Creates a '..' entry for the given
1137 * directory and returns it in the uio space. The function returns 0
1138 * on success, -1 if there was not enough space in the uio structure to
1139 * hold the directory entry or an appropriate error code if another
1140 * error happens.
1141 */
1142static int
1140tmpfs_dir_getdotdotdent(struct tmpfs_node *node, struct uio *uio)
1143tmpfs_dir_getdotdotdent(struct tmpfs_mount *tm, struct tmpfs_node *node,
1144 struct uio *uio)
1141{
1142 int error;
1143 struct dirent dent;
1144
1145 TMPFS_VALIDATE_DIR(node);
1146 MPASS(uio->uio_offset == TMPFS_DIRCOOKIE_DOTDOT);
1147
1148 /*

--- 14 unchanged lines hidden (view full) ---

1163 dent.d_reclen = GENERIC_DIRSIZ(&dent);
1164 dirent_terminate(&dent);
1165
1166 if (dent.d_reclen > uio->uio_resid)
1167 error = EJUSTRETURN;
1168 else
1169 error = uiomove(&dent, dent.d_reclen, uio);
1170
1145{
1146 int error;
1147 struct dirent dent;
1148
1149 TMPFS_VALIDATE_DIR(node);
1150 MPASS(uio->uio_offset == TMPFS_DIRCOOKIE_DOTDOT);
1151
1152 /*

--- 14 unchanged lines hidden (view full) ---

1167 dent.d_reclen = GENERIC_DIRSIZ(&dent);
1168 dirent_terminate(&dent);
1169
1170 if (dent.d_reclen > uio->uio_resid)
1171 error = EJUSTRETURN;
1172 else
1173 error = uiomove(&dent, dent.d_reclen, uio);
1174
1171 tmpfs_set_status(node, TMPFS_NODE_ACCESSED);
1175 tmpfs_set_status(tm, node, TMPFS_NODE_ACCESSED);
1172
1173 return (error);
1174}
1175
1176/*
1177 * Helper function for tmpfs_readdir. Returns as much directory entries
1178 * as can fit in the uio space. The read starts at uio->uio_offset.
1179 * The function returns 0 on success, -1 if there was not enough space
1180 * in the uio structure to hold the directory entry or an appropriate
1181 * error code if another error happens.
1182 */
1183int
1176
1177 return (error);
1178}
1179
1180/*
1181 * Helper function for tmpfs_readdir. Returns as much directory entries
1182 * as can fit in the uio space. The read starts at uio->uio_offset.
1183 * The function returns 0 on success, -1 if there was not enough space
1184 * in the uio structure to hold the directory entry or an appropriate
1185 * error code if another error happens.
1186 */
1187int
1184tmpfs_dir_getdents(struct tmpfs_node *node, struct uio *uio, int maxcookies,
1185 u_long *cookies, int *ncookies)
1188tmpfs_dir_getdents(struct tmpfs_mount *tm, struct tmpfs_node *node,
1189 struct uio *uio, int maxcookies, u_long *cookies, int *ncookies)
1186{
1187 struct tmpfs_dir_cursor dc;
1188 struct tmpfs_dirent *de;
1189 off_t off;
1190 int error;
1191
1192 TMPFS_VALIDATE_DIR(node);
1193

--- 4 unchanged lines hidden (view full) ---

1198 * 0 will lookup both '.' and '..', and then the first real entry,
1199 * or EOF if there are none. Then find all entries for the dir that
1200 * fit into the buffer. Once no more entries are found (de == NULL),
1201 * the offset is set to TMPFS_DIRCOOKIE_EOF, which will cause the next
1202 * call to return 0.
1203 */
1204 switch (uio->uio_offset) {
1205 case TMPFS_DIRCOOKIE_DOT:
1190{
1191 struct tmpfs_dir_cursor dc;
1192 struct tmpfs_dirent *de;
1193 off_t off;
1194 int error;
1195
1196 TMPFS_VALIDATE_DIR(node);
1197

--- 4 unchanged lines hidden (view full) ---

1202 * 0 will lookup both '.' and '..', and then the first real entry,
1203 * or EOF if there are none. Then find all entries for the dir that
1204 * fit into the buffer. Once no more entries are found (de == NULL),
1205 * the offset is set to TMPFS_DIRCOOKIE_EOF, which will cause the next
1206 * call to return 0.
1207 */
1208 switch (uio->uio_offset) {
1209 case TMPFS_DIRCOOKIE_DOT:
1206 error = tmpfs_dir_getdotdent(node, uio);
1210 error = tmpfs_dir_getdotdent(tm, node, uio);
1207 if (error != 0)
1208 return (error);
1209 uio->uio_offset = TMPFS_DIRCOOKIE_DOTDOT;
1210 if (cookies != NULL)
1211 cookies[(*ncookies)++] = off = uio->uio_offset;
1212 /* FALLTHROUGH */
1213 case TMPFS_DIRCOOKIE_DOTDOT:
1211 if (error != 0)
1212 return (error);
1213 uio->uio_offset = TMPFS_DIRCOOKIE_DOTDOT;
1214 if (cookies != NULL)
1215 cookies[(*ncookies)++] = off = uio->uio_offset;
1216 /* FALLTHROUGH */
1217 case TMPFS_DIRCOOKIE_DOTDOT:
1214 error = tmpfs_dir_getdotdotdent(node, uio);
1218 error = tmpfs_dir_getdotdotdent(tm, node, uio);
1215 if (error != 0)
1216 return (error);
1217 de = tmpfs_dir_first(node, &dc);
1218 uio->uio_offset = tmpfs_dirent_cookie(de);
1219 if (cookies != NULL)
1220 cookies[(*ncookies)++] = off = uio->uio_offset;
1221 /* EOF. */
1222 if (de == NULL)

--- 85 unchanged lines hidden (view full) ---

1308 if (cookies == NULL)
1309 off = tmpfs_dirent_cookie(de);
1310
1311 /* Update the offset and cache. */
1312 uio->uio_offset = off;
1313 node->tn_dir.tn_readdir_lastn = off;
1314 node->tn_dir.tn_readdir_lastp = de;
1315
1219 if (error != 0)
1220 return (error);
1221 de = tmpfs_dir_first(node, &dc);
1222 uio->uio_offset = tmpfs_dirent_cookie(de);
1223 if (cookies != NULL)
1224 cookies[(*ncookies)++] = off = uio->uio_offset;
1225 /* EOF. */
1226 if (de == NULL)

--- 85 unchanged lines hidden (view full) ---

1312 if (cookies == NULL)
1313 off = tmpfs_dirent_cookie(de);
1314
1315 /* Update the offset and cache. */
1316 uio->uio_offset = off;
1317 node->tn_dir.tn_readdir_lastn = off;
1318 node->tn_dir.tn_readdir_lastp = de;
1319
1316 tmpfs_set_status(node, TMPFS_NODE_ACCESSED);
1320 tmpfs_set_status(tm, node, TMPFS_NODE_ACCESSED);
1317 return error;
1318}
1319
1320int
1321tmpfs_dir_whiteout_add(struct vnode *dvp, struct componentname *cnp)
1322{
1323 struct tmpfs_dirent *de;
1324 int error;

--- 430 unchanged lines hidden (view full) ---

1755 if (vap->va_birthtime.tv_sec != VNOVAL)
1756 node->tn_birthtime = vap->va_birthtime;
1757 ASSERT_VOP_ELOCKED(vp, "chtimes2");
1758
1759 return (0);
1760}
1761
1762void
1321 return error;
1322}
1323
1324int
1325tmpfs_dir_whiteout_add(struct vnode *dvp, struct componentname *cnp)
1326{
1327 struct tmpfs_dirent *de;
1328 int error;

--- 430 unchanged lines hidden (view full) ---

1759 if (vap->va_birthtime.tv_sec != VNOVAL)
1760 node->tn_birthtime = vap->va_birthtime;
1761 ASSERT_VOP_ELOCKED(vp, "chtimes2");
1762
1763 return (0);
1764}
1765
1766void
1763tmpfs_set_status(struct tmpfs_node *node, int status)
1767tmpfs_set_status(struct tmpfs_mount *tm, struct tmpfs_node *node, int status)
1764{
1765
1768{
1769
1766 if ((node->tn_status & status) == status)
1770 if ((node->tn_status & status) == status || tm->tm_ronly)
1767 return;
1768 TMPFS_NODE_LOCK(node);
1769 node->tn_status |= status;
1770 TMPFS_NODE_UNLOCK(node);
1771}
1772
1773/* Sync timestamps */
1774void

--- 84 unchanged lines hidden ---
1771 return;
1772 TMPFS_NODE_LOCK(node);
1773 node->tn_status |= status;
1774 TMPFS_NODE_UNLOCK(node);
1775}
1776
1777/* Sync timestamps */
1778void

--- 84 unchanged lines hidden ---