You've already forked linux-apfs
mirror of
https://github.com/linux-apfs/linux-apfs.git
synced 2026-05-01 15:00:59 -07:00
Merge rsync://oss.sgi.com/git/xfs-2.6
This commit is contained in:
+77
-76
@@ -61,12 +61,13 @@
|
||||
* File wide globals
|
||||
*/
|
||||
|
||||
STATIC kmem_cache_t *pagebuf_cache;
|
||||
STATIC kmem_cache_t *pagebuf_zone;
|
||||
STATIC kmem_shaker_t pagebuf_shake;
|
||||
STATIC int pagebuf_daemon_wakeup(int, unsigned int);
|
||||
STATIC int xfsbufd_wakeup(int, unsigned int);
|
||||
STATIC void pagebuf_delwri_queue(xfs_buf_t *, int);
|
||||
STATIC struct workqueue_struct *pagebuf_logio_workqueue;
|
||||
STATIC struct workqueue_struct *pagebuf_dataio_workqueue;
|
||||
|
||||
STATIC struct workqueue_struct *xfslogd_workqueue;
|
||||
STATIC struct workqueue_struct *xfsdatad_workqueue;
|
||||
|
||||
/*
|
||||
* Pagebuf debugging
|
||||
@@ -123,9 +124,9 @@ ktrace_t *pagebuf_trace_buf;
|
||||
|
||||
|
||||
#define pagebuf_allocate(flags) \
|
||||
kmem_zone_alloc(pagebuf_cache, pb_to_km(flags))
|
||||
kmem_zone_alloc(pagebuf_zone, pb_to_km(flags))
|
||||
#define pagebuf_deallocate(pb) \
|
||||
kmem_zone_free(pagebuf_cache, (pb));
|
||||
kmem_zone_free(pagebuf_zone, (pb));
|
||||
|
||||
/*
|
||||
* Page Region interfaces.
|
||||
@@ -425,7 +426,7 @@ _pagebuf_lookup_pages(
|
||||
__FUNCTION__, gfp_mask);
|
||||
|
||||
XFS_STATS_INC(pb_page_retries);
|
||||
pagebuf_daemon_wakeup(0, gfp_mask);
|
||||
xfsbufd_wakeup(0, gfp_mask);
|
||||
blk_congestion_wait(WRITE, HZ/50);
|
||||
goto retry;
|
||||
}
|
||||
@@ -1136,8 +1137,8 @@ pagebuf_iodone(
|
||||
if ((pb->pb_iodone) || (pb->pb_flags & PBF_ASYNC)) {
|
||||
if (schedule) {
|
||||
INIT_WORK(&pb->pb_iodone_work, pagebuf_iodone_work, pb);
|
||||
queue_work(dataio ? pagebuf_dataio_workqueue :
|
||||
pagebuf_logio_workqueue, &pb->pb_iodone_work);
|
||||
queue_work(dataio ? xfsdatad_workqueue :
|
||||
xfslogd_workqueue, &pb->pb_iodone_work);
|
||||
} else {
|
||||
pagebuf_iodone_work(pb);
|
||||
}
|
||||
@@ -1562,16 +1563,6 @@ xfs_free_buftarg(
|
||||
kmem_free(btp, sizeof(*btp));
|
||||
}
|
||||
|
||||
void
|
||||
xfs_incore_relse(
|
||||
xfs_buftarg_t *btp,
|
||||
int delwri_only,
|
||||
int wait)
|
||||
{
|
||||
invalidate_bdev(btp->pbr_bdev, 1);
|
||||
truncate_inode_pages(btp->pbr_mapping, 0LL);
|
||||
}
|
||||
|
||||
STATIC int
|
||||
xfs_setsize_buftarg_flags(
|
||||
xfs_buftarg_t *btp,
|
||||
@@ -1742,27 +1733,27 @@ pagebuf_runall_queues(
|
||||
}
|
||||
|
||||
/* Defines for pagebuf daemon */
|
||||
STATIC DECLARE_COMPLETION(pagebuf_daemon_done);
|
||||
STATIC struct task_struct *pagebuf_daemon_task;
|
||||
STATIC int pagebuf_daemon_active;
|
||||
STATIC int force_flush;
|
||||
STATIC int force_sleep;
|
||||
STATIC DECLARE_COMPLETION(xfsbufd_done);
|
||||
STATIC struct task_struct *xfsbufd_task;
|
||||
STATIC int xfsbufd_active;
|
||||
STATIC int xfsbufd_force_flush;
|
||||
STATIC int xfsbufd_force_sleep;
|
||||
|
||||
STATIC int
|
||||
pagebuf_daemon_wakeup(
|
||||
xfsbufd_wakeup(
|
||||
int priority,
|
||||
unsigned int mask)
|
||||
{
|
||||
if (force_sleep)
|
||||
if (xfsbufd_force_sleep)
|
||||
return 0;
|
||||
force_flush = 1;
|
||||
xfsbufd_force_flush = 1;
|
||||
barrier();
|
||||
wake_up_process(pagebuf_daemon_task);
|
||||
wake_up_process(xfsbufd_task);
|
||||
return 0;
|
||||
}
|
||||
|
||||
STATIC int
|
||||
pagebuf_daemon(
|
||||
xfsbufd(
|
||||
void *data)
|
||||
{
|
||||
struct list_head tmp;
|
||||
@@ -1774,17 +1765,17 @@ pagebuf_daemon(
|
||||
daemonize("xfsbufd");
|
||||
current->flags |= PF_MEMALLOC;
|
||||
|
||||
pagebuf_daemon_task = current;
|
||||
pagebuf_daemon_active = 1;
|
||||
xfsbufd_task = current;
|
||||
xfsbufd_active = 1;
|
||||
barrier();
|
||||
|
||||
INIT_LIST_HEAD(&tmp);
|
||||
do {
|
||||
if (unlikely(current->flags & PF_FREEZE)) {
|
||||
force_sleep = 1;
|
||||
xfsbufd_force_sleep = 1;
|
||||
refrigerator(PF_FREEZE);
|
||||
} else {
|
||||
force_sleep = 0;
|
||||
xfsbufd_force_sleep = 0;
|
||||
}
|
||||
|
||||
set_current_state(TASK_INTERRUPTIBLE);
|
||||
@@ -1797,7 +1788,7 @@ pagebuf_daemon(
|
||||
ASSERT(pb->pb_flags & PBF_DELWRI);
|
||||
|
||||
if (!pagebuf_ispin(pb) && !pagebuf_cond_lock(pb)) {
|
||||
if (!force_flush &&
|
||||
if (!xfsbufd_force_flush &&
|
||||
time_before(jiffies,
|
||||
pb->pb_queuetime + age)) {
|
||||
pagebuf_unlock(pb);
|
||||
@@ -1824,10 +1815,10 @@ pagebuf_daemon(
|
||||
if (as_list_len > 0)
|
||||
purge_addresses();
|
||||
|
||||
force_flush = 0;
|
||||
} while (pagebuf_daemon_active);
|
||||
xfsbufd_force_flush = 0;
|
||||
} while (xfsbufd_active);
|
||||
|
||||
complete_and_exit(&pagebuf_daemon_done, 0);
|
||||
complete_and_exit(&xfsbufd_done, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1844,8 +1835,8 @@ xfs_flush_buftarg(
|
||||
xfs_buf_t *pb, *n;
|
||||
int pincount = 0;
|
||||
|
||||
pagebuf_runall_queues(pagebuf_dataio_workqueue);
|
||||
pagebuf_runall_queues(pagebuf_logio_workqueue);
|
||||
pagebuf_runall_queues(xfsdatad_workqueue);
|
||||
pagebuf_runall_queues(xfslogd_workqueue);
|
||||
|
||||
INIT_LIST_HEAD(&tmp);
|
||||
spin_lock(&pbd_delwrite_lock);
|
||||
@@ -1898,43 +1889,43 @@ xfs_flush_buftarg(
|
||||
}
|
||||
|
||||
STATIC int
|
||||
pagebuf_daemon_start(void)
|
||||
xfs_buf_daemons_start(void)
|
||||
{
|
||||
int rval;
|
||||
int error = -ENOMEM;
|
||||
|
||||
pagebuf_logio_workqueue = create_workqueue("xfslogd");
|
||||
if (!pagebuf_logio_workqueue)
|
||||
return -ENOMEM;
|
||||
xfslogd_workqueue = create_workqueue("xfslogd");
|
||||
if (!xfslogd_workqueue)
|
||||
goto out;
|
||||
|
||||
pagebuf_dataio_workqueue = create_workqueue("xfsdatad");
|
||||
if (!pagebuf_dataio_workqueue) {
|
||||
destroy_workqueue(pagebuf_logio_workqueue);
|
||||
return -ENOMEM;
|
||||
}
|
||||
xfsdatad_workqueue = create_workqueue("xfsdatad");
|
||||
if (!xfsdatad_workqueue)
|
||||
goto out_destroy_xfslogd_workqueue;
|
||||
|
||||
rval = kernel_thread(pagebuf_daemon, NULL, CLONE_FS|CLONE_FILES);
|
||||
if (rval < 0) {
|
||||
destroy_workqueue(pagebuf_logio_workqueue);
|
||||
destroy_workqueue(pagebuf_dataio_workqueue);
|
||||
}
|
||||
error = kernel_thread(xfsbufd, NULL, CLONE_FS|CLONE_FILES);
|
||||
if (error < 0)
|
||||
goto out_destroy_xfsdatad_workqueue;
|
||||
return 0;
|
||||
|
||||
return rval;
|
||||
out_destroy_xfsdatad_workqueue:
|
||||
destroy_workqueue(xfsdatad_workqueue);
|
||||
out_destroy_xfslogd_workqueue:
|
||||
destroy_workqueue(xfslogd_workqueue);
|
||||
out:
|
||||
return error;
|
||||
}
|
||||
|
||||
/*
|
||||
* pagebuf_daemon_stop
|
||||
*
|
||||
* Note: do not mark as __exit, it is called from pagebuf_terminate.
|
||||
*/
|
||||
STATIC void
|
||||
pagebuf_daemon_stop(void)
|
||||
xfs_buf_daemons_stop(void)
|
||||
{
|
||||
pagebuf_daemon_active = 0;
|
||||
xfsbufd_active = 0;
|
||||
barrier();
|
||||
wait_for_completion(&pagebuf_daemon_done);
|
||||
wait_for_completion(&xfsbufd_done);
|
||||
|
||||
destroy_workqueue(pagebuf_logio_workqueue);
|
||||
destroy_workqueue(pagebuf_dataio_workqueue);
|
||||
destroy_workqueue(xfslogd_workqueue);
|
||||
destroy_workqueue(xfsdatad_workqueue);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1944,27 +1935,37 @@ pagebuf_daemon_stop(void)
|
||||
int __init
|
||||
pagebuf_init(void)
|
||||
{
|
||||
pagebuf_cache = kmem_cache_create("xfs_buf_t", sizeof(xfs_buf_t), 0,
|
||||
SLAB_HWCACHE_ALIGN, NULL, NULL);
|
||||
if (pagebuf_cache == NULL) {
|
||||
printk("XFS: couldn't init xfs_buf_t cache\n");
|
||||
pagebuf_terminate();
|
||||
return -ENOMEM;
|
||||
}
|
||||
int error = -ENOMEM;
|
||||
|
||||
pagebuf_zone = kmem_zone_init(sizeof(xfs_buf_t), "xfs_buf");
|
||||
if (!pagebuf_zone)
|
||||
goto out;
|
||||
|
||||
#ifdef PAGEBUF_TRACE
|
||||
pagebuf_trace_buf = ktrace_alloc(PAGEBUF_TRACE_SIZE, KM_SLEEP);
|
||||
#endif
|
||||
|
||||
pagebuf_daemon_start();
|
||||
error = xfs_buf_daemons_start();
|
||||
if (error)
|
||||
goto out_free_buf_zone;
|
||||
|
||||
pagebuf_shake = kmem_shake_register(pagebuf_daemon_wakeup);
|
||||
if (pagebuf_shake == NULL) {
|
||||
pagebuf_terminate();
|
||||
return -ENOMEM;
|
||||
pagebuf_shake = kmem_shake_register(xfsbufd_wakeup);
|
||||
if (!pagebuf_shake) {
|
||||
error = -ENOMEM;
|
||||
goto out_stop_daemons;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
out_stop_daemons:
|
||||
xfs_buf_daemons_stop();
|
||||
out_free_buf_zone:
|
||||
#ifdef PAGEBUF_TRACE
|
||||
ktrace_free(pagebuf_trace_buf);
|
||||
#endif
|
||||
kmem_zone_destroy(pagebuf_zone);
|
||||
out:
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
@@ -1976,12 +1977,12 @@ pagebuf_init(void)
|
||||
void
|
||||
pagebuf_terminate(void)
|
||||
{
|
||||
pagebuf_daemon_stop();
|
||||
xfs_buf_daemons_stop();
|
||||
|
||||
#ifdef PAGEBUF_TRACE
|
||||
ktrace_free(pagebuf_trace_buf);
|
||||
#endif
|
||||
|
||||
kmem_zone_destroy(pagebuf_cache);
|
||||
kmem_zone_destroy(pagebuf_zone);
|
||||
kmem_shake_deregister(pagebuf_shake);
|
||||
}
|
||||
|
||||
@@ -576,7 +576,6 @@ extern xfs_buftarg_t *xfs_alloc_buftarg(struct block_device *, int);
|
||||
extern void xfs_free_buftarg(xfs_buftarg_t *, int);
|
||||
extern void xfs_wait_buftarg(xfs_buftarg_t *);
|
||||
extern int xfs_setsize_buftarg(xfs_buftarg_t *, unsigned int, unsigned int);
|
||||
extern void xfs_incore_relse(xfs_buftarg_t *, int, int);
|
||||
extern int xfs_flush_buftarg(xfs_buftarg_t *, int);
|
||||
|
||||
#define xfs_getsize_buftarg(buftarg) \
|
||||
|
||||
@@ -57,7 +57,9 @@
|
||||
#include <linux/smp_lock.h>
|
||||
|
||||
static struct vm_operations_struct linvfs_file_vm_ops;
|
||||
|
||||
#ifdef CONFIG_XFS_DMAPI
|
||||
static struct vm_operations_struct linvfs_dmapi_file_vm_ops;
|
||||
#endif
|
||||
|
||||
STATIC inline ssize_t
|
||||
__linvfs_read(
|
||||
@@ -388,6 +390,14 @@ done:
|
||||
return -error;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_XFS_DMAPI
|
||||
STATIC void
|
||||
linvfs_mmap_close(
|
||||
struct vm_area_struct *vma)
|
||||
{
|
||||
xfs_dm_mm_put(vma);
|
||||
}
|
||||
#endif /* CONFIG_XFS_DMAPI */
|
||||
|
||||
STATIC int
|
||||
linvfs_file_mmap(
|
||||
@@ -399,16 +409,19 @@ linvfs_file_mmap(
|
||||
vattr_t va = { .va_mask = XFS_AT_UPDATIME };
|
||||
int error;
|
||||
|
||||
vma->vm_ops = &linvfs_file_vm_ops;
|
||||
|
||||
if (vp->v_vfsp->vfs_flag & VFS_DMI) {
|
||||
xfs_mount_t *mp = XFS_VFSTOM(vp->v_vfsp);
|
||||
|
||||
error = -XFS_SEND_MMAP(mp, vma, 0);
|
||||
if (error)
|
||||
return error;
|
||||
#ifdef CONFIG_XFS_DMAPI
|
||||
vma->vm_ops = &linvfs_dmapi_file_vm_ops;
|
||||
#endif
|
||||
}
|
||||
|
||||
vma->vm_ops = &linvfs_file_vm_ops;
|
||||
|
||||
VOP_SETATTR(vp, &va, XFS_AT_UPDATIME, NULL, error);
|
||||
if (!error)
|
||||
vn_revalidate(vp); /* update Linux inode flags */
|
||||
@@ -609,7 +622,15 @@ struct file_operations linvfs_dir_operations = {
|
||||
static struct vm_operations_struct linvfs_file_vm_ops = {
|
||||
.nopage = filemap_nopage,
|
||||
.populate = filemap_populate,
|
||||
};
|
||||
|
||||
#ifdef CONFIG_XFS_DMAPI
|
||||
static struct vm_operations_struct linvfs_dmapi_file_vm_ops = {
|
||||
.close = linvfs_mmap_close,
|
||||
.nopage = filemap_nopage,
|
||||
.populate = filemap_populate,
|
||||
#ifdef HAVE_VMOP_MPROTECT
|
||||
.mprotect = linvfs_mprotect,
|
||||
#endif
|
||||
};
|
||||
#endif /* CONFIG_XFS_DMAPI */
|
||||
|
||||
@@ -1174,7 +1174,8 @@ xfs_ioc_xattr(
|
||||
|
||||
switch (cmd) {
|
||||
case XFS_IOC_FSGETXATTR: {
|
||||
va.va_mask = XFS_AT_XFLAGS|XFS_AT_EXTSIZE|XFS_AT_NEXTENTS;
|
||||
va.va_mask = XFS_AT_XFLAGS | XFS_AT_EXTSIZE | \
|
||||
XFS_AT_NEXTENTS | XFS_AT_PROJID;
|
||||
VOP_GETATTR(vp, &va, 0, NULL, error);
|
||||
if (error)
|
||||
return -error;
|
||||
@@ -1182,6 +1183,7 @@ xfs_ioc_xattr(
|
||||
fa.fsx_xflags = va.va_xflags;
|
||||
fa.fsx_extsize = va.va_extsize;
|
||||
fa.fsx_nextents = va.va_nextents;
|
||||
fa.fsx_projid = va.va_projid;
|
||||
|
||||
if (copy_to_user(arg, &fa, sizeof(fa)))
|
||||
return -XFS_ERROR(EFAULT);
|
||||
@@ -1196,9 +1198,10 @@ xfs_ioc_xattr(
|
||||
if (filp->f_flags & (O_NDELAY|O_NONBLOCK))
|
||||
attr_flags |= ATTR_NONBLOCK;
|
||||
|
||||
va.va_mask = XFS_AT_XFLAGS | XFS_AT_EXTSIZE;
|
||||
va.va_mask = XFS_AT_XFLAGS | XFS_AT_EXTSIZE | XFS_AT_PROJID;
|
||||
va.va_xflags = fa.fsx_xflags;
|
||||
va.va_extsize = fa.fsx_extsize;
|
||||
va.va_projid = fa.fsx_projid;
|
||||
|
||||
VOP_SETATTR(vp, &va, attr_flags, NULL, error);
|
||||
if (!error)
|
||||
@@ -1207,7 +1210,8 @@ xfs_ioc_xattr(
|
||||
}
|
||||
|
||||
case XFS_IOC_FSGETXATTRA: {
|
||||
va.va_mask = XFS_AT_XFLAGS|XFS_AT_EXTSIZE|XFS_AT_ANEXTENTS;
|
||||
va.va_mask = XFS_AT_XFLAGS | XFS_AT_EXTSIZE | \
|
||||
XFS_AT_ANEXTENTS | XFS_AT_PROJID;
|
||||
VOP_GETATTR(vp, &va, 0, NULL, error);
|
||||
if (error)
|
||||
return -error;
|
||||
@@ -1215,6 +1219,7 @@ xfs_ioc_xattr(
|
||||
fa.fsx_xflags = va.va_xflags;
|
||||
fa.fsx_extsize = va.va_extsize;
|
||||
fa.fsx_nextents = va.va_anextents;
|
||||
fa.fsx_projid = va.va_projid;
|
||||
|
||||
if (copy_to_user(arg, &fa, sizeof(fa)))
|
||||
return -XFS_ERROR(EFAULT);
|
||||
|
||||
@@ -230,8 +230,10 @@ static inline void set_buffer_unwritten_io(struct buffer_head *bh)
|
||||
* field (see the QCMD macro in quota.h). These macros help keep the
|
||||
* code portable - they are not visible from the syscall interface.
|
||||
*/
|
||||
#define Q_XSETGQLIM XQM_CMD(0x8) /* set groups disk limits */
|
||||
#define Q_XGETGQUOTA XQM_CMD(0x9) /* get groups disk limits */
|
||||
#define Q_XSETGQLIM XQM_CMD(8) /* set groups disk limits */
|
||||
#define Q_XGETGQUOTA XQM_CMD(9) /* get groups disk limits */
|
||||
#define Q_XSETPQLIM XQM_CMD(10) /* set projects disk limits */
|
||||
#define Q_XGETPQUOTA XQM_CMD(11) /* get projects disk limits */
|
||||
|
||||
/* IRIX uses a dynamic sizing algorithm (ndquot = 200 + numprocs*2) */
|
||||
/* we may well need to fine-tune this if it ever becomes an issue. */
|
||||
|
||||
@@ -209,30 +209,6 @@ unlock:
|
||||
return (-status);
|
||||
}
|
||||
|
||||
/*
|
||||
* xfs_inval_cached_pages
|
||||
*
|
||||
* This routine is responsible for keeping direct I/O and buffered I/O
|
||||
* somewhat coherent. From here we make sure that we're at least
|
||||
* temporarily holding the inode I/O lock exclusively and then call
|
||||
* the page cache to flush and invalidate any cached pages. If there
|
||||
* are no cached pages this routine will be very quick.
|
||||
*/
|
||||
void
|
||||
xfs_inval_cached_pages(
|
||||
vnode_t *vp,
|
||||
xfs_iocore_t *io,
|
||||
xfs_off_t offset,
|
||||
int write,
|
||||
int relock)
|
||||
{
|
||||
if (VN_CACHED(vp)) {
|
||||
xfs_inval_cached_trace(io, offset, -1, ctooff(offtoct(offset)), -1);
|
||||
VOP_FLUSHINVAL_PAGES(vp, ctooff(offtoct(offset)), -1, FI_REMAPF_LOCKED);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
ssize_t /* bytes read, or (-) error */
|
||||
xfs_read(
|
||||
bhv_desc_t *bdp,
|
||||
@@ -304,10 +280,11 @@ xfs_read(
|
||||
if (DM_EVENT_ENABLED(vp->v_vfsp, ip, DM_EVENT_READ) &&
|
||||
!(ioflags & IO_INVIS)) {
|
||||
vrwlock_t locktype = VRWLOCK_READ;
|
||||
int dmflags = FILP_DELAY_FLAG(file) | DM_SEM_FLAG_RD(ioflags);
|
||||
|
||||
ret = -XFS_SEND_DATA(mp, DM_EVENT_READ,
|
||||
BHV_TO_VNODE(bdp), *offset, size,
|
||||
FILP_DELAY_FLAG(file), &locktype);
|
||||
dmflags, &locktype);
|
||||
if (ret) {
|
||||
xfs_iunlock(ip, XFS_IOLOCK_SHARED);
|
||||
goto unlock_isem;
|
||||
@@ -867,11 +844,15 @@ retry:
|
||||
!(ioflags & IO_INVIS)) {
|
||||
|
||||
xfs_rwunlock(bdp, locktype);
|
||||
if (need_isem)
|
||||
up(&inode->i_sem);
|
||||
error = XFS_SEND_NAMESP(xip->i_mount, DM_EVENT_NOSPACE, vp,
|
||||
DM_RIGHT_NULL, vp, DM_RIGHT_NULL, NULL, NULL,
|
||||
0, 0, 0); /* Delay flag intentionally unused */
|
||||
if (error)
|
||||
goto out_unlock_isem;
|
||||
goto out_nounlocks;
|
||||
if (need_isem)
|
||||
down(&inode->i_sem);
|
||||
xfs_rwlock(bdp, locktype);
|
||||
pos = xip->i_d.di_size;
|
||||
ret = 0;
|
||||
@@ -986,6 +967,7 @@ retry:
|
||||
out_unlock_isem:
|
||||
if (need_isem)
|
||||
up(&inode->i_sem);
|
||||
out_nounlocks:
|
||||
return -error;
|
||||
}
|
||||
|
||||
|
||||
@@ -94,8 +94,6 @@ extern int xfs_bdstrat_cb(struct xfs_buf *);
|
||||
|
||||
extern int xfs_zero_eof(struct vnode *, struct xfs_iocore *, xfs_off_t,
|
||||
xfs_fsize_t, xfs_fsize_t);
|
||||
extern void xfs_inval_cached_pages(struct vnode *, struct xfs_iocore *,
|
||||
xfs_off_t, int, int);
|
||||
extern ssize_t xfs_read(struct bhv_desc *, struct kiocb *,
|
||||
const struct iovec *, unsigned int,
|
||||
loff_t *, int, struct cred *);
|
||||
|
||||
@@ -590,8 +590,10 @@ linvfs_sync_super(
|
||||
int error;
|
||||
int flags = SYNC_FSDATA;
|
||||
|
||||
if (wait)
|
||||
flags |= SYNC_WAIT;
|
||||
if (unlikely(sb->s_frozen == SB_FREEZE_WRITE))
|
||||
flags = SYNC_QUIESCE;
|
||||
else
|
||||
flags = SYNC_FSDATA | (wait ? SYNC_WAIT : 0);
|
||||
|
||||
VFS_SYNC(vfsp, flags, NULL, error);
|
||||
sb->s_dirt = 0;
|
||||
@@ -701,7 +703,8 @@ linvfs_getxquota(
|
||||
struct vfs *vfsp = LINVFS_GET_VFS(sb);
|
||||
int error, getmode;
|
||||
|
||||
getmode = (type == GRPQUOTA) ? Q_XGETGQUOTA : Q_XGETQUOTA;
|
||||
getmode = (type == USRQUOTA) ? Q_XGETQUOTA :
|
||||
((type == GRPQUOTA) ? Q_XGETGQUOTA : Q_XGETPQUOTA);
|
||||
VFS_QUOTACTL(vfsp, getmode, id, (caddr_t)fdq, error);
|
||||
return -error;
|
||||
}
|
||||
@@ -716,7 +719,8 @@ linvfs_setxquota(
|
||||
struct vfs *vfsp = LINVFS_GET_VFS(sb);
|
||||
int error, setmode;
|
||||
|
||||
setmode = (type == GRPQUOTA) ? Q_XSETGQLIM : Q_XSETQLIM;
|
||||
setmode = (type == USRQUOTA) ? Q_XSETQLIM :
|
||||
((type == GRPQUOTA) ? Q_XSETGQLIM : Q_XSETPQLIM);
|
||||
VFS_QUOTACTL(vfsp, setmode, id, (caddr_t)fdq, error);
|
||||
return -error;
|
||||
}
|
||||
|
||||
@@ -107,6 +107,7 @@ typedef enum {
|
||||
#define SYNC_FSDATA 0x0020 /* flush fs data (e.g. superblocks) */
|
||||
#define SYNC_REFCACHE 0x0040 /* prune some of the nfs ref cache */
|
||||
#define SYNC_REMOUNT 0x0080 /* remount readonly, no dummy LRs */
|
||||
#define SYNC_QUIESCE 0x0100 /* quiesce fileystem for a snapshot */
|
||||
|
||||
typedef int (*vfs_mount_t)(bhv_desc_t *,
|
||||
struct xfs_mount_args *, struct cred *);
|
||||
|
||||
@@ -411,13 +411,13 @@ vn_remove(
|
||||
/* 0 */ (void *)(__psint_t)(vk), \
|
||||
/* 1 */ (void *)(s), \
|
||||
/* 2 */ (void *)(__psint_t) line, \
|
||||
/* 3 */ (void *)(vn_count(vp)), \
|
||||
/* 3 */ (void *)(__psint_t)(vn_count(vp)), \
|
||||
/* 4 */ (void *)(ra), \
|
||||
/* 5 */ (void *)(__psunsigned_t)(vp)->v_flag, \
|
||||
/* 6 */ (void *)(__psint_t)current_cpu(), \
|
||||
/* 7 */ (void *)(__psint_t)current_pid(), \
|
||||
/* 8 */ (void *)__return_address, \
|
||||
/* 9 */ 0, 0, 0, 0, 0, 0, 0)
|
||||
/* 9 */ NULL, NULL, NULL, NULL, NULL, NULL, NULL)
|
||||
|
||||
/*
|
||||
* Vnode tracing code.
|
||||
|
||||
@@ -426,7 +426,7 @@ typedef struct vattr {
|
||||
u_long va_extsize; /* file extent size */
|
||||
u_long va_nextents; /* number of extents in file */
|
||||
u_long va_anextents; /* number of attr extents in file */
|
||||
int va_projid; /* project id */
|
||||
prid_t va_projid; /* project id */
|
||||
} vattr_t;
|
||||
|
||||
/*
|
||||
|
||||
+26
-79
@@ -101,7 +101,7 @@ int xfs_dqerror_mod = 33;
|
||||
* is the d_id field. The idea is to fill in the entire q_core
|
||||
* when we read in the on disk dquot.
|
||||
*/
|
||||
xfs_dquot_t *
|
||||
STATIC xfs_dquot_t *
|
||||
xfs_qm_dqinit(
|
||||
xfs_mount_t *mp,
|
||||
xfs_dqid_t id,
|
||||
@@ -286,7 +286,9 @@ xfs_qm_adjust_dqlimits(
|
||||
* We also return 0 as the values of the timers in Q_GETQUOTA calls, when
|
||||
* enforcement's off.
|
||||
* In contrast, warnings are a little different in that they don't
|
||||
* 'automatically' get started when limits get exceeded.
|
||||
* 'automatically' get started when limits get exceeded. They do
|
||||
* get reset to zero, however, when we find the count to be under
|
||||
* the soft limit (they are only ever set non-zero via userspace).
|
||||
*/
|
||||
void
|
||||
xfs_qm_adjust_dqtimers(
|
||||
@@ -315,6 +317,8 @@ xfs_qm_adjust_dqtimers(
|
||||
INT_GET(d->d_blk_hardlimit, ARCH_CONVERT)))) {
|
||||
INT_SET(d->d_btimer, ARCH_CONVERT,
|
||||
get_seconds() + XFS_QI_BTIMELIMIT(mp));
|
||||
} else {
|
||||
d->d_bwarns = 0;
|
||||
}
|
||||
} else {
|
||||
if ((!d->d_blk_softlimit ||
|
||||
@@ -336,6 +340,8 @@ xfs_qm_adjust_dqtimers(
|
||||
INT_GET(d->d_ino_hardlimit, ARCH_CONVERT)))) {
|
||||
INT_SET(d->d_itimer, ARCH_CONVERT,
|
||||
get_seconds() + XFS_QI_ITIMELIMIT(mp));
|
||||
} else {
|
||||
d->d_iwarns = 0;
|
||||
}
|
||||
} else {
|
||||
if ((!d->d_ino_softlimit ||
|
||||
@@ -357,6 +363,8 @@ xfs_qm_adjust_dqtimers(
|
||||
INT_GET(d->d_rtb_hardlimit, ARCH_CONVERT)))) {
|
||||
INT_SET(d->d_rtbtimer, ARCH_CONVERT,
|
||||
get_seconds() + XFS_QI_RTBTIMELIMIT(mp));
|
||||
} else {
|
||||
d->d_rtbwarns = 0;
|
||||
}
|
||||
} else {
|
||||
if ((!d->d_rtb_softlimit ||
|
||||
@@ -370,68 +378,6 @@ xfs_qm_adjust_dqtimers(
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Increment or reset warnings of a given dquot.
|
||||
*/
|
||||
int
|
||||
xfs_qm_dqwarn(
|
||||
xfs_disk_dquot_t *d,
|
||||
uint flags)
|
||||
{
|
||||
int warned;
|
||||
|
||||
/*
|
||||
* root's limits are not real limits.
|
||||
*/
|
||||
if (!d->d_id)
|
||||
return (0);
|
||||
|
||||
warned = 0;
|
||||
if (INT_GET(d->d_blk_softlimit, ARCH_CONVERT) &&
|
||||
(INT_GET(d->d_bcount, ARCH_CONVERT) >=
|
||||
INT_GET(d->d_blk_softlimit, ARCH_CONVERT))) {
|
||||
if (flags & XFS_QMOPT_DOWARN) {
|
||||
INT_MOD(d->d_bwarns, ARCH_CONVERT, +1);
|
||||
warned++;
|
||||
}
|
||||
} else {
|
||||
if (!d->d_blk_softlimit ||
|
||||
(INT_GET(d->d_bcount, ARCH_CONVERT) <
|
||||
INT_GET(d->d_blk_softlimit, ARCH_CONVERT))) {
|
||||
d->d_bwarns = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (INT_GET(d->d_ino_softlimit, ARCH_CONVERT) > 0 &&
|
||||
(INT_GET(d->d_icount, ARCH_CONVERT) >=
|
||||
INT_GET(d->d_ino_softlimit, ARCH_CONVERT))) {
|
||||
if (flags & XFS_QMOPT_DOWARN) {
|
||||
INT_MOD(d->d_iwarns, ARCH_CONVERT, +1);
|
||||
warned++;
|
||||
}
|
||||
} else {
|
||||
if (!d->d_ino_softlimit ||
|
||||
(INT_GET(d->d_icount, ARCH_CONVERT) <
|
||||
INT_GET(d->d_ino_softlimit, ARCH_CONVERT))) {
|
||||
d->d_iwarns = 0;
|
||||
}
|
||||
}
|
||||
#ifdef QUOTADEBUG
|
||||
if (INT_GET(d->d_iwarns, ARCH_CONVERT))
|
||||
cmn_err(CE_DEBUG,
|
||||
"--------@@Inode warnings running : %Lu >= %Lu",
|
||||
INT_GET(d->d_icount, ARCH_CONVERT),
|
||||
INT_GET(d->d_ino_softlimit, ARCH_CONVERT));
|
||||
if (INT_GET(d->d_bwarns, ARCH_CONVERT))
|
||||
cmn_err(CE_DEBUG,
|
||||
"--------@@Blks warnings running : %Lu >= %Lu",
|
||||
INT_GET(d->d_bcount, ARCH_CONVERT),
|
||||
INT_GET(d->d_blk_softlimit, ARCH_CONVERT));
|
||||
#endif
|
||||
return (warned);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* initialize a buffer full of dquots and log the whole thing
|
||||
*/
|
||||
@@ -461,9 +407,9 @@ xfs_qm_init_dquot_blk(
|
||||
for (i = 0; i < XFS_QM_DQPERBLK(mp); i++, d++, curid++)
|
||||
xfs_qm_dqinit_core(curid, type, d);
|
||||
xfs_trans_dquot_buf(tp, bp,
|
||||
type & XFS_DQ_USER ?
|
||||
XFS_BLI_UDQUOT_BUF :
|
||||
XFS_BLI_GDQUOT_BUF);
|
||||
(type & XFS_DQ_USER ? XFS_BLI_UDQUOT_BUF :
|
||||
((type & XFS_DQ_PROJ) ? XFS_BLI_PDQUOT_BUF :
|
||||
XFS_BLI_GDQUOT_BUF)));
|
||||
xfs_trans_log_buf(tp, bp, 0, BBTOB(XFS_QI_DQCHUNKLEN(mp)) - 1);
|
||||
}
|
||||
|
||||
@@ -544,8 +490,7 @@ xfs_qm_dqalloc(
|
||||
* the entire thing.
|
||||
*/
|
||||
xfs_qm_init_dquot_blk(tp, mp, INT_GET(dqp->q_core.d_id, ARCH_CONVERT),
|
||||
dqp->dq_flags & (XFS_DQ_USER|XFS_DQ_GROUP),
|
||||
bp);
|
||||
dqp->dq_flags & XFS_DQ_ALLTYPES, bp);
|
||||
|
||||
if ((error = xfs_bmap_finish(&tp, &flist, firstblock, &committed))) {
|
||||
goto error1;
|
||||
@@ -675,8 +620,7 @@ xfs_qm_dqtobp(
|
||||
/*
|
||||
* A simple sanity check in case we got a corrupted dquot...
|
||||
*/
|
||||
if (xfs_qm_dqcheck(ddq, id,
|
||||
dqp->dq_flags & (XFS_DQ_USER|XFS_DQ_GROUP),
|
||||
if (xfs_qm_dqcheck(ddq, id, dqp->dq_flags & XFS_DQ_ALLTYPES,
|
||||
flags & (XFS_QMOPT_DQREPAIR|XFS_QMOPT_DOWARN),
|
||||
"dqtobp")) {
|
||||
if (!(flags & XFS_QMOPT_DQREPAIR)) {
|
||||
@@ -953,8 +897,8 @@ int
|
||||
xfs_qm_dqget(
|
||||
xfs_mount_t *mp,
|
||||
xfs_inode_t *ip, /* locked inode (optional) */
|
||||
xfs_dqid_t id, /* gid or uid, depending on type */
|
||||
uint type, /* UDQUOT or GDQUOT */
|
||||
xfs_dqid_t id, /* uid/projid/gid depending on type */
|
||||
uint type, /* XFS_DQ_USER/XFS_DQ_PROJ/XFS_DQ_GROUP */
|
||||
uint flags, /* DQALLOC, DQSUSER, DQREPAIR, DOWARN */
|
||||
xfs_dquot_t **O_dqpp) /* OUT : locked incore dquot */
|
||||
{
|
||||
@@ -965,6 +909,7 @@ xfs_qm_dqget(
|
||||
|
||||
ASSERT(XFS_IS_QUOTA_RUNNING(mp));
|
||||
if ((! XFS_IS_UQUOTA_ON(mp) && type == XFS_DQ_USER) ||
|
||||
(! XFS_IS_PQUOTA_ON(mp) && type == XFS_DQ_PROJ) ||
|
||||
(! XFS_IS_GQUOTA_ON(mp) && type == XFS_DQ_GROUP)) {
|
||||
return (ESRCH);
|
||||
}
|
||||
@@ -983,7 +928,9 @@ xfs_qm_dqget(
|
||||
again:
|
||||
|
||||
#ifdef DEBUG
|
||||
ASSERT(type == XFS_DQ_USER || type == XFS_DQ_GROUP);
|
||||
ASSERT(type == XFS_DQ_USER ||
|
||||
type == XFS_DQ_PROJ ||
|
||||
type == XFS_DQ_GROUP);
|
||||
if (ip) {
|
||||
ASSERT(XFS_ISLOCKED_INODE_EXCL(ip));
|
||||
if (type == XFS_DQ_USER)
|
||||
@@ -1306,8 +1253,8 @@ xfs_qm_dqflush(
|
||||
return (error);
|
||||
}
|
||||
|
||||
if (xfs_qm_dqcheck(&dqp->q_core, INT_GET(ddqp->d_id, ARCH_CONVERT), 0, XFS_QMOPT_DOWARN,
|
||||
"dqflush (incore copy)")) {
|
||||
if (xfs_qm_dqcheck(&dqp->q_core, INT_GET(ddqp->d_id, ARCH_CONVERT),
|
||||
0, XFS_QMOPT_DOWARN, "dqflush (incore copy)")) {
|
||||
xfs_force_shutdown(dqp->q_mount, XFS_CORRUPT_INCORE);
|
||||
return XFS_ERROR(EIO);
|
||||
}
|
||||
@@ -1459,7 +1406,8 @@ xfs_dqlock2(
|
||||
{
|
||||
if (d1 && d2) {
|
||||
ASSERT(d1 != d2);
|
||||
if (INT_GET(d1->q_core.d_id, ARCH_CONVERT) > INT_GET(d2->q_core.d_id, ARCH_CONVERT)) {
|
||||
if (INT_GET(d1->q_core.d_id, ARCH_CONVERT) >
|
||||
INT_GET(d2->q_core.d_id, ARCH_CONVERT)) {
|
||||
xfs_dqlock(d2);
|
||||
xfs_dqlock(d1);
|
||||
} else {
|
||||
@@ -1582,8 +1530,7 @@ xfs_qm_dqprint(xfs_dquot_t *dqp)
|
||||
cmn_err(CE_DEBUG, "-----------KERNEL DQUOT----------------");
|
||||
cmn_err(CE_DEBUG, "---- dquotID = %d",
|
||||
(int)INT_GET(dqp->q_core.d_id, ARCH_CONVERT));
|
||||
cmn_err(CE_DEBUG, "---- type = %s",
|
||||
XFS_QM_ISUDQ(dqp) ? "USR" : "GRP");
|
||||
cmn_err(CE_DEBUG, "---- type = %s", DQFLAGTO_TYPESTR(dqp));
|
||||
cmn_err(CE_DEBUG, "---- fs = 0x%p", dqp->q_mount);
|
||||
cmn_err(CE_DEBUG, "---- blkno = 0x%x", (int) dqp->q_blkno);
|
||||
cmn_err(CE_DEBUG, "---- boffset = 0x%x", (int) dqp->q_bufoffset);
|
||||
|
||||
+12
-18
@@ -114,25 +114,18 @@ typedef struct xfs_dquot {
|
||||
#define XFS_DQHOLD(dqp) ((dqp)->q_nrefs++)
|
||||
|
||||
/*
|
||||
* Quota Accounting flags
|
||||
* Quota Accounting/Enforcement flags
|
||||
*/
|
||||
#define XFS_ALL_QUOTA_ACCT (XFS_UQUOTA_ACCT | XFS_GQUOTA_ACCT)
|
||||
#define XFS_ALL_QUOTA_ENFD (XFS_UQUOTA_ENFD | XFS_GQUOTA_ENFD)
|
||||
#define XFS_ALL_QUOTA_CHKD (XFS_UQUOTA_CHKD | XFS_GQUOTA_CHKD)
|
||||
#define XFS_ALL_QUOTA_ACTV (XFS_UQUOTA_ACTIVE | XFS_GQUOTA_ACTIVE)
|
||||
#define XFS_ALL_QUOTA_ACCT_ENFD (XFS_UQUOTA_ACCT|XFS_UQUOTA_ENFD|\
|
||||
XFS_GQUOTA_ACCT|XFS_GQUOTA_ENFD)
|
||||
#define XFS_ALL_QUOTA_ACCT \
|
||||
(XFS_UQUOTA_ACCT | XFS_GQUOTA_ACCT | XFS_PQUOTA_ACCT)
|
||||
#define XFS_ALL_QUOTA_ENFD (XFS_UQUOTA_ENFD | XFS_OQUOTA_ENFD)
|
||||
#define XFS_ALL_QUOTA_CHKD (XFS_UQUOTA_CHKD | XFS_OQUOTA_CHKD)
|
||||
|
||||
#define XFS_IS_QUOTA_RUNNING(mp) ((mp)->m_qflags & XFS_ALL_QUOTA_ACCT)
|
||||
#define XFS_IS_UQUOTA_RUNNING(mp) ((mp)->m_qflags & XFS_UQUOTA_ACCT)
|
||||
#define XFS_IS_GQUOTA_RUNNING(mp) ((mp)->m_qflags & XFS_GQUOTA_ACCT)
|
||||
|
||||
/*
|
||||
* Quota Limit Enforcement flags
|
||||
*/
|
||||
#define XFS_IS_QUOTA_RUNNING(mp) ((mp)->m_qflags & XFS_ALL_QUOTA_ACCT)
|
||||
#define XFS_IS_QUOTA_ENFORCED(mp) ((mp)->m_qflags & XFS_ALL_QUOTA_ENFD)
|
||||
#define XFS_IS_UQUOTA_ENFORCED(mp) ((mp)->m_qflags & XFS_UQUOTA_ENFD)
|
||||
#define XFS_IS_GQUOTA_ENFORCED(mp) ((mp)->m_qflags & XFS_GQUOTA_ENFD)
|
||||
#define XFS_IS_UQUOTA_RUNNING(mp) ((mp)->m_qflags & XFS_UQUOTA_ACCT)
|
||||
#define XFS_IS_PQUOTA_RUNNING(mp) ((mp)->m_qflags & XFS_PQUOTA_ACCT)
|
||||
#define XFS_IS_GQUOTA_RUNNING(mp) ((mp)->m_qflags & XFS_GQUOTA_ACCT)
|
||||
|
||||
#ifdef DEBUG
|
||||
static inline int
|
||||
@@ -167,6 +160,8 @@ XFS_DQ_IS_LOCKED(xfs_dquot_t *dqp)
|
||||
#define XFS_DQ_IS_ON_FREELIST(dqp) ((dqp)->dq_flnext != (dqp))
|
||||
#define XFS_DQ_IS_DIRTY(dqp) ((dqp)->dq_flags & XFS_DQ_DIRTY)
|
||||
#define XFS_QM_ISUDQ(dqp) ((dqp)->dq_flags & XFS_DQ_USER)
|
||||
#define XFS_QM_ISPDQ(dqp) ((dqp)->dq_flags & XFS_DQ_PROJ)
|
||||
#define XFS_QM_ISGDQ(dqp) ((dqp)->dq_flags & XFS_DQ_GROUP)
|
||||
#define XFS_DQ_TO_QINF(dqp) ((dqp)->q_mount->m_quotainfo)
|
||||
#define XFS_DQ_TO_QIP(dqp) (XFS_QM_ISUDQ(dqp) ? \
|
||||
XFS_DQ_TO_QINF(dqp)->qi_uquotaip : \
|
||||
@@ -174,7 +169,7 @@ XFS_DQ_IS_LOCKED(xfs_dquot_t *dqp)
|
||||
|
||||
#define XFS_IS_THIS_QUOTA_OFF(d) (! (XFS_QM_ISUDQ(d) ? \
|
||||
(XFS_IS_UQUOTA_ON((d)->q_mount)) : \
|
||||
(XFS_IS_GQUOTA_ON((d)->q_mount))))
|
||||
(XFS_IS_OQUOTA_ON((d)->q_mount))))
|
||||
|
||||
#ifdef XFS_DQUOT_TRACE
|
||||
/*
|
||||
@@ -211,7 +206,6 @@ extern void xfs_qm_adjust_dqtimers(xfs_mount_t *,
|
||||
xfs_disk_dquot_t *);
|
||||
extern void xfs_qm_adjust_dqlimits(xfs_mount_t *,
|
||||
xfs_disk_dquot_t *);
|
||||
extern int xfs_qm_dqwarn(xfs_disk_dquot_t *, uint);
|
||||
extern int xfs_qm_dqget(xfs_mount_t *, xfs_inode_t *,
|
||||
xfs_dqid_t, uint, uint, xfs_dquot_t **);
|
||||
extern void xfs_qm_dqput(xfs_dquot_t *);
|
||||
|
||||
@@ -428,7 +428,7 @@ xfs_qm_dquot_logitem_committing(
|
||||
/*
|
||||
* This is the ops vector for dquots
|
||||
*/
|
||||
struct xfs_item_ops xfs_dquot_item_ops = {
|
||||
STATIC struct xfs_item_ops xfs_dquot_item_ops = {
|
||||
.iop_size = (uint(*)(xfs_log_item_t*))xfs_qm_dquot_logitem_size,
|
||||
.iop_format = (void(*)(xfs_log_item_t*, xfs_log_iovec_t*))
|
||||
xfs_qm_dquot_logitem_format,
|
||||
@@ -646,7 +646,7 @@ xfs_qm_qoffend_logitem_committing(xfs_qoff_logitem_t *qip, xfs_lsn_t commit_lsn)
|
||||
return;
|
||||
}
|
||||
|
||||
struct xfs_item_ops xfs_qm_qoffend_logitem_ops = {
|
||||
STATIC struct xfs_item_ops xfs_qm_qoffend_logitem_ops = {
|
||||
.iop_size = (uint(*)(xfs_log_item_t*))xfs_qm_qoff_logitem_size,
|
||||
.iop_format = (void(*)(xfs_log_item_t*, xfs_log_iovec_t*))
|
||||
xfs_qm_qoff_logitem_format,
|
||||
@@ -669,7 +669,7 @@ struct xfs_item_ops xfs_qm_qoffend_logitem_ops = {
|
||||
/*
|
||||
* This is the ops vector shared by all quotaoff-start log items.
|
||||
*/
|
||||
struct xfs_item_ops xfs_qm_qoff_logitem_ops = {
|
||||
STATIC struct xfs_item_ops xfs_qm_qoff_logitem_ops = {
|
||||
.iop_size = (uint(*)(xfs_log_item_t*))xfs_qm_qoff_logitem_size,
|
||||
.iop_format = (void(*)(xfs_log_item_t*, xfs_log_iovec_t*))
|
||||
xfs_qm_qoff_logitem_format,
|
||||
|
||||
+130
-72
File diff suppressed because it is too large
Load Diff
+6
-10
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2000-2004 Silicon Graphics, Inc. All Rights Reserved.
|
||||
* Copyright (c) 2000-2005 Silicon Graphics, Inc. All Rights Reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of version 2 of the GNU General Public License as
|
||||
@@ -133,8 +133,9 @@ typedef struct xfs_quotainfo {
|
||||
time_t qi_btimelimit; /* limit for blks timer */
|
||||
time_t qi_itimelimit; /* limit for inodes timer */
|
||||
time_t qi_rtbtimelimit;/* limit for rt blks timer */
|
||||
xfs_qwarncnt_t qi_bwarnlimit; /* limit for num warnings */
|
||||
xfs_qwarncnt_t qi_iwarnlimit; /* limit for num warnings */
|
||||
xfs_qwarncnt_t qi_bwarnlimit; /* limit for blks warnings */
|
||||
xfs_qwarncnt_t qi_iwarnlimit; /* limit for inodes warnings */
|
||||
xfs_qwarncnt_t qi_rtbwarnlimit;/* limit for rt blks warnings */
|
||||
mutex_t qi_quotaofflock;/* to serialize quotaoff */
|
||||
xfs_filblks_t qi_dqchunklen; /* # BBs in a chunk of dqs */
|
||||
uint qi_dqperchunk; /* # ondisk dqs in above chunk */
|
||||
@@ -176,6 +177,7 @@ typedef struct xfs_dquot_acct {
|
||||
|
||||
#define XFS_QM_BWARNLIMIT 5
|
||||
#define XFS_QM_IWARNLIMIT 5
|
||||
#define XFS_QM_RTBWARNLIMIT 5
|
||||
|
||||
#define XFS_QM_LOCK(xqm) (mutex_lock(&xqm##_lock, PINOD))
|
||||
#define XFS_QM_UNLOCK(xqm) (mutex_unlock(&xqm##_lock))
|
||||
@@ -184,7 +186,6 @@ typedef struct xfs_dquot_acct {
|
||||
|
||||
extern void xfs_mount_reset_sbqflags(xfs_mount_t *);
|
||||
|
||||
extern int xfs_qm_init_quotainfo(xfs_mount_t *);
|
||||
extern void xfs_qm_destroy_quotainfo(xfs_mount_t *);
|
||||
extern int xfs_qm_mount_quotas(xfs_mount_t *, int);
|
||||
extern void xfs_qm_mount_quotainit(xfs_mount_t *, uint);
|
||||
@@ -203,7 +204,7 @@ extern void xfs_qm_dqrele_all_inodes(xfs_mount_t *, uint);
|
||||
|
||||
/* vop stuff */
|
||||
extern int xfs_qm_vop_dqalloc(xfs_mount_t *, xfs_inode_t *,
|
||||
uid_t, gid_t, uint,
|
||||
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 *,
|
||||
@@ -215,14 +216,9 @@ extern int xfs_qm_vop_chown_reserve(xfs_trans_t *, xfs_inode_t *,
|
||||
xfs_dquot_t *, xfs_dquot_t *, uint);
|
||||
|
||||
/* list stuff */
|
||||
extern void xfs_qm_freelist_init(xfs_frlist_t *);
|
||||
extern void xfs_qm_freelist_destroy(xfs_frlist_t *);
|
||||
extern void xfs_qm_freelist_insert(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 int xfs_qm_freelist_lock_nowait(xfs_qm_t *);
|
||||
extern int xfs_qm_mplist_nowait(xfs_mount_t *);
|
||||
extern int xfs_qm_dqhashlock_nowait(xfs_dquot_t *);
|
||||
|
||||
/* system call interface */
|
||||
extern int xfs_qm_quotactl(bhv_desc_t *, int, int, xfs_caddr_t);
|
||||
|
||||
@@ -71,10 +71,13 @@
|
||||
#define MNTOPT_NOQUOTA "noquota" /* no quotas */
|
||||
#define MNTOPT_USRQUOTA "usrquota" /* user quota enabled */
|
||||
#define MNTOPT_GRPQUOTA "grpquota" /* group quota enabled */
|
||||
#define MNTOPT_PRJQUOTA "prjquota" /* project quota enabled */
|
||||
#define MNTOPT_UQUOTA "uquota" /* user quota (IRIX variant) */
|
||||
#define MNTOPT_GQUOTA "gquota" /* group quota (IRIX variant) */
|
||||
#define MNTOPT_PQUOTA "pquota" /* project quota (IRIX variant) */
|
||||
#define MNTOPT_UQUOTANOENF "uqnoenforce"/* user quota limit enforcement */
|
||||
#define MNTOPT_GQUOTANOENF "gqnoenforce"/* group quota limit enforcement */
|
||||
#define MNTOPT_PQUOTANOENF "pqnoenforce"/* project quota limit enforcement */
|
||||
#define MNTOPT_QUOTANOENF "qnoenforce" /* same as uqnoenforce */
|
||||
|
||||
STATIC int
|
||||
@@ -109,6 +112,14 @@ xfs_qm_parseargs(
|
||||
args->flags |= XFSMNT_UQUOTA;
|
||||
args->flags &= ~XFSMNT_UQUOTAENF;
|
||||
referenced = 1;
|
||||
} else if (!strcmp(this_char, MNTOPT_PQUOTA) ||
|
||||
!strcmp(this_char, MNTOPT_PRJQUOTA)) {
|
||||
args->flags |= XFSMNT_PQUOTA | XFSMNT_PQUOTAENF;
|
||||
referenced = 1;
|
||||
} else if (!strcmp(this_char, MNTOPT_PQUOTANOENF)) {
|
||||
args->flags |= XFSMNT_PQUOTA;
|
||||
args->flags &= ~XFSMNT_PQUOTAENF;
|
||||
referenced = 1;
|
||||
} else if (!strcmp(this_char, MNTOPT_GQUOTA) ||
|
||||
!strcmp(this_char, MNTOPT_GRPQUOTA)) {
|
||||
args->flags |= XFSMNT_GQUOTA | XFSMNT_GQUOTAENF;
|
||||
@@ -127,6 +138,12 @@ xfs_qm_parseargs(
|
||||
*this_char++ = ',';
|
||||
}
|
||||
|
||||
if ((args->flags & XFSMNT_GQUOTA) && (args->flags & XFSMNT_PQUOTA)) {
|
||||
cmn_err(CE_WARN,
|
||||
"XFS: cannot mount with both project and group quota");
|
||||
return XFS_ERROR(EINVAL);
|
||||
}
|
||||
|
||||
PVFS_PARSEARGS(BHV_NEXT(bhv), options, args, update, error);
|
||||
if (!error && !referenced)
|
||||
bhv_remove_vfsops(bhvtovfs(bhv), VFS_POSITION_QM);
|
||||
@@ -148,13 +165,19 @@ xfs_qm_showargs(
|
||||
seq_puts(m, "," MNTOPT_UQUOTANOENF);
|
||||
}
|
||||
|
||||
if (mp->m_qflags & XFS_PQUOTA_ACCT) {
|
||||
(mp->m_qflags & XFS_OQUOTA_ENFD) ?
|
||||
seq_puts(m, "," MNTOPT_PRJQUOTA) :
|
||||
seq_puts(m, "," MNTOPT_PQUOTANOENF);
|
||||
}
|
||||
|
||||
if (mp->m_qflags & XFS_GQUOTA_ACCT) {
|
||||
(mp->m_qflags & XFS_GQUOTA_ENFD) ?
|
||||
(mp->m_qflags & XFS_OQUOTA_ENFD) ?
|
||||
seq_puts(m, "," MNTOPT_GRPQUOTA) :
|
||||
seq_puts(m, "," MNTOPT_GQUOTANOENF);
|
||||
}
|
||||
|
||||
if (!(mp->m_qflags & (XFS_UQUOTA_ACCT|XFS_GQUOTA_ACCT)))
|
||||
if (!(mp->m_qflags & XFS_ALL_QUOTA_ACCT))
|
||||
seq_puts(m, "," MNTOPT_NOQUOTA);
|
||||
|
||||
PVFS_SHOWARGS(BHV_NEXT(bhv), m, error);
|
||||
@@ -171,7 +194,7 @@ xfs_qm_mount(
|
||||
struct xfs_mount *mp = XFS_VFSTOM(vfsp);
|
||||
int error;
|
||||
|
||||
if (args->flags & (XFSMNT_UQUOTA | XFSMNT_GQUOTA))
|
||||
if (args->flags & (XFSMNT_UQUOTA | XFSMNT_GQUOTA | XFSMNT_PQUOTA))
|
||||
xfs_qm_mount_quotainit(mp, args->flags);
|
||||
PVFS_MOUNT(BHV_NEXT(bhv), args, cr, error);
|
||||
return error;
|
||||
@@ -255,16 +278,17 @@ xfs_qm_newmount(
|
||||
uint *quotaflags)
|
||||
{
|
||||
uint quotaondisk;
|
||||
uint uquotaondisk = 0, gquotaondisk = 0;
|
||||
uint uquotaondisk = 0, gquotaondisk = 0, pquotaondisk = 0;
|
||||
|
||||
*quotaflags = 0;
|
||||
*needquotamount = B_FALSE;
|
||||
|
||||
quotaondisk = XFS_SB_VERSION_HASQUOTA(&mp->m_sb) &&
|
||||
mp->m_sb.sb_qflags & (XFS_UQUOTA_ACCT|XFS_GQUOTA_ACCT);
|
||||
(mp->m_sb.sb_qflags & XFS_ALL_QUOTA_ACCT);
|
||||
|
||||
if (quotaondisk) {
|
||||
uquotaondisk = mp->m_sb.sb_qflags & XFS_UQUOTA_ACCT;
|
||||
pquotaondisk = mp->m_sb.sb_qflags & XFS_PQUOTA_ACCT;
|
||||
gquotaondisk = mp->m_sb.sb_qflags & XFS_GQUOTA_ACCT;
|
||||
}
|
||||
|
||||
@@ -277,13 +301,16 @@ xfs_qm_newmount(
|
||||
|
||||
if (((uquotaondisk && !XFS_IS_UQUOTA_ON(mp)) ||
|
||||
(!uquotaondisk && XFS_IS_UQUOTA_ON(mp)) ||
|
||||
(pquotaondisk && !XFS_IS_PQUOTA_ON(mp)) ||
|
||||
(!pquotaondisk && XFS_IS_PQUOTA_ON(mp)) ||
|
||||
(gquotaondisk && !XFS_IS_GQUOTA_ON(mp)) ||
|
||||
(!gquotaondisk && XFS_IS_GQUOTA_ON(mp))) &&
|
||||
(!gquotaondisk && XFS_IS_OQUOTA_ON(mp))) &&
|
||||
xfs_dev_is_read_only(mp, "changing quota state")) {
|
||||
cmn_err(CE_WARN,
|
||||
"XFS: please mount with%s%s%s.",
|
||||
"XFS: please mount with%s%s%s%s.",
|
||||
(!quotaondisk ? "out quota" : ""),
|
||||
(uquotaondisk ? " usrquota" : ""),
|
||||
(pquotaondisk ? " prjquota" : ""),
|
||||
(gquotaondisk ? " grpquota" : ""));
|
||||
return XFS_ERROR(EPERM);
|
||||
}
|
||||
@@ -359,7 +386,7 @@ xfs_qm_dqrele_null(
|
||||
}
|
||||
|
||||
|
||||
struct xfs_qmops xfs_qmcore_xfs = {
|
||||
STATIC struct xfs_qmops xfs_qmcore_xfs = {
|
||||
.xfs_qminit = xfs_qm_newmount,
|
||||
.xfs_qmdone = xfs_qm_unmount_quotadestroy,
|
||||
.xfs_qmmount = xfs_qm_endmount,
|
||||
|
||||
+113
-62
@@ -118,40 +118,41 @@ xfs_qm_quotactl(
|
||||
* The following commands are valid even when quotaoff.
|
||||
*/
|
||||
switch (cmd) {
|
||||
case Q_XQUOTARM:
|
||||
/*
|
||||
* truncate quota files. quota must be off.
|
||||
* Truncate quota files. quota must be off.
|
||||
*/
|
||||
case Q_XQUOTARM:
|
||||
if (XFS_IS_QUOTA_ON(mp) || addr == NULL)
|
||||
return XFS_ERROR(EINVAL);
|
||||
if (vfsp->vfs_flag & VFS_RDONLY)
|
||||
return XFS_ERROR(EROFS);
|
||||
return (xfs_qm_scall_trunc_qfiles(mp,
|
||||
xfs_qm_import_qtype_flags(*(uint *)addr)));
|
||||
|
||||
case Q_XGETQSTAT:
|
||||
/*
|
||||
* Get quota status information.
|
||||
*/
|
||||
case Q_XGETQSTAT:
|
||||
return (xfs_qm_scall_getqstat(mp, (fs_quota_stat_t *)addr));
|
||||
|
||||
case Q_XQUOTAON:
|
||||
/*
|
||||
* QUOTAON for root f/s and quota enforcement on others..
|
||||
* Quota accounting for non-root f/s's must be turned on
|
||||
* at mount time.
|
||||
* QUOTAON - enabling quota enforcement.
|
||||
* Quota accounting must be turned on at mount time.
|
||||
*/
|
||||
case Q_XQUOTAON:
|
||||
if (addr == NULL)
|
||||
return XFS_ERROR(EINVAL);
|
||||
if (vfsp->vfs_flag & VFS_RDONLY)
|
||||
return XFS_ERROR(EROFS);
|
||||
return (xfs_qm_scall_quotaon(mp,
|
||||
xfs_qm_import_flags(*(uint *)addr)));
|
||||
case Q_XQUOTAOFF:
|
||||
|
||||
case Q_XQUOTAOFF:
|
||||
if (vfsp->vfs_flag & VFS_RDONLY)
|
||||
return XFS_ERROR(EROFS);
|
||||
break;
|
||||
|
||||
default:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -159,7 +160,7 @@ xfs_qm_quotactl(
|
||||
return XFS_ERROR(ESRCH);
|
||||
|
||||
switch (cmd) {
|
||||
case Q_XQUOTAOFF:
|
||||
case Q_XQUOTAOFF:
|
||||
if (vfsp->vfs_flag & VFS_RDONLY)
|
||||
return XFS_ERROR(EROFS);
|
||||
error = xfs_qm_scall_quotaoff(mp,
|
||||
@@ -167,42 +168,39 @@ xfs_qm_quotactl(
|
||||
B_FALSE);
|
||||
break;
|
||||
|
||||
/*
|
||||
* Defaults to XFS_GETUQUOTA.
|
||||
*/
|
||||
case Q_XGETQUOTA:
|
||||
case Q_XGETQUOTA:
|
||||
error = xfs_qm_scall_getquota(mp, (xfs_dqid_t)id, XFS_DQ_USER,
|
||||
(fs_disk_quota_t *)addr);
|
||||
break;
|
||||
/*
|
||||
* Set limits, both hard and soft. Defaults to Q_SETUQLIM.
|
||||
*/
|
||||
case Q_XSETQLIM:
|
||||
case Q_XGETGQUOTA:
|
||||
error = xfs_qm_scall_getquota(mp, (xfs_dqid_t)id, XFS_DQ_GROUP,
|
||||
(fs_disk_quota_t *)addr);
|
||||
break;
|
||||
case Q_XGETPQUOTA:
|
||||
error = xfs_qm_scall_getquota(mp, (xfs_dqid_t)id, XFS_DQ_PROJ,
|
||||
(fs_disk_quota_t *)addr);
|
||||
break;
|
||||
|
||||
case Q_XSETQLIM:
|
||||
if (vfsp->vfs_flag & VFS_RDONLY)
|
||||
return XFS_ERROR(EROFS);
|
||||
error = xfs_qm_scall_setqlim(mp, (xfs_dqid_t)id, XFS_DQ_USER,
|
||||
(fs_disk_quota_t *)addr);
|
||||
break;
|
||||
|
||||
case Q_XSETGQLIM:
|
||||
case Q_XSETGQLIM:
|
||||
if (vfsp->vfs_flag & VFS_RDONLY)
|
||||
return XFS_ERROR(EROFS);
|
||||
error = xfs_qm_scall_setqlim(mp, (xfs_dqid_t)id, XFS_DQ_GROUP,
|
||||
(fs_disk_quota_t *)addr);
|
||||
break;
|
||||
|
||||
|
||||
case Q_XGETGQUOTA:
|
||||
error = xfs_qm_scall_getquota(mp, (xfs_dqid_t)id, XFS_DQ_GROUP,
|
||||
(fs_disk_quota_t *)addr);
|
||||
case Q_XSETPQLIM:
|
||||
if (vfsp->vfs_flag & VFS_RDONLY)
|
||||
return XFS_ERROR(EROFS);
|
||||
error = xfs_qm_scall_setqlim(mp, (xfs_dqid_t)id, XFS_DQ_PROJ,
|
||||
(fs_disk_quota_t *)addr);
|
||||
break;
|
||||
|
||||
/*
|
||||
* Quotas are entirely undefined after quotaoff in XFS quotas.
|
||||
* For instance, there's no way to set limits when quotaoff.
|
||||
*/
|
||||
|
||||
default:
|
||||
default:
|
||||
error = XFS_ERROR(EINVAL);
|
||||
break;
|
||||
}
|
||||
@@ -286,8 +284,12 @@ xfs_qm_scall_quotaoff(
|
||||
}
|
||||
if (flags & XFS_GQUOTA_ACCT) {
|
||||
dqtype |= XFS_QMOPT_GQUOTA;
|
||||
flags |= (XFS_GQUOTA_CHKD | XFS_GQUOTA_ENFD);
|
||||
flags |= (XFS_OQUOTA_CHKD | XFS_OQUOTA_ENFD);
|
||||
inactivate_flags |= XFS_GQUOTA_ACTIVE;
|
||||
} else if (flags & XFS_PQUOTA_ACCT) {
|
||||
dqtype |= XFS_QMOPT_PQUOTA;
|
||||
flags |= (XFS_OQUOTA_CHKD | XFS_OQUOTA_ENFD);
|
||||
inactivate_flags |= XFS_PQUOTA_ACTIVE;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -364,7 +366,8 @@ xfs_qm_scall_quotaoff(
|
||||
/*
|
||||
* If quotas is completely disabled, close shop.
|
||||
*/
|
||||
if ((flags & XFS_MOUNT_QUOTA_ALL) == XFS_MOUNT_QUOTA_ALL) {
|
||||
if (((flags & XFS_MOUNT_QUOTA_ALL) == XFS_MOUNT_QUOTA_SET1) ||
|
||||
((flags & XFS_MOUNT_QUOTA_ALL) == XFS_MOUNT_QUOTA_SET2)) {
|
||||
mutex_unlock(&(XFS_QI_QOFFLOCK(mp)));
|
||||
xfs_qm_destroy_quotainfo(mp);
|
||||
return (0);
|
||||
@@ -378,7 +381,7 @@ xfs_qm_scall_quotaoff(
|
||||
XFS_PURGE_INODE(XFS_QI_UQIP(mp));
|
||||
XFS_QI_UQIP(mp) = NULL;
|
||||
}
|
||||
if ((dqtype & XFS_QMOPT_GQUOTA) && XFS_QI_GQIP(mp)) {
|
||||
if ((dqtype & (XFS_QMOPT_GQUOTA|XFS_QMOPT_PQUOTA)) && XFS_QI_GQIP(mp)) {
|
||||
XFS_PURGE_INODE(XFS_QI_GQIP(mp));
|
||||
XFS_QI_GQIP(mp) = NULL;
|
||||
}
|
||||
@@ -411,7 +414,8 @@ xfs_qm_scall_trunc_qfiles(
|
||||
}
|
||||
}
|
||||
|
||||
if ((flags & XFS_DQ_GROUP) && mp->m_sb.sb_gquotino != NULLFSINO) {
|
||||
if ((flags & (XFS_DQ_GROUP|XFS_DQ_PROJ)) &&
|
||||
mp->m_sb.sb_gquotino != NULLFSINO) {
|
||||
error = xfs_iget(mp, NULL, mp->m_sb.sb_gquotino, 0, 0, &qip, 0);
|
||||
if (! error) {
|
||||
(void) xfs_truncate_file(mp, qip);
|
||||
@@ -434,7 +438,7 @@ xfs_qm_scall_quotaon(
|
||||
uint flags)
|
||||
{
|
||||
int error;
|
||||
unsigned long s;
|
||||
unsigned long s;
|
||||
uint qf;
|
||||
uint accflags;
|
||||
__int64_t sbflags;
|
||||
@@ -468,9 +472,13 @@ xfs_qm_scall_quotaon(
|
||||
(mp->m_sb.sb_qflags & XFS_UQUOTA_ACCT) == 0 &&
|
||||
(flags & XFS_UQUOTA_ENFD))
|
||||
||
|
||||
((flags & XFS_PQUOTA_ACCT) == 0 &&
|
||||
(mp->m_sb.sb_qflags & XFS_PQUOTA_ACCT) == 0 &&
|
||||
(flags & XFS_OQUOTA_ENFD))
|
||||
||
|
||||
((flags & XFS_GQUOTA_ACCT) == 0 &&
|
||||
(mp->m_sb.sb_qflags & XFS_GQUOTA_ACCT) == 0 &&
|
||||
(flags & XFS_GQUOTA_ENFD))) {
|
||||
(flags & XFS_OQUOTA_ENFD))) {
|
||||
qdprintk("Can't enforce without acct, flags=%x sbflags=%x\n",
|
||||
flags, mp->m_sb.sb_qflags);
|
||||
return XFS_ERROR(EINVAL);
|
||||
@@ -504,6 +512,10 @@ xfs_qm_scall_quotaon(
|
||||
*/
|
||||
if (((mp->m_sb.sb_qflags & XFS_UQUOTA_ACCT) !=
|
||||
(mp->m_qflags & XFS_UQUOTA_ACCT)) ||
|
||||
((mp->m_sb.sb_qflags & XFS_PQUOTA_ACCT) !=
|
||||
(mp->m_qflags & XFS_PQUOTA_ACCT)) ||
|
||||
((mp->m_sb.sb_qflags & XFS_GQUOTA_ACCT) !=
|
||||
(mp->m_qflags & XFS_GQUOTA_ACCT)) ||
|
||||
(flags & XFS_ALL_QUOTA_ENFD) == 0)
|
||||
return (0);
|
||||
|
||||
@@ -521,7 +533,6 @@ xfs_qm_scall_quotaon(
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Return quota status information, such as uquota-off, enforcements, etc.
|
||||
*/
|
||||
@@ -606,7 +617,8 @@ xfs_qm_scall_setqlim(
|
||||
if (!capable(CAP_SYS_ADMIN))
|
||||
return XFS_ERROR(EPERM);
|
||||
|
||||
if ((newlim->d_fieldmask & (FS_DQ_LIMIT_MASK|FS_DQ_TIMER_MASK)) == 0)
|
||||
if ((newlim->d_fieldmask &
|
||||
(FS_DQ_LIMIT_MASK|FS_DQ_TIMER_MASK|FS_DQ_WARNS_MASK)) == 0)
|
||||
return (0);
|
||||
|
||||
tp = xfs_trans_alloc(mp, XFS_TRANS_QM_SETQLIM);
|
||||
@@ -691,12 +703,23 @@ xfs_qm_scall_setqlim(
|
||||
qdprintk("ihard %Ld < isoft %Ld\n", hard, soft);
|
||||
}
|
||||
|
||||
/*
|
||||
* Update warnings counter(s) if requested
|
||||
*/
|
||||
if (newlim->d_fieldmask & FS_DQ_BWARNS)
|
||||
INT_SET(ddq->d_bwarns, ARCH_CONVERT, newlim->d_bwarns);
|
||||
if (newlim->d_fieldmask & FS_DQ_IWARNS)
|
||||
INT_SET(ddq->d_iwarns, ARCH_CONVERT, newlim->d_iwarns);
|
||||
if (newlim->d_fieldmask & FS_DQ_RTBWARNS)
|
||||
INT_SET(ddq->d_rtbwarns, ARCH_CONVERT, newlim->d_rtbwarns);
|
||||
|
||||
if (id == 0) {
|
||||
/*
|
||||
* Timelimits for the super user set the relative time
|
||||
* the other users can be over quota for this file system.
|
||||
* If it is zero a default is used. Ditto for the default
|
||||
* soft and hard limit values (already done, above).
|
||||
* soft and hard limit values (already done, above), and
|
||||
* for warnings.
|
||||
*/
|
||||
if (newlim->d_fieldmask & FS_DQ_BTIMER) {
|
||||
mp->m_quotainfo->qi_btimelimit = newlim->d_btimer;
|
||||
@@ -710,7 +733,13 @@ xfs_qm_scall_setqlim(
|
||||
mp->m_quotainfo->qi_rtbtimelimit = newlim->d_rtbtimer;
|
||||
INT_SET(ddq->d_rtbtimer, ARCH_CONVERT, newlim->d_rtbtimer);
|
||||
}
|
||||
} else /* if (XFS_IS_QUOTA_ENFORCED(mp)) */ {
|
||||
if (newlim->d_fieldmask & FS_DQ_BWARNS)
|
||||
mp->m_quotainfo->qi_bwarnlimit = newlim->d_bwarns;
|
||||
if (newlim->d_fieldmask & FS_DQ_IWARNS)
|
||||
mp->m_quotainfo->qi_iwarnlimit = newlim->d_iwarns;
|
||||
if (newlim->d_fieldmask & FS_DQ_RTBWARNS)
|
||||
mp->m_quotainfo->qi_rtbwarnlimit = newlim->d_rtbwarns;
|
||||
} else {
|
||||
/*
|
||||
* If the user is now over quota, start the timelimit.
|
||||
* The user will not be 'warned'.
|
||||
@@ -776,9 +805,9 @@ xfs_qm_log_quotaoff_end(
|
||||
xfs_qoff_logitem_t *startqoff,
|
||||
uint flags)
|
||||
{
|
||||
xfs_trans_t *tp;
|
||||
xfs_trans_t *tp;
|
||||
int error;
|
||||
xfs_qoff_logitem_t *qoffi;
|
||||
xfs_qoff_logitem_t *qoffi;
|
||||
|
||||
tp = xfs_trans_alloc(mp, XFS_TRANS_QM_QUOTAOFF_END);
|
||||
|
||||
@@ -928,18 +957,26 @@ xfs_qm_export_dquot(
|
||||
|
||||
STATIC uint
|
||||
xfs_qm_import_qtype_flags(
|
||||
uint uflags)
|
||||
uint uflags)
|
||||
{
|
||||
uint oflags = 0;
|
||||
|
||||
/*
|
||||
* Can't be both at the same time.
|
||||
* Can't be more than one, or none.
|
||||
*/
|
||||
if (((uflags & (XFS_GROUP_QUOTA | XFS_USER_QUOTA)) ==
|
||||
(XFS_GROUP_QUOTA | XFS_USER_QUOTA)) ||
|
||||
((uflags & (XFS_GROUP_QUOTA | XFS_USER_QUOTA)) == 0))
|
||||
(XFS_GROUP_QUOTA | XFS_USER_QUOTA)) ||
|
||||
((uflags & (XFS_GROUP_QUOTA | XFS_PROJ_QUOTA)) ==
|
||||
(XFS_GROUP_QUOTA | XFS_PROJ_QUOTA)) ||
|
||||
((uflags & (XFS_USER_QUOTA | XFS_PROJ_QUOTA)) ==
|
||||
(XFS_USER_QUOTA | XFS_PROJ_QUOTA)) ||
|
||||
((uflags & (XFS_GROUP_QUOTA|XFS_USER_QUOTA|XFS_PROJ_QUOTA)) == 0))
|
||||
return (0);
|
||||
|
||||
return (uflags & XFS_USER_QUOTA) ?
|
||||
XFS_DQ_USER : XFS_DQ_GROUP;
|
||||
oflags |= (uflags & XFS_USER_QUOTA) ? XFS_DQ_USER : 0;
|
||||
oflags |= (uflags & XFS_PROJ_QUOTA) ? XFS_DQ_PROJ : 0;
|
||||
oflags |= (uflags & XFS_GROUP_QUOTA) ? XFS_DQ_GROUP: 0;
|
||||
return oflags;
|
||||
}
|
||||
|
||||
STATIC uint
|
||||
@@ -947,14 +984,19 @@ xfs_qm_export_qtype_flags(
|
||||
uint flags)
|
||||
{
|
||||
/*
|
||||
* Can't be both at the same time.
|
||||
* Can't be more than one, or none.
|
||||
*/
|
||||
ASSERT((flags & (XFS_GROUP_QUOTA | XFS_USER_QUOTA)) !=
|
||||
(XFS_GROUP_QUOTA | XFS_USER_QUOTA));
|
||||
ASSERT((flags & (XFS_GROUP_QUOTA | XFS_USER_QUOTA)) != 0);
|
||||
ASSERT((flags & (XFS_PROJ_QUOTA | XFS_USER_QUOTA)) !=
|
||||
(XFS_PROJ_QUOTA | XFS_USER_QUOTA));
|
||||
ASSERT((flags & (XFS_PROJ_QUOTA | XFS_GROUP_QUOTA)) !=
|
||||
(XFS_PROJ_QUOTA | XFS_GROUP_QUOTA));
|
||||
ASSERT((flags & (XFS_USER_QUOTA | XFS_GROUP_QUOTA)) !=
|
||||
(XFS_USER_QUOTA | XFS_GROUP_QUOTA));
|
||||
ASSERT((flags & (XFS_PROJ_QUOTA|XFS_USER_QUOTA|XFS_GROUP_QUOTA)) != 0);
|
||||
|
||||
return (flags & XFS_DQ_USER) ?
|
||||
XFS_USER_QUOTA : XFS_GROUP_QUOTA;
|
||||
XFS_USER_QUOTA : (flags & XFS_DQ_PROJ) ?
|
||||
XFS_PROJ_QUOTA : XFS_GROUP_QUOTA;
|
||||
}
|
||||
|
||||
STATIC uint
|
||||
@@ -965,12 +1007,14 @@ xfs_qm_import_flags(
|
||||
|
||||
if (uflags & XFS_QUOTA_UDQ_ACCT)
|
||||
flags |= XFS_UQUOTA_ACCT;
|
||||
if (uflags & XFS_QUOTA_PDQ_ACCT)
|
||||
flags |= XFS_PQUOTA_ACCT;
|
||||
if (uflags & XFS_QUOTA_GDQ_ACCT)
|
||||
flags |= XFS_GQUOTA_ACCT;
|
||||
if (uflags & XFS_QUOTA_UDQ_ENFD)
|
||||
flags |= XFS_UQUOTA_ENFD;
|
||||
if (uflags & XFS_QUOTA_GDQ_ENFD)
|
||||
flags |= XFS_GQUOTA_ENFD;
|
||||
if (uflags & (XFS_QUOTA_PDQ_ENFD|XFS_QUOTA_GDQ_ENFD))
|
||||
flags |= XFS_OQUOTA_ENFD;
|
||||
return (flags);
|
||||
}
|
||||
|
||||
@@ -984,12 +1028,16 @@ xfs_qm_export_flags(
|
||||
uflags = 0;
|
||||
if (flags & XFS_UQUOTA_ACCT)
|
||||
uflags |= XFS_QUOTA_UDQ_ACCT;
|
||||
if (flags & XFS_PQUOTA_ACCT)
|
||||
uflags |= XFS_QUOTA_PDQ_ACCT;
|
||||
if (flags & XFS_GQUOTA_ACCT)
|
||||
uflags |= XFS_QUOTA_GDQ_ACCT;
|
||||
if (flags & XFS_UQUOTA_ENFD)
|
||||
uflags |= XFS_QUOTA_UDQ_ENFD;
|
||||
if (flags & XFS_GQUOTA_ENFD)
|
||||
uflags |= XFS_QUOTA_GDQ_ENFD;
|
||||
if (flags & (XFS_OQUOTA_ENFD)) {
|
||||
uflags |= (flags & XFS_GQUOTA_ACCT) ?
|
||||
XFS_QUOTA_GDQ_ENFD : XFS_QUOTA_PDQ_ENFD;
|
||||
}
|
||||
return (uflags);
|
||||
}
|
||||
|
||||
@@ -1070,7 +1118,7 @@ again:
|
||||
xfs_qm_dqrele(ip->i_udquot);
|
||||
ip->i_udquot = NULL;
|
||||
}
|
||||
if ((flags & XFS_GQUOTA_ACCT) && ip->i_gdquot) {
|
||||
if (flags & (XFS_PQUOTA_ACCT|XFS_GQUOTA_ACCT) && ip->i_gdquot) {
|
||||
xfs_qm_dqrele(ip->i_gdquot);
|
||||
ip->i_gdquot = NULL;
|
||||
}
|
||||
@@ -1160,7 +1208,6 @@ xfs_qm_dqtest_print(
|
||||
{
|
||||
cmn_err(CE_DEBUG, "-----------DQTEST DQUOT----------------");
|
||||
cmn_err(CE_DEBUG, "---- dquot ID = %d", d->d_id);
|
||||
cmn_err(CE_DEBUG, "---- type = %s", XFS_QM_ISUDQ(d)? "USR" : "GRP");
|
||||
cmn_err(CE_DEBUG, "---- fs = 0x%p", d->q_mount);
|
||||
cmn_err(CE_DEBUG, "---- bcount = %Lu (0x%x)",
|
||||
d->d_bcount, (int)d->d_bcount);
|
||||
@@ -1231,7 +1278,7 @@ xfs_dqtest_cmp2(
|
||||
#ifdef QUOTADEBUG
|
||||
if (!err) {
|
||||
cmn_err(CE_DEBUG, "%d [%s] [0x%p] qchecked",
|
||||
d->d_id, XFS_QM_ISUDQ(d) ? "USR" : "GRP", d->q_mount);
|
||||
d->d_id, DQFLAGTO_TYPESTR(d), d->q_mount);
|
||||
}
|
||||
#endif
|
||||
return (err);
|
||||
@@ -1287,6 +1334,7 @@ STATIC void
|
||||
xfs_qm_internalqcheck_get_dquots(
|
||||
xfs_mount_t *mp,
|
||||
xfs_dqid_t uid,
|
||||
xfs_dqid_t projid,
|
||||
xfs_dqid_t gid,
|
||||
xfs_dqtest_t **ud,
|
||||
xfs_dqtest_t **gd)
|
||||
@@ -1295,6 +1343,8 @@ xfs_qm_internalqcheck_get_dquots(
|
||||
xfs_qm_internalqcheck_dqget(mp, uid, XFS_DQ_USER, ud);
|
||||
if (XFS_IS_GQUOTA_ON(mp))
|
||||
xfs_qm_internalqcheck_dqget(mp, gid, XFS_DQ_GROUP, gd);
|
||||
else if (XFS_IS_PQUOTA_ON(mp))
|
||||
xfs_qm_internalqcheck_dqget(mp, projid, XFS_DQ_PROJ, gd);
|
||||
}
|
||||
|
||||
|
||||
@@ -1362,13 +1412,14 @@ xfs_qm_internalqcheck_adjust(
|
||||
}
|
||||
xfs_qm_internalqcheck_get_dquots(mp,
|
||||
(xfs_dqid_t) ip->i_d.di_uid,
|
||||
(xfs_dqid_t) ip->i_d.di_projid,
|
||||
(xfs_dqid_t) ip->i_d.di_gid,
|
||||
&ud, &gd);
|
||||
if (XFS_IS_UQUOTA_ON(mp)) {
|
||||
ASSERT(ud);
|
||||
xfs_qm_internalqcheck_dqadjust(ip, ud);
|
||||
}
|
||||
if (XFS_IS_GQUOTA_ON(mp)) {
|
||||
if (XFS_IS_OQUOTA_ON(mp)) {
|
||||
ASSERT(gd);
|
||||
xfs_qm_internalqcheck_dqadjust(ip, gd);
|
||||
}
|
||||
|
||||
@@ -56,6 +56,7 @@
|
||||
#define XFS_QI_RTBTIMELIMIT(mp) ((mp)->m_quotainfo->qi_rtbtimelimit)
|
||||
#define XFS_QI_ITIMELIMIT(mp) ((mp)->m_quotainfo->qi_itimelimit)
|
||||
#define XFS_QI_BWARNLIMIT(mp) ((mp)->m_quotainfo->qi_bwarnlimit)
|
||||
#define XFS_QI_RTBWARNLIMIT(mp) ((mp)->m_quotainfo->qi_rtbwarnlimit)
|
||||
#define XFS_QI_IWARNLIMIT(mp) ((mp)->m_quotainfo->qi_iwarnlimit)
|
||||
#define XFS_QI_QOFFLOCK(mp) ((mp)->m_quotainfo->qi_quotaofflock)
|
||||
|
||||
@@ -102,7 +103,8 @@ static inline int XQMISLCKD(struct xfs_dqhash *h)
|
||||
(xfs_Gqm->qm_grp_dqhtable + \
|
||||
XFS_DQ_HASHVAL(mp, id)))
|
||||
#define XFS_IS_DQTYPE_ON(mp, type) (type == XFS_DQ_USER ? \
|
||||
XFS_IS_UQUOTA_ON(mp):XFS_IS_GQUOTA_ON(mp))
|
||||
XFS_IS_UQUOTA_ON(mp) : \
|
||||
XFS_IS_OQUOTA_ON(mp))
|
||||
#define XFS_IS_DQUOT_UNINITIALIZED(dqp) ( \
|
||||
!dqp->q_core.d_blk_hardlimit && \
|
||||
!dqp->q_core.d_blk_softlimit && \
|
||||
@@ -177,16 +179,11 @@ for ((dqp) = (qlist)->qh_next; (dqp) != (xfs_dquot_t *)(qlist); \
|
||||
(!((dqp)->q_core.d_id))
|
||||
|
||||
#define XFS_PURGE_INODE(ip) \
|
||||
{ \
|
||||
vmap_t dqvmap; \
|
||||
vnode_t *dqvp; \
|
||||
dqvp = XFS_ITOV(ip); \
|
||||
VMAP(dqvp, dqvmap); \
|
||||
VN_RELE(dqvp); \
|
||||
}
|
||||
IRELE(ip);
|
||||
|
||||
#define DQFLAGTO_TYPESTR(d) (((d)->dq_flags & XFS_DQ_USER) ? "USR" : \
|
||||
(((d)->dq_flags & XFS_DQ_GROUP) ? "GRP" : "???"))
|
||||
(((d)->dq_flags & XFS_DQ_GROUP) ? "GRP" : \
|
||||
(((d)->dq_flags & XFS_DQ_PROJ) ? "PRJ":"???")))
|
||||
#define DQFLAGTO_DIRTYSTR(d) (XFS_DQ_IS_DIRTY(d) ? "DIRTY" : "NOTDIRTY")
|
||||
|
||||
#endif /* __XFS_QUOTA_PRIV_H__ */
|
||||
|
||||
@@ -187,7 +187,7 @@ xfs_trans_dup_dqinfo(
|
||||
/*
|
||||
* Wrap around mod_dquot to account for both user and group quotas.
|
||||
*/
|
||||
void
|
||||
STATIC void
|
||||
xfs_trans_mod_dquot_byino(
|
||||
xfs_trans_t *tp,
|
||||
xfs_inode_t *ip,
|
||||
@@ -207,12 +207,10 @@ xfs_trans_mod_dquot_byino(
|
||||
if (tp->t_dqinfo == NULL)
|
||||
xfs_trans_alloc_dqinfo(tp);
|
||||
|
||||
if (XFS_IS_UQUOTA_ON(mp) && ip->i_udquot) {
|
||||
if (XFS_IS_UQUOTA_ON(mp) && ip->i_udquot)
|
||||
(void) xfs_trans_mod_dquot(tp, ip->i_udquot, field, delta);
|
||||
}
|
||||
if (XFS_IS_GQUOTA_ON(mp) && ip->i_gdquot) {
|
||||
if (XFS_IS_OQUOTA_ON(mp) && ip->i_gdquot)
|
||||
(void) xfs_trans_mod_dquot(tp, ip->i_gdquot, field, delta);
|
||||
}
|
||||
}
|
||||
|
||||
STATIC xfs_dqtrx_t *
|
||||
@@ -368,7 +366,7 @@ xfs_trans_dqlockedjoin(
|
||||
* Unreserve just the reservations done by this transaction.
|
||||
* dquot is still left locked at exit.
|
||||
*/
|
||||
void
|
||||
STATIC void
|
||||
xfs_trans_apply_dquot_deltas(
|
||||
xfs_trans_t *tp)
|
||||
{
|
||||
@@ -499,7 +497,7 @@ xfs_trans_apply_dquot_deltas(
|
||||
* Adjust the RT reservation.
|
||||
*/
|
||||
if (qtrx->qt_rtblk_res != 0) {
|
||||
if (qtrx->qt_blk_res != qtrx->qt_blk_res_used) {
|
||||
if (qtrx->qt_rtblk_res != qtrx->qt_rtblk_res_used) {
|
||||
if (qtrx->qt_rtblk_res >
|
||||
qtrx->qt_rtblk_res_used)
|
||||
dqp->q_res_rtbcount -= (xfs_qcnt_t)
|
||||
@@ -532,12 +530,6 @@ xfs_trans_apply_dquot_deltas(
|
||||
(xfs_qcnt_t)qtrx->qt_icount_delta;
|
||||
}
|
||||
|
||||
|
||||
#ifdef QUOTADEBUG
|
||||
if (qtrx->qt_rtblk_res != 0)
|
||||
cmn_err(CE_DEBUG, "RT res %d for 0x%p\n",
|
||||
(int) qtrx->qt_rtblk_res, dqp);
|
||||
#endif
|
||||
ASSERT(dqp->q_res_bcount >=
|
||||
INT_GET(dqp->q_core.d_bcount, ARCH_CONVERT));
|
||||
ASSERT(dqp->q_res_icount >=
|
||||
@@ -638,7 +630,10 @@ xfs_trans_dqresv(
|
||||
int error;
|
||||
xfs_qcnt_t hardlimit;
|
||||
xfs_qcnt_t softlimit;
|
||||
time_t btimer;
|
||||
time_t timer;
|
||||
xfs_qwarncnt_t warns;
|
||||
xfs_qwarncnt_t warnlimit;
|
||||
xfs_qcnt_t count;
|
||||
xfs_qcnt_t *resbcountp;
|
||||
xfs_quotainfo_t *q = mp->m_quotainfo;
|
||||
|
||||
@@ -653,7 +648,9 @@ xfs_trans_dqresv(
|
||||
softlimit = INT_GET(dqp->q_core.d_blk_softlimit, ARCH_CONVERT);
|
||||
if (!softlimit)
|
||||
softlimit = q->qi_bsoftlimit;
|
||||
btimer = INT_GET(dqp->q_core.d_btimer, ARCH_CONVERT);
|
||||
timer = INT_GET(dqp->q_core.d_btimer, ARCH_CONVERT);
|
||||
warns = INT_GET(dqp->q_core.d_bwarns, ARCH_CONVERT);
|
||||
warnlimit = XFS_QI_BWARNLIMIT(dqp->q_mount);
|
||||
resbcountp = &dqp->q_res_bcount;
|
||||
} else {
|
||||
ASSERT(flags & XFS_TRANS_DQ_RES_RTBLKS);
|
||||
@@ -663,7 +660,9 @@ xfs_trans_dqresv(
|
||||
softlimit = INT_GET(dqp->q_core.d_rtb_softlimit, ARCH_CONVERT);
|
||||
if (!softlimit)
|
||||
softlimit = q->qi_rtbsoftlimit;
|
||||
btimer = INT_GET(dqp->q_core.d_rtbtimer, ARCH_CONVERT);
|
||||
timer = INT_GET(dqp->q_core.d_rtbtimer, ARCH_CONVERT);
|
||||
warns = INT_GET(dqp->q_core.d_rtbwarns, ARCH_CONVERT);
|
||||
warnlimit = XFS_QI_RTBWARNLIMIT(dqp->q_mount);
|
||||
resbcountp = &dqp->q_res_rtbcount;
|
||||
}
|
||||
error = 0;
|
||||
@@ -693,37 +692,36 @@ xfs_trans_dqresv(
|
||||
* If timer or warnings has expired,
|
||||
* return EDQUOT
|
||||
*/
|
||||
if ((btimer != 0 && get_seconds() > btimer) ||
|
||||
(dqp->q_core.d_bwarns &&
|
||||
INT_GET(dqp->q_core.d_bwarns, ARCH_CONVERT) >=
|
||||
XFS_QI_BWARNLIMIT(dqp->q_mount))) {
|
||||
if ((timer != 0 && get_seconds() > timer) ||
|
||||
(warns != 0 && warns >= warnlimit)) {
|
||||
error = EDQUOT;
|
||||
goto error_return;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (ninos > 0) {
|
||||
hardlimit = INT_GET(dqp->q_core.d_ino_hardlimit, ARCH_CONVERT);
|
||||
count = INT_GET(dqp->q_core.d_icount, ARCH_CONVERT);
|
||||
timer = INT_GET(dqp->q_core.d_itimer, ARCH_CONVERT);
|
||||
warns = INT_GET(dqp->q_core.d_iwarns, ARCH_CONVERT);
|
||||
warnlimit = XFS_QI_IWARNLIMIT(dqp->q_mount);
|
||||
hardlimit = INT_GET(dqp->q_core.d_ino_hardlimit,
|
||||
ARCH_CONVERT);
|
||||
if (!hardlimit)
|
||||
hardlimit = q->qi_ihardlimit;
|
||||
softlimit = INT_GET(dqp->q_core.d_ino_softlimit, ARCH_CONVERT);
|
||||
softlimit = INT_GET(dqp->q_core.d_ino_softlimit,
|
||||
ARCH_CONVERT);
|
||||
if (!softlimit)
|
||||
softlimit = q->qi_isoftlimit;
|
||||
if (hardlimit > 0ULL &&
|
||||
INT_GET(dqp->q_core.d_icount, ARCH_CONVERT) >= hardlimit) {
|
||||
if (hardlimit > 0ULL && count >= hardlimit) {
|
||||
error = EDQUOT;
|
||||
goto error_return;
|
||||
} else if (softlimit > 0ULL &&
|
||||
INT_GET(dqp->q_core.d_icount, ARCH_CONVERT) >= softlimit) {
|
||||
} else if (softlimit > 0ULL && count >= softlimit) {
|
||||
/*
|
||||
* If timer or warnings has expired,
|
||||
* return EDQUOT
|
||||
*/
|
||||
if ((dqp->q_core.d_itimer &&
|
||||
get_seconds() > INT_GET(dqp->q_core.d_itimer, ARCH_CONVERT)) ||
|
||||
(dqp->q_core.d_iwarns &&
|
||||
INT_GET(dqp->q_core.d_iwarns, ARCH_CONVERT) >=
|
||||
XFS_QI_IWARNLIMIT(dqp->q_mount))) {
|
||||
if ((timer != 0 && get_seconds() > timer) ||
|
||||
(warns != 0 && warns >= warnlimit)) {
|
||||
error = EDQUOT;
|
||||
goto error_return;
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user