tmpfs_vnops.c (239065) | tmpfs_vnops.c (245115) |
---|---|
1/* $NetBSD: tmpfs_vnops.c,v 1.39 2007/07/23 15:41:01 jmmv Exp $ */ 2 3/*- 4 * Copyright (c) 2005, 2006 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 * tmpfs vnode interface. 35 */ 36#include <sys/cdefs.h> | 1/* $NetBSD: tmpfs_vnops.c,v 1.39 2007/07/23 15:41:01 jmmv Exp $ */ 2 3/*- 4 * Copyright (c) 2005, 2006 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 * tmpfs vnode interface. 35 */ 36#include <sys/cdefs.h> |
37__FBSDID("$FreeBSD: head/sys/fs/tmpfs/tmpfs_vnops.c 239065 2012-08-05 14:11:42Z kib $"); | 37__FBSDID("$FreeBSD: head/sys/fs/tmpfs/tmpfs_vnops.c 245115 2013-01-06 22:15:44Z gleb $"); |
38 39#include <sys/param.h> 40#include <sys/fcntl.h> 41#include <sys/lockf.h> 42#include <sys/namei.h> 43#include <sys/priv.h> 44#include <sys/proc.h> 45#include <sys/sched.h> --- 796 unchanged lines hidden (view full) --- 842 * have to change the number of hard links of the directory. */ 843 tmpfs_dir_detach(dvp, de); 844 if (v->a_cnp->cn_flags & DOWHITEOUT) 845 tmpfs_dir_whiteout_add(dvp, v->a_cnp); 846 847 /* Free the directory entry we just deleted. Note that the node 848 * referred by it will not be removed until the vnode is really 849 * reclaimed. */ | 38 39#include <sys/param.h> 40#include <sys/fcntl.h> 41#include <sys/lockf.h> 42#include <sys/namei.h> 43#include <sys/priv.h> 44#include <sys/proc.h> 45#include <sys/sched.h> --- 796 unchanged lines hidden (view full) --- 842 * have to change the number of hard links of the directory. */ 843 tmpfs_dir_detach(dvp, de); 844 if (v->a_cnp->cn_flags & DOWHITEOUT) 845 tmpfs_dir_whiteout_add(dvp, v->a_cnp); 846 847 /* Free the directory entry we just deleted. Note that the node 848 * referred by it will not be removed until the vnode is really 849 * reclaimed. */ |
850 tmpfs_free_dirent(tmp, de, TRUE); | 850 tmpfs_free_dirent(tmp, de); |
851 852 node->tn_status |= TMPFS_NODE_ACCESSED | TMPFS_NODE_CHANGED; 853 error = 0; 854 855out: 856 857 return error; 858} --- 399 unchanged lines hidden (view full) --- 1258 tdnode->tn_links++; 1259 TMPFS_NODE_UNLOCK(tdnode); 1260 1261 TMPFS_NODE_LOCK(fdnode); 1262 TMPFS_ASSERT_LOCKED(fdnode); 1263 fdnode->tn_links--; 1264 TMPFS_NODE_UNLOCK(fdnode); 1265 } | 851 852 node->tn_status |= TMPFS_NODE_ACCESSED | TMPFS_NODE_CHANGED; 853 error = 0; 854 855out: 856 857 return error; 858} --- 399 unchanged lines hidden (view full) --- 1258 tdnode->tn_links++; 1259 TMPFS_NODE_UNLOCK(tdnode); 1260 1261 TMPFS_NODE_LOCK(fdnode); 1262 TMPFS_ASSERT_LOCKED(fdnode); 1263 fdnode->tn_links--; 1264 TMPFS_NODE_UNLOCK(fdnode); 1265 } |
1266 1267 /* Do the move: just remove the entry from the source directory 1268 * and insert it into the target one. */ 1269 tmpfs_dir_detach(fdvp, de); 1270 if (fcnp->cn_flags & DOWHITEOUT) 1271 tmpfs_dir_whiteout_add(fdvp, fcnp); 1272 if (tcnp->cn_flags & ISWHITEOUT) 1273 tmpfs_dir_whiteout_remove(tdvp, tcnp); 1274 tmpfs_dir_attach(tdvp, de); | |
1275 } 1276 | 1266 } 1267 |
1268 /* Do the move: just remove the entry from the source directory 1269 * and insert it into the target one. */ 1270 tmpfs_dir_detach(fdvp, de); 1271 1272 if (fcnp->cn_flags & DOWHITEOUT) 1273 tmpfs_dir_whiteout_add(fdvp, fcnp); 1274 if (tcnp->cn_flags & ISWHITEOUT) 1275 tmpfs_dir_whiteout_remove(tdvp, tcnp); 1276 |
|
1277 /* If the name has changed, we need to make it effective by changing 1278 * it in the directory entry. */ 1279 if (newname != NULL) { 1280 MPASS(tcnp->cn_namelen <= MAXNAMLEN); 1281 | 1277 /* If the name has changed, we need to make it effective by changing 1278 * it in the directory entry. */ 1279 if (newname != NULL) { 1280 MPASS(tcnp->cn_namelen <= MAXNAMLEN); 1281 |
1282 free(de->td_name, M_TMPFSNAME); 1283 de->td_namelen = (uint16_t)tcnp->cn_namelen; 1284 memcpy(newname, tcnp->cn_nameptr, tcnp->cn_namelen); 1285 de->td_name = newname; | 1282 free(de->ud.td_name, M_TMPFSNAME); 1283 de->ud.td_name = newname; 1284 tmpfs_dirent_init(de, tcnp->cn_nameptr, tcnp->cn_namelen); |
1286 1287 fnode->tn_status |= TMPFS_NODE_CHANGED; 1288 tdnode->tn_status |= TMPFS_NODE_MODIFIED; 1289 } 1290 1291 /* If we are overwriting an entry, we have to remove the old one 1292 * from the target directory. */ 1293 if (tvp != NULL) { | 1285 1286 fnode->tn_status |= TMPFS_NODE_CHANGED; 1287 tdnode->tn_status |= TMPFS_NODE_MODIFIED; 1288 } 1289 1290 /* If we are overwriting an entry, we have to remove the old one 1291 * from the target directory. */ 1292 if (tvp != NULL) { |
1293 struct tmpfs_dirent *tde; 1294 |
|
1294 /* Remove the old entry from the target directory. */ | 1295 /* Remove the old entry from the target directory. */ |
1295 de = tmpfs_dir_lookup(tdnode, tnode, tcnp); 1296 tmpfs_dir_detach(tdvp, de); | 1296 tde = tmpfs_dir_lookup(tdnode, tnode, tcnp); 1297 tmpfs_dir_detach(tdvp, tde); |
1297 1298 /* Free the directory entry we just deleted. Note that the 1299 * node referred by it will not be removed until the vnode is 1300 * really reclaimed. */ | 1298 1299 /* Free the directory entry we just deleted. Note that the 1300 * node referred by it will not be removed until the vnode is 1301 * really reclaimed. */ |
1301 tmpfs_free_dirent(VFS_TO_TMPFS(tvp->v_mount), de, TRUE); | 1302 tmpfs_free_dirent(VFS_TO_TMPFS(tvp->v_mount), tde); |
1302 } | 1303 } |
1304 1305 tmpfs_dir_attach(tdvp, de); 1306 |
|
1303 cache_purge(fvp); 1304 if (tvp != NULL) 1305 cache_purge(tvp); 1306 1307 error = 0; 1308 1309out_locked: 1310 if (fdvp != tdvp && fdvp != tvp) --- 111 unchanged lines hidden (view full) --- 1422 TMPFS_NODE_UNLOCK(dnode); 1423 1424 cache_purge(dvp); 1425 cache_purge(vp); 1426 1427 /* Free the directory entry we just deleted. Note that the node 1428 * referred by it will not be removed until the vnode is really 1429 * reclaimed. */ | 1307 cache_purge(fvp); 1308 if (tvp != NULL) 1309 cache_purge(tvp); 1310 1311 error = 0; 1312 1313out_locked: 1314 if (fdvp != tdvp && fdvp != tvp) --- 111 unchanged lines hidden (view full) --- 1426 TMPFS_NODE_UNLOCK(dnode); 1427 1428 cache_purge(dvp); 1429 cache_purge(vp); 1430 1431 /* Free the directory entry we just deleted. Note that the node 1432 * referred by it will not be removed until the vnode is really 1433 * reclaimed. */ |
1430 tmpfs_free_dirent(tmp, de, TRUE); | 1434 tmpfs_free_dirent(tmp, de); |
1431 1432 /* Release the deleted vnode (will destroy the node, notify 1433 * interested parties and clean it from the cache). */ 1434 1435 dnode->tn_status |= TMPFS_NODE_CHANGED; 1436 tmpfs_update(dvp); 1437 1438 error = 0; --- 29 unchanged lines hidden (view full) --- 1468{ 1469 struct vnode *vp = v->a_vp; 1470 struct uio *uio = v->a_uio; 1471 int *eofflag = v->a_eofflag; 1472 u_long **cookies = v->a_cookies; 1473 int *ncookies = v->a_ncookies; 1474 1475 int error; | 1435 1436 /* Release the deleted vnode (will destroy the node, notify 1437 * interested parties and clean it from the cache). */ 1438 1439 dnode->tn_status |= TMPFS_NODE_CHANGED; 1440 tmpfs_update(dvp); 1441 1442 error = 0; --- 29 unchanged lines hidden (view full) --- 1472{ 1473 struct vnode *vp = v->a_vp; 1474 struct uio *uio = v->a_uio; 1475 int *eofflag = v->a_eofflag; 1476 u_long **cookies = v->a_cookies; 1477 int *ncookies = v->a_ncookies; 1478 1479 int error; |
1476 off_t startoff; 1477 off_t cnt = 0; | 1480 ssize_t startresid; 1481 int cnt = 0; |
1478 struct tmpfs_node *node; 1479 1480 /* This operation only makes sense on directory nodes. */ 1481 if (vp->v_type != VDIR) 1482 return ENOTDIR; 1483 1484 node = VP_TO_TMPFS_DIR(vp); 1485 | 1482 struct tmpfs_node *node; 1483 1484 /* This operation only makes sense on directory nodes. */ 1485 if (vp->v_type != VDIR) 1486 return ENOTDIR; 1487 1488 node = VP_TO_TMPFS_DIR(vp); 1489 |
1486 startoff = uio->uio_offset; | 1490 startresid = uio->uio_resid; |
1487 | 1491 |
1488 if (uio->uio_offset == TMPFS_DIRCOOKIE_DOT) { 1489 error = tmpfs_dir_getdotdent(node, uio); 1490 if (error != 0) 1491 goto outok; 1492 cnt++; | 1492 if (cookies != NULL && ncookies != NULL) { 1493 cnt = howmany(node->tn_size, sizeof(struct tmpfs_dirent)) + 2; 1494 *cookies = malloc(cnt * sizeof(**cookies), M_TEMP, M_WAITOK); 1495 *ncookies = 0; |
1493 } 1494 | 1496 } 1497 |
1495 if (uio->uio_offset == TMPFS_DIRCOOKIE_DOTDOT) { 1496 error = tmpfs_dir_getdotdotdent(node, uio); 1497 if (error != 0) 1498 goto outok; 1499 cnt++; 1500 } | 1498 if (cnt == 0) 1499 error = tmpfs_dir_getdents(node, uio, 0, NULL, NULL); 1500 else 1501 error = tmpfs_dir_getdents(node, uio, cnt, *cookies, ncookies); |
1501 | 1502 |
1502 error = tmpfs_dir_getdents(node, uio, &cnt); | 1503 if (error == EJUSTRETURN) 1504 error = (uio->uio_resid != startresid) ? 0 : EINVAL; |
1503 | 1505 |
1504outok: 1505 MPASS(error >= -1); | 1506 if (error != 0 && cnt != 0) 1507 free(*cookies, M_TEMP); |
1506 | 1508 |
1507 if (error == -1) 1508 error = (cnt != 0) ? 0 : EINVAL; 1509 | |
1510 if (eofflag != NULL) 1511 *eofflag = 1512 (error == 0 && uio->uio_offset == TMPFS_DIRCOOKIE_EOF); 1513 | 1509 if (eofflag != NULL) 1510 *eofflag = 1511 (error == 0 && uio->uio_offset == TMPFS_DIRCOOKIE_EOF); 1512 |
1514 /* Update NFS-related variables. */ 1515 if (error == 0 && cookies != NULL && ncookies != NULL) { 1516 off_t i; 1517 off_t off = startoff; 1518 struct tmpfs_dirent *de = NULL; 1519 1520 *ncookies = cnt; 1521 *cookies = malloc(cnt * sizeof(off_t), M_TEMP, M_WAITOK); 1522 1523 for (i = 0; i < cnt; i++) { 1524 MPASS(off != TMPFS_DIRCOOKIE_EOF); 1525 if (off == TMPFS_DIRCOOKIE_DOT) { 1526 off = TMPFS_DIRCOOKIE_DOTDOT; 1527 } else { 1528 if (off == TMPFS_DIRCOOKIE_DOTDOT) { 1529 de = TAILQ_FIRST(&node->tn_dir.tn_dirhead); 1530 } else if (de != NULL) { 1531 de = TAILQ_NEXT(de, td_entries); 1532 } else { 1533 de = tmpfs_dir_lookupbycookie(node, 1534 off); 1535 MPASS(de != NULL); 1536 de = TAILQ_NEXT(de, td_entries); 1537 } 1538 if (de == NULL) 1539 off = TMPFS_DIRCOOKIE_EOF; 1540 else 1541 off = tmpfs_dircookie(de); 1542 } 1543 1544 (*cookies)[i] = off; 1545 } 1546 MPASS(uio->uio_offset == off); 1547 } 1548 | |
1549 return error; 1550} 1551 1552/* --------------------------------------------------------------------- */ 1553 1554static int 1555tmpfs_readlink(struct vop_readlink_args *v) 1556{ --- 224 unchanged lines hidden --- | 1513 return error; 1514} 1515 1516/* --------------------------------------------------------------------- */ 1517 1518static int 1519tmpfs_readlink(struct vop_readlink_args *v) 1520{ --- 224 unchanged lines hidden --- |