X-Git-Url: https://git.camperquake.de/gitweb.cgi?a=blobdiff_plain;f=module%2Fzfs%2Fzfs_vfsops.c;h=8a82d9d4b226ecbe4514545b5f95145977a04cf0;hb=e30c0ada6d0174e044b96fbedf5946c3be66e956;hp=1763d171a06ddf9f7d15f99a73b2c0a0712c037f;hpb=3558fd73b5d863304102f6745c26e0b592aca60a;p=zfs.git diff --git a/module/zfs/zfs_vfsops.c b/module/zfs/zfs_vfsops.c index 1763d17..8a82d9d 100644 --- a/module/zfs/zfs_vfsops.c +++ b/module/zfs/zfs_vfsops.c @@ -69,8 +69,10 @@ /*ARGSUSED*/ int -zfs_sync(zfs_sb_t *zsb, short flag, cred_t *cr) +zfs_sync(struct super_block *sb, int wait, cred_t *cr) { + zfs_sb_t *zsb = sb->s_fs_info; + /* * Data integrity is job one. We don't want a compromised kernel * writing to the storage pool, so we never sync during panic. @@ -78,6 +80,13 @@ zfs_sync(zfs_sb_t *zsb, short flag, cred_t *cr) if (unlikely(oops_in_progress)) return (0); + /* + * Semantically, the only requirement is that the sync be initiated. + * The DMU syncs out txgs frequently, so there's nothing to do. + */ + if (!wait) + return (0); + if (zsb != NULL) { /* * Sync a specific filesystem. @@ -87,19 +96,14 @@ zfs_sync(zfs_sb_t *zsb, short flag, cred_t *cr) ZFS_ENTER(zsb); dp = dmu_objset_pool(zsb->z_os); -#ifdef HAVE_SHUTDOWN /* * If the system is shutting down, then skip any * filesystems which may exist on a suspended pool. - * - * XXX: This can be implemented using the Linux reboot - * notifiers: {un}register_reboot_notifier(). */ - if (sys_shutdown && spa_suspended(dp->dp_spa)) { + if (spa_suspended(dp->dp_spa)) { ZFS_EXIT(zsb); return (0); } -#endif /* HAVE_SHUTDOWN */ if (zsb->z_log != NULL) zil_commit(zsb->z_log, 0); @@ -997,11 +1001,15 @@ zfs_statvfs(struct dentry *dentry, struct kstatfs *statp) &refdbytes, &availbytes, &usedobjs, &availobjs); /* - * The underlying storage pool actually uses multiple block sizes. - * We report the fragsize as the smallest block size we support, - * and we report our blocksize as the filesystem's maximum blocksize. + * The underlying storage pool actually uses multiple block + * size. Under Solaris frsize (fragment size) is reported as + * the smallest block size we support, and bsize (block size) + * as the filesystem's maximum block size. Unfortunately, + * under Linux the fragment size and block size are often used + * interchangeably. Thus we are forced to report both of them + * as the filesystem's maximum block size. */ - statp->f_frsize = 1UL << SPA_MINBLOCKSHIFT; + statp->f_frsize = zsb->z_max_blksz; statp->f_bsize = zsb->z_max_blksz; bshift = fls(statp->f_bsize) - 1; @@ -1025,7 +1033,7 @@ zfs_statvfs(struct dentry *dentry, struct kstatfs *statp) */ statp->f_ffree = MIN(availobjs, statp->f_bfree); statp->f_files = statp->f_ffree + usedobjs; - statp->f_fsid.val[0] = 0; /* XXX: Map up some unique ID */ + statp->f_fsid.val[0] = dentry->d_sb->s_dev; statp->f_fsid.val[1] = 0; statp->f_type = ZFS_SUPER_MAGIC; statp->f_namelen = ZFS_MAXNAMELEN; @@ -1071,17 +1079,17 @@ zfsvfs_teardown(zfs_sb_t *zsb, boolean_t unmounting) rrw_enter(&zsb->z_teardown_lock, RW_WRITER, FTAG); -#ifdef HAVE_DNLC if (!unmounting) { /* - * We purge the parent filesystem's vfsp as the parent - * filesystem and all of its snapshots have their vnode's - * v_vfsp set to the parent's filesystem's vfsp. Note, - * 'z_parent' is self referential for non-snapshots. + * We purge the parent filesystem's super block as the + * parent filesystem and all of its snapshots have their + * inode's super block set to the parent's filesystem's + * super block. Note, 'z_parent' is self referential + * for non-snapshots. */ - (void) dnlc_purge_vfsp(zsb->z_parent->z_vfs, 0); + shrink_dcache_sb(zsb->z_parent->z_sb); + (void) spl_invalidate_inodes(zsb->z_parent->z_sb, 0); } -#endif /* HAVE_DNLC */ /* * Close the zil. NB: Can't close the zil while zfs_inactive @@ -1284,6 +1292,46 @@ zfs_umount(struct super_block *sb) EXPORT_SYMBOL(zfs_umount); int +zfs_remount(struct super_block *sb, int *flags, char *data) +{ + zfs_sb_t *zsb = sb->s_fs_info; + boolean_t readonly = B_FALSE; + boolean_t setuid = B_TRUE; + boolean_t exec = B_TRUE; + boolean_t devices = B_TRUE; + boolean_t atime = B_TRUE; + + if (*flags & MS_RDONLY) + readonly = B_TRUE; + + if (*flags & MS_NOSUID) { + devices = B_FALSE; + setuid = B_FALSE; + } else { + if (*flags & MS_NODEV) + devices = B_FALSE; + } + + if (*flags & MS_NOEXEC) + exec = B_FALSE; + + if (*flags & MS_NOATIME) + atime = B_FALSE; + + /* + * Invoke our callbacks to set required flags. + */ + readonly_changed_cb(zsb, readonly); + setuid_changed_cb(zsb, setuid); + exec_changed_cb(zsb, exec); + devices_changed_cb(zsb, devices); + atime_changed_cb(zsb, atime); + + return (0); +} +EXPORT_SYMBOL(zfs_remount); + +int zfs_vget(struct vfsmount *vfsp, struct inode **ipp, fid_t *fidp) { zfs_sb_t *zsb = VTOZSB(vfsp);