Commit 7603ef03 authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'for-linus' of git://oss.sgi.com/xfs/xfs

* 'for-linus' of git://oss.sgi.com/xfs/xfs: (23 commits)
  xfs: fix small mismerge in xfs_vn_mknod
  xfs: fix warnings with CONFIG_XFS_QUOTA disabled
  xfs: fix freeing memory in xfs_getbmap()
  xfs: use generic Posix ACL code
  xfs: remove SYNC_BDFLUSH
  xfs: remove SYNC_IOWAIT
  xfs: split xfs_sync_inodes
  xfs: use generic inode iterator in xfs_qm_dqrele_all_inodes
  xfs: introduce a per-ag inode iterator
  xfs: remove unused parameter from xfs_reclaim_inodes
  xfs: factor out inode validation for sync
  xfs: split inode flushing from xfs_sync_inodes_ag
  xfs: split inode data writeback from xfs_sync_inodes_ag
  xfs: kill xfs_qmops
  xfs: validate quota log items during log recovery
  xfs: update max log size
  xfs: prevent deadlock in xfs_qm_shake()
  xfs: fix overflow in xfs_growfs_data_private
  xfs: fix double unlock in xfs_swap_extents()
  xfs: fix getbmap vs mmap deadlock
  ...
parents 1904187a fd402613
...@@ -39,6 +39,7 @@ config XFS_QUOTA ...@@ -39,6 +39,7 @@ config XFS_QUOTA
config XFS_POSIX_ACL config XFS_POSIX_ACL
bool "XFS POSIX ACL support" bool "XFS POSIX ACL support"
depends on XFS_FS depends on XFS_FS
select FS_POSIX_ACL
help help
POSIX Access Control Lists (ACLs) support permissions for users and POSIX Access Control Lists (ACLs) support permissions for users and
groups beyond the owner/group/world scheme. groups beyond the owner/group/world scheme.
......
...@@ -40,7 +40,7 @@ xfs-$(CONFIG_PROC_FS) += quota/xfs_qm_stats.o ...@@ -40,7 +40,7 @@ xfs-$(CONFIG_PROC_FS) += quota/xfs_qm_stats.o
endif endif
xfs-$(CONFIG_XFS_RT) += xfs_rtalloc.o xfs-$(CONFIG_XFS_RT) += xfs_rtalloc.o
xfs-$(CONFIG_XFS_POSIX_ACL) += xfs_acl.o xfs-$(CONFIG_XFS_POSIX_ACL) += $(XFS_LINUX)/xfs_acl.o
xfs-$(CONFIG_PROC_FS) += $(XFS_LINUX)/xfs_stats.o xfs-$(CONFIG_PROC_FS) += $(XFS_LINUX)/xfs_stats.o
xfs-$(CONFIG_SYSCTL) += $(XFS_LINUX)/xfs_sysctl.o xfs-$(CONFIG_SYSCTL) += $(XFS_LINUX)/xfs_sysctl.o
xfs-$(CONFIG_COMPAT) += $(XFS_LINUX)/xfs_ioctl32.o xfs-$(CONFIG_COMPAT) += $(XFS_LINUX)/xfs_ioctl32.o
...@@ -88,8 +88,7 @@ xfs-y += xfs_alloc.o \ ...@@ -88,8 +88,7 @@ xfs-y += xfs_alloc.o \
xfs_utils.o \ xfs_utils.o \
xfs_vnodeops.o \ xfs_vnodeops.o \
xfs_rw.o \ xfs_rw.o \
xfs_dmops.o \ xfs_dmops.o
xfs_qmops.o
xfs-$(CONFIG_XFS_TRACE) += xfs_btree_trace.o \ xfs-$(CONFIG_XFS_TRACE) += xfs_btree_trace.o \
xfs_dir2_trace.o xfs_dir2_trace.o
......
This diff is collapsed.
...@@ -41,7 +41,6 @@ ...@@ -41,7 +41,6 @@
#include "xfs_itable.h" #include "xfs_itable.h"
#include "xfs_error.h" #include "xfs_error.h"
#include "xfs_rw.h" #include "xfs_rw.h"
#include "xfs_acl.h"
#include "xfs_attr.h" #include "xfs_attr.h"
#include "xfs_bmap.h" #include "xfs_bmap.h"
#include "xfs_buf_item.h" #include "xfs_buf_item.h"
...@@ -899,7 +898,8 @@ xfs_ioctl_setattr( ...@@ -899,7 +898,8 @@ xfs_ioctl_setattr(
struct xfs_mount *mp = ip->i_mount; struct xfs_mount *mp = ip->i_mount;
struct xfs_trans *tp; struct xfs_trans *tp;
unsigned int lock_flags = 0; unsigned int lock_flags = 0;
struct xfs_dquot *udqp = NULL, *gdqp = NULL; struct xfs_dquot *udqp = NULL;
struct xfs_dquot *gdqp = NULL;
struct xfs_dquot *olddquot = NULL; struct xfs_dquot *olddquot = NULL;
int code; int code;
...@@ -919,7 +919,7 @@ xfs_ioctl_setattr( ...@@ -919,7 +919,7 @@ xfs_ioctl_setattr(
* because the i_*dquot fields will get updated anyway. * because the i_*dquot fields will get updated anyway.
*/ */
if (XFS_IS_QUOTA_ON(mp) && (mask & FSX_PROJID)) { if (XFS_IS_QUOTA_ON(mp) && (mask & FSX_PROJID)) {
code = XFS_QM_DQVOPALLOC(mp, ip, ip->i_d.di_uid, code = xfs_qm_vop_dqalloc(ip, ip->i_d.di_uid,
ip->i_d.di_gid, fa->fsx_projid, ip->i_d.di_gid, fa->fsx_projid,
XFS_QMOPT_PQUOTA, &udqp, &gdqp); XFS_QMOPT_PQUOTA, &udqp, &gdqp);
if (code) if (code)
...@@ -954,10 +954,11 @@ xfs_ioctl_setattr( ...@@ -954,10 +954,11 @@ xfs_ioctl_setattr(
* Do a quota reservation only if projid is actually going to change. * Do a quota reservation only if projid is actually going to change.
*/ */
if (mask & FSX_PROJID) { if (mask & FSX_PROJID) {
if (XFS_IS_PQUOTA_ON(mp) && if (XFS_IS_QUOTA_RUNNING(mp) &&
XFS_IS_PQUOTA_ON(mp) &&
ip->i_d.di_projid != fa->fsx_projid) { ip->i_d.di_projid != fa->fsx_projid) {
ASSERT(tp); ASSERT(tp);
code = XFS_QM_DQVOPCHOWNRESV(mp, tp, ip, udqp, gdqp, code = xfs_qm_vop_chown_reserve(tp, ip, udqp, gdqp,
capable(CAP_FOWNER) ? capable(CAP_FOWNER) ?
XFS_QMOPT_FORCE_RES : 0); XFS_QMOPT_FORCE_RES : 0);
if (code) /* out of quota */ if (code) /* out of quota */
...@@ -1059,8 +1060,8 @@ xfs_ioctl_setattr( ...@@ -1059,8 +1060,8 @@ xfs_ioctl_setattr(
* in the transaction. * in the transaction.
*/ */
if (ip->i_d.di_projid != fa->fsx_projid) { if (ip->i_d.di_projid != fa->fsx_projid) {
if (XFS_IS_PQUOTA_ON(mp)) { if (XFS_IS_QUOTA_RUNNING(mp) && XFS_IS_PQUOTA_ON(mp)) {
olddquot = XFS_QM_DQVOPCHOWN(mp, tp, ip, olddquot = xfs_qm_vop_chown(tp, ip,
&ip->i_gdquot, gdqp); &ip->i_gdquot, gdqp);
} }
ip->i_d.di_projid = fa->fsx_projid; ip->i_d.di_projid = fa->fsx_projid;
...@@ -1106,9 +1107,9 @@ xfs_ioctl_setattr( ...@@ -1106,9 +1107,9 @@ xfs_ioctl_setattr(
/* /*
* Release any dquot(s) the inode had kept before chown. * Release any dquot(s) the inode had kept before chown.
*/ */
XFS_QM_DQRELE(mp, olddquot); xfs_qm_dqrele(olddquot);
XFS_QM_DQRELE(mp, udqp); xfs_qm_dqrele(udqp);
XFS_QM_DQRELE(mp, gdqp); xfs_qm_dqrele(gdqp);
if (code) if (code)
return code; return code;
...@@ -1122,8 +1123,8 @@ xfs_ioctl_setattr( ...@@ -1122,8 +1123,8 @@ xfs_ioctl_setattr(
return 0; return 0;
error_return: error_return:
XFS_QM_DQRELE(mp, udqp); xfs_qm_dqrele(udqp);
XFS_QM_DQRELE(mp, gdqp); xfs_qm_dqrele(gdqp);
xfs_trans_cancel(tp, 0); xfs_trans_cancel(tp, 0);
if (lock_flags) if (lock_flags)
xfs_iunlock(ip, lock_flags); xfs_iunlock(ip, lock_flags);
......
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
*/ */
#include "xfs.h" #include "xfs.h"
#include "xfs_fs.h" #include "xfs_fs.h"
#include "xfs_acl.h"
#include "xfs_bit.h" #include "xfs_bit.h"
#include "xfs_log.h" #include "xfs_log.h"
#include "xfs_inum.h" #include "xfs_inum.h"
...@@ -51,6 +52,7 @@ ...@@ -51,6 +52,7 @@
#include <linux/capability.h> #include <linux/capability.h>
#include <linux/xattr.h> #include <linux/xattr.h>
#include <linux/namei.h> #include <linux/namei.h>
#include <linux/posix_acl.h>
#include <linux/security.h> #include <linux/security.h>
#include <linux/falloc.h> #include <linux/falloc.h>
#include <linux/fiemap.h> #include <linux/fiemap.h>
...@@ -202,9 +204,8 @@ xfs_vn_mknod( ...@@ -202,9 +204,8 @@ xfs_vn_mknod(
{ {
struct inode *inode; struct inode *inode;
struct xfs_inode *ip = NULL; struct xfs_inode *ip = NULL;
xfs_acl_t *default_acl = NULL; struct posix_acl *default_acl = NULL;
struct xfs_name name; struct xfs_name name;
int (*test_default_acl)(struct inode *) = _ACL_DEFAULT_EXISTS;
int error; int error;
/* /*
...@@ -219,18 +220,14 @@ xfs_vn_mknod( ...@@ -219,18 +220,14 @@ xfs_vn_mknod(
rdev = 0; rdev = 0;
} }
if (test_default_acl && test_default_acl(dir)) { if (IS_POSIXACL(dir)) {
if (!_ACL_ALLOC(default_acl)) { default_acl = xfs_get_acl(dir, ACL_TYPE_DEFAULT);
return -ENOMEM; if (IS_ERR(default_acl))
} return -PTR_ERR(default_acl);
if (!_ACL_GET_DEFAULT(dir, default_acl)) {
_ACL_FREE(default_acl);
default_acl = NULL;
}
}
if (IS_POSIXACL(dir) && !default_acl) if (!default_acl)
mode &= ~current_umask(); mode &= ~current_umask();
}
xfs_dentry_to_name(&name, dentry); xfs_dentry_to_name(&name, dentry);
error = xfs_create(XFS_I(dir), &name, mode, rdev, &ip, NULL); error = xfs_create(XFS_I(dir), &name, mode, rdev, &ip, NULL);
...@@ -244,10 +241,10 @@ xfs_vn_mknod( ...@@ -244,10 +241,10 @@ xfs_vn_mknod(
goto out_cleanup_inode; goto out_cleanup_inode;
if (default_acl) { if (default_acl) {
error = _ACL_INHERIT(inode, mode, default_acl); error = -xfs_inherit_acl(inode, default_acl);
if (unlikely(error)) if (unlikely(error))
goto out_cleanup_inode; goto out_cleanup_inode;
_ACL_FREE(default_acl); posix_acl_release(default_acl);
} }
...@@ -257,8 +254,7 @@ xfs_vn_mknod( ...@@ -257,8 +254,7 @@ xfs_vn_mknod(
out_cleanup_inode: out_cleanup_inode:
xfs_cleanup_inode(dir, inode, dentry); xfs_cleanup_inode(dir, inode, dentry);
out_free_acl: out_free_acl:
if (default_acl) posix_acl_release(default_acl);
_ACL_FREE(default_acl);
return -error; return -error;
} }
...@@ -488,26 +484,6 @@ xfs_vn_put_link( ...@@ -488,26 +484,6 @@ xfs_vn_put_link(
kfree(s); kfree(s);
} }
#ifdef CONFIG_XFS_POSIX_ACL
STATIC int
xfs_check_acl(
struct inode *inode,
int mask)
{
struct xfs_inode *ip = XFS_I(inode);
int error;
xfs_itrace_entry(ip);
if (XFS_IFORK_Q(ip)) {
error = xfs_acl_iaccess(ip, mask, NULL);
if (error != -1)
return -error;
}
return -EAGAIN;
}
STATIC int STATIC int
xfs_vn_permission( xfs_vn_permission(
struct inode *inode, struct inode *inode,
...@@ -515,9 +491,6 @@ xfs_vn_permission( ...@@ -515,9 +491,6 @@ xfs_vn_permission(
{ {
return generic_permission(inode, mask, xfs_check_acl); return generic_permission(inode, mask, xfs_check_acl);
} }
#else
#define xfs_vn_permission NULL
#endif
STATIC int STATIC int
xfs_vn_getattr( xfs_vn_getattr(
......
...@@ -42,7 +42,6 @@ ...@@ -42,7 +42,6 @@
#include "xfs_error.h" #include "xfs_error.h"
#include "xfs_itable.h" #include "xfs_itable.h"
#include "xfs_rw.h" #include "xfs_rw.h"
#include "xfs_acl.h"
#include "xfs_attr.h" #include "xfs_attr.h"
#include "xfs_inode_item.h" #include "xfs_inode_item.h"
#include "xfs_buf_item.h" #include "xfs_buf_item.h"
......
...@@ -50,9 +50,11 @@ xfs_fs_quota_sync( ...@@ -50,9 +50,11 @@ xfs_fs_quota_sync(
{ {
struct xfs_mount *mp = XFS_M(sb); struct xfs_mount *mp = XFS_M(sb);
if (sb->s_flags & MS_RDONLY)
return -EROFS;
if (!XFS_IS_QUOTA_RUNNING(mp)) if (!XFS_IS_QUOTA_RUNNING(mp))
return -ENOSYS; return -ENOSYS;
return -xfs_sync_inodes(mp, SYNC_DELWRI); return -xfs_sync_data(mp, 0);
} }
STATIC int STATIC int
......
...@@ -43,7 +43,6 @@ ...@@ -43,7 +43,6 @@
#include "xfs_itable.h" #include "xfs_itable.h"
#include "xfs_fsops.h" #include "xfs_fsops.h"
#include "xfs_rw.h" #include "xfs_rw.h"
#include "xfs_acl.h"
#include "xfs_attr.h" #include "xfs_attr.h"
#include "xfs_buf_item.h" #include "xfs_buf_item.h"
#include "xfs_utils.h" #include "xfs_utils.h"
...@@ -405,6 +404,14 @@ xfs_parseargs( ...@@ -405,6 +404,14 @@ xfs_parseargs(
return EINVAL; return EINVAL;
} }
#ifndef CONFIG_XFS_QUOTA
if (XFS_IS_QUOTA_RUNNING(mp)) {
cmn_err(CE_WARN,
"XFS: quota support not available in this kernel.");
return EINVAL;
}
#endif
if ((mp->m_qflags & (XFS_GQUOTA_ACCT | XFS_GQUOTA_ACTIVE)) && if ((mp->m_qflags & (XFS_GQUOTA_ACCT | XFS_GQUOTA_ACTIVE)) &&
(mp->m_qflags & (XFS_PQUOTA_ACCT | XFS_PQUOTA_ACTIVE))) { (mp->m_qflags & (XFS_PQUOTA_ACCT | XFS_PQUOTA_ACTIVE))) {
cmn_err(CE_WARN, cmn_err(CE_WARN,
...@@ -1063,7 +1070,18 @@ xfs_fs_put_super( ...@@ -1063,7 +1070,18 @@ xfs_fs_put_super(
int unmount_event_flags = 0; int unmount_event_flags = 0;
xfs_syncd_stop(mp); xfs_syncd_stop(mp);
xfs_sync_inodes(mp, SYNC_ATTR|SYNC_DELWRI);
if (!(sb->s_flags & MS_RDONLY)) {
/*
* XXX(hch): this should be SYNC_WAIT.
*
* Or more likely not needed at all because the VFS is already
* calling ->sync_fs after shutting down all filestem
* operations and just before calling ->put_super.
*/
xfs_sync_data(mp, 0);
xfs_sync_attr(mp, 0);
}
#ifdef HAVE_DMAPI #ifdef HAVE_DMAPI
if (mp->m_flags & XFS_MOUNT_DMAPI) { if (mp->m_flags & XFS_MOUNT_DMAPI) {
...@@ -1098,7 +1116,6 @@ xfs_fs_put_super( ...@@ -1098,7 +1116,6 @@ xfs_fs_put_super(
xfs_freesb(mp); xfs_freesb(mp);
xfs_icsb_destroy_counters(mp); xfs_icsb_destroy_counters(mp);
xfs_close_devices(mp); xfs_close_devices(mp);
xfs_qmops_put(mp);
xfs_dmops_put(mp); xfs_dmops_put(mp);
xfs_free_fsname(mp); xfs_free_fsname(mp);
kfree(mp); kfree(mp);
...@@ -1158,6 +1175,7 @@ xfs_fs_statfs( ...@@ -1158,6 +1175,7 @@ xfs_fs_statfs(
{ {
struct xfs_mount *mp = XFS_M(dentry->d_sb); struct xfs_mount *mp = XFS_M(dentry->d_sb);
xfs_sb_t *sbp = &mp->m_sb; xfs_sb_t *sbp = &mp->m_sb;
struct xfs_inode *ip = XFS_I(dentry->d_inode);
__uint64_t fakeinos, id; __uint64_t fakeinos, id;
xfs_extlen_t lsize; xfs_extlen_t lsize;
...@@ -1186,7 +1204,10 @@ xfs_fs_statfs( ...@@ -1186,7 +1204,10 @@ xfs_fs_statfs(
statp->f_ffree = statp->f_files - (sbp->sb_icount - sbp->sb_ifree); statp->f_ffree = statp->f_files - (sbp->sb_icount - sbp->sb_ifree);
spin_unlock(&mp->m_sb_lock); spin_unlock(&mp->m_sb_lock);
XFS_QM_DQSTATVFS(XFS_I(dentry->d_inode), statp); if ((ip->i_d.di_flags & XFS_DIFLAG_PROJINHERIT) ||
((mp->m_qflags & (XFS_PQUOTA_ACCT|XFS_OQUOTA_ENFD))) ==
(XFS_PQUOTA_ACCT|XFS_OQUOTA_ENFD))
xfs_qm_statvfs(ip, statp);
return 0; return 0;
} }
...@@ -1394,16 +1415,13 @@ xfs_fs_fill_super( ...@@ -1394,16 +1415,13 @@ xfs_fs_fill_super(
error = xfs_dmops_get(mp); error = xfs_dmops_get(mp);
if (error) if (error)
goto out_free_fsname; goto out_free_fsname;
error = xfs_qmops_get(mp);
if (error)
goto out_put_dmops;
if (silent) if (silent)
flags |= XFS_MFSI_QUIET; flags |= XFS_MFSI_QUIET;
error = xfs_open_devices(mp); error = xfs_open_devices(mp);
if (error) if (error)
goto out_put_qmops; goto out_put_dmops;
if (xfs_icsb_init_counters(mp)) if (xfs_icsb_init_counters(mp))
mp->m_flags |= XFS_MOUNT_NO_PERCPU_SB; mp->m_flags |= XFS_MOUNT_NO_PERCPU_SB;
...@@ -1471,8 +1489,6 @@ xfs_fs_fill_super( ...@@ -1471,8 +1489,6 @@ xfs_fs_fill_super(
out_destroy_counters: out_destroy_counters:
xfs_icsb_destroy_counters(mp); xfs_icsb_destroy_counters(mp);
xfs_close_devices(mp); xfs_close_devices(mp);
out_put_qmops:
xfs_qmops_put(mp);
out_put_dmops: out_put_dmops:
xfs_dmops_put(mp); xfs_dmops_put(mp);
out_free_fsname: out_free_fsname:
...@@ -1706,18 +1722,8 @@ xfs_init_zones(void) ...@@ -1706,18 +1722,8 @@ xfs_init_zones(void)
if (!xfs_ili_zone) if (!xfs_ili_zone)
goto out_destroy_inode_zone; goto out_destroy_inode_zone;
#ifdef CONFIG_XFS_POSIX_ACL
xfs_acl_zone = kmem_zone_init(sizeof(xfs_acl_t), "xfs_acl");
if (!xfs_acl_zone)
goto out_destroy_ili_zone;
#endif
return 0; return 0;
#ifdef CONFIG_XFS_POSIX_ACL
out_destroy_ili_zone:
#endif
kmem_zone_destroy(xfs_ili_zone);
out_destroy_inode_zone: out_destroy_inode_zone:
kmem_zone_destroy(xfs_inode_zone); kmem_zone_destroy(xfs_inode_zone);
out_destroy_efi_zone: out_destroy_efi_zone:
...@@ -1751,9 +1757,6 @@ xfs_init_zones(void) ...@@ -1751,9 +1757,6 @@ xfs_init_zones(void)
STATIC void STATIC void
xfs_destroy_zones(void) xfs_destroy_zones(void)
{ {
#ifdef CONFIG_XFS_POSIX_ACL
kmem_zone_destroy(xfs_acl_zone);
#endif
kmem_zone_destroy(xfs_ili_zone); kmem_zone_destroy(xfs_ili_zone);
kmem_zone_destroy(xfs_inode_zone); kmem_zone_destroy(xfs_inode_zone);
kmem_zone_destroy(xfs_efi_zone); kmem_zone_destroy(xfs_efi_zone);
......
This diff is collapsed.
...@@ -29,17 +29,14 @@ typedef struct xfs_sync_work { ...@@ -29,17 +29,14 @@ typedef struct xfs_sync_work {
struct completion *w_completion; struct completion *w_completion;
} xfs_sync_work_t; } xfs_sync_work_t;
#define SYNC_ATTR 0x0001 /* sync attributes */ #define SYNC_WAIT 0x0001 /* wait for i/o to complete */
#define SYNC_DELWRI 0x0002 /* look at delayed writes */ #define SYNC_TRYLOCK 0x0002 /* only try to lock inodes */
#define SYNC_WAIT 0x0004 /* wait for i/o to complete */
#define SYNC_BDFLUSH 0x0008 /* BDFLUSH is calling -- don't block */
#define SYNC_IOWAIT 0x0010 /* wait for all I/O to complete */
#define SYNC_TRYLOCK 0x0020 /* only try to lock inodes */
int xfs_syncd_init(struct xfs_mount *mp); int xfs_syncd_init(struct xfs_mount *mp);
void xfs_syncd_stop(struct xfs_mount *mp); void xfs_syncd_stop(struct xfs_mount *mp);
int xfs_sync_inodes(struct xfs_mount *mp, int flags); int xfs_sync_attr(struct xfs_mount *mp, int flags);
int xfs_sync_data(struct xfs_mount *mp, int flags);
int xfs_sync_fsdata(struct xfs_mount *mp, int flags); int xfs_sync_fsdata(struct xfs_mount *mp, int flags);
int xfs_quiesce_data(struct xfs_mount *mp); int xfs_quiesce_data(struct xfs_mount *mp);
...@@ -48,10 +45,16 @@ void xfs_quiesce_attr(struct xfs_mount *mp); ...@@ -48,10 +45,16 @@ void xfs_quiesce_attr(struct xfs_mount *mp);
void xfs_flush_inodes(struct xfs_inode *ip); void xfs_flush_inodes(struct xfs_inode *ip);
int xfs_reclaim_inode(struct xfs_inode *ip, int locked, int sync_mode); int xfs_reclaim_inode(struct xfs_inode *ip, int locked, int sync_mode);
int xfs_reclaim_inodes(struct xfs_mount *mp, int noblock, int mode); int xfs_reclaim_inodes(struct xfs_mount *mp, int mode);
void xfs_inode_set_reclaim_tag(struct xfs_inode *ip); void xfs_inode_set_reclaim_tag(struct xfs_inode *ip);
void xfs_inode_clear_reclaim_tag(struct xfs_inode *ip); void xfs_inode_clear_reclaim_tag(struct xfs_inode *ip);
void __xfs_inode_clear_reclaim_tag(struct xfs_mount *mp, struct xfs_perag *pag, void __xfs_inode_clear_reclaim_tag(struct xfs_mount *mp, struct xfs_perag *pag,
struct xfs_inode *ip); struct xfs_inode *ip);
int xfs_sync_inode_valid(struct xfs_inode *ip, struct xfs_perag *pag);
int xfs_inode_ag_iterator(struct xfs_mount *mp,
int (*execute)(struct xfs_inode *ip, struct xfs_perag *pag, int flags),
int flags, int tag);
#endif #endif
...@@ -29,67 +29,6 @@ ...@@ -29,67 +29,6 @@
#include <linux/xattr.h> #include <linux/xattr.h>
/*
* ACL handling. Should eventually be moved into xfs_acl.c
*/
static int
xfs_decode_acl(const char *name)
{
if (strcmp(name, "posix_acl_access") == 0)
return _ACL_TYPE_ACCESS;
else if (strcmp(name, "posix_acl_default") == 0)
return _ACL_TYPE_DEFAULT;
return -EINVAL;
}
/*
* Get system extended attributes which at the moment only
* includes Posix ACLs.
*/
static int
xfs_xattr_system_get(struct inode *inode, const char *name,
void *buffer, size_t size)
{
int acl;
acl = xfs_decode_acl(name);
if (acl < 0)
return acl;
return xfs_acl_vget(inode, buffer, size, acl);
}
static int
xfs_xattr_system_set(struct inode *inode, const char *name,
const void *value, size_t size, int flags)
{
int acl;
acl = xfs_decode_acl(name);
if (acl < 0)
return acl;
if (flags & XATTR_CREATE)
return -EINVAL;
if (!value)
return xfs_acl_vremove(inode, acl);
return xfs_acl_vset(inode, (void *)value, size, acl);
}
static struct xattr_handler xfs_xattr_system_handler = {
.prefix = XATTR_SYSTEM_PREFIX,
.get = xfs_xattr_system_get,
.set = xfs_xattr_system_set,
};
/*
* Real xattr handling. The only difference between the namespaces is
* a flag passed to the low-level attr code.
*/
static int static int
__xfs_xattr_get(struct inode *inode, const char *name, __xfs_xattr_get(struct inode *inode, const char *name,
void *value, size_t size, int xflags) void *value, size_t size, int xflags)
...@@ -199,7 +138,9 @@ struct xattr_handler *xfs_xattr_handlers[] = { ...@@ -199,7 +138,9 @@ struct xattr_handler *xfs_xattr_handlers[] = {
&xfs_xattr_user_handler, &xfs_xattr_user_handler,
&xfs_xattr_trusted_handler, &xfs_xattr_trusted_handler,
&xfs_xattr_security_handler, &xfs_xattr_security_handler,
#ifdef CONFIG_XFS_POSIX_ACL
&xfs_xattr_system_handler, &xfs_xattr_system_handler,
#endif
NULL NULL
}; };
...@@ -310,7 +251,7 @@ xfs_vn_listxattr(struct dentry *dentry, char *data, size_t size) ...@@ -310,7 +251,7 @@ xfs_vn_listxattr(struct dentry *dentry, char *data, size_t size)
/* /*
* Then add the two synthetic ACL attributes. * Then add the two synthetic ACL attributes.
*/ */
if (xfs_acl_vhasacl_access(inode)) { if (posix_acl_access_exists(inode)) {
error = list_one_attr(POSIX_ACL_XATTR_ACCESS, error = list_one_attr(POSIX_ACL_XATTR_ACCESS,
strlen(POSIX_ACL_XATTR_ACCESS) + 1, strlen(POSIX_ACL_XATTR_ACCESS) + 1,
data, size, &context.count); data, size, &context.count);
...@@ -318,7 +259,7 @@ xfs_vn_listxattr(struct dentry *dentry, char *data, size_t size) ...@@ -318,7 +259,7 @@ xfs_vn_listxattr(struct dentry *dentry, char *data, size_t size)
return error; return error;
} }
if (xfs_acl_vhasacl_default(inode)) { if (posix_acl_default_exists(inode)) {
error = list_one_attr(POSIX_ACL_XATTR_DEFAULT, error = list_one_attr(POSIX_ACL_XATTR_DEFAULT,
strlen(POSIX_ACL_XATTR_DEFAULT) + 1, strlen(POSIX_ACL_XATTR_DEFAULT) + 1,
data, size, &context.count); data, size, &context.count);
......
...@@ -42,7 +42,6 @@ ...@@ -42,7 +42,6 @@
#include "xfs_error.h" #include "xfs_error.h"
#include "xfs_itable.h" #include "xfs_itable.h"
#include "xfs_rw.h" #include "xfs_rw.h"
#include "xfs_acl.h"
#include "xfs_attr.h" #include "xfs_attr.h"
#include "xfs_buf_item.h" #include "xfs_buf_item.h"
#include "xfs_trans_space.h" #include "xfs_trans_space.h"
...@@ -1194,7 +1193,9 @@ void ...@@ -1194,7 +1193,9 @@ void
xfs_qm_dqrele( xfs_qm_dqrele(
xfs_dquot_t *dqp) xfs_dquot_t *dqp)
{ {
ASSERT(dqp); if (!dqp)
return;
xfs_dqtrace_entry(dqp, "DQRELE"); xfs_dqtrace_entry(dqp, "DQRELE");
xfs_dqlock(dqp); xfs_dqlock(dqp);
......
...@@ -181,7 +181,6 @@ extern void xfs_qm_adjust_dqlimits(xfs_mount_t *, ...@@ -181,7 +181,6 @@ extern void xfs_qm_adjust_dqlimits(xfs_mount_t *,
extern int xfs_qm_dqget(xfs_mount_t *, xfs_inode_t *, extern int xfs_qm_dqget(xfs_mount_t *, xfs_inode_t *,
xfs_dqid_t, uint, uint, xfs_dquot_t **); xfs_dqid_t, uint, uint, xfs_dquot_t **);
extern void xfs_qm_dqput(xfs_dquot_t *); extern void xfs_qm_dqput(xfs_dquot_t *);
extern void xfs_qm_dqrele(xfs_dquot_t *);
extern void xfs_dqlock(xfs_dquot_t *); extern void xfs_dqlock(xfs_dquot_t *);
extern void xfs_dqlock2(xfs_dquot_t *, xfs_dquot_t *); extern void xfs_dqlock2(xfs_dquot_t *, xfs_dquot_t *);
extern void xfs_dqunlock(xfs_dquot_t *); extern void xfs_dqunlock(xfs_dquot_t *);
......
...@@ -42,7 +42,6 @@ ...@@ -42,7 +42,6 @@
#include "xfs_error.h" #include "xfs_error.h"
#include "xfs_itable.h" #include "xfs_itable.h"
#include "xfs_rw.h" #include "xfs_rw.h"
#include "xfs_acl.h"
#include "xfs_attr.h" #include "xfs_attr.h"
#include "xfs_buf_item.h" #include "xfs_buf_item.h"
#include "xfs_trans_priv.h" #include "xfs_trans_priv.h"
......
...@@ -42,7 +42,6 @@ ...@@ -42,7 +42,6 @@
#include "xfs_error.h" #include "xfs_error.h"
#include "xfs_bmap.h" #include "xfs_bmap.h"
#include "xfs_rw.h" #include "xfs_rw.h"
#include "xfs_acl.h"
#include "xfs_attr.h" #include "xfs_attr.h"
#include "xfs_buf_item.h" #include "xfs_buf_item.h"
#include "xfs_trans_space.h" #include "xfs_trans_space.h"
...@@ -287,11 +286,13 @@ xfs_qm_rele_quotafs_ref( ...@@ -287,11 +286,13 @@ xfs_qm_rele_quotafs_ref(
* Just destroy the quotainfo structure. * Just destroy the quotainfo structure.
*/ */
void void
xfs_qm_unmount_quotadestroy( xfs_qm_unmount(
xfs_mount_t *mp) struct xfs_mount *mp)
{ {
if (mp->m_quotainfo) if (mp->m_quotainfo) {
xfs_qm_dqpurge_all(mp, XFS_QMOPT_QUOTALL | XFS_QMOPT_UMOUNTING);
xfs_qm_destroy_quotainfo(mp); xfs_qm_destroy_quotainfo(mp);
}
} }
...@@ -385,8 +386,13 @@ xfs_qm_mount_quotas( ...@@ -385,8 +386,13 @@ xfs_qm_mount_quotas(
if (error) { if (error) {
xfs_fs_cmn_err(CE_WARN, mp, xfs_fs_cmn_err(CE_WARN, mp,
"Failed to initialize disk quotas."); "Failed to initialize disk quotas.");
return;
} }
return;
#ifdef QUOTADEBUG
if (XFS_IS_QUOTA_ON(mp))
xfs_qm_internalqcheck(mp);
#endif
} }
/* /*
...@@ -774,12 +780,11 @@ xfs_qm_dqattach_grouphint( ...@@ -774,12 +780,11 @@ xfs_qm_dqattach_grouphint(
* Given a locked inode, attach dquot(s) to it, taking U/G/P-QUOTAON * Given a locked inode, attach dquot(s) to it, taking U/G/P-QUOTAON
* into account. * into account.
* If XFS_QMOPT_DQALLOC, the dquot(s) will be allocated if needed. * If XFS_QMOPT_DQALLOC, the dquot(s) will be allocated if needed.
* If XFS_QMOPT_ILOCKED, then inode sent is already locked EXCL.
* Inode may get unlocked and relocked in here, and the caller must deal with * Inode may get unlocked and relocked in here, and the caller must deal with
* the consequences. * the consequences.
*/ */
int int
xfs_qm_dqattach( xfs_qm_dqattach_locked(
xfs_inode_t *ip, xfs_inode_t *ip,
uint flags) uint flags)
{ {
...@@ -787,17 +792,14 @@ xfs_qm_dqattach( ...@@ -787,17 +792,14 @@ xfs_qm_dqattach(
uint nquotas = 0; uint nquotas = 0;
int error = 0; int error = 0;
if ((! XFS_IS_QUOTA_ON(mp)) || if (!XFS_IS_QUOTA_RUNNING(mp) ||
(! XFS_NOT_DQATTACHED(mp, ip)) || !XFS_IS_QUOTA_ON(mp) ||
(ip->i_ino == mp->m_sb.sb_uquotino) || !XFS_NOT_DQATTACHED(mp, ip) ||
(ip->i_ino == mp->m_sb.sb_gquotino)) ip->i_ino == mp->m_sb.sb_uquotino ||
ip->i_ino == mp->m_sb.sb_gquotino)
return 0; return 0;
ASSERT((flags & XFS_QMOPT_ILOCKED) == 0 || ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL));
xfs_isilocked(ip, XFS_ILOCK_EXCL));
if (! (flags & XFS_QMOPT_ILOCKED))
xfs_ilock(ip, XFS_ILOCK_EXCL);
if (XFS_IS_UQUOTA_ON(mp)) { if (XFS_IS_UQUOTA_ON(mp)) {
error = xfs_qm_dqattach_one(ip, ip->i_d.di_uid, XFS_DQ_USER, error = xfs_qm_dqattach_one(ip, ip->i_d.di_uid, XFS_DQ_USER,
...@@ -849,8 +851,7 @@ xfs_qm_dqattach( ...@@ -849,8 +851,7 @@ xfs_qm_dqattach(
xfs_qm_dqattach_grouphint(ip->i_udquot, ip->i_gdquot); xfs_qm_dqattach_grouphint(ip->i_udquot, ip->i_gdquot);
} }
done: done:
#ifdef QUOTADEBUG #ifdef QUOTADEBUG
if (! error) { if (! error) {
if (XFS_IS_UQUOTA_ON(mp)) if (XFS_IS_UQUOTA_ON(mp))
...@@ -858,15 +859,22 @@ xfs_qm_dqattach( ...@@ -858,15 +859,22 @@ xfs_qm_dqattach(
if (XFS_IS_OQUOTA_ON(mp)) if (XFS_IS_OQUOTA_ON(mp))
ASSERT(ip->i_gdquot); ASSERT(ip->i_gdquot);
} }
ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL));
#endif #endif
return error;
}
if (! (flags & XFS_QMOPT_ILOCKED)) int
xfs_iunlock(ip, XFS_ILOCK_EXCL); xfs_qm_dqattach(
struct xfs_inode *ip,
uint flags)
{
int error;
xfs_ilock(ip, XFS_ILOCK_EXCL);
error = xfs_qm_dqattach_locked(ip, flags);
xfs_iunlock(ip, XFS_ILOCK_EXCL);
#ifdef QUOTADEBUG
else
ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL));
#endif
return error; return error;
} }
...@@ -896,11 +904,6 @@ xfs_qm_dqdetach( ...@@ -896,11 +904,6 @@ xfs_qm_dqdetach(
} }
} }
/*
* This is called to sync quotas. We can be told to use non-blocking
* semantics by either the SYNC_BDFLUSH flag or the absence of the
* SYNC_WAIT flag.
*/
int int
xfs_qm_sync( xfs_qm_sync(
xfs_mount_t *mp, xfs_mount_t *mp,
...@@ -909,17 +912,13 @@ xfs_qm_sync( ...@@ -909,17 +912,13 @@ xfs_qm_sync(
int recl, restarts; int recl, restarts;
xfs_dquot_t *dqp; xfs_dquot_t *dqp;
uint flush_flags; uint flush_flags;
boolean_t nowait;
int error; int error;
if (! XFS_IS_QUOTA_ON(mp)) if (!XFS_IS_QUOTA_RUNNING(mp) || !XFS_IS_QUOTA_ON(mp))
return 0; return 0;
flush_flags = (flags & SYNC_WAIT) ? XFS_QMOPT_SYNC : XFS_QMOPT_DELWRI;
restarts = 0; restarts = 0;
/*
* We won't block unless we are asked to.
*/
nowait = (boolean_t)(flags & SYNC_BDFLUSH || (flags & SYNC_WAIT) == 0);
again: again:
xfs_qm_mplist_lock(mp); xfs_qm_mplist_lock(mp);
...@@ -939,18 +938,10 @@ xfs_qm_sync( ...@@ -939,18 +938,10 @@ xfs_qm_sync(
* don't 'seem' to be dirty. ie. don't acquire dqlock. * don't 'seem' to be dirty. ie. don't acquire dqlock.
* This is very similar to what xfs_sync does with inodes. * This is very similar to what xfs_sync does with inodes.
*/ */
if (flags & SYNC_BDFLUSH) { if (flags & SYNC_TRYLOCK) {
if (! XFS_DQ_IS_DIRTY(dqp)) if (!XFS_DQ_IS_DIRTY(dqp))
continue; continue;
} if (!xfs_qm_dqlock_nowait(dqp))
if (nowait) {
/*
* Try to acquire the dquot lock. We are NOT out of
* lock order, but we just don't want to wait for this
* lock, unless somebody wanted us to.
*/
if (! xfs_qm_dqlock_nowait(dqp))
continue; continue;
} else { } else {
xfs_dqlock(dqp); xfs_dqlock(dqp);
...@@ -967,7 +958,7 @@ xfs_qm_sync( ...@@ -967,7 +958,7 @@ xfs_qm_sync(
/* XXX a sentinel would be better */ /* XXX a sentinel would be better */
recl = XFS_QI_MPLRECLAIMS(mp); recl = XFS_QI_MPLRECLAIMS(mp);
if (!xfs_dqflock_nowait(dqp)) { if (!xfs_dqflock_nowait(dqp)) {
if (nowait) { if (flags & SYNC_TRYLOCK) {
xfs_dqunlock(dqp); xfs_dqunlock(dqp);
continue; continue;
} }
...@@ -985,7 +976,6 @@ xfs_qm_sync( ...@@ -985,7 +976,6 @@ xfs_qm_sync(
* Let go of the mplist lock. We don't want to hold it * Let go of the mplist lock. We don't want to hold it
* across a disk write * across a disk write
*/ */
flush_flags = (nowait) ? XFS_QMOPT_DELWRI : XFS_QMOPT_SYNC;
xfs_qm_mplist_unlock(mp); xfs_qm_mplist_unlock(mp);
xfs_dqtrace_entry(dqp, "XQM_SYNC: DQFLUSH"); xfs_dqtrace_entry(dqp, "XQM_SYNC: DQFLUSH");
error = xfs_qm_dqflush(dqp, flush_flags); error = xfs_qm_dqflush(dqp, flush_flags);
...@@ -2319,20 +2309,20 @@ xfs_qm_write_sb_changes( ...@@ -2319,20 +2309,20 @@ xfs_qm_write_sb_changes(
*/ */
int int
xfs_qm_vop_dqalloc( xfs_qm_vop_dqalloc(
xfs_mount_t *mp, struct xfs_inode *ip,
xfs_inode_t *ip, uid_t uid,
uid_t uid, gid_t gid,
gid_t gid, prid_t prid,
prid_t prid, uint flags,
uint flags, struct xfs_dquot **O_udqpp,
xfs_dquot_t **O_udqpp, struct xfs_dquot **O_gdqpp)
xfs_dquot_t **O_gdqpp)
{ {
int error; struct xfs_mount *mp = ip->i_mount;
xfs_dquot_t *uq, *gq; struct xfs_dquot *uq, *gq;
uint lockflags; int error;
uint lockflags;
if (!XFS_IS_QUOTA_ON(mp)) if (!XFS_IS_QUOTA_RUNNING(mp) || !XFS_IS_QUOTA_ON(mp))
return 0; return 0;
lockflags = XFS_ILOCK_EXCL; lockflags = XFS_ILOCK_EXCL;
...@@ -2346,8 +2336,8 @@ xfs_qm_vop_dqalloc( ...@@ -2346,8 +2336,8 @@ xfs_qm_vop_dqalloc(
* if necessary. The dquot(s) will not be locked. * if necessary. The dquot(s) will not be locked.
*/ */
if (XFS_NOT_DQATTACHED(mp, ip)) { if (XFS_NOT_DQATTACHED(mp, ip)) {
if ((error = xfs_qm_dqattach(ip, XFS_QMOPT_DQALLOC | error = xfs_qm_dqattach_locked(ip, XFS_QMOPT_DQALLOC);
XFS_QMOPT_ILOCKED))) { if (error) {
xfs_iunlock(ip, lockflags); xfs_iunlock(ip, lockflags);
return error; return error;
} }
...@@ -2469,6 +2459,7 @@ xfs_qm_vop_chown( ...@@ -2469,6 +2459,7 @@ xfs_qm_vop_chown(
uint bfield = XFS_IS_REALTIME_INODE(ip) ? uint bfield = XFS_IS_REALTIME_INODE(ip) ?
XFS_TRANS_DQ_RTBCOUNT : XFS_TRANS_DQ_BCOUNT; XFS_TRANS_DQ_RTBCOUNT : XFS_TRANS_DQ_BCOUNT;
ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL)); ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL));
ASSERT(XFS_IS_QUOTA_RUNNING(ip->i_mount)); ASSERT(XFS_IS_QUOTA_RUNNING(ip->i_mount));
...@@ -2508,13 +2499,13 @@ xfs_qm_vop_chown_reserve( ...@@ -2508,13 +2499,13 @@ xfs_qm_vop_chown_reserve(
xfs_dquot_t *gdqp, xfs_dquot_t *gdqp,
uint flags) uint flags)
{ {
int error; xfs_mount_t *mp = ip->i_mount;
xfs_mount_t *mp;
uint delblks, blkflags, prjflags = 0; uint delblks, blkflags, prjflags = 0;
xfs_dquot_t *unresudq, *unresgdq, *delblksudq, *delblksgdq; xfs_dquot_t *unresudq, *unresgdq, *delblksudq, *delblksgdq;
int error;
ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL|XFS_ILOCK_SHARED)); ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL|XFS_ILOCK_SHARED));
mp = ip->i_mount;
ASSERT(XFS_IS_QUOTA_RUNNING(mp)); ASSERT(XFS_IS_QUOTA_RUNNING(mp));
delblks = ip->i_delayed_blks; delblks = ip->i_delayed_blks;
...@@ -2582,28 +2573,23 @@ xfs_qm_vop_chown_reserve( ...@@ -2582,28 +2573,23 @@ xfs_qm_vop_chown_reserve(
int int
xfs_qm_vop_rename_dqattach( xfs_qm_vop_rename_dqattach(
xfs_inode_t **i_tab) struct xfs_inode **i_tab)
{ {
xfs_inode_t *ip; struct xfs_mount *mp = i_tab[0]->i_mount;
int i; int i;
int error;
ip = i_tab[0]; if (!XFS_IS_QUOTA_RUNNING(mp) || !XFS_IS_QUOTA_ON(mp))
if (! XFS_IS_QUOTA_ON(ip->i_mount))
return 0; return 0;
if (XFS_NOT_DQATTACHED(ip->i_mount, ip)) { for (i = 0; (i < 4 && i_tab[i]); i++) {
error = xfs_qm_dqattach(ip, 0); struct xfs_inode *ip = i_tab[i];
if (error) int error;
return error;
}
for (i = 1; (i < 4 && i_tab[i]); i++) {
/* /*
* Watch out for duplicate entries in the table. * Watch out for duplicate entries in the table.
*/ */
if ((ip = i_tab[i]) != i_tab[i-1]) { if (i == 0 || ip != i_tab[i-1]) {
if (XFS_NOT_DQATTACHED(ip->i_mount, ip)) { if (XFS_NOT_DQATTACHED(mp, ip)) {
error = xfs_qm_dqattach(ip, 0); error = xfs_qm_dqattach(ip, 0);
if (error) if (error)
return error; return error;
...@@ -2614,17 +2600,19 @@ xfs_qm_vop_rename_dqattach( ...@@ -2614,17 +2600,19 @@ xfs_qm_vop_rename_dqattach(
} }
void void
xfs_qm_vop_dqattach_and_dqmod_newinode( xfs_qm_vop_create_dqattach(
xfs_trans_t *tp, struct xfs_trans *tp,
xfs_inode_t *ip, struct xfs_inode *ip,
xfs_dquot_t *udqp, struct xfs_dquot *udqp,
xfs_dquot_t *gdqp) struct xfs_dquot *gdqp)
{ {
if (!XFS_IS_QUOTA_ON(tp->t_mountp)) struct xfs_mount *mp = tp->t_mountp;
if (!XFS_IS_QUOTA_RUNNING(mp) || !XFS_IS_QUOTA_ON(mp))
return; return;
ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL)); ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL));
ASSERT(XFS_IS_QUOTA_RUNNING(tp->t_mountp)); ASSERT(XFS_IS_QUOTA_RUNNING(mp));
if (udqp) { if (udqp) {
xfs_dqlock(udqp); xfs_dqlock(udqp);
...@@ -2632,7 +2620,7 @@ xfs_qm_vop_dqattach_and_dqmod_newinode( ...@@ -2632,7 +2620,7 @@ xfs_qm_vop_dqattach_and_dqmod_newinode(
xfs_dqunlock(udqp); xfs_dqunlock(udqp);
ASSERT(ip->i_udquot == NULL); ASSERT(ip->i_udquot == NULL);
ip->i_udquot = udqp; ip->i_udquot = udqp;
ASSERT(XFS_IS_UQUOTA_ON(tp->t_mountp)); ASSERT(XFS_IS_UQUOTA_ON(mp));
ASSERT(ip->i_d.di_uid == be32_to_cpu(udqp->q_core.d_id)); ASSERT(ip->i_d.di_uid == be32_to_cpu(udqp->q_core.d_id));
xfs_trans_mod_dquot(tp, udqp, XFS_TRANS_DQ_ICOUNT, 1); xfs_trans_mod_dquot(tp, udqp, XFS_TRANS_DQ_ICOUNT, 1);
} }
...@@ -2642,8 +2630,8 @@ xfs_qm_vop_dqattach_and_dqmod_newinode( ...@@ -2642,8 +2630,8 @@ xfs_qm_vop_dqattach_and_dqmod_newinode(
xfs_dqunlock(gdqp); xfs_dqunlock(gdqp);
ASSERT(ip->i_gdquot == NULL); ASSERT(ip->i_gdquot == NULL);
ip->i_gdquot = gdqp; ip->i_gdquot = gdqp;
ASSERT(XFS_IS_OQUOTA_ON(tp->t_mountp)); ASSERT(XFS_IS_OQUOTA_ON(mp));
ASSERT((XFS_IS_GQUOTA_ON(tp->t_mountp) ? ASSERT((XFS_IS_GQUOTA_ON(mp) ?
ip->i_d.di_gid : ip->i_d.di_projid) == ip->i_d.di_gid : ip->i_d.di_projid) ==
be32_to_cpu(gdqp->q_core.d_id)); be32_to_cpu(gdqp->q_core.d_id));
xfs_trans_mod_dquot(tp, gdqp, XFS_TRANS_DQ_ICOUNT, 1); xfs_trans_mod_dquot(tp, gdqp, XFS_TRANS_DQ_ICOUNT, 1);
......
...@@ -127,8 +127,6 @@ typedef struct xfs_quotainfo { ...@@ -127,8 +127,6 @@ typedef struct xfs_quotainfo {
} xfs_quotainfo_t; } xfs_quotainfo_t;
extern xfs_dqtrxops_t xfs_trans_dquot_ops;
extern void xfs_trans_mod_dquot(xfs_trans_t *, xfs_dquot_t *, uint, long); extern void xfs_trans_mod_dquot(xfs_trans_t *, xfs_dquot_t *, uint, long);
extern int xfs_trans_reserve_quota_bydquots(xfs_trans_t *, xfs_mount_t *, extern int xfs_trans_reserve_quota_bydquots(xfs_trans_t *, xfs_mount_t *,
xfs_dquot_t *, xfs_dquot_t *, long, long, uint); xfs_dquot_t *, xfs_dquot_t *, long, long, uint);
...@@ -159,17 +157,11 @@ typedef struct xfs_dquot_acct { ...@@ -159,17 +157,11 @@ typedef struct xfs_dquot_acct {
#define XFS_QM_RTBWARNLIMIT 5 #define XFS_QM_RTBWARNLIMIT 5
extern void xfs_qm_destroy_quotainfo(xfs_mount_t *); extern void xfs_qm_destroy_quotainfo(xfs_mount_t *);
extern void xfs_qm_mount_quotas(xfs_mount_t *);
extern int xfs_qm_quotacheck(xfs_mount_t *); extern int xfs_qm_quotacheck(xfs_mount_t *);
extern void xfs_qm_unmount_quotadestroy(xfs_mount_t *);
extern void xfs_qm_unmount_quotas(xfs_mount_t *);
extern int xfs_qm_write_sb_changes(xfs_mount_t *, __int64_t); extern int xfs_qm_write_sb_changes(xfs_mount_t *, __int64_t);
extern int xfs_qm_sync(xfs_mount_t *, int);
/* dquot stuff */ /* dquot stuff */
extern boolean_t xfs_qm_dqalloc_incore(xfs_dquot_t **); extern boolean_t xfs_qm_dqalloc_incore(xfs_dquot_t **);
extern int xfs_qm_dqattach(xfs_inode_t *, uint);
extern void xfs_qm_dqdetach(xfs_inode_t *);
extern int xfs_qm_dqpurge_all(xfs_mount_t *, uint); extern int xfs_qm_dqpurge_all(xfs_mount_t *, uint);
extern void xfs_qm_dqrele_all_inodes(xfs_mount_t *, uint); extern void xfs_qm_dqrele_all_inodes(xfs_mount_t *, uint);
...@@ -183,19 +175,6 @@ extern int xfs_qm_scall_getqstat(xfs_mount_t *, fs_quota_stat_t *); ...@@ -183,19 +175,6 @@ extern int xfs_qm_scall_getqstat(xfs_mount_t *, fs_quota_stat_t *);
extern int xfs_qm_scall_quotaon(xfs_mount_t *, uint); extern int xfs_qm_scall_quotaon(xfs_mount_t *, uint);
extern int xfs_qm_scall_quotaoff(xfs_mount_t *, uint); extern int xfs_qm_scall_quotaoff(xfs_mount_t *, uint);
/* vop stuff */
extern int xfs_qm_vop_dqalloc(xfs_mount_t *, xfs_inode_t *,
uid_t, gid_t, prid_t, uint,
xfs_dquot_t **, xfs_dquot_t **);
extern void xfs_qm_vop_dqattach_and_dqmod_newinode(
xfs_trans_t *, xfs_inode_t *,
xfs_dquot_t *, xfs_dquot_t *);
extern int xfs_qm_vop_rename_dqattach(xfs_inode_t **);
extern xfs_dquot_t * xfs_qm_vop_chown(xfs_trans_t *, xfs_inode_t *,
xfs_dquot_t **, xfs_dquot_t *);
extern int xfs_qm_vop_chown_reserve(xfs_trans_t *, xfs_inode_t *,
xfs_dquot_t *, xfs_dquot_t *, uint);
/* list stuff */ /* list stuff */
extern void xfs_qm_freelist_append(xfs_frlist_t *, xfs_dquot_t *); extern void xfs_qm_freelist_append(xfs_frlist_t *, xfs_dquot_t *);
extern void xfs_qm_freelist_unlink(xfs_dquot_t *); extern void xfs_qm_freelist_unlink(xfs_dquot_t *);
......
...@@ -42,7 +42,6 @@ ...@@ -42,7 +42,6 @@
#include "xfs_rtalloc.h" #include "xfs_rtalloc.h"
#include "xfs_error.h" #include "xfs_error.h"
#include "xfs_rw.h" #include "xfs_rw.h"
#include "xfs_acl.h"
#include "xfs_attr.h" #include "xfs_attr.h"
#include "xfs_buf_item.h" #include "xfs_buf_item.h"
#include "xfs_qm.h" #include "xfs_qm.h"
...@@ -84,7 +83,7 @@ xfs_fill_statvfs_from_dquot( ...@@ -84,7 +83,7 @@ xfs_fill_statvfs_from_dquot(
* return a statvfs of the project, not the entire filesystem. * return a statvfs of the project, not the entire filesystem.
* This makes such trees appear as if they are filesystems in themselves. * This makes such trees appear as if they are filesystems in themselves.
*/ */
STATIC void void
xfs_qm_statvfs( xfs_qm_statvfs(
xfs_inode_t *ip, xfs_inode_t *ip,
struct kstatfs *statp) struct kstatfs *statp)
...@@ -92,20 +91,13 @@ xfs_qm_statvfs( ...@@ -92,20 +91,13 @@ xfs_qm_statvfs(
xfs_mount_t *mp = ip->i_mount; xfs_mount_t *mp = ip->i_mount;
xfs_dquot_t *dqp; xfs_dquot_t *dqp;
if (!(ip->i_d.di_flags & XFS_DIFLAG_PROJINHERIT) ||
!((mp->m_qflags & (XFS_PQUOTA_ACCT|XFS_OQUOTA_ENFD))) ==
(XFS_PQUOTA_ACCT|XFS_OQUOTA_ENFD))
return;
if (!xfs_qm_dqget(mp, NULL, ip->i_d.di_projid, XFS_DQ_PROJ, 0, &dqp)) { if (!xfs_qm_dqget(mp, NULL, ip->i_d.di_projid, XFS_DQ_PROJ, 0, &dqp)) {
xfs_disk_dquot_t *dp = &dqp->q_core; xfs_fill_statvfs_from_dquot(statp, &dqp->q_core);
xfs_fill_statvfs_from_dquot(statp, dp);
xfs_qm_dqput(dqp); xfs_qm_dqput(dqp);
} }
} }
STATIC int int
xfs_qm_newmount( xfs_qm_newmount(
xfs_mount_t *mp, xfs_mount_t *mp,
uint *needquotamount, uint *needquotamount,
...@@ -114,9 +106,6 @@ xfs_qm_newmount( ...@@ -114,9 +106,6 @@ xfs_qm_newmount(
uint quotaondisk; uint quotaondisk;
uint uquotaondisk = 0, gquotaondisk = 0, pquotaondisk = 0; uint uquotaondisk = 0, gquotaondisk = 0, pquotaondisk = 0;
*quotaflags = 0;
*needquotamount = B_FALSE;
quotaondisk = xfs_sb_version_hasquota(&mp->m_sb) && quotaondisk = xfs_sb_version_hasquota(&mp->m_sb) &&
(mp->m_sb.sb_qflags & XFS_ALL_QUOTA_ACCT); (mp->m_sb.sb_qflags & XFS_ALL_QUOTA_ACCT);
...@@ -179,66 +168,6 @@ xfs_qm_newmount( ...@@ -179,66 +168,6 @@ xfs_qm_newmount(
return 0; return 0;
} }
STATIC int
xfs_qm_endmount(
xfs_mount_t *mp,
uint needquotamount,
uint quotaflags)
{
if (needquotamount) {
ASSERT(mp->m_qflags == 0);
mp->m_qflags = quotaflags;
xfs_qm_mount_quotas(mp);
}
#if defined(DEBUG) && defined(XFS_LOUD_RECOVERY)
if (! (XFS_IS_QUOTA_ON(mp)))
xfs_fs_cmn_err(CE_NOTE, mp, "Disk quotas not turned on");
else
xfs_fs_cmn_err(CE_NOTE, mp, "Disk quotas turned on");
#endif
#ifdef QUOTADEBUG
if (XFS_IS_QUOTA_ON(mp) && xfs_qm_internalqcheck(mp))
cmn_err(CE_WARN, "XFS: mount internalqcheck failed");
#endif
return 0;
}
STATIC void
xfs_qm_dqrele_null(
xfs_dquot_t *dq)
{
/*
* Called from XFS, where we always check first for a NULL dquot.
*/
if (!dq)
return;
xfs_qm_dqrele(dq);
}
struct xfs_qmops xfs_qmcore_xfs = {
.xfs_qminit = xfs_qm_newmount,
.xfs_qmdone = xfs_qm_unmount_quotadestroy,
.xfs_qmmount = xfs_qm_endmount,
.xfs_qmunmount = xfs_qm_unmount_quotas,
.xfs_dqrele = xfs_qm_dqrele_null,
.xfs_dqattach = xfs_qm_dqattach,
.xfs_dqdetach = xfs_qm_dqdetach,
.xfs_dqpurgeall = xfs_qm_dqpurge_all,
.xfs_dqvopalloc = xfs_qm_vop_dqalloc,
.xfs_dqvopcreate = xfs_qm_vop_dqattach_and_dqmod_newinode,
.xfs_dqvoprename = xfs_qm_vop_rename_dqattach,
.xfs_dqvopchown = xfs_qm_vop_chown,
.xfs_dqvopchownresv = xfs_qm_vop_chown_reserve,
.xfs_dqstatvfs = xfs_qm_statvfs,
.xfs_dqsync = xfs_qm_sync,
.xfs_dqtrxops = &xfs_trans_dquot_ops,
};
EXPORT_SYMBOL(xfs_qmcore_xfs);
void __init void __init
xfs_qm_init(void) xfs_qm_init(void)
{ {
......
...@@ -42,7 +42,6 @@ ...@@ -42,7 +42,6 @@
#include "xfs_rtalloc.h" #include "xfs_rtalloc.h"
#include "xfs_error.h" #include "xfs_error.h"
#include "xfs_rw.h" #include "xfs_rw.h"
#include "xfs_acl.h"
#include "xfs_attr.h" #include "xfs_attr.h"
#include "xfs_buf_item.h" #include "xfs_buf_item.h"
#include "xfs_qm.h" #include "xfs_qm.h"
......
...@@ -45,7 +45,6 @@ ...@@ -45,7 +45,6 @@
#include "xfs_rtalloc.h" #include "xfs_rtalloc.h"
#include "xfs_error.h" #include "xfs_error.h"
#include "xfs_rw.h" #include "xfs_rw.h"
#include "xfs_acl.h"
#include "xfs_attr.h" #include "xfs_attr.h"
#include "xfs_buf_item.h" #include "xfs_buf_item.h"
#include "xfs_utils.h" #include "xfs_utils.h"
...@@ -847,105 +846,55 @@ xfs_qm_export_flags( ...@@ -847,105 +846,55 @@ xfs_qm_export_flags(
} }
/* STATIC int
* Release all the dquots on the inodes in an AG. xfs_dqrele_inode(
*/ struct xfs_inode *ip,
STATIC void struct xfs_perag *pag,
xfs_qm_dqrele_inodes_ag( int flags)
xfs_mount_t *mp,
int ag,
uint flags)
{ {
xfs_inode_t *ip = NULL; int error;
xfs_perag_t *pag = &mp->m_perag[ag];
int first_index = 0;
int nr_found;
do {
/*
* use a gang lookup to find the next inode in the tree
* as the tree is sparse and a gang lookup walks to find
* the number of objects requested.
*/
read_lock(&pag->pag_ici_lock);
nr_found = radix_tree_gang_lookup(&pag->pag_ici_root,
(void**)&ip, first_index, 1);
if (!nr_found) {
read_unlock(&pag->pag_ici_lock);
break;
}
/*
* Update the index for the next lookup. Catch overflows
* into the next AG range which can occur if we have inodes
* in the last block of the AG and we are currently
* pointing to the last inode.
*/
first_index = XFS_INO_TO_AGINO(mp, ip->i_ino + 1);
if (first_index < XFS_INO_TO_AGINO(mp, ip->i_ino)) {
read_unlock(&pag->pag_ici_lock);
break;
}
/* skip quota inodes */
if (ip == XFS_QI_UQIP(mp) || ip == XFS_QI_GQIP(mp)) {
ASSERT(ip->i_udquot == NULL);
ASSERT(ip->i_gdquot == NULL);
read_unlock(&pag->pag_ici_lock);
continue;
}
/* /* skip quota inodes */
* If we can't get a reference on the inode, it must be if (ip == XFS_QI_UQIP(ip->i_mount) || ip == XFS_QI_GQIP(ip->i_mount)) {
* in reclaim. Leave it for the reclaim code to flush. ASSERT(ip->i_udquot == NULL);
*/ ASSERT(ip->i_gdquot == NULL);
if (!igrab(VFS_I(ip))) {
read_unlock(&pag->pag_ici_lock);
continue;
}
read_unlock(&pag->pag_ici_lock); read_unlock(&pag->pag_ici_lock);
return 0;
}
/* avoid new inodes though we shouldn't find any here */ error = xfs_sync_inode_valid(ip, pag);
if (xfs_iflags_test(ip, XFS_INEW)) { if (error)
IRELE(ip); return error;
continue;
}
xfs_ilock(ip, XFS_ILOCK_EXCL); xfs_ilock(ip, XFS_ILOCK_EXCL);
if ((flags & XFS_UQUOTA_ACCT) && ip->i_udquot) { if ((flags & XFS_UQUOTA_ACCT) && ip->i_udquot) {
xfs_qm_dqrele(ip->i_udquot); xfs_qm_dqrele(ip->i_udquot);
ip->i_udquot = NULL; ip->i_udquot = NULL;
} }
if (flags & (XFS_PQUOTA_ACCT|XFS_GQUOTA_ACCT) && if (flags & (XFS_PQUOTA_ACCT|XFS_GQUOTA_ACCT) && ip->i_gdquot) {
ip->i_gdquot) { xfs_qm_dqrele(ip->i_gdquot);
xfs_qm_dqrele(ip->i_gdquot); ip->i_gdquot = NULL;
ip->i_gdquot = NULL; }
} xfs_iput(ip, XFS_ILOCK_EXCL);
xfs_iput(ip, XFS_ILOCK_EXCL); IRELE(ip);
} while (nr_found); return 0;
} }
/* /*
* Go thru all the inodes in the file system, releasing their dquots. * Go thru all the inodes in the file system, releasing their dquots.
*
* Note that the mount structure gets modified to indicate that quotas are off * Note that the mount structure gets modified to indicate that quotas are off
* AFTER this, in the case of quotaoff. This also gets called from * AFTER this, in the case of quotaoff.
* xfs_rootumount.
*/ */
void void
xfs_qm_dqrele_all_inodes( xfs_qm_dqrele_all_inodes(
struct xfs_mount *mp, struct xfs_mount *mp,
uint flags) uint flags)
{ {
int i;
ASSERT(mp->m_quotainfo); ASSERT(mp->m_quotainfo);
for (i = 0; i < mp->m_sb.sb_agcount; i++) { xfs_inode_ag_iterator(mp, xfs_dqrele_inode, flags, XFS_ICI_NO_TAG);
if (!mp->m_perag[i].pag_ici_init)
continue;
xfs_qm_dqrele_inodes_ag(mp, i, flags);
}
} }
/*------------------------------------------------------------------------*/ /*------------------------------------------------------------------------*/
......
...@@ -42,7 +42,6 @@ ...@@ -42,7 +42,6 @@
#include "xfs_rtalloc.h" #include "xfs_rtalloc.h"
#include "xfs_error.h" #include "xfs_error.h"
#include "xfs_rw.h" #include "xfs_rw.h"
#include "xfs_acl.h"
#include "xfs_attr.h" #include "xfs_attr.h"
#include "xfs_buf_item.h" #include "xfs_buf_item.h"
#include "xfs_trans_priv.h" #include "xfs_trans_priv.h"
...@@ -111,7 +110,7 @@ xfs_trans_log_dquot( ...@@ -111,7 +110,7 @@ xfs_trans_log_dquot(
* Carry forward whatever is left of the quota blk reservation to * Carry forward whatever is left of the quota blk reservation to
* the spanky new transaction * the spanky new transaction
*/ */
STATIC void void
xfs_trans_dup_dqinfo( xfs_trans_dup_dqinfo(
xfs_trans_t *otp, xfs_trans_t *otp,
xfs_trans_t *ntp) xfs_trans_t *ntp)
...@@ -167,19 +166,17 @@ xfs_trans_dup_dqinfo( ...@@ -167,19 +166,17 @@ xfs_trans_dup_dqinfo(
/* /*
* Wrap around mod_dquot to account for both user and group quotas. * Wrap around mod_dquot to account for both user and group quotas.
*/ */
STATIC void void
xfs_trans_mod_dquot_byino( xfs_trans_mod_dquot_byino(
xfs_trans_t *tp, xfs_trans_t *tp,
xfs_inode_t *ip, xfs_inode_t *ip,
uint field, uint field,
long delta) long delta)
{ {
xfs_mount_t *mp; xfs_mount_t *mp = tp->t_mountp;
ASSERT(tp);
mp = tp->t_mountp;
if (!XFS_IS_QUOTA_ON(mp) || if (!XFS_IS_QUOTA_RUNNING(mp) ||
!XFS_IS_QUOTA_ON(mp) ||
ip->i_ino == mp->m_sb.sb_uquotino || ip->i_ino == mp->m_sb.sb_uquotino ||
ip->i_ino == mp->m_sb.sb_gquotino) ip->i_ino == mp->m_sb.sb_gquotino)
return; return;
...@@ -229,6 +226,7 @@ xfs_trans_mod_dquot( ...@@ -229,6 +226,7 @@ xfs_trans_mod_dquot(
xfs_dqtrx_t *qtrx; xfs_dqtrx_t *qtrx;
ASSERT(tp); ASSERT(tp);
ASSERT(XFS_IS_QUOTA_RUNNING(tp->t_mountp));
qtrx = NULL; qtrx = NULL;
if (tp->t_dqinfo == NULL) if (tp->t_dqinfo == NULL)
...@@ -346,7 +344,7 @@ xfs_trans_dqlockedjoin( ...@@ -346,7 +344,7 @@ xfs_trans_dqlockedjoin(
* Unreserve just the reservations done by this transaction. * Unreserve just the reservations done by this transaction.
* dquot is still left locked at exit. * dquot is still left locked at exit.
*/ */
STATIC void void
xfs_trans_apply_dquot_deltas( xfs_trans_apply_dquot_deltas(
xfs_trans_t *tp) xfs_trans_t *tp)
{ {
...@@ -357,7 +355,7 @@ xfs_trans_apply_dquot_deltas( ...@@ -357,7 +355,7 @@ xfs_trans_apply_dquot_deltas(
long totalbdelta; long totalbdelta;
long totalrtbdelta; long totalrtbdelta;
if (! (tp->t_flags & XFS_TRANS_DQ_DIRTY)) if (!(tp->t_flags & XFS_TRANS_DQ_DIRTY))
return; return;
ASSERT(tp->t_dqinfo); ASSERT(tp->t_dqinfo);
...@@ -531,7 +529,7 @@ xfs_trans_apply_dquot_deltas( ...@@ -531,7 +529,7 @@ xfs_trans_apply_dquot_deltas(
* we simply throw those away, since that's the expected behavior * we simply throw those away, since that's the expected behavior
* when a transaction is curtailed without a commit. * when a transaction is curtailed without a commit.
*/ */
STATIC void void
xfs_trans_unreserve_and_mod_dquots( xfs_trans_unreserve_and_mod_dquots(
xfs_trans_t *tp) xfs_trans_t *tp)
{ {
...@@ -768,7 +766,7 @@ xfs_trans_reserve_quota_bydquots( ...@@ -768,7 +766,7 @@ xfs_trans_reserve_quota_bydquots(
{ {
int resvd = 0, error; int resvd = 0, error;
if (!XFS_IS_QUOTA_ON(mp)) if (!XFS_IS_QUOTA_RUNNING(mp) || !XFS_IS_QUOTA_ON(mp))
return 0; return 0;
if (tp && tp->t_dqinfo == NULL) if (tp && tp->t_dqinfo == NULL)
...@@ -811,18 +809,17 @@ xfs_trans_reserve_quota_bydquots( ...@@ -811,18 +809,17 @@ xfs_trans_reserve_quota_bydquots(
* This doesn't change the actual usage, just the reservation. * This doesn't change the actual usage, just the reservation.
* The inode sent in is locked. * The inode sent in is locked.
*/ */
STATIC int int
xfs_trans_reserve_quota_nblks( xfs_trans_reserve_quota_nblks(
xfs_trans_t *tp, struct xfs_trans *tp,
xfs_mount_t *mp, struct xfs_inode *ip,
xfs_inode_t *ip, long nblks,
long nblks, long ninos,
long ninos, uint flags)
uint flags)
{ {
int error; struct xfs_mount *mp = ip->i_mount;
if (!XFS_IS_QUOTA_ON(mp)) if (!XFS_IS_QUOTA_RUNNING(mp) || !XFS_IS_QUOTA_ON(mp))
return 0; return 0;
if (XFS_IS_PQUOTA_ON(mp)) if (XFS_IS_PQUOTA_ON(mp))
flags |= XFS_QMOPT_ENOSPC; flags |= XFS_QMOPT_ENOSPC;
...@@ -831,7 +828,6 @@ xfs_trans_reserve_quota_nblks( ...@@ -831,7 +828,6 @@ xfs_trans_reserve_quota_nblks(
ASSERT(ip->i_ino != mp->m_sb.sb_gquotino); ASSERT(ip->i_ino != mp->m_sb.sb_gquotino);
ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL)); ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL));
ASSERT(XFS_IS_QUOTA_RUNNING(ip->i_mount));
ASSERT((flags & ~(XFS_QMOPT_FORCE_RES | XFS_QMOPT_ENOSPC)) == ASSERT((flags & ~(XFS_QMOPT_FORCE_RES | XFS_QMOPT_ENOSPC)) ==
XFS_TRANS_DQ_RES_RTBLKS || XFS_TRANS_DQ_RES_RTBLKS ||
(flags & ~(XFS_QMOPT_FORCE_RES | XFS_QMOPT_ENOSPC)) == (flags & ~(XFS_QMOPT_FORCE_RES | XFS_QMOPT_ENOSPC)) ==
...@@ -840,11 +836,9 @@ xfs_trans_reserve_quota_nblks( ...@@ -840,11 +836,9 @@ xfs_trans_reserve_quota_nblks(
/* /*
* Reserve nblks against these dquots, with trans as the mediator. * Reserve nblks against these dquots, with trans as the mediator.
*/ */
error = xfs_trans_reserve_quota_bydquots(tp, mp, return xfs_trans_reserve_quota_bydquots(tp, mp,
ip->i_udquot, ip->i_gdquot, ip->i_udquot, ip->i_gdquot,
nblks, ninos, nblks, ninos, flags);
flags);
return error;
} }
/* /*
...@@ -895,25 +889,15 @@ STATIC void ...@@ -895,25 +889,15 @@ STATIC void
xfs_trans_alloc_dqinfo( xfs_trans_alloc_dqinfo(
xfs_trans_t *tp) xfs_trans_t *tp)
{ {
(tp)->t_dqinfo = kmem_zone_zalloc(xfs_Gqm->qm_dqtrxzone, KM_SLEEP); tp->t_dqinfo = kmem_zone_zalloc(xfs_Gqm->qm_dqtrxzone, KM_SLEEP);
} }
STATIC void void
xfs_trans_free_dqinfo( xfs_trans_free_dqinfo(
xfs_trans_t *tp) xfs_trans_t *tp)
{ {
if (!tp->t_dqinfo) if (!tp->t_dqinfo)
return; return;
kmem_zone_free(xfs_Gqm->qm_dqtrxzone, (tp)->t_dqinfo); kmem_zone_free(xfs_Gqm->qm_dqtrxzone, tp->t_dqinfo);
(tp)->t_dqinfo = NULL; tp->t_dqinfo = NULL;
} }
xfs_dqtrxops_t xfs_trans_dquot_ops = {
.qo_dup_dqinfo = xfs_trans_dup_dqinfo,
.qo_free_dqinfo = xfs_trans_free_dqinfo,
.qo_mod_dquot_byino = xfs_trans_mod_dquot_byino,
.qo_apply_dquot_deltas = xfs_trans_apply_dquot_deltas,
.qo_reserve_quota_nblks = xfs_trans_reserve_quota_nblks,
.qo_reserve_quota_bydquots = xfs_trans_reserve_quota_bydquots,
.qo_unreserve_and_mod_dquots = xfs_trans_unreserve_and_mod_dquots,
};
This diff is collapsed.
...@@ -18,81 +18,48 @@ ...@@ -18,81 +18,48 @@
#ifndef __XFS_ACL_H__ #ifndef __XFS_ACL_H__
#define __XFS_ACL_H__ #define __XFS_ACL_H__
/* struct inode;
* Access Control Lists struct posix_acl;
*/ struct xfs_inode;
typedef __uint16_t xfs_acl_perm_t;
typedef __int32_t xfs_acl_tag_t;
typedef __int32_t xfs_acl_id_t;
#define XFS_ACL_MAX_ENTRIES 25 #define XFS_ACL_MAX_ENTRIES 25
#define XFS_ACL_NOT_PRESENT (-1) #define XFS_ACL_NOT_PRESENT (-1)
typedef struct xfs_acl_entry { /* On-disk XFS access control list structure */
xfs_acl_tag_t ae_tag; struct xfs_acl {
xfs_acl_id_t ae_id; __be32 acl_cnt;
xfs_acl_perm_t ae_perm; struct xfs_acl_entry {
} xfs_acl_entry_t; __be32 ae_tag;
__be32 ae_id;
typedef struct xfs_acl { __be16 ae_perm;
__int32_t acl_cnt; } acl_entry[XFS_ACL_MAX_ENTRIES];
xfs_acl_entry_t acl_entry[XFS_ACL_MAX_ENTRIES]; };
} xfs_acl_t;
/* On-disk XFS extended attribute names */ /* On-disk XFS extended attribute names */
#define SGI_ACL_FILE "SGI_ACL_FILE" #define SGI_ACL_FILE "SGI_ACL_FILE"
#define SGI_ACL_DEFAULT "SGI_ACL_DEFAULT" #define SGI_ACL_DEFAULT "SGI_ACL_DEFAULT"
#define SGI_ACL_FILE_SIZE (sizeof(SGI_ACL_FILE)-1) #define SGI_ACL_FILE_SIZE (sizeof(SGI_ACL_FILE)-1)
#define SGI_ACL_DEFAULT_SIZE (sizeof(SGI_ACL_DEFAULT)-1) #define SGI_ACL_DEFAULT_SIZE (sizeof(SGI_ACL_DEFAULT)-1)
#define _ACL_TYPE_ACCESS 1
#define _ACL_TYPE_DEFAULT 2
#ifdef CONFIG_XFS_POSIX_ACL #ifdef CONFIG_XFS_POSIX_ACL
extern int xfs_check_acl(struct inode *inode, int mask);
extern struct posix_acl *xfs_get_acl(struct inode *inode, int type);
extern int xfs_inherit_acl(struct inode *inode, struct posix_acl *default_acl);
extern int xfs_acl_chmod(struct inode *inode);
extern void xfs_inode_init_acls(struct xfs_inode *ip);
extern void xfs_inode_clear_acls(struct xfs_inode *ip);
extern int posix_acl_access_exists(struct inode *inode);
extern int posix_acl_default_exists(struct inode *inode);
struct vattr; extern struct xattr_handler xfs_xattr_system_handler;
struct xfs_inode;
extern struct kmem_zone *xfs_acl_zone;
#define xfs_acl_zone_init(zone, name) \
(zone) = kmem_zone_init(sizeof(xfs_acl_t), (name))
#define xfs_acl_zone_destroy(zone) kmem_zone_destroy(zone)
extern int xfs_acl_inherit(struct inode *, mode_t mode, xfs_acl_t *);
extern int xfs_acl_iaccess(struct xfs_inode *, mode_t, cred_t *);
extern int xfs_acl_vtoacl(struct inode *, xfs_acl_t *, xfs_acl_t *);
extern int xfs_acl_vhasacl_access(struct inode *);
extern int xfs_acl_vhasacl_default(struct inode *);
extern int xfs_acl_vset(struct inode *, void *, size_t, int);
extern int xfs_acl_vget(struct inode *, void *, size_t, int);
extern int xfs_acl_vremove(struct inode *, int);
#define _ACL_PERM_INVALID(perm) ((perm) & ~(ACL_READ|ACL_WRITE|ACL_EXECUTE))
#define _ACL_INHERIT(c,m,d) (xfs_acl_inherit(c,m,d))
#define _ACL_GET_ACCESS(pv,pa) (xfs_acl_vtoacl(pv,pa,NULL) == 0)
#define _ACL_GET_DEFAULT(pv,pd) (xfs_acl_vtoacl(pv,NULL,pd) == 0)
#define _ACL_ACCESS_EXISTS xfs_acl_vhasacl_access
#define _ACL_DEFAULT_EXISTS xfs_acl_vhasacl_default
#define _ACL_ALLOC(a) ((a) = kmem_zone_alloc(xfs_acl_zone, KM_SLEEP))
#define _ACL_FREE(a) ((a)? kmem_zone_free(xfs_acl_zone, (a)):(void)0)
#else #else
#define xfs_acl_zone_init(zone,name) # define xfs_check_acl NULL
#define xfs_acl_zone_destroy(zone) # define xfs_get_acl(inode, type) NULL
#define xfs_acl_vset(v,p,sz,t) (-EOPNOTSUPP) # define xfs_inherit_acl(inode, default_acl) 0
#define xfs_acl_vget(v,p,sz,t) (-EOPNOTSUPP) # define xfs_acl_chmod(inode) 0
#define xfs_acl_vremove(v,t) (-EOPNOTSUPP) # define xfs_inode_init_acls(ip)
#define xfs_acl_vhasacl_access(v) (0) # define xfs_inode_clear_acls(ip)
#define xfs_acl_vhasacl_default(v) (0) # define posix_acl_access_exists(inode) 0
#define _ACL_ALLOC(a) (1) /* successfully allocate nothing */ # define posix_acl_default_exists(inode) 0
#define _ACL_FREE(a) ((void)0) #endif /* CONFIG_XFS_POSIX_ACL */
#define _ACL_INHERIT(c,m,d) (0)
#define _ACL_GET_ACCESS(pv,pa) (0)
#define _ACL_GET_DEFAULT(pv,pd) (0)
#define _ACL_ACCESS_EXISTS (NULL)
#define _ACL_DEFAULT_EXISTS (NULL)
#endif
#endif /* __XFS_ACL_H__ */ #endif /* __XFS_ACL_H__ */
...@@ -212,6 +212,8 @@ typedef struct xfs_perag ...@@ -212,6 +212,8 @@ typedef struct xfs_perag
/* /*
* tags for inode radix tree * tags for inode radix tree
*/ */
#define XFS_ICI_NO_TAG (-1) /* special flag for an untagged lookup
in xfs_inode_ag_iterator */
#define XFS_ICI_RECLAIM_TAG 0 /* inode is to be reclaimed */ #define XFS_ICI_RECLAIM_TAG 0 /* inode is to be reclaimed */
#define XFS_AG_MAXLEVELS(mp) ((mp)->m_ag_maxlevels) #define XFS_AG_MAXLEVELS(mp) ((mp)->m_ag_maxlevels)
......
...@@ -73,28 +73,6 @@ static inline void be64_add_cpu(__be64 *a, __s64 b) ...@@ -73,28 +73,6 @@ static inline void be64_add_cpu(__be64 *a, __s64 b)
#endif /* __KERNEL__ */ #endif /* __KERNEL__ */
/* do we need conversion? */
#define ARCH_NOCONVERT 1
#ifdef XFS_NATIVE_HOST
# define ARCH_CONVERT ARCH_NOCONVERT
#else
# define ARCH_CONVERT 0
#endif
/* generic swapping macros */
#ifndef HAVE_SWABMACROS
#define INT_SWAP16(type,var) ((typeof(type))(__swab16((__u16)(var))))
#define INT_SWAP32(type,var) ((typeof(type))(__swab32((__u32)(var))))
#define INT_SWAP64(type,var) ((typeof(type))(__swab64((__u64)(var))))
#endif
#define INT_SWAP(type, var) \
((sizeof(type) == 8) ? INT_SWAP64(type,var) : \
((sizeof(type) == 4) ? INT_SWAP32(type,var) : \
((sizeof(type) == 2) ? INT_SWAP16(type,var) : \
(var))))
/* /*
* get and set integers from potentially unaligned locations * get and set integers from potentially unaligned locations
*/ */
...@@ -107,16 +85,6 @@ static inline void be64_add_cpu(__be64 *a, __s64 b) ...@@ -107,16 +85,6 @@ static inline void be64_add_cpu(__be64 *a, __s64 b)
((__u8*)(pointer))[1] = (((value) ) & 0xff); \ ((__u8*)(pointer))[1] = (((value) ) & 0xff); \
} }
/* does not return a value */
#define INT_SET(reference,arch,valueref) \
(__builtin_constant_p(valueref) ? \
(void)( (reference) = ( ((arch) != ARCH_NOCONVERT) ? (INT_SWAP((reference),(valueref))) : (valueref)) ) : \
(void)( \
((reference) = (valueref)), \
( ((arch) != ARCH_NOCONVERT) ? (reference) = INT_SWAP((reference),(reference)) : 0 ) \
) \
)
/* /*
* In directories inode numbers are stored as unaligned arrays of unsigned * In directories inode numbers are stored as unaligned arrays of unsigned
* 8bit integers on disk. * 8bit integers on disk.
......
...@@ -45,7 +45,6 @@ ...@@ -45,7 +45,6 @@
#include "xfs_error.h" #include "xfs_error.h"
#include "xfs_quota.h" #include "xfs_quota.h"
#include "xfs_trans_space.h" #include "xfs_trans_space.h"
#include "xfs_acl.h"
#include "xfs_rw.h" #include "xfs_rw.h"
#include "xfs_vnodeops.h" #include "xfs_vnodeops.h"
...@@ -249,8 +248,9 @@ xfs_attr_set_int(xfs_inode_t *dp, struct xfs_name *name, ...@@ -249,8 +248,9 @@ xfs_attr_set_int(xfs_inode_t *dp, struct xfs_name *name,
/* /*
* Attach the dquots to the inode. * Attach the dquots to the inode.
*/ */
if ((error = XFS_QM_DQATTACH(mp, dp, 0))) error = xfs_qm_dqattach(dp, 0);
return (error); if (error)
return error;
/* /*
* If the inode doesn't have an attribute fork, add one. * If the inode doesn't have an attribute fork, add one.
...@@ -311,7 +311,7 @@ xfs_attr_set_int(xfs_inode_t *dp, struct xfs_name *name, ...@@ -311,7 +311,7 @@ xfs_attr_set_int(xfs_inode_t *dp, struct xfs_name *name,
} }
xfs_ilock(dp, XFS_ILOCK_EXCL); xfs_ilock(dp, XFS_ILOCK_EXCL);
error = XFS_TRANS_RESERVE_QUOTA_NBLKS(mp, args.trans, dp, args.total, 0, error = xfs_trans_reserve_quota_nblks(args.trans, dp, args.total, 0,
rsvd ? XFS_QMOPT_RES_REGBLKS | XFS_QMOPT_FORCE_RES : rsvd ? XFS_QMOPT_RES_REGBLKS | XFS_QMOPT_FORCE_RES :
XFS_QMOPT_RES_REGBLKS); XFS_QMOPT_RES_REGBLKS);
if (error) { if (error) {
...@@ -501,8 +501,9 @@ xfs_attr_remove_int(xfs_inode_t *dp, struct xfs_name *name, int flags) ...@@ -501,8 +501,9 @@ xfs_attr_remove_int(xfs_inode_t *dp, struct xfs_name *name, int flags)
/* /*
* Attach the dquots to the inode. * Attach the dquots to the inode.
*/ */
if ((error = XFS_QM_DQATTACH(mp, dp, 0))) error = xfs_qm_dqattach(dp, 0);
return (error); if (error)
return error;
/* /*
* Start our first transaction of the day. * Start our first transaction of the day.
......
...@@ -2691,7 +2691,7 @@ xfs_bmap_rtalloc( ...@@ -2691,7 +2691,7 @@ xfs_bmap_rtalloc(
* Adjust the disk quota also. This was reserved * Adjust the disk quota also. This was reserved
* earlier. * earlier.
*/ */
XFS_TRANS_MOD_DQUOT_BYINO(mp, ap->tp, ap->ip, xfs_trans_mod_dquot_byino(ap->tp, ap->ip,
ap->wasdel ? XFS_TRANS_DQ_DELRTBCOUNT : ap->wasdel ? XFS_TRANS_DQ_DELRTBCOUNT :
XFS_TRANS_DQ_RTBCOUNT, (long) ralen); XFS_TRANS_DQ_RTBCOUNT, (long) ralen);
} else { } else {
...@@ -2995,7 +2995,7 @@ xfs_bmap_btalloc( ...@@ -2995,7 +2995,7 @@ xfs_bmap_btalloc(
* Adjust the disk quota also. This was reserved * Adjust the disk quota also. This was reserved
* earlier. * earlier.
*/ */
XFS_TRANS_MOD_DQUOT_BYINO(mp, ap->tp, ap->ip, xfs_trans_mod_dquot_byino(ap->tp, ap->ip,
ap->wasdel ? XFS_TRANS_DQ_DELBCOUNT : ap->wasdel ? XFS_TRANS_DQ_DELBCOUNT :
XFS_TRANS_DQ_BCOUNT, XFS_TRANS_DQ_BCOUNT,
(long) args.len); (long) args.len);
...@@ -3066,7 +3066,7 @@ xfs_bmap_btree_to_extents( ...@@ -3066,7 +3066,7 @@ xfs_bmap_btree_to_extents(
return error; return error;
xfs_bmap_add_free(cbno, 1, cur->bc_private.b.flist, mp); xfs_bmap_add_free(cbno, 1, cur->bc_private.b.flist, mp);
ip->i_d.di_nblocks--; ip->i_d.di_nblocks--;
XFS_TRANS_MOD_DQUOT_BYINO(mp, tp, ip, XFS_TRANS_DQ_BCOUNT, -1L); xfs_trans_mod_dquot_byino(tp, ip, XFS_TRANS_DQ_BCOUNT, -1L);
xfs_trans_binval(tp, cbp); xfs_trans_binval(tp, cbp);
if (cur->bc_bufs[0] == cbp) if (cur->bc_bufs[0] == cbp)
cur->bc_bufs[0] = NULL; cur->bc_bufs[0] = NULL;
...@@ -3386,7 +3386,7 @@ xfs_bmap_del_extent( ...@@ -3386,7 +3386,7 @@ xfs_bmap_del_extent(
* Adjust quota data. * Adjust quota data.
*/ */
if (qfield) if (qfield)
XFS_TRANS_MOD_DQUOT_BYINO(mp, tp, ip, qfield, (long)-nblks); xfs_trans_mod_dquot_byino(tp, ip, qfield, (long)-nblks);
/* /*
* Account for change in delayed indirect blocks. * Account for change in delayed indirect blocks.
...@@ -3523,7 +3523,7 @@ xfs_bmap_extents_to_btree( ...@@ -3523,7 +3523,7 @@ xfs_bmap_extents_to_btree(
*firstblock = cur->bc_private.b.firstblock = args.fsbno; *firstblock = cur->bc_private.b.firstblock = args.fsbno;
cur->bc_private.b.allocated++; cur->bc_private.b.allocated++;
ip->i_d.di_nblocks++; ip->i_d.di_nblocks++;
XFS_TRANS_MOD_DQUOT_BYINO(mp, tp, ip, XFS_TRANS_DQ_BCOUNT, 1L); xfs_trans_mod_dquot_byino(tp, ip, XFS_TRANS_DQ_BCOUNT, 1L);
abp = xfs_btree_get_bufl(mp, tp, args.fsbno, 0); abp = xfs_btree_get_bufl(mp, tp, args.fsbno, 0);
/* /*
* Fill in the child block. * Fill in the child block.
...@@ -3690,7 +3690,7 @@ xfs_bmap_local_to_extents( ...@@ -3690,7 +3690,7 @@ xfs_bmap_local_to_extents(
XFS_BMAP_TRACE_POST_UPDATE("new", ip, 0, whichfork); XFS_BMAP_TRACE_POST_UPDATE("new", ip, 0, whichfork);
XFS_IFORK_NEXT_SET(ip, whichfork, 1); XFS_IFORK_NEXT_SET(ip, whichfork, 1);
ip->i_d.di_nblocks = 1; ip->i_d.di_nblocks = 1;
XFS_TRANS_MOD_DQUOT_BYINO(args.mp, tp, ip, xfs_trans_mod_dquot_byino(tp, ip,
XFS_TRANS_DQ_BCOUNT, 1L); XFS_TRANS_DQ_BCOUNT, 1L);
flags |= xfs_ilog_fext(whichfork); flags |= xfs_ilog_fext(whichfork);
} else { } else {
...@@ -4048,7 +4048,7 @@ xfs_bmap_add_attrfork( ...@@ -4048,7 +4048,7 @@ xfs_bmap_add_attrfork(
XFS_TRANS_PERM_LOG_RES, XFS_ADDAFORK_LOG_COUNT))) XFS_TRANS_PERM_LOG_RES, XFS_ADDAFORK_LOG_COUNT)))
goto error0; goto error0;
xfs_ilock(ip, XFS_ILOCK_EXCL); xfs_ilock(ip, XFS_ILOCK_EXCL);
error = XFS_TRANS_RESERVE_QUOTA_NBLKS(mp, tp, ip, blks, 0, rsvd ? error = xfs_trans_reserve_quota_nblks(tp, ip, blks, 0, rsvd ?
XFS_QMOPT_RES_REGBLKS | XFS_QMOPT_FORCE_RES : XFS_QMOPT_RES_REGBLKS | XFS_QMOPT_FORCE_RES :
XFS_QMOPT_RES_REGBLKS); XFS_QMOPT_RES_REGBLKS);
if (error) { if (error) {
...@@ -4983,10 +4983,11 @@ xfs_bmapi( ...@@ -4983,10 +4983,11 @@ xfs_bmapi(
* adjusted later. We return if we haven't * adjusted later. We return if we haven't
* allocated blocks already inside this loop. * allocated blocks already inside this loop.
*/ */
if ((error = XFS_TRANS_RESERVE_QUOTA_NBLKS( error = xfs_trans_reserve_quota_nblks(
mp, NULL, ip, (long)alen, 0, NULL, ip, (long)alen, 0,
rt ? XFS_QMOPT_RES_RTBLKS : rt ? XFS_QMOPT_RES_RTBLKS :
XFS_QMOPT_RES_REGBLKS))) { XFS_QMOPT_RES_REGBLKS);
if (error) {
if (n == 0) { if (n == 0) {
*nmap = 0; *nmap = 0;
ASSERT(cur == NULL); ASSERT(cur == NULL);
...@@ -5035,8 +5036,8 @@ xfs_bmapi( ...@@ -5035,8 +5036,8 @@ xfs_bmapi(
if (XFS_IS_QUOTA_ON(mp)) if (XFS_IS_QUOTA_ON(mp))
/* unreserve the blocks now */ /* unreserve the blocks now */
(void) (void)
XFS_TRANS_UNRESERVE_QUOTA_NBLKS( xfs_trans_unreserve_quota_nblks(
mp, NULL, ip, NULL, ip,
(long)alen, 0, rt ? (long)alen, 0, rt ?
XFS_QMOPT_RES_RTBLKS : XFS_QMOPT_RES_RTBLKS :
XFS_QMOPT_RES_REGBLKS); XFS_QMOPT_RES_REGBLKS);
...@@ -5691,14 +5692,14 @@ xfs_bunmapi( ...@@ -5691,14 +5692,14 @@ xfs_bunmapi(
do_div(rtexts, mp->m_sb.sb_rextsize); do_div(rtexts, mp->m_sb.sb_rextsize);
xfs_mod_incore_sb(mp, XFS_SBS_FREXTENTS, xfs_mod_incore_sb(mp, XFS_SBS_FREXTENTS,
(int64_t)rtexts, rsvd); (int64_t)rtexts, rsvd);
(void)XFS_TRANS_RESERVE_QUOTA_NBLKS(mp, (void)xfs_trans_reserve_quota_nblks(NULL,
NULL, ip, -((long)del.br_blockcount), 0, ip, -((long)del.br_blockcount), 0,
XFS_QMOPT_RES_RTBLKS); XFS_QMOPT_RES_RTBLKS);
} else { } else {
xfs_mod_incore_sb(mp, XFS_SBS_FDBLOCKS, xfs_mod_incore_sb(mp, XFS_SBS_FDBLOCKS,
(int64_t)del.br_blockcount, rsvd); (int64_t)del.br_blockcount, rsvd);
(void)XFS_TRANS_RESERVE_QUOTA_NBLKS(mp, (void)xfs_trans_reserve_quota_nblks(NULL,
NULL, ip, -((long)del.br_blockcount), 0, ip, -((long)del.br_blockcount), 0,
XFS_QMOPT_RES_REGBLKS); XFS_QMOPT_RES_REGBLKS);
} }
ip->i_delayed_blks -= del.br_blockcount; ip->i_delayed_blks -= del.br_blockcount;
...@@ -6085,6 +6086,7 @@ xfs_getbmap( ...@@ -6085,6 +6086,7 @@ xfs_getbmap(
break; break;
} }
kmem_free(out);
return error; return error;
} }
......
...@@ -590,7 +590,7 @@ xfs_bmbt_alloc_block( ...@@ -590,7 +590,7 @@ xfs_bmbt_alloc_block(
cur->bc_private.b.allocated++; cur->bc_private.b.allocated++;
cur->bc_private.b.ip->i_d.di_nblocks++; cur->bc_private.b.ip->i_d.di_nblocks++;
xfs_trans_log_inode(args.tp, cur->bc_private.b.ip, XFS_ILOG_CORE); xfs_trans_log_inode(args.tp, cur->bc_private.b.ip, XFS_ILOG_CORE);
XFS_TRANS_MOD_DQUOT_BYINO(args.mp, args.tp, cur->bc_private.b.ip, xfs_trans_mod_dquot_byino(args.tp, cur->bc_private.b.ip,
XFS_TRANS_DQ_BCOUNT, 1L); XFS_TRANS_DQ_BCOUNT, 1L);
new->l = cpu_to_be64(args.fsbno); new->l = cpu_to_be64(args.fsbno);
...@@ -618,7 +618,7 @@ xfs_bmbt_free_block( ...@@ -618,7 +618,7 @@ xfs_bmbt_free_block(
ip->i_d.di_nblocks--; ip->i_d.di_nblocks--;
xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
XFS_TRANS_MOD_DQUOT_BYINO(mp, tp, ip, XFS_TRANS_DQ_BCOUNT, -1L); xfs_trans_mod_dquot_byino(tp, ip, XFS_TRANS_DQ_BCOUNT, -1L);
xfs_trans_binval(tp, bp); xfs_trans_binval(tp, bp);
return 0; return 0;
} }
......
...@@ -542,10 +542,8 @@ xfs_filestream_associate( ...@@ -542,10 +542,8 @@ xfs_filestream_associate(
* waiting for the lock because someone else is waiting on the lock we * waiting for the lock because someone else is waiting on the lock we
* hold and we cannot drop that as we are in a transaction here. * hold and we cannot drop that as we are in a transaction here.
* *
* Lucky for us, this inversion is rarely a problem because it's a * Lucky for us, this inversion is not a problem because it's a
* directory inode that we are trying to lock here and that means the * directory inode that we are trying to lock here.
* only place that matters is xfs_sync_inodes() and SYNC_DELWRI is
* used. i.e. freeze, remount-ro, quotasync or unmount.
* *
* So, if we can't get the iolock without sleeping then just give up * So, if we can't get the iolock without sleeping then just give up
*/ */
......
...@@ -239,10 +239,13 @@ typedef struct xfs_fsop_resblks { ...@@ -239,10 +239,13 @@ typedef struct xfs_fsop_resblks {
* Minimum and maximum sizes need for growth checks * Minimum and maximum sizes need for growth checks
*/ */
#define XFS_MIN_AG_BLOCKS 64 #define XFS_MIN_AG_BLOCKS 64
#define XFS_MIN_LOG_BLOCKS 512 #define XFS_MIN_LOG_BLOCKS 512ULL
#define XFS_MAX_LOG_BLOCKS (64 * 1024) #define XFS_MAX_LOG_BLOCKS (1024 * 1024ULL)
#define XFS_MIN_LOG_BYTES (256 * 1024) #define XFS_MIN_LOG_BYTES (10 * 1024 * 1024ULL)
#define XFS_MAX_LOG_BYTES (128 * 1024 * 1024)
/* keep the maximum size under 2^31 by a small amount */
#define XFS_MAX_LOG_BYTES \
((2 * 1024 * 1024 * 1024ULL) - XFS_MIN_LOG_BYTES)
/* /*
* Structures for XFS_IOC_FSGROWFSDATA, XFS_IOC_FSGROWFSLOG & XFS_IOC_FSGROWFSRT * Structures for XFS_IOC_FSGROWFSDATA, XFS_IOC_FSGROWFSLOG & XFS_IOC_FSGROWFSRT
......
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
#include "xfs.h" #include "xfs.h"
#include "xfs_fs.h" #include "xfs_fs.h"
#include "xfs_types.h" #include "xfs_types.h"
#include "xfs_acl.h"
#include "xfs_bit.h" #include "xfs_bit.h"
#include "xfs_log.h" #include "xfs_log.h"
#include "xfs_inum.h" #include "xfs_inum.h"
...@@ -82,6 +83,7 @@ xfs_inode_alloc( ...@@ -82,6 +83,7 @@ xfs_inode_alloc(
memset(&ip->i_d, 0, sizeof(xfs_icdinode_t)); memset(&ip->i_d, 0, sizeof(xfs_icdinode_t));
ip->i_size = 0; ip->i_size = 0;
ip->i_new_size = 0; ip->i_new_size = 0;
xfs_inode_init_acls(ip);
/* /*
* Initialize inode's trace buffers. * Initialize inode's trace buffers.
...@@ -500,10 +502,7 @@ xfs_ireclaim( ...@@ -500,10 +502,7 @@ xfs_ireclaim(
* ilock one but will still hold the iolock. * ilock one but will still hold the iolock.
*/ */
xfs_ilock(ip, XFS_ILOCK_EXCL | XFS_IOLOCK_EXCL); xfs_ilock(ip, XFS_ILOCK_EXCL | XFS_IOLOCK_EXCL);
/* xfs_qm_dqdetach(ip);
* Release dquots (and their references) if any.
*/
XFS_QM_DQDETACH(ip->i_mount, ip);
xfs_iunlock(ip, XFS_ILOCK_EXCL | XFS_IOLOCK_EXCL); xfs_iunlock(ip, XFS_ILOCK_EXCL | XFS_IOLOCK_EXCL);
switch (ip->i_d.di_mode & S_IFMT) { switch (ip->i_d.di_mode & S_IFMT) {
...@@ -561,6 +560,7 @@ xfs_ireclaim( ...@@ -561,6 +560,7 @@ xfs_ireclaim(
ASSERT(atomic_read(&ip->i_pincount) == 0); ASSERT(atomic_read(&ip->i_pincount) == 0);
ASSERT(!spin_is_locked(&ip->i_flags_lock)); ASSERT(!spin_is_locked(&ip->i_flags_lock));
ASSERT(completion_done(&ip->i_flush)); ASSERT(completion_done(&ip->i_flush));
xfs_inode_clear_acls(ip);
kmem_zone_free(xfs_inode_zone, ip); kmem_zone_free(xfs_inode_zone, ip);
} }
......
...@@ -49,7 +49,6 @@ ...@@ -49,7 +49,6 @@
#include "xfs_utils.h" #include "xfs_utils.h"
#include "xfs_dir2_trace.h" #include "xfs_dir2_trace.h"
#include "xfs_quota.h" #include "xfs_quota.h"
#include "xfs_acl.h"
#include "xfs_filestream.h" #include "xfs_filestream.h"
#include "xfs_vnodeops.h" #include "xfs_vnodeops.h"
......
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
#ifndef __XFS_INODE_H__ #ifndef __XFS_INODE_H__
#define __XFS_INODE_H__ #define __XFS_INODE_H__
struct posix_acl;
struct xfs_dinode; struct xfs_dinode;
struct xfs_inode; struct xfs_inode;
...@@ -272,6 +273,11 @@ typedef struct xfs_inode { ...@@ -272,6 +273,11 @@ typedef struct xfs_inode {
/* VFS inode */ /* VFS inode */
struct inode i_vnode; /* embedded VFS inode */ struct inode i_vnode; /* embedded VFS inode */
#ifdef CONFIG_XFS_POSIX_ACL
struct posix_acl *i_acl;
struct posix_acl *i_default_acl;
#endif
/* Trace buffers per inode. */ /* Trace buffers per inode. */
#ifdef XFS_INODE_TRACE #ifdef XFS_INODE_TRACE
struct ktrace *i_trace; /* general inode trace */ struct ktrace *i_trace; /* general inode trace */
......
...@@ -42,7 +42,6 @@ ...@@ -42,7 +42,6 @@
#include "xfs_error.h" #include "xfs_error.h"
#include "xfs_itable.h" #include "xfs_itable.h"
#include "xfs_rw.h" #include "xfs_rw.h"
#include "xfs_acl.h"
#include "xfs_attr.h" #include "xfs_attr.h"
#include "xfs_buf_item.h" #include "xfs_buf_item.h"
#include "xfs_trans_space.h" #include "xfs_trans_space.h"
...@@ -385,7 +384,7 @@ xfs_iomap_write_direct( ...@@ -385,7 +384,7 @@ xfs_iomap_write_direct(
* Make sure that the dquots are there. This doesn't hold * Make sure that the dquots are there. This doesn't hold
* the ilock across a disk read. * the ilock across a disk read.
*/ */
error = XFS_QM_DQATTACH(ip->i_mount, ip, XFS_QMOPT_ILOCKED); error = xfs_qm_dqattach_locked(ip, 0);
if (error) if (error)
return XFS_ERROR(error); return XFS_ERROR(error);
...@@ -444,8 +443,7 @@ xfs_iomap_write_direct( ...@@ -444,8 +443,7 @@ xfs_iomap_write_direct(
if (error) if (error)
goto error_out; goto error_out;
error = XFS_TRANS_RESERVE_QUOTA_NBLKS(mp, tp, ip, error = xfs_trans_reserve_quota_nblks(tp, ip, qblocks, 0, quota_flag);
qblocks, 0, quota_flag);
if (error) if (error)
goto error1; goto error1;
...@@ -495,7 +493,7 @@ xfs_iomap_write_direct( ...@@ -495,7 +493,7 @@ xfs_iomap_write_direct(
error0: /* Cancel bmap, unlock inode, unreserve quota blocks, cancel trans */ error0: /* Cancel bmap, unlock inode, unreserve quota blocks, cancel trans */
xfs_bmap_cancel(&free_list); xfs_bmap_cancel(&free_list);
XFS_TRANS_UNRESERVE_QUOTA_NBLKS(mp, tp, ip, qblocks, 0, quota_flag); xfs_trans_unreserve_quota_nblks(tp, ip, qblocks, 0, quota_flag);
error1: /* Just cancel transaction */ error1: /* Just cancel transaction */
xfs_trans_cancel(tp, XFS_TRANS_RELEASE_LOG_RES | XFS_TRANS_ABORT); xfs_trans_cancel(tp, XFS_TRANS_RELEASE_LOG_RES | XFS_TRANS_ABORT);
...@@ -582,7 +580,7 @@ xfs_iomap_write_delay( ...@@ -582,7 +580,7 @@ xfs_iomap_write_delay(
* Make sure that the dquots are there. This doesn't hold * Make sure that the dquots are there. This doesn't hold
* the ilock across a disk read. * the ilock across a disk read.
*/ */
error = XFS_QM_DQATTACH(mp, ip, XFS_QMOPT_ILOCKED); error = xfs_qm_dqattach_locked(ip, 0);
if (error) if (error)
return XFS_ERROR(error); return XFS_ERROR(error);
...@@ -684,7 +682,8 @@ xfs_iomap_write_allocate( ...@@ -684,7 +682,8 @@ xfs_iomap_write_allocate(
/* /*
* Make sure that the dquots are there. * Make sure that the dquots are there.
*/ */
if ((error = XFS_QM_DQATTACH(mp, ip, 0))) error = xfs_qm_dqattach(ip, 0);
if (error)
return XFS_ERROR(error); return XFS_ERROR(error);
offset_fsb = XFS_B_TO_FSBT(mp, offset); offset_fsb = XFS_B_TO_FSBT(mp, offset);
......
...@@ -1975,16 +1975,30 @@ xlog_recover_do_reg_buffer( ...@@ -1975,16 +1975,30 @@ xlog_recover_do_reg_buffer(
error = 0; error = 0;
if (buf_f->blf_flags & if (buf_f->blf_flags &
(XFS_BLI_UDQUOT_BUF|XFS_BLI_PDQUOT_BUF|XFS_BLI_GDQUOT_BUF)) { (XFS_BLI_UDQUOT_BUF|XFS_BLI_PDQUOT_BUF|XFS_BLI_GDQUOT_BUF)) {
if (item->ri_buf[i].i_addr == NULL) {
cmn_err(CE_ALERT,
"XFS: NULL dquot in %s.", __func__);
goto next;
}
if (item->ri_buf[i].i_len < sizeof(xfs_dqblk_t)) {
cmn_err(CE_ALERT,
"XFS: dquot too small (%d) in %s.",
item->ri_buf[i].i_len, __func__);
goto next;
}
error = xfs_qm_dqcheck((xfs_disk_dquot_t *) error = xfs_qm_dqcheck((xfs_disk_dquot_t *)
item->ri_buf[i].i_addr, item->ri_buf[i].i_addr,
-1, 0, XFS_QMOPT_DOWARN, -1, 0, XFS_QMOPT_DOWARN,
"dquot_buf_recover"); "dquot_buf_recover");
if (error)
goto next;
} }
if (!error)
memcpy(xfs_buf_offset(bp, memcpy(xfs_buf_offset(bp,
(uint)bit << XFS_BLI_SHIFT), /* dest */ (uint)bit << XFS_BLI_SHIFT), /* dest */
item->ri_buf[i].i_addr, /* source */ item->ri_buf[i].i_addr, /* source */
nbits<<XFS_BLI_SHIFT); /* length */ nbits<<XFS_BLI_SHIFT); /* length */
next:
i++; i++;
bit += nbits; bit += nbits;
} }
...@@ -2615,7 +2629,19 @@ xlog_recover_do_dquot_trans( ...@@ -2615,7 +2629,19 @@ xlog_recover_do_dquot_trans(
return (0); return (0);
recddq = (xfs_disk_dquot_t *)item->ri_buf[1].i_addr; recddq = (xfs_disk_dquot_t *)item->ri_buf[1].i_addr;
ASSERT(recddq);
if (item->ri_buf[1].i_addr == NULL) {
cmn_err(CE_ALERT,
"XFS: NULL dquot in %s.", __func__);
return XFS_ERROR(EIO);
}
if (item->ri_buf[1].i_len < sizeof(xfs_dqblk_t)) {
cmn_err(CE_ALERT,
"XFS: dquot too small (%d) in %s.",
item->ri_buf[1].i_len, __func__);
return XFS_ERROR(EIO);
}
/* /*
* This type of quotas was turned off, so ignore this record. * This type of quotas was turned off, so ignore this record.
*/ */
......
...@@ -959,6 +959,53 @@ xfs_check_sizes(xfs_mount_t *mp) ...@@ -959,6 +959,53 @@ xfs_check_sizes(xfs_mount_t *mp)
return 0; return 0;
} }
/*
* Clear the quotaflags in memory and in the superblock.
*/
int
xfs_mount_reset_sbqflags(
struct xfs_mount *mp)
{
int error;
struct xfs_trans *tp;
mp->m_qflags = 0;
/*
* It is OK to look at sb_qflags here in mount path,
* without m_sb_lock.
*/
if (mp->m_sb.sb_qflags == 0)
return 0;
spin_lock(&mp->m_sb_lock);
mp->m_sb.sb_qflags = 0;
spin_unlock(&mp->m_sb_lock);
/*
* If the fs is readonly, let the incore superblock run
* with quotas off but don't flush the update out to disk
*/
if (mp->m_flags & XFS_MOUNT_RDONLY)
return 0;
#ifdef QUOTADEBUG
xfs_fs_cmn_err(CE_NOTE, mp, "Writing superblock quota changes");
#endif
tp = xfs_trans_alloc(mp, XFS_TRANS_QM_SBCHANGE);
error = xfs_trans_reserve(tp, 0, mp->m_sb.sb_sectsize + 128, 0, 0,
XFS_DEFAULT_LOG_COUNT);
if (error) {
xfs_trans_cancel(tp, 0);
xfs_fs_cmn_err(CE_ALERT, mp,
"xfs_mount_reset_sbqflags: Superblock update failed!");
return error;
}
xfs_mod_sb(tp, XFS_SB_QFLAGS);
return xfs_trans_commit(tp, 0);
}
/* /*
* This function does the following on an initial mount of a file system: * This function does the following on an initial mount of a file system:
* - reads the superblock from disk and init the mount struct * - reads the superblock from disk and init the mount struct
...@@ -976,7 +1023,8 @@ xfs_mountfs( ...@@ -976,7 +1023,8 @@ xfs_mountfs(
xfs_sb_t *sbp = &(mp->m_sb); xfs_sb_t *sbp = &(mp->m_sb);
xfs_inode_t *rip; xfs_inode_t *rip;
__uint64_t resblks; __uint64_t resblks;
uint quotamount, quotaflags; uint quotamount = 0;
uint quotaflags = 0;
int error = 0; int error = 0;
xfs_mount_common(mp, sbp); xfs_mount_common(mp, sbp);
...@@ -1210,9 +1258,28 @@ xfs_mountfs( ...@@ -1210,9 +1258,28 @@ xfs_mountfs(
/* /*
* Initialise the XFS quota management subsystem for this mount * Initialise the XFS quota management subsystem for this mount
*/ */
error = XFS_QM_INIT(mp, &quotamount, &quotaflags); if (XFS_IS_QUOTA_RUNNING(mp)) {
if (error) error = xfs_qm_newmount(mp, &quotamount, &quotaflags);
goto out_rtunmount; if (error)
goto out_rtunmount;
} else {
ASSERT(!XFS_IS_QUOTA_ON(mp));
/*
* If a file system had quotas running earlier, but decided to
* mount without -o uquota/pquota/gquota options, revoke the
* quotachecked license.
*/
if (mp->m_sb.sb_qflags & XFS_ALL_QUOTA_ACCT) {
cmn_err(CE_NOTE,
"XFS: resetting qflags for filesystem %s",
mp->m_fsname);
error = xfs_mount_reset_sbqflags(mp);
if (error)
return error;
}
}
/* /*
* Finish recovering the file system. This part needed to be * Finish recovering the file system. This part needed to be
...@@ -1228,9 +1295,19 @@ xfs_mountfs( ...@@ -1228,9 +1295,19 @@ xfs_mountfs(
/* /*
* Complete the quota initialisation, post-log-replay component. * Complete the quota initialisation, post-log-replay component.
*/ */
error = XFS_QM_MOUNT(mp, quotamount, quotaflags); if (quotamount) {
if (error) ASSERT(mp->m_qflags == 0);
goto out_rtunmount; mp->m_qflags = quotaflags;
xfs_qm_mount_quotas(mp);
}
#if defined(DEBUG) && defined(XFS_LOUD_RECOVERY)
if (XFS_IS_QUOTA_ON(mp))
xfs_fs_cmn_err(CE_NOTE, mp, "Disk quotas turned on");
else
xfs_fs_cmn_err(CE_NOTE, mp, "Disk quotas not turned on");
#endif
/* /*
* Now we are mounted, reserve a small amount of unused space for * Now we are mounted, reserve a small amount of unused space for
...@@ -1279,12 +1356,7 @@ xfs_unmountfs( ...@@ -1279,12 +1356,7 @@ xfs_unmountfs(
__uint64_t resblks; __uint64_t resblks;
int error; int error;
/* xfs_qm_unmount_quotas(mp);
* Release dquot that rootinode, rbmino and rsumino might be holding,
* and release the quota inodes.
*/
XFS_QM_UNMOUNT(mp);
xfs_rtunmount_inodes(mp); xfs_rtunmount_inodes(mp);
IRELE(mp->m_rootip); IRELE(mp->m_rootip);
...@@ -1299,12 +1371,9 @@ xfs_unmountfs( ...@@ -1299,12 +1371,9 @@ xfs_unmountfs(
* need to force the log first. * need to force the log first.
*/ */
xfs_log_force(mp, (xfs_lsn_t)0, XFS_LOG_FORCE | XFS_LOG_SYNC); xfs_log_force(mp, (xfs_lsn_t)0, XFS_LOG_FORCE | XFS_LOG_SYNC);
xfs_reclaim_inodes(mp, 0, XFS_IFLUSH_ASYNC); xfs_reclaim_inodes(mp, XFS_IFLUSH_ASYNC);
XFS_QM_DQPURGEALL(mp, XFS_QMOPT_QUOTALL | XFS_QMOPT_UMOUNTING);
if (mp->m_quotainfo) xfs_qm_unmount(mp);
XFS_QM_DONE(mp);
/* /*
* Flush out the log synchronously so that we know for sure * Flush out the log synchronously so that we know for sure
......
...@@ -64,6 +64,8 @@ struct xfs_swapext; ...@@ -64,6 +64,8 @@ struct xfs_swapext;
struct xfs_mru_cache; struct xfs_mru_cache;
struct xfs_nameops; struct xfs_nameops;
struct xfs_ail; struct xfs_ail;
struct xfs_quotainfo;
/* /*
* Prototypes and functions for the Data Migration subsystem. * Prototypes and functions for the Data Migration subsystem.
...@@ -107,86 +109,6 @@ typedef struct xfs_dmops { ...@@ -107,86 +109,6 @@ typedef struct xfs_dmops {
(*(mp)->m_dm_ops->xfs_send_unmount)(mp,ip,right,mode,rval,fl) (*(mp)->m_dm_ops->xfs_send_unmount)(mp,ip,right,mode,rval,fl)
/*
* Prototypes and functions for the Quota Management subsystem.
*/
struct xfs_dquot;
struct xfs_dqtrxops;
struct xfs_quotainfo;
typedef int (*xfs_qminit_t)(struct xfs_mount *, uint *, uint *);
typedef int (*xfs_qmmount_t)(struct xfs_mount *, uint, uint);
typedef void (*xfs_qmunmount_t)(struct xfs_mount *);
typedef void (*xfs_qmdone_t)(struct xfs_mount *);
typedef void (*xfs_dqrele_t)(struct xfs_dquot *);
typedef int (*xfs_dqattach_t)(struct xfs_inode *, uint);
typedef void (*xfs_dqdetach_t)(struct xfs_inode *);
typedef int (*xfs_dqpurgeall_t)(struct xfs_mount *, uint);
typedef int (*xfs_dqvopalloc_t)(struct xfs_mount *,
struct xfs_inode *, uid_t, gid_t, prid_t, uint,
struct xfs_dquot **, struct xfs_dquot **);
typedef void (*xfs_dqvopcreate_t)(struct xfs_trans *, struct xfs_inode *,
struct xfs_dquot *, struct xfs_dquot *);
typedef int (*xfs_dqvoprename_t)(struct xfs_inode **);
typedef struct xfs_dquot * (*xfs_dqvopchown_t)(
struct xfs_trans *, struct xfs_inode *,
struct xfs_dquot **, struct xfs_dquot *);
typedef int (*xfs_dqvopchownresv_t)(struct xfs_trans *, struct xfs_inode *,
struct xfs_dquot *, struct xfs_dquot *, uint);
typedef void (*xfs_dqstatvfs_t)(struct xfs_inode *, struct kstatfs *);
typedef int (*xfs_dqsync_t)(struct xfs_mount *, int flags);
typedef struct xfs_qmops {
xfs_qminit_t xfs_qminit;
xfs_qmdone_t xfs_qmdone;
xfs_qmmount_t xfs_qmmount;
xfs_qmunmount_t xfs_qmunmount;
xfs_dqrele_t xfs_dqrele;
xfs_dqattach_t xfs_dqattach;
xfs_dqdetach_t xfs_dqdetach;
xfs_dqpurgeall_t xfs_dqpurgeall;
xfs_dqvopalloc_t xfs_dqvopalloc;
xfs_dqvopcreate_t xfs_dqvopcreate;
xfs_dqvoprename_t xfs_dqvoprename;
xfs_dqvopchown_t xfs_dqvopchown;
xfs_dqvopchownresv_t xfs_dqvopchownresv;
xfs_dqstatvfs_t xfs_dqstatvfs;
xfs_dqsync_t xfs_dqsync;
struct xfs_dqtrxops *xfs_dqtrxops;
} xfs_qmops_t;
#define XFS_QM_INIT(mp, mnt, fl) \
(*(mp)->m_qm_ops->xfs_qminit)(mp, mnt, fl)
#define XFS_QM_MOUNT(mp, mnt, fl) \
(*(mp)->m_qm_ops->xfs_qmmount)(mp, mnt, fl)
#define XFS_QM_UNMOUNT(mp) \
(*(mp)->m_qm_ops->xfs_qmunmount)(mp)
#define XFS_QM_DONE(mp) \
(*(mp)->m_qm_ops->xfs_qmdone)(mp)
#define XFS_QM_DQRELE(mp, dq) \
(*(mp)->m_qm_ops->xfs_dqrele)(dq)
#define XFS_QM_DQATTACH(mp, ip, fl) \
(*(mp)->m_qm_ops->xfs_dqattach)(ip, fl)
#define XFS_QM_DQDETACH(mp, ip) \
(*(mp)->m_qm_ops->xfs_dqdetach)(ip)
#define XFS_QM_DQPURGEALL(mp, fl) \
(*(mp)->m_qm_ops->xfs_dqpurgeall)(mp, fl)
#define XFS_QM_DQVOPALLOC(mp, ip, uid, gid, prid, fl, dq1, dq2) \
(*(mp)->m_qm_ops->xfs_dqvopalloc)(mp, ip, uid, gid, prid, fl, dq1, dq2)
#define XFS_QM_DQVOPCREATE(mp, tp, ip, dq1, dq2) \
(*(mp)->m_qm_ops->xfs_dqvopcreate)(tp, ip, dq1, dq2)
#define XFS_QM_DQVOPRENAME(mp, ip) \
(*(mp)->m_qm_ops->xfs_dqvoprename)(ip)
#define XFS_QM_DQVOPCHOWN(mp, tp, ip, dqp, dq) \
(*(mp)->m_qm_ops->xfs_dqvopchown)(tp, ip, dqp, dq)
#define XFS_QM_DQVOPCHOWNRESV(mp, tp, ip, dq1, dq2, fl) \
(*(mp)->m_qm_ops->xfs_dqvopchownresv)(tp, ip, dq1, dq2, fl)
#define XFS_QM_DQSTATVFS(ip, statp) \
(*(ip)->i_mount->m_qm_ops->xfs_dqstatvfs)(ip, statp)
#define XFS_QM_DQSYNC(mp, flags) \
(*(mp)->m_qm_ops->xfs_dqsync)(mp, flags)
#ifdef HAVE_PERCPU_SB #ifdef HAVE_PERCPU_SB
/* /*
...@@ -510,8 +432,6 @@ extern int xfs_sb_validate_fsb_count(struct xfs_sb *, __uint64_t); ...@@ -510,8 +432,6 @@ extern int xfs_sb_validate_fsb_count(struct xfs_sb *, __uint64_t);
extern int xfs_dmops_get(struct xfs_mount *); extern int xfs_dmops_get(struct xfs_mount *);
extern void xfs_dmops_put(struct xfs_mount *); extern void xfs_dmops_put(struct xfs_mount *);
extern int xfs_qmops_get(struct xfs_mount *);
extern void xfs_qmops_put(struct xfs_mount *);
extern struct xfs_dmops xfs_dmcore_xfs; extern struct xfs_dmops xfs_dmcore_xfs;
......
/*
* 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 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. See the
* GNU General Public License for more details.
*
* 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_fs.h"
#include "xfs_types.h"
#include "xfs_log.h"
#include "xfs_inum.h"
#include "xfs_trans.h"
#include "xfs_sb.h"
#include "xfs_ag.h"
#include "xfs_dir2.h"
#include "xfs_dmapi.h"
#include "xfs_mount.h"
#include "xfs_quota.h"
#include "xfs_error.h"
STATIC struct xfs_dquot *
xfs_dqvopchown_default(
struct xfs_trans *tp,
struct xfs_inode *ip,
struct xfs_dquot **dqp,
struct xfs_dquot *dq)
{
return NULL;
}
/*
* Clear the quotaflags in memory and in the superblock.
*/
int
xfs_mount_reset_sbqflags(xfs_mount_t *mp)
{
int error;
xfs_trans_t *tp;
mp->m_qflags = 0;
/*
* It is OK to look at sb_qflags here in mount path,
* without m_sb_lock.
*/
if (mp->m_sb.sb_qflags == 0)
return 0;
spin_lock(&mp->m_sb_lock);
mp->m_sb.sb_qflags = 0;
spin_unlock(&mp->m_sb_lock);
/*
* if the fs is readonly, let the incore superblock run
* with quotas off but don't flush the update out to disk
*/
if (mp->m_flags & XFS_MOUNT_RDONLY)
return 0;
#ifdef QUOTADEBUG
xfs_fs_cmn_err(CE_NOTE, mp, "Writing superblock quota changes");
#endif
tp = xfs_trans_alloc(mp, XFS_TRANS_QM_SBCHANGE);
if ((error = 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 error;
}
xfs_mod_sb(tp, XFS_SB_QFLAGS);
error = xfs_trans_commit(tp, 0);
return error;
}
STATIC int
xfs_noquota_init(
xfs_mount_t *mp,
uint *needquotamount,
uint *quotaflags)
{
int error = 0;
*quotaflags = 0;
*needquotamount = B_FALSE;
ASSERT(!XFS_IS_QUOTA_ON(mp));
/*
* If a file system had quotas running earlier, but decided to
* mount without -o uquota/pquota/gquota options, revoke the
* quotachecked license.
*/
if (mp->m_sb.sb_qflags & XFS_ALL_QUOTA_ACCT) {
cmn_err(CE_NOTE,
"XFS resetting qflags for filesystem %s",
mp->m_fsname);
error = xfs_mount_reset_sbqflags(mp);
}
return error;
}
static struct xfs_qmops xfs_qmcore_stub = {
.xfs_qminit = (xfs_qminit_t) xfs_noquota_init,
.xfs_qmdone = (xfs_qmdone_t) fs_noerr,
.xfs_qmmount = (xfs_qmmount_t) fs_noerr,
.xfs_qmunmount = (xfs_qmunmount_t) fs_noerr,
.xfs_dqrele = (xfs_dqrele_t) fs_noerr,
.xfs_dqattach = (xfs_dqattach_t) fs_noerr,
.xfs_dqdetach = (xfs_dqdetach_t) fs_noerr,
.xfs_dqpurgeall = (xfs_dqpurgeall_t) fs_noerr,
.xfs_dqvopalloc = (xfs_dqvopalloc_t) fs_noerr,
.xfs_dqvopcreate = (xfs_dqvopcreate_t) fs_noerr,
.xfs_dqvoprename = (xfs_dqvoprename_t) fs_noerr,
.xfs_dqvopchown = xfs_dqvopchown_default,
.xfs_dqvopchownresv = (xfs_dqvopchownresv_t) fs_noerr,
.xfs_dqstatvfs = (xfs_dqstatvfs_t) fs_noval,
.xfs_dqsync = (xfs_dqsync_t) fs_noerr,
};
int
xfs_qmops_get(struct xfs_mount *mp)
{
if (XFS_IS_QUOTA_RUNNING(mp)) {
#ifdef CONFIG_XFS_QUOTA
mp->m_qm_ops = &xfs_qmcore_xfs;
#else
cmn_err(CE_WARN,
"XFS: qouta support not available in this kernel.");
return EINVAL;
#endif
} else {
mp->m_qm_ops = &xfs_qmcore_stub;
}
return 0;
}
void
xfs_qmops_put(struct xfs_mount *mp)
{
}
...@@ -197,7 +197,6 @@ typedef struct xfs_qoff_logformat { ...@@ -197,7 +197,6 @@ typedef struct xfs_qoff_logformat {
#define XFS_QMOPT_UMOUNTING 0x0000100 /* filesys is being unmounted */ #define XFS_QMOPT_UMOUNTING 0x0000100 /* filesys is being unmounted */
#define XFS_QMOPT_DOLOG 0x0000200 /* log buf changes (in quotacheck) */ #define XFS_QMOPT_DOLOG 0x0000200 /* log buf changes (in quotacheck) */
#define XFS_QMOPT_DOWARN 0x0000400 /* increase warning cnt if needed */ #define XFS_QMOPT_DOWARN 0x0000400 /* increase warning cnt if needed */
#define XFS_QMOPT_ILOCKED 0x0000800 /* inode is already locked (excl) */
#define XFS_QMOPT_DQREPAIR 0x0001000 /* repair dquot if damaged */ #define XFS_QMOPT_DQREPAIR 0x0001000 /* repair dquot if damaged */
#define XFS_QMOPT_GQUOTA 0x0002000 /* group dquot requested */ #define XFS_QMOPT_GQUOTA 0x0002000 /* group dquot requested */
#define XFS_QMOPT_ENOSPC 0x0004000 /* enospc instead of edquot (prj) */ #define XFS_QMOPT_ENOSPC 0x0004000 /* enospc instead of edquot (prj) */
...@@ -302,69 +301,79 @@ typedef struct xfs_dqtrx { ...@@ -302,69 +301,79 @@ typedef struct xfs_dqtrx {
long qt_delrtb_delta; /* delayed RT blk count changes */ long qt_delrtb_delta; /* delayed RT blk count changes */
} xfs_dqtrx_t; } xfs_dqtrx_t;
/* #ifdef CONFIG_XFS_QUOTA
* Dquot transaction functions, used if quota is enabled. extern void xfs_trans_dup_dqinfo(struct xfs_trans *, struct xfs_trans *);
*/ extern void xfs_trans_free_dqinfo(struct xfs_trans *);
typedef void (*qo_dup_dqinfo_t)(struct xfs_trans *, struct xfs_trans *); extern void xfs_trans_mod_dquot_byino(struct xfs_trans *, struct xfs_inode *,
typedef void (*qo_mod_dquot_byino_t)(struct xfs_trans *, uint, long);
struct xfs_inode *, uint, long); extern void xfs_trans_apply_dquot_deltas(struct xfs_trans *);
typedef void (*qo_free_dqinfo_t)(struct xfs_trans *); extern void xfs_trans_unreserve_and_mod_dquots(struct xfs_trans *);
typedef void (*qo_apply_dquot_deltas_t)(struct xfs_trans *); extern int xfs_trans_reserve_quota_nblks(struct xfs_trans *,
typedef void (*qo_unreserve_and_mod_dquots_t)(struct xfs_trans *); struct xfs_inode *, long, long, uint);
typedef int (*qo_reserve_quota_nblks_t)( extern int xfs_trans_reserve_quota_bydquots(struct xfs_trans *,
struct xfs_trans *, struct xfs_mount *, struct xfs_mount *, struct xfs_dquot *,
struct xfs_inode *, long, long, uint); struct xfs_dquot *, long, long, uint);
typedef int (*qo_reserve_quota_bydquots_t)(
struct xfs_trans *, struct xfs_mount *, extern int xfs_qm_vop_dqalloc(struct xfs_inode *, uid_t, gid_t, prid_t, uint,
struct xfs_dquot *, struct xfs_dquot *, struct xfs_dquot **, struct xfs_dquot **);
long, long, uint); extern void xfs_qm_vop_create_dqattach(struct xfs_trans *, struct xfs_inode *,
typedef struct xfs_dqtrxops { struct xfs_dquot *, struct xfs_dquot *);
qo_dup_dqinfo_t qo_dup_dqinfo; extern int xfs_qm_vop_rename_dqattach(struct xfs_inode **);
qo_free_dqinfo_t qo_free_dqinfo; extern struct xfs_dquot *xfs_qm_vop_chown(struct xfs_trans *,
qo_mod_dquot_byino_t qo_mod_dquot_byino; struct xfs_inode *, struct xfs_dquot **, struct xfs_dquot *);
qo_apply_dquot_deltas_t qo_apply_dquot_deltas; extern int xfs_qm_vop_chown_reserve(struct xfs_trans *, struct xfs_inode *,
qo_reserve_quota_nblks_t qo_reserve_quota_nblks; struct xfs_dquot *, struct xfs_dquot *, uint);
qo_reserve_quota_bydquots_t qo_reserve_quota_bydquots; extern int xfs_qm_dqattach(struct xfs_inode *, uint);
qo_unreserve_and_mod_dquots_t qo_unreserve_and_mod_dquots; extern int xfs_qm_dqattach_locked(struct xfs_inode *, uint);
} xfs_dqtrxops_t; extern void xfs_qm_dqdetach(struct xfs_inode *);
extern void xfs_qm_dqrele(struct xfs_dquot *);
#define XFS_DQTRXOP(mp, tp, op, args...) \ extern void xfs_qm_statvfs(struct xfs_inode *, struct kstatfs *);
((mp)->m_qm_ops->xfs_dqtrxops ? \ extern int xfs_qm_sync(struct xfs_mount *, int);
((mp)->m_qm_ops->xfs_dqtrxops->op)(tp, ## args) : 0) extern int xfs_qm_newmount(struct xfs_mount *, uint *, uint *);
extern void xfs_qm_mount_quotas(struct xfs_mount *);
#define XFS_DQTRXOP_VOID(mp, tp, op, args...) \ extern void xfs_qm_unmount(struct xfs_mount *);
((mp)->m_qm_ops->xfs_dqtrxops ? \ extern void xfs_qm_unmount_quotas(struct xfs_mount *);
((mp)->m_qm_ops->xfs_dqtrxops->op)(tp, ## args) : (void)0)
#else
#define XFS_TRANS_DUP_DQINFO(mp, otp, ntp) \ static inline int
XFS_DQTRXOP_VOID(mp, otp, qo_dup_dqinfo, ntp) xfs_qm_vop_dqalloc(struct xfs_inode *ip, uid_t uid, gid_t gid, prid_t prid,
#define XFS_TRANS_FREE_DQINFO(mp, tp) \ uint flags, struct xfs_dquot **udqp, struct xfs_dquot **gdqp)
XFS_DQTRXOP_VOID(mp, tp, qo_free_dqinfo) {
#define XFS_TRANS_MOD_DQUOT_BYINO(mp, tp, ip, field, delta) \ *udqp = NULL;
XFS_DQTRXOP_VOID(mp, tp, qo_mod_dquot_byino, ip, field, delta) *gdqp = NULL;
#define XFS_TRANS_APPLY_DQUOT_DELTAS(mp, tp) \ return 0;
XFS_DQTRXOP_VOID(mp, tp, qo_apply_dquot_deltas) }
#define XFS_TRANS_RESERVE_QUOTA_NBLKS(mp, tp, ip, nblks, ninos, fl) \ #define xfs_trans_dup_dqinfo(tp, tp2)
XFS_DQTRXOP(mp, tp, qo_reserve_quota_nblks, mp, ip, nblks, ninos, fl) #define xfs_trans_free_dqinfo(tp)
#define XFS_TRANS_RESERVE_QUOTA_BYDQUOTS(mp, tp, ud, gd, nb, ni, fl) \ #define xfs_trans_mod_dquot_byino(tp, ip, fields, delta)
XFS_DQTRXOP(mp, tp, qo_reserve_quota_bydquots, mp, ud, gd, nb, ni, fl) #define xfs_trans_apply_dquot_deltas(tp)
#define XFS_TRANS_UNRESERVE_AND_MOD_DQUOTS(mp, tp) \ #define xfs_trans_unreserve_and_mod_dquots(tp)
XFS_DQTRXOP_VOID(mp, tp, qo_unreserve_and_mod_dquots) #define xfs_trans_reserve_quota_nblks(tp, ip, nblks, ninos, flags) (0)
#define xfs_trans_reserve_quota_bydquots(tp, mp, u, g, nb, ni, fl) (0)
#define XFS_TRANS_UNRESERVE_QUOTA_NBLKS(mp, tp, ip, nblks, ninos, flags) \ #define xfs_qm_vop_create_dqattach(tp, ip, u, g)
XFS_TRANS_RESERVE_QUOTA_NBLKS(mp, tp, ip, -(nblks), -(ninos), flags) #define xfs_qm_vop_rename_dqattach(it) (0)
#define XFS_TRANS_RESERVE_QUOTA(mp, tp, ud, gd, nb, ni, f) \ #define xfs_qm_vop_chown(tp, ip, old, new) (NULL)
XFS_TRANS_RESERVE_QUOTA_BYDQUOTS(mp, tp, ud, gd, nb, ni, \ #define xfs_qm_vop_chown_reserve(tp, ip, u, g, fl) (0)
f | XFS_QMOPT_RES_REGBLKS) #define xfs_qm_dqattach(ip, fl) (0)
#define XFS_TRANS_UNRESERVE_QUOTA(mp, tp, ud, gd, nb, ni, f) \ #define xfs_qm_dqattach_locked(ip, fl) (0)
XFS_TRANS_RESERVE_QUOTA_BYDQUOTS(mp, tp, ud, gd, -(nb), -(ni), \ #define xfs_qm_dqdetach(ip)
#define xfs_qm_dqrele(d)
#define xfs_qm_statvfs(ip, s)
#define xfs_qm_sync(mp, fl) (0)
#define xfs_qm_newmount(mp, a, b) (0)
#define xfs_qm_mount_quotas(mp)
#define xfs_qm_unmount(mp)
#define xfs_qm_unmount_quotas(mp) (0)
#endif /* CONFIG_XFS_QUOTA */
#define xfs_trans_unreserve_quota_nblks(tp, ip, nblks, ninos, flags) \
xfs_trans_reserve_quota_nblks(tp, ip, -(nblks), -(ninos), flags)
#define xfs_trans_reserve_quota(tp, mp, ud, gd, nb, ni, f) \
xfs_trans_reserve_quota_bydquots(tp, mp, ud, gd, nb, ni, \
f | XFS_QMOPT_RES_REGBLKS) f | XFS_QMOPT_RES_REGBLKS)
extern int xfs_qm_dqcheck(xfs_disk_dquot_t *, xfs_dqid_t, uint, uint, char *); extern int xfs_qm_dqcheck(xfs_disk_dquot_t *, xfs_dqid_t, uint, uint, char *);
extern int xfs_mount_reset_sbqflags(struct xfs_mount *); extern int xfs_mount_reset_sbqflags(struct xfs_mount *);
extern struct xfs_qmops xfs_qmcore_xfs;
#endif /* __KERNEL__ */ #endif /* __KERNEL__ */
#endif /* __XFS_QUOTA_H__ */ #endif /* __XFS_QUOTA_H__ */
...@@ -166,7 +166,8 @@ xfs_rename( ...@@ -166,7 +166,8 @@ xfs_rename(
/* /*
* Attach the dquots to the inodes * Attach the dquots to the inodes
*/ */
if ((error = XFS_QM_DQVOPRENAME(mp, inodes))) { error = xfs_qm_vop_rename_dqattach(inodes);
if (error) {
xfs_trans_cancel(tp, cancel_flags); xfs_trans_cancel(tp, cancel_flags);
goto std_return; goto std_return;
} }
......
...@@ -41,7 +41,6 @@ ...@@ -41,7 +41,6 @@
#include "xfs_ialloc.h" #include "xfs_ialloc.h"
#include "xfs_attr.h" #include "xfs_attr.h"
#include "xfs_bmap.h" #include "xfs_bmap.h"
#include "xfs_acl.h"
#include "xfs_error.h" #include "xfs_error.h"
#include "xfs_buf_item.h" #include "xfs_buf_item.h"
#include "xfs_rw.h" #include "xfs_rw.h"
......
...@@ -297,7 +297,7 @@ xfs_trans_dup( ...@@ -297,7 +297,7 @@ xfs_trans_dup(
tp->t_rtx_res = tp->t_rtx_res_used; tp->t_rtx_res = tp->t_rtx_res_used;
ntp->t_pflags = tp->t_pflags; ntp->t_pflags = tp->t_pflags;
XFS_TRANS_DUP_DQINFO(tp->t_mountp, tp, ntp); xfs_trans_dup_dqinfo(tp, ntp);
atomic_inc(&tp->t_mountp->m_active_trans); atomic_inc(&tp->t_mountp->m_active_trans);
return ntp; return ntp;
...@@ -829,7 +829,7 @@ _xfs_trans_commit( ...@@ -829,7 +829,7 @@ _xfs_trans_commit(
* means is that we have some (non-persistent) quota * means is that we have some (non-persistent) quota
* reservations that need to be unreserved. * reservations that need to be unreserved.
*/ */
XFS_TRANS_UNRESERVE_AND_MOD_DQUOTS(mp, tp); xfs_trans_unreserve_and_mod_dquots(tp);
if (tp->t_ticket) { if (tp->t_ticket) {
commit_lsn = xfs_log_done(mp, tp->t_ticket, commit_lsn = xfs_log_done(mp, tp->t_ticket,
NULL, log_flags); NULL, log_flags);
...@@ -848,10 +848,9 @@ _xfs_trans_commit( ...@@ -848,10 +848,9 @@ _xfs_trans_commit(
/* /*
* If we need to update the superblock, then do it now. * If we need to update the superblock, then do it now.
*/ */
if (tp->t_flags & XFS_TRANS_SB_DIRTY) { if (tp->t_flags & XFS_TRANS_SB_DIRTY)
xfs_trans_apply_sb_deltas(tp); xfs_trans_apply_sb_deltas(tp);
} xfs_trans_apply_dquot_deltas(tp);
XFS_TRANS_APPLY_DQUOT_DELTAS(mp, tp);
/* /*
* Ask each log item how many log_vector entries it will * Ask each log item how many log_vector entries it will
...@@ -1056,7 +1055,7 @@ xfs_trans_uncommit( ...@@ -1056,7 +1055,7 @@ xfs_trans_uncommit(
} }
xfs_trans_unreserve_and_mod_sb(tp); xfs_trans_unreserve_and_mod_sb(tp);
XFS_TRANS_UNRESERVE_AND_MOD_DQUOTS(tp->t_mountp, tp); xfs_trans_unreserve_and_mod_dquots(tp);
xfs_trans_free_items(tp, flags); xfs_trans_free_items(tp, flags);
xfs_trans_free_busy(tp); xfs_trans_free_busy(tp);
...@@ -1181,7 +1180,7 @@ xfs_trans_cancel( ...@@ -1181,7 +1180,7 @@ xfs_trans_cancel(
} }
#endif #endif
xfs_trans_unreserve_and_mod_sb(tp); xfs_trans_unreserve_and_mod_sb(tp);
XFS_TRANS_UNRESERVE_AND_MOD_DQUOTS(mp, tp); xfs_trans_unreserve_and_mod_dquots(tp);
if (tp->t_ticket) { if (tp->t_ticket) {
if (flags & XFS_TRANS_RELEASE_LOG_RES) { if (flags & XFS_TRANS_RELEASE_LOG_RES) {
...@@ -1211,7 +1210,7 @@ xfs_trans_free( ...@@ -1211,7 +1210,7 @@ xfs_trans_free(
xfs_trans_t *tp) xfs_trans_t *tp)
{ {
atomic_dec(&tp->t_mountp->m_active_trans); atomic_dec(&tp->t_mountp->m_active_trans);
XFS_TRANS_FREE_DQINFO(tp->t_mountp, tp); xfs_trans_free_dqinfo(tp);
kmem_zone_free(xfs_trans_zone, tp); kmem_zone_free(xfs_trans_zone, tp);
} }
......
...@@ -166,7 +166,7 @@ xfs_dir_ialloc( ...@@ -166,7 +166,7 @@ xfs_dir_ialloc(
xfs_buf_relse(ialloc_context); xfs_buf_relse(ialloc_context);
if (dqinfo) { if (dqinfo) {
tp->t_dqinfo = dqinfo; tp->t_dqinfo = dqinfo;
XFS_TRANS_FREE_DQINFO(tp->t_mountp, tp); xfs_trans_free_dqinfo(tp);
} }
*tpp = ntp; *tpp = ntp;
*ipp = NULL; *ipp = NULL;
......
...@@ -42,6 +42,7 @@ ...@@ -42,6 +42,7 @@
#include "xfs_ialloc.h" #include "xfs_ialloc.h"
#include "xfs_alloc.h" #include "xfs_alloc.h"
#include "xfs_bmap.h" #include "xfs_bmap.h"
#include "xfs_acl.h"
#include "xfs_attr.h" #include "xfs_attr.h"
#include "xfs_rw.h" #include "xfs_rw.h"
#include "xfs_error.h" #include "xfs_error.h"
...@@ -118,7 +119,7 @@ xfs_setattr( ...@@ -118,7 +119,7 @@ xfs_setattr(
*/ */
ASSERT(udqp == NULL); ASSERT(udqp == NULL);
ASSERT(gdqp == NULL); ASSERT(gdqp == NULL);
code = XFS_QM_DQVOPALLOC(mp, ip, uid, gid, ip->i_d.di_projid, code = xfs_qm_vop_dqalloc(ip, uid, gid, ip->i_d.di_projid,
qflags, &udqp, &gdqp); qflags, &udqp, &gdqp);
if (code) if (code)
return code; return code;
...@@ -180,10 +181,11 @@ xfs_setattr( ...@@ -180,10 +181,11 @@ xfs_setattr(
* Do a quota reservation only if uid/gid is actually * Do a quota reservation only if uid/gid is actually
* going to change. * going to change.
*/ */
if ((XFS_IS_UQUOTA_ON(mp) && iuid != uid) || if (XFS_IS_QUOTA_RUNNING(mp) &&
(XFS_IS_GQUOTA_ON(mp) && igid != gid)) { ((XFS_IS_UQUOTA_ON(mp) && iuid != uid) ||
(XFS_IS_GQUOTA_ON(mp) && igid != gid))) {
ASSERT(tp); ASSERT(tp);
code = XFS_QM_DQVOPCHOWNRESV(mp, tp, ip, udqp, gdqp, code = xfs_qm_vop_chown_reserve(tp, ip, udqp, gdqp,
capable(CAP_FOWNER) ? capable(CAP_FOWNER) ?
XFS_QMOPT_FORCE_RES : 0); XFS_QMOPT_FORCE_RES : 0);
if (code) /* out of quota */ if (code) /* out of quota */
...@@ -217,7 +219,7 @@ xfs_setattr( ...@@ -217,7 +219,7 @@ xfs_setattr(
/* /*
* Make sure that the dquots are attached to the inode. * Make sure that the dquots are attached to the inode.
*/ */
code = XFS_QM_DQATTACH(mp, ip, XFS_QMOPT_ILOCKED); code = xfs_qm_dqattach_locked(ip, 0);
if (code) if (code)
goto error_return; goto error_return;
...@@ -351,21 +353,21 @@ xfs_setattr( ...@@ -351,21 +353,21 @@ xfs_setattr(
* in the transaction. * in the transaction.
*/ */
if (iuid != uid) { if (iuid != uid) {
if (XFS_IS_UQUOTA_ON(mp)) { if (XFS_IS_QUOTA_RUNNING(mp) && XFS_IS_UQUOTA_ON(mp)) {
ASSERT(mask & ATTR_UID); ASSERT(mask & ATTR_UID);
ASSERT(udqp); ASSERT(udqp);
olddquot1 = XFS_QM_DQVOPCHOWN(mp, tp, ip, olddquot1 = xfs_qm_vop_chown(tp, ip,
&ip->i_udquot, udqp); &ip->i_udquot, udqp);
} }
ip->i_d.di_uid = uid; ip->i_d.di_uid = uid;
inode->i_uid = uid; inode->i_uid = uid;
} }
if (igid != gid) { if (igid != gid) {
if (XFS_IS_GQUOTA_ON(mp)) { if (XFS_IS_QUOTA_RUNNING(mp) && XFS_IS_GQUOTA_ON(mp)) {
ASSERT(!XFS_IS_PQUOTA_ON(mp)); ASSERT(!XFS_IS_PQUOTA_ON(mp));
ASSERT(mask & ATTR_GID); ASSERT(mask & ATTR_GID);
ASSERT(gdqp); ASSERT(gdqp);
olddquot2 = XFS_QM_DQVOPCHOWN(mp, tp, ip, olddquot2 = xfs_qm_vop_chown(tp, ip,
&ip->i_gdquot, gdqp); &ip->i_gdquot, gdqp);
} }
ip->i_d.di_gid = gid; ip->i_d.di_gid = gid;
...@@ -461,13 +463,25 @@ xfs_setattr( ...@@ -461,13 +463,25 @@ xfs_setattr(
/* /*
* Release any dquot(s) the inode had kept before chown. * Release any dquot(s) the inode had kept before chown.
*/ */
XFS_QM_DQRELE(mp, olddquot1); xfs_qm_dqrele(olddquot1);
XFS_QM_DQRELE(mp, olddquot2); xfs_qm_dqrele(olddquot2);
XFS_QM_DQRELE(mp, udqp); xfs_qm_dqrele(udqp);
XFS_QM_DQRELE(mp, gdqp); xfs_qm_dqrele(gdqp);
if (code) { if (code)
return code; return code;
/*
* XXX(hch): Updating the ACL entries is not atomic vs the i_mode
* update. We could avoid this with linked transactions
* and passing down the transaction pointer all the way
* to attr_set. No previous user of the generic
* Posix ACL code seems to care about this issue either.
*/
if ((mask & ATTR_MODE) && !(flags & XFS_ATTR_NOACL)) {
code = -xfs_acl_chmod(inode);
if (code)
return XFS_ERROR(code);
} }
if (DM_EVENT_ENABLED(ip, DM_EVENT_ATTRIBUTE) && if (DM_EVENT_ENABLED(ip, DM_EVENT_ATTRIBUTE) &&
...@@ -482,8 +496,8 @@ xfs_setattr( ...@@ -482,8 +496,8 @@ xfs_setattr(
commit_flags |= XFS_TRANS_ABORT; commit_flags |= XFS_TRANS_ABORT;
/* FALLTHROUGH */ /* FALLTHROUGH */
error_return: error_return:
XFS_QM_DQRELE(mp, udqp); xfs_qm_dqrele(udqp);
XFS_QM_DQRELE(mp, gdqp); xfs_qm_dqrele(gdqp);
if (tp) { if (tp) {
xfs_trans_cancel(tp, commit_flags); xfs_trans_cancel(tp, commit_flags);
} }
...@@ -739,7 +753,8 @@ xfs_free_eofblocks( ...@@ -739,7 +753,8 @@ xfs_free_eofblocks(
/* /*
* Attach the dquots to the inode up front. * Attach the dquots to the inode up front.
*/ */
if ((error = XFS_QM_DQATTACH(mp, ip, 0))) error = xfs_qm_dqattach(ip, 0);
if (error)
return error; return error;
/* /*
...@@ -1181,7 +1196,8 @@ xfs_inactive( ...@@ -1181,7 +1196,8 @@ xfs_inactive(
ASSERT(ip->i_d.di_nlink == 0); ASSERT(ip->i_d.di_nlink == 0);
if ((error = XFS_QM_DQATTACH(mp, ip, 0))) error = xfs_qm_dqattach(ip, 0);
if (error)
return VN_INACTIVE_CACHE; return VN_INACTIVE_CACHE;
tp = xfs_trans_alloc(mp, XFS_TRANS_INACTIVE); tp = xfs_trans_alloc(mp, XFS_TRANS_INACTIVE);
...@@ -1307,7 +1323,7 @@ xfs_inactive( ...@@ -1307,7 +1323,7 @@ xfs_inactive(
/* /*
* Credit the quota account(s). The inode is gone. * Credit the quota account(s). The inode is gone.
*/ */
XFS_TRANS_MOD_DQUOT_BYINO(mp, tp, ip, XFS_TRANS_DQ_ICOUNT, -1); xfs_trans_mod_dquot_byino(tp, ip, XFS_TRANS_DQ_ICOUNT, -1);
/* /*
* Just ignore errors at this point. There is nothing we can * Just ignore errors at this point. There is nothing we can
...@@ -1323,11 +1339,11 @@ xfs_inactive( ...@@ -1323,11 +1339,11 @@ xfs_inactive(
xfs_fs_cmn_err(CE_NOTE, mp, "xfs_inactive: " xfs_fs_cmn_err(CE_NOTE, mp, "xfs_inactive: "
"xfs_trans_commit() returned error %d", error); "xfs_trans_commit() returned error %d", error);
} }
/* /*
* Release the dquots held by inode, if any. * Release the dquots held by inode, if any.
*/ */
XFS_QM_DQDETACH(mp, ip); xfs_qm_dqdetach(ip);
xfs_iunlock(ip, XFS_IOLOCK_EXCL | XFS_ILOCK_EXCL); xfs_iunlock(ip, XFS_IOLOCK_EXCL | XFS_ILOCK_EXCL);
out: out:
...@@ -1427,8 +1443,7 @@ xfs_create( ...@@ -1427,8 +1443,7 @@ xfs_create(
/* /*
* Make sure that we have allocated dquot(s) on disk. * Make sure that we have allocated dquot(s) on disk.
*/ */
error = XFS_QM_DQVOPALLOC(mp, dp, error = xfs_qm_vop_dqalloc(dp, current_fsuid(), current_fsgid(), prid,
current_fsuid(), current_fsgid(), prid,
XFS_QMOPT_QUOTALL | XFS_QMOPT_INHERIT, &udqp, &gdqp); XFS_QMOPT_QUOTALL | XFS_QMOPT_INHERIT, &udqp, &gdqp);
if (error) if (error)
goto std_return; goto std_return;
...@@ -1489,7 +1504,7 @@ xfs_create( ...@@ -1489,7 +1504,7 @@ xfs_create(
/* /*
* Reserve disk quota and the inode. * Reserve disk quota and the inode.
*/ */
error = XFS_TRANS_RESERVE_QUOTA(mp, tp, udqp, gdqp, resblks, 1, 0); error = xfs_trans_reserve_quota(tp, mp, udqp, gdqp, resblks, 1, 0);
if (error) if (error)
goto out_trans_cancel; goto out_trans_cancel;
...@@ -1561,7 +1576,7 @@ xfs_create( ...@@ -1561,7 +1576,7 @@ xfs_create(
* These ids of the inode couldn't have changed since the new * These ids of the inode couldn't have changed since the new
* inode has been locked ever since it was created. * inode has been locked ever since it was created.
*/ */
XFS_QM_DQVOPCREATE(mp, tp, ip, udqp, gdqp); xfs_qm_vop_create_dqattach(tp, ip, udqp, gdqp);
/* /*
* xfs_trans_commit normally decrements the vnode ref count * xfs_trans_commit normally decrements the vnode ref count
...@@ -1580,8 +1595,8 @@ xfs_create( ...@@ -1580,8 +1595,8 @@ xfs_create(
goto out_dqrele; goto out_dqrele;
} }
XFS_QM_DQRELE(mp, udqp); xfs_qm_dqrele(udqp);
XFS_QM_DQRELE(mp, gdqp); xfs_qm_dqrele(gdqp);
*ipp = ip; *ipp = ip;
...@@ -1602,8 +1617,8 @@ xfs_create( ...@@ -1602,8 +1617,8 @@ xfs_create(
out_trans_cancel: out_trans_cancel:
xfs_trans_cancel(tp, cancel_flags); xfs_trans_cancel(tp, cancel_flags);
out_dqrele: out_dqrele:
XFS_QM_DQRELE(mp, udqp); xfs_qm_dqrele(udqp);
XFS_QM_DQRELE(mp, gdqp); xfs_qm_dqrele(gdqp);
if (unlock_dp_on_error) if (unlock_dp_on_error)
xfs_iunlock(dp, XFS_ILOCK_EXCL); xfs_iunlock(dp, XFS_ILOCK_EXCL);
...@@ -1837,11 +1852,11 @@ xfs_remove( ...@@ -1837,11 +1852,11 @@ xfs_remove(
return error; return error;
} }
error = XFS_QM_DQATTACH(mp, dp, 0); error = xfs_qm_dqattach(dp, 0);
if (error) if (error)
goto std_return; goto std_return;
error = XFS_QM_DQATTACH(mp, ip, 0); error = xfs_qm_dqattach(ip, 0);
if (error) if (error)
goto std_return; goto std_return;
...@@ -2028,11 +2043,11 @@ xfs_link( ...@@ -2028,11 +2043,11 @@ xfs_link(
/* Return through std_return after this point. */ /* Return through std_return after this point. */
error = XFS_QM_DQATTACH(mp, sip, 0); error = xfs_qm_dqattach(sip, 0);
if (error) if (error)
goto std_return; goto std_return;
error = XFS_QM_DQATTACH(mp, tdp, 0); error = xfs_qm_dqattach(tdp, 0);
if (error) if (error)
goto std_return; goto std_return;
...@@ -2205,8 +2220,7 @@ xfs_symlink( ...@@ -2205,8 +2220,7 @@ xfs_symlink(
/* /*
* Make sure that we have allocated dquot(s) on disk. * Make sure that we have allocated dquot(s) on disk.
*/ */
error = XFS_QM_DQVOPALLOC(mp, dp, error = xfs_qm_vop_dqalloc(dp, current_fsuid(), current_fsgid(), prid,
current_fsuid(), current_fsgid(), prid,
XFS_QMOPT_QUOTALL | XFS_QMOPT_INHERIT, &udqp, &gdqp); XFS_QMOPT_QUOTALL | XFS_QMOPT_INHERIT, &udqp, &gdqp);
if (error) if (error)
goto std_return; goto std_return;
...@@ -2248,7 +2262,7 @@ xfs_symlink( ...@@ -2248,7 +2262,7 @@ xfs_symlink(
/* /*
* Reserve disk quota : blocks and inode. * Reserve disk quota : blocks and inode.
*/ */
error = XFS_TRANS_RESERVE_QUOTA(mp, tp, udqp, gdqp, resblks, 1, 0); error = xfs_trans_reserve_quota(tp, mp, udqp, gdqp, resblks, 1, 0);
if (error) if (error)
goto error_return; goto error_return;
...@@ -2288,7 +2302,7 @@ xfs_symlink( ...@@ -2288,7 +2302,7 @@ xfs_symlink(
/* /*
* Also attach the dquot(s) to it, if applicable. * Also attach the dquot(s) to it, if applicable.
*/ */
XFS_QM_DQVOPCREATE(mp, tp, ip, udqp, gdqp); xfs_qm_vop_create_dqattach(tp, ip, udqp, gdqp);
if (resblks) if (resblks)
resblks -= XFS_IALLOC_SPACE_RES(mp); resblks -= XFS_IALLOC_SPACE_RES(mp);
...@@ -2376,8 +2390,8 @@ xfs_symlink( ...@@ -2376,8 +2390,8 @@ xfs_symlink(
goto error2; goto error2;
} }
error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES); error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES);
XFS_QM_DQRELE(mp, udqp); xfs_qm_dqrele(udqp);
XFS_QM_DQRELE(mp, gdqp); xfs_qm_dqrele(gdqp);
/* Fall through to std_return with error = 0 or errno from /* Fall through to std_return with error = 0 or errno from
* xfs_trans_commit */ * xfs_trans_commit */
...@@ -2401,8 +2415,8 @@ xfs_symlink( ...@@ -2401,8 +2415,8 @@ xfs_symlink(
cancel_flags |= XFS_TRANS_ABORT; cancel_flags |= XFS_TRANS_ABORT;
error_return: error_return:
xfs_trans_cancel(tp, cancel_flags); xfs_trans_cancel(tp, cancel_flags);
XFS_QM_DQRELE(mp, udqp); xfs_qm_dqrele(udqp);
XFS_QM_DQRELE(mp, gdqp); xfs_qm_dqrele(gdqp);
if (unlock_dp_on_error) if (unlock_dp_on_error)
xfs_iunlock(dp, XFS_ILOCK_EXCL); xfs_iunlock(dp, XFS_ILOCK_EXCL);
...@@ -2541,7 +2555,8 @@ xfs_alloc_file_space( ...@@ -2541,7 +2555,8 @@ xfs_alloc_file_space(
if (XFS_FORCED_SHUTDOWN(mp)) if (XFS_FORCED_SHUTDOWN(mp))
return XFS_ERROR(EIO); return XFS_ERROR(EIO);
if ((error = XFS_QM_DQATTACH(mp, ip, 0))) error = xfs_qm_dqattach(ip, 0);
if (error)
return error; return error;
if (len <= 0) if (len <= 0)
...@@ -2628,8 +2643,8 @@ xfs_alloc_file_space( ...@@ -2628,8 +2643,8 @@ xfs_alloc_file_space(
break; break;
} }
xfs_ilock(ip, XFS_ILOCK_EXCL); xfs_ilock(ip, XFS_ILOCK_EXCL);
error = XFS_TRANS_RESERVE_QUOTA_NBLKS(mp, tp, ip, error = xfs_trans_reserve_quota_nblks(tp, ip, qblocks,
qblocks, 0, quota_flag); 0, quota_flag);
if (error) if (error)
goto error1; goto error1;
...@@ -2688,7 +2703,7 @@ xfs_alloc_file_space( ...@@ -2688,7 +2703,7 @@ xfs_alloc_file_space(
error0: /* Cancel bmap, unlock inode, unreserve quota blocks, cancel trans */ error0: /* Cancel bmap, unlock inode, unreserve quota blocks, cancel trans */
xfs_bmap_cancel(&free_list); xfs_bmap_cancel(&free_list);
XFS_TRANS_UNRESERVE_QUOTA_NBLKS(mp, tp, ip, qblocks, 0, quota_flag); xfs_trans_unreserve_quota_nblks(tp, ip, qblocks, 0, quota_flag);
error1: /* Just cancel transaction */ error1: /* Just cancel transaction */
xfs_trans_cancel(tp, XFS_TRANS_RELEASE_LOG_RES | XFS_TRANS_ABORT); xfs_trans_cancel(tp, XFS_TRANS_RELEASE_LOG_RES | XFS_TRANS_ABORT);
...@@ -2827,7 +2842,8 @@ xfs_free_file_space( ...@@ -2827,7 +2842,8 @@ xfs_free_file_space(
xfs_itrace_entry(ip); xfs_itrace_entry(ip);
if ((error = XFS_QM_DQATTACH(mp, ip, 0))) error = xfs_qm_dqattach(ip, 0);
if (error)
return error; return error;
error = 0; error = 0;
...@@ -2953,9 +2969,9 @@ xfs_free_file_space( ...@@ -2953,9 +2969,9 @@ xfs_free_file_space(
break; break;
} }
xfs_ilock(ip, XFS_ILOCK_EXCL); xfs_ilock(ip, XFS_ILOCK_EXCL);
error = XFS_TRANS_RESERVE_QUOTA(mp, tp, error = xfs_trans_reserve_quota(tp, mp,
ip->i_udquot, ip->i_gdquot, resblks, 0, ip->i_udquot, ip->i_gdquot,
XFS_QMOPT_RES_REGBLKS); resblks, 0, XFS_QMOPT_RES_REGBLKS);
if (error) if (error)
goto error1; goto error1;
......
...@@ -18,6 +18,7 @@ int xfs_setattr(struct xfs_inode *ip, struct iattr *vap, int flags); ...@@ -18,6 +18,7 @@ int xfs_setattr(struct xfs_inode *ip, struct iattr *vap, int flags);
#define XFS_ATTR_DMI 0x01 /* invocation from a DMI function */ #define XFS_ATTR_DMI 0x01 /* invocation from a DMI function */
#define XFS_ATTR_NONBLOCK 0x02 /* return EAGAIN if operation would block */ #define XFS_ATTR_NONBLOCK 0x02 /* return EAGAIN if operation would block */
#define XFS_ATTR_NOLOCK 0x04 /* Don't grab any conflicting locks */ #define XFS_ATTR_NOLOCK 0x04 /* Don't grab any conflicting locks */
#define XFS_ATTR_NOACL 0x08 /* Don't call xfs_acl_chmod */
int xfs_readlink(struct xfs_inode *ip, char *link); int xfs_readlink(struct xfs_inode *ip, char *link);
int xfs_fsync(struct xfs_inode *ip); int xfs_fsync(struct xfs_inode *ip);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment