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 --- |