aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/xfs/linux-2.6/xfs_buf.c153
-rw-r--r--fs/xfs/linux-2.6/xfs_buf.h1
-rw-r--r--fs/xfs/linux-2.6/xfs_file.c27
-rw-r--r--fs/xfs/linux-2.6/xfs_ioctl.c11
-rw-r--r--fs/xfs/linux-2.6/xfs_linux.h6
-rw-r--r--fs/xfs/linux-2.6/xfs_lrw.c34
-rw-r--r--fs/xfs/linux-2.6/xfs_lrw.h2
-rw-r--r--fs/xfs/linux-2.6/xfs_super.c12
-rw-r--r--fs/xfs/linux-2.6/xfs_vfs.h1
-rw-r--r--fs/xfs/linux-2.6/xfs_vnode.c4
-rw-r--r--fs/xfs/linux-2.6/xfs_vnode.h2
-rw-r--r--fs/xfs/quota/xfs_dquot.c105
-rw-r--r--fs/xfs/quota/xfs_dquot.h30
-rw-r--r--fs/xfs/quota/xfs_dquot_item.c6
-rw-r--r--fs/xfs/quota/xfs_qm.c202
-rw-r--r--fs/xfs/quota/xfs_qm.h16
-rw-r--r--fs/xfs/quota/xfs_qm_bhv.c43
-rw-r--r--fs/xfs/quota/xfs_qm_syscalls.c175
-rw-r--r--fs/xfs/quota/xfs_quota_priv.h15
-rw-r--r--fs/xfs/quota/xfs_trans_dquot.c60
-rw-r--r--fs/xfs/support/debug.c1
-rw-r--r--fs/xfs/support/debug.h7
-rw-r--r--fs/xfs/xfs_alloc.c4
-rw-r--r--fs/xfs/xfs_attr.c17
-rw-r--r--fs/xfs/xfs_attr.h7
-rw-r--r--fs/xfs/xfs_attr_leaf.c28
-rw-r--r--fs/xfs/xfs_attr_leaf.h12
-rw-r--r--fs/xfs/xfs_bit.c2
-rw-r--r--fs/xfs/xfs_bmap.c127
-rw-r--r--fs/xfs/xfs_bmap.h13
-rw-r--r--fs/xfs/xfs_bmap_btree.c14
-rw-r--r--fs/xfs/xfs_bmap_btree.h8
-rw-r--r--fs/xfs/xfs_btree.c12
-rw-r--r--fs/xfs/xfs_btree.h10
-rw-r--r--fs/xfs/xfs_buf_item.c24
-rw-r--r--fs/xfs/xfs_buf_item.h2
-rw-r--r--fs/xfs/xfs_da_btree.c9
-rw-r--r--fs/xfs/xfs_da_btree.h3
-rw-r--r--fs/xfs/xfs_dfrag.c7
-rw-r--r--fs/xfs/xfs_dir2_data.c2
-rw-r--r--fs/xfs/xfs_dir2_data.h4
-rw-r--r--fs/xfs/xfs_dir2_leaf.c8
-rw-r--r--fs/xfs/xfs_dir2_leaf.h7
-rw-r--r--fs/xfs/xfs_dir_leaf.c6
-rw-r--r--fs/xfs/xfs_dir_leaf.h2
-rw-r--r--fs/xfs/xfs_dmapi.h19
-rw-r--r--fs/xfs/xfs_error.c2
-rw-r--r--fs/xfs/xfs_error.h3
-rw-r--r--fs/xfs/xfs_extfree_item.c126
-rw-r--r--fs/xfs/xfs_extfree_item.h2
-rw-r--r--fs/xfs/xfs_fs.h3
-rw-r--r--fs/xfs/xfs_fsops.c26
-rw-r--r--fs/xfs/xfs_ialloc_btree.h8
-rw-r--r--fs/xfs/xfs_inode.c185
-rw-r--r--fs/xfs/xfs_inode.h9
-rw-r--r--fs/xfs/xfs_inode_item.c2
-rw-r--r--fs/xfs/xfs_iomap.c65
-rw-r--r--fs/xfs/xfs_log.c6
-rw-r--r--fs/xfs/xfs_log_priv.h2
-rw-r--r--fs/xfs/xfs_log_recover.c31
-rw-r--r--fs/xfs/xfs_macros.c5
-rw-r--r--fs/xfs/xfs_mount.c16
-rw-r--r--fs/xfs/xfs_mount.h7
-rw-r--r--fs/xfs/xfs_quota.h72
-rw-r--r--fs/xfs/xfs_rename.c18
-rw-r--r--fs/xfs/xfs_trans.c21
-rw-r--r--fs/xfs/xfs_trans.h3
-rw-r--r--fs/xfs/xfs_trans_buf.c1
-rw-r--r--fs/xfs/xfs_trans_inode.c18
-rw-r--r--fs/xfs/xfs_types.h2
-rw-r--r--fs/xfs/xfs_utils.c2
-rw-r--r--fs/xfs/xfs_vfsops.c74
-rw-r--r--fs/xfs/xfs_vnodeops.c95
73 files changed, 957 insertions, 1107 deletions
diff --git a/fs/xfs/linux-2.6/xfs_buf.c b/fs/xfs/linux-2.6/xfs_buf.c
index 997963e53622..c60e69431e11 100644
--- a/fs/xfs/linux-2.6/xfs_buf.c
+++ b/fs/xfs/linux-2.6/xfs_buf.c
@@ -61,12 +61,13 @@
61 * File wide globals 61 * File wide globals
62 */ 62 */
63 63
64STATIC kmem_cache_t *pagebuf_cache; 64STATIC kmem_cache_t *pagebuf_zone;
65STATIC kmem_shaker_t pagebuf_shake; 65STATIC kmem_shaker_t pagebuf_shake;
66STATIC int pagebuf_daemon_wakeup(int, unsigned int); 66STATIC int xfsbufd_wakeup(int, unsigned int);
67STATIC void pagebuf_delwri_queue(xfs_buf_t *, int); 67STATIC void pagebuf_delwri_queue(xfs_buf_t *, int);
68STATIC struct workqueue_struct *pagebuf_logio_workqueue; 68
69STATIC struct workqueue_struct *pagebuf_dataio_workqueue; 69STATIC struct workqueue_struct *xfslogd_workqueue;
70STATIC struct workqueue_struct *xfsdatad_workqueue;
70 71
71/* 72/*
72 * Pagebuf debugging 73 * Pagebuf debugging
@@ -123,9 +124,9 @@ ktrace_t *pagebuf_trace_buf;
123 124
124 125
125#define pagebuf_allocate(flags) \ 126#define pagebuf_allocate(flags) \
126 kmem_zone_alloc(pagebuf_cache, pb_to_km(flags)) 127 kmem_zone_alloc(pagebuf_zone, pb_to_km(flags))
127#define pagebuf_deallocate(pb) \ 128#define pagebuf_deallocate(pb) \
128 kmem_zone_free(pagebuf_cache, (pb)); 129 kmem_zone_free(pagebuf_zone, (pb));
129 130
130/* 131/*
131 * Page Region interfaces. 132 * Page Region interfaces.
@@ -425,7 +426,7 @@ _pagebuf_lookup_pages(
425 __FUNCTION__, gfp_mask); 426 __FUNCTION__, gfp_mask);
426 427
427 XFS_STATS_INC(pb_page_retries); 428 XFS_STATS_INC(pb_page_retries);
428 pagebuf_daemon_wakeup(0, gfp_mask); 429 xfsbufd_wakeup(0, gfp_mask);
429 blk_congestion_wait(WRITE, HZ/50); 430 blk_congestion_wait(WRITE, HZ/50);
430 goto retry; 431 goto retry;
431 } 432 }
@@ -1136,8 +1137,8 @@ pagebuf_iodone(
1136 if ((pb->pb_iodone) || (pb->pb_flags & PBF_ASYNC)) { 1137 if ((pb->pb_iodone) || (pb->pb_flags & PBF_ASYNC)) {
1137 if (schedule) { 1138 if (schedule) {
1138 INIT_WORK(&pb->pb_iodone_work, pagebuf_iodone_work, pb); 1139 INIT_WORK(&pb->pb_iodone_work, pagebuf_iodone_work, pb);
1139 queue_work(dataio ? pagebuf_dataio_workqueue : 1140 queue_work(dataio ? xfsdatad_workqueue :
1140 pagebuf_logio_workqueue, &pb->pb_iodone_work); 1141 xfslogd_workqueue, &pb->pb_iodone_work);
1141 } else { 1142 } else {
1142 pagebuf_iodone_work(pb); 1143 pagebuf_iodone_work(pb);
1143 } 1144 }
@@ -1562,16 +1563,6 @@ xfs_free_buftarg(
1562 kmem_free(btp, sizeof(*btp)); 1563 kmem_free(btp, sizeof(*btp));
1563} 1564}
1564 1565
1565void
1566xfs_incore_relse(
1567 xfs_buftarg_t *btp,
1568 int delwri_only,
1569 int wait)
1570{
1571 invalidate_bdev(btp->pbr_bdev, 1);
1572 truncate_inode_pages(btp->pbr_mapping, 0LL);
1573}
1574
1575STATIC int 1566STATIC int
1576xfs_setsize_buftarg_flags( 1567xfs_setsize_buftarg_flags(
1577 xfs_buftarg_t *btp, 1568 xfs_buftarg_t *btp,
@@ -1742,27 +1733,27 @@ pagebuf_runall_queues(
1742} 1733}
1743 1734
1744/* Defines for pagebuf daemon */ 1735/* Defines for pagebuf daemon */
1745STATIC DECLARE_COMPLETION(pagebuf_daemon_done); 1736STATIC DECLARE_COMPLETION(xfsbufd_done);
1746STATIC struct task_struct *pagebuf_daemon_task; 1737STATIC struct task_struct *xfsbufd_task;
1747STATIC int pagebuf_daemon_active; 1738STATIC int xfsbufd_active;
1748STATIC int force_flush; 1739STATIC int xfsbufd_force_flush;
1749STATIC int force_sleep; 1740STATIC int xfsbufd_force_sleep;
1750 1741
1751STATIC int 1742STATIC int
1752pagebuf_daemon_wakeup( 1743xfsbufd_wakeup(
1753 int priority, 1744 int priority,
1754 unsigned int mask) 1745 unsigned int mask)
1755{ 1746{
1756 if (force_sleep) 1747 if (xfsbufd_force_sleep)
1757 return 0; 1748 return 0;
1758 force_flush = 1; 1749 xfsbufd_force_flush = 1;
1759 barrier(); 1750 barrier();
1760 wake_up_process(pagebuf_daemon_task); 1751 wake_up_process(xfsbufd_task);
1761 return 0; 1752 return 0;
1762} 1753}
1763 1754
1764STATIC int 1755STATIC int
1765pagebuf_daemon( 1756xfsbufd(
1766 void *data) 1757 void *data)
1767{ 1758{
1768 struct list_head tmp; 1759 struct list_head tmp;
@@ -1774,17 +1765,17 @@ pagebuf_daemon(
1774 daemonize("xfsbufd"); 1765 daemonize("xfsbufd");
1775 current->flags |= PF_MEMALLOC; 1766 current->flags |= PF_MEMALLOC;
1776 1767
1777 pagebuf_daemon_task = current; 1768 xfsbufd_task = current;
1778 pagebuf_daemon_active = 1; 1769 xfsbufd_active = 1;
1779 barrier(); 1770 barrier();
1780 1771
1781 INIT_LIST_HEAD(&tmp); 1772 INIT_LIST_HEAD(&tmp);
1782 do { 1773 do {
1783 if (unlikely(current->flags & PF_FREEZE)) { 1774 if (unlikely(current->flags & PF_FREEZE)) {
1784 force_sleep = 1; 1775 xfsbufd_force_sleep = 1;
1785 refrigerator(PF_FREEZE); 1776 refrigerator(PF_FREEZE);
1786 } else { 1777 } else {
1787 force_sleep = 0; 1778 xfsbufd_force_sleep = 0;
1788 } 1779 }
1789 1780
1790 set_current_state(TASK_INTERRUPTIBLE); 1781 set_current_state(TASK_INTERRUPTIBLE);
@@ -1797,7 +1788,7 @@ pagebuf_daemon(
1797 ASSERT(pb->pb_flags & PBF_DELWRI); 1788 ASSERT(pb->pb_flags & PBF_DELWRI);
1798 1789
1799 if (!pagebuf_ispin(pb) && !pagebuf_cond_lock(pb)) { 1790 if (!pagebuf_ispin(pb) && !pagebuf_cond_lock(pb)) {
1800 if (!force_flush && 1791 if (!xfsbufd_force_flush &&
1801 time_before(jiffies, 1792 time_before(jiffies,
1802 pb->pb_queuetime + age)) { 1793 pb->pb_queuetime + age)) {
1803 pagebuf_unlock(pb); 1794 pagebuf_unlock(pb);
@@ -1824,10 +1815,10 @@ pagebuf_daemon(
1824 if (as_list_len > 0) 1815 if (as_list_len > 0)
1825 purge_addresses(); 1816 purge_addresses();
1826 1817
1827 force_flush = 0; 1818 xfsbufd_force_flush = 0;
1828 } while (pagebuf_daemon_active); 1819 } while (xfsbufd_active);
1829 1820
1830 complete_and_exit(&pagebuf_daemon_done, 0); 1821 complete_and_exit(&xfsbufd_done, 0);
1831} 1822}
1832 1823
1833/* 1824/*
@@ -1844,8 +1835,8 @@ xfs_flush_buftarg(
1844 xfs_buf_t *pb, *n; 1835 xfs_buf_t *pb, *n;
1845 int pincount = 0; 1836 int pincount = 0;
1846 1837
1847 pagebuf_runall_queues(pagebuf_dataio_workqueue); 1838 pagebuf_runall_queues(xfsdatad_workqueue);
1848 pagebuf_runall_queues(pagebuf_logio_workqueue); 1839 pagebuf_runall_queues(xfslogd_workqueue);
1849 1840
1850 INIT_LIST_HEAD(&tmp); 1841 INIT_LIST_HEAD(&tmp);
1851 spin_lock(&pbd_delwrite_lock); 1842 spin_lock(&pbd_delwrite_lock);
@@ -1898,43 +1889,43 @@ xfs_flush_buftarg(
1898} 1889}
1899 1890
1900STATIC int 1891STATIC int
1901pagebuf_daemon_start(void) 1892xfs_buf_daemons_start(void)
1902{ 1893{
1903 int rval; 1894 int error = -ENOMEM;
1904 1895
1905 pagebuf_logio_workqueue = create_workqueue("xfslogd"); 1896 xfslogd_workqueue = create_workqueue("xfslogd");
1906 if (!pagebuf_logio_workqueue) 1897 if (!xfslogd_workqueue)
1907 return -ENOMEM; 1898 goto out;
1908 1899
1909 pagebuf_dataio_workqueue = create_workqueue("xfsdatad"); 1900 xfsdatad_workqueue = create_workqueue("xfsdatad");
1910 if (!pagebuf_dataio_workqueue) { 1901 if (!xfsdatad_workqueue)
1911 destroy_workqueue(pagebuf_logio_workqueue); 1902 goto out_destroy_xfslogd_workqueue;
1912 return -ENOMEM;
1913 }
1914 1903
1915 rval = kernel_thread(pagebuf_daemon, NULL, CLONE_FS|CLONE_FILES); 1904 error = kernel_thread(xfsbufd, NULL, CLONE_FS|CLONE_FILES);
1916 if (rval < 0) { 1905 if (error < 0)
1917 destroy_workqueue(pagebuf_logio_workqueue); 1906 goto out_destroy_xfsdatad_workqueue;
1918 destroy_workqueue(pagebuf_dataio_workqueue); 1907 return 0;
1919 }
1920 1908
1921 return rval; 1909 out_destroy_xfsdatad_workqueue:
1910 destroy_workqueue(xfsdatad_workqueue);
1911 out_destroy_xfslogd_workqueue:
1912 destroy_workqueue(xfslogd_workqueue);
1913 out:
1914 return error;
1922} 1915}
1923 1916
1924/* 1917/*
1925 * pagebuf_daemon_stop
1926 *
1927 * Note: do not mark as __exit, it is called from pagebuf_terminate. 1918 * Note: do not mark as __exit, it is called from pagebuf_terminate.
1928 */ 1919 */
1929STATIC void 1920STATIC void
1930pagebuf_daemon_stop(void) 1921xfs_buf_daemons_stop(void)
1931{ 1922{
1932 pagebuf_daemon_active = 0; 1923 xfsbufd_active = 0;
1933 barrier(); 1924 barrier();
1934 wait_for_completion(&pagebuf_daemon_done); 1925 wait_for_completion(&xfsbufd_done);
1935 1926
1936 destroy_workqueue(pagebuf_logio_workqueue); 1927 destroy_workqueue(xfslogd_workqueue);
1937 destroy_workqueue(pagebuf_dataio_workqueue); 1928 destroy_workqueue(xfsdatad_workqueue);
1938} 1929}
1939 1930
1940/* 1931/*
@@ -1944,27 +1935,37 @@ pagebuf_daemon_stop(void)
1944int __init 1935int __init
1945pagebuf_init(void) 1936pagebuf_init(void)
1946{ 1937{
1947 pagebuf_cache = kmem_cache_create("xfs_buf_t", sizeof(xfs_buf_t), 0, 1938 int error = -ENOMEM;
1948 SLAB_HWCACHE_ALIGN, NULL, NULL); 1939
1949 if (pagebuf_cache == NULL) { 1940 pagebuf_zone = kmem_zone_init(sizeof(xfs_buf_t), "xfs_buf");
1950 printk("XFS: couldn't init xfs_buf_t cache\n"); 1941 if (!pagebuf_zone)
1951 pagebuf_terminate(); 1942 goto out;
1952 return -ENOMEM;
1953 }
1954 1943
1955#ifdef PAGEBUF_TRACE 1944#ifdef PAGEBUF_TRACE
1956 pagebuf_trace_buf = ktrace_alloc(PAGEBUF_TRACE_SIZE, KM_SLEEP); 1945 pagebuf_trace_buf = ktrace_alloc(PAGEBUF_TRACE_SIZE, KM_SLEEP);
1957#endif 1946#endif
1958 1947
1959 pagebuf_daemon_start(); 1948 error = xfs_buf_daemons_start();
1949 if (error)
1950 goto out_free_buf_zone;
1960 1951
1961 pagebuf_shake = kmem_shake_register(pagebuf_daemon_wakeup); 1952 pagebuf_shake = kmem_shake_register(xfsbufd_wakeup);
1962 if (pagebuf_shake == NULL) { 1953 if (!pagebuf_shake) {
1963 pagebuf_terminate(); 1954 error = -ENOMEM;
1964 return -ENOMEM; 1955 goto out_stop_daemons;
1965 } 1956 }
1966 1957
1967 return 0; 1958 return 0;
1959
1960 out_stop_daemons:
1961 xfs_buf_daemons_stop();
1962 out_free_buf_zone:
1963#ifdef PAGEBUF_TRACE
1964 ktrace_free(pagebuf_trace_buf);
1965#endif
1966 kmem_zone_destroy(pagebuf_zone);
1967 out:
1968 return error;
1968} 1969}
1969 1970
1970 1971
@@ -1976,12 +1977,12 @@ pagebuf_init(void)
1976void 1977void
1977pagebuf_terminate(void) 1978pagebuf_terminate(void)
1978{ 1979{
1979 pagebuf_daemon_stop(); 1980 xfs_buf_daemons_stop();
1980 1981
1981#ifdef PAGEBUF_TRACE 1982#ifdef PAGEBUF_TRACE
1982 ktrace_free(pagebuf_trace_buf); 1983 ktrace_free(pagebuf_trace_buf);
1983#endif 1984#endif
1984 1985
1985 kmem_zone_destroy(pagebuf_cache); 1986 kmem_zone_destroy(pagebuf_zone);
1986 kmem_shake_deregister(pagebuf_shake); 1987 kmem_shake_deregister(pagebuf_shake);
1987} 1988}
diff --git a/fs/xfs/linux-2.6/xfs_buf.h b/fs/xfs/linux-2.6/xfs_buf.h
index 74deed8e6d90..3f8f69a66aea 100644
--- a/fs/xfs/linux-2.6/xfs_buf.h
+++ b/fs/xfs/linux-2.6/xfs_buf.h
@@ -576,7 +576,6 @@ extern xfs_buftarg_t *xfs_alloc_buftarg(struct block_device *, int);
576extern void xfs_free_buftarg(xfs_buftarg_t *, int); 576extern void xfs_free_buftarg(xfs_buftarg_t *, int);
577extern void xfs_wait_buftarg(xfs_buftarg_t *); 577extern void xfs_wait_buftarg(xfs_buftarg_t *);
578extern int xfs_setsize_buftarg(xfs_buftarg_t *, unsigned int, unsigned int); 578extern int xfs_setsize_buftarg(xfs_buftarg_t *, unsigned int, unsigned int);
579extern void xfs_incore_relse(xfs_buftarg_t *, int, int);
580extern int xfs_flush_buftarg(xfs_buftarg_t *, int); 579extern int xfs_flush_buftarg(xfs_buftarg_t *, int);
581 580
582#define xfs_getsize_buftarg(buftarg) \ 581#define xfs_getsize_buftarg(buftarg) \
diff --git a/fs/xfs/linux-2.6/xfs_file.c b/fs/xfs/linux-2.6/xfs_file.c
index 24fa3b101b93..f1ce4323f56e 100644
--- a/fs/xfs/linux-2.6/xfs_file.c
+++ b/fs/xfs/linux-2.6/xfs_file.c
@@ -57,7 +57,9 @@
57#include <linux/smp_lock.h> 57#include <linux/smp_lock.h>
58 58
59static struct vm_operations_struct linvfs_file_vm_ops; 59static struct vm_operations_struct linvfs_file_vm_ops;
60 60#ifdef CONFIG_XFS_DMAPI
61static struct vm_operations_struct linvfs_dmapi_file_vm_ops;
62#endif
61 63
62STATIC inline ssize_t 64STATIC inline ssize_t
63__linvfs_read( 65__linvfs_read(
@@ -388,6 +390,14 @@ done:
388 return -error; 390 return -error;
389} 391}
390 392
393#ifdef CONFIG_XFS_DMAPI
394STATIC void
395linvfs_mmap_close(
396 struct vm_area_struct *vma)
397{
398 xfs_dm_mm_put(vma);
399}
400#endif /* CONFIG_XFS_DMAPI */
391 401
392STATIC int 402STATIC int
393linvfs_file_mmap( 403linvfs_file_mmap(
@@ -399,16 +409,19 @@ linvfs_file_mmap(
399 vattr_t va = { .va_mask = XFS_AT_UPDATIME }; 409 vattr_t va = { .va_mask = XFS_AT_UPDATIME };
400 int error; 410 int error;
401 411
412 vma->vm_ops = &linvfs_file_vm_ops;
413
402 if (vp->v_vfsp->vfs_flag & VFS_DMI) { 414 if (vp->v_vfsp->vfs_flag & VFS_DMI) {
403 xfs_mount_t *mp = XFS_VFSTOM(vp->v_vfsp); 415 xfs_mount_t *mp = XFS_VFSTOM(vp->v_vfsp);
404 416
405 error = -XFS_SEND_MMAP(mp, vma, 0); 417 error = -XFS_SEND_MMAP(mp, vma, 0);
406 if (error) 418 if (error)
407 return error; 419 return error;
420#ifdef CONFIG_XFS_DMAPI
421 vma->vm_ops = &linvfs_dmapi_file_vm_ops;
422#endif
408 } 423 }
409 424
410 vma->vm_ops = &linvfs_file_vm_ops;
411
412 VOP_SETATTR(vp, &va, XFS_AT_UPDATIME, NULL, error); 425 VOP_SETATTR(vp, &va, XFS_AT_UPDATIME, NULL, error);
413 if (!error) 426 if (!error)
414 vn_revalidate(vp); /* update Linux inode flags */ 427 vn_revalidate(vp); /* update Linux inode flags */
@@ -609,7 +622,15 @@ struct file_operations linvfs_dir_operations = {
609static struct vm_operations_struct linvfs_file_vm_ops = { 622static struct vm_operations_struct linvfs_file_vm_ops = {
610 .nopage = filemap_nopage, 623 .nopage = filemap_nopage,
611 .populate = filemap_populate, 624 .populate = filemap_populate,
625};
626
627#ifdef CONFIG_XFS_DMAPI
628static struct vm_operations_struct linvfs_dmapi_file_vm_ops = {
629 .close = linvfs_mmap_close,
630 .nopage = filemap_nopage,
631 .populate = filemap_populate,
612#ifdef HAVE_VMOP_MPROTECT 632#ifdef HAVE_VMOP_MPROTECT
613 .mprotect = linvfs_mprotect, 633 .mprotect = linvfs_mprotect,
614#endif 634#endif
615}; 635};
636#endif /* CONFIG_XFS_DMAPI */
diff --git a/fs/xfs/linux-2.6/xfs_ioctl.c b/fs/xfs/linux-2.6/xfs_ioctl.c
index 69809eef8a54..05a447e51cc0 100644
--- a/fs/xfs/linux-2.6/xfs_ioctl.c
+++ b/fs/xfs/linux-2.6/xfs_ioctl.c
@@ -1174,7 +1174,8 @@ xfs_ioc_xattr(
1174 1174
1175 switch (cmd) { 1175 switch (cmd) {
1176 case XFS_IOC_FSGETXATTR: { 1176 case XFS_IOC_FSGETXATTR: {
1177 va.va_mask = XFS_AT_XFLAGS|XFS_AT_EXTSIZE|XFS_AT_NEXTENTS; 1177 va.va_mask = XFS_AT_XFLAGS | XFS_AT_EXTSIZE | \
1178 XFS_AT_NEXTENTS | XFS_AT_PROJID;
1178 VOP_GETATTR(vp, &va, 0, NULL, error); 1179 VOP_GETATTR(vp, &va, 0, NULL, error);
1179 if (error) 1180 if (error)
1180 return -error; 1181 return -error;
@@ -1182,6 +1183,7 @@ xfs_ioc_xattr(
1182 fa.fsx_xflags = va.va_xflags; 1183 fa.fsx_xflags = va.va_xflags;
1183 fa.fsx_extsize = va.va_extsize; 1184 fa.fsx_extsize = va.va_extsize;
1184 fa.fsx_nextents = va.va_nextents; 1185 fa.fsx_nextents = va.va_nextents;
1186 fa.fsx_projid = va.va_projid;
1185 1187
1186 if (copy_to_user(arg, &fa, sizeof(fa))) 1188 if (copy_to_user(arg, &fa, sizeof(fa)))
1187 return -XFS_ERROR(EFAULT); 1189 return -XFS_ERROR(EFAULT);
@@ -1196,9 +1198,10 @@ xfs_ioc_xattr(
1196 if (filp->f_flags & (O_NDELAY|O_NONBLOCK)) 1198 if (filp->f_flags & (O_NDELAY|O_NONBLOCK))
1197 attr_flags |= ATTR_NONBLOCK; 1199 attr_flags |= ATTR_NONBLOCK;
1198 1200
1199 va.va_mask = XFS_AT_XFLAGS | XFS_AT_EXTSIZE; 1201 va.va_mask = XFS_AT_XFLAGS | XFS_AT_EXTSIZE | XFS_AT_PROJID;
1200 va.va_xflags = fa.fsx_xflags; 1202 va.va_xflags = fa.fsx_xflags;
1201 va.va_extsize = fa.fsx_extsize; 1203 va.va_extsize = fa.fsx_extsize;
1204 va.va_projid = fa.fsx_projid;
1202 1205
1203 VOP_SETATTR(vp, &va, attr_flags, NULL, error); 1206 VOP_SETATTR(vp, &va, attr_flags, NULL, error);
1204 if (!error) 1207 if (!error)
@@ -1207,7 +1210,8 @@ xfs_ioc_xattr(
1207 } 1210 }
1208 1211
1209 case XFS_IOC_FSGETXATTRA: { 1212 case XFS_IOC_FSGETXATTRA: {
1210 va.va_mask = XFS_AT_XFLAGS|XFS_AT_EXTSIZE|XFS_AT_ANEXTENTS; 1213 va.va_mask = XFS_AT_XFLAGS | XFS_AT_EXTSIZE | \
1214 XFS_AT_ANEXTENTS | XFS_AT_PROJID;
1211 VOP_GETATTR(vp, &va, 0, NULL, error); 1215 VOP_GETATTR(vp, &va, 0, NULL, error);
1212 if (error) 1216 if (error)
1213 return -error; 1217 return -error;
@@ -1215,6 +1219,7 @@ xfs_ioc_xattr(
1215 fa.fsx_xflags = va.va_xflags; 1219 fa.fsx_xflags = va.va_xflags;
1216 fa.fsx_extsize = va.va_extsize; 1220 fa.fsx_extsize = va.va_extsize;
1217 fa.fsx_nextents = va.va_anextents; 1221 fa.fsx_nextents = va.va_anextents;
1222 fa.fsx_projid = va.va_projid;
1218 1223
1219 if (copy_to_user(arg, &fa, sizeof(fa))) 1224 if (copy_to_user(arg, &fa, sizeof(fa)))
1220 return -XFS_ERROR(EFAULT); 1225 return -XFS_ERROR(EFAULT);
diff --git a/fs/xfs/linux-2.6/xfs_linux.h b/fs/xfs/linux-2.6/xfs_linux.h
index 7d7c8788ea75..42dc5e4662ed 100644
--- a/fs/xfs/linux-2.6/xfs_linux.h
+++ b/fs/xfs/linux-2.6/xfs_linux.h
@@ -230,8 +230,10 @@ static inline void set_buffer_unwritten_io(struct buffer_head *bh)
230 * field (see the QCMD macro in quota.h). These macros help keep the 230 * field (see the QCMD macro in quota.h). These macros help keep the
231 * code portable - they are not visible from the syscall interface. 231 * code portable - they are not visible from the syscall interface.
232 */ 232 */
233#define Q_XSETGQLIM XQM_CMD(0x8) /* set groups disk limits */ 233#define Q_XSETGQLIM XQM_CMD(8) /* set groups disk limits */
234#define Q_XGETGQUOTA XQM_CMD(0x9) /* get groups disk limits */ 234#define Q_XGETGQUOTA XQM_CMD(9) /* get groups disk limits */
235#define Q_XSETPQLIM XQM_CMD(10) /* set projects disk limits */
236#define Q_XGETPQUOTA XQM_CMD(11) /* get projects disk limits */
235 237
236/* IRIX uses a dynamic sizing algorithm (ndquot = 200 + numprocs*2) */ 238/* IRIX uses a dynamic sizing algorithm (ndquot = 200 + numprocs*2) */
237/* we may well need to fine-tune this if it ever becomes an issue. */ 239/* we may well need to fine-tune this if it ever becomes an issue. */
diff --git a/fs/xfs/linux-2.6/xfs_lrw.c b/fs/xfs/linux-2.6/xfs_lrw.c
index aa9daaea6c34..acab58c48043 100644
--- a/fs/xfs/linux-2.6/xfs_lrw.c
+++ b/fs/xfs/linux-2.6/xfs_lrw.c
@@ -209,30 +209,6 @@ unlock:
209 return (-status); 209 return (-status);
210} 210}
211 211
212/*
213 * xfs_inval_cached_pages
214 *
215 * This routine is responsible for keeping direct I/O and buffered I/O
216 * somewhat coherent. From here we make sure that we're at least
217 * temporarily holding the inode I/O lock exclusively and then call
218 * the page cache to flush and invalidate any cached pages. If there
219 * are no cached pages this routine will be very quick.
220 */
221void
222xfs_inval_cached_pages(
223 vnode_t *vp,
224 xfs_iocore_t *io,
225 xfs_off_t offset,
226 int write,
227 int relock)
228{
229 if (VN_CACHED(vp)) {
230 xfs_inval_cached_trace(io, offset, -1, ctooff(offtoct(offset)), -1);
231 VOP_FLUSHINVAL_PAGES(vp, ctooff(offtoct(offset)), -1, FI_REMAPF_LOCKED);
232 }
233
234}
235
236ssize_t /* bytes read, or (-) error */ 212ssize_t /* bytes read, or (-) error */
237xfs_read( 213xfs_read(
238 bhv_desc_t *bdp, 214 bhv_desc_t *bdp,
@@ -304,10 +280,11 @@ xfs_read(
304 if (DM_EVENT_ENABLED(vp->v_vfsp, ip, DM_EVENT_READ) && 280 if (DM_EVENT_ENABLED(vp->v_vfsp, ip, DM_EVENT_READ) &&
305 !(ioflags & IO_INVIS)) { 281 !(ioflags & IO_INVIS)) {
306 vrwlock_t locktype = VRWLOCK_READ; 282 vrwlock_t locktype = VRWLOCK_READ;
283 int dmflags = FILP_DELAY_FLAG(file) | DM_SEM_FLAG_RD(ioflags);
307 284
308 ret = -XFS_SEND_DATA(mp, DM_EVENT_READ, 285 ret = -XFS_SEND_DATA(mp, DM_EVENT_READ,
309 BHV_TO_VNODE(bdp), *offset, size, 286 BHV_TO_VNODE(bdp), *offset, size,
310 FILP_DELAY_FLAG(file), &locktype); 287 dmflags, &locktype);
311 if (ret) { 288 if (ret) {
312 xfs_iunlock(ip, XFS_IOLOCK_SHARED); 289 xfs_iunlock(ip, XFS_IOLOCK_SHARED);
313 goto unlock_isem; 290 goto unlock_isem;
@@ -867,11 +844,15 @@ retry:
867 !(ioflags & IO_INVIS)) { 844 !(ioflags & IO_INVIS)) {
868 845
869 xfs_rwunlock(bdp, locktype); 846 xfs_rwunlock(bdp, locktype);
847 if (need_isem)
848 up(&inode->i_sem);
870 error = XFS_SEND_NAMESP(xip->i_mount, DM_EVENT_NOSPACE, vp, 849 error = XFS_SEND_NAMESP(xip->i_mount, DM_EVENT_NOSPACE, vp,
871 DM_RIGHT_NULL, vp, DM_RIGHT_NULL, NULL, NULL, 850 DM_RIGHT_NULL, vp, DM_RIGHT_NULL, NULL, NULL,
872 0, 0, 0); /* Delay flag intentionally unused */ 851 0, 0, 0); /* Delay flag intentionally unused */
873 if (error) 852 if (error)
874 goto out_unlock_isem; 853 goto out_nounlocks;
854 if (need_isem)
855 down(&inode->i_sem);
875 xfs_rwlock(bdp, locktype); 856 xfs_rwlock(bdp, locktype);
876 pos = xip->i_d.di_size; 857 pos = xip->i_d.di_size;
877 ret = 0; 858 ret = 0;
@@ -986,6 +967,7 @@ retry:
986 out_unlock_isem: 967 out_unlock_isem:
987 if (need_isem) 968 if (need_isem)
988 up(&inode->i_sem); 969 up(&inode->i_sem);
970 out_nounlocks:
989 return -error; 971 return -error;
990} 972}
991 973
diff --git a/fs/xfs/linux-2.6/xfs_lrw.h b/fs/xfs/linux-2.6/xfs_lrw.h
index d723e35254a0..f197a720e394 100644
--- a/fs/xfs/linux-2.6/xfs_lrw.h
+++ b/fs/xfs/linux-2.6/xfs_lrw.h
@@ -94,8 +94,6 @@ extern int xfs_bdstrat_cb(struct xfs_buf *);
94 94
95extern int xfs_zero_eof(struct vnode *, struct xfs_iocore *, xfs_off_t, 95extern int xfs_zero_eof(struct vnode *, struct xfs_iocore *, xfs_off_t,
96 xfs_fsize_t, xfs_fsize_t); 96 xfs_fsize_t, xfs_fsize_t);
97extern void xfs_inval_cached_pages(struct vnode *, struct xfs_iocore *,
98 xfs_off_t, int, int);
99extern ssize_t xfs_read(struct bhv_desc *, struct kiocb *, 97extern ssize_t xfs_read(struct bhv_desc *, struct kiocb *,
100 const struct iovec *, unsigned int, 98 const struct iovec *, unsigned int,
101 loff_t *, int, struct cred *); 99 loff_t *, int, struct cred *);
diff --git a/fs/xfs/linux-2.6/xfs_super.c b/fs/xfs/linux-2.6/xfs_super.c
index 455e2b2fb964..5fe9af38aa20 100644
--- a/fs/xfs/linux-2.6/xfs_super.c
+++ b/fs/xfs/linux-2.6/xfs_super.c
@@ -590,8 +590,10 @@ linvfs_sync_super(
590 int error; 590 int error;
591 int flags = SYNC_FSDATA; 591 int flags = SYNC_FSDATA;
592 592
593 if (wait) 593 if (unlikely(sb->s_frozen == SB_FREEZE_WRITE))
594 flags |= SYNC_WAIT; 594 flags = SYNC_QUIESCE;
595 else
596 flags = SYNC_FSDATA | (wait ? SYNC_WAIT : 0);
595 597
596 VFS_SYNC(vfsp, flags, NULL, error); 598 VFS_SYNC(vfsp, flags, NULL, error);
597 sb->s_dirt = 0; 599 sb->s_dirt = 0;
@@ -701,7 +703,8 @@ linvfs_getxquota(
701 struct vfs *vfsp = LINVFS_GET_VFS(sb); 703 struct vfs *vfsp = LINVFS_GET_VFS(sb);
702 int error, getmode; 704 int error, getmode;
703 705
704 getmode = (type == GRPQUOTA) ? Q_XGETGQUOTA : Q_XGETQUOTA; 706 getmode = (type == USRQUOTA) ? Q_XGETQUOTA :
707 ((type == GRPQUOTA) ? Q_XGETGQUOTA : Q_XGETPQUOTA);
705 VFS_QUOTACTL(vfsp, getmode, id, (caddr_t)fdq, error); 708 VFS_QUOTACTL(vfsp, getmode, id, (caddr_t)fdq, error);
706 return -error; 709 return -error;
707} 710}
@@ -716,7 +719,8 @@ linvfs_setxquota(
716 struct vfs *vfsp = LINVFS_GET_VFS(sb); 719 struct vfs *vfsp = LINVFS_GET_VFS(sb);
717 int error, setmode; 720 int error, setmode;
718 721
719 setmode = (type == GRPQUOTA) ? Q_XSETGQLIM : Q_XSETQLIM; 722 setmode = (type == USRQUOTA) ? Q_XSETQLIM :
723 ((type == GRPQUOTA) ? Q_XSETGQLIM : Q_XSETPQLIM);
720 VFS_QUOTACTL(vfsp, setmode, id, (caddr_t)fdq, error); 724 VFS_QUOTACTL(vfsp, setmode, id, (caddr_t)fdq, error);
721 return -error; 725 return -error;
722} 726}
diff --git a/fs/xfs/linux-2.6/xfs_vfs.h b/fs/xfs/linux-2.6/xfs_vfs.h
index 76493991578f..7ee1f714e9ba 100644
--- a/fs/xfs/linux-2.6/xfs_vfs.h
+++ b/fs/xfs/linux-2.6/xfs_vfs.h
@@ -107,6 +107,7 @@ typedef enum {
107#define SYNC_FSDATA 0x0020 /* flush fs data (e.g. superblocks) */ 107#define SYNC_FSDATA 0x0020 /* flush fs data (e.g. superblocks) */
108#define SYNC_REFCACHE 0x0040 /* prune some of the nfs ref cache */ 108#define SYNC_REFCACHE 0x0040 /* prune some of the nfs ref cache */
109#define SYNC_REMOUNT 0x0080 /* remount readonly, no dummy LRs */ 109#define SYNC_REMOUNT 0x0080 /* remount readonly, no dummy LRs */
110#define SYNC_QUIESCE 0x0100 /* quiesce fileystem for a snapshot */
110 111
111typedef int (*vfs_mount_t)(bhv_desc_t *, 112typedef int (*vfs_mount_t)(bhv_desc_t *,
112 struct xfs_mount_args *, struct cred *); 113 struct xfs_mount_args *, struct cred *);
diff --git a/fs/xfs/linux-2.6/xfs_vnode.c b/fs/xfs/linux-2.6/xfs_vnode.c
index a832d165f24f..250cad54e892 100644
--- a/fs/xfs/linux-2.6/xfs_vnode.c
+++ b/fs/xfs/linux-2.6/xfs_vnode.c
@@ -411,13 +411,13 @@ vn_remove(
411/* 0 */ (void *)(__psint_t)(vk), \ 411/* 0 */ (void *)(__psint_t)(vk), \
412/* 1 */ (void *)(s), \ 412/* 1 */ (void *)(s), \
413/* 2 */ (void *)(__psint_t) line, \ 413/* 2 */ (void *)(__psint_t) line, \
414/* 3 */ (void *)(vn_count(vp)), \ 414/* 3 */ (void *)(__psint_t)(vn_count(vp)), \
415/* 4 */ (void *)(ra), \ 415/* 4 */ (void *)(ra), \
416/* 5 */ (void *)(__psunsigned_t)(vp)->v_flag, \ 416/* 5 */ (void *)(__psunsigned_t)(vp)->v_flag, \
417/* 6 */ (void *)(__psint_t)current_cpu(), \ 417/* 6 */ (void *)(__psint_t)current_cpu(), \
418/* 7 */ (void *)(__psint_t)current_pid(), \ 418/* 7 */ (void *)(__psint_t)current_pid(), \
419/* 8 */ (void *)__return_address, \ 419/* 8 */ (void *)__return_address, \
420/* 9 */ 0, 0, 0, 0, 0, 0, 0) 420/* 9 */ NULL, NULL, NULL, NULL, NULL, NULL, NULL)
421 421
422/* 422/*
423 * Vnode tracing code. 423 * Vnode tracing code.
diff --git a/fs/xfs/linux-2.6/xfs_vnode.h b/fs/xfs/linux-2.6/xfs_vnode.h
index 00466c3194ac..a6e57c647be4 100644
--- a/fs/xfs/linux-2.6/xfs_vnode.h
+++ b/fs/xfs/linux-2.6/xfs_vnode.h
@@ -426,7 +426,7 @@ typedef struct vattr {
426 u_long va_extsize; /* file extent size */ 426 u_long va_extsize; /* file extent size */
427 u_long va_nextents; /* number of extents in file */ 427 u_long va_nextents; /* number of extents in file */
428 u_long va_anextents; /* number of attr extents in file */ 428 u_long va_anextents; /* number of attr extents in file */
429 int va_projid; /* project id */ 429 prid_t va_projid; /* project id */
430} vattr_t; 430} vattr_t;
431 431
432/* 432/*
diff --git a/fs/xfs/quota/xfs_dquot.c b/fs/xfs/quota/xfs_dquot.c
index 740d20d33187..46ce1e3ce1d6 100644
--- a/fs/xfs/quota/xfs_dquot.c
+++ b/fs/xfs/quota/xfs_dquot.c
@@ -101,7 +101,7 @@ int xfs_dqerror_mod = 33;
101 * is the d_id field. The idea is to fill in the entire q_core 101 * is the d_id field. The idea is to fill in the entire q_core
102 * when we read in the on disk dquot. 102 * when we read in the on disk dquot.
103 */ 103 */
104xfs_dquot_t * 104STATIC xfs_dquot_t *
105xfs_qm_dqinit( 105xfs_qm_dqinit(
106 xfs_mount_t *mp, 106 xfs_mount_t *mp,
107 xfs_dqid_t id, 107 xfs_dqid_t id,
@@ -286,7 +286,9 @@ xfs_qm_adjust_dqlimits(
286 * We also return 0 as the values of the timers in Q_GETQUOTA calls, when 286 * We also return 0 as the values of the timers in Q_GETQUOTA calls, when
287 * enforcement's off. 287 * enforcement's off.
288 * In contrast, warnings are a little different in that they don't 288 * In contrast, warnings are a little different in that they don't
289 * 'automatically' get started when limits get exceeded. 289 * 'automatically' get started when limits get exceeded. They do
290 * get reset to zero, however, when we find the count to be under
291 * the soft limit (they are only ever set non-zero via userspace).
290 */ 292 */
291void 293void
292xfs_qm_adjust_dqtimers( 294xfs_qm_adjust_dqtimers(
@@ -315,6 +317,8 @@ xfs_qm_adjust_dqtimers(
315 INT_GET(d->d_blk_hardlimit, ARCH_CONVERT)))) { 317 INT_GET(d->d_blk_hardlimit, ARCH_CONVERT)))) {
316 INT_SET(d->d_btimer, ARCH_CONVERT, 318 INT_SET(d->d_btimer, ARCH_CONVERT,
317 get_seconds() + XFS_QI_BTIMELIMIT(mp)); 319 get_seconds() + XFS_QI_BTIMELIMIT(mp));
320 } else {
321 d->d_bwarns = 0;
318 } 322 }
319 } else { 323 } else {
320 if ((!d->d_blk_softlimit || 324 if ((!d->d_blk_softlimit ||
@@ -336,6 +340,8 @@ xfs_qm_adjust_dqtimers(
336 INT_GET(d->d_ino_hardlimit, ARCH_CONVERT)))) { 340 INT_GET(d->d_ino_hardlimit, ARCH_CONVERT)))) {
337 INT_SET(d->d_itimer, ARCH_CONVERT, 341 INT_SET(d->d_itimer, ARCH_CONVERT,
338 get_seconds() + XFS_QI_ITIMELIMIT(mp)); 342 get_seconds() + XFS_QI_ITIMELIMIT(mp));
343 } else {
344 d->d_iwarns = 0;
339 } 345 }
340 } else { 346 } else {
341 if ((!d->d_ino_softlimit || 347 if ((!d->d_ino_softlimit ||
@@ -357,6 +363,8 @@ xfs_qm_adjust_dqtimers(
357 INT_GET(d->d_rtb_hardlimit, ARCH_CONVERT)))) { 363 INT_GET(d->d_rtb_hardlimit, ARCH_CONVERT)))) {
358 INT_SET(d->d_rtbtimer, ARCH_CONVERT, 364 INT_SET(d->d_rtbtimer, ARCH_CONVERT,
359 get_seconds() + XFS_QI_RTBTIMELIMIT(mp)); 365 get_seconds() + XFS_QI_RTBTIMELIMIT(mp));
366 } else {
367 d->d_rtbwarns = 0;
360 } 368 }
361 } else { 369 } else {
362 if ((!d->d_rtb_softlimit || 370 if ((!d->d_rtb_softlimit ||
@@ -371,68 +379,6 @@ xfs_qm_adjust_dqtimers(
371} 379}
372 380
373/* 381/*
374 * Increment or reset warnings of a given dquot.
375 */
376int
377xfs_qm_dqwarn(
378 xfs_disk_dquot_t *d,
379 uint flags)
380{
381 int warned;
382
383 /*
384 * root's limits are not real limits.
385 */
386 if (!d->d_id)
387 return (0);
388
389 warned = 0;
390 if (INT_GET(d->d_blk_softlimit, ARCH_CONVERT) &&
391 (INT_GET(d->d_bcount, ARCH_CONVERT) >=
392 INT_GET(d->d_blk_softlimit, ARCH_CONVERT))) {
393 if (flags & XFS_QMOPT_DOWARN) {
394 INT_MOD(d->d_bwarns, ARCH_CONVERT, +1);
395 warned++;
396 }
397 } else {
398 if (!d->d_blk_softlimit ||
399 (INT_GET(d->d_bcount, ARCH_CONVERT) <
400 INT_GET(d->d_blk_softlimit, ARCH_CONVERT))) {
401 d->d_bwarns = 0;
402 }
403 }
404
405 if (INT_GET(d->d_ino_softlimit, ARCH_CONVERT) > 0 &&
406 (INT_GET(d->d_icount, ARCH_CONVERT) >=
407 INT_GET(d->d_ino_softlimit, ARCH_CONVERT))) {
408 if (flags & XFS_QMOPT_DOWARN) {
409 INT_MOD(d->d_iwarns, ARCH_CONVERT, +1);
410 warned++;
411 }
412 } else {
413 if (!d->d_ino_softlimit ||
414 (INT_GET(d->d_icount, ARCH_CONVERT) <
415 INT_GET(d->d_ino_softlimit, ARCH_CONVERT))) {
416 d->d_iwarns = 0;
417 }
418 }
419#ifdef QUOTADEBUG
420 if (INT_GET(d->d_iwarns, ARCH_CONVERT))
421 cmn_err(CE_DEBUG,
422 "--------@@Inode warnings running : %Lu >= %Lu",
423 INT_GET(d->d_icount, ARCH_CONVERT),
424 INT_GET(d->d_ino_softlimit, ARCH_CONVERT));
425 if (INT_GET(d->d_bwarns, ARCH_CONVERT))
426 cmn_err(CE_DEBUG,
427 "--------@@Blks warnings running : %Lu >= %Lu",
428 INT_GET(d->d_bcount, ARCH_CONVERT),
429 INT_GET(d->d_blk_softlimit, ARCH_CONVERT));
430#endif
431 return (warned);
432}
433
434
435/*
436 * initialize a buffer full of dquots and log the whole thing 382 * initialize a buffer full of dquots and log the whole thing
437 */ 383 */
438STATIC void 384STATIC void
@@ -461,9 +407,9 @@ xfs_qm_init_dquot_blk(
461 for (i = 0; i < XFS_QM_DQPERBLK(mp); i++, d++, curid++) 407 for (i = 0; i < XFS_QM_DQPERBLK(mp); i++, d++, curid++)
462 xfs_qm_dqinit_core(curid, type, d); 408 xfs_qm_dqinit_core(curid, type, d);
463 xfs_trans_dquot_buf(tp, bp, 409 xfs_trans_dquot_buf(tp, bp,
464 type & XFS_DQ_USER ? 410 (type & XFS_DQ_USER ? XFS_BLI_UDQUOT_BUF :
465 XFS_BLI_UDQUOT_BUF : 411 ((type & XFS_DQ_PROJ) ? XFS_BLI_PDQUOT_BUF :
466 XFS_BLI_GDQUOT_BUF); 412 XFS_BLI_GDQUOT_BUF)));
467 xfs_trans_log_buf(tp, bp, 0, BBTOB(XFS_QI_DQCHUNKLEN(mp)) - 1); 413 xfs_trans_log_buf(tp, bp, 0, BBTOB(XFS_QI_DQCHUNKLEN(mp)) - 1);
468} 414}
469 415
@@ -544,8 +490,7 @@ xfs_qm_dqalloc(
544 * the entire thing. 490 * the entire thing.
545 */ 491 */
546 xfs_qm_init_dquot_blk(tp, mp, INT_GET(dqp->q_core.d_id, ARCH_CONVERT), 492 xfs_qm_init_dquot_blk(tp, mp, INT_GET(dqp->q_core.d_id, ARCH_CONVERT),
547 dqp->dq_flags & (XFS_DQ_USER|XFS_DQ_GROUP), 493 dqp->dq_flags & XFS_DQ_ALLTYPES, bp);
548 bp);
549 494
550 if ((error = xfs_bmap_finish(&tp, &flist, firstblock, &committed))) { 495 if ((error = xfs_bmap_finish(&tp, &flist, firstblock, &committed))) {
551 goto error1; 496 goto error1;
@@ -675,8 +620,7 @@ xfs_qm_dqtobp(
675 /* 620 /*
676 * A simple sanity check in case we got a corrupted dquot... 621 * A simple sanity check in case we got a corrupted dquot...
677 */ 622 */
678 if (xfs_qm_dqcheck(ddq, id, 623 if (xfs_qm_dqcheck(ddq, id, dqp->dq_flags & XFS_DQ_ALLTYPES,
679 dqp->dq_flags & (XFS_DQ_USER|XFS_DQ_GROUP),
680 flags & (XFS_QMOPT_DQREPAIR|XFS_QMOPT_DOWARN), 624 flags & (XFS_QMOPT_DQREPAIR|XFS_QMOPT_DOWARN),
681 "dqtobp")) { 625 "dqtobp")) {
682 if (!(flags & XFS_QMOPT_DQREPAIR)) { 626 if (!(flags & XFS_QMOPT_DQREPAIR)) {
@@ -953,8 +897,8 @@ int
953xfs_qm_dqget( 897xfs_qm_dqget(
954 xfs_mount_t *mp, 898 xfs_mount_t *mp,
955 xfs_inode_t *ip, /* locked inode (optional) */ 899 xfs_inode_t *ip, /* locked inode (optional) */
956 xfs_dqid_t id, /* gid or uid, depending on type */ 900 xfs_dqid_t id, /* uid/projid/gid depending on type */
957 uint type, /* UDQUOT or GDQUOT */ 901 uint type, /* XFS_DQ_USER/XFS_DQ_PROJ/XFS_DQ_GROUP */
958 uint flags, /* DQALLOC, DQSUSER, DQREPAIR, DOWARN */ 902 uint flags, /* DQALLOC, DQSUSER, DQREPAIR, DOWARN */
959 xfs_dquot_t **O_dqpp) /* OUT : locked incore dquot */ 903 xfs_dquot_t **O_dqpp) /* OUT : locked incore dquot */
960{ 904{
@@ -965,6 +909,7 @@ xfs_qm_dqget(
965 909
966 ASSERT(XFS_IS_QUOTA_RUNNING(mp)); 910 ASSERT(XFS_IS_QUOTA_RUNNING(mp));
967 if ((! XFS_IS_UQUOTA_ON(mp) && type == XFS_DQ_USER) || 911 if ((! XFS_IS_UQUOTA_ON(mp) && type == XFS_DQ_USER) ||
912 (! XFS_IS_PQUOTA_ON(mp) && type == XFS_DQ_PROJ) ||
968 (! XFS_IS_GQUOTA_ON(mp) && type == XFS_DQ_GROUP)) { 913 (! XFS_IS_GQUOTA_ON(mp) && type == XFS_DQ_GROUP)) {
969 return (ESRCH); 914 return (ESRCH);
970 } 915 }
@@ -983,7 +928,9 @@ xfs_qm_dqget(
983 again: 928 again:
984 929
985#ifdef DEBUG 930#ifdef DEBUG
986 ASSERT(type == XFS_DQ_USER || type == XFS_DQ_GROUP); 931 ASSERT(type == XFS_DQ_USER ||
932 type == XFS_DQ_PROJ ||
933 type == XFS_DQ_GROUP);
987 if (ip) { 934 if (ip) {
988 ASSERT(XFS_ISLOCKED_INODE_EXCL(ip)); 935 ASSERT(XFS_ISLOCKED_INODE_EXCL(ip));
989 if (type == XFS_DQ_USER) 936 if (type == XFS_DQ_USER)
@@ -1306,8 +1253,8 @@ xfs_qm_dqflush(
1306 return (error); 1253 return (error);
1307 } 1254 }
1308 1255
1309 if (xfs_qm_dqcheck(&dqp->q_core, INT_GET(ddqp->d_id, ARCH_CONVERT), 0, XFS_QMOPT_DOWARN, 1256 if (xfs_qm_dqcheck(&dqp->q_core, INT_GET(ddqp->d_id, ARCH_CONVERT),
1310 "dqflush (incore copy)")) { 1257 0, XFS_QMOPT_DOWARN, "dqflush (incore copy)")) {
1311 xfs_force_shutdown(dqp->q_mount, XFS_CORRUPT_INCORE); 1258 xfs_force_shutdown(dqp->q_mount, XFS_CORRUPT_INCORE);
1312 return XFS_ERROR(EIO); 1259 return XFS_ERROR(EIO);
1313 } 1260 }
@@ -1459,7 +1406,8 @@ xfs_dqlock2(
1459{ 1406{
1460 if (d1 && d2) { 1407 if (d1 && d2) {
1461 ASSERT(d1 != d2); 1408 ASSERT(d1 != d2);
1462 if (INT_GET(d1->q_core.d_id, ARCH_CONVERT) > INT_GET(d2->q_core.d_id, ARCH_CONVERT)) { 1409 if (INT_GET(d1->q_core.d_id, ARCH_CONVERT) >
1410 INT_GET(d2->q_core.d_id, ARCH_CONVERT)) {
1463 xfs_dqlock(d2); 1411 xfs_dqlock(d2);
1464 xfs_dqlock(d1); 1412 xfs_dqlock(d1);
1465 } else { 1413 } else {
@@ -1582,8 +1530,7 @@ xfs_qm_dqprint(xfs_dquot_t *dqp)
1582 cmn_err(CE_DEBUG, "-----------KERNEL DQUOT----------------"); 1530 cmn_err(CE_DEBUG, "-----------KERNEL DQUOT----------------");
1583 cmn_err(CE_DEBUG, "---- dquotID = %d", 1531 cmn_err(CE_DEBUG, "---- dquotID = %d",
1584 (int)INT_GET(dqp->q_core.d_id, ARCH_CONVERT)); 1532 (int)INT_GET(dqp->q_core.d_id, ARCH_CONVERT));
1585 cmn_err(CE_DEBUG, "---- type = %s", 1533 cmn_err(CE_DEBUG, "---- type = %s", DQFLAGTO_TYPESTR(dqp));
1586 XFS_QM_ISUDQ(dqp) ? "USR" : "GRP");
1587 cmn_err(CE_DEBUG, "---- fs = 0x%p", dqp->q_mount); 1534 cmn_err(CE_DEBUG, "---- fs = 0x%p", dqp->q_mount);
1588 cmn_err(CE_DEBUG, "---- blkno = 0x%x", (int) dqp->q_blkno); 1535 cmn_err(CE_DEBUG, "---- blkno = 0x%x", (int) dqp->q_blkno);
1589 cmn_err(CE_DEBUG, "---- boffset = 0x%x", (int) dqp->q_bufoffset); 1536 cmn_err(CE_DEBUG, "---- boffset = 0x%x", (int) dqp->q_bufoffset);
diff --git a/fs/xfs/quota/xfs_dquot.h b/fs/xfs/quota/xfs_dquot.h
index 0c3fe3175baa..39175103c8e0 100644
--- a/fs/xfs/quota/xfs_dquot.h
+++ b/fs/xfs/quota/xfs_dquot.h
@@ -114,25 +114,18 @@ typedef struct xfs_dquot {
114#define XFS_DQHOLD(dqp) ((dqp)->q_nrefs++) 114#define XFS_DQHOLD(dqp) ((dqp)->q_nrefs++)
115 115
116/* 116/*
117 * Quota Accounting flags 117 * Quota Accounting/Enforcement flags
118 */ 118 */
119#define XFS_ALL_QUOTA_ACCT (XFS_UQUOTA_ACCT | XFS_GQUOTA_ACCT) 119#define XFS_ALL_QUOTA_ACCT \
120#define XFS_ALL_QUOTA_ENFD (XFS_UQUOTA_ENFD | XFS_GQUOTA_ENFD) 120 (XFS_UQUOTA_ACCT | XFS_GQUOTA_ACCT | XFS_PQUOTA_ACCT)
121#define XFS_ALL_QUOTA_CHKD (XFS_UQUOTA_CHKD | XFS_GQUOTA_CHKD) 121#define XFS_ALL_QUOTA_ENFD (XFS_UQUOTA_ENFD | XFS_OQUOTA_ENFD)
122#define XFS_ALL_QUOTA_ACTV (XFS_UQUOTA_ACTIVE | XFS_GQUOTA_ACTIVE) 122#define XFS_ALL_QUOTA_CHKD (XFS_UQUOTA_CHKD | XFS_OQUOTA_CHKD)
123#define XFS_ALL_QUOTA_ACCT_ENFD (XFS_UQUOTA_ACCT|XFS_UQUOTA_ENFD|\
124 XFS_GQUOTA_ACCT|XFS_GQUOTA_ENFD)
125 123
126#define XFS_IS_QUOTA_RUNNING(mp) ((mp)->m_qflags & XFS_ALL_QUOTA_ACCT) 124#define XFS_IS_QUOTA_RUNNING(mp) ((mp)->m_qflags & XFS_ALL_QUOTA_ACCT)
127#define XFS_IS_UQUOTA_RUNNING(mp) ((mp)->m_qflags & XFS_UQUOTA_ACCT)
128#define XFS_IS_GQUOTA_RUNNING(mp) ((mp)->m_qflags & XFS_GQUOTA_ACCT)
129
130/*
131 * Quota Limit Enforcement flags
132 */
133#define XFS_IS_QUOTA_ENFORCED(mp) ((mp)->m_qflags & XFS_ALL_QUOTA_ENFD) 125#define XFS_IS_QUOTA_ENFORCED(mp) ((mp)->m_qflags & XFS_ALL_QUOTA_ENFD)
134#define XFS_IS_UQUOTA_ENFORCED(mp) ((mp)->m_qflags & XFS_UQUOTA_ENFD) 126#define XFS_IS_UQUOTA_RUNNING(mp) ((mp)->m_qflags & XFS_UQUOTA_ACCT)
135#define XFS_IS_GQUOTA_ENFORCED(mp) ((mp)->m_qflags & XFS_GQUOTA_ENFD) 127#define XFS_IS_PQUOTA_RUNNING(mp) ((mp)->m_qflags & XFS_PQUOTA_ACCT)
128#define XFS_IS_GQUOTA_RUNNING(mp) ((mp)->m_qflags & XFS_GQUOTA_ACCT)
136 129
137#ifdef DEBUG 130#ifdef DEBUG
138static inline int 131static inline int
@@ -167,6 +160,8 @@ XFS_DQ_IS_LOCKED(xfs_dquot_t *dqp)
167#define XFS_DQ_IS_ON_FREELIST(dqp) ((dqp)->dq_flnext != (dqp)) 160#define XFS_DQ_IS_ON_FREELIST(dqp) ((dqp)->dq_flnext != (dqp))
168#define XFS_DQ_IS_DIRTY(dqp) ((dqp)->dq_flags & XFS_DQ_DIRTY) 161#define XFS_DQ_IS_DIRTY(dqp) ((dqp)->dq_flags & XFS_DQ_DIRTY)
169#define XFS_QM_ISUDQ(dqp) ((dqp)->dq_flags & XFS_DQ_USER) 162#define XFS_QM_ISUDQ(dqp) ((dqp)->dq_flags & XFS_DQ_USER)
163#define XFS_QM_ISPDQ(dqp) ((dqp)->dq_flags & XFS_DQ_PROJ)
164#define XFS_QM_ISGDQ(dqp) ((dqp)->dq_flags & XFS_DQ_GROUP)
170#define XFS_DQ_TO_QINF(dqp) ((dqp)->q_mount->m_quotainfo) 165#define XFS_DQ_TO_QINF(dqp) ((dqp)->q_mount->m_quotainfo)
171#define XFS_DQ_TO_QIP(dqp) (XFS_QM_ISUDQ(dqp) ? \ 166#define XFS_DQ_TO_QIP(dqp) (XFS_QM_ISUDQ(dqp) ? \
172 XFS_DQ_TO_QINF(dqp)->qi_uquotaip : \ 167 XFS_DQ_TO_QINF(dqp)->qi_uquotaip : \
@@ -174,7 +169,7 @@ XFS_DQ_IS_LOCKED(xfs_dquot_t *dqp)
174 169
175#define XFS_IS_THIS_QUOTA_OFF(d) (! (XFS_QM_ISUDQ(d) ? \ 170#define XFS_IS_THIS_QUOTA_OFF(d) (! (XFS_QM_ISUDQ(d) ? \
176 (XFS_IS_UQUOTA_ON((d)->q_mount)) : \ 171 (XFS_IS_UQUOTA_ON((d)->q_mount)) : \
177 (XFS_IS_GQUOTA_ON((d)->q_mount)))) 172 (XFS_IS_OQUOTA_ON((d)->q_mount))))
178 173
179#ifdef XFS_DQUOT_TRACE 174#ifdef XFS_DQUOT_TRACE
180/* 175/*
@@ -211,7 +206,6 @@ extern void xfs_qm_adjust_dqtimers(xfs_mount_t *,
211 xfs_disk_dquot_t *); 206 xfs_disk_dquot_t *);
212extern void xfs_qm_adjust_dqlimits(xfs_mount_t *, 207extern void xfs_qm_adjust_dqlimits(xfs_mount_t *,
213 xfs_disk_dquot_t *); 208 xfs_disk_dquot_t *);
214extern int xfs_qm_dqwarn(xfs_disk_dquot_t *, uint);
215extern int xfs_qm_dqget(xfs_mount_t *, xfs_inode_t *, 209extern int xfs_qm_dqget(xfs_mount_t *, xfs_inode_t *,
216 xfs_dqid_t, uint, uint, xfs_dquot_t **); 210 xfs_dqid_t, uint, uint, xfs_dquot_t **);
217extern void xfs_qm_dqput(xfs_dquot_t *); 211extern void xfs_qm_dqput(xfs_dquot_t *);
diff --git a/fs/xfs/quota/xfs_dquot_item.c b/fs/xfs/quota/xfs_dquot_item.c
index a5425ee6e7bd..f5271b7b1e84 100644
--- a/fs/xfs/quota/xfs_dquot_item.c
+++ b/fs/xfs/quota/xfs_dquot_item.c
@@ -428,7 +428,7 @@ xfs_qm_dquot_logitem_committing(
428/* 428/*
429 * This is the ops vector for dquots 429 * This is the ops vector for dquots
430 */ 430 */
431struct xfs_item_ops xfs_dquot_item_ops = { 431STATIC struct xfs_item_ops xfs_dquot_item_ops = {
432 .iop_size = (uint(*)(xfs_log_item_t*))xfs_qm_dquot_logitem_size, 432 .iop_size = (uint(*)(xfs_log_item_t*))xfs_qm_dquot_logitem_size,
433 .iop_format = (void(*)(xfs_log_item_t*, xfs_log_iovec_t*)) 433 .iop_format = (void(*)(xfs_log_item_t*, xfs_log_iovec_t*))
434 xfs_qm_dquot_logitem_format, 434 xfs_qm_dquot_logitem_format,
@@ -646,7 +646,7 @@ xfs_qm_qoffend_logitem_committing(xfs_qoff_logitem_t *qip, xfs_lsn_t commit_lsn)
646 return; 646 return;
647} 647}
648 648
649struct xfs_item_ops xfs_qm_qoffend_logitem_ops = { 649STATIC struct xfs_item_ops xfs_qm_qoffend_logitem_ops = {
650 .iop_size = (uint(*)(xfs_log_item_t*))xfs_qm_qoff_logitem_size, 650 .iop_size = (uint(*)(xfs_log_item_t*))xfs_qm_qoff_logitem_size,
651 .iop_format = (void(*)(xfs_log_item_t*, xfs_log_iovec_t*)) 651 .iop_format = (void(*)(xfs_log_item_t*, xfs_log_iovec_t*))
652 xfs_qm_qoff_logitem_format, 652 xfs_qm_qoff_logitem_format,
@@ -669,7 +669,7 @@ struct xfs_item_ops xfs_qm_qoffend_logitem_ops = {
669/* 669/*
670 * This is the ops vector shared by all quotaoff-start log items. 670 * This is the ops vector shared by all quotaoff-start log items.
671 */ 671 */
672struct xfs_item_ops xfs_qm_qoff_logitem_ops = { 672STATIC struct xfs_item_ops xfs_qm_qoff_logitem_ops = {
673 .iop_size = (uint(*)(xfs_log_item_t*))xfs_qm_qoff_logitem_size, 673 .iop_size = (uint(*)(xfs_log_item_t*))xfs_qm_qoff_logitem_size,
674 .iop_format = (void(*)(xfs_log_item_t*, xfs_log_iovec_t*)) 674 .iop_format = (void(*)(xfs_log_item_t*, xfs_log_iovec_t*))
675 xfs_qm_qoff_logitem_format, 675 xfs_qm_qoff_logitem_format,
diff --git a/fs/xfs/quota/xfs_qm.c b/fs/xfs/quota/xfs_qm.c
index 89f2cd656ebf..f665ca8f9e96 100644
--- a/fs/xfs/quota/xfs_qm.c
+++ b/fs/xfs/quota/xfs_qm.c
@@ -81,12 +81,18 @@ struct xfs_qm *xfs_Gqm;
81 81
82kmem_zone_t *qm_dqzone; 82kmem_zone_t *qm_dqzone;
83kmem_zone_t *qm_dqtrxzone; 83kmem_zone_t *qm_dqtrxzone;
84kmem_shaker_t xfs_qm_shaker; 84STATIC kmem_shaker_t xfs_qm_shaker;
85 85
86STATIC void xfs_qm_list_init(xfs_dqlist_t *, char *, int); 86STATIC void xfs_qm_list_init(xfs_dqlist_t *, char *, int);
87STATIC void xfs_qm_list_destroy(xfs_dqlist_t *); 87STATIC void xfs_qm_list_destroy(xfs_dqlist_t *);
88 88
89STATIC void xfs_qm_freelist_init(xfs_frlist_t *);
90STATIC void xfs_qm_freelist_destroy(xfs_frlist_t *);
91STATIC int xfs_qm_mplist_nowait(xfs_mount_t *);
92STATIC int xfs_qm_dqhashlock_nowait(xfs_dquot_t *);
93
89STATIC int xfs_qm_init_quotainos(xfs_mount_t *); 94STATIC int xfs_qm_init_quotainos(xfs_mount_t *);
95STATIC int xfs_qm_init_quotainfo(xfs_mount_t *);
90STATIC int xfs_qm_shake(int, unsigned int); 96STATIC int xfs_qm_shake(int, unsigned int);
91 97
92#ifdef DEBUG 98#ifdef DEBUG
@@ -184,7 +190,7 @@ xfs_Gqm_init(void)
184/* 190/*
185 * Destroy the global quota manager when its reference count goes to zero. 191 * Destroy the global quota manager when its reference count goes to zero.
186 */ 192 */
187void 193STATIC void
188xfs_qm_destroy( 194xfs_qm_destroy(
189 struct xfs_qm *xqm) 195 struct xfs_qm *xqm)
190{ 196{
@@ -304,9 +310,9 @@ xfs_qm_mount_quotainit(
304 uint flags) 310 uint flags)
305{ 311{
306 /* 312 /*
307 * User or group quotas has to be on. 313 * User, projects or group quotas has to be on.
308 */ 314 */
309 ASSERT(flags & (XFSMNT_UQUOTA | XFSMNT_GQUOTA)); 315 ASSERT(flags & (XFSMNT_UQUOTA | XFSMNT_PQUOTA | XFSMNT_GQUOTA));
310 316
311 /* 317 /*
312 * Initialize the flags in the mount structure. From this point 318 * Initialize the flags in the mount structure. From this point
@@ -324,7 +330,11 @@ xfs_qm_mount_quotainit(
324 if (flags & XFSMNT_GQUOTA) { 330 if (flags & XFSMNT_GQUOTA) {
325 mp->m_qflags |= (XFS_GQUOTA_ACCT | XFS_GQUOTA_ACTIVE); 331 mp->m_qflags |= (XFS_GQUOTA_ACCT | XFS_GQUOTA_ACTIVE);
326 if (flags & XFSMNT_GQUOTAENF) 332 if (flags & XFSMNT_GQUOTAENF)
327 mp->m_qflags |= XFS_GQUOTA_ENFD; 333 mp->m_qflags |= XFS_OQUOTA_ENFD;
334 } else if (flags & XFSMNT_PQUOTA) {
335 mp->m_qflags |= (XFS_PQUOTA_ACCT | XFS_PQUOTA_ACTIVE);
336 if (flags & XFSMNT_PQUOTAENF)
337 mp->m_qflags |= XFS_OQUOTA_ENFD;
328 } 338 }
329} 339}
330 340
@@ -357,11 +367,11 @@ xfs_qm_mount_quotas(
357 367
358 /* 368 /*
359 * If a file system had quotas running earlier, but decided to 369 * If a file system had quotas running earlier, but decided to
360 * mount without -o quota/uquota/gquota options, revoke the 370 * mount without -o uquota/pquota/gquota options, revoke the
361 * quotachecked license, and bail out. 371 * quotachecked license, and bail out.
362 */ 372 */
363 if (! XFS_IS_QUOTA_ON(mp) && 373 if (! XFS_IS_QUOTA_ON(mp) &&
364 (mp->m_sb.sb_qflags & (XFS_UQUOTA_ACCT|XFS_GQUOTA_ACCT))) { 374 (mp->m_sb.sb_qflags & XFS_ALL_QUOTA_ACCT)) {
365 mp->m_qflags = 0; 375 mp->m_qflags = 0;
366 goto write_changes; 376 goto write_changes;
367 } 377 }
@@ -509,7 +519,7 @@ out:
509 * Flush all dquots of the given file system to disk. The dquots are 519 * Flush all dquots of the given file system to disk. The dquots are
510 * _not_ purged from memory here, just their data written to disk. 520 * _not_ purged from memory here, just their data written to disk.
511 */ 521 */
512int 522STATIC int
513xfs_qm_dqflush_all( 523xfs_qm_dqflush_all(
514 xfs_mount_t *mp, 524 xfs_mount_t *mp,
515 int flags) 525 int flags)
@@ -613,7 +623,7 @@ xfs_qm_detach_gdquots(
613STATIC int 623STATIC int
614xfs_qm_dqpurge_int( 624xfs_qm_dqpurge_int(
615 xfs_mount_t *mp, 625 xfs_mount_t *mp,
616 uint flags) /* QUOTAOFF/UMOUNTING/UQUOTA/GQUOTA */ 626 uint flags) /* QUOTAOFF/UMOUNTING/UQUOTA/PQUOTA/GQUOTA */
617{ 627{
618 xfs_dquot_t *dqp; 628 xfs_dquot_t *dqp;
619 uint dqtype; 629 uint dqtype;
@@ -625,6 +635,7 @@ xfs_qm_dqpurge_int(
625 return (0); 635 return (0);
626 636
627 dqtype = (flags & XFS_QMOPT_UQUOTA) ? XFS_DQ_USER : 0; 637 dqtype = (flags & XFS_QMOPT_UQUOTA) ? XFS_DQ_USER : 0;
638 dqtype |= (flags & XFS_QMOPT_PQUOTA) ? XFS_DQ_PROJ : 0;
628 dqtype |= (flags & XFS_QMOPT_GQUOTA) ? XFS_DQ_GROUP : 0; 639 dqtype |= (flags & XFS_QMOPT_GQUOTA) ? XFS_DQ_GROUP : 0;
629 640
630 xfs_qm_mplist_lock(mp); 641 xfs_qm_mplist_lock(mp);
@@ -734,11 +745,11 @@ xfs_qm_dqattach_one(
734 745
735 /* 746 /*
736 * udqhint is the i_udquot field in inode, and is non-NULL only 747 * udqhint is the i_udquot field in inode, and is non-NULL only
737 * when the type arg is XFS_DQ_GROUP. Its purpose is to save a 748 * when the type arg is group/project. Its purpose is to save a
738 * lookup by dqid (xfs_qm_dqget) by caching a group dquot inside 749 * lookup by dqid (xfs_qm_dqget) by caching a group dquot inside
739 * the user dquot. 750 * the user dquot.
740 */ 751 */
741 ASSERT(!udqhint || type == XFS_DQ_GROUP); 752 ASSERT(!udqhint || type == XFS_DQ_GROUP || type == XFS_DQ_PROJ);
742 if (udqhint && !dolock) 753 if (udqhint && !dolock)
743 xfs_dqlock(udqhint); 754 xfs_dqlock(udqhint);
744 755
@@ -897,8 +908,8 @@ xfs_qm_dqattach_grouphint(
897 908
898 909
899/* 910/*
900 * Given a locked inode, attach dquot(s) to it, taking UQUOTAON / GQUOTAON 911 * Given a locked inode, attach dquot(s) to it, taking U/G/P-QUOTAON
901 * in to account. 912 * into account.
902 * If XFS_QMOPT_DQALLOC, the dquot(s) will be allocated if needed. 913 * If XFS_QMOPT_DQALLOC, the dquot(s) will be allocated if needed.
903 * If XFS_QMOPT_DQLOCK, the dquot(s) will be returned locked. This option pretty 914 * If XFS_QMOPT_DQLOCK, the dquot(s) will be returned locked. This option pretty
904 * much made this code a complete mess, but it has been pretty useful. 915 * much made this code a complete mess, but it has been pretty useful.
@@ -937,8 +948,13 @@ xfs_qm_dqattach(
937 nquotas++; 948 nquotas++;
938 } 949 }
939 ASSERT(XFS_ISLOCKED_INODE_EXCL(ip)); 950 ASSERT(XFS_ISLOCKED_INODE_EXCL(ip));
940 if (XFS_IS_GQUOTA_ON(mp)) { 951 if (XFS_IS_OQUOTA_ON(mp)) {
941 error = xfs_qm_dqattach_one(ip, ip->i_d.di_gid, XFS_DQ_GROUP, 952 error = XFS_IS_GQUOTA_ON(mp) ?
953 xfs_qm_dqattach_one(ip, ip->i_d.di_gid, XFS_DQ_GROUP,
954 flags & XFS_QMOPT_DQALLOC,
955 flags & XFS_QMOPT_DQLOCK,
956 ip->i_udquot, &ip->i_gdquot) :
957 xfs_qm_dqattach_one(ip, ip->i_d.di_projid, XFS_DQ_PROJ,
942 flags & XFS_QMOPT_DQALLOC, 958 flags & XFS_QMOPT_DQALLOC,
943 flags & XFS_QMOPT_DQLOCK, 959 flags & XFS_QMOPT_DQLOCK,
944 ip->i_udquot, &ip->i_gdquot); 960 ip->i_udquot, &ip->i_gdquot);
@@ -989,7 +1005,7 @@ xfs_qm_dqattach(
989 } 1005 }
990 if (XFS_IS_UQUOTA_ON(mp)) 1006 if (XFS_IS_UQUOTA_ON(mp))
991 ASSERT(ip->i_udquot); 1007 ASSERT(ip->i_udquot);
992 if (XFS_IS_GQUOTA_ON(mp)) 1008 if (XFS_IS_OQUOTA_ON(mp))
993 ASSERT(ip->i_gdquot); 1009 ASSERT(ip->i_gdquot);
994 } 1010 }
995#endif 1011#endif
@@ -1018,13 +1034,13 @@ xfs_qm_dqdetach(
1018 1034
1019 ASSERT(ip->i_ino != ip->i_mount->m_sb.sb_uquotino); 1035 ASSERT(ip->i_ino != ip->i_mount->m_sb.sb_uquotino);
1020 ASSERT(ip->i_ino != ip->i_mount->m_sb.sb_gquotino); 1036 ASSERT(ip->i_ino != ip->i_mount->m_sb.sb_gquotino);
1021 if (ip->i_udquot)
1022 xfs_dqtrace_entry_ino(ip->i_udquot, "DQDETTACH", ip);
1023 if (ip->i_udquot) { 1037 if (ip->i_udquot) {
1038 xfs_dqtrace_entry_ino(ip->i_udquot, "DQDETTACH", ip);
1024 xfs_qm_dqrele(ip->i_udquot); 1039 xfs_qm_dqrele(ip->i_udquot);
1025 ip->i_udquot = NULL; 1040 ip->i_udquot = NULL;
1026 } 1041 }
1027 if (ip->i_gdquot) { 1042 if (ip->i_gdquot) {
1043 xfs_dqtrace_entry_ino(ip->i_gdquot, "DQDETTACH", ip);
1028 xfs_qm_dqrele(ip->i_gdquot); 1044 xfs_qm_dqrele(ip->i_gdquot);
1029 ip->i_gdquot = NULL; 1045 ip->i_gdquot = NULL;
1030 } 1046 }
@@ -1149,7 +1165,7 @@ xfs_qm_sync(
1149 * This initializes all the quota information that's kept in the 1165 * This initializes all the quota information that's kept in the
1150 * mount structure 1166 * mount structure
1151 */ 1167 */
1152int 1168STATIC int
1153xfs_qm_init_quotainfo( 1169xfs_qm_init_quotainfo(
1154 xfs_mount_t *mp) 1170 xfs_mount_t *mp)
1155{ 1171{
@@ -1202,8 +1218,9 @@ xfs_qm_init_quotainfo(
1202 * and group quotas, at least not at this point. 1218 * and group quotas, at least not at this point.
1203 */ 1219 */
1204 error = xfs_qm_dqget(mp, NULL, (xfs_dqid_t)0, 1220 error = xfs_qm_dqget(mp, NULL, (xfs_dqid_t)0,
1205 (XFS_IS_UQUOTA_RUNNING(mp)) ? 1221 XFS_IS_UQUOTA_RUNNING(mp) ? XFS_DQ_USER :
1206 XFS_DQ_USER : XFS_DQ_GROUP, 1222 (XFS_IS_GQUOTA_RUNNING(mp) ? XFS_DQ_GROUP :
1223 XFS_DQ_PROJ),
1207 XFS_QMOPT_DQSUSER|XFS_QMOPT_DOWARN, 1224 XFS_QMOPT_DQSUSER|XFS_QMOPT_DOWARN,
1208 &dqp); 1225 &dqp);
1209 if (! error) { 1226 if (! error) {
@@ -1234,6 +1251,10 @@ xfs_qm_init_quotainfo(
1234 INT_GET(ddqp->d_iwarns, ARCH_CONVERT) ? 1251 INT_GET(ddqp->d_iwarns, ARCH_CONVERT) ?
1235 INT_GET(ddqp->d_iwarns, ARCH_CONVERT) : 1252 INT_GET(ddqp->d_iwarns, ARCH_CONVERT) :
1236 XFS_QM_IWARNLIMIT; 1253 XFS_QM_IWARNLIMIT;
1254 qinf->qi_rtbwarnlimit =
1255 INT_GET(ddqp->d_rtbwarns, ARCH_CONVERT) ?
1256 INT_GET(ddqp->d_rtbwarns, ARCH_CONVERT) :
1257 XFS_QM_RTBWARNLIMIT;
1237 qinf->qi_bhardlimit = 1258 qinf->qi_bhardlimit =
1238 INT_GET(ddqp->d_blk_hardlimit, ARCH_CONVERT); 1259 INT_GET(ddqp->d_blk_hardlimit, ARCH_CONVERT);
1239 qinf->qi_bsoftlimit = 1260 qinf->qi_bsoftlimit =
@@ -1259,6 +1280,7 @@ xfs_qm_init_quotainfo(
1259 qinf->qi_rtbtimelimit = XFS_QM_RTBTIMELIMIT; 1280 qinf->qi_rtbtimelimit = XFS_QM_RTBTIMELIMIT;
1260 qinf->qi_bwarnlimit = XFS_QM_BWARNLIMIT; 1281 qinf->qi_bwarnlimit = XFS_QM_BWARNLIMIT;
1261 qinf->qi_iwarnlimit = XFS_QM_IWARNLIMIT; 1282 qinf->qi_iwarnlimit = XFS_QM_IWARNLIMIT;
1283 qinf->qi_rtbwarnlimit = XFS_QM_RTBWARNLIMIT;
1262 } 1284 }
1263 1285
1264 return (0); 1286 return (0);
@@ -1366,13 +1388,20 @@ xfs_qm_dqget_noattach(
1366 ASSERT(udqp); 1388 ASSERT(udqp);
1367 } 1389 }
1368 1390
1369 if (XFS_IS_GQUOTA_ON(mp)) { 1391 if (XFS_IS_OQUOTA_ON(mp)) {
1370 ASSERT(ip->i_gdquot == NULL); 1392 ASSERT(ip->i_gdquot == NULL);
1371 if (udqp) 1393 if (udqp)
1372 xfs_dqunlock(udqp); 1394 xfs_dqunlock(udqp);
1373 if ((error = xfs_qm_dqget(mp, ip, ip->i_d.di_gid, XFS_DQ_GROUP, 1395 error = XFS_IS_GQUOTA_ON(mp) ?
1374 XFS_QMOPT_DQALLOC|XFS_QMOPT_DOWARN, 1396 xfs_qm_dqget(mp, ip,
1375 &gdqp))) { 1397 ip->i_d.di_gid, XFS_DQ_GROUP,
1398 XFS_QMOPT_DQALLOC|XFS_QMOPT_DOWARN,
1399 &gdqp) :
1400 xfs_qm_dqget(mp, ip,
1401 ip->i_d.di_projid, XFS_DQ_PROJ,
1402 XFS_QMOPT_DQALLOC|XFS_QMOPT_DOWARN,
1403 &gdqp);
1404 if (error) {
1376 if (udqp) 1405 if (udqp)
1377 xfs_qm_dqrele(udqp); 1406 xfs_qm_dqrele(udqp);
1378 ASSERT(error != ESRCH); 1407 ASSERT(error != ESRCH);
@@ -1521,8 +1550,10 @@ xfs_qm_reset_dqcounts(
1521 INT_SET(ddq->d_rtbcount, ARCH_CONVERT, 0ULL); 1550 INT_SET(ddq->d_rtbcount, ARCH_CONVERT, 0ULL);
1522 INT_SET(ddq->d_btimer, ARCH_CONVERT, (time_t)0); 1551 INT_SET(ddq->d_btimer, ARCH_CONVERT, (time_t)0);
1523 INT_SET(ddq->d_itimer, ARCH_CONVERT, (time_t)0); 1552 INT_SET(ddq->d_itimer, ARCH_CONVERT, (time_t)0);
1553 INT_SET(ddq->d_rtbtimer, ARCH_CONVERT, (time_t)0);
1524 INT_SET(ddq->d_bwarns, ARCH_CONVERT, 0UL); 1554 INT_SET(ddq->d_bwarns, ARCH_CONVERT, 0UL);
1525 INT_SET(ddq->d_iwarns, ARCH_CONVERT, 0UL); 1555 INT_SET(ddq->d_iwarns, ARCH_CONVERT, 0UL);
1556 INT_SET(ddq->d_rtbwarns, ARCH_CONVERT, 0UL);
1526 ddq = (xfs_disk_dquot_t *) ((xfs_dqblk_t *)ddq + 1); 1557 ddq = (xfs_disk_dquot_t *) ((xfs_dqblk_t *)ddq + 1);
1527 } 1558 }
1528 1559
@@ -1541,11 +1572,14 @@ xfs_qm_dqiter_bufs(
1541 int error; 1572 int error;
1542 int notcommitted; 1573 int notcommitted;
1543 int incr; 1574 int incr;
1575 int type;
1544 1576
1545 ASSERT(blkcnt > 0); 1577 ASSERT(blkcnt > 0);
1546 notcommitted = 0; 1578 notcommitted = 0;
1547 incr = (blkcnt > XFS_QM_MAX_DQCLUSTER_LOGSZ) ? 1579 incr = (blkcnt > XFS_QM_MAX_DQCLUSTER_LOGSZ) ?
1548 XFS_QM_MAX_DQCLUSTER_LOGSZ : blkcnt; 1580 XFS_QM_MAX_DQCLUSTER_LOGSZ : blkcnt;
1581 type = flags & XFS_QMOPT_UQUOTA ? XFS_DQ_USER :
1582 (flags & XFS_QMOPT_PQUOTA ? XFS_DQ_PROJ : XFS_DQ_GROUP);
1549 error = 0; 1583 error = 0;
1550 1584
1551 /* 1585 /*
@@ -1564,9 +1598,7 @@ xfs_qm_dqiter_bufs(
1564 if (error) 1598 if (error)
1565 break; 1599 break;
1566 1600
1567 (void) xfs_qm_reset_dqcounts(mp, bp, firstid, 1601 (void) xfs_qm_reset_dqcounts(mp, bp, firstid, type);
1568 flags & XFS_QMOPT_UQUOTA ?
1569 XFS_DQ_USER : XFS_DQ_GROUP);
1570 xfs_bdwrite(mp, bp); 1602 xfs_bdwrite(mp, bp);
1571 /* 1603 /*
1572 * goto the next block. 1604 * goto the next block.
@@ -1578,7 +1610,7 @@ xfs_qm_dqiter_bufs(
1578} 1610}
1579 1611
1580/* 1612/*
1581 * Iterate over all allocated USR/GRP dquots in the system, calling a 1613 * Iterate over all allocated USR/GRP/PRJ dquots in the system, calling a
1582 * caller supplied function for every chunk of dquots that we find. 1614 * caller supplied function for every chunk of dquots that we find.
1583 */ 1615 */
1584STATIC int 1616STATIC int
@@ -1849,7 +1881,7 @@ xfs_qm_dqusage_adjust(
1849 xfs_qm_quotacheck_dqadjust(udqp, nblks, rtblks); 1881 xfs_qm_quotacheck_dqadjust(udqp, nblks, rtblks);
1850 xfs_qm_dqput(udqp); 1882 xfs_qm_dqput(udqp);
1851 } 1883 }
1852 if (XFS_IS_GQUOTA_ON(mp)) { 1884 if (XFS_IS_OQUOTA_ON(mp)) {
1853 ASSERT(gdqp); 1885 ASSERT(gdqp);
1854 xfs_qm_quotacheck_dqadjust(gdqp, nblks, rtblks); 1886 xfs_qm_quotacheck_dqadjust(gdqp, nblks, rtblks);
1855 xfs_qm_dqput(gdqp); 1887 xfs_qm_dqput(gdqp);
@@ -1898,7 +1930,7 @@ xfs_qm_quotacheck(
1898 cmn_err(CE_NOTE, "XFS quotacheck %s: Please wait.", mp->m_fsname); 1930 cmn_err(CE_NOTE, "XFS quotacheck %s: Please wait.", mp->m_fsname);
1899 1931
1900 /* 1932 /*
1901 * First we go thru all the dquots on disk, USR and GRP, and reset 1933 * First we go thru all the dquots on disk, USR and GRP/PRJ, and reset
1902 * their counters to zero. We need a clean slate. 1934 * their counters to zero. We need a clean slate.
1903 * We don't log our changes till later. 1935 * We don't log our changes till later.
1904 */ 1936 */
@@ -1909,9 +1941,10 @@ xfs_qm_quotacheck(
1909 } 1941 }
1910 1942
1911 if ((gip = XFS_QI_GQIP(mp))) { 1943 if ((gip = XFS_QI_GQIP(mp))) {
1912 if ((error = xfs_qm_dqiterate(mp, gip, XFS_QMOPT_GQUOTA))) 1944 if ((error = xfs_qm_dqiterate(mp, gip, XFS_IS_GQUOTA_ON(mp) ?
1945 XFS_QMOPT_GQUOTA : XFS_QMOPT_PQUOTA)))
1913 goto error_return; 1946 goto error_return;
1914 flags |= XFS_GQUOTA_CHKD; 1947 flags |= XFS_OQUOTA_CHKD;
1915 } 1948 }
1916 1949
1917 do { 1950 do {
@@ -1938,7 +1971,7 @@ xfs_qm_quotacheck(
1938 if (error) { 1971 if (error) {
1939 xfs_qm_dqpurge_all(mp, 1972 xfs_qm_dqpurge_all(mp,
1940 XFS_QMOPT_UQUOTA|XFS_QMOPT_GQUOTA| 1973 XFS_QMOPT_UQUOTA|XFS_QMOPT_GQUOTA|
1941 XFS_QMOPT_QUOTAOFF); 1974 XFS_QMOPT_PQUOTA|XFS_QMOPT_QUOTAOFF);
1942 goto error_return; 1975 goto error_return;
1943 } 1976 }
1944 /* 1977 /*
@@ -1961,7 +1994,7 @@ xfs_qm_quotacheck(
1961 * quotachecked status, since we won't be doing accounting for 1994 * quotachecked status, since we won't be doing accounting for
1962 * that type anymore. 1995 * that type anymore.
1963 */ 1996 */
1964 mp->m_qflags &= ~(XFS_GQUOTA_CHKD | XFS_UQUOTA_CHKD); 1997 mp->m_qflags &= ~(XFS_OQUOTA_CHKD | XFS_UQUOTA_CHKD);
1965 mp->m_qflags |= flags; 1998 mp->m_qflags |= flags;
1966 1999
1967 XQM_LIST_PRINT(&(XFS_QI_MPL_LIST(mp)), MPL_NEXT, "++++ Mp list +++"); 2000 XQM_LIST_PRINT(&(XFS_QI_MPL_LIST(mp)), MPL_NEXT, "++++ Mp list +++");
@@ -2013,7 +2046,7 @@ xfs_qm_init_quotainos(
2013 0, 0, &uip, 0))) 2046 0, 0, &uip, 0)))
2014 return XFS_ERROR(error); 2047 return XFS_ERROR(error);
2015 } 2048 }
2016 if (XFS_IS_GQUOTA_ON(mp) && 2049 if (XFS_IS_OQUOTA_ON(mp) &&
2017 mp->m_sb.sb_gquotino != NULLFSINO) { 2050 mp->m_sb.sb_gquotino != NULLFSINO) {
2018 ASSERT(mp->m_sb.sb_gquotino > 0); 2051 ASSERT(mp->m_sb.sb_gquotino > 0);
2019 if ((error = xfs_iget(mp, NULL, mp->m_sb.sb_gquotino, 2052 if ((error = xfs_iget(mp, NULL, mp->m_sb.sb_gquotino,
@@ -2043,10 +2076,12 @@ xfs_qm_init_quotainos(
2043 2076
2044 flags &= ~XFS_QMOPT_SBVERSION; 2077 flags &= ~XFS_QMOPT_SBVERSION;
2045 } 2078 }
2046 if (XFS_IS_GQUOTA_ON(mp) && gip == NULL) { 2079 if (XFS_IS_OQUOTA_ON(mp) && gip == NULL) {
2047 if ((error = xfs_qm_qino_alloc(mp, &gip, 2080 flags |= (XFS_IS_GQUOTA_ON(mp) ?
2048 sbflags | XFS_SB_GQUOTINO, 2081 XFS_QMOPT_GQUOTA : XFS_QMOPT_PQUOTA);
2049 flags | XFS_QMOPT_GQUOTA))) { 2082 error = xfs_qm_qino_alloc(mp, &gip,
2083 sbflags | XFS_SB_GQUOTINO, flags);
2084 if (error) {
2050 if (uip) 2085 if (uip)
2051 VN_RELE(XFS_ITOV(uip)); 2086 VN_RELE(XFS_ITOV(uip));
2052 2087
@@ -2452,6 +2487,7 @@ xfs_qm_vop_dqalloc(
2452 xfs_inode_t *ip, 2487 xfs_inode_t *ip,
2453 uid_t uid, 2488 uid_t uid,
2454 gid_t gid, 2489 gid_t gid,
2490 prid_t prid,
2455 uint flags, 2491 uint flags,
2456 xfs_dquot_t **O_udqpp, 2492 xfs_dquot_t **O_udqpp,
2457 xfs_dquot_t **O_gdqpp) 2493 xfs_dquot_t **O_gdqpp)
@@ -2483,8 +2519,7 @@ xfs_qm_vop_dqalloc(
2483 } 2519 }
2484 2520
2485 uq = gq = NULL; 2521 uq = gq = NULL;
2486 if ((flags & XFS_QMOPT_UQUOTA) && 2522 if ((flags & XFS_QMOPT_UQUOTA) && XFS_IS_UQUOTA_ON(mp)) {
2487 XFS_IS_UQUOTA_ON(mp)) {
2488 if (ip->i_d.di_uid != uid) { 2523 if (ip->i_d.di_uid != uid) {
2489 /* 2524 /*
2490 * What we need is the dquot that has this uid, and 2525 * What we need is the dquot that has this uid, and
@@ -2522,8 +2557,7 @@ xfs_qm_vop_dqalloc(
2522 xfs_dqunlock(uq); 2557 xfs_dqunlock(uq);
2523 } 2558 }
2524 } 2559 }
2525 if ((flags & XFS_QMOPT_GQUOTA) && 2560 if ((flags & XFS_QMOPT_GQUOTA) && XFS_IS_GQUOTA_ON(mp)) {
2526 XFS_IS_GQUOTA_ON(mp)) {
2527 if (ip->i_d.di_gid != gid) { 2561 if (ip->i_d.di_gid != gid) {
2528 xfs_iunlock(ip, lockflags); 2562 xfs_iunlock(ip, lockflags);
2529 if ((error = xfs_qm_dqget(mp, NULL, (xfs_dqid_t)gid, 2563 if ((error = xfs_qm_dqget(mp, NULL, (xfs_dqid_t)gid,
@@ -2546,6 +2580,29 @@ xfs_qm_vop_dqalloc(
2546 XFS_DQHOLD(gq); 2580 XFS_DQHOLD(gq);
2547 xfs_dqunlock(gq); 2581 xfs_dqunlock(gq);
2548 } 2582 }
2583 } else if ((flags & XFS_QMOPT_PQUOTA) && XFS_IS_PQUOTA_ON(mp)) {
2584 if (ip->i_d.di_projid != prid) {
2585 xfs_iunlock(ip, lockflags);
2586 if ((error = xfs_qm_dqget(mp, NULL, (xfs_dqid_t)prid,
2587 XFS_DQ_PROJ,
2588 XFS_QMOPT_DQALLOC |
2589 XFS_QMOPT_DOWARN,
2590 &gq))) {
2591 if (uq)
2592 xfs_qm_dqrele(uq);
2593 ASSERT(error != ENOENT);
2594 return (error);
2595 }
2596 xfs_dqunlock(gq);
2597 lockflags = XFS_ILOCK_SHARED;
2598 xfs_ilock(ip, lockflags);
2599 } else {
2600 ASSERT(ip->i_gdquot);
2601 gq = ip->i_gdquot;
2602 xfs_dqlock(gq);
2603 XFS_DQHOLD(gq);
2604 xfs_dqunlock(gq);
2605 }
2549 } 2606 }
2550 if (uq) 2607 if (uq)
2551 xfs_dqtrace_entry_ino(uq, "DQALLOC", ip); 2608 xfs_dqtrace_entry_ino(uq, "DQALLOC", ip);
@@ -2574,6 +2631,9 @@ xfs_qm_vop_chown(
2574 xfs_dquot_t *newdq) 2631 xfs_dquot_t *newdq)
2575{ 2632{
2576 xfs_dquot_t *prevdq; 2633 xfs_dquot_t *prevdq;
2634 uint bfield = XFS_IS_REALTIME_INODE(ip) ?
2635 XFS_TRANS_DQ_RTBCOUNT : XFS_TRANS_DQ_BCOUNT;
2636
2577 ASSERT(XFS_ISLOCKED_INODE_EXCL(ip)); 2637 ASSERT(XFS_ISLOCKED_INODE_EXCL(ip));
2578 ASSERT(XFS_IS_QUOTA_RUNNING(ip->i_mount)); 2638 ASSERT(XFS_IS_QUOTA_RUNNING(ip->i_mount));
2579 2639
@@ -2582,20 +2642,12 @@ xfs_qm_vop_chown(
2582 ASSERT(prevdq); 2642 ASSERT(prevdq);
2583 ASSERT(prevdq != newdq); 2643 ASSERT(prevdq != newdq);
2584 2644
2585 xfs_trans_mod_dquot(tp, prevdq, 2645 xfs_trans_mod_dquot(tp, prevdq, bfield, -(ip->i_d.di_nblocks));
2586 XFS_TRANS_DQ_BCOUNT, 2646 xfs_trans_mod_dquot(tp, prevdq, XFS_TRANS_DQ_ICOUNT, -1);
2587 -(ip->i_d.di_nblocks));
2588 xfs_trans_mod_dquot(tp, prevdq,
2589 XFS_TRANS_DQ_ICOUNT,
2590 -1);
2591 2647
2592 /* the sparkling new dquot */ 2648 /* the sparkling new dquot */
2593 xfs_trans_mod_dquot(tp, newdq, 2649 xfs_trans_mod_dquot(tp, newdq, bfield, ip->i_d.di_nblocks);
2594 XFS_TRANS_DQ_BCOUNT, 2650 xfs_trans_mod_dquot(tp, newdq, XFS_TRANS_DQ_ICOUNT, 1);
2595 ip->i_d.di_nblocks);
2596 xfs_trans_mod_dquot(tp, newdq,
2597 XFS_TRANS_DQ_ICOUNT,
2598 1);
2599 2651
2600 /* 2652 /*
2601 * Take an extra reference, because the inode 2653 * Take an extra reference, because the inode
@@ -2611,7 +2663,7 @@ xfs_qm_vop_chown(
2611} 2663}
2612 2664
2613/* 2665/*
2614 * Quota reservations for setattr(AT_UID|AT_GID). 2666 * Quota reservations for setattr(AT_UID|AT_GID|AT_PROJID).
2615 */ 2667 */
2616int 2668int
2617xfs_qm_vop_chown_reserve( 2669xfs_qm_vop_chown_reserve(
@@ -2623,7 +2675,7 @@ xfs_qm_vop_chown_reserve(
2623{ 2675{
2624 int error; 2676 int error;
2625 xfs_mount_t *mp; 2677 xfs_mount_t *mp;
2626 uint delblks; 2678 uint delblks, blkflags;
2627 xfs_dquot_t *unresudq, *unresgdq, *delblksudq, *delblksgdq; 2679 xfs_dquot_t *unresudq, *unresgdq, *delblksudq, *delblksgdq;
2628 2680
2629 ASSERT(XFS_ISLOCKED_INODE(ip)); 2681 ASSERT(XFS_ISLOCKED_INODE(ip));
@@ -2632,6 +2684,8 @@ xfs_qm_vop_chown_reserve(
2632 2684
2633 delblks = ip->i_delayed_blks; 2685 delblks = ip->i_delayed_blks;
2634 delblksudq = delblksgdq = unresudq = unresgdq = NULL; 2686 delblksudq = delblksgdq = unresudq = unresgdq = NULL;
2687 blkflags = XFS_IS_REALTIME_INODE(ip) ?
2688 XFS_QMOPT_RES_RTBLKS : XFS_QMOPT_RES_REGBLKS;
2635 2689
2636 if (XFS_IS_UQUOTA_ON(mp) && udqp && 2690 if (XFS_IS_UQUOTA_ON(mp) && udqp &&
2637 ip->i_d.di_uid != (uid_t)INT_GET(udqp->q_core.d_id, ARCH_CONVERT)) { 2691 ip->i_d.di_uid != (uid_t)INT_GET(udqp->q_core.d_id, ARCH_CONVERT)) {
@@ -2646,18 +2700,22 @@ xfs_qm_vop_chown_reserve(
2646 unresudq = ip->i_udquot; 2700 unresudq = ip->i_udquot;
2647 } 2701 }
2648 } 2702 }
2649 if (XFS_IS_GQUOTA_ON(ip->i_mount) && gdqp && 2703 if (XFS_IS_OQUOTA_ON(ip->i_mount) && gdqp) {
2650 ip->i_d.di_gid != INT_GET(gdqp->q_core.d_id, ARCH_CONVERT)) { 2704 if ((XFS_IS_GQUOTA_ON(ip->i_mount) && ip->i_d.di_gid !=
2651 delblksgdq = gdqp; 2705 INT_GET(gdqp->q_core.d_id, ARCH_CONVERT)) ||
2652 if (delblks) { 2706 (XFS_IS_PQUOTA_ON(ip->i_mount) && ip->i_d.di_projid !=
2653 ASSERT(ip->i_gdquot); 2707 INT_GET(gdqp->q_core.d_id, ARCH_CONVERT))) {
2654 unresgdq = ip->i_gdquot; 2708 delblksgdq = gdqp;
2709 if (delblks) {
2710 ASSERT(ip->i_gdquot);
2711 unresgdq = ip->i_gdquot;
2712 }
2655 } 2713 }
2656 } 2714 }
2657 2715
2658 if ((error = xfs_trans_reserve_quota_bydquots(tp, ip->i_mount, 2716 if ((error = xfs_trans_reserve_quota_bydquots(tp, ip->i_mount,
2659 delblksudq, delblksgdq, ip->i_d.di_nblocks, 1, 2717 delblksudq, delblksgdq, ip->i_d.di_nblocks, 1,
2660 flags | XFS_QMOPT_RES_REGBLKS))) 2718 flags | blkflags)))
2661 return (error); 2719 return (error);
2662 2720
2663 /* 2721 /*
@@ -2674,11 +2732,11 @@ xfs_qm_vop_chown_reserve(
2674 ASSERT(unresudq || unresgdq); 2732 ASSERT(unresudq || unresgdq);
2675 if ((error = xfs_trans_reserve_quota_bydquots(NULL, ip->i_mount, 2733 if ((error = xfs_trans_reserve_quota_bydquots(NULL, ip->i_mount,
2676 delblksudq, delblksgdq, (xfs_qcnt_t)delblks, 0, 2734 delblksudq, delblksgdq, (xfs_qcnt_t)delblks, 0,
2677 flags | XFS_QMOPT_RES_REGBLKS))) 2735 flags | blkflags)))
2678 return (error); 2736 return (error);
2679 xfs_trans_reserve_quota_bydquots(NULL, ip->i_mount, 2737 xfs_trans_reserve_quota_bydquots(NULL, ip->i_mount,
2680 unresudq, unresgdq, -((xfs_qcnt_t)delblks), 0, 2738 unresudq, unresgdq, -((xfs_qcnt_t)delblks), 0,
2681 XFS_QMOPT_RES_REGBLKS); 2739 blkflags);
2682 } 2740 }
2683 2741
2684 return (0); 2742 return (0);
@@ -2751,7 +2809,7 @@ xfs_qm_vop_dqattach_and_dqmod_newinode(
2751} 2809}
2752 2810
2753/* ------------- list stuff -----------------*/ 2811/* ------------- list stuff -----------------*/
2754void 2812STATIC void
2755xfs_qm_freelist_init(xfs_frlist_t *ql) 2813xfs_qm_freelist_init(xfs_frlist_t *ql)
2756{ 2814{
2757 ql->qh_next = ql->qh_prev = (xfs_dquot_t *) ql; 2815 ql->qh_next = ql->qh_prev = (xfs_dquot_t *) ql;
@@ -2760,7 +2818,7 @@ xfs_qm_freelist_init(xfs_frlist_t *ql)
2760 ql->qh_nelems = 0; 2818 ql->qh_nelems = 0;
2761} 2819}
2762 2820
2763void 2821STATIC void
2764xfs_qm_freelist_destroy(xfs_frlist_t *ql) 2822xfs_qm_freelist_destroy(xfs_frlist_t *ql)
2765{ 2823{
2766 xfs_dquot_t *dqp, *nextdqp; 2824 xfs_dquot_t *dqp, *nextdqp;
@@ -2786,7 +2844,7 @@ xfs_qm_freelist_destroy(xfs_frlist_t *ql)
2786 ASSERT(ql->qh_nelems == 0); 2844 ASSERT(ql->qh_nelems == 0);
2787} 2845}
2788 2846
2789void 2847STATIC void
2790xfs_qm_freelist_insert(xfs_frlist_t *ql, xfs_dquot_t *dq) 2848xfs_qm_freelist_insert(xfs_frlist_t *ql, xfs_dquot_t *dq)
2791{ 2849{
2792 dq->dq_flnext = ql->qh_next; 2850 dq->dq_flnext = ql->qh_next;
@@ -2816,7 +2874,7 @@ xfs_qm_freelist_append(xfs_frlist_t *ql, xfs_dquot_t *dq)
2816 xfs_qm_freelist_insert((xfs_frlist_t *)ql->qh_prev, dq); 2874 xfs_qm_freelist_insert((xfs_frlist_t *)ql->qh_prev, dq);
2817} 2875}
2818 2876
2819int 2877STATIC int
2820xfs_qm_dqhashlock_nowait( 2878xfs_qm_dqhashlock_nowait(
2821 xfs_dquot_t *dqp) 2879 xfs_dquot_t *dqp)
2822{ 2880{
@@ -2836,7 +2894,7 @@ xfs_qm_freelist_lock_nowait(
2836 return (locked); 2894 return (locked);
2837} 2895}
2838 2896
2839int 2897STATIC int
2840xfs_qm_mplist_nowait( 2898xfs_qm_mplist_nowait(
2841 xfs_mount_t *mp) 2899 xfs_mount_t *mp)
2842{ 2900{
diff --git a/fs/xfs/quota/xfs_qm.h b/fs/xfs/quota/xfs_qm.h
index dcf1a7a831d8..b03eecf3b6cb 100644
--- a/fs/xfs/quota/xfs_qm.h
+++ b/fs/xfs/quota/xfs_qm.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2000-2004 Silicon Graphics, Inc. All Rights Reserved. 2 * Copyright (c) 2000-2005 Silicon Graphics, Inc. All Rights Reserved.
3 * 3 *
4 * This program is free software; you can redistribute it and/or modify it 4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of version 2 of the GNU General Public License as 5 * under the terms of version 2 of the GNU General Public License as
@@ -133,8 +133,9 @@ typedef struct xfs_quotainfo {
133 time_t qi_btimelimit; /* limit for blks timer */ 133 time_t qi_btimelimit; /* limit for blks timer */
134 time_t qi_itimelimit; /* limit for inodes timer */ 134 time_t qi_itimelimit; /* limit for inodes timer */
135 time_t qi_rtbtimelimit;/* limit for rt blks timer */ 135 time_t qi_rtbtimelimit;/* limit for rt blks timer */
136 xfs_qwarncnt_t qi_bwarnlimit; /* limit for num warnings */ 136 xfs_qwarncnt_t qi_bwarnlimit; /* limit for blks warnings */
137 xfs_qwarncnt_t qi_iwarnlimit; /* limit for num warnings */ 137 xfs_qwarncnt_t qi_iwarnlimit; /* limit for inodes warnings */
138 xfs_qwarncnt_t qi_rtbwarnlimit;/* limit for rt blks warnings */
138 mutex_t qi_quotaofflock;/* to serialize quotaoff */ 139 mutex_t qi_quotaofflock;/* to serialize quotaoff */
139 xfs_filblks_t qi_dqchunklen; /* # BBs in a chunk of dqs */ 140 xfs_filblks_t qi_dqchunklen; /* # BBs in a chunk of dqs */
140 uint qi_dqperchunk; /* # ondisk dqs in above chunk */ 141 uint qi_dqperchunk; /* # ondisk dqs in above chunk */
@@ -176,6 +177,7 @@ typedef struct xfs_dquot_acct {
176 177
177#define XFS_QM_BWARNLIMIT 5 178#define XFS_QM_BWARNLIMIT 5
178#define XFS_QM_IWARNLIMIT 5 179#define XFS_QM_IWARNLIMIT 5
180#define XFS_QM_RTBWARNLIMIT 5
179 181
180#define XFS_QM_LOCK(xqm) (mutex_lock(&xqm##_lock, PINOD)) 182#define XFS_QM_LOCK(xqm) (mutex_lock(&xqm##_lock, PINOD))
181#define XFS_QM_UNLOCK(xqm) (mutex_unlock(&xqm##_lock)) 183#define XFS_QM_UNLOCK(xqm) (mutex_unlock(&xqm##_lock))
@@ -184,7 +186,6 @@ typedef struct xfs_dquot_acct {
184 186
185extern void xfs_mount_reset_sbqflags(xfs_mount_t *); 187extern void xfs_mount_reset_sbqflags(xfs_mount_t *);
186 188
187extern int xfs_qm_init_quotainfo(xfs_mount_t *);
188extern void xfs_qm_destroy_quotainfo(xfs_mount_t *); 189extern void xfs_qm_destroy_quotainfo(xfs_mount_t *);
189extern int xfs_qm_mount_quotas(xfs_mount_t *, int); 190extern int xfs_qm_mount_quotas(xfs_mount_t *, int);
190extern void xfs_qm_mount_quotainit(xfs_mount_t *, uint); 191extern void xfs_qm_mount_quotainit(xfs_mount_t *, uint);
@@ -203,7 +204,7 @@ extern void xfs_qm_dqrele_all_inodes(xfs_mount_t *, uint);
203 204
204/* vop stuff */ 205/* vop stuff */
205extern int xfs_qm_vop_dqalloc(xfs_mount_t *, xfs_inode_t *, 206extern int xfs_qm_vop_dqalloc(xfs_mount_t *, xfs_inode_t *,
206 uid_t, gid_t, uint, 207 uid_t, gid_t, prid_t, uint,
207 xfs_dquot_t **, xfs_dquot_t **); 208 xfs_dquot_t **, xfs_dquot_t **);
208extern void xfs_qm_vop_dqattach_and_dqmod_newinode( 209extern void xfs_qm_vop_dqattach_and_dqmod_newinode(
209 xfs_trans_t *, xfs_inode_t *, 210 xfs_trans_t *, xfs_inode_t *,
@@ -215,14 +216,9 @@ extern int xfs_qm_vop_chown_reserve(xfs_trans_t *, xfs_inode_t *,
215 xfs_dquot_t *, xfs_dquot_t *, uint); 216 xfs_dquot_t *, xfs_dquot_t *, uint);
216 217
217/* list stuff */ 218/* list stuff */
218extern void xfs_qm_freelist_init(xfs_frlist_t *);
219extern void xfs_qm_freelist_destroy(xfs_frlist_t *);
220extern void xfs_qm_freelist_insert(xfs_frlist_t *, xfs_dquot_t *);
221extern void xfs_qm_freelist_append(xfs_frlist_t *, xfs_dquot_t *); 219extern void xfs_qm_freelist_append(xfs_frlist_t *, xfs_dquot_t *);
222extern void xfs_qm_freelist_unlink(xfs_dquot_t *); 220extern void xfs_qm_freelist_unlink(xfs_dquot_t *);
223extern int xfs_qm_freelist_lock_nowait(xfs_qm_t *); 221extern int xfs_qm_freelist_lock_nowait(xfs_qm_t *);
224extern int xfs_qm_mplist_nowait(xfs_mount_t *);
225extern int xfs_qm_dqhashlock_nowait(xfs_dquot_t *);
226 222
227/* system call interface */ 223/* system call interface */
228extern int xfs_qm_quotactl(bhv_desc_t *, int, int, xfs_caddr_t); 224extern int xfs_qm_quotactl(bhv_desc_t *, int, int, xfs_caddr_t);
diff --git a/fs/xfs/quota/xfs_qm_bhv.c b/fs/xfs/quota/xfs_qm_bhv.c
index be67d9c265f8..dc3c37a1e158 100644
--- a/fs/xfs/quota/xfs_qm_bhv.c
+++ b/fs/xfs/quota/xfs_qm_bhv.c
@@ -71,10 +71,13 @@
71#define MNTOPT_NOQUOTA "noquota" /* no quotas */ 71#define MNTOPT_NOQUOTA "noquota" /* no quotas */
72#define MNTOPT_USRQUOTA "usrquota" /* user quota enabled */ 72#define MNTOPT_USRQUOTA "usrquota" /* user quota enabled */
73#define MNTOPT_GRPQUOTA "grpquota" /* group quota enabled */ 73#define MNTOPT_GRPQUOTA "grpquota" /* group quota enabled */
74#define MNTOPT_PRJQUOTA "prjquota" /* project quota enabled */
74#define MNTOPT_UQUOTA "uquota" /* user quota (IRIX variant) */ 75#define MNTOPT_UQUOTA "uquota" /* user quota (IRIX variant) */
75#define MNTOPT_GQUOTA "gquota" /* group quota (IRIX variant) */ 76#define MNTOPT_GQUOTA "gquota" /* group quota (IRIX variant) */
77#define MNTOPT_PQUOTA "pquota" /* project quota (IRIX variant) */
76#define MNTOPT_UQUOTANOENF "uqnoenforce"/* user quota limit enforcement */ 78#define MNTOPT_UQUOTANOENF "uqnoenforce"/* user quota limit enforcement */
77#define MNTOPT_GQUOTANOENF "gqnoenforce"/* group quota limit enforcement */ 79#define MNTOPT_GQUOTANOENF "gqnoenforce"/* group quota limit enforcement */
80#define MNTOPT_PQUOTANOENF "pqnoenforce"/* project quota limit enforcement */
78#define MNTOPT_QUOTANOENF "qnoenforce" /* same as uqnoenforce */ 81#define MNTOPT_QUOTANOENF "qnoenforce" /* same as uqnoenforce */
79 82
80STATIC int 83STATIC int
@@ -109,6 +112,14 @@ xfs_qm_parseargs(
109 args->flags |= XFSMNT_UQUOTA; 112 args->flags |= XFSMNT_UQUOTA;
110 args->flags &= ~XFSMNT_UQUOTAENF; 113 args->flags &= ~XFSMNT_UQUOTAENF;
111 referenced = 1; 114 referenced = 1;
115 } else if (!strcmp(this_char, MNTOPT_PQUOTA) ||
116 !strcmp(this_char, MNTOPT_PRJQUOTA)) {
117 args->flags |= XFSMNT_PQUOTA | XFSMNT_PQUOTAENF;
118 referenced = 1;
119 } else if (!strcmp(this_char, MNTOPT_PQUOTANOENF)) {
120 args->flags |= XFSMNT_PQUOTA;
121 args->flags &= ~XFSMNT_PQUOTAENF;
122 referenced = 1;
112 } else if (!strcmp(this_char, MNTOPT_GQUOTA) || 123 } else if (!strcmp(this_char, MNTOPT_GQUOTA) ||
113 !strcmp(this_char, MNTOPT_GRPQUOTA)) { 124 !strcmp(this_char, MNTOPT_GRPQUOTA)) {
114 args->flags |= XFSMNT_GQUOTA | XFSMNT_GQUOTAENF; 125 args->flags |= XFSMNT_GQUOTA | XFSMNT_GQUOTAENF;
@@ -127,6 +138,12 @@ xfs_qm_parseargs(
127 *this_char++ = ','; 138 *this_char++ = ',';
128 } 139 }
129 140
141 if ((args->flags & XFSMNT_GQUOTA) && (args->flags & XFSMNT_PQUOTA)) {
142 cmn_err(CE_WARN,
143 "XFS: cannot mount with both project and group quota");
144 return XFS_ERROR(EINVAL);
145 }
146
130 PVFS_PARSEARGS(BHV_NEXT(bhv), options, args, update, error); 147 PVFS_PARSEARGS(BHV_NEXT(bhv), options, args, update, error);
131 if (!error && !referenced) 148 if (!error && !referenced)
132 bhv_remove_vfsops(bhvtovfs(bhv), VFS_POSITION_QM); 149 bhv_remove_vfsops(bhvtovfs(bhv), VFS_POSITION_QM);
@@ -148,13 +165,19 @@ xfs_qm_showargs(
148 seq_puts(m, "," MNTOPT_UQUOTANOENF); 165 seq_puts(m, "," MNTOPT_UQUOTANOENF);
149 } 166 }
150 167
168 if (mp->m_qflags & XFS_PQUOTA_ACCT) {
169 (mp->m_qflags & XFS_OQUOTA_ENFD) ?
170 seq_puts(m, "," MNTOPT_PRJQUOTA) :
171 seq_puts(m, "," MNTOPT_PQUOTANOENF);
172 }
173
151 if (mp->m_qflags & XFS_GQUOTA_ACCT) { 174 if (mp->m_qflags & XFS_GQUOTA_ACCT) {
152 (mp->m_qflags & XFS_GQUOTA_ENFD) ? 175 (mp->m_qflags & XFS_OQUOTA_ENFD) ?
153 seq_puts(m, "," MNTOPT_GRPQUOTA) : 176 seq_puts(m, "," MNTOPT_GRPQUOTA) :
154 seq_puts(m, "," MNTOPT_GQUOTANOENF); 177 seq_puts(m, "," MNTOPT_GQUOTANOENF);
155 } 178 }
156 179
157 if (!(mp->m_qflags & (XFS_UQUOTA_ACCT|XFS_GQUOTA_ACCT))) 180 if (!(mp->m_qflags & XFS_ALL_QUOTA_ACCT))
158 seq_puts(m, "," MNTOPT_NOQUOTA); 181 seq_puts(m, "," MNTOPT_NOQUOTA);
159 182
160 PVFS_SHOWARGS(BHV_NEXT(bhv), m, error); 183 PVFS_SHOWARGS(BHV_NEXT(bhv), m, error);
@@ -171,7 +194,7 @@ xfs_qm_mount(
171 struct xfs_mount *mp = XFS_VFSTOM(vfsp); 194 struct xfs_mount *mp = XFS_VFSTOM(vfsp);
172 int error; 195 int error;
173 196
174 if (args->flags & (XFSMNT_UQUOTA | XFSMNT_GQUOTA)) 197 if (args->flags & (XFSMNT_UQUOTA | XFSMNT_GQUOTA | XFSMNT_PQUOTA))
175 xfs_qm_mount_quotainit(mp, args->flags); 198 xfs_qm_mount_quotainit(mp, args->flags);
176 PVFS_MOUNT(BHV_NEXT(bhv), args, cr, error); 199 PVFS_MOUNT(BHV_NEXT(bhv), args, cr, error);
177 return error; 200 return error;
@@ -255,16 +278,17 @@ xfs_qm_newmount(
255 uint *quotaflags) 278 uint *quotaflags)
256{ 279{
257 uint quotaondisk; 280 uint quotaondisk;
258 uint uquotaondisk = 0, gquotaondisk = 0; 281 uint uquotaondisk = 0, gquotaondisk = 0, pquotaondisk = 0;
259 282
260 *quotaflags = 0; 283 *quotaflags = 0;
261 *needquotamount = B_FALSE; 284 *needquotamount = B_FALSE;
262 285
263 quotaondisk = XFS_SB_VERSION_HASQUOTA(&mp->m_sb) && 286 quotaondisk = XFS_SB_VERSION_HASQUOTA(&mp->m_sb) &&
264 mp->m_sb.sb_qflags & (XFS_UQUOTA_ACCT|XFS_GQUOTA_ACCT); 287 (mp->m_sb.sb_qflags & XFS_ALL_QUOTA_ACCT);
265 288
266 if (quotaondisk) { 289 if (quotaondisk) {
267 uquotaondisk = mp->m_sb.sb_qflags & XFS_UQUOTA_ACCT; 290 uquotaondisk = mp->m_sb.sb_qflags & XFS_UQUOTA_ACCT;
291 pquotaondisk = mp->m_sb.sb_qflags & XFS_PQUOTA_ACCT;
268 gquotaondisk = mp->m_sb.sb_qflags & XFS_GQUOTA_ACCT; 292 gquotaondisk = mp->m_sb.sb_qflags & XFS_GQUOTA_ACCT;
269 } 293 }
270 294
@@ -277,13 +301,16 @@ xfs_qm_newmount(
277 301
278 if (((uquotaondisk && !XFS_IS_UQUOTA_ON(mp)) || 302 if (((uquotaondisk && !XFS_IS_UQUOTA_ON(mp)) ||
279 (!uquotaondisk && XFS_IS_UQUOTA_ON(mp)) || 303 (!uquotaondisk && XFS_IS_UQUOTA_ON(mp)) ||
304 (pquotaondisk && !XFS_IS_PQUOTA_ON(mp)) ||
305 (!pquotaondisk && XFS_IS_PQUOTA_ON(mp)) ||
280 (gquotaondisk && !XFS_IS_GQUOTA_ON(mp)) || 306 (gquotaondisk && !XFS_IS_GQUOTA_ON(mp)) ||
281 (!gquotaondisk && XFS_IS_GQUOTA_ON(mp))) && 307 (!gquotaondisk && XFS_IS_OQUOTA_ON(mp))) &&
282 xfs_dev_is_read_only(mp, "changing quota state")) { 308 xfs_dev_is_read_only(mp, "changing quota state")) {
283 cmn_err(CE_WARN, 309 cmn_err(CE_WARN,
284 "XFS: please mount with%s%s%s.", 310 "XFS: please mount with%s%s%s%s.",
285 (!quotaondisk ? "out quota" : ""), 311 (!quotaondisk ? "out quota" : ""),
286 (uquotaondisk ? " usrquota" : ""), 312 (uquotaondisk ? " usrquota" : ""),
313 (pquotaondisk ? " prjquota" : ""),
287 (gquotaondisk ? " grpquota" : "")); 314 (gquotaondisk ? " grpquota" : ""));
288 return XFS_ERROR(EPERM); 315 return XFS_ERROR(EPERM);
289 } 316 }
@@ -359,7 +386,7 @@ xfs_qm_dqrele_null(
359} 386}
360 387
361 388
362struct xfs_qmops xfs_qmcore_xfs = { 389STATIC struct xfs_qmops xfs_qmcore_xfs = {
363 .xfs_qminit = xfs_qm_newmount, 390 .xfs_qminit = xfs_qm_newmount,
364 .xfs_qmdone = xfs_qm_unmount_quotadestroy, 391 .xfs_qmdone = xfs_qm_unmount_quotadestroy,
365 .xfs_qmmount = xfs_qm_endmount, 392 .xfs_qmmount = xfs_qm_endmount,
diff --git a/fs/xfs/quota/xfs_qm_syscalls.c b/fs/xfs/quota/xfs_qm_syscalls.c
index 229f5b5a2d25..68e98962dbef 100644
--- a/fs/xfs/quota/xfs_qm_syscalls.c
+++ b/fs/xfs/quota/xfs_qm_syscalls.c
@@ -118,40 +118,41 @@ xfs_qm_quotactl(
118 * The following commands are valid even when quotaoff. 118 * The following commands are valid even when quotaoff.
119 */ 119 */
120 switch (cmd) { 120 switch (cmd) {
121 case Q_XQUOTARM:
121 /* 122 /*
122 * truncate quota files. quota must be off. 123 * Truncate quota files. quota must be off.
123 */ 124 */
124 case Q_XQUOTARM:
125 if (XFS_IS_QUOTA_ON(mp) || addr == NULL) 125 if (XFS_IS_QUOTA_ON(mp) || addr == NULL)
126 return XFS_ERROR(EINVAL); 126 return XFS_ERROR(EINVAL);
127 if (vfsp->vfs_flag & VFS_RDONLY) 127 if (vfsp->vfs_flag & VFS_RDONLY)
128 return XFS_ERROR(EROFS); 128 return XFS_ERROR(EROFS);
129 return (xfs_qm_scall_trunc_qfiles(mp, 129 return (xfs_qm_scall_trunc_qfiles(mp,
130 xfs_qm_import_qtype_flags(*(uint *)addr))); 130 xfs_qm_import_qtype_flags(*(uint *)addr)));
131
132 case Q_XGETQSTAT:
131 /* 133 /*
132 * Get quota status information. 134 * Get quota status information.
133 */ 135 */
134 case Q_XGETQSTAT:
135 return (xfs_qm_scall_getqstat(mp, (fs_quota_stat_t *)addr)); 136 return (xfs_qm_scall_getqstat(mp, (fs_quota_stat_t *)addr));
136 137
138 case Q_XQUOTAON:
137 /* 139 /*
138 * QUOTAON for root f/s and quota enforcement on others.. 140 * QUOTAON - enabling quota enforcement.
139 * Quota accounting for non-root f/s's must be turned on 141 * Quota accounting must be turned on at mount time.
140 * at mount time.
141 */ 142 */
142 case Q_XQUOTAON:
143 if (addr == NULL) 143 if (addr == NULL)
144 return XFS_ERROR(EINVAL); 144 return XFS_ERROR(EINVAL);
145 if (vfsp->vfs_flag & VFS_RDONLY) 145 if (vfsp->vfs_flag & VFS_RDONLY)
146 return XFS_ERROR(EROFS); 146 return XFS_ERROR(EROFS);
147 return (xfs_qm_scall_quotaon(mp, 147 return (xfs_qm_scall_quotaon(mp,
148 xfs_qm_import_flags(*(uint *)addr))); 148 xfs_qm_import_flags(*(uint *)addr)));
149 case Q_XQUOTAOFF: 149
150 case Q_XQUOTAOFF:
150 if (vfsp->vfs_flag & VFS_RDONLY) 151 if (vfsp->vfs_flag & VFS_RDONLY)
151 return XFS_ERROR(EROFS); 152 return XFS_ERROR(EROFS);
152 break; 153 break;
153 154
154 default: 155 default:
155 break; 156 break;
156 } 157 }
157 158
@@ -159,7 +160,7 @@ xfs_qm_quotactl(
159 return XFS_ERROR(ESRCH); 160 return XFS_ERROR(ESRCH);
160 161
161 switch (cmd) { 162 switch (cmd) {
162 case Q_XQUOTAOFF: 163 case Q_XQUOTAOFF:
163 if (vfsp->vfs_flag & VFS_RDONLY) 164 if (vfsp->vfs_flag & VFS_RDONLY)
164 return XFS_ERROR(EROFS); 165 return XFS_ERROR(EROFS);
165 error = xfs_qm_scall_quotaoff(mp, 166 error = xfs_qm_scall_quotaoff(mp,
@@ -167,42 +168,39 @@ xfs_qm_quotactl(
167 B_FALSE); 168 B_FALSE);
168 break; 169 break;
169 170
170 /* 171 case Q_XGETQUOTA:
171 * Defaults to XFS_GETUQUOTA.
172 */
173 case Q_XGETQUOTA:
174 error = xfs_qm_scall_getquota(mp, (xfs_dqid_t)id, XFS_DQ_USER, 172 error = xfs_qm_scall_getquota(mp, (xfs_dqid_t)id, XFS_DQ_USER,
175 (fs_disk_quota_t *)addr); 173 (fs_disk_quota_t *)addr);
176 break; 174 break;
177 /* 175 case Q_XGETGQUOTA:
178 * Set limits, both hard and soft. Defaults to Q_SETUQLIM. 176 error = xfs_qm_scall_getquota(mp, (xfs_dqid_t)id, XFS_DQ_GROUP,
179 */ 177 (fs_disk_quota_t *)addr);
180 case Q_XSETQLIM: 178 break;
179 case Q_XGETPQUOTA:
180 error = xfs_qm_scall_getquota(mp, (xfs_dqid_t)id, XFS_DQ_PROJ,
181 (fs_disk_quota_t *)addr);
182 break;
183
184 case Q_XSETQLIM:
181 if (vfsp->vfs_flag & VFS_RDONLY) 185 if (vfsp->vfs_flag & VFS_RDONLY)
182 return XFS_ERROR(EROFS); 186 return XFS_ERROR(EROFS);
183 error = xfs_qm_scall_setqlim(mp, (xfs_dqid_t)id, XFS_DQ_USER, 187 error = xfs_qm_scall_setqlim(mp, (xfs_dqid_t)id, XFS_DQ_USER,
184 (fs_disk_quota_t *)addr); 188 (fs_disk_quota_t *)addr);
185 break; 189 break;
186 190 case Q_XSETGQLIM:
187 case Q_XSETGQLIM:
188 if (vfsp->vfs_flag & VFS_RDONLY) 191 if (vfsp->vfs_flag & VFS_RDONLY)
189 return XFS_ERROR(EROFS); 192 return XFS_ERROR(EROFS);
190 error = xfs_qm_scall_setqlim(mp, (xfs_dqid_t)id, XFS_DQ_GROUP, 193 error = xfs_qm_scall_setqlim(mp, (xfs_dqid_t)id, XFS_DQ_GROUP,
191 (fs_disk_quota_t *)addr); 194 (fs_disk_quota_t *)addr);
192 break; 195 break;
193 196 case Q_XSETPQLIM:
194 197 if (vfsp->vfs_flag & VFS_RDONLY)
195 case Q_XGETGQUOTA: 198 return XFS_ERROR(EROFS);
196 error = xfs_qm_scall_getquota(mp, (xfs_dqid_t)id, XFS_DQ_GROUP, 199 error = xfs_qm_scall_setqlim(mp, (xfs_dqid_t)id, XFS_DQ_PROJ,
197 (fs_disk_quota_t *)addr); 200 (fs_disk_quota_t *)addr);
198 break; 201 break;
199 202
200 /* 203 default:
201 * Quotas are entirely undefined after quotaoff in XFS quotas.
202 * For instance, there's no way to set limits when quotaoff.
203 */
204
205 default:
206 error = XFS_ERROR(EINVAL); 204 error = XFS_ERROR(EINVAL);
207 break; 205 break;
208 } 206 }
@@ -286,8 +284,12 @@ xfs_qm_scall_quotaoff(
286 } 284 }
287 if (flags & XFS_GQUOTA_ACCT) { 285 if (flags & XFS_GQUOTA_ACCT) {
288 dqtype |= XFS_QMOPT_GQUOTA; 286 dqtype |= XFS_QMOPT_GQUOTA;
289 flags |= (XFS_GQUOTA_CHKD | XFS_GQUOTA_ENFD); 287 flags |= (XFS_OQUOTA_CHKD | XFS_OQUOTA_ENFD);
290 inactivate_flags |= XFS_GQUOTA_ACTIVE; 288 inactivate_flags |= XFS_GQUOTA_ACTIVE;
289 } else if (flags & XFS_PQUOTA_ACCT) {
290 dqtype |= XFS_QMOPT_PQUOTA;
291 flags |= (XFS_OQUOTA_CHKD | XFS_OQUOTA_ENFD);
292 inactivate_flags |= XFS_PQUOTA_ACTIVE;
291 } 293 }
292 294
293 /* 295 /*
@@ -364,7 +366,8 @@ xfs_qm_scall_quotaoff(
364 /* 366 /*
365 * If quotas is completely disabled, close shop. 367 * If quotas is completely disabled, close shop.
366 */ 368 */
367 if ((flags & XFS_MOUNT_QUOTA_ALL) == XFS_MOUNT_QUOTA_ALL) { 369 if (((flags & XFS_MOUNT_QUOTA_ALL) == XFS_MOUNT_QUOTA_SET1) ||
370 ((flags & XFS_MOUNT_QUOTA_ALL) == XFS_MOUNT_QUOTA_SET2)) {
368 mutex_unlock(&(XFS_QI_QOFFLOCK(mp))); 371 mutex_unlock(&(XFS_QI_QOFFLOCK(mp)));
369 xfs_qm_destroy_quotainfo(mp); 372 xfs_qm_destroy_quotainfo(mp);
370 return (0); 373 return (0);
@@ -378,7 +381,7 @@ xfs_qm_scall_quotaoff(
378 XFS_PURGE_INODE(XFS_QI_UQIP(mp)); 381 XFS_PURGE_INODE(XFS_QI_UQIP(mp));
379 XFS_QI_UQIP(mp) = NULL; 382 XFS_QI_UQIP(mp) = NULL;
380 } 383 }
381 if ((dqtype & XFS_QMOPT_GQUOTA) && XFS_QI_GQIP(mp)) { 384 if ((dqtype & (XFS_QMOPT_GQUOTA|XFS_QMOPT_PQUOTA)) && XFS_QI_GQIP(mp)) {
382 XFS_PURGE_INODE(XFS_QI_GQIP(mp)); 385 XFS_PURGE_INODE(XFS_QI_GQIP(mp));
383 XFS_QI_GQIP(mp) = NULL; 386 XFS_QI_GQIP(mp) = NULL;
384 } 387 }
@@ -411,7 +414,8 @@ xfs_qm_scall_trunc_qfiles(
411 } 414 }
412 } 415 }
413 416
414 if ((flags & XFS_DQ_GROUP) && mp->m_sb.sb_gquotino != NULLFSINO) { 417 if ((flags & (XFS_DQ_GROUP|XFS_DQ_PROJ)) &&
418 mp->m_sb.sb_gquotino != NULLFSINO) {
415 error = xfs_iget(mp, NULL, mp->m_sb.sb_gquotino, 0, 0, &qip, 0); 419 error = xfs_iget(mp, NULL, mp->m_sb.sb_gquotino, 0, 0, &qip, 0);
416 if (! error) { 420 if (! error) {
417 (void) xfs_truncate_file(mp, qip); 421 (void) xfs_truncate_file(mp, qip);
@@ -434,7 +438,7 @@ xfs_qm_scall_quotaon(
434 uint flags) 438 uint flags)
435{ 439{
436 int error; 440 int error;
437 unsigned long s; 441 unsigned long s;
438 uint qf; 442 uint qf;
439 uint accflags; 443 uint accflags;
440 __int64_t sbflags; 444 __int64_t sbflags;
@@ -468,9 +472,13 @@ xfs_qm_scall_quotaon(
468 (mp->m_sb.sb_qflags & XFS_UQUOTA_ACCT) == 0 && 472 (mp->m_sb.sb_qflags & XFS_UQUOTA_ACCT) == 0 &&
469 (flags & XFS_UQUOTA_ENFD)) 473 (flags & XFS_UQUOTA_ENFD))
470 || 474 ||
475 ((flags & XFS_PQUOTA_ACCT) == 0 &&
476 (mp->m_sb.sb_qflags & XFS_PQUOTA_ACCT) == 0 &&
477 (flags & XFS_OQUOTA_ENFD))
478 ||
471 ((flags & XFS_GQUOTA_ACCT) == 0 && 479 ((flags & XFS_GQUOTA_ACCT) == 0 &&
472 (mp->m_sb.sb_qflags & XFS_GQUOTA_ACCT) == 0 && 480 (mp->m_sb.sb_qflags & XFS_GQUOTA_ACCT) == 0 &&
473 (flags & XFS_GQUOTA_ENFD))) { 481 (flags & XFS_OQUOTA_ENFD))) {
474 qdprintk("Can't enforce without acct, flags=%x sbflags=%x\n", 482 qdprintk("Can't enforce without acct, flags=%x sbflags=%x\n",
475 flags, mp->m_sb.sb_qflags); 483 flags, mp->m_sb.sb_qflags);
476 return XFS_ERROR(EINVAL); 484 return XFS_ERROR(EINVAL);
@@ -504,6 +512,10 @@ xfs_qm_scall_quotaon(
504 */ 512 */
505 if (((mp->m_sb.sb_qflags & XFS_UQUOTA_ACCT) != 513 if (((mp->m_sb.sb_qflags & XFS_UQUOTA_ACCT) !=
506 (mp->m_qflags & XFS_UQUOTA_ACCT)) || 514 (mp->m_qflags & XFS_UQUOTA_ACCT)) ||
515 ((mp->m_sb.sb_qflags & XFS_PQUOTA_ACCT) !=
516 (mp->m_qflags & XFS_PQUOTA_ACCT)) ||
517 ((mp->m_sb.sb_qflags & XFS_GQUOTA_ACCT) !=
518 (mp->m_qflags & XFS_GQUOTA_ACCT)) ||
507 (flags & XFS_ALL_QUOTA_ENFD) == 0) 519 (flags & XFS_ALL_QUOTA_ENFD) == 0)
508 return (0); 520 return (0);
509 521
@@ -521,7 +533,6 @@ xfs_qm_scall_quotaon(
521} 533}
522 534
523 535
524
525/* 536/*
526 * Return quota status information, such as uquota-off, enforcements, etc. 537 * Return quota status information, such as uquota-off, enforcements, etc.
527 */ 538 */
@@ -606,7 +617,8 @@ xfs_qm_scall_setqlim(
606 if (!capable(CAP_SYS_ADMIN)) 617 if (!capable(CAP_SYS_ADMIN))
607 return XFS_ERROR(EPERM); 618 return XFS_ERROR(EPERM);
608 619
609 if ((newlim->d_fieldmask & (FS_DQ_LIMIT_MASK|FS_DQ_TIMER_MASK)) == 0) 620 if ((newlim->d_fieldmask &
621 (FS_DQ_LIMIT_MASK|FS_DQ_TIMER_MASK|FS_DQ_WARNS_MASK)) == 0)
610 return (0); 622 return (0);
611 623
612 tp = xfs_trans_alloc(mp, XFS_TRANS_QM_SETQLIM); 624 tp = xfs_trans_alloc(mp, XFS_TRANS_QM_SETQLIM);
@@ -691,12 +703,23 @@ xfs_qm_scall_setqlim(
691 qdprintk("ihard %Ld < isoft %Ld\n", hard, soft); 703 qdprintk("ihard %Ld < isoft %Ld\n", hard, soft);
692 } 704 }
693 705
706 /*
707 * Update warnings counter(s) if requested
708 */
709 if (newlim->d_fieldmask & FS_DQ_BWARNS)
710 INT_SET(ddq->d_bwarns, ARCH_CONVERT, newlim->d_bwarns);
711 if (newlim->d_fieldmask & FS_DQ_IWARNS)
712 INT_SET(ddq->d_iwarns, ARCH_CONVERT, newlim->d_iwarns);
713 if (newlim->d_fieldmask & FS_DQ_RTBWARNS)
714 INT_SET(ddq->d_rtbwarns, ARCH_CONVERT, newlim->d_rtbwarns);
715
694 if (id == 0) { 716 if (id == 0) {
695 /* 717 /*
696 * Timelimits for the super user set the relative time 718 * Timelimits for the super user set the relative time
697 * the other users can be over quota for this file system. 719 * the other users can be over quota for this file system.
698 * If it is zero a default is used. Ditto for the default 720 * If it is zero a default is used. Ditto for the default
699 * soft and hard limit values (already done, above). 721 * soft and hard limit values (already done, above), and
722 * for warnings.
700 */ 723 */
701 if (newlim->d_fieldmask & FS_DQ_BTIMER) { 724 if (newlim->d_fieldmask & FS_DQ_BTIMER) {
702 mp->m_quotainfo->qi_btimelimit = newlim->d_btimer; 725 mp->m_quotainfo->qi_btimelimit = newlim->d_btimer;
@@ -710,7 +733,13 @@ xfs_qm_scall_setqlim(
710 mp->m_quotainfo->qi_rtbtimelimit = newlim->d_rtbtimer; 733 mp->m_quotainfo->qi_rtbtimelimit = newlim->d_rtbtimer;
711 INT_SET(ddq->d_rtbtimer, ARCH_CONVERT, newlim->d_rtbtimer); 734 INT_SET(ddq->d_rtbtimer, ARCH_CONVERT, newlim->d_rtbtimer);
712 } 735 }
713 } else /* if (XFS_IS_QUOTA_ENFORCED(mp)) */ { 736 if (newlim->d_fieldmask & FS_DQ_BWARNS)
737 mp->m_quotainfo->qi_bwarnlimit = newlim->d_bwarns;
738 if (newlim->d_fieldmask & FS_DQ_IWARNS)
739 mp->m_quotainfo->qi_iwarnlimit = newlim->d_iwarns;
740 if (newlim->d_fieldmask & FS_DQ_RTBWARNS)
741 mp->m_quotainfo->qi_rtbwarnlimit = newlim->d_rtbwarns;
742 } else {
714 /* 743 /*
715 * If the user is now over quota, start the timelimit. 744 * If the user is now over quota, start the timelimit.
716 * The user will not be 'warned'. 745 * The user will not be 'warned'.
@@ -776,9 +805,9 @@ xfs_qm_log_quotaoff_end(
776 xfs_qoff_logitem_t *startqoff, 805 xfs_qoff_logitem_t *startqoff,
777 uint flags) 806 uint flags)
778{ 807{
779 xfs_trans_t *tp; 808 xfs_trans_t *tp;
780 int error; 809 int error;
781 xfs_qoff_logitem_t *qoffi; 810 xfs_qoff_logitem_t *qoffi;
782 811
783 tp = xfs_trans_alloc(mp, XFS_TRANS_QM_QUOTAOFF_END); 812 tp = xfs_trans_alloc(mp, XFS_TRANS_QM_QUOTAOFF_END);
784 813
@@ -928,18 +957,26 @@ xfs_qm_export_dquot(
928 957
929STATIC uint 958STATIC uint
930xfs_qm_import_qtype_flags( 959xfs_qm_import_qtype_flags(
931 uint uflags) 960 uint uflags)
932{ 961{
962 uint oflags = 0;
963
933 /* 964 /*
934 * Can't be both at the same time. 965 * Can't be more than one, or none.
935 */ 966 */
936 if (((uflags & (XFS_GROUP_QUOTA | XFS_USER_QUOTA)) == 967 if (((uflags & (XFS_GROUP_QUOTA | XFS_USER_QUOTA)) ==
937 (XFS_GROUP_QUOTA | XFS_USER_QUOTA)) || 968 (XFS_GROUP_QUOTA | XFS_USER_QUOTA)) ||
938 ((uflags & (XFS_GROUP_QUOTA | XFS_USER_QUOTA)) == 0)) 969 ((uflags & (XFS_GROUP_QUOTA | XFS_PROJ_QUOTA)) ==
970 (XFS_GROUP_QUOTA | XFS_PROJ_QUOTA)) ||
971 ((uflags & (XFS_USER_QUOTA | XFS_PROJ_QUOTA)) ==
972 (XFS_USER_QUOTA | XFS_PROJ_QUOTA)) ||
973 ((uflags & (XFS_GROUP_QUOTA|XFS_USER_QUOTA|XFS_PROJ_QUOTA)) == 0))
939 return (0); 974 return (0);
940 975
941 return (uflags & XFS_USER_QUOTA) ? 976 oflags |= (uflags & XFS_USER_QUOTA) ? XFS_DQ_USER : 0;
942 XFS_DQ_USER : XFS_DQ_GROUP; 977 oflags |= (uflags & XFS_PROJ_QUOTA) ? XFS_DQ_PROJ : 0;
978 oflags |= (uflags & XFS_GROUP_QUOTA) ? XFS_DQ_GROUP: 0;
979 return oflags;
943} 980}
944 981
945STATIC uint 982STATIC uint
@@ -947,14 +984,19 @@ xfs_qm_export_qtype_flags(
947 uint flags) 984 uint flags)
948{ 985{
949 /* 986 /*
950 * Can't be both at the same time. 987 * Can't be more than one, or none.
951 */ 988 */
952 ASSERT((flags & (XFS_GROUP_QUOTA | XFS_USER_QUOTA)) != 989 ASSERT((flags & (XFS_PROJ_QUOTA | XFS_USER_QUOTA)) !=
953 (XFS_GROUP_QUOTA | XFS_USER_QUOTA)); 990 (XFS_PROJ_QUOTA | XFS_USER_QUOTA));
954 ASSERT((flags & (XFS_GROUP_QUOTA | XFS_USER_QUOTA)) != 0); 991 ASSERT((flags & (XFS_PROJ_QUOTA | XFS_GROUP_QUOTA)) !=
992 (XFS_PROJ_QUOTA | XFS_GROUP_QUOTA));
993 ASSERT((flags & (XFS_USER_QUOTA | XFS_GROUP_QUOTA)) !=
994 (XFS_USER_QUOTA | XFS_GROUP_QUOTA));
995 ASSERT((flags & (XFS_PROJ_QUOTA|XFS_USER_QUOTA|XFS_GROUP_QUOTA)) != 0);
955 996
956 return (flags & XFS_DQ_USER) ? 997 return (flags & XFS_DQ_USER) ?
957 XFS_USER_QUOTA : XFS_GROUP_QUOTA; 998 XFS_USER_QUOTA : (flags & XFS_DQ_PROJ) ?
999 XFS_PROJ_QUOTA : XFS_GROUP_QUOTA;
958} 1000}
959 1001
960STATIC uint 1002STATIC uint
@@ -965,12 +1007,14 @@ xfs_qm_import_flags(
965 1007
966 if (uflags & XFS_QUOTA_UDQ_ACCT) 1008 if (uflags & XFS_QUOTA_UDQ_ACCT)
967 flags |= XFS_UQUOTA_ACCT; 1009 flags |= XFS_UQUOTA_ACCT;
1010 if (uflags & XFS_QUOTA_PDQ_ACCT)
1011 flags |= XFS_PQUOTA_ACCT;
968 if (uflags & XFS_QUOTA_GDQ_ACCT) 1012 if (uflags & XFS_QUOTA_GDQ_ACCT)
969 flags |= XFS_GQUOTA_ACCT; 1013 flags |= XFS_GQUOTA_ACCT;
970 if (uflags & XFS_QUOTA_UDQ_ENFD) 1014 if (uflags & XFS_QUOTA_UDQ_ENFD)
971 flags |= XFS_UQUOTA_ENFD; 1015 flags |= XFS_UQUOTA_ENFD;
972 if (uflags & XFS_QUOTA_GDQ_ENFD) 1016 if (uflags & (XFS_QUOTA_PDQ_ENFD|XFS_QUOTA_GDQ_ENFD))
973 flags |= XFS_GQUOTA_ENFD; 1017 flags |= XFS_OQUOTA_ENFD;
974 return (flags); 1018 return (flags);
975} 1019}
976 1020
@@ -984,12 +1028,16 @@ xfs_qm_export_flags(
984 uflags = 0; 1028 uflags = 0;
985 if (flags & XFS_UQUOTA_ACCT) 1029 if (flags & XFS_UQUOTA_ACCT)
986 uflags |= XFS_QUOTA_UDQ_ACCT; 1030 uflags |= XFS_QUOTA_UDQ_ACCT;
1031 if (flags & XFS_PQUOTA_ACCT)
1032 uflags |= XFS_QUOTA_PDQ_ACCT;
987 if (flags & XFS_GQUOTA_ACCT) 1033 if (flags & XFS_GQUOTA_ACCT)
988 uflags |= XFS_QUOTA_GDQ_ACCT; 1034 uflags |= XFS_QUOTA_GDQ_ACCT;
989 if (flags & XFS_UQUOTA_ENFD) 1035 if (flags & XFS_UQUOTA_ENFD)
990 uflags |= XFS_QUOTA_UDQ_ENFD; 1036 uflags |= XFS_QUOTA_UDQ_ENFD;
991 if (flags & XFS_GQUOTA_ENFD) 1037 if (flags & (XFS_OQUOTA_ENFD)) {
992 uflags |= XFS_QUOTA_GDQ_ENFD; 1038 uflags |= (flags & XFS_GQUOTA_ACCT) ?
1039 XFS_QUOTA_GDQ_ENFD : XFS_QUOTA_PDQ_ENFD;
1040 }
993 return (uflags); 1041 return (uflags);
994} 1042}
995 1043
@@ -1070,7 +1118,7 @@ again:
1070 xfs_qm_dqrele(ip->i_udquot); 1118 xfs_qm_dqrele(ip->i_udquot);
1071 ip->i_udquot = NULL; 1119 ip->i_udquot = NULL;
1072 } 1120 }
1073 if ((flags & XFS_GQUOTA_ACCT) && ip->i_gdquot) { 1121 if (flags & (XFS_PQUOTA_ACCT|XFS_GQUOTA_ACCT) && ip->i_gdquot) {
1074 xfs_qm_dqrele(ip->i_gdquot); 1122 xfs_qm_dqrele(ip->i_gdquot);
1075 ip->i_gdquot = NULL; 1123 ip->i_gdquot = NULL;
1076 } 1124 }
@@ -1160,7 +1208,6 @@ xfs_qm_dqtest_print(
1160{ 1208{
1161 cmn_err(CE_DEBUG, "-----------DQTEST DQUOT----------------"); 1209 cmn_err(CE_DEBUG, "-----------DQTEST DQUOT----------------");
1162 cmn_err(CE_DEBUG, "---- dquot ID = %d", d->d_id); 1210 cmn_err(CE_DEBUG, "---- dquot ID = %d", d->d_id);
1163 cmn_err(CE_DEBUG, "---- type = %s", XFS_QM_ISUDQ(d)? "USR" : "GRP");
1164 cmn_err(CE_DEBUG, "---- fs = 0x%p", d->q_mount); 1211 cmn_err(CE_DEBUG, "---- fs = 0x%p", d->q_mount);
1165 cmn_err(CE_DEBUG, "---- bcount = %Lu (0x%x)", 1212 cmn_err(CE_DEBUG, "---- bcount = %Lu (0x%x)",
1166 d->d_bcount, (int)d->d_bcount); 1213 d->d_bcount, (int)d->d_bcount);
@@ -1231,7 +1278,7 @@ xfs_dqtest_cmp2(
1231#ifdef QUOTADEBUG 1278#ifdef QUOTADEBUG
1232 if (!err) { 1279 if (!err) {
1233 cmn_err(CE_DEBUG, "%d [%s] [0x%p] qchecked", 1280 cmn_err(CE_DEBUG, "%d [%s] [0x%p] qchecked",
1234 d->d_id, XFS_QM_ISUDQ(d) ? "USR" : "GRP", d->q_mount); 1281 d->d_id, DQFLAGTO_TYPESTR(d), d->q_mount);
1235 } 1282 }
1236#endif 1283#endif
1237 return (err); 1284 return (err);
@@ -1287,6 +1334,7 @@ STATIC void
1287xfs_qm_internalqcheck_get_dquots( 1334xfs_qm_internalqcheck_get_dquots(
1288 xfs_mount_t *mp, 1335 xfs_mount_t *mp,
1289 xfs_dqid_t uid, 1336 xfs_dqid_t uid,
1337 xfs_dqid_t projid,
1290 xfs_dqid_t gid, 1338 xfs_dqid_t gid,
1291 xfs_dqtest_t **ud, 1339 xfs_dqtest_t **ud,
1292 xfs_dqtest_t **gd) 1340 xfs_dqtest_t **gd)
@@ -1295,6 +1343,8 @@ xfs_qm_internalqcheck_get_dquots(
1295 xfs_qm_internalqcheck_dqget(mp, uid, XFS_DQ_USER, ud); 1343 xfs_qm_internalqcheck_dqget(mp, uid, XFS_DQ_USER, ud);
1296 if (XFS_IS_GQUOTA_ON(mp)) 1344 if (XFS_IS_GQUOTA_ON(mp))
1297 xfs_qm_internalqcheck_dqget(mp, gid, XFS_DQ_GROUP, gd); 1345 xfs_qm_internalqcheck_dqget(mp, gid, XFS_DQ_GROUP, gd);
1346 else if (XFS_IS_PQUOTA_ON(mp))
1347 xfs_qm_internalqcheck_dqget(mp, projid, XFS_DQ_PROJ, gd);
1298} 1348}
1299 1349
1300 1350
@@ -1362,13 +1412,14 @@ xfs_qm_internalqcheck_adjust(
1362 } 1412 }
1363 xfs_qm_internalqcheck_get_dquots(mp, 1413 xfs_qm_internalqcheck_get_dquots(mp,
1364 (xfs_dqid_t) ip->i_d.di_uid, 1414 (xfs_dqid_t) ip->i_d.di_uid,
1415 (xfs_dqid_t) ip->i_d.di_projid,
1365 (xfs_dqid_t) ip->i_d.di_gid, 1416 (xfs_dqid_t) ip->i_d.di_gid,
1366 &ud, &gd); 1417 &ud, &gd);
1367 if (XFS_IS_UQUOTA_ON(mp)) { 1418 if (XFS_IS_UQUOTA_ON(mp)) {
1368 ASSERT(ud); 1419 ASSERT(ud);
1369 xfs_qm_internalqcheck_dqadjust(ip, ud); 1420 xfs_qm_internalqcheck_dqadjust(ip, ud);
1370 } 1421 }
1371 if (XFS_IS_GQUOTA_ON(mp)) { 1422 if (XFS_IS_OQUOTA_ON(mp)) {
1372 ASSERT(gd); 1423 ASSERT(gd);
1373 xfs_qm_internalqcheck_dqadjust(ip, gd); 1424 xfs_qm_internalqcheck_dqadjust(ip, gd);
1374 } 1425 }
diff --git a/fs/xfs/quota/xfs_quota_priv.h b/fs/xfs/quota/xfs_quota_priv.h
index 414b6004af21..bf413e70ec07 100644
--- a/fs/xfs/quota/xfs_quota_priv.h
+++ b/fs/xfs/quota/xfs_quota_priv.h
@@ -56,6 +56,7 @@
56#define XFS_QI_RTBTIMELIMIT(mp) ((mp)->m_quotainfo->qi_rtbtimelimit) 56#define XFS_QI_RTBTIMELIMIT(mp) ((mp)->m_quotainfo->qi_rtbtimelimit)
57#define XFS_QI_ITIMELIMIT(mp) ((mp)->m_quotainfo->qi_itimelimit) 57#define XFS_QI_ITIMELIMIT(mp) ((mp)->m_quotainfo->qi_itimelimit)
58#define XFS_QI_BWARNLIMIT(mp) ((mp)->m_quotainfo->qi_bwarnlimit) 58#define XFS_QI_BWARNLIMIT(mp) ((mp)->m_quotainfo->qi_bwarnlimit)
59#define XFS_QI_RTBWARNLIMIT(mp) ((mp)->m_quotainfo->qi_rtbwarnlimit)
59#define XFS_QI_IWARNLIMIT(mp) ((mp)->m_quotainfo->qi_iwarnlimit) 60#define XFS_QI_IWARNLIMIT(mp) ((mp)->m_quotainfo->qi_iwarnlimit)
60#define XFS_QI_QOFFLOCK(mp) ((mp)->m_quotainfo->qi_quotaofflock) 61#define XFS_QI_QOFFLOCK(mp) ((mp)->m_quotainfo->qi_quotaofflock)
61 62
@@ -102,7 +103,8 @@ static inline int XQMISLCKD(struct xfs_dqhash *h)
102 (xfs_Gqm->qm_grp_dqhtable + \ 103 (xfs_Gqm->qm_grp_dqhtable + \
103 XFS_DQ_HASHVAL(mp, id))) 104 XFS_DQ_HASHVAL(mp, id)))
104#define XFS_IS_DQTYPE_ON(mp, type) (type == XFS_DQ_USER ? \ 105#define XFS_IS_DQTYPE_ON(mp, type) (type == XFS_DQ_USER ? \
105 XFS_IS_UQUOTA_ON(mp):XFS_IS_GQUOTA_ON(mp)) 106 XFS_IS_UQUOTA_ON(mp) : \
107 XFS_IS_OQUOTA_ON(mp))
106#define XFS_IS_DQUOT_UNINITIALIZED(dqp) ( \ 108#define XFS_IS_DQUOT_UNINITIALIZED(dqp) ( \
107 !dqp->q_core.d_blk_hardlimit && \ 109 !dqp->q_core.d_blk_hardlimit && \
108 !dqp->q_core.d_blk_softlimit && \ 110 !dqp->q_core.d_blk_softlimit && \
@@ -177,16 +179,11 @@ for ((dqp) = (qlist)->qh_next; (dqp) != (xfs_dquot_t *)(qlist); \
177 (!((dqp)->q_core.d_id)) 179 (!((dqp)->q_core.d_id))
178 180
179#define XFS_PURGE_INODE(ip) \ 181#define XFS_PURGE_INODE(ip) \
180 { \ 182 IRELE(ip);
181 vmap_t dqvmap; \
182 vnode_t *dqvp; \
183 dqvp = XFS_ITOV(ip); \
184 VMAP(dqvp, dqvmap); \
185 VN_RELE(dqvp); \
186 }
187 183
188#define DQFLAGTO_TYPESTR(d) (((d)->dq_flags & XFS_DQ_USER) ? "USR" : \ 184#define DQFLAGTO_TYPESTR(d) (((d)->dq_flags & XFS_DQ_USER) ? "USR" : \
189 (((d)->dq_flags & XFS_DQ_GROUP) ? "GRP" : "???")) 185 (((d)->dq_flags & XFS_DQ_GROUP) ? "GRP" : \
186 (((d)->dq_flags & XFS_DQ_PROJ) ? "PRJ":"???")))
190#define DQFLAGTO_DIRTYSTR(d) (XFS_DQ_IS_DIRTY(d) ? "DIRTY" : "NOTDIRTY") 187#define DQFLAGTO_DIRTYSTR(d) (XFS_DQ_IS_DIRTY(d) ? "DIRTY" : "NOTDIRTY")
191 188
192#endif /* __XFS_QUOTA_PRIV_H__ */ 189#endif /* __XFS_QUOTA_PRIV_H__ */
diff --git a/fs/xfs/quota/xfs_trans_dquot.c b/fs/xfs/quota/xfs_trans_dquot.c
index 149b2a1fd949..3b99daf8a640 100644
--- a/fs/xfs/quota/xfs_trans_dquot.c
+++ b/fs/xfs/quota/xfs_trans_dquot.c
@@ -187,7 +187,7 @@ xfs_trans_dup_dqinfo(
187/* 187/*
188 * Wrap around mod_dquot to account for both user and group quotas. 188 * Wrap around mod_dquot to account for both user and group quotas.
189 */ 189 */
190void 190STATIC void
191xfs_trans_mod_dquot_byino( 191xfs_trans_mod_dquot_byino(
192 xfs_trans_t *tp, 192 xfs_trans_t *tp,
193 xfs_inode_t *ip, 193 xfs_inode_t *ip,
@@ -207,12 +207,10 @@ xfs_trans_mod_dquot_byino(
207 if (tp->t_dqinfo == NULL) 207 if (tp->t_dqinfo == NULL)
208 xfs_trans_alloc_dqinfo(tp); 208 xfs_trans_alloc_dqinfo(tp);
209 209
210 if (XFS_IS_UQUOTA_ON(mp) && ip->i_udquot) { 210 if (XFS_IS_UQUOTA_ON(mp) && ip->i_udquot)
211 (void) xfs_trans_mod_dquot(tp, ip->i_udquot, field, delta); 211 (void) xfs_trans_mod_dquot(tp, ip->i_udquot, field, delta);
212 } 212 if (XFS_IS_OQUOTA_ON(mp) && ip->i_gdquot)
213 if (XFS_IS_GQUOTA_ON(mp) && ip->i_gdquot) {
214 (void) xfs_trans_mod_dquot(tp, ip->i_gdquot, field, delta); 213 (void) xfs_trans_mod_dquot(tp, ip->i_gdquot, field, delta);
215 }
216} 214}
217 215
218STATIC xfs_dqtrx_t * 216STATIC xfs_dqtrx_t *
@@ -368,7 +366,7 @@ xfs_trans_dqlockedjoin(
368 * Unreserve just the reservations done by this transaction. 366 * Unreserve just the reservations done by this transaction.
369 * dquot is still left locked at exit. 367 * dquot is still left locked at exit.
370 */ 368 */
371void 369STATIC void
372xfs_trans_apply_dquot_deltas( 370xfs_trans_apply_dquot_deltas(
373 xfs_trans_t *tp) 371 xfs_trans_t *tp)
374{ 372{
@@ -499,7 +497,7 @@ xfs_trans_apply_dquot_deltas(
499 * Adjust the RT reservation. 497 * Adjust the RT reservation.
500 */ 498 */
501 if (qtrx->qt_rtblk_res != 0) { 499 if (qtrx->qt_rtblk_res != 0) {
502 if (qtrx->qt_blk_res != qtrx->qt_blk_res_used) { 500 if (qtrx->qt_rtblk_res != qtrx->qt_rtblk_res_used) {
503 if (qtrx->qt_rtblk_res > 501 if (qtrx->qt_rtblk_res >
504 qtrx->qt_rtblk_res_used) 502 qtrx->qt_rtblk_res_used)
505 dqp->q_res_rtbcount -= (xfs_qcnt_t) 503 dqp->q_res_rtbcount -= (xfs_qcnt_t)
@@ -532,12 +530,6 @@ xfs_trans_apply_dquot_deltas(
532 (xfs_qcnt_t)qtrx->qt_icount_delta; 530 (xfs_qcnt_t)qtrx->qt_icount_delta;
533 } 531 }
534 532
535
536#ifdef QUOTADEBUG
537 if (qtrx->qt_rtblk_res != 0)
538 cmn_err(CE_DEBUG, "RT res %d for 0x%p\n",
539 (int) qtrx->qt_rtblk_res, dqp);
540#endif
541 ASSERT(dqp->q_res_bcount >= 533 ASSERT(dqp->q_res_bcount >=
542 INT_GET(dqp->q_core.d_bcount, ARCH_CONVERT)); 534 INT_GET(dqp->q_core.d_bcount, ARCH_CONVERT));
543 ASSERT(dqp->q_res_icount >= 535 ASSERT(dqp->q_res_icount >=
@@ -638,7 +630,10 @@ xfs_trans_dqresv(
638 int error; 630 int error;
639 xfs_qcnt_t hardlimit; 631 xfs_qcnt_t hardlimit;
640 xfs_qcnt_t softlimit; 632 xfs_qcnt_t softlimit;
641 time_t btimer; 633 time_t timer;
634 xfs_qwarncnt_t warns;
635 xfs_qwarncnt_t warnlimit;
636 xfs_qcnt_t count;
642 xfs_qcnt_t *resbcountp; 637 xfs_qcnt_t *resbcountp;
643 xfs_quotainfo_t *q = mp->m_quotainfo; 638 xfs_quotainfo_t *q = mp->m_quotainfo;
644 639
@@ -653,7 +648,9 @@ xfs_trans_dqresv(
653 softlimit = INT_GET(dqp->q_core.d_blk_softlimit, ARCH_CONVERT); 648 softlimit = INT_GET(dqp->q_core.d_blk_softlimit, ARCH_CONVERT);
654 if (!softlimit) 649 if (!softlimit)
655 softlimit = q->qi_bsoftlimit; 650 softlimit = q->qi_bsoftlimit;
656 btimer = INT_GET(dqp->q_core.d_btimer, ARCH_CONVERT); 651 timer = INT_GET(dqp->q_core.d_btimer, ARCH_CONVERT);
652 warns = INT_GET(dqp->q_core.d_bwarns, ARCH_CONVERT);
653 warnlimit = XFS_QI_BWARNLIMIT(dqp->q_mount);
657 resbcountp = &dqp->q_res_bcount; 654 resbcountp = &dqp->q_res_bcount;
658 } else { 655 } else {
659 ASSERT(flags & XFS_TRANS_DQ_RES_RTBLKS); 656 ASSERT(flags & XFS_TRANS_DQ_RES_RTBLKS);
@@ -663,7 +660,9 @@ xfs_trans_dqresv(
663 softlimit = INT_GET(dqp->q_core.d_rtb_softlimit, ARCH_CONVERT); 660 softlimit = INT_GET(dqp->q_core.d_rtb_softlimit, ARCH_CONVERT);
664 if (!softlimit) 661 if (!softlimit)
665 softlimit = q->qi_rtbsoftlimit; 662 softlimit = q->qi_rtbsoftlimit;
666 btimer = INT_GET(dqp->q_core.d_rtbtimer, ARCH_CONVERT); 663 timer = INT_GET(dqp->q_core.d_rtbtimer, ARCH_CONVERT);
664 warns = INT_GET(dqp->q_core.d_rtbwarns, ARCH_CONVERT);
665 warnlimit = XFS_QI_RTBWARNLIMIT(dqp->q_mount);
667 resbcountp = &dqp->q_res_rtbcount; 666 resbcountp = &dqp->q_res_rtbcount;
668 } 667 }
669 error = 0; 668 error = 0;
@@ -693,37 +692,36 @@ xfs_trans_dqresv(
693 * If timer or warnings has expired, 692 * If timer or warnings has expired,
694 * return EDQUOT 693 * return EDQUOT
695 */ 694 */
696 if ((btimer != 0 && get_seconds() > btimer) || 695 if ((timer != 0 && get_seconds() > timer) ||
697 (dqp->q_core.d_bwarns && 696 (warns != 0 && warns >= warnlimit)) {
698 INT_GET(dqp->q_core.d_bwarns, ARCH_CONVERT) >=
699 XFS_QI_BWARNLIMIT(dqp->q_mount))) {
700 error = EDQUOT; 697 error = EDQUOT;
701 goto error_return; 698 goto error_return;
702 } 699 }
703 } 700 }
704 } 701 }
705 if (ninos > 0) { 702 if (ninos > 0) {
706 hardlimit = INT_GET(dqp->q_core.d_ino_hardlimit, ARCH_CONVERT); 703 count = INT_GET(dqp->q_core.d_icount, ARCH_CONVERT);
704 timer = INT_GET(dqp->q_core.d_itimer, ARCH_CONVERT);
705 warns = INT_GET(dqp->q_core.d_iwarns, ARCH_CONVERT);
706 warnlimit = XFS_QI_IWARNLIMIT(dqp->q_mount);
707 hardlimit = INT_GET(dqp->q_core.d_ino_hardlimit,
708 ARCH_CONVERT);
707 if (!hardlimit) 709 if (!hardlimit)
708 hardlimit = q->qi_ihardlimit; 710 hardlimit = q->qi_ihardlimit;
709 softlimit = INT_GET(dqp->q_core.d_ino_softlimit, ARCH_CONVERT); 711 softlimit = INT_GET(dqp->q_core.d_ino_softlimit,
712 ARCH_CONVERT);
710 if (!softlimit) 713 if (!softlimit)
711 softlimit = q->qi_isoftlimit; 714 softlimit = q->qi_isoftlimit;
712 if (hardlimit > 0ULL && 715 if (hardlimit > 0ULL && count >= hardlimit) {
713 INT_GET(dqp->q_core.d_icount, ARCH_CONVERT) >= hardlimit) {
714 error = EDQUOT; 716 error = EDQUOT;
715 goto error_return; 717 goto error_return;
716 } else if (softlimit > 0ULL && 718 } else if (softlimit > 0ULL && count >= softlimit) {
717 INT_GET(dqp->q_core.d_icount, ARCH_CONVERT) >= softlimit) {
718 /* 719 /*
719 * If timer or warnings has expired, 720 * If timer or warnings has expired,
720 * return EDQUOT 721 * return EDQUOT
721 */ 722 */
722 if ((dqp->q_core.d_itimer && 723 if ((timer != 0 && get_seconds() > timer) ||
723 get_seconds() > INT_GET(dqp->q_core.d_itimer, ARCH_CONVERT)) || 724 (warns != 0 && warns >= warnlimit)) {
724 (dqp->q_core.d_iwarns &&
725 INT_GET(dqp->q_core.d_iwarns, ARCH_CONVERT) >=
726 XFS_QI_IWARNLIMIT(dqp->q_mount))) {
727 error = EDQUOT; 725 error = EDQUOT;
728 goto error_return; 726 goto error_return;
729 } 727 }
diff --git a/fs/xfs/support/debug.c b/fs/xfs/support/debug.c
index 7d6e1f37df10..4ed7b6928cd7 100644
--- a/fs/xfs/support/debug.c
+++ b/fs/xfs/support/debug.c
@@ -36,7 +36,6 @@
36#include <linux/sched.h> 36#include <linux/sched.h>
37#include <linux/kernel.h> 37#include <linux/kernel.h>
38 38
39int doass = 1;
40static char message[256]; /* keep it off the stack */ 39static char message[256]; /* keep it off the stack */
41static DEFINE_SPINLOCK(xfs_err_lock); 40static DEFINE_SPINLOCK(xfs_err_lock);
42 41
diff --git a/fs/xfs/support/debug.h b/fs/xfs/support/debug.h
index 40b0f4c54d9e..c5b9365a7e2a 100644
--- a/fs/xfs/support/debug.h
+++ b/fs/xfs/support/debug.h
@@ -50,16 +50,11 @@ extern void cmn_err(int, char *, ...);
50#endif 50#endif
51 51
52#ifdef DEBUG 52#ifdef DEBUG
53# ifdef lint 53# define ASSERT(EX) ((EX) ? ((void)0) : assfail(#EX, __FILE__, __LINE__))
54# define ASSERT(EX) ((void)0) /* avoid "constant in conditional" babble */
55# else
56# define ASSERT(EX) ((!doass||(EX))?((void)0):assfail(#EX, __FILE__, __LINE__))
57# endif /* lint */
58#else 54#else
59# define ASSERT(x) ((void)0) 55# define ASSERT(x) ((void)0)
60#endif 56#endif
61 57
62extern int doass; /* dynamically turn off asserts */
63extern void assfail(char *, char *, int); 58extern void assfail(char *, char *, int);
64#ifdef DEBUG 59#ifdef DEBUG
65extern unsigned long random(void); 60extern unsigned long random(void);
diff --git a/fs/xfs/xfs_alloc.c b/fs/xfs/xfs_alloc.c
index 36603db10fe9..dcfe19703620 100644
--- a/fs/xfs/xfs_alloc.c
+++ b/fs/xfs/xfs_alloc.c
@@ -59,7 +59,7 @@
59#define XFSA_FIXUP_BNO_OK 1 59#define XFSA_FIXUP_BNO_OK 1
60#define XFSA_FIXUP_CNT_OK 2 60#define XFSA_FIXUP_CNT_OK 2
61 61
62int 62STATIC int
63xfs_alloc_search_busy(xfs_trans_t *tp, 63xfs_alloc_search_busy(xfs_trans_t *tp,
64 xfs_agnumber_t agno, 64 xfs_agnumber_t agno,
65 xfs_agblock_t bno, 65 xfs_agblock_t bno,
@@ -2562,7 +2562,7 @@ xfs_alloc_clear_busy(xfs_trans_t *tp,
2562/* 2562/*
2563 * returns non-zero if any of (agno,bno):len is in a busy list 2563 * returns non-zero if any of (agno,bno):len is in a busy list
2564 */ 2564 */
2565int 2565STATIC int
2566xfs_alloc_search_busy(xfs_trans_t *tp, 2566xfs_alloc_search_busy(xfs_trans_t *tp,
2567 xfs_agnumber_t agno, 2567 xfs_agnumber_t agno,
2568 xfs_agblock_t bno, 2568 xfs_agblock_t bno,
diff --git a/fs/xfs/xfs_attr.c b/fs/xfs/xfs_attr.c
index ee8b5904ec7c..a41ad3a5e554 100644
--- a/fs/xfs/xfs_attr.c
+++ b/fs/xfs/xfs_attr.c
@@ -71,6 +71,11 @@
71 * Provide the external interfaces to manage attribute lists. 71 * Provide the external interfaces to manage attribute lists.
72 */ 72 */
73 73
74#define ATTR_SYSCOUNT 2
75STATIC struct attrnames posix_acl_access;
76STATIC struct attrnames posix_acl_default;
77STATIC struct attrnames *attr_system_names[ATTR_SYSCOUNT];
78
74/*======================================================================== 79/*========================================================================
75 * Function prototypes for the kernel. 80 * Function prototypes for the kernel.
76 *========================================================================*/ 81 *========================================================================*/
@@ -83,6 +88,7 @@ STATIC int xfs_attr_shortform_addname(xfs_da_args_t *args);
83/* 88/*
84 * Internal routines when attribute list is one block. 89 * Internal routines when attribute list is one block.
85 */ 90 */
91STATIC int xfs_attr_leaf_get(xfs_da_args_t *args);
86STATIC int xfs_attr_leaf_addname(xfs_da_args_t *args); 92STATIC int xfs_attr_leaf_addname(xfs_da_args_t *args);
87STATIC int xfs_attr_leaf_removename(xfs_da_args_t *args); 93STATIC int xfs_attr_leaf_removename(xfs_da_args_t *args);
88STATIC int xfs_attr_leaf_list(xfs_attr_list_context_t *context); 94STATIC int xfs_attr_leaf_list(xfs_attr_list_context_t *context);
@@ -90,6 +96,7 @@ STATIC int xfs_attr_leaf_list(xfs_attr_list_context_t *context);
90/* 96/*
91 * Internal routines when attribute list is more than one block. 97 * Internal routines when attribute list is more than one block.
92 */ 98 */
99STATIC int xfs_attr_node_get(xfs_da_args_t *args);
93STATIC int xfs_attr_node_addname(xfs_da_args_t *args); 100STATIC int xfs_attr_node_addname(xfs_da_args_t *args);
94STATIC int xfs_attr_node_removename(xfs_da_args_t *args); 101STATIC int xfs_attr_node_removename(xfs_da_args_t *args);
95STATIC int xfs_attr_node_list(xfs_attr_list_context_t *context); 102STATIC int xfs_attr_node_list(xfs_attr_list_context_t *context);
@@ -1102,7 +1109,7 @@ xfs_attr_leaf_removename(xfs_da_args_t *args)
1102 * This leaf block cannot have a "remote" value, we only call this routine 1109 * This leaf block cannot have a "remote" value, we only call this routine
1103 * if bmap_one_block() says there is only one block (ie: no remote blks). 1110 * if bmap_one_block() says there is only one block (ie: no remote blks).
1104 */ 1111 */
1105int 1112STATIC int
1106xfs_attr_leaf_get(xfs_da_args_t *args) 1113xfs_attr_leaf_get(xfs_da_args_t *args)
1107{ 1114{
1108 xfs_dabuf_t *bp; 1115 xfs_dabuf_t *bp;
@@ -1707,7 +1714,7 @@ xfs_attr_refillstate(xfs_da_state_t *state)
1707 * block, ie: both true Btree attr lists and for single-leaf-blocks with 1714 * block, ie: both true Btree attr lists and for single-leaf-blocks with
1708 * "remote" values taking up more blocks. 1715 * "remote" values taking up more blocks.
1709 */ 1716 */
1710int 1717STATIC int
1711xfs_attr_node_get(xfs_da_args_t *args) 1718xfs_attr_node_get(xfs_da_args_t *args)
1712{ 1719{
1713 xfs_da_state_t *state; 1720 xfs_da_state_t *state;
@@ -2398,7 +2405,7 @@ posix_acl_default_exists(
2398 return xfs_acl_vhasacl_default(vp); 2405 return xfs_acl_vhasacl_default(vp);
2399} 2406}
2400 2407
2401struct attrnames posix_acl_access = { 2408STATIC struct attrnames posix_acl_access = {
2402 .attr_name = "posix_acl_access", 2409 .attr_name = "posix_acl_access",
2403 .attr_namelen = sizeof("posix_acl_access") - 1, 2410 .attr_namelen = sizeof("posix_acl_access") - 1,
2404 .attr_get = posix_acl_access_get, 2411 .attr_get = posix_acl_access_get,
@@ -2407,7 +2414,7 @@ struct attrnames posix_acl_access = {
2407 .attr_exists = posix_acl_access_exists, 2414 .attr_exists = posix_acl_access_exists,
2408}; 2415};
2409 2416
2410struct attrnames posix_acl_default = { 2417STATIC struct attrnames posix_acl_default = {
2411 .attr_name = "posix_acl_default", 2418 .attr_name = "posix_acl_default",
2412 .attr_namelen = sizeof("posix_acl_default") - 1, 2419 .attr_namelen = sizeof("posix_acl_default") - 1,
2413 .attr_get = posix_acl_default_get, 2420 .attr_get = posix_acl_default_get,
@@ -2416,7 +2423,7 @@ struct attrnames posix_acl_default = {
2416 .attr_exists = posix_acl_default_exists, 2423 .attr_exists = posix_acl_default_exists,
2417}; 2424};
2418 2425
2419struct attrnames *attr_system_names[] = 2426STATIC struct attrnames *attr_system_names[] =
2420 { &posix_acl_access, &posix_acl_default }; 2427 { &posix_acl_access, &posix_acl_default };
2421 2428
2422 2429
diff --git a/fs/xfs/xfs_attr.h b/fs/xfs/xfs_attr.h
index 67cd0f5ac1a7..45ab1c542baf 100644
--- a/fs/xfs/xfs_attr.h
+++ b/fs/xfs/xfs_attr.h
@@ -76,11 +76,6 @@ extern struct attrnames attr_system;
76extern struct attrnames attr_trusted; 76extern struct attrnames attr_trusted;
77extern struct attrnames *attr_namespaces[ATTR_NAMECOUNT]; 77extern struct attrnames *attr_namespaces[ATTR_NAMECOUNT];
78 78
79#define ATTR_SYSCOUNT 2
80extern struct attrnames posix_acl_access;
81extern struct attrnames posix_acl_default;
82extern struct attrnames *attr_system_names[ATTR_SYSCOUNT];
83
84extern attrnames_t *attr_lookup_namespace(char *, attrnames_t **, int); 79extern attrnames_t *attr_lookup_namespace(char *, attrnames_t **, int);
85extern int attr_generic_list(struct vnode *, void *, size_t, int, ssize_t *); 80extern int attr_generic_list(struct vnode *, void *, size_t, int, ssize_t *);
86 81
@@ -184,8 +179,6 @@ int xfs_attr_list(bhv_desc_t *, char *, int, int,
184 struct attrlist_cursor_kern *, struct cred *); 179 struct attrlist_cursor_kern *, struct cred *);
185int xfs_attr_inactive(struct xfs_inode *dp); 180int xfs_attr_inactive(struct xfs_inode *dp);
186 181
187int xfs_attr_node_get(struct xfs_da_args *);
188int xfs_attr_leaf_get(struct xfs_da_args *);
189int xfs_attr_shortform_getvalue(struct xfs_da_args *); 182int xfs_attr_shortform_getvalue(struct xfs_da_args *);
190int xfs_attr_fetch(struct xfs_inode *, char *, int, 183int xfs_attr_fetch(struct xfs_inode *, char *, int,
191 char *, int *, int, struct cred *); 184 char *, int *, int, struct cred *);
diff --git a/fs/xfs/xfs_attr_leaf.c b/fs/xfs/xfs_attr_leaf.c
index b11256e58bf4..1cdd574c63a9 100644
--- a/fs/xfs/xfs_attr_leaf.c
+++ b/fs/xfs/xfs_attr_leaf.c
@@ -79,6 +79,8 @@
79/* 79/*
80 * Routines used for growing the Btree. 80 * Routines used for growing the Btree.
81 */ 81 */
82STATIC int xfs_attr_leaf_create(xfs_da_args_t *args, xfs_dablk_t which_block,
83 xfs_dabuf_t **bpp);
82STATIC int xfs_attr_leaf_add_work(xfs_dabuf_t *leaf_buffer, xfs_da_args_t *args, 84STATIC int xfs_attr_leaf_add_work(xfs_dabuf_t *leaf_buffer, xfs_da_args_t *args,
83 int freemap_index); 85 int freemap_index);
84STATIC void xfs_attr_leaf_compact(xfs_trans_t *trans, xfs_dabuf_t *leaf_buffer); 86STATIC void xfs_attr_leaf_compact(xfs_trans_t *trans, xfs_dabuf_t *leaf_buffer);
@@ -92,6 +94,16 @@ STATIC int xfs_attr_leaf_figure_balance(xfs_da_state_t *state,
92 int *number_usedbytes_in_blk1); 94 int *number_usedbytes_in_blk1);
93 95
94/* 96/*
97 * Routines used for shrinking the Btree.
98 */
99STATIC int xfs_attr_node_inactive(xfs_trans_t **trans, xfs_inode_t *dp,
100 xfs_dabuf_t *bp, int level);
101STATIC int xfs_attr_leaf_inactive(xfs_trans_t **trans, xfs_inode_t *dp,
102 xfs_dabuf_t *bp);
103STATIC int xfs_attr_leaf_freextent(xfs_trans_t **trans, xfs_inode_t *dp,
104 xfs_dablk_t blkno, int blkcnt);
105
106/*
95 * Utility routines. 107 * Utility routines.
96 */ 108 */
97STATIC void xfs_attr_leaf_moveents(xfs_attr_leafblock_t *src_leaf, 109STATIC void xfs_attr_leaf_moveents(xfs_attr_leafblock_t *src_leaf,
@@ -99,6 +111,10 @@ STATIC void xfs_attr_leaf_moveents(xfs_attr_leafblock_t *src_leaf,
99 xfs_attr_leafblock_t *dst_leaf, 111 xfs_attr_leafblock_t *dst_leaf,
100 int dst_start, int move_count, 112 int dst_start, int move_count,
101 xfs_mount_t *mp); 113 xfs_mount_t *mp);
114STATIC int xfs_attr_leaf_entsize(xfs_attr_leafblock_t *leaf, int index);
115STATIC int xfs_attr_put_listent(xfs_attr_list_context_t *context,
116 attrnames_t *, char *name, int namelen,
117 int valuelen);
102 118
103 119
104/*======================================================================== 120/*========================================================================
@@ -774,7 +790,7 @@ out:
774 * Create the initial contents of a leaf attribute list 790 * Create the initial contents of a leaf attribute list
775 * or a leaf in a node attribute list. 791 * or a leaf in a node attribute list.
776 */ 792 */
777int 793STATIC int
778xfs_attr_leaf_create(xfs_da_args_t *args, xfs_dablk_t blkno, xfs_dabuf_t **bpp) 794xfs_attr_leaf_create(xfs_da_args_t *args, xfs_dablk_t blkno, xfs_dabuf_t **bpp)
779{ 795{
780 xfs_attr_leafblock_t *leaf; 796 xfs_attr_leafblock_t *leaf;
@@ -2209,7 +2225,7 @@ xfs_attr_leaf_lasthash(xfs_dabuf_t *bp, int *count)
2209 * Calculate the number of bytes used to store the indicated attribute 2225 * Calculate the number of bytes used to store the indicated attribute
2210 * (whether local or remote only calculate bytes in this block). 2226 * (whether local or remote only calculate bytes in this block).
2211 */ 2227 */
2212int 2228STATIC int
2213xfs_attr_leaf_entsize(xfs_attr_leafblock_t *leaf, int index) 2229xfs_attr_leaf_entsize(xfs_attr_leafblock_t *leaf, int index)
2214{ 2230{
2215 xfs_attr_leaf_name_local_t *name_loc; 2231 xfs_attr_leaf_name_local_t *name_loc;
@@ -2380,7 +2396,7 @@ xfs_attr_leaf_list_int(xfs_dabuf_t *bp, xfs_attr_list_context_t *context)
2380 * we may be reading them directly out of a user buffer. 2396 * we may be reading them directly out of a user buffer.
2381 */ 2397 */
2382/*ARGSUSED*/ 2398/*ARGSUSED*/
2383int 2399STATIC int
2384xfs_attr_put_listent(xfs_attr_list_context_t *context, 2400xfs_attr_put_listent(xfs_attr_list_context_t *context,
2385 attrnames_t *namesp, char *name, int namelen, int valuelen) 2401 attrnames_t *namesp, char *name, int namelen, int valuelen)
2386{ 2402{
@@ -2740,7 +2756,7 @@ xfs_attr_root_inactive(xfs_trans_t **trans, xfs_inode_t *dp)
2740 * Recurse (gasp!) through the attribute nodes until we find leaves. 2756 * Recurse (gasp!) through the attribute nodes until we find leaves.
2741 * We're doing a depth-first traversal in order to invalidate everything. 2757 * We're doing a depth-first traversal in order to invalidate everything.
2742 */ 2758 */
2743int 2759STATIC int
2744xfs_attr_node_inactive(xfs_trans_t **trans, xfs_inode_t *dp, xfs_dabuf_t *bp, 2760xfs_attr_node_inactive(xfs_trans_t **trans, xfs_inode_t *dp, xfs_dabuf_t *bp,
2745 int level) 2761 int level)
2746{ 2762{
@@ -2849,7 +2865,7 @@ xfs_attr_node_inactive(xfs_trans_t **trans, xfs_inode_t *dp, xfs_dabuf_t *bp,
2849 * Note that we must release the lock on the buffer so that we are not 2865 * Note that we must release the lock on the buffer so that we are not
2850 * caught holding something that the logging code wants to flush to disk. 2866 * caught holding something that the logging code wants to flush to disk.
2851 */ 2867 */
2852int 2868STATIC int
2853xfs_attr_leaf_inactive(xfs_trans_t **trans, xfs_inode_t *dp, xfs_dabuf_t *bp) 2869xfs_attr_leaf_inactive(xfs_trans_t **trans, xfs_inode_t *dp, xfs_dabuf_t *bp)
2854{ 2870{
2855 xfs_attr_leafblock_t *leaf; 2871 xfs_attr_leafblock_t *leaf;
@@ -2934,7 +2950,7 @@ xfs_attr_leaf_inactive(xfs_trans_t **trans, xfs_inode_t *dp, xfs_dabuf_t *bp)
2934 * Look at all the extents for this logical region, 2950 * Look at all the extents for this logical region,
2935 * invalidate any buffers that are incore/in transactions. 2951 * invalidate any buffers that are incore/in transactions.
2936 */ 2952 */
2937int 2953STATIC int
2938xfs_attr_leaf_freextent(xfs_trans_t **trans, xfs_inode_t *dp, 2954xfs_attr_leaf_freextent(xfs_trans_t **trans, xfs_inode_t *dp,
2939 xfs_dablk_t blkno, int blkcnt) 2955 xfs_dablk_t blkno, int blkcnt)
2940{ 2956{
diff --git a/fs/xfs/xfs_attr_leaf.h b/fs/xfs/xfs_attr_leaf.h
index b1480e0b3349..0a4cfad6df91 100644
--- a/fs/xfs/xfs_attr_leaf.h
+++ b/fs/xfs/xfs_attr_leaf.h
@@ -261,8 +261,6 @@ int xfs_attr_leaf_flipflags(xfs_da_args_t *args);
261/* 261/*
262 * Routines used for growing the Btree. 262 * Routines used for growing the Btree.
263 */ 263 */
264int xfs_attr_leaf_create(struct xfs_da_args *args, xfs_dablk_t which_block,
265 struct xfs_dabuf **bpp);
266int xfs_attr_leaf_split(struct xfs_da_state *state, 264int xfs_attr_leaf_split(struct xfs_da_state *state,
267 struct xfs_da_state_blk *oldblk, 265 struct xfs_da_state_blk *oldblk,
268 struct xfs_da_state_blk *newblk); 266 struct xfs_da_state_blk *newblk);
@@ -284,12 +282,6 @@ void xfs_attr_leaf_unbalance(struct xfs_da_state *state,
284 struct xfs_da_state_blk *drop_blk, 282 struct xfs_da_state_blk *drop_blk,
285 struct xfs_da_state_blk *save_blk); 283 struct xfs_da_state_blk *save_blk);
286int xfs_attr_root_inactive(struct xfs_trans **trans, struct xfs_inode *dp); 284int xfs_attr_root_inactive(struct xfs_trans **trans, struct xfs_inode *dp);
287int xfs_attr_node_inactive(struct xfs_trans **trans, struct xfs_inode *dp,
288 struct xfs_dabuf *bp, int level);
289int xfs_attr_leaf_inactive(struct xfs_trans **trans, struct xfs_inode *dp,
290 struct xfs_dabuf *bp);
291int xfs_attr_leaf_freextent(struct xfs_trans **trans, struct xfs_inode *dp,
292 xfs_dablk_t blkno, int blkcnt);
293 285
294/* 286/*
295 * Utility routines. 287 * Utility routines.
@@ -299,10 +291,6 @@ int xfs_attr_leaf_order(struct xfs_dabuf *leaf1_bp,
299 struct xfs_dabuf *leaf2_bp); 291 struct xfs_dabuf *leaf2_bp);
300int xfs_attr_leaf_newentsize(struct xfs_da_args *args, int blocksize, 292int xfs_attr_leaf_newentsize(struct xfs_da_args *args, int blocksize,
301 int *local); 293 int *local);
302int xfs_attr_leaf_entsize(struct xfs_attr_leafblock *leaf, int index);
303int xfs_attr_put_listent(struct xfs_attr_list_context *context,
304 struct attrnames *, char *name, int namelen,
305 int valuelen);
306int xfs_attr_rolltrans(struct xfs_trans **transp, struct xfs_inode *dp); 294int xfs_attr_rolltrans(struct xfs_trans **transp, struct xfs_inode *dp);
307 295
308#endif /* __XFS_ATTR_LEAF_H__ */ 296#endif /* __XFS_ATTR_LEAF_H__ */
diff --git a/fs/xfs/xfs_bit.c b/fs/xfs/xfs_bit.c
index a20a6c3dc13e..76c9ad3875ef 100644
--- a/fs/xfs/xfs_bit.c
+++ b/fs/xfs/xfs_bit.c
@@ -45,7 +45,7 @@
45/* 45/*
46 * Index of high bit number in byte, -1 for none set, 0..7 otherwise. 46 * Index of high bit number in byte, -1 for none set, 0..7 otherwise.
47 */ 47 */
48const char xfs_highbit[256] = { 48STATIC const char xfs_highbit[256] = {
49 -1, 0, 1, 1, 2, 2, 2, 2, /* 00 .. 07 */ 49 -1, 0, 1, 1, 2, 2, 2, 2, /* 00 .. 07 */
50 3, 3, 3, 3, 3, 3, 3, 3, /* 08 .. 0f */ 50 3, 3, 3, 3, 3, 3, 3, 3, /* 08 .. 0f */
51 4, 4, 4, 4, 4, 4, 4, 4, /* 10 .. 17 */ 51 4, 4, 4, 4, 4, 4, 4, 4, /* 10 .. 17 */
diff --git a/fs/xfs/xfs_bmap.c b/fs/xfs/xfs_bmap.c
index de3162418663..6f5d283888aa 100644
--- a/fs/xfs/xfs_bmap.c
+++ b/fs/xfs/xfs_bmap.c
@@ -301,6 +301,19 @@ xfs_bmap_search_extents(
301 xfs_bmbt_irec_t *gotp, /* out: extent entry found */ 301 xfs_bmbt_irec_t *gotp, /* out: extent entry found */
302 xfs_bmbt_irec_t *prevp); /* out: previous extent entry found */ 302 xfs_bmbt_irec_t *prevp); /* out: previous extent entry found */
303 303
304/*
305 * Check the last inode extent to determine whether this allocation will result
306 * in blocks being allocated at the end of the file. When we allocate new data
307 * blocks at the end of the file which do not start at the previous data block,
308 * we will try to align the new blocks at stripe unit boundaries.
309 */
310STATIC int /* error */
311xfs_bmap_isaeof(
312 xfs_inode_t *ip, /* incore inode pointer */
313 xfs_fileoff_t off, /* file offset in fsblocks */
314 int whichfork, /* data or attribute fork */
315 char *aeof); /* return value */
316
304#ifdef XFS_BMAP_TRACE 317#ifdef XFS_BMAP_TRACE
305/* 318/*
306 * Add a bmap trace buffer entry. Base routine for the others. 319 * Add a bmap trace buffer entry. Base routine for the others.
@@ -4532,18 +4545,17 @@ xfs_bmapi(
4532 xfs_extlen_t alen; /* allocated extent length */ 4545 xfs_extlen_t alen; /* allocated extent length */
4533 xfs_fileoff_t aoff; /* allocated file offset */ 4546 xfs_fileoff_t aoff; /* allocated file offset */
4534 xfs_bmalloca_t bma; /* args for xfs_bmap_alloc */ 4547 xfs_bmalloca_t bma; /* args for xfs_bmap_alloc */
4535 char contig; /* allocation must be one extent */
4536 xfs_btree_cur_t *cur; /* bmap btree cursor */ 4548 xfs_btree_cur_t *cur; /* bmap btree cursor */
4537 char delay; /* this request is for delayed alloc */
4538 xfs_fileoff_t end; /* end of mapped file region */ 4549 xfs_fileoff_t end; /* end of mapped file region */
4539 int eof; /* we've hit the end of extent list */ 4550 int eof; /* we've hit the end of extent list */
4551 char contig; /* allocation must be one extent */
4552 char delay; /* this request is for delayed alloc */
4553 char exact; /* don't do all of wasdelayed extent */
4540 xfs_bmbt_rec_t *ep; /* extent list entry pointer */ 4554 xfs_bmbt_rec_t *ep; /* extent list entry pointer */
4541 int error; /* error return */ 4555 int error; /* error return */
4542 char exact; /* don't do all of wasdelayed extent */
4543 xfs_bmbt_irec_t got; /* current extent list record */ 4556 xfs_bmbt_irec_t got; /* current extent list record */
4544 xfs_ifork_t *ifp; /* inode fork pointer */ 4557 xfs_ifork_t *ifp; /* inode fork pointer */
4545 xfs_extlen_t indlen; /* indirect blocks length */ 4558 xfs_extlen_t indlen; /* indirect blocks length */
4546 char inhole; /* current location is hole in file */
4547 xfs_extnum_t lastx; /* last useful extent number */ 4559 xfs_extnum_t lastx; /* last useful extent number */
4548 int logflags; /* flags for transaction logging */ 4560 int logflags; /* flags for transaction logging */
4549 xfs_extlen_t minleft; /* min blocks left after allocation */ 4561 xfs_extlen_t minleft; /* min blocks left after allocation */
@@ -4554,13 +4566,15 @@ xfs_bmapi(
4554 xfs_extnum_t nextents; /* number of extents in file */ 4566 xfs_extnum_t nextents; /* number of extents in file */
4555 xfs_fileoff_t obno; /* old block number (offset) */ 4567 xfs_fileoff_t obno; /* old block number (offset) */
4556 xfs_bmbt_irec_t prev; /* previous extent list record */ 4568 xfs_bmbt_irec_t prev; /* previous extent list record */
4557 char stateless; /* ignore state flag set */
4558 int tmp_logflags; /* temp flags holder */ 4569 int tmp_logflags; /* temp flags holder */
4570 int whichfork; /* data or attr fork */
4571 char inhole; /* current location is hole in file */
4572 char stateless; /* ignore state flag set */
4559 char trim; /* output trimmed to match range */ 4573 char trim; /* output trimmed to match range */
4560 char userdata; /* allocating non-metadata */ 4574 char userdata; /* allocating non-metadata */
4561 char wasdelay; /* old extent was delayed */ 4575 char wasdelay; /* old extent was delayed */
4562 int whichfork; /* data or attr fork */
4563 char wr; /* this is a write request */ 4576 char wr; /* this is a write request */
4577 char rt; /* this is a realtime file */
4564 char rsvd; /* OK to allocate reserved blocks */ 4578 char rsvd; /* OK to allocate reserved blocks */
4565#ifdef DEBUG 4579#ifdef DEBUG
4566 xfs_fileoff_t orig_bno; /* original block number value */ 4580 xfs_fileoff_t orig_bno; /* original block number value */
@@ -4590,6 +4604,7 @@ xfs_bmapi(
4590 } 4604 }
4591 if (XFS_FORCED_SHUTDOWN(mp)) 4605 if (XFS_FORCED_SHUTDOWN(mp))
4592 return XFS_ERROR(EIO); 4606 return XFS_ERROR(EIO);
4607 rt = XFS_IS_REALTIME_INODE(ip);
4593 ifp = XFS_IFORK_PTR(ip, whichfork); 4608 ifp = XFS_IFORK_PTR(ip, whichfork);
4594 ASSERT(ifp->if_ext_max == 4609 ASSERT(ifp->if_ext_max ==
4595 XFS_IFORK_SIZE(ip, whichfork) / (uint)sizeof(xfs_bmbt_rec_t)); 4610 XFS_IFORK_SIZE(ip, whichfork) / (uint)sizeof(xfs_bmbt_rec_t));
@@ -4694,9 +4709,16 @@ xfs_bmapi(
4694 } 4709 }
4695 minlen = contig ? alen : 1; 4710 minlen = contig ? alen : 1;
4696 if (delay) { 4711 if (delay) {
4697 indlen = (xfs_extlen_t) 4712 xfs_extlen_t extsz = 0;
4698 xfs_bmap_worst_indlen(ip, alen); 4713
4699 ASSERT(indlen > 0); 4714 /* Figure out the extent size, adjust alen */
4715 if (rt) {
4716 if (!(extsz = ip->i_d.di_extsize))
4717 extsz = mp->m_sb.sb_rextsize;
4718 alen = roundup(alen, extsz);
4719 extsz = alen / mp->m_sb.sb_rextsize;
4720 }
4721
4700 /* 4722 /*
4701 * Make a transaction-less quota reservation for 4723 * Make a transaction-less quota reservation for
4702 * delayed allocation blocks. This number gets 4724 * delayed allocation blocks. This number gets
@@ -4704,8 +4726,10 @@ xfs_bmapi(
4704 * We return EDQUOT if we haven't allocated 4726 * We return EDQUOT if we haven't allocated
4705 * blks already inside this loop; 4727 * blks already inside this loop;
4706 */ 4728 */
4707 if (XFS_TRANS_RESERVE_BLKQUOTA( 4729 if (XFS_TRANS_RESERVE_QUOTA_NBLKS(
4708 mp, NULL, ip, (long)alen)) { 4730 mp, NULL, ip, (long)alen, 0,
4731 rt ? XFS_QMOPT_RES_RTBLKS :
4732 XFS_QMOPT_RES_REGBLKS)) {
4709 if (n == 0) { 4733 if (n == 0) {
4710 *nmap = 0; 4734 *nmap = 0;
4711 ASSERT(cur == NULL); 4735 ASSERT(cur == NULL);
@@ -4718,40 +4742,34 @@ xfs_bmapi(
4718 * Split changing sb for alen and indlen since 4742 * Split changing sb for alen and indlen since
4719 * they could be coming from different places. 4743 * they could be coming from different places.
4720 */ 4744 */
4721 if (ip->i_d.di_flags & XFS_DIFLAG_REALTIME) { 4745 indlen = (xfs_extlen_t)
4722 xfs_extlen_t extsz; 4746 xfs_bmap_worst_indlen(ip, alen);
4723 xfs_extlen_t ralen; 4747 ASSERT(indlen > 0);
4724 if (!(extsz = ip->i_d.di_extsize))
4725 extsz = mp->m_sb.sb_rextsize;
4726 ralen = roundup(alen, extsz);
4727 ralen = ralen / mp->m_sb.sb_rextsize;
4728 if (xfs_mod_incore_sb(mp,
4729 XFS_SBS_FREXTENTS,
4730 -(ralen), rsvd)) {
4731 if (XFS_IS_QUOTA_ON(ip->i_mount))
4732 XFS_TRANS_UNRESERVE_BLKQUOTA(
4733 mp, NULL, ip,
4734 (long)alen);
4735 break;
4736 }
4737 } else {
4738 if (xfs_mod_incore_sb(mp,
4739 XFS_SBS_FDBLOCKS,
4740 -(alen), rsvd)) {
4741 if (XFS_IS_QUOTA_ON(ip->i_mount))
4742 XFS_TRANS_UNRESERVE_BLKQUOTA(
4743 mp, NULL, ip,
4744 (long)alen);
4745 break;
4746 }
4747 }
4748 4748
4749 if (xfs_mod_incore_sb(mp, XFS_SBS_FDBLOCKS, 4749 if (rt)
4750 -(indlen), rsvd)) { 4750 error = xfs_mod_incore_sb(mp,
4751 XFS_TRANS_UNRESERVE_BLKQUOTA( 4751 XFS_SBS_FREXTENTS,
4752 mp, NULL, ip, (long)alen); 4752 -(extsz), rsvd);
4753 else
4754 error = xfs_mod_incore_sb(mp,
4755 XFS_SBS_FDBLOCKS,
4756 -(alen), rsvd);
4757 if (!error)
4758 error = xfs_mod_incore_sb(mp,
4759 XFS_SBS_FDBLOCKS,
4760 -(indlen), rsvd);
4761
4762 if (error) {
4763 if (XFS_IS_QUOTA_ON(ip->i_mount))
4764 /* unreserve the blocks now */
4765 XFS_TRANS_UNRESERVE_QUOTA_NBLKS(
4766 mp, NULL, ip,
4767 (long)alen, 0, rt ?
4768 XFS_QMOPT_RES_RTBLKS :
4769 XFS_QMOPT_RES_REGBLKS);
4753 break; 4770 break;
4754 } 4771 }
4772
4755 ip->i_delayed_blks += alen; 4773 ip->i_delayed_blks += alen;
4756 abno = NULLSTARTBLOCK(indlen); 4774 abno = NULLSTARTBLOCK(indlen);
4757 } else { 4775 } else {
@@ -5376,13 +5394,24 @@ xfs_bunmapi(
5376 } 5394 }
5377 if (wasdel) { 5395 if (wasdel) {
5378 ASSERT(STARTBLOCKVAL(del.br_startblock) > 0); 5396 ASSERT(STARTBLOCKVAL(del.br_startblock) > 0);
5379 xfs_mod_incore_sb(mp, XFS_SBS_FDBLOCKS, 5397 /* Update realtim/data freespace, unreserve quota */
5380 (int)del.br_blockcount, rsvd); 5398 if (isrt) {
5381 /* Unreserve our quota space */ 5399 xfs_filblks_t rtexts;
5382 XFS_TRANS_RESERVE_QUOTA_NBLKS( 5400
5383 mp, NULL, ip, -((long)del.br_blockcount), 0, 5401 rtexts = XFS_FSB_TO_B(mp, del.br_blockcount);
5384 isrt ? XFS_QMOPT_RES_RTBLKS : 5402 do_div(rtexts, mp->m_sb.sb_rextsize);
5403 xfs_mod_incore_sb(mp, XFS_SBS_FREXTENTS,
5404 (int)rtexts, rsvd);
5405 XFS_TRANS_RESERVE_QUOTA_NBLKS(mp, NULL, ip,
5406 -((long)del.br_blockcount), 0,
5407 XFS_QMOPT_RES_RTBLKS);
5408 } else {
5409 xfs_mod_incore_sb(mp, XFS_SBS_FDBLOCKS,
5410 (int)del.br_blockcount, rsvd);
5411 XFS_TRANS_RESERVE_QUOTA_NBLKS(mp, NULL, ip,
5412 -((long)del.br_blockcount), 0,
5385 XFS_QMOPT_RES_REGBLKS); 5413 XFS_QMOPT_RES_REGBLKS);
5414 }
5386 ip->i_delayed_blks -= del.br_blockcount; 5415 ip->i_delayed_blks -= del.br_blockcount;
5387 if (cur) 5416 if (cur)
5388 cur->bc_private.b.flags |= 5417 cur->bc_private.b.flags |=
@@ -5714,7 +5743,7 @@ unlock_and_return:
5714 * blocks at the end of the file which do not start at the previous data block, 5743 * blocks at the end of the file which do not start at the previous data block,
5715 * we will try to align the new blocks at stripe unit boundaries. 5744 * we will try to align the new blocks at stripe unit boundaries.
5716 */ 5745 */
5717int /* error */ 5746STATIC int /* error */
5718xfs_bmap_isaeof( 5747xfs_bmap_isaeof(
5719 xfs_inode_t *ip, /* incore inode pointer */ 5748 xfs_inode_t *ip, /* incore inode pointer */
5720 xfs_fileoff_t off, /* file offset in fsblocks */ 5749 xfs_fileoff_t off, /* file offset in fsblocks */
diff --git a/fs/xfs/xfs_bmap.h b/fs/xfs/xfs_bmap.h
index f1bc22fb26ae..e6d22ec9b2e4 100644
--- a/fs/xfs/xfs_bmap.h
+++ b/fs/xfs/xfs_bmap.h
@@ -332,19 +332,6 @@ xfs_getbmap(
332 int iflags); /* interface flags */ 332 int iflags); /* interface flags */
333 333
334/* 334/*
335 * Check the last inode extent to determine whether this allocation will result
336 * in blocks being allocated at the end of the file. When we allocate new data
337 * blocks at the end of the file which do not start at the previous data block,
338 * we will try to align the new blocks at stripe unit boundaries.
339 */
340int
341xfs_bmap_isaeof(
342 struct xfs_inode *ip,
343 xfs_fileoff_t off,
344 int whichfork,
345 char *aeof);
346
347/*
348 * Check if the endoff is outside the last extent. If so the caller will grow 335 * Check if the endoff is outside the last extent. If so the caller will grow
349 * the allocation to a stripe unit boundary 336 * the allocation to a stripe unit boundary
350 */ 337 */
diff --git a/fs/xfs/xfs_bmap_btree.c b/fs/xfs/xfs_bmap_btree.c
index 163305a79fcc..09c413576ba8 100644
--- a/fs/xfs/xfs_bmap_btree.c
+++ b/fs/xfs/xfs_bmap_btree.c
@@ -2331,20 +2331,6 @@ xfs_bmbt_lookup_ge(
2331 return xfs_bmbt_lookup(cur, XFS_LOOKUP_GE, stat); 2331 return xfs_bmbt_lookup(cur, XFS_LOOKUP_GE, stat);
2332} 2332}
2333 2333
2334int /* error */
2335xfs_bmbt_lookup_le(
2336 xfs_btree_cur_t *cur,
2337 xfs_fileoff_t off,
2338 xfs_fsblock_t bno,
2339 xfs_filblks_t len,
2340 int *stat) /* success/failure */
2341{
2342 cur->bc_rec.b.br_startoff = off;
2343 cur->bc_rec.b.br_startblock = bno;
2344 cur->bc_rec.b.br_blockcount = len;
2345 return xfs_bmbt_lookup(cur, XFS_LOOKUP_LE, stat);
2346}
2347
2348/* 2334/*
2349 * Give the bmap btree a new root block. Copy the old broot contents 2335 * Give the bmap btree a new root block. Copy the old broot contents
2350 * down into a real block and make the broot point to it. 2336 * down into a real block and make the broot point to it.
diff --git a/fs/xfs/xfs_bmap_btree.h b/fs/xfs/xfs_bmap_btree.h
index 843ff12b4bf2..0a40cf126c28 100644
--- a/fs/xfs/xfs_bmap_btree.h
+++ b/fs/xfs/xfs_bmap_btree.h
@@ -580,14 +580,6 @@ xfs_bmbt_lookup_ge(
580 xfs_filblks_t, 580 xfs_filblks_t,
581 int *); 581 int *);
582 582
583int
584xfs_bmbt_lookup_le(
585 struct xfs_btree_cur *,
586 xfs_fileoff_t,
587 xfs_fsblock_t,
588 xfs_filblks_t,
589 int *);
590
591/* 583/*
592 * Give the bmap btree a new root block. Copy the old broot contents 584 * Give the bmap btree a new root block. Copy the old broot contents
593 * down into a real block and make the broot point to it. 585 * down into a real block and make the broot point to it.
diff --git a/fs/xfs/xfs_btree.c b/fs/xfs/xfs_btree.c
index 9dd22dd95487..0cc63d657a14 100644
--- a/fs/xfs/xfs_btree.c
+++ b/fs/xfs/xfs_btree.c
@@ -90,6 +90,16 @@ xfs_btree_maxrecs(
90 */ 90 */
91 91
92/* 92/*
93 * Retrieve the block pointer from the cursor at the given level.
94 * This may be a bmap btree root or from a buffer.
95 */
96STATIC xfs_btree_block_t * /* generic btree block pointer */
97xfs_btree_get_block(
98 xfs_btree_cur_t *cur, /* btree cursor */
99 int level, /* level in btree */
100 struct xfs_buf **bpp); /* buffer containing the block */
101
102/*
93 * Checking routine: return maxrecs for the block. 103 * Checking routine: return maxrecs for the block.
94 */ 104 */
95STATIC int /* number of records fitting in block */ 105STATIC int /* number of records fitting in block */
@@ -497,7 +507,7 @@ xfs_btree_firstrec(
497 * Retrieve the block pointer from the cursor at the given level. 507 * Retrieve the block pointer from the cursor at the given level.
498 * This may be a bmap btree root or from a buffer. 508 * This may be a bmap btree root or from a buffer.
499 */ 509 */
500xfs_btree_block_t * /* generic btree block pointer */ 510STATIC xfs_btree_block_t * /* generic btree block pointer */
501xfs_btree_get_block( 511xfs_btree_get_block(
502 xfs_btree_cur_t *cur, /* btree cursor */ 512 xfs_btree_cur_t *cur, /* btree cursor */
503 int level, /* level in btree */ 513 int level, /* level in btree */
diff --git a/fs/xfs/xfs_btree.h b/fs/xfs/xfs_btree.h
index 93872bba41f5..09b4e1532a35 100644
--- a/fs/xfs/xfs_btree.h
+++ b/fs/xfs/xfs_btree.h
@@ -325,16 +325,6 @@ xfs_btree_firstrec(
325 int level); /* level to change */ 325 int level); /* level to change */
326 326
327/* 327/*
328 * Retrieve the block pointer from the cursor at the given level.
329 * This may be a bmap btree root or from a buffer.
330 */
331xfs_btree_block_t * /* generic btree block pointer */
332xfs_btree_get_block(
333 xfs_btree_cur_t *cur, /* btree cursor */
334 int level, /* level in btree */
335 struct xfs_buf **bpp); /* buffer containing the block */
336
337/*
338 * Get a buffer for the block, return it with no data read. 328 * Get a buffer for the block, return it with no data read.
339 * Long-form addressing. 329 * Long-form addressing.
340 */ 330 */
diff --git a/fs/xfs/xfs_buf_item.c b/fs/xfs/xfs_buf_item.c
index 9ab0039f07df..30b8285ad476 100644
--- a/fs/xfs/xfs_buf_item.c
+++ b/fs/xfs/xfs_buf_item.c
@@ -172,7 +172,7 @@ STATIC void xfs_buf_do_callbacks(xfs_buf_t *bp, xfs_log_item_t *lip);
172 * 172 *
173 * If the XFS_BLI_STALE flag has been set, then log nothing. 173 * If the XFS_BLI_STALE flag has been set, then log nothing.
174 */ 174 */
175uint 175STATIC uint
176xfs_buf_item_size( 176xfs_buf_item_size(
177 xfs_buf_log_item_t *bip) 177 xfs_buf_log_item_t *bip)
178{ 178{
@@ -240,7 +240,7 @@ xfs_buf_item_size(
240 * format structure, and the rest point to contiguous chunks 240 * format structure, and the rest point to contiguous chunks
241 * within the buffer. 241 * within the buffer.
242 */ 242 */
243void 243STATIC void
244xfs_buf_item_format( 244xfs_buf_item_format(
245 xfs_buf_log_item_t *bip, 245 xfs_buf_log_item_t *bip,
246 xfs_log_iovec_t *log_vector) 246 xfs_log_iovec_t *log_vector)
@@ -365,7 +365,7 @@ xfs_buf_item_format(
365 * item in memory so it cannot be written out. Simply call bpin() 365 * item in memory so it cannot be written out. Simply call bpin()
366 * on the buffer to do this. 366 * on the buffer to do this.
367 */ 367 */
368void 368STATIC void
369xfs_buf_item_pin( 369xfs_buf_item_pin(
370 xfs_buf_log_item_t *bip) 370 xfs_buf_log_item_t *bip)
371{ 371{
@@ -391,7 +391,7 @@ xfs_buf_item_pin(
391 * If the XFS_BLI_STALE flag is set and we are the last reference, 391 * If the XFS_BLI_STALE flag is set and we are the last reference,
392 * then free up the buf log item and unlock the buffer. 392 * then free up the buf log item and unlock the buffer.
393 */ 393 */
394void 394STATIC void
395xfs_buf_item_unpin( 395xfs_buf_item_unpin(
396 xfs_buf_log_item_t *bip, 396 xfs_buf_log_item_t *bip,
397 int stale) 397 int stale)
@@ -446,7 +446,7 @@ xfs_buf_item_unpin(
446 * so we need to free the item's descriptor (that points to the item) 446 * so we need to free the item's descriptor (that points to the item)
447 * in the transaction. 447 * in the transaction.
448 */ 448 */
449void 449STATIC void
450xfs_buf_item_unpin_remove( 450xfs_buf_item_unpin_remove(
451 xfs_buf_log_item_t *bip, 451 xfs_buf_log_item_t *bip,
452 xfs_trans_t *tp) 452 xfs_trans_t *tp)
@@ -493,7 +493,7 @@ xfs_buf_item_unpin_remove(
493 * the lock right away, return 0. If we can get the lock, pull the 493 * the lock right away, return 0. If we can get the lock, pull the
494 * buffer from the free list, mark it busy, and return 1. 494 * buffer from the free list, mark it busy, and return 1.
495 */ 495 */
496uint 496STATIC uint
497xfs_buf_item_trylock( 497xfs_buf_item_trylock(
498 xfs_buf_log_item_t *bip) 498 xfs_buf_log_item_t *bip)
499{ 499{
@@ -537,7 +537,7 @@ xfs_buf_item_trylock(
537 * This is for support of xfs_trans_bhold(). Make sure the 537 * This is for support of xfs_trans_bhold(). Make sure the
538 * XFS_BLI_HOLD field is cleared if we don't free the item. 538 * XFS_BLI_HOLD field is cleared if we don't free the item.
539 */ 539 */
540void 540STATIC void
541xfs_buf_item_unlock( 541xfs_buf_item_unlock(
542 xfs_buf_log_item_t *bip) 542 xfs_buf_log_item_t *bip)
543{ 543{
@@ -635,7 +635,7 @@ xfs_buf_item_unlock(
635 * by returning the original lsn of that transaction here rather than 635 * by returning the original lsn of that transaction here rather than
636 * the current one. 636 * the current one.
637 */ 637 */
638xfs_lsn_t 638STATIC xfs_lsn_t
639xfs_buf_item_committed( 639xfs_buf_item_committed(
640 xfs_buf_log_item_t *bip, 640 xfs_buf_log_item_t *bip,
641 xfs_lsn_t lsn) 641 xfs_lsn_t lsn)
@@ -654,7 +654,7 @@ xfs_buf_item_committed(
654 * and have aborted this transaction, we'll trap this buffer when it tries to 654 * and have aborted this transaction, we'll trap this buffer when it tries to
655 * get written out. 655 * get written out.
656 */ 656 */
657void 657STATIC void
658xfs_buf_item_abort( 658xfs_buf_item_abort(
659 xfs_buf_log_item_t *bip) 659 xfs_buf_log_item_t *bip)
660{ 660{
@@ -674,7 +674,7 @@ xfs_buf_item_abort(
674 * B_DELWRI set, then get it going out to disk with a call to bawrite(). 674 * B_DELWRI set, then get it going out to disk with a call to bawrite().
675 * If not, then just release the buffer. 675 * If not, then just release the buffer.
676 */ 676 */
677void 677STATIC void
678xfs_buf_item_push( 678xfs_buf_item_push(
679 xfs_buf_log_item_t *bip) 679 xfs_buf_log_item_t *bip)
680{ 680{
@@ -693,7 +693,7 @@ xfs_buf_item_push(
693} 693}
694 694
695/* ARGSUSED */ 695/* ARGSUSED */
696void 696STATIC void
697xfs_buf_item_committing(xfs_buf_log_item_t *bip, xfs_lsn_t commit_lsn) 697xfs_buf_item_committing(xfs_buf_log_item_t *bip, xfs_lsn_t commit_lsn)
698{ 698{
699} 699}
@@ -701,7 +701,7 @@ xfs_buf_item_committing(xfs_buf_log_item_t *bip, xfs_lsn_t commit_lsn)
701/* 701/*
702 * This is the ops vector shared by all buf log items. 702 * This is the ops vector shared by all buf log items.
703 */ 703 */
704struct xfs_item_ops xfs_buf_item_ops = { 704STATIC struct xfs_item_ops xfs_buf_item_ops = {
705 .iop_size = (uint(*)(xfs_log_item_t*))xfs_buf_item_size, 705 .iop_size = (uint(*)(xfs_log_item_t*))xfs_buf_item_size,
706 .iop_format = (void(*)(xfs_log_item_t*, xfs_log_iovec_t*)) 706 .iop_format = (void(*)(xfs_log_item_t*, xfs_log_iovec_t*))
707 xfs_buf_item_format, 707 xfs_buf_item_format,
diff --git a/fs/xfs/xfs_buf_item.h b/fs/xfs/xfs_buf_item.h
index 5f1b0c9308f6..01aed5f2d579 100644
--- a/fs/xfs/xfs_buf_item.h
+++ b/fs/xfs/xfs_buf_item.h
@@ -80,7 +80,7 @@ typedef struct xfs_buf_log_format_t {
80 * user or group dquots and may require special recovery handling. 80 * user or group dquots and may require special recovery handling.
81 */ 81 */
82#define XFS_BLI_UDQUOT_BUF 0x4 82#define XFS_BLI_UDQUOT_BUF 0x4
83/* #define XFS_BLI_PDQUOT_BUF 0x8 */ 83#define XFS_BLI_PDQUOT_BUF 0x8
84#define XFS_BLI_GDQUOT_BUF 0x10 84#define XFS_BLI_GDQUOT_BUF 0x10
85 85
86#define XFS_BLI_CHUNK 128 86#define XFS_BLI_CHUNK 128
diff --git a/fs/xfs/xfs_da_btree.c b/fs/xfs/xfs_da_btree.c
index d7fe28866764..8b792ddf2164 100644
--- a/fs/xfs/xfs_da_btree.c
+++ b/fs/xfs/xfs_da_btree.c
@@ -113,7 +113,10 @@ STATIC void xfs_da_node_unbalance(xfs_da_state_t *state,
113STATIC uint xfs_da_node_lasthash(xfs_dabuf_t *bp, int *count); 113STATIC uint xfs_da_node_lasthash(xfs_dabuf_t *bp, int *count);
114STATIC int xfs_da_node_order(xfs_dabuf_t *node1_bp, xfs_dabuf_t *node2_bp); 114STATIC int xfs_da_node_order(xfs_dabuf_t *node1_bp, xfs_dabuf_t *node2_bp);
115STATIC xfs_dabuf_t *xfs_da_buf_make(int nbuf, xfs_buf_t **bps, inst_t *ra); 115STATIC xfs_dabuf_t *xfs_da_buf_make(int nbuf, xfs_buf_t **bps, inst_t *ra);
116 116STATIC int xfs_da_blk_unlink(xfs_da_state_t *state,
117 xfs_da_state_blk_t *drop_blk,
118 xfs_da_state_blk_t *save_blk);
119STATIC void xfs_da_state_kill_altpath(xfs_da_state_t *state);
117 120
118/*======================================================================== 121/*========================================================================
119 * Routines used for growing the Btree. 122 * Routines used for growing the Btree.
@@ -1424,7 +1427,7 @@ xfs_da_node_lasthash(xfs_dabuf_t *bp, int *count)
1424/* 1427/*
1425 * Unlink a block from a doubly linked list of blocks. 1428 * Unlink a block from a doubly linked list of blocks.
1426 */ 1429 */
1427int /* error */ 1430STATIC int /* error */
1428xfs_da_blk_unlink(xfs_da_state_t *state, xfs_da_state_blk_t *drop_blk, 1431xfs_da_blk_unlink(xfs_da_state_t *state, xfs_da_state_blk_t *drop_blk,
1429 xfs_da_state_blk_t *save_blk) 1432 xfs_da_state_blk_t *save_blk)
1430{ 1433{
@@ -2381,7 +2384,7 @@ xfs_da_state_alloc(void)
2381/* 2384/*
2382 * Kill the altpath contents of a da-state structure. 2385 * Kill the altpath contents of a da-state structure.
2383 */ 2386 */
2384void 2387STATIC void
2385xfs_da_state_kill_altpath(xfs_da_state_t *state) 2388xfs_da_state_kill_altpath(xfs_da_state_t *state)
2386{ 2389{
2387 int i; 2390 int i;
diff --git a/fs/xfs/xfs_da_btree.h b/fs/xfs/xfs_da_btree.h
index 9fc699d96995..3a9b9e809c60 100644
--- a/fs/xfs/xfs_da_btree.h
+++ b/fs/xfs/xfs_da_btree.h
@@ -296,8 +296,6 @@ int xfs_da_path_shift(xfs_da_state_t *state, xfs_da_state_path_t *path,
296/* 296/*
297 * Utility routines. 297 * Utility routines.
298 */ 298 */
299int xfs_da_blk_unlink(xfs_da_state_t *state, xfs_da_state_blk_t *drop_blk,
300 xfs_da_state_blk_t *save_blk);
301int xfs_da_blk_link(xfs_da_state_t *state, xfs_da_state_blk_t *old_blk, 299int xfs_da_blk_link(xfs_da_state_t *state, xfs_da_state_blk_t *old_blk,
302 xfs_da_state_blk_t *new_blk); 300 xfs_da_state_blk_t *new_blk);
303 301
@@ -320,7 +318,6 @@ uint xfs_da_hashname(uchar_t *name_string, int name_length);
320uint xfs_da_log2_roundup(uint i); 318uint xfs_da_log2_roundup(uint i);
321xfs_da_state_t *xfs_da_state_alloc(void); 319xfs_da_state_t *xfs_da_state_alloc(void);
322void xfs_da_state_free(xfs_da_state_t *state); 320void xfs_da_state_free(xfs_da_state_t *state);
323void xfs_da_state_kill_altpath(xfs_da_state_t *state);
324 321
325void xfs_da_buf_done(xfs_dabuf_t *dabuf); 322void xfs_da_buf_done(xfs_dabuf_t *dabuf);
326void xfs_da_log_buf(struct xfs_trans *tp, xfs_dabuf_t *dabuf, uint first, 323void xfs_da_log_buf(struct xfs_trans *tp, xfs_dabuf_t *dabuf, uint first,
diff --git a/fs/xfs/xfs_dfrag.c b/fs/xfs/xfs_dfrag.c
index 63abdc2ac7f4..681be5c93af5 100644
--- a/fs/xfs/xfs_dfrag.c
+++ b/fs/xfs/xfs_dfrag.c
@@ -180,9 +180,10 @@ xfs_swapext(
180 goto error0; 180 goto error0;
181 } 181 }
182 182
183 if (VN_CACHED(tvp) != 0) 183 if (VN_CACHED(tvp) != 0) {
184 xfs_inval_cached_pages(XFS_ITOV(tip), &(tip->i_iocore), 184 xfs_inval_cached_trace(&tip->i_iocore, 0, -1, 0, -1);
185 (xfs_off_t)0, 0, 0); 185 VOP_FLUSHINVAL_PAGES(tvp, 0, -1, FI_REMAPF_LOCKED);
186 }
186 187
187 /* Verify O_DIRECT for ftmp */ 188 /* Verify O_DIRECT for ftmp */
188 if (VN_CACHED(tvp) != 0) { 189 if (VN_CACHED(tvp) != 0) {
diff --git a/fs/xfs/xfs_dir2_data.c b/fs/xfs/xfs_dir2_data.c
index db9887a107de..a0aa0e44ff9d 100644
--- a/fs/xfs/xfs_dir2_data.c
+++ b/fs/xfs/xfs_dir2_data.c
@@ -304,7 +304,7 @@ xfs_dir2_data_freeinsert(
304/* 304/*
305 * Remove a bestfree entry from the table. 305 * Remove a bestfree entry from the table.
306 */ 306 */
307void 307STATIC void
308xfs_dir2_data_freeremove( 308xfs_dir2_data_freeremove(
309 xfs_dir2_data_t *d, /* data block pointer */ 309 xfs_dir2_data_t *d, /* data block pointer */
310 xfs_dir2_data_free_t *dfp, /* bestfree entry pointer */ 310 xfs_dir2_data_free_t *dfp, /* bestfree entry pointer */
diff --git a/fs/xfs/xfs_dir2_data.h b/fs/xfs/xfs_dir2_data.h
index 3f02294ccff0..476cac920bf5 100644
--- a/fs/xfs/xfs_dir2_data.h
+++ b/fs/xfs/xfs_dir2_data.h
@@ -193,10 +193,6 @@ extern xfs_dir2_data_free_t *
193 xfs_dir2_data_unused_t *dup, int *loghead); 193 xfs_dir2_data_unused_t *dup, int *loghead);
194 194
195extern void 195extern void
196 xfs_dir2_data_freeremove(xfs_dir2_data_t *d,
197 xfs_dir2_data_free_t *dfp, int *loghead);
198
199extern void
200 xfs_dir2_data_freescan(struct xfs_mount *mp, xfs_dir2_data_t *d, 196 xfs_dir2_data_freescan(struct xfs_mount *mp, xfs_dir2_data_t *d,
201 int *loghead, char *aendp); 197 int *loghead, char *aendp);
202 198
diff --git a/fs/xfs/xfs_dir2_leaf.c b/fs/xfs/xfs_dir2_leaf.c
index 262d1e86df30..056f5283904b 100644
--- a/fs/xfs/xfs_dir2_leaf.c
+++ b/fs/xfs/xfs_dir2_leaf.c
@@ -77,6 +77,10 @@ static void xfs_dir2_leaf_check(xfs_inode_t *dp, xfs_dabuf_t *bp);
77#endif 77#endif
78static int xfs_dir2_leaf_lookup_int(xfs_da_args_t *args, xfs_dabuf_t **lbpp, 78static int xfs_dir2_leaf_lookup_int(xfs_da_args_t *args, xfs_dabuf_t **lbpp,
79 int *indexp, xfs_dabuf_t **dbpp); 79 int *indexp, xfs_dabuf_t **dbpp);
80static void xfs_dir2_leaf_log_bests(struct xfs_trans *tp, struct xfs_dabuf *bp,
81 int first, int last);
82static void xfs_dir2_leaf_log_tail(struct xfs_trans *tp, struct xfs_dabuf *bp);
83
80 84
81/* 85/*
82 * Convert a block form directory to a leaf form directory. 86 * Convert a block form directory to a leaf form directory.
@@ -1214,7 +1218,7 @@ xfs_dir2_leaf_init(
1214/* 1218/*
1215 * Log the bests entries indicated from a leaf1 block. 1219 * Log the bests entries indicated from a leaf1 block.
1216 */ 1220 */
1217void 1221static void
1218xfs_dir2_leaf_log_bests( 1222xfs_dir2_leaf_log_bests(
1219 xfs_trans_t *tp, /* transaction pointer */ 1223 xfs_trans_t *tp, /* transaction pointer */
1220 xfs_dabuf_t *bp, /* leaf buffer */ 1224 xfs_dabuf_t *bp, /* leaf buffer */
@@ -1278,7 +1282,7 @@ xfs_dir2_leaf_log_header(
1278/* 1282/*
1279 * Log the tail of the leaf1 block. 1283 * Log the tail of the leaf1 block.
1280 */ 1284 */
1281void 1285STATIC void
1282xfs_dir2_leaf_log_tail( 1286xfs_dir2_leaf_log_tail(
1283 xfs_trans_t *tp, /* transaction pointer */ 1287 xfs_trans_t *tp, /* transaction pointer */
1284 xfs_dabuf_t *bp) /* leaf buffer */ 1288 xfs_dabuf_t *bp) /* leaf buffer */
diff --git a/fs/xfs/xfs_dir2_leaf.h b/fs/xfs/xfs_dir2_leaf.h
index 7f20eee56a52..3303cd6f4c00 100644
--- a/fs/xfs/xfs_dir2_leaf.h
+++ b/fs/xfs/xfs_dir2_leaf.h
@@ -330,15 +330,8 @@ extern void
330 int first, int last); 330 int first, int last);
331 331
332extern void 332extern void
333 xfs_dir2_leaf_log_bests(struct xfs_trans *tp, struct xfs_dabuf *bp,
334 int first, int last);
335
336extern void
337 xfs_dir2_leaf_log_header(struct xfs_trans *tp, struct xfs_dabuf *bp); 333 xfs_dir2_leaf_log_header(struct xfs_trans *tp, struct xfs_dabuf *bp);
338 334
339extern void
340 xfs_dir2_leaf_log_tail(struct xfs_trans *tp, struct xfs_dabuf *bp);
341
342extern int 335extern int
343 xfs_dir2_leaf_lookup(struct xfs_da_args *args); 336 xfs_dir2_leaf_lookup(struct xfs_da_args *args);
344 337
diff --git a/fs/xfs/xfs_dir_leaf.c b/fs/xfs/xfs_dir_leaf.c
index 617018d6bbdc..c2ea6171fb0e 100644
--- a/fs/xfs/xfs_dir_leaf.c
+++ b/fs/xfs/xfs_dir_leaf.c
@@ -91,6 +91,10 @@ STATIC int xfs_dir_leaf_figure_balance(xfs_da_state_t *state,
91 int *number_entries_in_blk1, 91 int *number_entries_in_blk1,
92 int *number_namebytes_in_blk1); 92 int *number_namebytes_in_blk1);
93 93
94STATIC int xfs_dir_leaf_create(struct xfs_da_args *args,
95 xfs_dablk_t which_block,
96 struct xfs_dabuf **bpp);
97
94/* 98/*
95 * Utility routines. 99 * Utility routines.
96 */ 100 */
@@ -781,7 +785,7 @@ xfs_dir_leaf_to_node(xfs_da_args_t *args)
781 * Create the initial contents of a leaf directory 785 * Create the initial contents of a leaf directory
782 * or a leaf in a node directory. 786 * or a leaf in a node directory.
783 */ 787 */
784int 788STATIC int
785xfs_dir_leaf_create(xfs_da_args_t *args, xfs_dablk_t blkno, xfs_dabuf_t **bpp) 789xfs_dir_leaf_create(xfs_da_args_t *args, xfs_dablk_t blkno, xfs_dabuf_t **bpp)
786{ 790{
787 xfs_dir_leafblock_t *leaf; 791 xfs_dir_leafblock_t *leaf;
diff --git a/fs/xfs/xfs_dir_leaf.h b/fs/xfs/xfs_dir_leaf.h
index 00d68d33cc7a..dd423ce1bc8d 100644
--- a/fs/xfs/xfs_dir_leaf.h
+++ b/fs/xfs/xfs_dir_leaf.h
@@ -202,8 +202,6 @@ int xfs_dir_leaf_to_shortform(struct xfs_da_args *args);
202/* 202/*
203 * Routines used for growing the Btree. 203 * Routines used for growing the Btree.
204 */ 204 */
205int xfs_dir_leaf_create(struct xfs_da_args *args, xfs_dablk_t which_block,
206 struct xfs_dabuf **bpp);
207int xfs_dir_leaf_split(struct xfs_da_state *state, 205int xfs_dir_leaf_split(struct xfs_da_state *state,
208 struct xfs_da_state_blk *oldblk, 206 struct xfs_da_state_blk *oldblk,
209 struct xfs_da_state_blk *newblk); 207 struct xfs_da_state_blk *newblk);
diff --git a/fs/xfs/xfs_dmapi.h b/fs/xfs/xfs_dmapi.h
index 55ae3e67d245..55c17adaaa37 100644
--- a/fs/xfs/xfs_dmapi.h
+++ b/fs/xfs/xfs_dmapi.h
@@ -166,27 +166,32 @@ typedef enum {
166#define DM_FLAGS_NDELAY 0x001 /* return EAGAIN after dm_pending() */ 166#define DM_FLAGS_NDELAY 0x001 /* return EAGAIN after dm_pending() */
167#define DM_FLAGS_UNWANTED 0x002 /* event not in fsys dm_eventset_t */ 167#define DM_FLAGS_UNWANTED 0x002 /* event not in fsys dm_eventset_t */
168#define DM_FLAGS_ISEM 0x004 /* thread holds i_sem */ 168#define DM_FLAGS_ISEM 0x004 /* thread holds i_sem */
169#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
170#if LINUX_VERSION_CODE > KERNEL_VERSION(2,4,21)
171/* i_alloc_sem was added in 2.4.22-pre1 */
172#define DM_FLAGS_IALLOCSEM_RD 0x010 /* thread holds i_alloc_sem rd */ 169#define DM_FLAGS_IALLOCSEM_RD 0x010 /* thread holds i_alloc_sem rd */
173#define DM_FLAGS_IALLOCSEM_WR 0x020 /* thread holds i_alloc_sem wr */ 170#define DM_FLAGS_IALLOCSEM_WR 0x020 /* thread holds i_alloc_sem wr */
174#endif
175#endif
176 171
177/* 172/*
178 * Based on IO_ISDIRECT, decide which i_ flag is set. 173 * Based on IO_ISDIRECT, decide which i_ flag is set.
179 */ 174 */
180#ifdef DM_FLAGS_IALLOCSEM_RD 175#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0)
176#define DM_SEM_FLAG_RD(ioflags) (((ioflags) & IO_ISDIRECT) ? \
177 DM_FLAGS_ISEM : 0)
178#define DM_SEM_FLAG_WR (DM_FLAGS_IALLOCSEM_WR | DM_FLAGS_ISEM)
179#endif
180
181#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)) && \
182 (LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,22))
181#define DM_SEM_FLAG_RD(ioflags) (((ioflags) & IO_ISDIRECT) ? \ 183#define DM_SEM_FLAG_RD(ioflags) (((ioflags) & IO_ISDIRECT) ? \
182 DM_FLAGS_IALLOCSEM_RD : DM_FLAGS_ISEM) 184 DM_FLAGS_IALLOCSEM_RD : DM_FLAGS_ISEM)
183#define DM_SEM_FLAG_WR (DM_FLAGS_IALLOCSEM_WR | DM_FLAGS_ISEM) 185#define DM_SEM_FLAG_WR (DM_FLAGS_IALLOCSEM_WR | DM_FLAGS_ISEM)
184#else 186#endif
187
188#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,4,21)
185#define DM_SEM_FLAG_RD(ioflags) (((ioflags) & IO_ISDIRECT) ? \ 189#define DM_SEM_FLAG_RD(ioflags) (((ioflags) & IO_ISDIRECT) ? \
186 0 : DM_FLAGS_ISEM) 190 0 : DM_FLAGS_ISEM)
187#define DM_SEM_FLAG_WR (DM_FLAGS_ISEM) 191#define DM_SEM_FLAG_WR (DM_FLAGS_ISEM)
188#endif 192#endif
189 193
194
190/* 195/*
191 * Macros to turn caller specified delay/block flags into 196 * Macros to turn caller specified delay/block flags into
192 * dm_send_xxxx_event flag DM_FLAGS_NDELAY. 197 * dm_send_xxxx_event flag DM_FLAGS_NDELAY.
diff --git a/fs/xfs/xfs_error.c b/fs/xfs/xfs_error.c
index bbe1dea11c08..dcd3fdd5c1f7 100644
--- a/fs/xfs/xfs_error.c
+++ b/fs/xfs/xfs_error.c
@@ -280,7 +280,7 @@ xfs_error_report(
280 } 280 }
281} 281}
282 282
283void 283STATIC void
284xfs_hex_dump(void *p, int length) 284xfs_hex_dump(void *p, int length)
285{ 285{
286 __uint8_t *uip = (__uint8_t*)p; 286 __uint8_t *uip = (__uint8_t*)p;
diff --git a/fs/xfs/xfs_error.h b/fs/xfs/xfs_error.h
index 6bc0535c0a65..52ee2b90b5ed 100644
--- a/fs/xfs/xfs_error.h
+++ b/fs/xfs/xfs_error.h
@@ -73,9 +73,6 @@ xfs_corruption_error(
73 int linenum, 73 int linenum,
74 inst_t *ra); 74 inst_t *ra);
75 75
76extern void
77xfs_hex_dump(void *p, int length);
78
79#define XFS_ERROR_REPORT(e, lvl, mp) \ 76#define XFS_ERROR_REPORT(e, lvl, mp) \
80 xfs_error_report(e, lvl, mp, __FILE__, __LINE__, __return_address) 77 xfs_error_report(e, lvl, mp, __FILE__, __LINE__, __return_address)
81#define XFS_CORRUPTION_ERROR(e, lvl, mp, mem) \ 78#define XFS_CORRUPTION_ERROR(e, lvl, mp, mem) \
diff --git a/fs/xfs/xfs_extfree_item.c b/fs/xfs/xfs_extfree_item.c
index 5eafd5b63211..db7cbd1bc857 100644
--- a/fs/xfs/xfs_extfree_item.c
+++ b/fs/xfs/xfs_extfree_item.c
@@ -59,6 +59,18 @@ STATIC void xfs_efi_item_abort(xfs_efi_log_item_t *);
59STATIC void xfs_efd_item_abort(xfs_efd_log_item_t *); 59STATIC void xfs_efd_item_abort(xfs_efd_log_item_t *);
60 60
61 61
62void
63xfs_efi_item_free(xfs_efi_log_item_t *efip)
64{
65 int nexts = efip->efi_format.efi_nextents;
66
67 if (nexts > XFS_EFI_MAX_FAST_EXTENTS) {
68 kmem_free(efip, sizeof(xfs_efi_log_item_t) +
69 (nexts - 1) * sizeof(xfs_extent_t));
70 } else {
71 kmem_zone_free(xfs_efi_zone, efip);
72 }
73}
62 74
63/* 75/*
64 * This returns the number of iovecs needed to log the given efi item. 76 * This returns the number of iovecs needed to log the given efi item.
@@ -120,8 +132,6 @@ xfs_efi_item_pin(xfs_efi_log_item_t *efip)
120STATIC void 132STATIC void
121xfs_efi_item_unpin(xfs_efi_log_item_t *efip, int stale) 133xfs_efi_item_unpin(xfs_efi_log_item_t *efip, int stale)
122{ 134{
123 int nexts;
124 int size;
125 xfs_mount_t *mp; 135 xfs_mount_t *mp;
126 SPLDECL(s); 136 SPLDECL(s);
127 137
@@ -132,21 +142,11 @@ xfs_efi_item_unpin(xfs_efi_log_item_t *efip, int stale)
132 * xfs_trans_delete_ail() drops the AIL lock. 142 * xfs_trans_delete_ail() drops the AIL lock.
133 */ 143 */
134 xfs_trans_delete_ail(mp, (xfs_log_item_t *)efip, s); 144 xfs_trans_delete_ail(mp, (xfs_log_item_t *)efip, s);
135 145 xfs_efi_item_free(efip);
136 nexts = efip->efi_format.efi_nextents;
137 if (nexts > XFS_EFI_MAX_FAST_EXTENTS) {
138 size = sizeof(xfs_efi_log_item_t);
139 size += (nexts - 1) * sizeof(xfs_extent_t);
140 kmem_free(efip, size);
141 } else {
142 kmem_zone_free(xfs_efi_zone, efip);
143 }
144 } else { 146 } else {
145 efip->efi_flags |= XFS_EFI_COMMITTED; 147 efip->efi_flags |= XFS_EFI_COMMITTED;
146 AIL_UNLOCK(mp, s); 148 AIL_UNLOCK(mp, s);
147 } 149 }
148
149 return;
150} 150}
151 151
152/* 152/*
@@ -159,8 +159,6 @@ xfs_efi_item_unpin(xfs_efi_log_item_t *efip, int stale)
159STATIC void 159STATIC void
160xfs_efi_item_unpin_remove(xfs_efi_log_item_t *efip, xfs_trans_t *tp) 160xfs_efi_item_unpin_remove(xfs_efi_log_item_t *efip, xfs_trans_t *tp)
161{ 161{
162 int nexts;
163 int size;
164 xfs_mount_t *mp; 162 xfs_mount_t *mp;
165 xfs_log_item_desc_t *lidp; 163 xfs_log_item_desc_t *lidp;
166 SPLDECL(s); 164 SPLDECL(s);
@@ -178,23 +176,11 @@ xfs_efi_item_unpin_remove(xfs_efi_log_item_t *efip, xfs_trans_t *tp)
178 * xfs_trans_delete_ail() drops the AIL lock. 176 * xfs_trans_delete_ail() drops the AIL lock.
179 */ 177 */
180 xfs_trans_delete_ail(mp, (xfs_log_item_t *)efip, s); 178 xfs_trans_delete_ail(mp, (xfs_log_item_t *)efip, s);
181 /* 179 xfs_efi_item_free(efip);
182 * now free the item itself
183 */
184 nexts = efip->efi_format.efi_nextents;
185 if (nexts > XFS_EFI_MAX_FAST_EXTENTS) {
186 size = sizeof(xfs_efi_log_item_t);
187 size += (nexts - 1) * sizeof(xfs_extent_t);
188 kmem_free(efip, size);
189 } else {
190 kmem_zone_free(xfs_efi_zone, efip);
191 }
192 } else { 180 } else {
193 efip->efi_flags |= XFS_EFI_COMMITTED; 181 efip->efi_flags |= XFS_EFI_COMMITTED;
194 AIL_UNLOCK(mp, s); 182 AIL_UNLOCK(mp, s);
195 } 183 }
196
197 return;
198} 184}
199 185
200/* 186/*
@@ -245,18 +231,7 @@ xfs_efi_item_committed(xfs_efi_log_item_t *efip, xfs_lsn_t lsn)
245STATIC void 231STATIC void
246xfs_efi_item_abort(xfs_efi_log_item_t *efip) 232xfs_efi_item_abort(xfs_efi_log_item_t *efip)
247{ 233{
248 int nexts; 234 xfs_efi_item_free(efip);
249 int size;
250
251 nexts = efip->efi_format.efi_nextents;
252 if (nexts > XFS_EFI_MAX_FAST_EXTENTS) {
253 size = sizeof(xfs_efi_log_item_t);
254 size += (nexts - 1) * sizeof(xfs_extent_t);
255 kmem_free(efip, size);
256 } else {
257 kmem_zone_free(xfs_efi_zone, efip);
258 }
259 return;
260} 235}
261 236
262/* 237/*
@@ -288,7 +263,7 @@ xfs_efi_item_committing(xfs_efi_log_item_t *efip, xfs_lsn_t lsn)
288/* 263/*
289 * This is the ops vector shared by all efi log items. 264 * This is the ops vector shared by all efi log items.
290 */ 265 */
291struct xfs_item_ops xfs_efi_item_ops = { 266STATIC struct xfs_item_ops xfs_efi_item_ops = {
292 .iop_size = (uint(*)(xfs_log_item_t*))xfs_efi_item_size, 267 .iop_size = (uint(*)(xfs_log_item_t*))xfs_efi_item_size,
293 .iop_format = (void(*)(xfs_log_item_t*, xfs_log_iovec_t*)) 268 .iop_format = (void(*)(xfs_log_item_t*, xfs_log_iovec_t*))
294 xfs_efi_item_format, 269 xfs_efi_item_format,
@@ -355,8 +330,6 @@ xfs_efi_release(xfs_efi_log_item_t *efip,
355{ 330{
356 xfs_mount_t *mp; 331 xfs_mount_t *mp;
357 int extents_left; 332 int extents_left;
358 uint size;
359 int nexts;
360 SPLDECL(s); 333 SPLDECL(s);
361 334
362 mp = efip->efi_item.li_mountp; 335 mp = efip->efi_item.li_mountp;
@@ -372,20 +345,10 @@ xfs_efi_release(xfs_efi_log_item_t *efip,
372 * xfs_trans_delete_ail() drops the AIL lock. 345 * xfs_trans_delete_ail() drops the AIL lock.
373 */ 346 */
374 xfs_trans_delete_ail(mp, (xfs_log_item_t *)efip, s); 347 xfs_trans_delete_ail(mp, (xfs_log_item_t *)efip, s);
348 xfs_efi_item_free(efip);
375 } else { 349 } else {
376 AIL_UNLOCK(mp, s); 350 AIL_UNLOCK(mp, s);
377 } 351 }
378
379 if (extents_left == 0) {
380 nexts = efip->efi_format.efi_nextents;
381 if (nexts > XFS_EFI_MAX_FAST_EXTENTS) {
382 size = sizeof(xfs_efi_log_item_t);
383 size += (nexts - 1) * sizeof(xfs_extent_t);
384 kmem_free(efip, size);
385 } else {
386 kmem_zone_free(xfs_efi_zone, efip);
387 }
388 }
389} 352}
390 353
391/* 354/*
@@ -398,8 +361,6 @@ STATIC void
398xfs_efi_cancel( 361xfs_efi_cancel(
399 xfs_efi_log_item_t *efip) 362 xfs_efi_log_item_t *efip)
400{ 363{
401 int nexts;
402 int size;
403 xfs_mount_t *mp; 364 xfs_mount_t *mp;
404 SPLDECL(s); 365 SPLDECL(s);
405 366
@@ -410,26 +371,25 @@ xfs_efi_cancel(
410 * xfs_trans_delete_ail() drops the AIL lock. 371 * xfs_trans_delete_ail() drops the AIL lock.
411 */ 372 */
412 xfs_trans_delete_ail(mp, (xfs_log_item_t *)efip, s); 373 xfs_trans_delete_ail(mp, (xfs_log_item_t *)efip, s);
413 374 xfs_efi_item_free(efip);
414 nexts = efip->efi_format.efi_nextents;
415 if (nexts > XFS_EFI_MAX_FAST_EXTENTS) {
416 size = sizeof(xfs_efi_log_item_t);
417 size += (nexts - 1) * sizeof(xfs_extent_t);
418 kmem_free(efip, size);
419 } else {
420 kmem_zone_free(xfs_efi_zone, efip);
421 }
422 } else { 375 } else {
423 efip->efi_flags |= XFS_EFI_CANCELED; 376 efip->efi_flags |= XFS_EFI_CANCELED;
424 AIL_UNLOCK(mp, s); 377 AIL_UNLOCK(mp, s);
425 } 378 }
426
427 return;
428} 379}
429 380
381STATIC void
382xfs_efd_item_free(xfs_efd_log_item_t *efdp)
383{
384 int nexts = efdp->efd_format.efd_nextents;
430 385
431 386 if (nexts > XFS_EFD_MAX_FAST_EXTENTS) {
432 387 kmem_free(efdp, sizeof(xfs_efd_log_item_t) +
388 (nexts - 1) * sizeof(xfs_extent_t));
389 } else {
390 kmem_zone_free(xfs_efd_zone, efdp);
391 }
392}
433 393
434/* 394/*
435 * This returns the number of iovecs needed to log the given efd item. 395 * This returns the number of iovecs needed to log the given efd item.
@@ -533,9 +493,6 @@ xfs_efd_item_unlock(xfs_efd_log_item_t *efdp)
533STATIC xfs_lsn_t 493STATIC xfs_lsn_t
534xfs_efd_item_committed(xfs_efd_log_item_t *efdp, xfs_lsn_t lsn) 494xfs_efd_item_committed(xfs_efd_log_item_t *efdp, xfs_lsn_t lsn)
535{ 495{
536 uint size;
537 int nexts;
538
539 /* 496 /*
540 * If we got a log I/O error, it's always the case that the LR with the 497 * If we got a log I/O error, it's always the case that the LR with the
541 * EFI got unpinned and freed before the EFD got aborted. 498 * EFI got unpinned and freed before the EFD got aborted.
@@ -543,15 +500,7 @@ xfs_efd_item_committed(xfs_efd_log_item_t *efdp, xfs_lsn_t lsn)
543 if ((efdp->efd_item.li_flags & XFS_LI_ABORTED) == 0) 500 if ((efdp->efd_item.li_flags & XFS_LI_ABORTED) == 0)
544 xfs_efi_release(efdp->efd_efip, efdp->efd_format.efd_nextents); 501 xfs_efi_release(efdp->efd_efip, efdp->efd_format.efd_nextents);
545 502
546 nexts = efdp->efd_format.efd_nextents; 503 xfs_efd_item_free(efdp);
547 if (nexts > XFS_EFD_MAX_FAST_EXTENTS) {
548 size = sizeof(xfs_efd_log_item_t);
549 size += (nexts - 1) * sizeof(xfs_extent_t);
550 kmem_free(efdp, size);
551 } else {
552 kmem_zone_free(xfs_efd_zone, efdp);
553 }
554
555 return (xfs_lsn_t)-1; 504 return (xfs_lsn_t)-1;
556} 505}
557 506
@@ -565,9 +514,6 @@ xfs_efd_item_committed(xfs_efd_log_item_t *efdp, xfs_lsn_t lsn)
565STATIC void 514STATIC void
566xfs_efd_item_abort(xfs_efd_log_item_t *efdp) 515xfs_efd_item_abort(xfs_efd_log_item_t *efdp)
567{ 516{
568 int nexts;
569 int size;
570
571 /* 517 /*
572 * If we got a log I/O error, it's always the case that the LR with the 518 * If we got a log I/O error, it's always the case that the LR with the
573 * EFI got unpinned and freed before the EFD got aborted. So don't 519 * EFI got unpinned and freed before the EFD got aborted. So don't
@@ -576,15 +522,7 @@ xfs_efd_item_abort(xfs_efd_log_item_t *efdp)
576 if ((efdp->efd_item.li_flags & XFS_LI_ABORTED) == 0) 522 if ((efdp->efd_item.li_flags & XFS_LI_ABORTED) == 0)
577 xfs_efi_cancel(efdp->efd_efip); 523 xfs_efi_cancel(efdp->efd_efip);
578 524
579 nexts = efdp->efd_format.efd_nextents; 525 xfs_efd_item_free(efdp);
580 if (nexts > XFS_EFD_MAX_FAST_EXTENTS) {
581 size = sizeof(xfs_efd_log_item_t);
582 size += (nexts - 1) * sizeof(xfs_extent_t);
583 kmem_free(efdp, size);
584 } else {
585 kmem_zone_free(xfs_efd_zone, efdp);
586 }
587 return;
588} 526}
589 527
590/* 528/*
@@ -615,7 +553,7 @@ xfs_efd_item_committing(xfs_efd_log_item_t *efip, xfs_lsn_t lsn)
615/* 553/*
616 * This is the ops vector shared by all efd log items. 554 * This is the ops vector shared by all efd log items.
617 */ 555 */
618struct xfs_item_ops xfs_efd_item_ops = { 556STATIC struct xfs_item_ops xfs_efd_item_ops = {
619 .iop_size = (uint(*)(xfs_log_item_t*))xfs_efd_item_size, 557 .iop_size = (uint(*)(xfs_log_item_t*))xfs_efd_item_size,
620 .iop_format = (void(*)(xfs_log_item_t*, xfs_log_iovec_t*)) 558 .iop_format = (void(*)(xfs_log_item_t*, xfs_log_iovec_t*))
621 xfs_efd_item_format, 559 xfs_efd_item_format,
diff --git a/fs/xfs/xfs_extfree_item.h b/fs/xfs/xfs_extfree_item.h
index 7122d6101d15..d433bac9f59d 100644
--- a/fs/xfs/xfs_extfree_item.h
+++ b/fs/xfs/xfs_extfree_item.h
@@ -118,6 +118,8 @@ xfs_efi_log_item_t *xfs_efi_init(struct xfs_mount *, uint);
118xfs_efd_log_item_t *xfs_efd_init(struct xfs_mount *, xfs_efi_log_item_t *, 118xfs_efd_log_item_t *xfs_efd_init(struct xfs_mount *, xfs_efi_log_item_t *,
119 uint); 119 uint);
120 120
121void xfs_efi_item_free(xfs_efi_log_item_t *);
122
121#endif /* __KERNEL__ */ 123#endif /* __KERNEL__ */
122 124
123#endif /* __XFS_EXTFREE_ITEM_H__ */ 125#endif /* __XFS_EXTFREE_ITEM_H__ */
diff --git a/fs/xfs/xfs_fs.h b/fs/xfs/xfs_fs.h
index 6ee8443bf9d3..095af0a5cff3 100644
--- a/fs/xfs/xfs_fs.h
+++ b/fs/xfs/xfs_fs.h
@@ -60,7 +60,8 @@ struct fsxattr {
60 __u32 fsx_xflags; /* xflags field value (get/set) */ 60 __u32 fsx_xflags; /* xflags field value (get/set) */
61 __u32 fsx_extsize; /* extsize field value (get/set)*/ 61 __u32 fsx_extsize; /* extsize field value (get/set)*/
62 __u32 fsx_nextents; /* nextents field value (get) */ 62 __u32 fsx_nextents; /* nextents field value (get) */
63 unsigned char fsx_pad[16]; 63 __u32 fsx_projid; /* project identifier (get/set) */
64 unsigned char fsx_pad[12];
64}; 65};
65#endif 66#endif
66 67
diff --git a/fs/xfs/xfs_fsops.c b/fs/xfs/xfs_fsops.c
index 21213057c27f..ca535d613190 100644
--- a/fs/xfs/xfs_fsops.c
+++ b/fs/xfs/xfs_fsops.c
@@ -559,32 +559,6 @@ xfs_reserve_blocks(
559 return(0); 559 return(0);
560} 560}
561 561
562void
563xfs_fs_log_dummy(xfs_mount_t *mp)
564{
565 xfs_trans_t *tp;
566 xfs_inode_t *ip;
567
568
569 tp = _xfs_trans_alloc(mp, XFS_TRANS_DUMMY1);
570 atomic_inc(&mp->m_active_trans);
571 if (xfs_trans_reserve(tp, 0, XFS_ICHANGE_LOG_RES(mp), 0, 0, 0)) {
572 xfs_trans_cancel(tp, 0);
573 return;
574 }
575
576 ip = mp->m_rootip;
577 xfs_ilock(ip, XFS_ILOCK_EXCL);
578
579 xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL);
580 xfs_trans_ihold(tp, ip);
581 xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
582 xfs_trans_set_sync(tp);
583 xfs_trans_commit(tp, 0, NULL);
584
585 xfs_iunlock(ip, XFS_ILOCK_EXCL);
586}
587
588int 562int
589xfs_fs_goingdown( 563xfs_fs_goingdown(
590 xfs_mount_t *mp, 564 xfs_mount_t *mp,
diff --git a/fs/xfs/xfs_ialloc_btree.h b/fs/xfs/xfs_ialloc_btree.h
index 803c4d17a057..44be188674a6 100644
--- a/fs/xfs/xfs_ialloc_btree.h
+++ b/fs/xfs/xfs_ialloc_btree.h
@@ -100,9 +100,13 @@ xfs_inofree_t xfs_inobt_mask(int i);
100#endif 100#endif
101#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_INOBT_IS_FREE) 101#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_INOBT_IS_FREE)
102int xfs_inobt_is_free(xfs_inobt_rec_t *rp, int i); 102int xfs_inobt_is_free(xfs_inobt_rec_t *rp, int i);
103#define XFS_INOBT_IS_FREE(rp,i) xfs_inobt_is_free(rp,i) 103#define XFS_INOBT_IS_FREE(rp,i) xfs_inobt_is_free(rp,i)
104#define XFS_INOBT_IS_FREE_DISK(rp,i) xfs_inobt_is_free_disk(rp,i)
104#else 105#else
105#define XFS_INOBT_IS_FREE(rp,i) (((rp)->ir_free & XFS_INOBT_MASK(i)) != 0) 106#define XFS_INOBT_IS_FREE(rp,i) \
107 (((rp)->ir_free & XFS_INOBT_MASK(i)) != 0)
108#define XFS_INOBT_IS_FREE_DISK(rp,i) \
109 ((INT_GET((rp)->ir_free, ARCH_CONVERT) & XFS_INOBT_MASK(i)) != 0)
106#endif 110#endif
107#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_INOBT_SET_FREE) 111#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_INOBT_SET_FREE)
108void xfs_inobt_set_free(xfs_inobt_rec_t *rp, int i); 112void xfs_inobt_set_free(xfs_inobt_rec_t *rp, int i);
diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c
index bc8c8c7f9039..34bdf5909687 100644
--- a/fs/xfs/xfs_inode.c
+++ b/fs/xfs/xfs_inode.c
@@ -146,51 +146,6 @@ xfs_inobp_check(
146#endif 146#endif
147 147
148/* 148/*
149 * called from bwrite on xfs inode buffers
150 */
151void
152xfs_inobp_bwcheck(xfs_buf_t *bp)
153{
154 xfs_mount_t *mp;
155 int i;
156 int j;
157 xfs_dinode_t *dip;
158
159 ASSERT(XFS_BUF_FSPRIVATE3(bp, void *) != NULL);
160
161 mp = XFS_BUF_FSPRIVATE3(bp, xfs_mount_t *);
162
163
164 j = mp->m_inode_cluster_size >> mp->m_sb.sb_inodelog;
165
166 for (i = 0; i < j; i++) {
167 dip = (xfs_dinode_t *) xfs_buf_offset(bp,
168 i * mp->m_sb.sb_inodesize);
169 if (INT_GET(dip->di_core.di_magic, ARCH_CONVERT) != XFS_DINODE_MAGIC) {
170 cmn_err(CE_WARN,
171"Bad magic # 0x%x in XFS inode buffer 0x%Lx, starting blockno %Ld, offset 0x%x",
172 INT_GET(dip->di_core.di_magic, ARCH_CONVERT),
173 (__uint64_t)(__psunsigned_t) bp,
174 (__int64_t) XFS_BUF_ADDR(bp),
175 xfs_buf_offset(bp, i * mp->m_sb.sb_inodesize));
176 xfs_fs_cmn_err(CE_WARN, mp,
177 "corrupt, unmount and run xfs_repair");
178 }
179 if (!dip->di_next_unlinked) {
180 cmn_err(CE_WARN,
181"Bad next_unlinked field (0) in XFS inode buffer 0x%p, starting blockno %Ld, offset 0x%x",
182 (__uint64_t)(__psunsigned_t) bp,
183 (__int64_t) XFS_BUF_ADDR(bp),
184 xfs_buf_offset(bp, i * mp->m_sb.sb_inodesize));
185 xfs_fs_cmn_err(CE_WARN, mp,
186 "corrupt, unmount and run xfs_repair");
187 }
188 }
189
190 return;
191}
192
193/*
194 * This routine is called to map an inode number within a file 149 * This routine is called to map an inode number within a file
195 * system to the buffer containing the on-disk version of the 150 * system to the buffer containing the on-disk version of the
196 * inode. It returns a pointer to the buffer containing the 151 * inode. It returns a pointer to the buffer containing the
@@ -203,7 +158,7 @@ xfs_inobp_bwcheck(xfs_buf_t *bp)
203 * Use xfs_imap() to determine the size and location of the 158 * Use xfs_imap() to determine the size and location of the
204 * buffer to read from disk. 159 * buffer to read from disk.
205 */ 160 */
206int 161STATIC int
207xfs_inotobp( 162xfs_inotobp(
208 xfs_mount_t *mp, 163 xfs_mount_t *mp,
209 xfs_trans_t *tp, 164 xfs_trans_t *tp,
@@ -1247,26 +1202,32 @@ xfs_ialloc(
1247 case S_IFREG: 1202 case S_IFREG:
1248 case S_IFDIR: 1203 case S_IFDIR:
1249 if (unlikely(pip->i_d.di_flags & XFS_DIFLAG_ANY)) { 1204 if (unlikely(pip->i_d.di_flags & XFS_DIFLAG_ANY)) {
1250 if (pip->i_d.di_flags & XFS_DIFLAG_RTINHERIT) { 1205 uint di_flags = 0;
1251 if ((mode & S_IFMT) == S_IFDIR) { 1206
1252 ip->i_d.di_flags |= XFS_DIFLAG_RTINHERIT; 1207 if ((mode & S_IFMT) == S_IFDIR) {
1253 } else { 1208 if (pip->i_d.di_flags & XFS_DIFLAG_RTINHERIT)
1254 ip->i_d.di_flags |= XFS_DIFLAG_REALTIME; 1209 di_flags |= XFS_DIFLAG_RTINHERIT;
1210 } else {
1211 if (pip->i_d.di_flags & XFS_DIFLAG_RTINHERIT) {
1212 di_flags |= XFS_DIFLAG_REALTIME;
1255 ip->i_iocore.io_flags |= XFS_IOCORE_RT; 1213 ip->i_iocore.io_flags |= XFS_IOCORE_RT;
1256 } 1214 }
1257 } 1215 }
1258 if ((pip->i_d.di_flags & XFS_DIFLAG_NOATIME) && 1216 if ((pip->i_d.di_flags & XFS_DIFLAG_NOATIME) &&
1259 xfs_inherit_noatime) 1217 xfs_inherit_noatime)
1260 ip->i_d.di_flags |= XFS_DIFLAG_NOATIME; 1218 di_flags |= XFS_DIFLAG_NOATIME;
1261 if ((pip->i_d.di_flags & XFS_DIFLAG_NODUMP) && 1219 if ((pip->i_d.di_flags & XFS_DIFLAG_NODUMP) &&
1262 xfs_inherit_nodump) 1220 xfs_inherit_nodump)
1263 ip->i_d.di_flags |= XFS_DIFLAG_NODUMP; 1221 di_flags |= XFS_DIFLAG_NODUMP;
1264 if ((pip->i_d.di_flags & XFS_DIFLAG_SYNC) && 1222 if ((pip->i_d.di_flags & XFS_DIFLAG_SYNC) &&
1265 xfs_inherit_sync) 1223 xfs_inherit_sync)
1266 ip->i_d.di_flags |= XFS_DIFLAG_SYNC; 1224 di_flags |= XFS_DIFLAG_SYNC;
1267 if ((pip->i_d.di_flags & XFS_DIFLAG_NOSYMLINKS) && 1225 if ((pip->i_d.di_flags & XFS_DIFLAG_NOSYMLINKS) &&
1268 xfs_inherit_nosymlinks) 1226 xfs_inherit_nosymlinks)
1269 ip->i_d.di_flags |= XFS_DIFLAG_NOSYMLINKS; 1227 di_flags |= XFS_DIFLAG_NOSYMLINKS;
1228 if (pip->i_d.di_flags & XFS_DIFLAG_PROJINHERIT)
1229 di_flags |= XFS_DIFLAG_PROJINHERIT;
1230 ip->i_d.di_flags |= di_flags;
1270 } 1231 }
1271 /* FALLTHROUGH */ 1232 /* FALLTHROUGH */
1272 case S_IFLNK: 1233 case S_IFLNK:
@@ -2156,7 +2117,7 @@ static __inline__ int xfs_inode_clean(xfs_inode_t *ip)
2156 (ip->i_update_core == 0)); 2117 (ip->i_update_core == 0));
2157} 2118}
2158 2119
2159void 2120STATIC void
2160xfs_ifree_cluster( 2121xfs_ifree_cluster(
2161 xfs_inode_t *free_ip, 2122 xfs_inode_t *free_ip,
2162 xfs_trans_t *tp, 2123 xfs_trans_t *tp,
@@ -2875,7 +2836,7 @@ xfs_iunpin(
2875 * be subsequently pinned once someone is waiting for it to be 2836 * be subsequently pinned once someone is waiting for it to be
2876 * unpinned. 2837 * unpinned.
2877 */ 2838 */
2878void 2839STATIC void
2879xfs_iunpin_wait( 2840xfs_iunpin_wait(
2880 xfs_inode_t *ip) 2841 xfs_inode_t *ip)
2881{ 2842{
@@ -3601,107 +3562,43 @@ corrupt_out:
3601 3562
3602 3563
3603/* 3564/*
3604 * Flush all inactive inodes in mp. Return true if no user references 3565 * Flush all inactive inodes in mp.
3605 * were found, false otherwise.
3606 */ 3566 */
3607int 3567void
3608xfs_iflush_all( 3568xfs_iflush_all(
3609 xfs_mount_t *mp, 3569 xfs_mount_t *mp)
3610 int flag)
3611{ 3570{
3612 int busy;
3613 int done;
3614 int purged;
3615 xfs_inode_t *ip; 3571 xfs_inode_t *ip;
3616 vmap_t vmap;
3617 vnode_t *vp; 3572 vnode_t *vp;
3618 3573
3619 busy = done = 0; 3574 again:
3620 while (!done) { 3575 XFS_MOUNT_ILOCK(mp);
3621 purged = 0; 3576 ip = mp->m_inodes;
3622 XFS_MOUNT_ILOCK(mp); 3577 if (ip == NULL)
3623 ip = mp->m_inodes; 3578 goto out;
3624 if (ip == NULL) {
3625 break;
3626 }
3627 do {
3628 /* Make sure we skip markers inserted by sync */
3629 if (ip->i_mount == NULL) {
3630 ip = ip->i_mnext;
3631 continue;
3632 }
3633
3634 /*
3635 * It's up to our caller to purge the root
3636 * and quota vnodes later.
3637 */
3638 vp = XFS_ITOV_NULL(ip);
3639
3640 if (!vp) {
3641 XFS_MOUNT_IUNLOCK(mp);
3642 xfs_finish_reclaim(ip, 0, XFS_IFLUSH_ASYNC);
3643 purged = 1;
3644 break;
3645 }
3646 3579
3647 if (vn_count(vp) != 0) { 3580 do {
3648 if (vn_count(vp) == 1 && 3581 /* Make sure we skip markers inserted by sync */
3649 (ip == mp->m_rootip || 3582 if (ip->i_mount == NULL) {
3650 (mp->m_quotainfo && 3583 ip = ip->i_mnext;
3651 (ip->i_ino == mp->m_sb.sb_uquotino || 3584 continue;
3652 ip->i_ino == mp->m_sb.sb_gquotino)))) { 3585 }
3653 3586
3654 ip = ip->i_mnext; 3587 vp = XFS_ITOV_NULL(ip);
3655 continue; 3588 if (!vp) {
3656 }
3657 if (!(flag & XFS_FLUSH_ALL)) {
3658 busy = 1;
3659 done = 1;
3660 break;
3661 }
3662 /*
3663 * Ignore busy inodes but continue flushing
3664 * others.
3665 */
3666 ip = ip->i_mnext;
3667 continue;
3668 }
3669 /*
3670 * Sample vp mapping while holding mp locked on MP
3671 * systems, so we don't purge a reclaimed or
3672 * nonexistent vnode. We break from the loop
3673 * since we know that we modify
3674 * it by pulling ourselves from it in xfs_reclaim()
3675 * called via vn_purge() below. Set ip to the next
3676 * entry in the list anyway so we'll know below
3677 * whether we reached the end or not.
3678 */
3679 VMAP(vp, vmap);
3680 XFS_MOUNT_IUNLOCK(mp); 3589 XFS_MOUNT_IUNLOCK(mp);
3590 xfs_finish_reclaim(ip, 0, XFS_IFLUSH_ASYNC);
3591 goto again;
3592 }
3681 3593
3682 vn_purge(vp, &vmap); 3594 ASSERT(vn_count(vp) == 0);
3683 3595
3684 purged = 1; 3596 ip = ip->i_mnext;
3685 break; 3597 } while (ip != mp->m_inodes);
3686 } while (ip != mp->m_inodes); 3598 out:
3687 /*
3688 * We need to distinguish between when we exit the loop
3689 * after a purge and when we simply hit the end of the
3690 * list. We can't use the (ip == mp->m_inodes) test,
3691 * because when we purge an inode at the start of the list
3692 * the next inode on the list becomes mp->m_inodes. That
3693 * would cause such a test to bail out early. The purged
3694 * variable tells us how we got out of the loop.
3695 */
3696 if (!purged) {
3697 done = 1;
3698 }
3699 }
3700 XFS_MOUNT_IUNLOCK(mp); 3599 XFS_MOUNT_IUNLOCK(mp);
3701 return !busy;
3702} 3600}
3703 3601
3704
3705/* 3602/*
3706 * xfs_iaccess: check accessibility of inode for mode. 3603 * xfs_iaccess: check accessibility of inode for mode.
3707 */ 3604 */
diff --git a/fs/xfs/xfs_inode.h b/fs/xfs/xfs_inode.h
index 37e1c316f3b6..54d9e54c7c95 100644
--- a/fs/xfs/xfs_inode.h
+++ b/fs/xfs/xfs_inode.h
@@ -412,11 +412,6 @@ void xfs_ifork_next_set(xfs_inode_t *ip, int w, int n);
412#define XFS_IFLUSH_DELWRI 5 412#define XFS_IFLUSH_DELWRI 5
413 413
414/* 414/*
415 * Flags for xfs_iflush_all.
416 */
417#define XFS_FLUSH_ALL 0x1
418
419/*
420 * Flags for xfs_itruncate_start(). 415 * Flags for xfs_itruncate_start().
421 */ 416 */
422#define XFS_ITRUNC_DEFINITE 0x1 417#define XFS_ITRUNC_DEFINITE 0x1
@@ -487,8 +482,6 @@ int xfs_finish_reclaim_all(struct xfs_mount *, int);
487/* 482/*
488 * xfs_inode.c prototypes. 483 * xfs_inode.c prototypes.
489 */ 484 */
490int xfs_inotobp(struct xfs_mount *, struct xfs_trans *, xfs_ino_t,
491 xfs_dinode_t **, struct xfs_buf **, int *);
492int xfs_itobp(struct xfs_mount *, struct xfs_trans *, 485int xfs_itobp(struct xfs_mount *, struct xfs_trans *,
493 xfs_inode_t *, xfs_dinode_t **, struct xfs_buf **, 486 xfs_inode_t *, xfs_dinode_t **, struct xfs_buf **,
494 xfs_daddr_t); 487 xfs_daddr_t);
@@ -522,7 +515,7 @@ void xfs_ipin(xfs_inode_t *);
522void xfs_iunpin(xfs_inode_t *); 515void xfs_iunpin(xfs_inode_t *);
523int xfs_iextents_copy(xfs_inode_t *, xfs_bmbt_rec_t *, int); 516int xfs_iextents_copy(xfs_inode_t *, xfs_bmbt_rec_t *, int);
524int xfs_iflush(xfs_inode_t *, uint); 517int xfs_iflush(xfs_inode_t *, uint);
525int xfs_iflush_all(struct xfs_mount *, int); 518void xfs_iflush_all(struct xfs_mount *);
526int xfs_iaccess(xfs_inode_t *, mode_t, cred_t *); 519int xfs_iaccess(xfs_inode_t *, mode_t, cred_t *);
527uint xfs_iroundup(uint); 520uint xfs_iroundup(uint);
528void xfs_ichgtime(xfs_inode_t *, int); 521void xfs_ichgtime(xfs_inode_t *, int);
diff --git a/fs/xfs/xfs_inode_item.c b/fs/xfs/xfs_inode_item.c
index 768cb1816b8e..0eed30f5cb19 100644
--- a/fs/xfs/xfs_inode_item.c
+++ b/fs/xfs/xfs_inode_item.c
@@ -910,7 +910,7 @@ xfs_inode_item_committing(
910/* 910/*
911 * This is the ops vector shared by all buf log items. 911 * This is the ops vector shared by all buf log items.
912 */ 912 */
913struct xfs_item_ops xfs_inode_item_ops = { 913STATIC struct xfs_item_ops xfs_inode_item_ops = {
914 .iop_size = (uint(*)(xfs_log_item_t*))xfs_inode_item_size, 914 .iop_size = (uint(*)(xfs_log_item_t*))xfs_inode_item_size,
915 .iop_format = (void(*)(xfs_log_item_t*, xfs_log_iovec_t*)) 915 .iop_format = (void(*)(xfs_log_item_t*, xfs_log_iovec_t*))
916 xfs_inode_item_format, 916 xfs_inode_item_format,
diff --git a/fs/xfs/xfs_iomap.c b/fs/xfs/xfs_iomap.c
index 469e1a7939d4..2edd6769e5d3 100644
--- a/fs/xfs/xfs_iomap.c
+++ b/fs/xfs/xfs_iomap.c
@@ -385,15 +385,15 @@ xfs_iomap_write_direct(
385 int nimaps, maps; 385 int nimaps, maps;
386 int error; 386 int error;
387 int bmapi_flag; 387 int bmapi_flag;
388 int quota_flag;
388 int rt; 389 int rt;
389 xfs_trans_t *tp; 390 xfs_trans_t *tp;
390 xfs_bmbt_irec_t imap[XFS_WRITE_IMAPS], *imapp; 391 xfs_bmbt_irec_t imap[XFS_WRITE_IMAPS], *imapp;
391 xfs_bmap_free_t free_list; 392 xfs_bmap_free_t free_list;
392 int aeof; 393 int aeof;
393 xfs_filblks_t datablocks; 394 xfs_filblks_t datablocks, qblocks, resblks;
394 int committed; 395 int committed;
395 int numrtextents; 396 int numrtextents;
396 uint resblks;
397 397
398 /* 398 /*
399 * Make sure that the dquots are there. This doesn't hold 399 * Make sure that the dquots are there. This doesn't hold
@@ -419,7 +419,6 @@ xfs_iomap_write_direct(
419 xfs_fileoff_t map_last_fsb; 419 xfs_fileoff_t map_last_fsb;
420 420
421 map_last_fsb = ret_imap->br_blockcount + ret_imap->br_startoff; 421 map_last_fsb = ret_imap->br_blockcount + ret_imap->br_startoff;
422
423 if (map_last_fsb < last_fsb) { 422 if (map_last_fsb < last_fsb) {
424 last_fsb = map_last_fsb; 423 last_fsb = map_last_fsb;
425 count_fsb = last_fsb - offset_fsb; 424 count_fsb = last_fsb - offset_fsb;
@@ -428,56 +427,47 @@ xfs_iomap_write_direct(
428 } 427 }
429 428
430 /* 429 /*
431 * determine if reserving space on 430 * Determine if reserving space on the data or realtime partition.
432 * the data or realtime partition.
433 */ 431 */
434 if ((rt = XFS_IS_REALTIME_INODE(ip))) { 432 if ((rt = XFS_IS_REALTIME_INODE(ip))) {
435 int sbrtextsize, iprtextsize; 433 xfs_extlen_t extsz;
436 434
437 sbrtextsize = mp->m_sb.sb_rextsize; 435 if (!(extsz = ip->i_d.di_extsize))
438 iprtextsize = 436 extsz = mp->m_sb.sb_rextsize;
439 ip->i_d.di_extsize ? ip->i_d.di_extsize : sbrtextsize; 437 numrtextents = qblocks = (count_fsb + extsz - 1);
440 numrtextents = (count_fsb + iprtextsize - 1); 438 do_div(numrtextents, mp->m_sb.sb_rextsize);
441 do_div(numrtextents, sbrtextsize); 439 quota_flag = XFS_QMOPT_RES_RTBLKS;
442 datablocks = 0; 440 datablocks = 0;
443 } else { 441 } else {
444 datablocks = count_fsb; 442 datablocks = qblocks = count_fsb;
443 quota_flag = XFS_QMOPT_RES_REGBLKS;
445 numrtextents = 0; 444 numrtextents = 0;
446 } 445 }
447 446
448 /* 447 /*
449 * allocate and setup the transaction 448 * Allocate and setup the transaction
450 */ 449 */
451 xfs_iunlock(ip, XFS_ILOCK_EXCL); 450 xfs_iunlock(ip, XFS_ILOCK_EXCL);
452 tp = xfs_trans_alloc(mp, XFS_TRANS_DIOSTRAT); 451 tp = xfs_trans_alloc(mp, XFS_TRANS_DIOSTRAT);
453
454 resblks = XFS_DIOSTRAT_SPACE_RES(mp, datablocks); 452 resblks = XFS_DIOSTRAT_SPACE_RES(mp, datablocks);
455
456 error = xfs_trans_reserve(tp, resblks, 453 error = xfs_trans_reserve(tp, resblks,
457 XFS_WRITE_LOG_RES(mp), numrtextents, 454 XFS_WRITE_LOG_RES(mp), numrtextents,
458 XFS_TRANS_PERM_LOG_RES, 455 XFS_TRANS_PERM_LOG_RES,
459 XFS_WRITE_LOG_COUNT); 456 XFS_WRITE_LOG_COUNT);
460 457
461 /* 458 /*
462 * check for running out of space 459 * Check for running out of space, note: need lock to return
463 */ 460 */
464 if (error) 461 if (error)
465 /*
466 * Free the transaction structure.
467 */
468 xfs_trans_cancel(tp, 0); 462 xfs_trans_cancel(tp, 0);
469
470 xfs_ilock(ip, XFS_ILOCK_EXCL); 463 xfs_ilock(ip, XFS_ILOCK_EXCL);
471
472 if (error) 464 if (error)
473 goto error_out; /* Don't return in above if .. trans .., 465 goto error_out;
474 need lock to return */
475 466
476 if (XFS_TRANS_RESERVE_BLKQUOTA(mp, tp, ip, resblks)) { 467 if (XFS_TRANS_RESERVE_QUOTA_NBLKS(mp, tp, ip, qblocks, 0, quota_flag)) {
477 error = (EDQUOT); 468 error = (EDQUOT);
478 goto error1; 469 goto error1;
479 } 470 }
480 nimaps = 1;
481 471
482 bmapi_flag = XFS_BMAPI_WRITE; 472 bmapi_flag = XFS_BMAPI_WRITE;
483 xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL); 473 xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL);
@@ -487,31 +477,29 @@ xfs_iomap_write_direct(
487 bmapi_flag |= XFS_BMAPI_PREALLOC; 477 bmapi_flag |= XFS_BMAPI_PREALLOC;
488 478
489 /* 479 /*
490 * issue the bmapi() call to allocate the blocks 480 * Issue the bmapi() call to allocate the blocks
491 */ 481 */
492 XFS_BMAP_INIT(&free_list, &firstfsb); 482 XFS_BMAP_INIT(&free_list, &firstfsb);
483 nimaps = 1;
493 imapp = &imap[0]; 484 imapp = &imap[0];
494 error = xfs_bmapi(tp, ip, offset_fsb, count_fsb, 485 error = xfs_bmapi(tp, ip, offset_fsb, count_fsb,
495 bmapi_flag, &firstfsb, 0, imapp, &nimaps, &free_list); 486 bmapi_flag, &firstfsb, 0, imapp, &nimaps, &free_list);
496 if (error) { 487 if (error)
497 goto error0; 488 goto error0;
498 }
499 489
500 /* 490 /*
501 * complete the transaction 491 * Complete the transaction
502 */ 492 */
503
504 error = xfs_bmap_finish(&tp, &free_list, firstfsb, &committed); 493 error = xfs_bmap_finish(&tp, &free_list, firstfsb, &committed);
505 if (error) { 494 if (error)
506 goto error0; 495 goto error0;
507 }
508
509 error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES, NULL); 496 error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES, NULL);
510 if (error) { 497 if (error)
511 goto error_out; 498 goto error_out;
512 }
513 499
514 /* copy any maps to caller's array and return any error. */ 500 /*
501 * Copy any maps to caller's array and return any error.
502 */
515 if (nimaps == 0) { 503 if (nimaps == 0) {
516 error = (ENOSPC); 504 error = (ENOSPC);
517 goto error_out; 505 goto error_out;
@@ -530,10 +518,11 @@ xfs_iomap_write_direct(
530 } 518 }
531 return 0; 519 return 0;
532 520
533 error0: /* Cancel bmap, unlock inode, and cancel trans */ 521error0: /* Cancel bmap, unlock inode, unreserve quota blocks, cancel trans */
534 xfs_bmap_cancel(&free_list); 522 xfs_bmap_cancel(&free_list);
523 XFS_TRANS_UNRESERVE_QUOTA_NBLKS(mp, tp, ip, qblocks, 0, quota_flag);
535 524
536 error1: /* Just cancel transaction */ 525error1: /* Just cancel transaction */
537 xfs_trans_cancel(tp, XFS_TRANS_RELEASE_LOG_RES | XFS_TRANS_ABORT); 526 xfs_trans_cancel(tp, XFS_TRANS_RELEASE_LOG_RES | XFS_TRANS_ABORT);
538 *nmaps = 0; /* nothing set-up here */ 527 *nmaps = 0; /* nothing set-up here */
539 528
diff --git a/fs/xfs/xfs_log.c b/fs/xfs/xfs_log.c
index 092d5fb096b1..1cd2ac163877 100644
--- a/fs/xfs/xfs_log.c
+++ b/fs/xfs/xfs_log.c
@@ -134,7 +134,7 @@ STATIC void xlog_verify_tail_lsn(xlog_t *log, xlog_in_core_t *iclog,
134#define xlog_verify_tail_lsn(a,b,c) 134#define xlog_verify_tail_lsn(a,b,c)
135#endif 135#endif
136 136
137int xlog_iclogs_empty(xlog_t *log); 137STATIC int xlog_iclogs_empty(xlog_t *log);
138 138
139#ifdef DEBUG 139#ifdef DEBUG
140int xlog_do_error = 0; 140int xlog_do_error = 0;
@@ -1857,7 +1857,7 @@ xlog_write(xfs_mount_t * mp,
1857 * 1857 *
1858 * State Change: DIRTY -> ACTIVE 1858 * State Change: DIRTY -> ACTIVE
1859 */ 1859 */
1860void 1860STATIC void
1861xlog_state_clean_log(xlog_t *log) 1861xlog_state_clean_log(xlog_t *log)
1862{ 1862{
1863 xlog_in_core_t *iclog; 1863 xlog_in_core_t *iclog;
@@ -3542,7 +3542,7 @@ xfs_log_force_umount(
3542 return (retval); 3542 return (retval);
3543} 3543}
3544 3544
3545int 3545STATIC int
3546xlog_iclogs_empty(xlog_t *log) 3546xlog_iclogs_empty(xlog_t *log)
3547{ 3547{
3548 xlog_in_core_t *iclog; 3548 xlog_in_core_t *iclog;
diff --git a/fs/xfs/xfs_log_priv.h b/fs/xfs/xfs_log_priv.h
index c31e3ce3be66..1a1d452f15f9 100644
--- a/fs/xfs/xfs_log_priv.h
+++ b/fs/xfs/xfs_log_priv.h
@@ -535,7 +535,6 @@ typedef struct log {
535 535
536/* common routines */ 536/* common routines */
537extern xfs_lsn_t xlog_assign_tail_lsn(struct xfs_mount *mp); 537extern xfs_lsn_t xlog_assign_tail_lsn(struct xfs_mount *mp);
538extern int xlog_find_head(xlog_t *log, xfs_daddr_t *head_blk);
539extern int xlog_find_tail(xlog_t *log, 538extern int xlog_find_tail(xlog_t *log,
540 xfs_daddr_t *head_blk, 539 xfs_daddr_t *head_blk,
541 xfs_daddr_t *tail_blk, 540 xfs_daddr_t *tail_blk,
@@ -548,7 +547,6 @@ extern void xlog_recover_process_iunlinks(xlog_t *log);
548extern struct xfs_buf *xlog_get_bp(xlog_t *, int); 547extern struct xfs_buf *xlog_get_bp(xlog_t *, int);
549extern void xlog_put_bp(struct xfs_buf *); 548extern void xlog_put_bp(struct xfs_buf *);
550extern int xlog_bread(xlog_t *, xfs_daddr_t, int, struct xfs_buf *); 549extern int xlog_bread(xlog_t *, xfs_daddr_t, int, struct xfs_buf *);
551extern xfs_caddr_t xlog_align(xlog_t *, xfs_daddr_t, int, struct xfs_buf *);
552 550
553/* iclog tracing */ 551/* iclog tracing */
554#define XLOG_TRACE_GRAB_FLUSH 1 552#define XLOG_TRACE_GRAB_FLUSH 1
diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c
index 9824b5bf0ec0..0aac28ddb81c 100644
--- a/fs/xfs/xfs_log_recover.c
+++ b/fs/xfs/xfs_log_recover.c
@@ -148,7 +148,7 @@ xlog_bread(
148 * The buffer is kept locked across the write and is returned locked. 148 * The buffer is kept locked across the write and is returned locked.
149 * This can only be used for synchronous log writes. 149 * This can only be used for synchronous log writes.
150 */ 150 */
151int 151STATIC int
152xlog_bwrite( 152xlog_bwrite(
153 xlog_t *log, 153 xlog_t *log,
154 xfs_daddr_t blk_no, 154 xfs_daddr_t blk_no,
@@ -179,7 +179,7 @@ xlog_bwrite(
179 return error; 179 return error;
180} 180}
181 181
182xfs_caddr_t 182STATIC xfs_caddr_t
183xlog_align( 183xlog_align(
184 xlog_t *log, 184 xlog_t *log,
185 xfs_daddr_t blk_no, 185 xfs_daddr_t blk_no,
@@ -528,7 +528,7 @@ out:
528 * 528 *
529 * Return: zero if normal, non-zero if error. 529 * Return: zero if normal, non-zero if error.
530 */ 530 */
531int 531STATIC int
532xlog_find_head( 532xlog_find_head(
533 xlog_t *log, 533 xlog_t *log,
534 xfs_daddr_t *return_head_blk) 534 xfs_daddr_t *return_head_blk)
@@ -1964,7 +1964,8 @@ xlog_recover_do_reg_buffer(
1964 * probably a good thing to do for other buf types also. 1964 * probably a good thing to do for other buf types also.
1965 */ 1965 */
1966 error = 0; 1966 error = 0;
1967 if (buf_f->blf_flags & (XFS_BLI_UDQUOT_BUF|XFS_BLI_GDQUOT_BUF)) { 1967 if (buf_f->blf_flags &
1968 (XFS_BLI_UDQUOT_BUF|XFS_BLI_PDQUOT_BUF|XFS_BLI_GDQUOT_BUF)) {
1968 error = xfs_qm_dqcheck((xfs_disk_dquot_t *) 1969 error = xfs_qm_dqcheck((xfs_disk_dquot_t *)
1969 item->ri_buf[i].i_addr, 1970 item->ri_buf[i].i_addr,
1970 -1, 0, XFS_QMOPT_DOWARN, 1971 -1, 0, XFS_QMOPT_DOWARN,
@@ -2030,6 +2031,7 @@ xfs_qm_dqcheck(
2030 } 2031 }
2031 2032
2032 if (INT_GET(ddq->d_flags, ARCH_CONVERT) != XFS_DQ_USER && 2033 if (INT_GET(ddq->d_flags, ARCH_CONVERT) != XFS_DQ_USER &&
2034 INT_GET(ddq->d_flags, ARCH_CONVERT) != XFS_DQ_PROJ &&
2033 INT_GET(ddq->d_flags, ARCH_CONVERT) != XFS_DQ_GROUP) { 2035 INT_GET(ddq->d_flags, ARCH_CONVERT) != XFS_DQ_GROUP) {
2034 if (flags & XFS_QMOPT_DOWARN) 2036 if (flags & XFS_QMOPT_DOWARN)
2035 cmn_err(CE_ALERT, 2037 cmn_err(CE_ALERT,
@@ -2135,6 +2137,8 @@ xlog_recover_do_dquot_buffer(
2135 type = 0; 2137 type = 0;
2136 if (buf_f->blf_flags & XFS_BLI_UDQUOT_BUF) 2138 if (buf_f->blf_flags & XFS_BLI_UDQUOT_BUF)
2137 type |= XFS_DQ_USER; 2139 type |= XFS_DQ_USER;
2140 if (buf_f->blf_flags & XFS_BLI_PDQUOT_BUF)
2141 type |= XFS_DQ_PROJ;
2138 if (buf_f->blf_flags & XFS_BLI_GDQUOT_BUF) 2142 if (buf_f->blf_flags & XFS_BLI_GDQUOT_BUF)
2139 type |= XFS_DQ_GROUP; 2143 type |= XFS_DQ_GROUP;
2140 /* 2144 /*
@@ -2247,7 +2251,8 @@ xlog_recover_do_buffer_trans(
2247 error = 0; 2251 error = 0;
2248 if (flags & XFS_BLI_INODE_BUF) { 2252 if (flags & XFS_BLI_INODE_BUF) {
2249 error = xlog_recover_do_inode_buffer(mp, item, bp, buf_f); 2253 error = xlog_recover_do_inode_buffer(mp, item, bp, buf_f);
2250 } else if (flags & (XFS_BLI_UDQUOT_BUF | XFS_BLI_GDQUOT_BUF)) { 2254 } else if (flags &
2255 (XFS_BLI_UDQUOT_BUF|XFS_BLI_PDQUOT_BUF|XFS_BLI_GDQUOT_BUF)) {
2251 xlog_recover_do_dquot_buffer(mp, log, item, bp, buf_f); 2256 xlog_recover_do_dquot_buffer(mp, log, item, bp, buf_f);
2252 } else { 2257 } else {
2253 xlog_recover_do_reg_buffer(mp, item, bp, buf_f); 2258 xlog_recover_do_reg_buffer(mp, item, bp, buf_f);
@@ -2619,7 +2624,7 @@ xlog_recover_do_dquot_trans(
2619 * This type of quotas was turned off, so ignore this record. 2624 * This type of quotas was turned off, so ignore this record.
2620 */ 2625 */
2621 type = INT_GET(recddq->d_flags, ARCH_CONVERT) & 2626 type = INT_GET(recddq->d_flags, ARCH_CONVERT) &
2622 (XFS_DQ_USER | XFS_DQ_GROUP); 2627 (XFS_DQ_USER | XFS_DQ_PROJ | XFS_DQ_GROUP);
2623 ASSERT(type); 2628 ASSERT(type);
2624 if (log->l_quotaoffs_flag & type) 2629 if (log->l_quotaoffs_flag & type)
2625 return (0); 2630 return (0);
@@ -2742,7 +2747,6 @@ xlog_recover_do_efd_trans(
2742 xfs_efi_log_item_t *efip = NULL; 2747 xfs_efi_log_item_t *efip = NULL;
2743 xfs_log_item_t *lip; 2748 xfs_log_item_t *lip;
2744 int gen; 2749 int gen;
2745 int nexts;
2746 __uint64_t efi_id; 2750 __uint64_t efi_id;
2747 SPLDECL(s); 2751 SPLDECL(s);
2748 2752
@@ -2777,22 +2781,15 @@ xlog_recover_do_efd_trans(
2777 } 2781 }
2778 lip = xfs_trans_next_ail(mp, lip, &gen, NULL); 2782 lip = xfs_trans_next_ail(mp, lip, &gen, NULL);
2779 } 2783 }
2780 if (lip == NULL) {
2781 AIL_UNLOCK(mp, s);
2782 }
2783 2784
2784 /* 2785 /*
2785 * If we found it, then free it up. If it wasn't there, it 2786 * If we found it, then free it up. If it wasn't there, it
2786 * must have been overwritten in the log. Oh well. 2787 * must have been overwritten in the log. Oh well.
2787 */ 2788 */
2788 if (lip != NULL) { 2789 if (lip != NULL) {
2789 nexts = efip->efi_format.efi_nextents; 2790 xfs_efi_item_free(efip);
2790 if (nexts > XFS_EFI_MAX_FAST_EXTENTS) { 2791 } else {
2791 kmem_free(lip, sizeof(xfs_efi_log_item_t) + 2792 AIL_UNLOCK(mp, s);
2792 ((nexts - 1) * sizeof(xfs_extent_t)));
2793 } else {
2794 kmem_zone_free(xfs_efi_zone, efip);
2795 }
2796 } 2793 }
2797} 2794}
2798 2795
diff --git a/fs/xfs/xfs_macros.c b/fs/xfs/xfs_macros.c
index ce4f46c6b3ab..698c2cd62858 100644
--- a/fs/xfs/xfs_macros.c
+++ b/fs/xfs/xfs_macros.c
@@ -1658,6 +1658,11 @@ xfs_inobt_is_free(xfs_inobt_rec_t *rp, int i)
1658{ 1658{
1659 return XFS_INOBT_IS_FREE(rp, i); 1659 return XFS_INOBT_IS_FREE(rp, i);
1660} 1660}
1661int
1662xfs_inobt_is_free_disk(xfs_inobt_rec_t *rp, int i)
1663{
1664 return XFS_INOBT_IS_FREE_DISK(rp, i);
1665}
1661#endif 1666#endif
1662 1667
1663#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_INOBT_IS_LAST_REC) 1668#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_INOBT_IS_LAST_REC)
diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c
index 2ec967d93e5a..82e1646e6243 100644
--- a/fs/xfs/xfs_mount.c
+++ b/fs/xfs/xfs_mount.c
@@ -64,6 +64,7 @@
64STATIC void xfs_mount_log_sbunit(xfs_mount_t *, __int64_t); 64STATIC void xfs_mount_log_sbunit(xfs_mount_t *, __int64_t);
65STATIC int xfs_uuid_mount(xfs_mount_t *); 65STATIC int xfs_uuid_mount(xfs_mount_t *);
66STATIC void xfs_uuid_unmount(xfs_mount_t *mp); 66STATIC void xfs_uuid_unmount(xfs_mount_t *mp);
67STATIC void xfs_unmountfs_wait(xfs_mount_t *);
67 68
68static struct { 69static struct {
69 short offset; 70 short offset;
@@ -555,7 +556,7 @@ xfs_readsb(xfs_mount_t *mp)
555 * fields from the superblock associated with the given 556 * fields from the superblock associated with the given
556 * mount structure 557 * mount structure
557 */ 558 */
558void 559STATIC void
559xfs_mount_common(xfs_mount_t *mp, xfs_sb_t *sbp) 560xfs_mount_common(xfs_mount_t *mp, xfs_sb_t *sbp)
560{ 561{
561 int i; 562 int i;
@@ -1081,7 +1082,7 @@ xfs_unmountfs(xfs_mount_t *mp, struct cred *cr)
1081 int64_t fsid; 1082 int64_t fsid;
1082#endif 1083#endif
1083 1084
1084 xfs_iflush_all(mp, XFS_FLUSH_ALL); 1085 xfs_iflush_all(mp);
1085 1086
1086 XFS_QM_DQPURGEALL(mp, 1087 XFS_QM_DQPURGEALL(mp,
1087 XFS_QMOPT_UQUOTA | XFS_QMOPT_GQUOTA | XFS_QMOPT_UMOUNTING); 1088 XFS_QMOPT_UQUOTA | XFS_QMOPT_GQUOTA | XFS_QMOPT_UMOUNTING);
@@ -1111,15 +1112,6 @@ xfs_unmountfs(xfs_mount_t *mp, struct cred *cr)
1111 */ 1112 */
1112 ASSERT(mp->m_inodes == NULL); 1113 ASSERT(mp->m_inodes == NULL);
1113 1114
1114 /*
1115 * We may have bufs that are in the process of getting written still.
1116 * We must wait for the I/O completion of those. The sync flag here
1117 * does a two pass iteration thru the bufcache.
1118 */
1119 if (XFS_FORCED_SHUTDOWN(mp)) {
1120 xfs_incore_relse(mp->m_ddev_targp, 0, 1); /* synchronous */
1121 }
1122
1123 xfs_unmountfs_close(mp, cr); 1115 xfs_unmountfs_close(mp, cr);
1124 if ((mp->m_flags & XFS_MOUNT_NOUUID) == 0) 1116 if ((mp->m_flags & XFS_MOUNT_NOUUID) == 0)
1125 xfs_uuid_unmount(mp); 1117 xfs_uuid_unmount(mp);
@@ -1146,7 +1138,7 @@ xfs_unmountfs_close(xfs_mount_t *mp, struct cred *cr)
1146 xfs_free_buftarg(mp->m_ddev_targp, 0); 1138 xfs_free_buftarg(mp->m_ddev_targp, 0);
1147} 1139}
1148 1140
1149void 1141STATIC void
1150xfs_unmountfs_wait(xfs_mount_t *mp) 1142xfs_unmountfs_wait(xfs_mount_t *mp)
1151{ 1143{
1152 if (mp->m_logdev_targp != mp->m_ddev_targp) 1144 if (mp->m_logdev_targp != mp->m_ddev_targp)
diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h
index 30dd08fb9f57..5affba38a577 100644
--- a/fs/xfs/xfs_mount.h
+++ b/fs/xfs/xfs_mount.h
@@ -141,7 +141,7 @@ typedef int (*xfs_dqattach_t)(struct xfs_inode *, uint);
141typedef void (*xfs_dqdetach_t)(struct xfs_inode *); 141typedef void (*xfs_dqdetach_t)(struct xfs_inode *);
142typedef int (*xfs_dqpurgeall_t)(struct xfs_mount *, uint); 142typedef int (*xfs_dqpurgeall_t)(struct xfs_mount *, uint);
143typedef int (*xfs_dqvopalloc_t)(struct xfs_mount *, 143typedef int (*xfs_dqvopalloc_t)(struct xfs_mount *,
144 struct xfs_inode *, uid_t, gid_t, uint, 144 struct xfs_inode *, uid_t, gid_t, prid_t, uint,
145 struct xfs_dquot **, struct xfs_dquot **); 145 struct xfs_dquot **, struct xfs_dquot **);
146typedef void (*xfs_dqvopcreate_t)(struct xfs_trans *, struct xfs_inode *, 146typedef void (*xfs_dqvopcreate_t)(struct xfs_trans *, struct xfs_inode *,
147 struct xfs_dquot *, struct xfs_dquot *); 147 struct xfs_dquot *, struct xfs_dquot *);
@@ -185,8 +185,8 @@ typedef struct xfs_qmops {
185 (*(mp)->m_qm_ops.xfs_dqdetach)(ip) 185 (*(mp)->m_qm_ops.xfs_dqdetach)(ip)
186#define XFS_QM_DQPURGEALL(mp, fl) \ 186#define XFS_QM_DQPURGEALL(mp, fl) \
187 (*(mp)->m_qm_ops.xfs_dqpurgeall)(mp, fl) 187 (*(mp)->m_qm_ops.xfs_dqpurgeall)(mp, fl)
188#define XFS_QM_DQVOPALLOC(mp, ip, uid, gid, fl, dq1, dq2) \ 188#define XFS_QM_DQVOPALLOC(mp, ip, uid, gid, prid, fl, dq1, dq2) \
189 (*(mp)->m_qm_ops.xfs_dqvopalloc)(mp, ip, uid, gid, fl, dq1, dq2) 189 (*(mp)->m_qm_ops.xfs_dqvopalloc)(mp, ip, uid, gid, prid, fl, dq1, dq2)
190#define XFS_QM_DQVOPCREATE(mp, tp, ip, dq1, dq2) \ 190#define XFS_QM_DQVOPCREATE(mp, tp, ip, dq1, dq2) \
191 (*(mp)->m_qm_ops.xfs_dqvopcreate)(tp, ip, dq1, dq2) 191 (*(mp)->m_qm_ops.xfs_dqvopcreate)(tp, ip, dq1, dq2)
192#define XFS_QM_DQVOPRENAME(mp, ip) \ 192#define XFS_QM_DQVOPRENAME(mp, ip) \
@@ -544,7 +544,6 @@ extern void xfs_mount_free(xfs_mount_t *mp, int remove_bhv);
544extern int xfs_mountfs(struct vfs *, xfs_mount_t *mp, int); 544extern int xfs_mountfs(struct vfs *, xfs_mount_t *mp, int);
545 545
546extern int xfs_unmountfs(xfs_mount_t *, struct cred *); 546extern int xfs_unmountfs(xfs_mount_t *, struct cred *);
547extern void xfs_unmountfs_wait(xfs_mount_t *);
548extern void xfs_unmountfs_close(xfs_mount_t *, struct cred *); 547extern void xfs_unmountfs_close(xfs_mount_t *, struct cred *);
549extern int xfs_unmountfs_writesb(xfs_mount_t *); 548extern int xfs_unmountfs_writesb(xfs_mount_t *);
550extern int xfs_unmount_flush(xfs_mount_t *, int); 549extern int xfs_unmount_flush(xfs_mount_t *, int);
diff --git a/fs/xfs/xfs_quota.h b/fs/xfs/xfs_quota.h
index 703ec4efcb41..7134576ae7fa 100644
--- a/fs/xfs/xfs_quota.h
+++ b/fs/xfs/xfs_quota.h
@@ -96,7 +96,7 @@ typedef struct xfs_dqblk {
96 * flags for q_flags field in the dquot. 96 * flags for q_flags field in the dquot.
97 */ 97 */
98#define XFS_DQ_USER 0x0001 /* a user quota */ 98#define XFS_DQ_USER 0x0001 /* a user quota */
99/* #define XFS_DQ_PROJ 0x0002 -- project quota (IRIX) */ 99#define XFS_DQ_PROJ 0x0002 /* project quota */
100#define XFS_DQ_GROUP 0x0004 /* a group quota */ 100#define XFS_DQ_GROUP 0x0004 /* a group quota */
101#define XFS_DQ_FLOCKED 0x0008 /* flush lock taken */ 101#define XFS_DQ_FLOCKED 0x0008 /* flush lock taken */
102#define XFS_DQ_DIRTY 0x0010 /* dquot is dirty */ 102#define XFS_DQ_DIRTY 0x0010 /* dquot is dirty */
@@ -104,6 +104,8 @@ typedef struct xfs_dqblk {
104#define XFS_DQ_INACTIVE 0x0040 /* dq off mplist & hashlist */ 104#define XFS_DQ_INACTIVE 0x0040 /* dq off mplist & hashlist */
105#define XFS_DQ_MARKER 0x0080 /* sentinel */ 105#define XFS_DQ_MARKER 0x0080 /* sentinel */
106 106
107#define XFS_DQ_ALLTYPES (XFS_DQ_USER|XFS_DQ_PROJ|XFS_DQ_GROUP)
108
107/* 109/*
108 * In the worst case, when both user and group quotas are on, 110 * In the worst case, when both user and group quotas are on,
109 * we can have a max of three dquots changing in a single transaction. 111 * we can have a max of three dquots changing in a single transaction.
@@ -124,7 +126,7 @@ typedef struct xfs_dqblk {
124typedef struct xfs_dq_logformat { 126typedef struct xfs_dq_logformat {
125 __uint16_t qlf_type; /* dquot log item type */ 127 __uint16_t qlf_type; /* dquot log item type */
126 __uint16_t qlf_size; /* size of this item */ 128 __uint16_t qlf_size; /* size of this item */
127 xfs_dqid_t qlf_id; /* usr/grp id number : 32 bits */ 129 xfs_dqid_t qlf_id; /* usr/grp/proj id : 32 bits */
128 __int64_t qlf_blkno; /* blkno of dquot buffer */ 130 __int64_t qlf_blkno; /* blkno of dquot buffer */
129 __int32_t qlf_len; /* len of dquot buffer */ 131 __int32_t qlf_len; /* len of dquot buffer */
130 __uint32_t qlf_boffset; /* off of dquot in buffer */ 132 __uint32_t qlf_boffset; /* off of dquot in buffer */
@@ -152,9 +154,9 @@ typedef struct xfs_qoff_logformat {
152#define XFS_UQUOTA_ACCT 0x0001 /* user quota accounting ON */ 154#define XFS_UQUOTA_ACCT 0x0001 /* user quota accounting ON */
153#define XFS_UQUOTA_ENFD 0x0002 /* user quota limits enforced */ 155#define XFS_UQUOTA_ENFD 0x0002 /* user quota limits enforced */
154#define XFS_UQUOTA_CHKD 0x0004 /* quotacheck run on usr quotas */ 156#define XFS_UQUOTA_CHKD 0x0004 /* quotacheck run on usr quotas */
155#define XFS_PQUOTA_ACCT 0x0008 /* (IRIX) project quota accounting ON */ 157#define XFS_PQUOTA_ACCT 0x0008 /* project quota accounting ON */
156#define XFS_GQUOTA_ENFD 0x0010 /* group quota limits enforced */ 158#define XFS_OQUOTA_ENFD 0x0010 /* other (grp/prj) quota limits enforced */
157#define XFS_GQUOTA_CHKD 0x0020 /* quotacheck run on grp quotas */ 159#define XFS_OQUOTA_CHKD 0x0020 /* quotacheck run on other (grp/prj) quotas */
158#define XFS_GQUOTA_ACCT 0x0040 /* group quota accounting ON */ 160#define XFS_GQUOTA_ACCT 0x0040 /* group quota accounting ON */
159 161
160/* 162/*
@@ -162,17 +164,22 @@ typedef struct xfs_qoff_logformat {
162 * are in the process of getting turned off. These flags are in m_qflags but 164 * are in the process of getting turned off. These flags are in m_qflags but
163 * never in sb_qflags. 165 * never in sb_qflags.
164 */ 166 */
165#define XFS_UQUOTA_ACTIVE 0x0080 /* uquotas are being turned off */ 167#define XFS_UQUOTA_ACTIVE 0x0100 /* uquotas are being turned off */
166#define XFS_GQUOTA_ACTIVE 0x0100 /* gquotas are being turned off */ 168#define XFS_PQUOTA_ACTIVE 0x0200 /* pquotas are being turned off */
169#define XFS_GQUOTA_ACTIVE 0x0400 /* gquotas are being turned off */
167 170
168/* 171/*
169 * Checking XFS_IS_*QUOTA_ON() while holding any inode lock guarantees 172 * Checking XFS_IS_*QUOTA_ON() while holding any inode lock guarantees
170 * quota will be not be switched off as long as that inode lock is held. 173 * quota will be not be switched off as long as that inode lock is held.
171 */ 174 */
172#define XFS_IS_QUOTA_ON(mp) ((mp)->m_qflags & (XFS_UQUOTA_ACTIVE | \ 175#define XFS_IS_QUOTA_ON(mp) ((mp)->m_qflags & (XFS_UQUOTA_ACTIVE | \
173 XFS_GQUOTA_ACTIVE)) 176 XFS_GQUOTA_ACTIVE | \
177 XFS_PQUOTA_ACTIVE))
178#define XFS_IS_OQUOTA_ON(mp) ((mp)->m_qflags & (XFS_GQUOTA_ACTIVE | \
179 XFS_PQUOTA_ACTIVE))
174#define XFS_IS_UQUOTA_ON(mp) ((mp)->m_qflags & XFS_UQUOTA_ACTIVE) 180#define XFS_IS_UQUOTA_ON(mp) ((mp)->m_qflags & XFS_UQUOTA_ACTIVE)
175#define XFS_IS_GQUOTA_ON(mp) ((mp)->m_qflags & XFS_GQUOTA_ACTIVE) 181#define XFS_IS_GQUOTA_ON(mp) ((mp)->m_qflags & XFS_GQUOTA_ACTIVE)
182#define XFS_IS_PQUOTA_ON(mp) ((mp)->m_qflags & XFS_PQUOTA_ACTIVE)
176 183
177/* 184/*
178 * Flags to tell various functions what to do. Not all of these are meaningful 185 * Flags to tell various functions what to do. Not all of these are meaningful
@@ -182,7 +189,7 @@ typedef struct xfs_qoff_logformat {
182#define XFS_QMOPT_DQLOCK 0x0000001 /* dqlock */ 189#define XFS_QMOPT_DQLOCK 0x0000001 /* dqlock */
183#define XFS_QMOPT_DQALLOC 0x0000002 /* alloc dquot ondisk if needed */ 190#define XFS_QMOPT_DQALLOC 0x0000002 /* alloc dquot ondisk if needed */
184#define XFS_QMOPT_UQUOTA 0x0000004 /* user dquot requested */ 191#define XFS_QMOPT_UQUOTA 0x0000004 /* user dquot requested */
185#define XFS_QMOPT_GQUOTA 0x0000008 /* group dquot requested */ 192#define XFS_QMOPT_PQUOTA 0x0000008 /* project dquot requested */
186#define XFS_QMOPT_FORCE_RES 0x0000010 /* ignore quota limits */ 193#define XFS_QMOPT_FORCE_RES 0x0000010 /* ignore quota limits */
187#define XFS_QMOPT_DQSUSER 0x0000020 /* don't cache super users dquot */ 194#define XFS_QMOPT_DQSUSER 0x0000020 /* don't cache super users dquot */
188#define XFS_QMOPT_SBVERSION 0x0000040 /* change superblock version num */ 195#define XFS_QMOPT_SBVERSION 0x0000040 /* change superblock version num */
@@ -192,6 +199,7 @@ typedef struct xfs_qoff_logformat {
192#define XFS_QMOPT_DOWARN 0x0000400 /* increase warning cnt if necessary */ 199#define XFS_QMOPT_DOWARN 0x0000400 /* increase warning cnt if necessary */
193#define XFS_QMOPT_ILOCKED 0x0000800 /* inode is already locked (excl) */ 200#define XFS_QMOPT_ILOCKED 0x0000800 /* inode is already locked (excl) */
194#define XFS_QMOPT_DQREPAIR 0x0001000 /* repair dquot, if damaged. */ 201#define XFS_QMOPT_DQREPAIR 0x0001000 /* repair dquot, if damaged. */
202#define XFS_QMOPT_GQUOTA 0x0002000 /* group dquot requested */
195 203
196/* 204/*
197 * flags to xfs_trans_mod_dquot to indicate which field needs to be 205 * flags to xfs_trans_mod_dquot to indicate which field needs to be
@@ -231,7 +239,8 @@ typedef struct xfs_qoff_logformat {
231#define XFS_TRANS_DQ_DELRTBCOUNT XFS_QMOPT_DELRTBCOUNT 239#define XFS_TRANS_DQ_DELRTBCOUNT XFS_QMOPT_DELRTBCOUNT
232 240
233 241
234#define XFS_QMOPT_QUOTALL (XFS_QMOPT_UQUOTA|XFS_QMOPT_GQUOTA) 242#define XFS_QMOPT_QUOTALL \
243 (XFS_QMOPT_UQUOTA | XFS_QMOPT_PQUOTA | XFS_QMOPT_GQUOTA)
235#define XFS_QMOPT_RESBLK_MASK (XFS_QMOPT_RES_REGBLKS | XFS_QMOPT_RES_RTBLKS) 244#define XFS_QMOPT_RESBLK_MASK (XFS_QMOPT_RES_REGBLKS | XFS_QMOPT_RES_RTBLKS)
236 245
237#ifdef __KERNEL__ 246#ifdef __KERNEL__
@@ -246,21 +255,33 @@ typedef struct xfs_qoff_logformat {
246 */ 255 */
247#define XFS_NOT_DQATTACHED(mp, ip) ((XFS_IS_UQUOTA_ON(mp) &&\ 256#define XFS_NOT_DQATTACHED(mp, ip) ((XFS_IS_UQUOTA_ON(mp) &&\
248 (ip)->i_udquot == NULL) || \ 257 (ip)->i_udquot == NULL) || \
249 (XFS_IS_GQUOTA_ON(mp) && \ 258 (XFS_IS_OQUOTA_ON(mp) && \
250 (ip)->i_gdquot == NULL)) 259 (ip)->i_gdquot == NULL))
251 260
252#define XFS_QM_NEED_QUOTACHECK(mp) ((XFS_IS_UQUOTA_ON(mp) && \ 261#define XFS_QM_NEED_QUOTACHECK(mp) \
253 (mp->m_sb.sb_qflags & \ 262 ((XFS_IS_UQUOTA_ON(mp) && \
254 XFS_UQUOTA_CHKD) == 0) || \ 263 (mp->m_sb.sb_qflags & XFS_UQUOTA_CHKD) == 0) || \
255 (XFS_IS_GQUOTA_ON(mp) && \ 264 (XFS_IS_GQUOTA_ON(mp) && \
256 (mp->m_sb.sb_qflags & \ 265 ((mp->m_sb.sb_qflags & XFS_OQUOTA_CHKD) == 0 || \
257 XFS_GQUOTA_CHKD) == 0)) 266 (mp->m_sb.sb_qflags & XFS_PQUOTA_ACCT))) || \
267 (XFS_IS_PQUOTA_ON(mp) && \
268 ((mp->m_sb.sb_qflags & XFS_OQUOTA_CHKD) == 0 || \
269 (mp->m_sb.sb_qflags & XFS_GQUOTA_ACCT))))
270
271#define XFS_MOUNT_QUOTA_SET1 (XFS_UQUOTA_ACCT|XFS_UQUOTA_ENFD|\
272 XFS_UQUOTA_CHKD|XFS_PQUOTA_ACCT|\
273 XFS_OQUOTA_ENFD|XFS_OQUOTA_CHKD)
274
275#define XFS_MOUNT_QUOTA_SET2 (XFS_UQUOTA_ACCT|XFS_UQUOTA_ENFD|\
276 XFS_UQUOTA_CHKD|XFS_GQUOTA_ACCT|\
277 XFS_OQUOTA_ENFD|XFS_OQUOTA_CHKD)
258 278
259#define XFS_MOUNT_QUOTA_ALL (XFS_UQUOTA_ACCT|XFS_UQUOTA_ENFD|\ 279#define XFS_MOUNT_QUOTA_ALL (XFS_UQUOTA_ACCT|XFS_UQUOTA_ENFD|\
260 XFS_UQUOTA_CHKD|XFS_GQUOTA_ACCT|\ 280 XFS_UQUOTA_CHKD|XFS_PQUOTA_ACCT|\
261 XFS_GQUOTA_ENFD|XFS_GQUOTA_CHKD) 281 XFS_OQUOTA_ENFD|XFS_OQUOTA_CHKD|\
282 XFS_GQUOTA_ACCT)
262#define XFS_MOUNT_QUOTA_MASK (XFS_MOUNT_QUOTA_ALL | XFS_UQUOTA_ACTIVE | \ 283#define XFS_MOUNT_QUOTA_MASK (XFS_MOUNT_QUOTA_ALL | XFS_UQUOTA_ACTIVE | \
263 XFS_GQUOTA_ACTIVE) 284 XFS_GQUOTA_ACTIVE | XFS_PQUOTA_ACTIVE)
264 285
265 286
266/* 287/*
@@ -331,15 +352,8 @@ typedef struct xfs_dqtrxops {
331#define XFS_TRANS_UNRESERVE_AND_MOD_DQUOTS(mp, tp) \ 352#define XFS_TRANS_UNRESERVE_AND_MOD_DQUOTS(mp, tp) \
332 XFS_DQTRXOP_VOID(mp, tp, qo_unreserve_and_mod_dquots) 353 XFS_DQTRXOP_VOID(mp, tp, qo_unreserve_and_mod_dquots)
333 354
334#define XFS_TRANS_RESERVE_BLKQUOTA(mp, tp, ip, nblks) \ 355#define XFS_TRANS_UNRESERVE_QUOTA_NBLKS(mp, tp, ip, nblks, ninos, flags) \
335 XFS_TRANS_RESERVE_QUOTA_NBLKS(mp, tp, ip, nblks, 0, \ 356 XFS_TRANS_RESERVE_QUOTA_NBLKS(mp, tp, ip, -(nblks), -(ninos), flags)
336 XFS_QMOPT_RES_REGBLKS)
337#define XFS_TRANS_RESERVE_BLKQUOTA_FORCE(mp, tp, ip, nblks) \
338 XFS_TRANS_RESERVE_QUOTA_NBLKS(mp, tp, ip, nblks, 0, \
339 XFS_QMOPT_RES_REGBLKS | XFS_QMOPT_FORCE_RES)
340#define XFS_TRANS_UNRESERVE_BLKQUOTA(mp, tp, ip, nblks) \
341 XFS_TRANS_RESERVE_QUOTA_NBLKS(mp, tp, ip, -(nblks), 0, \
342 XFS_QMOPT_RES_REGBLKS)
343#define XFS_TRANS_RESERVE_QUOTA(mp, tp, ud, gd, nb, ni, f) \ 357#define XFS_TRANS_RESERVE_QUOTA(mp, tp, ud, gd, nb, ni, f) \
344 XFS_TRANS_RESERVE_QUOTA_BYDQUOTS(mp, tp, ud, gd, nb, ni, \ 358 XFS_TRANS_RESERVE_QUOTA_BYDQUOTS(mp, tp, ud, gd, nb, ni, \
345 f | XFS_QMOPT_RES_REGBLKS) 359 f | XFS_QMOPT_RES_REGBLKS)
diff --git a/fs/xfs/xfs_rename.c b/fs/xfs/xfs_rename.c
index cb13f9a1d45b..23b48ac1cb7e 100644
--- a/fs/xfs/xfs_rename.c
+++ b/fs/xfs/xfs_rename.c
@@ -234,9 +234,6 @@ xfs_lock_for_rename(
234 return 0; 234 return 0;
235} 235}
236 236
237
238int rename_which_error_return = 0;
239
240/* 237/*
241 * xfs_rename 238 * xfs_rename
242 */ 239 */
@@ -316,7 +313,6 @@ xfs_rename(
316 &num_inodes); 313 &num_inodes);
317 314
318 if (error) { 315 if (error) {
319 rename_which_error_return = __LINE__;
320 /* 316 /*
321 * We have nothing locked, no inode references, and 317 * We have nothing locked, no inode references, and
322 * no transaction, so just get out. 318 * no transaction, so just get out.
@@ -332,7 +328,6 @@ xfs_rename(
332 */ 328 */
333 if (target_ip == NULL && (src_dp != target_dp) && 329 if (target_ip == NULL && (src_dp != target_dp) &&
334 target_dp->i_d.di_nlink >= XFS_MAXLINK) { 330 target_dp->i_d.di_nlink >= XFS_MAXLINK) {
335 rename_which_error_return = __LINE__;
336 error = XFS_ERROR(EMLINK); 331 error = XFS_ERROR(EMLINK);
337 xfs_rename_unlock4(inodes, XFS_ILOCK_SHARED); 332 xfs_rename_unlock4(inodes, XFS_ILOCK_SHARED);
338 goto rele_return; 333 goto rele_return;
@@ -359,7 +354,6 @@ xfs_rename(
359 XFS_TRANS_PERM_LOG_RES, XFS_RENAME_LOG_COUNT); 354 XFS_TRANS_PERM_LOG_RES, XFS_RENAME_LOG_COUNT);
360 } 355 }
361 if (error) { 356 if (error) {
362 rename_which_error_return = __LINE__;
363 xfs_trans_cancel(tp, 0); 357 xfs_trans_cancel(tp, 0);
364 goto rele_return; 358 goto rele_return;
365 } 359 }
@@ -369,7 +363,6 @@ xfs_rename(
369 */ 363 */
370 if ((error = XFS_QM_DQVOPRENAME(mp, inodes))) { 364 if ((error = XFS_QM_DQVOPRENAME(mp, inodes))) {
371 xfs_trans_cancel(tp, cancel_flags); 365 xfs_trans_cancel(tp, cancel_flags);
372 rename_which_error_return = __LINE__;
373 goto rele_return; 366 goto rele_return;
374 } 367 }
375 368
@@ -413,7 +406,6 @@ xfs_rename(
413 if (spaceres == 0 && 406 if (spaceres == 0 &&
414 (error = XFS_DIR_CANENTER(mp, tp, target_dp, target_name, 407 (error = XFS_DIR_CANENTER(mp, tp, target_dp, target_name,
415 target_namelen))) { 408 target_namelen))) {
416 rename_which_error_return = __LINE__;
417 goto error_return; 409 goto error_return;
418 } 410 }
419 /* 411 /*
@@ -425,11 +417,9 @@ xfs_rename(
425 target_namelen, src_ip->i_ino, 417 target_namelen, src_ip->i_ino,
426 &first_block, &free_list, spaceres); 418 &first_block, &free_list, spaceres);
427 if (error == ENOSPC) { 419 if (error == ENOSPC) {
428 rename_which_error_return = __LINE__;
429 goto error_return; 420 goto error_return;
430 } 421 }
431 if (error) { 422 if (error) {
432 rename_which_error_return = __LINE__;
433 goto abort_return; 423 goto abort_return;
434 } 424 }
435 xfs_ichgtime(target_dp, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG); 425 xfs_ichgtime(target_dp, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG);
@@ -437,7 +427,6 @@ xfs_rename(
437 if (new_parent && src_is_directory) { 427 if (new_parent && src_is_directory) {
438 error = xfs_bumplink(tp, target_dp); 428 error = xfs_bumplink(tp, target_dp);
439 if (error) { 429 if (error) {
440 rename_which_error_return = __LINE__;
441 goto abort_return; 430 goto abort_return;
442 } 431 }
443 } 432 }
@@ -455,7 +444,6 @@ xfs_rename(
455 if (!(XFS_DIR_ISEMPTY(target_ip->i_mount, target_ip)) || 444 if (!(XFS_DIR_ISEMPTY(target_ip->i_mount, target_ip)) ||
456 (target_ip->i_d.di_nlink > 2)) { 445 (target_ip->i_d.di_nlink > 2)) {
457 error = XFS_ERROR(EEXIST); 446 error = XFS_ERROR(EEXIST);
458 rename_which_error_return = __LINE__;
459 goto error_return; 447 goto error_return;
460 } 448 }
461 } 449 }
@@ -473,7 +461,6 @@ xfs_rename(
473 target_namelen, src_ip->i_ino, &first_block, 461 target_namelen, src_ip->i_ino, &first_block,
474 &free_list, spaceres); 462 &free_list, spaceres);
475 if (error) { 463 if (error) {
476 rename_which_error_return = __LINE__;
477 goto abort_return; 464 goto abort_return;
478 } 465 }
479 xfs_ichgtime(target_dp, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG); 466 xfs_ichgtime(target_dp, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG);
@@ -484,7 +471,6 @@ xfs_rename(
484 */ 471 */
485 error = xfs_droplink(tp, target_ip); 472 error = xfs_droplink(tp, target_ip);
486 if (error) { 473 if (error) {
487 rename_which_error_return = __LINE__;
488 goto abort_return; 474 goto abort_return;
489 } 475 }
490 target_ip_dropped = 1; 476 target_ip_dropped = 1;
@@ -495,7 +481,6 @@ xfs_rename(
495 */ 481 */
496 error = xfs_droplink(tp, target_ip); 482 error = xfs_droplink(tp, target_ip);
497 if (error) { 483 if (error) {
498 rename_which_error_return = __LINE__;
499 goto abort_return; 484 goto abort_return;
500 } 485 }
501 } 486 }
@@ -519,7 +504,6 @@ xfs_rename(
519 &free_list, spaceres); 504 &free_list, spaceres);
520 ASSERT(error != EEXIST); 505 ASSERT(error != EEXIST);
521 if (error) { 506 if (error) {
522 rename_which_error_return = __LINE__;
523 goto abort_return; 507 goto abort_return;
524 } 508 }
525 xfs_ichgtime(src_ip, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG); 509 xfs_ichgtime(src_ip, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG);
@@ -550,7 +534,6 @@ xfs_rename(
550 */ 534 */
551 error = xfs_droplink(tp, src_dp); 535 error = xfs_droplink(tp, src_dp);
552 if (error) { 536 if (error) {
553 rename_which_error_return = __LINE__;
554 goto abort_return; 537 goto abort_return;
555 } 538 }
556 } 539 }
@@ -558,7 +541,6 @@ xfs_rename(
558 error = XFS_DIR_REMOVENAME(mp, tp, src_dp, src_name, src_namelen, 541 error = XFS_DIR_REMOVENAME(mp, tp, src_dp, src_name, src_namelen,
559 src_ip->i_ino, &first_block, &free_list, spaceres); 542 src_ip->i_ino, &first_block, &free_list, spaceres);
560 if (error) { 543 if (error) {
561 rename_which_error_return = __LINE__;
562 goto abort_return; 544 goto abort_return;
563 } 545 }
564 xfs_ichgtime(src_dp, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG); 546 xfs_ichgtime(src_dp, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG);
diff --git a/fs/xfs/xfs_trans.c b/fs/xfs/xfs_trans.c
index 3db0e2200775..06dfca531f79 100644
--- a/fs/xfs/xfs_trans.c
+++ b/fs/xfs/xfs_trans.c
@@ -332,25 +332,6 @@ undo_blocks:
332 332
333 333
334/* 334/*
335 * This is called to set the a callback to be called when the given
336 * transaction is committed to disk. The transaction pointer and the
337 * argument pointer will be passed to the callback routine.
338 *
339 * Only one callback can be associated with any single transaction.
340 */
341void
342xfs_trans_callback(
343 xfs_trans_t *tp,
344 xfs_trans_callback_t callback,
345 void *arg)
346{
347 ASSERT(tp->t_callback == NULL);
348 tp->t_callback = callback;
349 tp->t_callarg = arg;
350}
351
352
353/*
354 * Record the indicated change to the given field for application 335 * Record the indicated change to the given field for application
355 * to the file system's superblock when the transaction commits. 336 * to the file system's superblock when the transaction commits.
356 * For now, just store the change in the transaction structure. 337 * For now, just store the change in the transaction structure.
@@ -551,7 +532,7 @@ xfs_trans_apply_sb_deltas(
551 * 532 *
552 * This is done efficiently with a single call to xfs_mod_incore_sb_batch(). 533 * This is done efficiently with a single call to xfs_mod_incore_sb_batch().
553 */ 534 */
554void 535STATIC void
555xfs_trans_unreserve_and_mod_sb( 536xfs_trans_unreserve_and_mod_sb(
556 xfs_trans_t *tp) 537 xfs_trans_t *tp)
557{ 538{
diff --git a/fs/xfs/xfs_trans.h b/fs/xfs/xfs_trans.h
index bd37ccb85e76..ec541d66fa2a 100644
--- a/fs/xfs/xfs_trans.h
+++ b/fs/xfs/xfs_trans.h
@@ -987,8 +987,6 @@ xfs_trans_t *_xfs_trans_alloc(struct xfs_mount *, uint);
987xfs_trans_t *xfs_trans_dup(xfs_trans_t *); 987xfs_trans_t *xfs_trans_dup(xfs_trans_t *);
988int xfs_trans_reserve(xfs_trans_t *, uint, uint, uint, 988int xfs_trans_reserve(xfs_trans_t *, uint, uint, uint,
989 uint, uint); 989 uint, uint);
990void xfs_trans_callback(xfs_trans_t *,
991 void (*)(xfs_trans_t *, void *), void *);
992void xfs_trans_mod_sb(xfs_trans_t *, uint, long); 990void xfs_trans_mod_sb(xfs_trans_t *, uint, long);
993struct xfs_buf *xfs_trans_get_buf(xfs_trans_t *, struct xfs_buftarg *, xfs_daddr_t, 991struct xfs_buf *xfs_trans_get_buf(xfs_trans_t *, struct xfs_buftarg *, xfs_daddr_t,
994 int, uint); 992 int, uint);
@@ -1010,7 +1008,6 @@ int xfs_trans_iget(struct xfs_mount *, xfs_trans_t *,
1010 xfs_ino_t , uint, uint, struct xfs_inode **); 1008 xfs_ino_t , uint, uint, struct xfs_inode **);
1011void xfs_trans_ijoin(xfs_trans_t *, struct xfs_inode *, uint); 1009void xfs_trans_ijoin(xfs_trans_t *, struct xfs_inode *, uint);
1012void xfs_trans_ihold(xfs_trans_t *, struct xfs_inode *); 1010void xfs_trans_ihold(xfs_trans_t *, struct xfs_inode *);
1013void xfs_trans_ihold_release(xfs_trans_t *, struct xfs_inode *);
1014void xfs_trans_log_buf(xfs_trans_t *, struct xfs_buf *, uint, uint); 1011void xfs_trans_log_buf(xfs_trans_t *, struct xfs_buf *, uint, uint);
1015void xfs_trans_log_inode(xfs_trans_t *, struct xfs_inode *, uint); 1012void xfs_trans_log_inode(xfs_trans_t *, struct xfs_inode *, uint);
1016struct xfs_efi_log_item *xfs_trans_get_efi(xfs_trans_t *, uint); 1013struct xfs_efi_log_item *xfs_trans_get_efi(xfs_trans_t *, uint);
diff --git a/fs/xfs/xfs_trans_buf.c b/fs/xfs/xfs_trans_buf.c
index a9682b9510c1..144da7a85466 100644
--- a/fs/xfs/xfs_trans_buf.c
+++ b/fs/xfs/xfs_trans_buf.c
@@ -976,6 +976,7 @@ xfs_trans_dquot_buf(
976 ASSERT(XFS_BUF_FSPRIVATE2(bp, xfs_trans_t *) == tp); 976 ASSERT(XFS_BUF_FSPRIVATE2(bp, xfs_trans_t *) == tp);
977 ASSERT(XFS_BUF_FSPRIVATE(bp, void *) != NULL); 977 ASSERT(XFS_BUF_FSPRIVATE(bp, void *) != NULL);
978 ASSERT(type == XFS_BLI_UDQUOT_BUF || 978 ASSERT(type == XFS_BLI_UDQUOT_BUF ||
979 type == XFS_BLI_PDQUOT_BUF ||
979 type == XFS_BLI_GDQUOT_BUF); 980 type == XFS_BLI_GDQUOT_BUF);
980 981
981 bip = XFS_BUF_FSPRIVATE(bp, xfs_buf_log_item_t *); 982 bip = XFS_BUF_FSPRIVATE(bp, xfs_buf_log_item_t *);
diff --git a/fs/xfs/xfs_trans_inode.c b/fs/xfs/xfs_trans_inode.c
index e2c3706f453d..7e7631ca4979 100644
--- a/fs/xfs/xfs_trans_inode.c
+++ b/fs/xfs/xfs_trans_inode.c
@@ -253,24 +253,6 @@ xfs_trans_ihold(
253 ip->i_itemp->ili_flags |= XFS_ILI_HOLD; 253 ip->i_itemp->ili_flags |= XFS_ILI_HOLD;
254} 254}
255 255
256/*
257 * Cancel the previous inode hold request made on this inode
258 * for this transaction.
259 */
260/*ARGSUSED*/
261void
262xfs_trans_ihold_release(
263 xfs_trans_t *tp,
264 xfs_inode_t *ip)
265{
266 ASSERT(ip->i_transp == tp);
267 ASSERT(ip->i_itemp != NULL);
268 ASSERT(ismrlocked(&ip->i_lock, MR_UPDATE));
269 ASSERT(ip->i_itemp->ili_flags & XFS_ILI_HOLD);
270
271 ip->i_itemp->ili_flags &= ~XFS_ILI_HOLD;
272}
273
274 256
275/* 257/*
276 * This is called to mark the fields indicated in fieldmask as needing 258 * This is called to mark the fields indicated in fieldmask as needing
diff --git a/fs/xfs/xfs_types.h b/fs/xfs/xfs_types.h
index e4bf711e48ff..16f5371ce102 100644
--- a/fs/xfs/xfs_types.h
+++ b/fs/xfs/xfs_types.h
@@ -55,7 +55,7 @@ typedef signed long long int __int64_t;
55typedef unsigned long long int __uint64_t; 55typedef unsigned long long int __uint64_t;
56 56
57typedef enum { B_FALSE,B_TRUE } boolean_t; 57typedef enum { B_FALSE,B_TRUE } boolean_t;
58typedef __int64_t prid_t; /* project ID */ 58typedef __uint32_t prid_t; /* project ID */
59typedef __uint32_t inst_t; /* an instruction */ 59typedef __uint32_t inst_t; /* an instruction */
60 60
61typedef __s64 xfs_off_t; /* <file offset> type */ 61typedef __s64 xfs_off_t; /* <file offset> type */
diff --git a/fs/xfs/xfs_utils.c b/fs/xfs/xfs_utils.c
index d1f8146a06ea..11351f08d438 100644
--- a/fs/xfs/xfs_utils.c
+++ b/fs/xfs/xfs_utils.c
@@ -428,7 +428,7 @@ xfs_truncate_file(
428 if (ip->i_ino != mp->m_sb.sb_uquotino) 428 if (ip->i_ino != mp->m_sb.sb_uquotino)
429 ASSERT(ip->i_udquot); 429 ASSERT(ip->i_udquot);
430 } 430 }
431 if (XFS_IS_GQUOTA_ON(mp)) { 431 if (XFS_IS_OQUOTA_ON(mp)) {
432 if (ip->i_ino != mp->m_sb.sb_gquotino) 432 if (ip->i_ino != mp->m_sb.sb_gquotino)
433 ASSERT(ip->i_gdquot); 433 ASSERT(ip->i_gdquot);
434 } 434 }
diff --git a/fs/xfs/xfs_vfsops.c b/fs/xfs/xfs_vfsops.c
index b53736650100..42bcc0215203 100644
--- a/fs/xfs/xfs_vfsops.c
+++ b/fs/xfs/xfs_vfsops.c
@@ -368,16 +368,6 @@ xfs_finish_flags(
368 } 368 }
369 369
370 /* 370 /*
371 * disallow mount attempts with (IRIX) project quota enabled
372 */
373 if (XFS_SB_VERSION_HASQUOTA(&mp->m_sb) &&
374 (mp->m_sb.sb_qflags & XFS_PQUOTA_ACCT)) {
375 cmn_err(CE_WARN,
376 "XFS: cannot mount a filesystem with IRIX project quota enabled");
377 return XFS_ERROR(ENOSYS);
378 }
379
380 /*
381 * check for shared mount. 371 * check for shared mount.
382 */ 372 */
383 if (ap->flags & XFSMNT_SHARED) { 373 if (ap->flags & XFSMNT_SHARED) {
@@ -622,7 +612,34 @@ out:
622 return XFS_ERROR(error); 612 return XFS_ERROR(error);
623} 613}
624 614
625#define REMOUNT_READONLY_FLAGS (SYNC_REMOUNT|SYNC_ATTR|SYNC_WAIT) 615STATIC int
616xfs_quiesce_fs(
617 xfs_mount_t *mp)
618{
619 int count = 0, pincount;
620
621 xfs_refcache_purge_mp(mp);
622 xfs_flush_buftarg(mp->m_ddev_targp, 0);
623 xfs_finish_reclaim_all(mp, 0);
624
625 /* This loop must run at least twice.
626 * The first instance of the loop will flush
627 * most meta data but that will generate more
628 * meta data (typically directory updates).
629 * Which then must be flushed and logged before
630 * we can write the unmount record.
631 */
632 do {
633 xfs_syncsub(mp, SYNC_REMOUNT|SYNC_ATTR|SYNC_WAIT, 0, NULL);
634 pincount = xfs_flush_buftarg(mp->m_ddev_targp, 1);
635 if (!pincount) {
636 delay(50);
637 count++;
638 }
639 } while (count < 2);
640
641 return 0;
642}
626 643
627STATIC int 644STATIC int
628xfs_mntupdate( 645xfs_mntupdate(
@@ -632,8 +649,7 @@ xfs_mntupdate(
632{ 649{
633 struct vfs *vfsp = bhvtovfs(bdp); 650 struct vfs *vfsp = bhvtovfs(bdp);
634 xfs_mount_t *mp = XFS_BHVTOM(bdp); 651 xfs_mount_t *mp = XFS_BHVTOM(bdp);
635 int pincount, error; 652 int error;
636 int count = 0;
637 653
638 if (args->flags & XFSMNT_NOATIME) 654 if (args->flags & XFSMNT_NOATIME)
639 mp->m_flags |= XFS_MOUNT_NOATIME; 655 mp->m_flags |= XFS_MOUNT_NOATIME;
@@ -645,25 +661,7 @@ xfs_mntupdate(
645 } 661 }
646 662
647 if (*flags & MS_RDONLY) { 663 if (*flags & MS_RDONLY) {
648 xfs_refcache_purge_mp(mp); 664 xfs_quiesce_fs(mp);
649 xfs_flush_buftarg(mp->m_ddev_targp, 0);
650 xfs_finish_reclaim_all(mp, 0);
651
652 /* This loop must run at least twice.
653 * The first instance of the loop will flush
654 * most meta data but that will generate more
655 * meta data (typically directory updates).
656 * Which then must be flushed and logged before
657 * we can write the unmount record.
658 */
659 do {
660 VFS_SYNC(vfsp, REMOUNT_READONLY_FLAGS, NULL, error);
661 pincount = xfs_flush_buftarg(mp->m_ddev_targp, 1);
662 if (!pincount) {
663 delay(50);
664 count++;
665 }
666 } while (count < 2);
667 665
668 /* Ok now write out an unmount record */ 666 /* Ok now write out an unmount record */
669 xfs_log_unmount_write(mp); 667 xfs_log_unmount_write(mp);
@@ -879,10 +877,12 @@ xfs_sync(
879 int flags, 877 int flags,
880 cred_t *credp) 878 cred_t *credp)
881{ 879{
882 xfs_mount_t *mp; 880 xfs_mount_t *mp = XFS_BHVTOM(bdp);
883 881
884 mp = XFS_BHVTOM(bdp); 882 if (unlikely(flags == SYNC_QUIESCE))
885 return (xfs_syncsub(mp, flags, 0, NULL)); 883 return xfs_quiesce_fs(mp);
884 else
885 return xfs_syncsub(mp, flags, 0, NULL);
886} 886}
887 887
888/* 888/*
@@ -1681,7 +1681,7 @@ suffix_strtoul(const char *cp, char **endp, unsigned int base)
1681 return simple_strtoul(cp, endp, base) << shift_left_factor; 1681 return simple_strtoul(cp, endp, base) << shift_left_factor;
1682} 1682}
1683 1683
1684int 1684STATIC int
1685xfs_parseargs( 1685xfs_parseargs(
1686 struct bhv_desc *bhv, 1686 struct bhv_desc *bhv,
1687 char *options, 1687 char *options,
@@ -1867,7 +1867,7 @@ printk("XFS: irixsgid is now a sysctl(2) variable, option is deprecated.\n");
1867 return 0; 1867 return 0;
1868} 1868}
1869 1869
1870int 1870STATIC int
1871xfs_showargs( 1871xfs_showargs(
1872 struct bhv_desc *bhv, 1872 struct bhv_desc *bhv,
1873 struct seq_file *m) 1873 struct seq_file *m)
diff --git a/fs/xfs/xfs_vnodeops.c b/fs/xfs/xfs_vnodeops.c
index 25a526629b12..1377c868f3f4 100644
--- a/fs/xfs/xfs_vnodeops.c
+++ b/fs/xfs/xfs_vnodeops.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2000-2004 Silicon Graphics, Inc. All Rights Reserved. 2 * Copyright (c) 2000-2005 Silicon Graphics, Inc. All Rights Reserved.
3 * 3 *
4 * This program is free software; you can redistribute it and/or modify it 4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of version 2 of the GNU General Public License as 5 * under the terms of version 2 of the GNU General Public License as
@@ -351,21 +351,28 @@ xfs_setattr(
351 * If the IDs do change before we take the ilock, we're covered 351 * If the IDs do change before we take the ilock, we're covered
352 * because the i_*dquot fields will get updated anyway. 352 * because the i_*dquot fields will get updated anyway.
353 */ 353 */
354 if (XFS_IS_QUOTA_ON(mp) && (mask & (XFS_AT_UID|XFS_AT_GID))) { 354 if (XFS_IS_QUOTA_ON(mp) &&
355 (mask & (XFS_AT_UID|XFS_AT_GID|XFS_AT_PROJID))) {
355 uint qflags = 0; 356 uint qflags = 0;
356 357
357 if (mask & XFS_AT_UID) { 358 if ((mask & XFS_AT_UID) && XFS_IS_UQUOTA_ON(mp)) {
358 uid = vap->va_uid; 359 uid = vap->va_uid;
359 qflags |= XFS_QMOPT_UQUOTA; 360 qflags |= XFS_QMOPT_UQUOTA;
360 } else { 361 } else {
361 uid = ip->i_d.di_uid; 362 uid = ip->i_d.di_uid;
362 } 363 }
363 if (mask & XFS_AT_GID) { 364 if ((mask & XFS_AT_GID) && XFS_IS_GQUOTA_ON(mp)) {
364 gid = vap->va_gid; 365 gid = vap->va_gid;
365 qflags |= XFS_QMOPT_GQUOTA; 366 qflags |= XFS_QMOPT_GQUOTA;
366 } else { 367 } else {
367 gid = ip->i_d.di_gid; 368 gid = ip->i_d.di_gid;
368 } 369 }
370 if ((mask & XFS_AT_PROJID) && XFS_IS_PQUOTA_ON(mp)) {
371 projid = vap->va_projid;
372 qflags |= XFS_QMOPT_PQUOTA;
373 } else {
374 projid = ip->i_d.di_projid;
375 }
369 /* 376 /*
370 * We take a reference when we initialize udqp and gdqp, 377 * We take a reference when we initialize udqp and gdqp,
371 * so it is important that we never blindly double trip on 378 * so it is important that we never blindly double trip on
@@ -373,7 +380,8 @@ xfs_setattr(
373 */ 380 */
374 ASSERT(udqp == NULL); 381 ASSERT(udqp == NULL);
375 ASSERT(gdqp == NULL); 382 ASSERT(gdqp == NULL);
376 code = XFS_QM_DQVOPALLOC(mp, ip, uid,gid, qflags, &udqp, &gdqp); 383 code = XFS_QM_DQVOPALLOC(mp, ip, uid, gid, projid, qflags,
384 &udqp, &gdqp);
377 if (code) 385 if (code)
378 return (code); 386 return (code);
379 } 387 }
@@ -499,8 +507,6 @@ xfs_setattr(
499 * that the group ID supplied to the chown() function 507 * that the group ID supplied to the chown() function
500 * shall be equal to either the group ID or one of the 508 * shall be equal to either the group ID or one of the
501 * supplementary group IDs of the calling process. 509 * supplementary group IDs of the calling process.
502 *
503 * XXX: How does restricted_chown affect projid?
504 */ 510 */
505 if (restricted_chown && 511 if (restricted_chown &&
506 (iuid != uid || (igid != gid && 512 (iuid != uid || (igid != gid &&
@@ -510,10 +516,11 @@ xfs_setattr(
510 goto error_return; 516 goto error_return;
511 } 517 }
512 /* 518 /*
513 * Do a quota reservation only if uid or gid is actually 519 * Do a quota reservation only if uid/projid/gid is actually
514 * going to change. 520 * going to change.
515 */ 521 */
516 if ((XFS_IS_UQUOTA_ON(mp) && iuid != uid) || 522 if ((XFS_IS_UQUOTA_ON(mp) && iuid != uid) ||
523 (XFS_IS_PQUOTA_ON(mp) && iprojid != projid) ||
517 (XFS_IS_GQUOTA_ON(mp) && igid != gid)) { 524 (XFS_IS_GQUOTA_ON(mp) && igid != gid)) {
518 ASSERT(tp); 525 ASSERT(tp);
519 code = XFS_QM_DQVOPCHOWNRESV(mp, tp, ip, udqp, gdqp, 526 code = XFS_QM_DQVOPCHOWNRESV(mp, tp, ip, udqp, gdqp,
@@ -774,6 +781,7 @@ xfs_setattr(
774 } 781 }
775 if (igid != gid) { 782 if (igid != gid) {
776 if (XFS_IS_GQUOTA_ON(mp)) { 783 if (XFS_IS_GQUOTA_ON(mp)) {
784 ASSERT(!XFS_IS_PQUOTA_ON(mp));
777 ASSERT(mask & XFS_AT_GID); 785 ASSERT(mask & XFS_AT_GID);
778 ASSERT(gdqp); 786 ASSERT(gdqp);
779 olddquot2 = XFS_QM_DQVOPCHOWN(mp, tp, ip, 787 olddquot2 = XFS_QM_DQVOPCHOWN(mp, tp, ip,
@@ -782,6 +790,13 @@ xfs_setattr(
782 ip->i_d.di_gid = gid; 790 ip->i_d.di_gid = gid;
783 } 791 }
784 if (iprojid != projid) { 792 if (iprojid != projid) {
793 if (XFS_IS_PQUOTA_ON(mp)) {
794 ASSERT(!XFS_IS_GQUOTA_ON(mp));
795 ASSERT(mask & XFS_AT_PROJID);
796 ASSERT(gdqp);
797 olddquot2 = XFS_QM_DQVOPCHOWN(mp, tp, ip,
798 &ip->i_gdquot, gdqp);
799 }
785 ip->i_d.di_projid = projid; 800 ip->i_d.di_projid = projid;
786 /* 801 /*
787 * We may have to rev the inode as well as 802 * We may have to rev the inode as well as
@@ -843,6 +858,8 @@ xfs_setattr(
843 di_flags |= XFS_DIFLAG_NOATIME; 858 di_flags |= XFS_DIFLAG_NOATIME;
844 if (vap->va_xflags & XFS_XFLAG_NODUMP) 859 if (vap->va_xflags & XFS_XFLAG_NODUMP)
845 di_flags |= XFS_DIFLAG_NODUMP; 860 di_flags |= XFS_DIFLAG_NODUMP;
861 if (vap->va_xflags & XFS_XFLAG_PROJINHERIT)
862 di_flags |= XFS_DIFLAG_PROJINHERIT;
846 if ((ip->i_d.di_mode & S_IFMT) == S_IFDIR) { 863 if ((ip->i_d.di_mode & S_IFMT) == S_IFDIR) {
847 if (vap->va_xflags & XFS_XFLAG_RTINHERIT) 864 if (vap->va_xflags & XFS_XFLAG_RTINHERIT)
848 di_flags |= XFS_DIFLAG_RTINHERIT; 865 di_flags |= XFS_DIFLAG_RTINHERIT;
@@ -1898,7 +1915,9 @@ xfs_create(
1898 /* Return through std_return after this point. */ 1915 /* Return through std_return after this point. */
1899 1916
1900 udqp = gdqp = NULL; 1917 udqp = gdqp = NULL;
1901 if (vap->va_mask & XFS_AT_PROJID) 1918 if (dp->i_d.di_flags & XFS_DIFLAG_PROJINHERIT)
1919 prid = dp->i_d.di_projid;
1920 else if (vap->va_mask & XFS_AT_PROJID)
1902 prid = (xfs_prid_t)vap->va_projid; 1921 prid = (xfs_prid_t)vap->va_projid;
1903 else 1922 else
1904 prid = (xfs_prid_t)dfltprid; 1923 prid = (xfs_prid_t)dfltprid;
@@ -1907,7 +1926,7 @@ xfs_create(
1907 * Make sure that we have allocated dquot(s) on disk. 1926 * Make sure that we have allocated dquot(s) on disk.
1908 */ 1927 */
1909 error = XFS_QM_DQVOPALLOC(mp, dp, 1928 error = XFS_QM_DQVOPALLOC(mp, dp,
1910 current_fsuid(credp), current_fsgid(credp), 1929 current_fsuid(credp), current_fsgid(credp), prid,
1911 XFS_QMOPT_QUOTALL|XFS_QMOPT_INHERIT, &udqp, &gdqp); 1930 XFS_QMOPT_QUOTALL|XFS_QMOPT_INHERIT, &udqp, &gdqp);
1912 if (error) 1931 if (error)
1913 goto std_return; 1932 goto std_return;
@@ -2604,17 +2623,7 @@ xfs_link(
2604 if (src_vp->v_type == VDIR) 2623 if (src_vp->v_type == VDIR)
2605 return XFS_ERROR(EPERM); 2624 return XFS_ERROR(EPERM);
2606 2625
2607 /*
2608 * For now, manually find the XFS behavior descriptor for
2609 * the source vnode. If it doesn't exist then something
2610 * is wrong and we should just return an error.
2611 * Eventually we need to figure out how link is going to
2612 * work in the face of stacked vnodes.
2613 */
2614 src_bdp = vn_bhv_lookup_unlocked(VN_BHV_HEAD(src_vp), &xfs_vnodeops); 2626 src_bdp = vn_bhv_lookup_unlocked(VN_BHV_HEAD(src_vp), &xfs_vnodeops);
2615 if (src_bdp == NULL) {
2616 return XFS_ERROR(EXDEV);
2617 }
2618 sip = XFS_BHVTOI(src_bdp); 2627 sip = XFS_BHVTOI(src_bdp);
2619 tdp = XFS_BHVTOI(target_dir_bdp); 2628 tdp = XFS_BHVTOI(target_dir_bdp);
2620 mp = tdp->i_mount; 2629 mp = tdp->i_mount;
@@ -2681,6 +2690,17 @@ xfs_link(
2681 goto error_return; 2690 goto error_return;
2682 } 2691 }
2683 2692
2693 /*
2694 * If we are using project inheritance, we only allow hard link
2695 * creation in our tree when the project IDs are the same; else
2696 * the tree quota mechanism could be circumvented.
2697 */
2698 if (unlikely((tdp->i_d.di_flags & XFS_DIFLAG_PROJINHERIT) &&
2699 (tdp->i_d.di_projid != sip->i_d.di_projid))) {
2700 error = XFS_ERROR(EPERM);
2701 goto error_return;
2702 }
2703
2684 if (resblks == 0 && 2704 if (resblks == 0 &&
2685 (error = XFS_DIR_CANENTER(mp, tp, tdp, target_name, 2705 (error = XFS_DIR_CANENTER(mp, tp, tdp, target_name,
2686 target_namelen))) 2706 target_namelen)))
@@ -2803,7 +2823,9 @@ xfs_mkdir(
2803 2823
2804 mp = dp->i_mount; 2824 mp = dp->i_mount;
2805 udqp = gdqp = NULL; 2825 udqp = gdqp = NULL;
2806 if (vap->va_mask & XFS_AT_PROJID) 2826 if (dp->i_d.di_flags & XFS_DIFLAG_PROJINHERIT)
2827 prid = dp->i_d.di_projid;
2828 else if (vap->va_mask & XFS_AT_PROJID)
2807 prid = (xfs_prid_t)vap->va_projid; 2829 prid = (xfs_prid_t)vap->va_projid;
2808 else 2830 else
2809 prid = (xfs_prid_t)dfltprid; 2831 prid = (xfs_prid_t)dfltprid;
@@ -2812,7 +2834,7 @@ xfs_mkdir(
2812 * Make sure that we have allocated dquot(s) on disk. 2834 * Make sure that we have allocated dquot(s) on disk.
2813 */ 2835 */
2814 error = XFS_QM_DQVOPALLOC(mp, dp, 2836 error = XFS_QM_DQVOPALLOC(mp, dp,
2815 current_fsuid(credp), current_fsgid(credp), 2837 current_fsuid(credp), current_fsgid(credp), prid,
2816 XFS_QMOPT_QUOTALL | XFS_QMOPT_INHERIT, &udqp, &gdqp); 2838 XFS_QMOPT_QUOTALL | XFS_QMOPT_INHERIT, &udqp, &gdqp);
2817 if (error) 2839 if (error)
2818 goto std_return; 2840 goto std_return;
@@ -3357,7 +3379,9 @@ xfs_symlink(
3357 /* Return through std_return after this point. */ 3379 /* Return through std_return after this point. */
3358 3380
3359 udqp = gdqp = NULL; 3381 udqp = gdqp = NULL;
3360 if (vap->va_mask & XFS_AT_PROJID) 3382 if (dp->i_d.di_flags & XFS_DIFLAG_PROJINHERIT)
3383 prid = dp->i_d.di_projid;
3384 else if (vap->va_mask & XFS_AT_PROJID)
3361 prid = (xfs_prid_t)vap->va_projid; 3385 prid = (xfs_prid_t)vap->va_projid;
3362 else 3386 else
3363 prid = (xfs_prid_t)dfltprid; 3387 prid = (xfs_prid_t)dfltprid;
@@ -3366,7 +3390,7 @@ xfs_symlink(
3366 * Make sure that we have allocated dquot(s) on disk. 3390 * Make sure that we have allocated dquot(s) on disk.
3367 */ 3391 */
3368 error = XFS_QM_DQVOPALLOC(mp, dp, 3392 error = XFS_QM_DQVOPALLOC(mp, dp,
3369 current_fsuid(credp), current_fsgid(credp), 3393 current_fsuid(credp), current_fsgid(credp), prid,
3370 XFS_QMOPT_QUOTALL | XFS_QMOPT_INHERIT, &udqp, &gdqp); 3394 XFS_QMOPT_QUOTALL | XFS_QMOPT_INHERIT, &udqp, &gdqp);
3371 if (error) 3395 if (error)
3372 goto std_return; 3396 goto std_return;
@@ -4028,7 +4052,7 @@ xfs_finish_reclaim_all(xfs_mount_t *mp, int noblock)
4028 * errno on error 4052 * errno on error
4029 * 4053 *
4030 */ 4054 */
4031int 4055STATIC int
4032xfs_alloc_file_space( 4056xfs_alloc_file_space(
4033 xfs_inode_t *ip, 4057 xfs_inode_t *ip,
4034 xfs_off_t offset, 4058 xfs_off_t offset,
@@ -4151,9 +4175,8 @@ retry:
4151 break; 4175 break;
4152 } 4176 }
4153 xfs_ilock(ip, XFS_ILOCK_EXCL); 4177 xfs_ilock(ip, XFS_ILOCK_EXCL);
4154 error = XFS_TRANS_RESERVE_QUOTA_BYDQUOTS(mp, tp, 4178 error = XFS_TRANS_RESERVE_QUOTA(mp, tp,
4155 ip->i_udquot, ip->i_gdquot, resblks, 0, rt ? 4179 ip->i_udquot, ip->i_gdquot, resblks, 0, 0);
4156 XFS_QMOPT_RES_RTBLKS : XFS_QMOPT_RES_REGBLKS);
4157 if (error) 4180 if (error)
4158 goto error1; 4181 goto error1;
4159 4182
@@ -4305,6 +4328,7 @@ xfs_free_file_space(
4305 xfs_off_t len, 4328 xfs_off_t len,
4306 int attr_flags) 4329 int attr_flags)
4307{ 4330{
4331 vnode_t *vp;
4308 int committed; 4332 int committed;
4309 int done; 4333 int done;
4310 xfs_off_t end_dmi_offset; 4334 xfs_off_t end_dmi_offset;
@@ -4325,9 +4349,11 @@ xfs_free_file_space(
4325 xfs_trans_t *tp; 4349 xfs_trans_t *tp;
4326 int need_iolock = 1; 4350 int need_iolock = 1;
4327 4351
4328 vn_trace_entry(XFS_ITOV(ip), __FUNCTION__, (inst_t *)__return_address); 4352 vp = XFS_ITOV(ip);
4329 mp = ip->i_mount; 4353 mp = ip->i_mount;
4330 4354
4355 vn_trace_entry(vp, __FUNCTION__, (inst_t *)__return_address);
4356
4331 if ((error = XFS_QM_DQATTACH(mp, ip, 0))) 4357 if ((error = XFS_QM_DQATTACH(mp, ip, 0)))
4332 return error; 4358 return error;
4333 4359
@@ -4344,7 +4370,7 @@ xfs_free_file_space(
4344 DM_EVENT_ENABLED(XFS_MTOVFS(mp), ip, DM_EVENT_WRITE)) { 4370 DM_EVENT_ENABLED(XFS_MTOVFS(mp), ip, DM_EVENT_WRITE)) {
4345 if (end_dmi_offset > ip->i_d.di_size) 4371 if (end_dmi_offset > ip->i_d.di_size)
4346 end_dmi_offset = ip->i_d.di_size; 4372 end_dmi_offset = ip->i_d.di_size;
4347 error = XFS_SEND_DATA(mp, DM_EVENT_WRITE, XFS_ITOV(ip), 4373 error = XFS_SEND_DATA(mp, DM_EVENT_WRITE, vp,
4348 offset, end_dmi_offset - offset, 4374 offset, end_dmi_offset - offset,
4349 AT_DELAY_FLAG(attr_flags), NULL); 4375 AT_DELAY_FLAG(attr_flags), NULL);
4350 if (error) 4376 if (error)
@@ -4363,7 +4389,14 @@ xfs_free_file_space(
4363 ioffset = offset & ~(rounding - 1); 4389 ioffset = offset & ~(rounding - 1);
4364 if (ilen & (rounding - 1)) 4390 if (ilen & (rounding - 1))
4365 ilen = (ilen + rounding) & ~(rounding - 1); 4391 ilen = (ilen + rounding) & ~(rounding - 1);
4366 xfs_inval_cached_pages(XFS_ITOV(ip), &(ip->i_iocore), ioffset, 0, 0); 4392
4393 if (VN_CACHED(vp) != 0) {
4394 xfs_inval_cached_trace(&ip->i_iocore, ioffset, -1,
4395 ctooff(offtoct(ioffset)), -1);
4396 VOP_FLUSHINVAL_PAGES(vp, ctooff(offtoct(ioffset)),
4397 -1, FI_REMAPF_LOCKED);
4398 }
4399
4367 /* 4400 /*
4368 * Need to zero the stuff we're not freeing, on disk. 4401 * Need to zero the stuff we're not freeing, on disk.
4369 * If its a realtime file & can't use unwritten extents then we 4402 * If its a realtime file & can't use unwritten extents then we