summaryrefslogtreecommitdiffstats
path: root/sys/gnu
diff options
context:
space:
mode:
authortegge <tegge@FreeBSD.org>2007-03-13 01:50:27 +0000
committertegge <tegge@FreeBSD.org>2007-03-13 01:50:27 +0000
commit214bc5723c38739a6060170f2c421e59d87b2c82 (patch)
tree6dca3f2c99e6dcb6402e1486118e56eb8d5e871b /sys/gnu
parent76cbc46fe707603a2b4dde9cc8398128868b56ee (diff)
downloadFreeBSD-src-214bc5723c38739a6060170f2c421e59d87b2c82.zip
FreeBSD-src-214bc5723c38739a6060170f2c421e59d87b2c82.tar.gz
Make insmntque() externally visibile and allow it to fail (e.g. during
late stages of unmount). On failure, the vnode is recycled. Add insmntque1(), to allow for file system specific cleanup when recycling vnode on failure. Change getnewvnode() to no longer call insmntque(). Previously, embryonic vnodes were put onto the list of vnode belonging to a file system, which is unsafe for a file system marked MPSAFE. Change vfs_hash_insert() to no longer lock the vnode. The caller now has that responsibility. Change most file systems to lock the vnode and call insmntque() or insmntque1() after a new vnode has been sufficiently setup. Handle failed insmntque*() calls by propagating errors to callers, possibly after some file system specific cleanup. Approved by: re (kensmith) Reviewed by: kib In collaboration with: kib
Diffstat (limited to 'sys/gnu')
-rw-r--r--sys/gnu/fs/ext2fs/ext2_vfsops.c13
-rw-r--r--sys/gnu/fs/reiserfs/reiserfs_inode.c8
-rw-r--r--sys/gnu/fs/xfs/FreeBSD/xfs_freebsd_iget.c5
3 files changed, 24 insertions, 2 deletions
diff --git a/sys/gnu/fs/ext2fs/ext2_vfsops.c b/sys/gnu/fs/ext2fs/ext2_vfsops.c
index 7abcb7e..3a362a4 100644
--- a/sys/gnu/fs/ext2fs/ext2_vfsops.c
+++ b/sys/gnu/fs/ext2fs/ext2_vfsops.c
@@ -954,8 +954,10 @@ ext2_vget(mp, ino, flags, vpp)
struct cdev *dev;
int i, error;
int used_blocks;
+ struct thread *td;
- error = vfs_hash_get(mp, ino, flags, curthread, vpp, NULL, NULL);
+ td = curthread;
+ error = vfs_hash_get(mp, ino, flags, td, vpp, NULL, NULL);
if (error || *vpp != NULL)
return (error);
@@ -982,7 +984,14 @@ ext2_vget(mp, ino, flags, vpp)
ip->i_e2fs = fs = ump->um_e2fs;
ip->i_number = ino;
- error = vfs_hash_insert(vp, ino, flags, curthread, vpp, NULL, NULL);
+ lockmgr(vp->v_vnlock, LK_EXCLUSIVE, NULL, td);
+ error = insmntque(vp, mp);
+ if (error != 0) {
+ free(ip, M_EXT2NODE);
+ *vpp = NULL;
+ return (error);
+ }
+ error = vfs_hash_insert(vp, ino, flags, td, vpp, NULL, NULL);
if (error || *vpp != NULL)
return (error);
diff --git a/sys/gnu/fs/reiserfs/reiserfs_inode.c b/sys/gnu/fs/reiserfs/reiserfs_inode.c
index ece4a75..3eddd84 100644
--- a/sys/gnu/fs/reiserfs/reiserfs_inode.c
+++ b/sys/gnu/fs/reiserfs/reiserfs_inode.c
@@ -815,6 +815,14 @@ reiserfs_iget(
lockmgr(vp->v_vnlock, LK_EXCLUSIVE, (struct mtx *)0, td);
#endif
+ lockmgr(vp->v_vnlock, LK_EXCLUSIVE, NULL, td);
+ error = insmntque(vp, mp);
+ if (error != 0) {
+ free(ip, M_REISERFSNODE);
+ *vpp = NULL;
+ reiserfs_log(LOG_DEBUG, "insmntque FAILED\n");
+ return (error);
+ }
error = vfs_hash_insert(vp, key->on_disk_key.k_objectid, flags,
td, vpp, NULL, NULL);
if (error || *vpp != NULL)
diff --git a/sys/gnu/fs/xfs/FreeBSD/xfs_freebsd_iget.c b/sys/gnu/fs/xfs/FreeBSD/xfs_freebsd_iget.c
index de5284c..7145b94 100644
--- a/sys/gnu/fs/xfs/FreeBSD/xfs_freebsd_iget.c
+++ b/sys/gnu/fs/xfs/FreeBSD/xfs_freebsd_iget.c
@@ -391,6 +391,11 @@ xfs_vn_allocate(xfs_mount_t *mp, xfs_inode_t *ip, struct xfs_vnode **vpp)
vp->v_vnlock->lk_flags |= LK_CANRECURSE;
vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, curthread);
+ error = insmntque(vp, XVFSTOMNT(XFS_MTOVFS(mp)));
+ if (error != 0) {
+ kmem_free(vdata, sizeof(*vdata));
+ return (error);
+ }
vp->v_data = (void *)vdata;
vdata->v_number= 0;
OpenPOWER on IntegriCloud