X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=fs%2Fxfs%2Flinux-2.6%2Fxfs_super.c;h=4a79c7f2d010105b6567909496da1151d6342ab8;hb=43bc926fffd92024b46cafaf7350d669ba9ca884;hp=674bf43fe193dd0a759c6090b798769275a49214;hpb=cee37fe97739d85991964371c1f3a745c00dd236;p=linux-2.6.git diff --git a/fs/xfs/linux-2.6/xfs_super.c b/fs/xfs/linux-2.6/xfs_super.c index 674bf43fe..4a79c7f2d 100644 --- a/fs/xfs/linux-2.6/xfs_super.c +++ b/fs/xfs/linux-2.6/xfs_super.c @@ -1,60 +1,45 @@ /* - * Copyright (c) 2000-2005 Silicon Graphics, Inc. All Rights Reserved. + * Copyright (c) 2000-2005 Silicon Graphics, Inc. + * All Rights Reserved. * - * This program is free software; you can redistribute it and/or modify it - * under the terms of version 2 of the GNU General Public License as + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * - * This program is distributed in the hope that it would be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * This program is distributed in the hope that it would be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. * - * Further, this software is distributed without any warranty that it is - * free of the rightful claim of any third person regarding infringement - * or the like. Any license provided herein, whether implied or - * otherwise, applies only to this software file. Patent licenses, if - * any, provided herein do not apply to combinations of this program with - * other software, or any other product whatsoever. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write the Free Software Foundation, Inc., 59 - * Temple Place - Suite 330, Boston MA 02111-1307, USA. - * - * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, - * Mountain View, CA 94043, or: - * - * http://www.sgi.com - * - * For further information regarding this notice, see: - * - * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/ + * You should have received a copy of the GNU General Public License + * along with this program; if not, write the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ - #include "xfs.h" - -#include "xfs_inum.h" +#include "xfs_bit.h" #include "xfs_log.h" #include "xfs_clnt.h" +#include "xfs_inum.h" #include "xfs_trans.h" #include "xfs_sb.h" +#include "xfs_ag.h" #include "xfs_dir.h" #include "xfs_dir2.h" #include "xfs_alloc.h" #include "xfs_dmapi.h" #include "xfs_quota.h" #include "xfs_mount.h" -#include "xfs_alloc_btree.h" #include "xfs_bmap_btree.h" +#include "xfs_alloc_btree.h" #include "xfs_ialloc_btree.h" -#include "xfs_btree.h" -#include "xfs_ialloc.h" -#include "xfs_attr_sf.h" #include "xfs_dir_sf.h" #include "xfs_dir2_sf.h" +#include "xfs_attr_sf.h" #include "xfs_dinode.h" #include "xfs_inode.h" +#include "xfs_btree.h" +#include "xfs_ialloc.h" #include "xfs_bmap.h" -#include "xfs_bit.h" #include "xfs_rtalloc.h" #include "xfs_error.h" #include "xfs_itable.h" @@ -70,15 +55,20 @@ #include #include #include +#include #include +#include -STATIC struct quotactl_ops linvfs_qops; -STATIC struct super_operations linvfs_sops; -STATIC kmem_zone_t *linvfs_inode_zone; +STATIC struct quotactl_ops xfs_quotactl_operations; +STATIC struct super_operations xfs_super_operations; +STATIC kmem_zone_t *xfs_vnode_zone; +STATIC kmem_zone_t *xfs_ioend_zone; +mempool_t *xfs_ioend_pool; STATIC struct xfs_mount_args * xfs_args_allocate( - struct super_block *sb) + struct super_block *sb, + int silent) { struct xfs_mount_args *args; @@ -87,14 +77,12 @@ xfs_args_allocate( strncpy(args->fsname, sb->s_id, MAXNAMELEN); /* Copy the already-parsed mount(2) flags we're interested in */ - if (sb->s_flags & MS_NOATIME) - args->flags |= XFSMNT_NOATIME; if (sb->s_flags & MS_DIRSYNC) args->flags |= XFSMNT_DIRSYNC; if (sb->s_flags & MS_SYNCHRONOUS) args->flags |= XFSMNT_WSYNC; - - /* Default to 32 bit inodes on Linux all the time */ + if (silent) + args->flags |= XFSMNT_QUIET; args->flags |= XFSMNT_32BITINODES; return args; @@ -138,24 +126,25 @@ STATIC __inline__ void xfs_set_inodeops( struct inode *inode) { - vnode_t *vp = LINVFS_GET_VP(inode); - - if (vp->v_type == VNON) { - vn_mark_bad(vp); - } else if (S_ISREG(inode->i_mode)) { - inode->i_op = &linvfs_file_inode_operations; - inode->i_fop = &linvfs_file_operations; - inode->i_mapping->a_ops = &linvfs_aops; - } else if (S_ISDIR(inode->i_mode)) { - inode->i_op = &linvfs_dir_inode_operations; - inode->i_fop = &linvfs_dir_operations; - } else if (S_ISLNK(inode->i_mode)) { - inode->i_op = &linvfs_symlink_inode_operations; + switch (inode->i_mode & S_IFMT) { + case S_IFREG: + inode->i_op = &xfs_inode_operations; + inode->i_fop = &xfs_file_operations; + inode->i_mapping->a_ops = &xfs_address_space_operations; + break; + case S_IFDIR: + inode->i_op = &xfs_dir_inode_operations; + inode->i_fop = &xfs_dir_file_operations; + break; + case S_IFLNK: + inode->i_op = &xfs_symlink_inode_operations; if (inode->i_blocks) - inode->i_mapping->a_ops = &linvfs_aops; - } else { - inode->i_op = &linvfs_file_inode_operations; + inode->i_mapping->a_ops = &xfs_address_space_operations; + break; + default: + inode->i_op = &xfs_inode_operations; init_special_inode(inode, inode->i_mode, inode->i_rdev); + break; } } @@ -165,20 +154,27 @@ xfs_revalidate_inode( vnode_t *vp, xfs_inode_t *ip) { - struct inode *inode = LINVFS_GET_IP(vp); + struct inode *inode = vn_to_inode(vp); - inode->i_mode = (ip->i_d.di_mode & MODEMASK) | VTTOIF(vp->v_type); + inode->i_mode = ip->i_d.di_mode; inode->i_nlink = ip->i_d.di_nlink; inode->i_uid = ip->i_d.di_uid; inode->i_gid = ip->i_d.di_gid; inode->i_xid = ip->i_d.di_xid; - if (((1 << vp->v_type) & ((1<i_mode & S_IFMT) { + case S_IFBLK: + case S_IFCHR: + inode->i_rdev = + MKDEV(sysv_major(ip->i_df.if_u2.if_rdev) & 0x1ff, + sysv_minor(ip->i_df.if_u2.if_rdev)); + break; + default: inode->i_rdev = 0; - } else { - xfs_dev_t dev = ip->i_df.if_u2.if_rdev; - inode->i_rdev = MKDEV(sysv_major(dev) & 0x1ff, sysv_minor(dev)); + break; } - inode->i_blksize = PAGE_CACHE_SIZE; + + inode->i_blksize = xfs_preferred_iosize(mp); inode->i_generation = ip->i_d.di_gen; i_size_write(inode, ip->i_d.di_size); inode->i_blocks = @@ -224,7 +220,7 @@ xfs_initialize_vnode( int unlock) { xfs_inode_t *ip = XFS_BHVTOI(inode_bhv); - struct inode *inode = LINVFS_GET_IP(vp); + struct inode *inode = vn_to_inode(vp); if (!inode_bhv->bd_vobj) { vp->v_vfsp = bhvtovfs(bdp); @@ -240,10 +236,9 @@ xfs_initialize_vnode( * finish our work. */ if (ip->i_d.di_mode != 0 && unlock && (inode->i_state & I_NEW)) { - vp->v_type = IFTOVT(ip->i_d.di_mode); xfs_revalidate_inode(XFS_BHVTOM(bdp), vp, ip); xfs_set_inodeops(inode); - + ip->i_flags &= ~XFS_INEW; barrier(); @@ -276,70 +271,154 @@ xfs_blkdev_put( close_bdev_excl(bdev); } +/* + * Try to write out the superblock using barriers. + */ +STATIC int +xfs_barrier_test( + xfs_mount_t *mp) +{ + xfs_buf_t *sbp = xfs_getsb(mp, 0); + int error; + + XFS_BUF_UNDONE(sbp); + XFS_BUF_UNREAD(sbp); + XFS_BUF_UNDELAYWRITE(sbp); + XFS_BUF_WRITE(sbp); + XFS_BUF_UNASYNC(sbp); + XFS_BUF_ORDERED(sbp); + + xfsbdstrat(mp, sbp); + error = xfs_iowait(sbp); + + /* + * Clear all the flags we set and possible error state in the + * buffer. We only did the write to try out whether barriers + * worked and shouldn't leave any traces in the superblock + * buffer. + */ + XFS_BUF_DONE(sbp); + XFS_BUF_ERROR(sbp, 0); + XFS_BUF_UNORDERED(sbp); + + xfs_buf_relse(sbp); + return error; +} + +void +xfs_mountfs_check_barriers(xfs_mount_t *mp) +{ + int error; + + if (mp->m_logdev_targp != mp->m_ddev_targp) { + xfs_fs_cmn_err(CE_NOTE, mp, + "Disabling barriers, not supported with external log device"); + mp->m_flags &= ~XFS_MOUNT_BARRIER; + return; + } + + if (mp->m_ddev_targp->bt_bdev->bd_disk->queue->ordered == + QUEUE_ORDERED_NONE) { + xfs_fs_cmn_err(CE_NOTE, mp, + "Disabling barriers, not supported by the underlying device"); + mp->m_flags &= ~XFS_MOUNT_BARRIER; + return; + } + + error = xfs_barrier_test(mp); + if (error) { + xfs_fs_cmn_err(CE_NOTE, mp, + "Disabling barriers, trial barrier write failed"); + mp->m_flags &= ~XFS_MOUNT_BARRIER; + return; + } +} + +void +xfs_blkdev_issue_flush( + xfs_buftarg_t *buftarg) +{ + blkdev_issue_flush(buftarg->bt_bdev, NULL); +} STATIC struct inode * -linvfs_alloc_inode( +xfs_fs_alloc_inode( struct super_block *sb) { vnode_t *vp; - vp = (vnode_t *)kmem_cache_alloc(linvfs_inode_zone, - kmem_flags_convert(KM_SLEEP)); - if (!vp) + vp = kmem_zone_alloc(xfs_vnode_zone, KM_SLEEP); + if (unlikely(!vp)) return NULL; - return LINVFS_GET_IP(vp); + return vn_to_inode(vp); } STATIC void -linvfs_destroy_inode( +xfs_fs_destroy_inode( struct inode *inode) { - kmem_cache_free(linvfs_inode_zone, LINVFS_GET_VP(inode)); + kmem_zone_free(xfs_vnode_zone, vn_from_inode(inode)); } STATIC void -init_once( - void *data, - kmem_cache_t *cachep, +xfs_fs_inode_init_once( + void *vnode, + kmem_zone_t *zonep, unsigned long flags) { - vnode_t *vp = (vnode_t *)data; - if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) == - SLAB_CTOR_CONSTRUCTOR) - inode_init_once(LINVFS_GET_IP(vp)); + SLAB_CTOR_CONSTRUCTOR) + inode_init_once(vn_to_inode((vnode_t *)vnode)); } STATIC int -init_inodecache( void ) -{ - linvfs_inode_zone = kmem_cache_create("linvfs_icache", - sizeof(vnode_t), 0, SLAB_RECLAIM_ACCOUNT, - init_once, NULL); - if (linvfs_inode_zone == NULL) - return -ENOMEM; +xfs_init_zones(void) +{ + xfs_vnode_zone = kmem_zone_init_flags(sizeof(vnode_t), "xfs_vnode_t", + KM_ZONE_HWALIGN | KM_ZONE_RECLAIM | + KM_ZONE_SPREAD, + xfs_fs_inode_init_once); + if (!xfs_vnode_zone) + goto out; + + xfs_ioend_zone = kmem_zone_init(sizeof(xfs_ioend_t), "xfs_ioend"); + if (!xfs_ioend_zone) + goto out_destroy_vnode_zone; + + xfs_ioend_pool = mempool_create_slab_pool(4 * MAX_BUF_PER_PAGE, + xfs_ioend_zone); + if (!xfs_ioend_pool) + goto out_free_ioend_zone; return 0; + + out_free_ioend_zone: + kmem_zone_destroy(xfs_ioend_zone); + out_destroy_vnode_zone: + kmem_zone_destroy(xfs_vnode_zone); + out: + return -ENOMEM; } STATIC void -destroy_inodecache( void ) +xfs_destroy_zones(void) { - if (kmem_cache_destroy(linvfs_inode_zone)) - printk(KERN_WARNING "%s: cache still in use!\n", __FUNCTION__); + mempool_destroy(xfs_ioend_pool); + kmem_zone_destroy(xfs_vnode_zone); + kmem_zone_destroy(xfs_ioend_zone); } /* * Attempt to flush the inode, this will actually fail * if the inode is pinned, but we dirty the inode again * at the point when it is unpinned after a log write, - * since this is when the inode itself becomes flushable. + * since this is when the inode itself becomes flushable. */ STATIC int -linvfs_write_inode( +xfs_fs_write_inode( struct inode *inode, int sync) { - vnode_t *vp = LINVFS_GET_VP(inode); + vnode_t *vp = vn_from_inode(inode); int error = 0, flags = FLUSH_INODE; if (vp) { @@ -359,21 +438,42 @@ linvfs_write_inode( } STATIC void -linvfs_clear_inode( +xfs_fs_clear_inode( struct inode *inode) { - vnode_t *vp = LINVFS_GET_VP(inode); + vnode_t *vp = vn_from_inode(inode); + int error, cache; - if (vp) { - vn_rele(vp); - vn_trace_entry(vp, __FUNCTION__, (inst_t *)__return_address); - /* - * Do all our cleanup, and remove this vnode. - */ - vn_remove(vp); + vn_trace_entry(vp, __FUNCTION__, (inst_t *)__return_address); + + XFS_STATS_INC(vn_rele); + XFS_STATS_INC(vn_remove); + XFS_STATS_INC(vn_reclaim); + XFS_STATS_DEC(vn_active); + + /* + * This can happen because xfs_iget_core calls xfs_idestroy if we + * find an inode with di_mode == 0 but without IGET_CREATE set. + */ + if (vp->v_fbhv) + VOP_INACTIVE(vp, NULL, cache); + + VN_LOCK(vp); + vp->v_flag &= ~VMODIFIED; + VN_UNLOCK(vp, 0); + + if (vp->v_fbhv) { + VOP_RECLAIM(vp, error); + if (error) + panic("vn_purge: cannot reclaim"); } -} + ASSERT(vp->v_fbhv == NULL); + +#ifdef XFS_VNODE_TRACE + ktrace_free(vp->v_trace); +#endif +} /* * Enqueue a work item to be picked up by the vfs xfssyncd thread. @@ -420,12 +520,12 @@ void xfs_flush_inode( xfs_inode_t *ip) { - struct inode *inode = LINVFS_GET_IP(XFS_ITOV(ip)); + struct inode *inode = vn_to_inode(XFS_ITOV(ip)); struct vfs *vfs = XFS_MTOVFS(ip->i_mount); igrab(inode); xfs_syncd_queue_work(vfs, inode, xfs_flush_inode_work); - delay(HZ/2); + delay(msecs_to_jiffies(500)); } /* @@ -445,16 +545,16 @@ void xfs_flush_device( xfs_inode_t *ip) { - struct inode *inode = LINVFS_GET_IP(XFS_ITOV(ip)); + struct inode *inode = vn_to_inode(XFS_ITOV(ip)); struct vfs *vfs = XFS_MTOVFS(ip->i_mount); igrab(inode); xfs_syncd_queue_work(vfs, inode, xfs_flush_device_work); - delay(HZ/2); + delay(msecs_to_jiffies(500)); xfs_log_force(ip->i_mount, (xfs_lsn_t)0, XFS_LOG_FORCE|XFS_LOG_SYNC); } -#define SYNCD_FLAGS (SYNC_FSDATA|SYNC_BDFLUSH|SYNC_ATTR) +#define SYNCD_FLAGS (SYNC_FSDATA|SYNC_BDFLUSH|SYNC_ATTR|SYNC_REFCACHE) STATIC void vfs_sync_worker( vfs_t *vfsp, @@ -475,25 +575,15 @@ xfssyncd( { long timeleft; vfs_t *vfsp = (vfs_t *) arg; - struct list_head tmp; struct vfs_sync_work *work, *n; + LIST_HEAD (tmp); - daemonize("xfssyncd"); - - vfsp->vfs_sync_work.w_vfs = vfsp; - vfsp->vfs_sync_work.w_syncer = vfs_sync_worker; - vfsp->vfs_sync_task = current; - wmb(); - wake_up(&vfsp->vfs_wait_sync_task); - - INIT_LIST_HEAD(&tmp); - timeleft = (xfs_syncd_centisecs * HZ) / 100; + timeleft = xfs_syncd_centisecs * msecs_to_jiffies(10); for (;;) { - set_current_state(TASK_INTERRUPTIBLE); - timeleft = schedule_timeout(timeleft); + timeleft = schedule_timeout_interruptible(timeleft); /* swsusp */ - try_to_freeze(PF_FREEZE); - if (vfsp->vfs_flag & VFS_UMOUNT) + try_to_freeze(); + if (kthread_should_stop() && list_empty(&vfsp->vfs_sync_list)) break; spin_lock(&vfsp->vfs_sync_lock); @@ -504,7 +594,8 @@ xfssyncd( */ if (!timeleft || list_empty(&vfsp->vfs_sync_list)) { if (!timeleft) - timeleft = (xfs_syncd_centisecs * HZ) / 100; + timeleft = xfs_syncd_centisecs * + msecs_to_jiffies(10); INIT_LIST_HEAD(&vfsp->vfs_sync_work.w_list); list_add_tail(&vfsp->vfs_sync_work.w_list, &vfsp->vfs_sync_list); @@ -522,46 +613,36 @@ xfssyncd( } } - vfsp->vfs_sync_task = NULL; - wmb(); - wake_up(&vfsp->vfs_wait_sync_task); - return 0; } STATIC int -linvfs_start_syncd( +xfs_fs_start_syncd( vfs_t *vfsp) { - int pid; - - pid = kernel_thread(xfssyncd, (void *) vfsp, - CLONE_VM | CLONE_FS | CLONE_FILES); - if (pid < 0) - return -pid; - wait_event(vfsp->vfs_wait_sync_task, vfsp->vfs_sync_task); + vfsp->vfs_sync_work.w_syncer = vfs_sync_worker; + vfsp->vfs_sync_work.w_vfs = vfsp; + vfsp->vfs_sync_task = kthread_run(xfssyncd, vfsp, "xfssyncd"); + if (IS_ERR(vfsp->vfs_sync_task)) + return -PTR_ERR(vfsp->vfs_sync_task); return 0; } STATIC void -linvfs_stop_syncd( +xfs_fs_stop_syncd( vfs_t *vfsp) { - vfsp->vfs_flag |= VFS_UMOUNT; - wmb(); - - wake_up_process(vfsp->vfs_sync_task); - wait_event(vfsp->vfs_wait_sync_task, !vfsp->vfs_sync_task); + kthread_stop(vfsp->vfs_sync_task); } STATIC void -linvfs_put_super( +xfs_fs_put_super( struct super_block *sb) { - vfs_t *vfsp = LINVFS_GET_VFS(sb); + vfs_t *vfsp = vfs_from_sb(sb); int error; - linvfs_stop_syncd(vfsp); + xfs_fs_stop_syncd(vfsp); VFS_SYNC(vfsp, SYNC_ATTR|SYNC_DELWRI, NULL, error); if (!error) VFS_UNMOUNT(vfsp, 0, NULL, error); @@ -575,10 +656,10 @@ linvfs_put_super( } STATIC void -linvfs_write_super( +xfs_fs_write_super( struct super_block *sb) { - vfs_t *vfsp = LINVFS_GET_VFS(sb); + vfs_t *vfsp = vfs_from_sb(sb); int error; if (sb->s_flags & MS_RDONLY) { @@ -591,16 +672,18 @@ linvfs_write_super( } STATIC int -linvfs_sync_super( +xfs_fs_sync_super( struct super_block *sb, int wait) { - vfs_t *vfsp = LINVFS_GET_VFS(sb); + vfs_t *vfsp = vfs_from_sb(sb); int error; int flags = SYNC_FSDATA; - if (wait) - flags |= SYNC_WAIT; + if (unlikely(sb->s_frozen == SB_FREEZE_WRITE)) + flags = SYNC_QUIESCE; + else + flags = SYNC_FSDATA | (wait ? SYNC_WAIT : 0); VFS_SYNC(vfsp, flags, NULL, error); sb->s_dirt = 0; @@ -628,11 +711,11 @@ linvfs_sync_super( } STATIC int -linvfs_statfs( +xfs_fs_statfs( struct super_block *sb, struct kstatfs *statp) { - vfs_t *vfsp = LINVFS_GET_VFS(sb); + vfs_t *vfsp = vfs_from_sb(sb); int error; VFS_STATVFS(vfsp, statp, NULL, error); @@ -640,16 +723,22 @@ linvfs_statfs( } STATIC int -linvfs_remount( +xfs_fs_remount( struct super_block *sb, int *flags, char *options) { - vfs_t *vfsp = LINVFS_GET_VFS(sb); - struct xfs_mount_args *args = xfs_args_allocate(sb); + vfs_t *vfsp = vfs_from_sb(sb); + struct xfs_mount_args *args = xfs_args_allocate(sb, 0); int error; VFS_PARSEARGS(vfsp, options, args, 1, error); + if ((args->flags2 & XFSMNT2_TAGXID) && + !(sb->s_flags & MS_TAGXID)) { + printk("XFS: %s: tagxid not permitted on remount.\n", + sb->s_id); + error = EINVAL; + } if (!error) VFS_MNTUPDATE(vfsp, flags, args, error); kmem_free(args, sizeof(*args)); @@ -657,18 +746,18 @@ linvfs_remount( } STATIC void -linvfs_freeze_fs( +xfs_fs_lockfs( struct super_block *sb) { - VFS_FREEZE(LINVFS_GET_VFS(sb)); + VFS_FREEZE(vfs_from_sb(sb)); } STATIC int -linvfs_show_options( +xfs_fs_show_options( struct seq_file *m, struct vfsmount *mnt) { - struct vfs *vfsp = LINVFS_GET_VFS(mnt->mnt_sb); + struct vfs *vfsp = vfs_from_sb(mnt->mnt_sb); int error; VFS_SHOWARGS(vfsp, m, error); @@ -676,11 +765,23 @@ linvfs_show_options( } STATIC int -linvfs_getxstate( +xfs_fs_quotasync( + struct super_block *sb, + int type) +{ + struct vfs *vfsp = vfs_from_sb(sb); + int error; + + VFS_QUOTACTL(vfsp, Q_XQUOTASYNC, 0, (caddr_t)NULL, error); + return -error; +} + +STATIC int +xfs_fs_getxstate( struct super_block *sb, struct fs_quota_stat *fqs) { - struct vfs *vfsp = LINVFS_GET_VFS(sb); + struct vfs *vfsp = vfs_from_sb(sb); int error; VFS_QUOTACTL(vfsp, Q_XGETQSTAT, 0, (caddr_t)fqs, error); @@ -688,12 +789,12 @@ linvfs_getxstate( } STATIC int -linvfs_setxstate( +xfs_fs_setxstate( struct super_block *sb, unsigned int flags, int op) { - struct vfs *vfsp = LINVFS_GET_VFS(sb); + struct vfs *vfsp = vfs_from_sb(sb); int error; VFS_QUOTACTL(vfsp, op, 0, (caddr_t)&flags, error); @@ -701,51 +802,49 @@ linvfs_setxstate( } STATIC int -linvfs_getxquota( +xfs_fs_getxquota( struct super_block *sb, int type, qid_t id, struct fs_disk_quota *fdq) { - struct vfs *vfsp = LINVFS_GET_VFS(sb); + struct vfs *vfsp = vfs_from_sb(sb); int error, getmode; - getmode = (type == GRPQUOTA) ? Q_XGETGQUOTA : Q_XGETQUOTA; + getmode = (type == USRQUOTA) ? Q_XGETQUOTA : + ((type == GRPQUOTA) ? Q_XGETGQUOTA : Q_XGETPQUOTA); VFS_QUOTACTL(vfsp, getmode, id, (caddr_t)fdq, error); return -error; } STATIC int -linvfs_setxquota( +xfs_fs_setxquota( struct super_block *sb, int type, qid_t id, struct fs_disk_quota *fdq) { - struct vfs *vfsp = LINVFS_GET_VFS(sb); + struct vfs *vfsp = vfs_from_sb(sb); int error, setmode; - setmode = (type == GRPQUOTA) ? Q_XSETGQLIM : Q_XSETQLIM; + setmode = (type == USRQUOTA) ? Q_XSETQLIM : + ((type == GRPQUOTA) ? Q_XSETGQLIM : Q_XSETPQLIM); VFS_QUOTACTL(vfsp, setmode, id, (caddr_t)fdq, error); return -error; } STATIC int -linvfs_fill_super( +xfs_fs_fill_super( struct super_block *sb, void *data, int silent) { vnode_t *rootvp; - struct vfs *vfsp = vfs_allocate(); - struct xfs_mount_args *args = xfs_args_allocate(sb); + struct vfs *vfsp = vfs_allocate(sb); + struct xfs_mount_args *args = xfs_args_allocate(sb, silent); struct kstatfs statvfs; int error, error2; - vfsp->vfs_super = sb; - LINVFS_SET_VFS(sb, vfsp); - if (sb->s_flags & MS_RDONLY) - vfsp->vfs_flag |= VFS_RDONLY; bhv_insert_all_vfsops(vfsp); VFS_PARSEARGS(vfsp, (char *)data, args, 0, error); @@ -756,10 +855,10 @@ linvfs_fill_super( sb_min_blocksize(sb, BBSIZE); #ifdef CONFIG_XFS_EXPORT - sb->s_export_op = &linvfs_export_ops; + sb->s_export_op = &xfs_export_operations; #endif - sb->s_qcop = &linvfs_qops; - sb->s_op = &linvfs_sops; + sb->s_qcop = &xfs_quotactl_operations; + sb->s_op = &xfs_super_operations; VFS_MOUNT(vfsp, args, NULL, error); if (error) { @@ -783,7 +882,7 @@ linvfs_fill_super( if (error) goto fail_unmount; - sb->s_root = d_alloc_root(LINVFS_GET_IP(rootvp)); + sb->s_root = d_alloc_root(vn_to_inode(rootvp)); if (!sb->s_root) { error = ENOMEM; goto fail_vnrele; @@ -792,7 +891,7 @@ linvfs_fill_super( error = EINVAL; goto fail_vnrele; } - if ((error = linvfs_start_syncd(vfsp))) + if ((error = xfs_fs_start_syncd(vfsp))) goto fail_vnrele; vn_trace_exit(rootvp, __FUNCTION__, (inst_t *)__return_address); @@ -817,40 +916,41 @@ fail_vfsop: } STATIC struct super_block * -linvfs_get_sb( +xfs_fs_get_sb( struct file_system_type *fs_type, int flags, const char *dev_name, void *data) { - return get_sb_bdev(fs_type, flags, dev_name, data, linvfs_fill_super); -} - -STATIC struct super_operations linvfs_sops = { - .alloc_inode = linvfs_alloc_inode, - .destroy_inode = linvfs_destroy_inode, - .write_inode = linvfs_write_inode, - .clear_inode = linvfs_clear_inode, - .put_super = linvfs_put_super, - .write_super = linvfs_write_super, - .sync_fs = linvfs_sync_super, - .write_super_lockfs = linvfs_freeze_fs, - .statfs = linvfs_statfs, - .remount_fs = linvfs_remount, - .show_options = linvfs_show_options, + return get_sb_bdev(fs_type, flags, dev_name, data, xfs_fs_fill_super); +} + +STATIC struct super_operations xfs_super_operations = { + .alloc_inode = xfs_fs_alloc_inode, + .destroy_inode = xfs_fs_destroy_inode, + .write_inode = xfs_fs_write_inode, + .clear_inode = xfs_fs_clear_inode, + .put_super = xfs_fs_put_super, + .write_super = xfs_fs_write_super, + .sync_fs = xfs_fs_sync_super, + .write_super_lockfs = xfs_fs_lockfs, + .statfs = xfs_fs_statfs, + .remount_fs = xfs_fs_remount, + .show_options = xfs_fs_show_options, }; -STATIC struct quotactl_ops linvfs_qops = { - .get_xstate = linvfs_getxstate, - .set_xstate = linvfs_setxstate, - .get_xquota = linvfs_getxquota, - .set_xquota = linvfs_setxquota, +STATIC struct quotactl_ops xfs_quotactl_operations = { + .quota_sync = xfs_fs_quotasync, + .get_xstate = xfs_fs_getxstate, + .set_xstate = xfs_fs_setxstate, + .get_xquota = xfs_fs_getxquota, + .set_xquota = xfs_fs_setxquota, }; STATIC struct file_system_type xfs_fs_type = { .owner = THIS_MODULE, .name = "xfs", - .get_sb = linvfs_get_sb, + .get_sb = xfs_fs_get_sb, .kill_sb = kill_block_super, .fs_flags = FS_REQUIRES_DEV, }; @@ -871,13 +971,13 @@ init_xfs_fs( void ) ktrace_init(64); - error = init_inodecache(); + error = xfs_init_zones(); if (error < 0) - goto undo_inodecache; + goto undo_zones; - error = pagebuf_init(); + error = xfs_buf_init(); if (error < 0) - goto undo_pagebuf; + goto undo_buffers; vn_init(); xfs_init(); @@ -887,16 +987,15 @@ init_xfs_fs( void ) error = register_filesystem(&xfs_fs_type); if (error) goto undo_register; - XFS_DM_INIT(&xfs_fs_type); return 0; undo_register: - pagebuf_terminate(); + xfs_buf_terminate(); -undo_pagebuf: - destroy_inodecache(); +undo_buffers: + xfs_destroy_zones(); -undo_inodecache: +undo_zones: return error; } @@ -904,11 +1003,10 @@ STATIC void __exit exit_xfs_fs( void ) { vfs_exitquota(); - XFS_DM_EXIT(&xfs_fs_type); unregister_filesystem(&xfs_fs_type); xfs_cleanup(); - pagebuf_terminate(); - destroy_inodecache(); + xfs_buf_terminate(); + xfs_destroy_zones(); ktrace_uninit(); }