diff options
Diffstat (limited to 'fs/xfs/quota')
-rw-r--r-- | fs/xfs/quota/Makefile | 1 | ||||
-rw-r--r-- | fs/xfs/quota/Makefile-linux-2.6 | 53 | ||||
-rw-r--r-- | fs/xfs/quota/xfs_dquot.c | 43 | ||||
-rw-r--r-- | fs/xfs/quota/xfs_dquot.h | 16 | ||||
-rw-r--r-- | fs/xfs/quota/xfs_dquot_item.c | 1 | ||||
-rw-r--r-- | fs/xfs/quota/xfs_qm.c | 26 | ||||
-rw-r--r-- | fs/xfs/quota/xfs_qm.h | 2 | ||||
-rw-r--r-- | fs/xfs/quota/xfs_qm_bhv.c | 44 | ||||
-rw-r--r-- | fs/xfs/quota/xfs_qm_syscalls.c | 16 |
9 files changed, 102 insertions, 100 deletions
diff --git a/fs/xfs/quota/Makefile b/fs/xfs/quota/Makefile new file mode 100644 index 00000000000..7a4f725b282 --- /dev/null +++ b/fs/xfs/quota/Makefile @@ -0,0 +1 @@ +include $(TOPDIR)/fs/xfs/quota/Makefile-linux-$(VERSION).$(PATCHLEVEL) diff --git a/fs/xfs/quota/Makefile-linux-2.6 b/fs/xfs/quota/Makefile-linux-2.6 new file mode 100644 index 00000000000..8b7b676718b --- /dev/null +++ b/fs/xfs/quota/Makefile-linux-2.6 @@ -0,0 +1,53 @@ +# +# Copyright (c) 2000-2003 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 +# 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. +# +# 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/ +# + +EXTRA_CFLAGS += -I $(TOPDIR)/fs/xfs -I $(TOPDIR)/fs/xfs/linux-2.6 + +ifeq ($(CONFIG_XFS_DEBUG),y) + EXTRA_CFLAGS += -g -DDEBUG + #EXTRA_CFLAGS += -DQUOTADEBUG +endif +ifeq ($(CONFIG_XFS_TRACE),y) + EXTRA_CFLAGS += -DXFS_DQUOT_TRACE + EXTRA_CFLAGS += -DXFS_VNODE_TRACE +endif + +obj-$(CONFIG_XFS_QUOTA) += xfs_quota.o + +xfs_quota-y += xfs_dquot.o \ + xfs_dquot_item.o \ + xfs_trans_dquot.o \ + xfs_qm_syscalls.o \ + xfs_qm_bhv.o \ + xfs_qm.o + +xfs_quota-$(CONFIG_PROC_FS) += xfs_qm_stats.o diff --git a/fs/xfs/quota/xfs_dquot.c b/fs/xfs/quota/xfs_dquot.c index 46ce1e3ce1d..e2e8d35fa4d 100644 --- a/fs/xfs/quota/xfs_dquot.c +++ b/fs/xfs/quota/xfs_dquot.c @@ -421,7 +421,7 @@ xfs_qm_init_dquot_blk( */ STATIC int xfs_qm_dqalloc( - xfs_trans_t *tp, + xfs_trans_t **tpp, xfs_mount_t *mp, xfs_dquot_t *dqp, xfs_inode_t *quotip, @@ -433,6 +433,7 @@ xfs_qm_dqalloc( xfs_bmbt_irec_t map; int nmaps, error, committed; xfs_buf_t *bp; + xfs_trans_t *tp = *tpp; ASSERT(tp != NULL); xfs_dqtrace_entry(dqp, "DQALLOC"); @@ -492,10 +493,32 @@ xfs_qm_dqalloc( xfs_qm_init_dquot_blk(tp, mp, INT_GET(dqp->q_core.d_id, ARCH_CONVERT), dqp->dq_flags & XFS_DQ_ALLTYPES, bp); - if ((error = xfs_bmap_finish(&tp, &flist, firstblock, &committed))) { + /* + * xfs_bmap_finish() may commit the current transaction and + * start a second transaction if the freelist is not empty. + * + * Since we still want to modify this buffer, we need to + * ensure that the buffer is not released on commit of + * the first transaction and ensure the buffer is added to the + * second transaction. + * + * If there is only one transaction then don't stop the buffer + * from being released when it commits later on. + */ + + xfs_trans_bhold(tp, bp); + + if ((error = xfs_bmap_finish(tpp, &flist, firstblock, &committed))) { goto error1; } + if (committed) { + tp = *tpp; + xfs_trans_bjoin(tp, bp); + } else { + xfs_trans_bhold_release(tp, bp); + } + *O_bpp = bp; return 0; @@ -514,7 +537,7 @@ xfs_qm_dqalloc( */ STATIC int xfs_qm_dqtobp( - xfs_trans_t *tp, + xfs_trans_t **tpp, xfs_dquot_t *dqp, xfs_disk_dquot_t **O_ddpp, xfs_buf_t **O_bpp, @@ -528,6 +551,7 @@ xfs_qm_dqtobp( xfs_disk_dquot_t *ddq; xfs_dqid_t id; boolean_t newdquot; + xfs_trans_t *tp = (tpp ? *tpp : NULL); mp = dqp->q_mount; id = INT_GET(dqp->q_core.d_id, ARCH_CONVERT); @@ -579,9 +603,10 @@ xfs_qm_dqtobp( return (ENOENT); ASSERT(tp); - if ((error = xfs_qm_dqalloc(tp, mp, dqp, quotip, + if ((error = xfs_qm_dqalloc(tpp, mp, dqp, quotip, dqp->q_fileoffset, &bp))) return (error); + tp = *tpp; newdquot = B_TRUE; } else { /* @@ -645,7 +670,7 @@ xfs_qm_dqtobp( /* ARGSUSED */ STATIC int xfs_qm_dqread( - xfs_trans_t *tp, + xfs_trans_t **tpp, xfs_dqid_t id, xfs_dquot_t *dqp, /* dquot to get filled in */ uint flags) @@ -653,15 +678,19 @@ xfs_qm_dqread( xfs_disk_dquot_t *ddqp; xfs_buf_t *bp; int error; + xfs_trans_t *tp; + + ASSERT(tpp); /* * get a pointer to the on-disk dquot and the buffer containing it * dqp already knows its own type (GROUP/USER). */ xfs_dqtrace_entry(dqp, "DQREAD"); - if ((error = xfs_qm_dqtobp(tp, dqp, &ddqp, &bp, flags))) { + if ((error = xfs_qm_dqtobp(tpp, dqp, &ddqp, &bp, flags))) { return (error); } + tp = *tpp; /* copy everything from disk dquot to the incore dquot */ memcpy(&dqp->q_core, ddqp, sizeof(xfs_disk_dquot_t)); @@ -740,7 +769,7 @@ xfs_qm_idtodq( * Read it from disk; xfs_dqread() takes care of * all the necessary initialization of dquot's fields (locks, etc) */ - if ((error = xfs_qm_dqread(tp, id, dqp, flags))) { + if ((error = xfs_qm_dqread(&tp, id, dqp, flags))) { /* * This can happen if quotas got turned off (ESRCH), * or if the dquot didn't exist on disk and we ask to diff --git a/fs/xfs/quota/xfs_dquot.h b/fs/xfs/quota/xfs_dquot.h index 39175103c8e..8ebc87176c7 100644 --- a/fs/xfs/quota/xfs_dquot.h +++ b/fs/xfs/quota/xfs_dquot.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000-2002 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 @@ -113,20 +113,6 @@ typedef struct xfs_dquot { #define XFS_DQHOLD(dqp) ((dqp)->q_nrefs++) -/* - * Quota Accounting/Enforcement flags - */ -#define XFS_ALL_QUOTA_ACCT \ - (XFS_UQUOTA_ACCT | XFS_GQUOTA_ACCT | XFS_PQUOTA_ACCT) -#define XFS_ALL_QUOTA_ENFD (XFS_UQUOTA_ENFD | XFS_OQUOTA_ENFD) -#define XFS_ALL_QUOTA_CHKD (XFS_UQUOTA_CHKD | XFS_OQUOTA_CHKD) - -#define XFS_IS_QUOTA_RUNNING(mp) ((mp)->m_qflags & XFS_ALL_QUOTA_ACCT) -#define XFS_IS_QUOTA_ENFORCED(mp) ((mp)->m_qflags & XFS_ALL_QUOTA_ENFD) -#define XFS_IS_UQUOTA_RUNNING(mp) ((mp)->m_qflags & XFS_UQUOTA_ACCT) -#define XFS_IS_PQUOTA_RUNNING(mp) ((mp)->m_qflags & XFS_PQUOTA_ACCT) -#define XFS_IS_GQUOTA_RUNNING(mp) ((mp)->m_qflags & XFS_GQUOTA_ACCT) - #ifdef DEBUG static inline int XFS_DQ_IS_LOCKED(xfs_dquot_t *dqp) diff --git a/fs/xfs/quota/xfs_dquot_item.c b/fs/xfs/quota/xfs_dquot_item.c index f5271b7b1e8..e74eaa7dd1b 100644 --- a/fs/xfs/quota/xfs_dquot_item.c +++ b/fs/xfs/quota/xfs_dquot_item.c @@ -509,6 +509,7 @@ xfs_qm_qoff_logitem_format(xfs_qoff_logitem_t *qf, log_vector->i_addr = (xfs_caddr_t)&(qf->qql_format); log_vector->i_len = sizeof(xfs_qoff_logitem_t); + XLOG_VEC_SET_TYPE(log_vector, XLOG_REG_TYPE_QUOTAOFF); qf->qql_format.qf_size = 1; } diff --git a/fs/xfs/quota/xfs_qm.c b/fs/xfs/quota/xfs_qm.c index f665ca8f9e9..efde16e0a91 100644 --- a/fs/xfs/quota/xfs_qm.c +++ b/fs/xfs/quota/xfs_qm.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000-2004 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 @@ -365,16 +365,6 @@ xfs_qm_mount_quotas( int error = 0; uint sbf; - /* - * If a file system had quotas running earlier, but decided to - * mount without -o uquota/pquota/gquota options, revoke the - * quotachecked license, and bail out. - */ - if (! XFS_IS_QUOTA_ON(mp) && - (mp->m_sb.sb_qflags & XFS_ALL_QUOTA_ACCT)) { - mp->m_qflags = 0; - goto write_changes; - } /* * If quotas on realtime volumes is not supported, we disable @@ -388,11 +378,8 @@ xfs_qm_mount_quotas( goto write_changes; } -#if defined(DEBUG) && defined(XFS_LOUD_RECOVERY) - cmn_err(CE_NOTE, "Attempting to turn on disk quotas."); -#endif - ASSERT(XFS_IS_QUOTA_RUNNING(mp)); + /* * Allocate the quotainfo structure inside the mount struct, and * create quotainode(s), and change/rev superblock if necessary. @@ -410,19 +397,14 @@ xfs_qm_mount_quotas( */ if (XFS_QM_NEED_QUOTACHECK(mp) && !(mfsi_flags & XFS_MFSI_NO_QUOTACHECK)) { -#ifdef DEBUG - cmn_err(CE_NOTE, "Doing a quotacheck. Please wait."); -#endif if ((error = xfs_qm_quotacheck(mp))) { /* Quotacheck has failed and quotas have * been disabled. */ return XFS_ERROR(error); } -#ifdef DEBUG - cmn_err(CE_NOTE, "Done quotacheck."); -#endif } + write_changes: /* * We actually don't have to acquire the SB_LOCK at all. @@ -2010,7 +1992,7 @@ xfs_qm_quotacheck( ASSERT(mp->m_quotainfo != NULL); ASSERT(xfs_Gqm != NULL); xfs_qm_destroy_quotainfo(mp); - xfs_mount_reset_sbqflags(mp); + (void)xfs_mount_reset_sbqflags(mp); } else { cmn_err(CE_NOTE, "XFS quotacheck %s: Done.", mp->m_fsname); } diff --git a/fs/xfs/quota/xfs_qm.h b/fs/xfs/quota/xfs_qm.h index b03eecf3b6c..0b00b3c6701 100644 --- a/fs/xfs/quota/xfs_qm.h +++ b/fs/xfs/quota/xfs_qm.h @@ -184,8 +184,6 @@ typedef struct xfs_dquot_acct { #define XFS_QM_HOLD(xqm) ((xqm)->qm_nrefs++) #define XFS_QM_RELE(xqm) ((xqm)->qm_nrefs--) -extern void xfs_mount_reset_sbqflags(xfs_mount_t *); - extern void xfs_qm_destroy_quotainfo(xfs_mount_t *); extern int xfs_qm_mount_quotas(xfs_mount_t *, int); extern void xfs_qm_mount_quotainit(xfs_mount_t *, uint); diff --git a/fs/xfs/quota/xfs_qm_bhv.c b/fs/xfs/quota/xfs_qm_bhv.c index dc3c37a1e15..8890a18a99d 100644 --- a/fs/xfs/quota/xfs_qm_bhv.c +++ b/fs/xfs/quota/xfs_qm_bhv.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000-2004 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 @@ -229,48 +229,6 @@ xfs_qm_syncall( return error; } -/* - * Clear the quotaflags in memory and in the superblock. - */ -void -xfs_mount_reset_sbqflags( - xfs_mount_t *mp) -{ - xfs_trans_t *tp; - unsigned long s; - - mp->m_qflags = 0; - /* - * It is OK to look at sb_qflags here in mount path, - * without SB_LOCK. - */ - if (mp->m_sb.sb_qflags == 0) - return; - s = XFS_SB_LOCK(mp); - mp->m_sb.sb_qflags = 0; - XFS_SB_UNLOCK(mp, s); - - /* - * if the fs is readonly, let the incore superblock run - * with quotas off but don't flush the update out to disk - */ - if (XFS_MTOVFS(mp)->vfs_flag & VFS_RDONLY) - return; -#ifdef QUOTADEBUG - xfs_fs_cmn_err(CE_NOTE, mp, "Writing superblock quota changes"); -#endif - tp = xfs_trans_alloc(mp, XFS_TRANS_QM_SBCHANGE); - if (xfs_trans_reserve(tp, 0, mp->m_sb.sb_sectsize + 128, 0, 0, - XFS_DEFAULT_LOG_COUNT)) { - xfs_trans_cancel(tp, 0); - xfs_fs_cmn_err(CE_ALERT, mp, - "xfs_mount_reset_sbqflags: Superblock update failed!"); - return; - } - xfs_mod_sb(tp, XFS_SB_QFLAGS); - xfs_trans_commit(tp, 0, NULL); -} - STATIC int xfs_qm_newmount( xfs_mount_t *mp, diff --git a/fs/xfs/quota/xfs_qm_syscalls.c b/fs/xfs/quota/xfs_qm_syscalls.c index 68e98962dbe..15e02e8a9d4 100644 --- a/fs/xfs/quota/xfs_qm_syscalls.c +++ b/fs/xfs/quota/xfs_qm_syscalls.c @@ -1053,7 +1053,6 @@ xfs_qm_dqrele_all_inodes( struct xfs_mount *mp, uint flags) { - vmap_t vmap; xfs_inode_t *ip, *topino; uint ireclaims; vnode_t *vp; @@ -1061,8 +1060,8 @@ xfs_qm_dqrele_all_inodes( ASSERT(mp->m_quotainfo); -again: XFS_MOUNT_ILOCK(mp); +again: ip = mp->m_inodes; if (ip == NULL) { XFS_MOUNT_IUNLOCK(mp); @@ -1090,18 +1089,14 @@ again: } vnode_refd = B_FALSE; if (xfs_ilock_nowait(ip, XFS_ILOCK_EXCL) == 0) { - /* - * Sample vp mapping while holding the mplock, lest - * we come across a non-existent vnode. - */ - VMAP(vp, vmap); ireclaims = mp->m_ireclaims; topino = mp->m_inodes; - XFS_MOUNT_IUNLOCK(mp); + vp = vn_grab(vp); + if (!vp) + goto again; + XFS_MOUNT_IUNLOCK(mp); /* XXX restart limit ? */ - if ( ! (vp = vn_get(vp, &vmap))) - goto again; xfs_ilock(ip, XFS_ILOCK_EXCL); vnode_refd = B_TRUE; } else { @@ -1137,7 +1132,6 @@ again: */ if (topino != mp->m_inodes || mp->m_ireclaims != ireclaims) { /* XXX use a sentinel */ - XFS_MOUNT_IUNLOCK(mp); goto again; } ip = ip->i_mnext; |