From: Matthew Dillon Date: Sat, 19 Jul 2008 04:49:39 +0000 (+0000) Subject: HAMMER 64/Many: NFS, cross-device links, synctid X-Git-Tag: v2.1.1~858 X-Git-Url: https://gitweb.dragonflybsd.org/dragonfly.git/commitdiff_plain/f437a2abb4442a26cda39281b627477603898334 HAMMER 64/Many: NFS, cross-device links, synctid * Check for cross-device links and cross-PFS links in the link and rename code. * Update a directory's mtime when a file is created or deleted within it. (good idea anyway, also allows NFS clients to properly invalidate their directory caches). * Only lock the PFS sync-end-tid field when the HAMMER_PFSD_SLAVE flag is not set. * Clear ocp->dip->objid_cache when cleaning out the object cache. * PFS softlinks in the form @@PFS%05d are auto-expanded by HAMMER's readlink() to include a snapshot transaction id. Adjust getattr to properly set va_size (aka stat->st_size) to the length of the expanded version. This fixes NFS confusion and allows PFS's to be mounted via their softlinks. * Fix another issue where the synctid ioctl would still sometimes stall until the next filesystem sync. Reported-by: YONETANI Tomokazu --- diff --git a/sys/vfs/hammer/hammer_flusher.c b/sys/vfs/hammer/hammer_flusher.c index 89616ce895..7209e5c61f 100644 --- a/sys/vfs/hammer/hammer_flusher.c +++ b/sys/vfs/hammer/hammer_flusher.c @@ -31,7 +31,7 @@ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $DragonFly: src/sys/vfs/hammer/hammer_flusher.c,v 1.43 2008/07/18 00:19:53 dillon Exp $ + * $DragonFly: src/sys/vfs/hammer/hammer_flusher.c,v 1.44 2008/07/19 04:49:39 dillon Exp $ */ /* * HAMMER dependancy flusher thread @@ -75,8 +75,7 @@ hammer_flusher_sync(hammer_mount_t hmp) int seq; seq = hammer_flusher_async(hmp, NULL); - while ((int)(seq - hmp->flusher.done) > 0) - tsleep(&hmp->flusher.done, 0, "hmrfls", 0); + hammer_flusher_wait(hmp, seq); } /* @@ -121,10 +120,18 @@ hammer_flusher_async_one(hammer_mount_t hmp) return(seq); } +/* + * Wait for the flusher to get to the specified sequence number. + * Signal the flusher as often as necessary to keep it going. + */ void hammer_flusher_wait(hammer_mount_t hmp, int seq) { while ((int)(seq - hmp->flusher.done) > 0) { + if (hmp->flusher.act != seq) { + if (hmp->flusher.signal++ == 0) + wakeup(&hmp->flusher.signal); + } tsleep(&hmp->flusher.done, 0, "hmrfls", 0); } } diff --git a/sys/vfs/hammer/hammer_object.c b/sys/vfs/hammer/hammer_object.c index 17b3fedca0..2f33e74c61 100644 --- a/sys/vfs/hammer/hammer_object.c +++ b/sys/vfs/hammer/hammer_object.c @@ -31,7 +31,7 @@ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $DragonFly: src/sys/vfs/hammer/hammer_object.c,v 1.91 2008/07/18 00:19:53 dillon Exp $ + * $DragonFly: src/sys/vfs/hammer/hammer_object.c,v 1.92 2008/07/19 04:49:39 dillon Exp $ */ #include "hammer.h" @@ -674,6 +674,10 @@ hammer_ip_add_directory(struct hammer_transaction *trans, ip->flush_state = HAMMER_FST_SETUP; } error = hammer_mem_add(record); + if (error == 0) { + dip->ino_data.mtime = trans->time; + hammer_modify_inode(dip, HAMMER_INODE_MTIME); + } failed: hammer_done_cursor(&cursor); return(error); @@ -769,6 +773,8 @@ hammer_ip_del_directory(struct hammer_transaction *trans, hammer_inode_unloadable_check(ip, 1); hammer_flush_inode(ip, 0); } + dip->ino_data.mtime = trans->time; + hammer_modify_inode(dip, HAMMER_INODE_MTIME); } return(error); diff --git a/sys/vfs/hammer/hammer_pfs.c b/sys/vfs/hammer/hammer_pfs.c index 6402a18792..bb1cc15a7f 100644 --- a/sys/vfs/hammer/hammer_pfs.c +++ b/sys/vfs/hammer/hammer_pfs.c @@ -31,7 +31,7 @@ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $DragonFly: src/sys/vfs/hammer/hammer_pfs.c,v 1.2 2008/07/14 20:27:54 dillon Exp $ + * $DragonFly: src/sys/vfs/hammer/hammer_pfs.c,v 1.3 2008/07/19 04:49:39 dillon Exp $ */ /* * HAMMER PFS ioctls - Manage pseudo-fs configurations @@ -77,7 +77,7 @@ hammer_ioc_get_pseudofs(hammer_transaction_t trans, hammer_inode_t ip, * rather then the mirroring code, and will always track the * real HAMMER filesystem. */ - if (pfsm->pfsd.master_id >= 0) + if ((pfsm->pfsd.mirror_flags & HAMMER_PFSD_SLAVE) == 0) pfsm->pfsd.sync_end_tid = trans->rootvol->ondisk->vol0_next_tid; /* diff --git a/sys/vfs/hammer/hammer_transaction.c b/sys/vfs/hammer/hammer_transaction.c index ef4e1ed513..500a7f8ec7 100644 --- a/sys/vfs/hammer/hammer_transaction.c +++ b/sys/vfs/hammer/hammer_transaction.c @@ -31,7 +31,7 @@ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $DragonFly: src/sys/vfs/hammer/hammer_transaction.c,v 1.22 2008/06/26 04:06:23 dillon Exp $ + * $DragonFly: src/sys/vfs/hammer/hammer_transaction.c,v 1.23 2008/07/19 04:49:39 dillon Exp $ */ #include "hammer.h" @@ -227,6 +227,8 @@ hammer_destroy_objid_cache(hammer_mount_t hmp) while ((ocp = TAILQ_FIRST(&hmp->objid_cache_list)) != NULL) { TAILQ_REMOVE(&hmp->objid_cache_list, ocp, entry); + if (ocp->dip) + ocp->dip->objid_cache = NULL; kfree(ocp, M_HAMMER); } } diff --git a/sys/vfs/hammer/hammer_vnops.c b/sys/vfs/hammer/hammer_vnops.c index c6624cd2a0..31fa543afb 100644 --- a/sys/vfs/hammer/hammer_vnops.c +++ b/sys/vfs/hammer/hammer_vnops.c @@ -31,7 +31,7 @@ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $DragonFly: src/sys/vfs/hammer/hammer_vnops.c,v 1.92 2008/07/14 20:27:54 dillon Exp $ + * $DragonFly: src/sys/vfs/hammer/hammer_vnops.c,v 1.93 2008/07/19 04:49:39 dillon Exp $ */ #include @@ -687,6 +687,18 @@ hammer_vop_getattr(struct vop_getattr_args *ap) vap->va_rminor = 0; vap->va_size = ip->ino_data.size; + /* + * Special case for @@PFS softlinks. The actual size of the + * expanded softlink is "@@0x%016llx:%05d" == 26 bytes. + */ + if (ip->ino_data.obj_type == HAMMER_OBJTYPE_SOFTLINK && + ip->ino_data.size == 10 && + ip->obj_asof == HAMMER_MAX_TID && + ip->obj_localization == 0 && + strncmp(ip->ino_data.ext.symlink, "@@PFS", 5) == 0) { + vap->va_size = 26; + } + /* * We must provide a consistent atime and mtime for snapshots * so people can do a 'tar cf - ... | md5' on them and get @@ -985,10 +997,16 @@ hammer_vop_nlink(struct vop_nlink_args *ap) struct nchandle *nch; int error; + if (ap->a_dvp->v_mount != ap->a_vp->v_mount) + return(EXDEV); + nch = ap->a_nch; dip = VTOI(ap->a_dvp); ip = VTOI(ap->a_vp); + if (dip->obj_localization != ip->obj_localization) + return(EXDEV); + if (dip->flags & HAMMER_INODE_RO) return (EROFS); if (ip->flags & HAMMER_INODE_RO) @@ -1496,6 +1514,11 @@ hammer_vop_nrename(struct vop_nrename_args *ap) int64_t namekey; int nlen, error; + if (ap->a_fdvp->v_mount != ap->a_tdvp->v_mount) + return(EXDEV); + if (ap->a_fdvp->v_mount != ap->a_fnch->ncp->nc_vp->v_mount) + return(EXDEV); + fdip = VTOI(ap->a_fdvp); tdip = VTOI(ap->a_tdvp); fncp = ap->a_fnch->ncp; @@ -1503,6 +1526,11 @@ hammer_vop_nrename(struct vop_nrename_args *ap) ip = VTOI(fncp->nc_vp); KKASSERT(ip != NULL); + if (fdip->obj_localization != tdip->obj_localization) + return(EXDEV); + if (fdip->obj_localization != ip->obj_localization) + return(EXDEV); + if (fdip->flags & HAMMER_INODE_RO) return (EROFS); if (tdip->flags & HAMMER_INODE_RO)