X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=fs%2Fxfs%2Fxfs_vfsops.c;h=dd003ee818d48cd917aec98557625116cdc4a90c;hb=8e8ece46a861c84343256819eaec77e608ff9217;hp=be11881656606e321da0be643066146e868890ea;hpb=9213980e6a70d8473e0ffd4b39ab5b6caaba9ff5;p=linux-2.6.git diff --git a/fs/xfs/xfs_vfsops.c b/fs/xfs/xfs_vfsops.c index be1188165..dd003ee81 100644 --- a/fs/xfs/xfs_vfsops.c +++ b/fs/xfs/xfs_vfsops.c @@ -118,7 +118,7 @@ xfs_init(void) xfs_ili_zone = kmem_zone_init(sizeof(xfs_inode_log_item_t), "xfs_ili"); xfs_chashlist_zone = kmem_zone_init(sizeof(xfs_chashlist_t), "xfs_chashlist"); - _ACL_ZONE_INIT(xfs_acl_zone, "xfs_acl"); + xfs_acl_zone_init(xfs_acl_zone, "xfs_acl"); /* * Allocate global trace buffers. @@ -170,6 +170,7 @@ xfs_cleanup(void) xfs_cleanup_procfs(); xfs_sysctl_unregister(); xfs_refcache_destroy(); + xfs_acl_zone_destroy(xfs_acl_zone); #ifdef XFS_DIR2_TRACE ktrace_free(xfs_dir2_trace_buf); @@ -202,7 +203,6 @@ xfs_cleanup(void) kmem_cache_destroy(xfs_ifork_zone); kmem_cache_destroy(xfs_ili_zone); kmem_cache_destroy(xfs_chashlist_zone); - _ACL_ZONE_DESTROY(xfs_acl_zone); } /* @@ -252,6 +252,7 @@ xfs_start_flags( ap->logbufsize); return XFS_ERROR(EINVAL); } + mp->m_ihsize = ap->ihashsize; mp->m_logbsize = ap->logbufsize; mp->m_fsname_len = strlen(ap->fsname) + 1; mp->m_fsname = kmem_alloc(mp->m_fsname_len, KM_SLEEP); @@ -318,6 +319,8 @@ xfs_start_flags( if (ap->flags & XFSMNT_NOUUID) mp->m_flags |= XFS_MOUNT_NOUUID; + if (ap->flags & XFSMNT_TAGXID) + mp->m_flags |= XFS_MOUNT_TAGXID; if (ap->flags & XFSMNT_NOLOGFLUSH) mp->m_flags |= XFS_MOUNT_NOLOGFLUSH; @@ -400,6 +403,8 @@ xfs_finish_flags( return XFS_ERROR(EINVAL); } + if (ap->flags & XFSMNT_TAGXID) + vfs->vfs_super->s_flags |= MS_TAGXID; return 0; } @@ -430,6 +435,16 @@ xfs_mount( ddev = vfsp->vfs_super->s_bdev; logdev = rtdev = NULL; + /* + * Setup xfs_mount function vectors from available behaviors + */ + p = vfs_bhv_lookup(vfsp, VFS_POSITION_DM); + mp->m_dm_ops = p ? *(xfs_dmops_t *) vfs_bhv_custom(p) : xfs_dmcore_stub; + p = vfs_bhv_lookup(vfsp, VFS_POSITION_QM); + mp->m_qm_ops = p ? *(xfs_qmops_t *) vfs_bhv_custom(p) : xfs_qmcore_stub; + p = vfs_bhv_lookup(vfsp, VFS_POSITION_IO); + mp->m_io_ops = p ? *(xfs_ioops_t *) vfs_bhv_custom(p) : xfs_iocore_xfs; + /* * Open real time and log devices - order is important. */ @@ -454,69 +469,74 @@ xfs_mount( } } - /* - * Setup xfs_mount function vectors from available behaviors - */ - p = vfs_bhv_lookup(vfsp, VFS_POSITION_DM); - mp->m_dm_ops = p ? *(xfs_dmops_t *) vfs_bhv_custom(p) : xfs_dmcore_stub; - p = vfs_bhv_lookup(vfsp, VFS_POSITION_QM); - mp->m_qm_ops = p ? *(xfs_qmops_t *) vfs_bhv_custom(p) : xfs_qmcore_stub; - p = vfs_bhv_lookup(vfsp, VFS_POSITION_IO); - mp->m_io_ops = p ? *(xfs_ioops_t *) vfs_bhv_custom(p) : xfs_iocore_xfs; - /* * Setup xfs_mount buffer target pointers */ - mp->m_ddev_targp = xfs_alloc_buftarg(ddev); - if (rtdev) - mp->m_rtdev_targp = xfs_alloc_buftarg(rtdev); + error = ENOMEM; + mp->m_ddev_targp = xfs_alloc_buftarg(ddev, 0); + if (!mp->m_ddev_targp) { + xfs_blkdev_put(logdev); + xfs_blkdev_put(rtdev); + return error; + } + if (rtdev) { + mp->m_rtdev_targp = xfs_alloc_buftarg(rtdev, 1); + if (!mp->m_rtdev_targp) + goto error0; + } mp->m_logdev_targp = (logdev && logdev != ddev) ? - xfs_alloc_buftarg(logdev) : mp->m_ddev_targp; + xfs_alloc_buftarg(logdev, 1) : mp->m_ddev_targp; + if (!mp->m_logdev_targp) + goto error0; /* * Setup flags based on mount(2) options and then the superblock */ error = xfs_start_flags(vfsp, args, mp); if (error) - goto error; + goto error1; error = xfs_readsb(mp); if (error) - goto error; + goto error1; error = xfs_finish_flags(vfsp, args, mp); - if (error) { - xfs_freesb(mp); - goto error; - } + if (error) + goto error2; /* * Setup xfs_mount buffer target pointers based on superblock */ - xfs_setsize_buftarg(mp->m_ddev_targp, mp->m_sb.sb_blocksize, - mp->m_sb.sb_sectsize); - if (logdev && logdev != ddev) { + error = xfs_setsize_buftarg(mp->m_ddev_targp, mp->m_sb.sb_blocksize, + mp->m_sb.sb_sectsize); + if (!error && logdev && logdev != ddev) { unsigned int log_sector_size = BBSIZE; if (XFS_SB_VERSION_HASSECTOR(&mp->m_sb)) log_sector_size = mp->m_sb.sb_logsectsize; - xfs_setsize_buftarg(mp->m_logdev_targp, mp->m_sb.sb_blocksize, - log_sector_size); + error = xfs_setsize_buftarg(mp->m_logdev_targp, + mp->m_sb.sb_blocksize, + log_sector_size); } - if (rtdev) - xfs_setsize_buftarg(mp->m_rtdev_targp, mp->m_sb.sb_blocksize, - mp->m_sb.sb_blocksize); + if (!error && rtdev) + error = xfs_setsize_buftarg(mp->m_rtdev_targp, + mp->m_sb.sb_blocksize, + mp->m_sb.sb_sectsize); + if (error) + goto error2; - if (!(error = XFS_IOINIT(vfsp, args, flags))) + error = XFS_IOINIT(vfsp, args, flags); + if (!error) return 0; - - error: +error2: + if (mp->m_sb_bp) + xfs_freesb(mp); +error1: xfs_binval(mp->m_ddev_targp); - if (logdev != NULL && logdev != ddev) { + if (logdev && logdev != ddev) xfs_binval(mp->m_logdev_targp); - } - if (rtdev != NULL) { + if (rtdev) xfs_binval(mp->m_rtdev_targp); - } - xfs_unmountfs_close(mp, NULL); +error0: + xfs_unmountfs_close(mp, credp); return error; } @@ -1040,6 +1060,11 @@ xfs_sync_inodes( continue; } + if (VN_BAD(vp)) { + ip = ip->i_mnext; + continue; + } + if (XFS_FORCED_SHUTDOWN(mp) && !(flags & SYNC_CLOSE)) { XFS_MOUNT_IUNLOCK(mp); kmem_free(ipointer, sizeof(xfs_iptr_t)); @@ -1559,7 +1584,7 @@ xfs_syncsub( } /* - * xfs_vget - called by DMAPI to get vnode from file handle + * xfs_vget - called by DMAPI and NFSD to get vnode from file handle */ STATIC int xfs_vget( @@ -1567,37 +1592,41 @@ xfs_vget( vnode_t **vpp, fid_t *fidp) { - xfs_fid_t *xfid; + xfs_mount_t *mp = XFS_BHVTOM(bdp); + xfs_fid_t *xfid = (struct xfs_fid *)fidp; xfs_inode_t *ip; int error; xfs_ino_t ino; unsigned int igen; - xfs_mount_t *mp; - xfid = (struct xfs_fid *)fidp; - if (xfid->xfs_fid_len == sizeof(*xfid) - sizeof(xfid->xfs_fid_len)) { - ino = xfid->xfs_fid_ino; - igen = xfid->xfs_fid_gen; - } else { - /* - * Invalid. Since handles can be created in user space - * and passed in via gethandle(), this is not cause for - * a panic. - */ + /* + * Invalid. Since handles can be created in user space and passed in + * via gethandle(), this is not cause for a panic. + */ + if (xfid->xfs_fid_len != sizeof(*xfid) - sizeof(xfid->xfs_fid_len)) return XFS_ERROR(EINVAL); - } - mp = XFS_BHVTOM(bdp); - error = xfs_iget(mp, NULL, ino, XFS_ILOCK_SHARED, &ip, 0); + + ino = xfid->xfs_fid_ino; + igen = xfid->xfs_fid_gen; + + /* + * NFS can sometimes send requests for ino 0. Fail them gracefully. + */ + if (ino == 0) + return XFS_ERROR(ESTALE); + + error = xfs_iget(mp, NULL, ino, 0, XFS_ILOCK_SHARED, &ip, 0); if (error) { *vpp = NULL; return error; } + if (ip == NULL) { *vpp = NULL; return XFS_ERROR(EIO); } - if (ip->i_d.di_mode == 0 || (igen && (ip->i_d.di_gen != igen))) { + if (ip->i_d.di_mode == 0 || ip->i_d.di_gen != igen) { xfs_iput_new(ip, XFS_ILOCK_SHARED); *vpp = NULL; return XFS_ERROR(ENOENT); @@ -1622,12 +1651,14 @@ xfs_vget( #define MNTOPT_SWIDTH "swidth" /* data volume stripe width */ #define MNTOPT_NOUUID "nouuid" /* ignore filesystem UUID */ #define MNTOPT_MTPT "mtpt" /* filesystem mount point */ +#define MNTOPT_IHASHSIZE "ihashsize" /* size of inode hash table */ #define MNTOPT_NORECOVERY "norecovery" /* don't run XFS recovery */ #define MNTOPT_NOLOGFLUSH "nologflush" /* don't hard flush on log writes */ #define MNTOPT_OSYNCISOSYNC "osyncisosync" /* o_sync is REALLY o_sync */ #define MNTOPT_64BITINODE "inode64" /* inodes can be allocated anywhere */ #define MNTOPT_IKEEP "ikeep" /* do not free empty inode clusters */ #define MNTOPT_NOIKEEP "noikeep" /* free empty inode clusters */ +#define MNTOPT_TAGXID "tagxid" /* context xid tagging for inodes */ int @@ -1710,6 +1741,13 @@ xfs_parseargs( iosize = simple_strtoul(value, &eov, 10); args->flags |= XFSMNT_IOSIZE; args->iosizelog = (uint8_t) iosize; + } else if (!strcmp(this_char, MNTOPT_IHASHSIZE)) { + if (!value || !*value) { + printk("XFS: %s option requires an argument\n", + this_char); + return EINVAL; + } + args->ihashsize = simple_strtoul(value, &eov, 10); } else if (!strcmp(this_char, MNTOPT_WSYNC)) { args->flags |= XFSMNT_WSYNC; } else if (!strcmp(this_char, MNTOPT_OSYNCISOSYNC)) { @@ -1756,6 +1794,8 @@ xfs_parseargs( args->flags &= ~XFSMNT_IDELETE; } else if (!strcmp(this_char, MNTOPT_NOIKEEP)) { args->flags |= XFSMNT_IDELETE; + } else if (!strcmp(this_char, MNTOPT_TAGXID)) { + args->flags |= XFSMNT_TAGXID; } else if (!strcmp(this_char, "osyncisdsync")) { /* no-op, this is now the default */ printk("XFS: osyncisdsync is now the default, option is deprecated.\n");