/* * Called for fsync(), and also on filesystem unmount, global sync(), * and some other cases. */ static int sfs_fsync(struct vnode *v) { struct sfs_vnode *sv = v->vn_data; return sfs_sync_inode(sv); }
/* * Called for fsync(), and also on filesystem unmount, global sync(), * and some other cases. */ static int sfs_fsync(struct vnode *v) { struct sfs_vnode *sv = v->vn_data; int result; vfs_biglock_acquire(); result = sfs_sync_inode(sv); vfs_biglock_release(); return result; }
/* * Called when the vnode refcount (in-memory usage count) hits zero. * * This function should try to avoid returning errors other than EBUSY. */ static int sfs_reclaim(struct vnode *v) { struct sfs_vnode *sv = v->vn_data; struct sfs_fs *sfs = v->vn_fs->fs_data; int ix, i, num, result; lock_acquire(sfs->sfs_vnodes_lock); /* * Make sure someone else hasn't picked up the vnode since the * decision was made to reclaim it. (You must also synchronize * this with sfs_loadvnode.) */ lock_acquire(v->vn_countlock); if (v->vn_refcount != 1) { /* consume the reference VOP_DECREF gave us */ assert(v->vn_refcount>1); v->vn_refcount--; lock_release(v->vn_countlock); lock_release(sfs->sfs_vnodes_lock); return EBUSY; } lock_release(v->vn_countlock); /* If there are no on-disk references to the file either, erase it. */ if (sv->sv_i.sfi_linkcount==0 && sv->sv_i.sfi_type==SFS_TYPE_FILE) { /* * VOP_TRUNCATE doesn't work on directories, which is why I added * the second requirement to the above if statement. */ result = VOP_TRUNCATE(&sv->sv_v, 0); if (result) { lock_release(sfs->sfs_vnodes_lock); return result; } } /* Sync the inode to disk */ result = sfs_sync_inode(sv); if (result) { lock_release(sfs->sfs_vnodes_lock); return result; } /* If there are no on-disk references, discard the inode */ if (sv->sv_i.sfi_linkcount==0) { sfs_bfree(sfs, sv->sv_ino); } /* Remove the vnode structure from the table in the struct sfs_fs. */ ix = -1; num = array_getnum(sfs->sfs_vnodes); for (i=0; i<num; i++) { struct sfs_vnode *sv2 = array_getguy(sfs->sfs_vnodes, i); if (sv2==sv) { ix = i; break; } } if (ix<0) { panic("sfs: reclaim vnode %u not in vnode pool\n", sv->sv_ino); } array_remove(sfs->sfs_vnodes, ix); VOP_KILL(&sv->sv_v); /* Release the storage for the vnode structure itself. */ kfree(sv); lock_release(sfs->sfs_vnodes_lock); /* Done */ return 0; }
/* * Called when the vnode refcount (in-memory usage count) hits zero. * * This function should try to avoid returning errors other than EBUSY. */ static int sfs_reclaim(struct vnode *v) { struct sfs_vnode *sv = v->vn_data; struct sfs_fs *sfs = v->vn_fs->fs_data; unsigned ix, i, num; int result; vfs_biglock_acquire(); /* * Make sure someone else hasn't picked up the vnode since the * decision was made to reclaim it. (You must also synchronize * this with sfs_loadvnode.) */ if (v->vn_refcount != 1) { /* consume the reference VOP_DECREF gave us */ KASSERT(v->vn_refcount>1); v->vn_refcount--; vfs_biglock_release(); return EBUSY; } /* If there are no on-disk references to the file either, erase it. */ if (sv->sv_i.sfi_linkcount==0) { result = VOP_TRUNCATE(&sv->sv_v, 0); if (result) { vfs_biglock_release(); return result; } } /* Sync the inode to disk */ result = sfs_sync_inode(sv); if (result) { vfs_biglock_release(); return result; } /* If there are no on-disk references, discard the inode */ if (sv->sv_i.sfi_linkcount==0) { sfs_bfree(sfs, sv->sv_ino); } /* Remove the vnode structure from the table in the struct sfs_fs. */ num = vnodearray_num(sfs->sfs_vnodes); ix = num; for (i=0; i<num; i++) { struct vnode *v2 = vnodearray_get(sfs->sfs_vnodes, i); struct sfs_vnode *sv2 = v2->vn_data; if (sv2 == sv) { ix = i; break; } } if (ix == num) { panic("sfs: reclaim vnode %u not in vnode pool\n", sv->sv_ino); } vnodearray_remove(sfs->sfs_vnodes, ix); VOP_CLEANUP(&sv->sv_v); vfs_biglock_release(); /* Release the storage for the vnode structure itself. */ kfree(sv); /* Done */ return 0; }