aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFelix Blyakher <felixb@sgi.com>2009-02-09 11:07:00 -0500
committerFelix Blyakher <felixb@sgi.com>2009-02-09 11:07:00 -0500
commit9483c89eae58bee79b0280c625ca35a7b78fa300 (patch)
tree5aab7aee070c3011b93662eb9db3f6abfafba479
parentd41d4113f49e16bfab02eff0248282200be21807 (diff)
parent8e9b6e7fa4544ea8a0e030c8987b918509c8ff47 (diff)
Merge branch 'master' of git://git.kernel.org/pub/scm/fs/xfs/xfs
-rw-r--r--fs/xfs/linux-2.6/xfs_ioctl.c106
-rw-r--r--fs/xfs/linux-2.6/xfs_super.c43
-rw-r--r--fs/xfs/linux-2.6/xfs_vnode.h5
-rw-r--r--fs/xfs/quota/xfs_qm.c146
-rw-r--r--fs/xfs/quota/xfs_trans_dquot.c16
-rw-r--r--fs/xfs/xfs_attr_leaf.c55
-rw-r--r--fs/xfs/xfs_dfrag.c62
-rw-r--r--fs/xfs/xfs_mount.c84
-rw-r--r--fs/xfs/xfs_mount.h3
-rw-r--r--fs/xfs/xfs_quota.h1
-rw-r--r--fs/xfs/xfs_rtalloc.c10
-rw-r--r--fs/xfs/xfs_rtalloc.h4
-rw-r--r--fs/xfs/xfs_vnodeops.c51
-rw-r--r--fs/xfs/xfs_vnodeops.h1
14 files changed, 239 insertions, 348 deletions
diff --git a/fs/xfs/linux-2.6/xfs_ioctl.c b/fs/xfs/linux-2.6/xfs_ioctl.c
index 4bd112313f33..6f04493b8aba 100644
--- a/fs/xfs/linux-2.6/xfs_ioctl.c
+++ b/fs/xfs/linux-2.6/xfs_ioctl.c
@@ -78,92 +78,74 @@ xfs_find_handle(
78 int hsize; 78 int hsize;
79 xfs_handle_t handle; 79 xfs_handle_t handle;
80 struct inode *inode; 80 struct inode *inode;
81 struct file *file = NULL;
82 struct path path;
83 int error;
84 struct xfs_inode *ip;
81 85
82 memset((char *)&handle, 0, sizeof(handle)); 86 if (cmd == XFS_IOC_FD_TO_HANDLE) {
83 87 file = fget(hreq->fd);
84 switch (cmd) { 88 if (!file)
85 case XFS_IOC_PATH_TO_FSHANDLE: 89 return -EBADF;
86 case XFS_IOC_PATH_TO_HANDLE: { 90 inode = file->f_path.dentry->d_inode;
87 struct path path; 91 } else {
88 int error = user_lpath((const char __user *)hreq->path, &path); 92 error = user_lpath((const char __user *)hreq->path, &path);
89 if (error) 93 if (error)
90 return error; 94 return error;
91 95 inode = path.dentry->d_inode;
92 ASSERT(path.dentry);
93 ASSERT(path.dentry->d_inode);
94 inode = igrab(path.dentry->d_inode);
95 path_put(&path);
96 break;
97 } 96 }
97 ip = XFS_I(inode);
98 98
99 case XFS_IOC_FD_TO_HANDLE: { 99 /*
100 struct file *file; 100 * We can only generate handles for inodes residing on a XFS filesystem,
101 101 * and only for regular files, directories or symbolic links.
102 file = fget(hreq->fd); 102 */
103 if (!file) 103 error = -EINVAL;
104 return -EBADF; 104 if (inode->i_sb->s_magic != XFS_SB_MAGIC)
105 goto out_put;
105 106
106 ASSERT(file->f_path.dentry); 107 error = -EBADF;
107 ASSERT(file->f_path.dentry->d_inode); 108 if (!S_ISREG(inode->i_mode) &&
108 inode = igrab(file->f_path.dentry->d_inode); 109 !S_ISDIR(inode->i_mode) &&
109 fput(file); 110 !S_ISLNK(inode->i_mode))
110 break; 111 goto out_put;
111 }
112 112
113 default:
114 ASSERT(0);
115 return -XFS_ERROR(EINVAL);
116 }
117 113
118 if (inode->i_sb->s_magic != XFS_SB_MAGIC) { 114 memcpy(&handle.ha_fsid, ip->i_mount->m_fixedfsid, sizeof(xfs_fsid_t));
119 /* we're not in XFS anymore, Toto */
120 iput(inode);
121 return -XFS_ERROR(EINVAL);
122 }
123 115
124 switch (inode->i_mode & S_IFMT) { 116 if (cmd == XFS_IOC_PATH_TO_FSHANDLE) {
125 case S_IFREG: 117 /*
126 case S_IFDIR: 118 * This handle only contains an fsid, zero the rest.
127 case S_IFLNK: 119 */
128 break; 120 memset(&handle.ha_fid, 0, sizeof(handle.ha_fid));
129 default: 121 hsize = sizeof(xfs_fsid_t);
130 iput(inode); 122 } else {
131 return -XFS_ERROR(EBADF);
132 }
133
134 /* now we can grab the fsid */
135 memcpy(&handle.ha_fsid, XFS_I(inode)->i_mount->m_fixedfsid,
136 sizeof(xfs_fsid_t));
137 hsize = sizeof(xfs_fsid_t);
138
139 if (cmd != XFS_IOC_PATH_TO_FSHANDLE) {
140 xfs_inode_t *ip = XFS_I(inode);
141 int lock_mode; 123 int lock_mode;
142 124
143 /* need to get access to the xfs_inode to read the generation */
144 lock_mode = xfs_ilock_map_shared(ip); 125 lock_mode = xfs_ilock_map_shared(ip);
145
146 /* fill in fid section of handle from inode */
147 handle.ha_fid.fid_len = sizeof(xfs_fid_t) - 126 handle.ha_fid.fid_len = sizeof(xfs_fid_t) -
148 sizeof(handle.ha_fid.fid_len); 127 sizeof(handle.ha_fid.fid_len);
149 handle.ha_fid.fid_pad = 0; 128 handle.ha_fid.fid_pad = 0;
150 handle.ha_fid.fid_gen = ip->i_d.di_gen; 129 handle.ha_fid.fid_gen = ip->i_d.di_gen;
151 handle.ha_fid.fid_ino = ip->i_ino; 130 handle.ha_fid.fid_ino = ip->i_ino;
152
153 xfs_iunlock_map_shared(ip, lock_mode); 131 xfs_iunlock_map_shared(ip, lock_mode);
154 132
155 hsize = XFS_HSIZE(handle); 133 hsize = XFS_HSIZE(handle);
156 } 134 }
157 135
158 /* now copy our handle into the user buffer & write out the size */ 136 error = -EFAULT;
159 if (copy_to_user(hreq->ohandle, &handle, hsize) || 137 if (copy_to_user(hreq->ohandle, &handle, hsize) ||
160 copy_to_user(hreq->ohandlen, &hsize, sizeof(__s32))) { 138 copy_to_user(hreq->ohandlen, &hsize, sizeof(__s32)))
161 iput(inode); 139 goto out_put;
162 return -XFS_ERROR(EFAULT);
163 }
164 140
165 iput(inode); 141 error = 0;
166 return 0; 142
143 out_put:
144 if (cmd == XFS_IOC_FD_TO_HANDLE)
145 fput(file);
146 else
147 path_put(&path);
148 return error;
167} 149}
168 150
169/* 151/*
diff --git a/fs/xfs/linux-2.6/xfs_super.c b/fs/xfs/linux-2.6/xfs_super.c
index c71e226da7f5..faf3aa3ca154 100644
--- a/fs/xfs/linux-2.6/xfs_super.c
+++ b/fs/xfs/linux-2.6/xfs_super.c
@@ -990,26 +990,57 @@ xfs_fs_write_inode(
990 int sync) 990 int sync)
991{ 991{
992 struct xfs_inode *ip = XFS_I(inode); 992 struct xfs_inode *ip = XFS_I(inode);
993 struct xfs_mount *mp = ip->i_mount;
993 int error = 0; 994 int error = 0;
994 int flags = 0;
995 995
996 xfs_itrace_entry(ip); 996 xfs_itrace_entry(ip);
997
998 if (XFS_FORCED_SHUTDOWN(mp))
999 return XFS_ERROR(EIO);
1000
997 if (sync) { 1001 if (sync) {
998 error = xfs_wait_on_pages(ip, 0, -1); 1002 error = xfs_wait_on_pages(ip, 0, -1);
999 if (error) 1003 if (error)
1000 goto out_error; 1004 goto out;
1001 flags |= FLUSH_SYNC; 1005 }
1006
1007 /*
1008 * Bypass inodes which have already been cleaned by
1009 * the inode flush clustering code inside xfs_iflush
1010 */
1011 if (xfs_inode_clean(ip))
1012 goto out;
1013
1014 /*
1015 * We make this non-blocking if the inode is contended, return
1016 * EAGAIN to indicate to the caller that they did not succeed.
1017 * This prevents the flush path from blocking on inodes inside
1018 * another operation right now, they get caught later by xfs_sync.
1019 */
1020 if (sync) {
1021 xfs_ilock(ip, XFS_ILOCK_SHARED);
1022 xfs_iflock(ip);
1023
1024 error = xfs_iflush(ip, XFS_IFLUSH_SYNC);
1025 } else {
1026 error = EAGAIN;
1027 if (!xfs_ilock_nowait(ip, XFS_ILOCK_SHARED))
1028 goto out;
1029 if (xfs_ipincount(ip) || !xfs_iflock_nowait(ip))
1030 goto out_unlock;
1031
1032 error = xfs_iflush(ip, XFS_IFLUSH_ASYNC_NOBLOCK);
1002 } 1033 }
1003 error = xfs_inode_flush(ip, flags);
1004 1034
1005out_error: 1035 out_unlock:
1036 xfs_iunlock(ip, XFS_ILOCK_SHARED);
1037 out:
1006 /* 1038 /*
1007 * if we failed to write out the inode then mark 1039 * if we failed to write out the inode then mark
1008 * it dirty again so we'll try again later. 1040 * it dirty again so we'll try again later.
1009 */ 1041 */
1010 if (error) 1042 if (error)
1011 xfs_mark_inode_dirty_sync(ip); 1043 xfs_mark_inode_dirty_sync(ip);
1012
1013 return -error; 1044 return -error;
1014} 1045}
1015 1046
diff --git a/fs/xfs/linux-2.6/xfs_vnode.h b/fs/xfs/linux-2.6/xfs_vnode.h
index f65983a230d3..ea4675c48209 100644
--- a/fs/xfs/linux-2.6/xfs_vnode.h
+++ b/fs/xfs/linux-2.6/xfs_vnode.h
@@ -41,11 +41,6 @@ struct attrlist_cursor_kern;
41#define IO_INVIS 0x00020 /* don't update inode timestamps */ 41#define IO_INVIS 0x00020 /* don't update inode timestamps */
42 42
43/* 43/*
44 * Flags for xfs_inode_flush
45 */
46#define FLUSH_SYNC 1 /* wait for flush to complete */
47
48/*
49 * Flush/Invalidate options for vop_toss/flush/flushinval_pages. 44 * Flush/Invalidate options for vop_toss/flush/flushinval_pages.
50 */ 45 */
51#define FI_NONE 0 /* none */ 46#define FI_NONE 0 /* none */
diff --git a/fs/xfs/quota/xfs_qm.c b/fs/xfs/quota/xfs_qm.c
index 7a2beb64314f..fd0b383d72a5 100644
--- a/fs/xfs/quota/xfs_qm.c
+++ b/fs/xfs/quota/xfs_qm.c
@@ -632,7 +632,6 @@ xfs_qm_dqattach_one(
632 xfs_dqid_t id, 632 xfs_dqid_t id,
633 uint type, 633 uint type,
634 uint doalloc, 634 uint doalloc,
635 uint dolock,
636 xfs_dquot_t *udqhint, /* hint */ 635 xfs_dquot_t *udqhint, /* hint */
637 xfs_dquot_t **IO_idqpp) 636 xfs_dquot_t **IO_idqpp)
638{ 637{
@@ -641,16 +640,16 @@ xfs_qm_dqattach_one(
641 640
642 ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL)); 641 ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL));
643 error = 0; 642 error = 0;
643
644 /* 644 /*
645 * See if we already have it in the inode itself. IO_idqpp is 645 * See if we already have it in the inode itself. IO_idqpp is
646 * &i_udquot or &i_gdquot. This made the code look weird, but 646 * &i_udquot or &i_gdquot. This made the code look weird, but
647 * made the logic a lot simpler. 647 * made the logic a lot simpler.
648 */ 648 */
649 if ((dqp = *IO_idqpp)) { 649 dqp = *IO_idqpp;
650 if (dolock) 650 if (dqp) {
651 xfs_dqlock(dqp);
652 xfs_dqtrace_entry(dqp, "DQATTACH: found in ip"); 651 xfs_dqtrace_entry(dqp, "DQATTACH: found in ip");
653 goto done; 652 return 0;
654 } 653 }
655 654
656 /* 655 /*
@@ -659,38 +658,38 @@ xfs_qm_dqattach_one(
659 * lookup by dqid (xfs_qm_dqget) by caching a group dquot inside 658 * lookup by dqid (xfs_qm_dqget) by caching a group dquot inside
660 * the user dquot. 659 * the user dquot.
661 */ 660 */
662 ASSERT(!udqhint || type == XFS_DQ_GROUP || type == XFS_DQ_PROJ); 661 if (udqhint) {
663 if (udqhint && !dolock) 662 ASSERT(type == XFS_DQ_GROUP || type == XFS_DQ_PROJ);
664 xfs_dqlock(udqhint); 663 xfs_dqlock(udqhint);
665 664
666 /* 665 /*
667 * No need to take dqlock to look at the id. 666 * No need to take dqlock to look at the id.
668 * The ID can't change until it gets reclaimed, and it won't 667 *
669 * be reclaimed as long as we have a ref from inode and we hold 668 * The ID can't change until it gets reclaimed, and it won't
670 * the ilock. 669 * be reclaimed as long as we have a ref from inode and we
671 */ 670 * hold the ilock.
672 if (udqhint && 671 */
673 (dqp = udqhint->q_gdquot) && 672 dqp = udqhint->q_gdquot;
674 (be32_to_cpu(dqp->q_core.d_id) == id)) { 673 if (dqp && be32_to_cpu(dqp->q_core.d_id) == id) {
675 ASSERT(XFS_DQ_IS_LOCKED(udqhint)); 674 xfs_dqlock(dqp);
676 xfs_dqlock(dqp); 675 XFS_DQHOLD(dqp);
677 XFS_DQHOLD(dqp); 676 ASSERT(*IO_idqpp == NULL);
678 ASSERT(*IO_idqpp == NULL); 677 *IO_idqpp = dqp;
679 *IO_idqpp = dqp; 678
680 if (!dolock) {
681 xfs_dqunlock(dqp); 679 xfs_dqunlock(dqp);
682 xfs_dqunlock(udqhint); 680 xfs_dqunlock(udqhint);
681 return 0;
683 } 682 }
684 goto done; 683
685 } 684 /*
686 /* 685 * We can't hold a dquot lock when we call the dqget code.
687 * We can't hold a dquot lock when we call the dqget code. 686 * We'll deadlock in no time, because of (not conforming to)
688 * We'll deadlock in no time, because of (not conforming to) 687 * lock ordering - the inodelock comes before any dquot lock,
689 * lock ordering - the inodelock comes before any dquot lock, 688 * and we may drop and reacquire the ilock in xfs_qm_dqget().
690 * and we may drop and reacquire the ilock in xfs_qm_dqget(). 689 */
691 */
692 if (udqhint)
693 xfs_dqunlock(udqhint); 690 xfs_dqunlock(udqhint);
691 }
692
694 /* 693 /*
695 * Find the dquot from somewhere. This bumps the 694 * Find the dquot from somewhere. This bumps the
696 * reference count of dquot and returns it locked. 695 * reference count of dquot and returns it locked.
@@ -698,48 +697,19 @@ xfs_qm_dqattach_one(
698 * disk and we didn't ask it to allocate; 697 * disk and we didn't ask it to allocate;
699 * ESRCH if quotas got turned off suddenly. 698 * ESRCH if quotas got turned off suddenly.
700 */ 699 */
701 if ((error = xfs_qm_dqget(ip->i_mount, ip, id, type, 700 error = xfs_qm_dqget(ip->i_mount, ip, id, type, XFS_QMOPT_DOWARN, &dqp);
702 doalloc|XFS_QMOPT_DOWARN, &dqp))) { 701 if (error)
703 if (udqhint && dolock) 702 return error;
704 xfs_dqlock(udqhint);
705 goto done;
706 }
707 703
708 xfs_dqtrace_entry(dqp, "DQATTACH: found by dqget"); 704 xfs_dqtrace_entry(dqp, "DQATTACH: found by dqget");
705
709 /* 706 /*
710 * dqget may have dropped and re-acquired the ilock, but it guarantees 707 * dqget may have dropped and re-acquired the ilock, but it guarantees
711 * that the dquot returned is the one that should go in the inode. 708 * that the dquot returned is the one that should go in the inode.
712 */ 709 */
713 *IO_idqpp = dqp; 710 *IO_idqpp = dqp;
714 ASSERT(dqp); 711 xfs_dqunlock(dqp);
715 ASSERT(XFS_DQ_IS_LOCKED(dqp)); 712 return 0;
716 if (! dolock) {
717 xfs_dqunlock(dqp);
718 goto done;
719 }
720 if (! udqhint)
721 goto done;
722
723 ASSERT(udqhint);
724 ASSERT(dolock);
725 ASSERT(XFS_DQ_IS_LOCKED(dqp));
726 if (! xfs_qm_dqlock_nowait(udqhint)) {
727 xfs_dqunlock(dqp);
728 xfs_dqlock(udqhint);
729 xfs_dqlock(dqp);
730 }
731 done:
732#ifdef QUOTADEBUG
733 if (udqhint) {
734 if (dolock)
735 ASSERT(XFS_DQ_IS_LOCKED(udqhint));
736 }
737 if (! error) {
738 if (dolock)
739 ASSERT(XFS_DQ_IS_LOCKED(dqp));
740 }
741#endif
742 return error;
743} 713}
744 714
745 715
@@ -754,24 +724,15 @@ xfs_qm_dqattach_one(
754STATIC void 724STATIC void
755xfs_qm_dqattach_grouphint( 725xfs_qm_dqattach_grouphint(
756 xfs_dquot_t *udq, 726 xfs_dquot_t *udq,
757 xfs_dquot_t *gdq, 727 xfs_dquot_t *gdq)
758 uint locked)
759{ 728{
760 xfs_dquot_t *tmp; 729 xfs_dquot_t *tmp;
761 730
762#ifdef QUOTADEBUG 731 xfs_dqlock(udq);
763 if (locked) {
764 ASSERT(XFS_DQ_IS_LOCKED(udq));
765 ASSERT(XFS_DQ_IS_LOCKED(gdq));
766 }
767#endif
768 if (! locked)
769 xfs_dqlock(udq);
770 732
771 if ((tmp = udq->q_gdquot)) { 733 if ((tmp = udq->q_gdquot)) {
772 if (tmp == gdq) { 734 if (tmp == gdq) {
773 if (! locked) 735 xfs_dqunlock(udq);
774 xfs_dqunlock(udq);
775 return; 736 return;
776 } 737 }
777 738
@@ -781,8 +742,6 @@ xfs_qm_dqattach_grouphint(
781 * because the freelist lock comes before dqlocks. 742 * because the freelist lock comes before dqlocks.
782 */ 743 */
783 xfs_dqunlock(udq); 744 xfs_dqunlock(udq);
784 if (locked)
785 xfs_dqunlock(gdq);
786 /* 745 /*
787 * we took a hard reference once upon a time in dqget, 746 * we took a hard reference once upon a time in dqget,
788 * so give it back when the udquot no longer points at it 747 * so give it back when the udquot no longer points at it
@@ -795,9 +754,7 @@ xfs_qm_dqattach_grouphint(
795 754
796 } else { 755 } else {
797 ASSERT(XFS_DQ_IS_LOCKED(udq)); 756 ASSERT(XFS_DQ_IS_LOCKED(udq));
798 if (! locked) { 757 xfs_dqlock(gdq);
799 xfs_dqlock(gdq);
800 }
801 } 758 }
802 759
803 ASSERT(XFS_DQ_IS_LOCKED(udq)); 760 ASSERT(XFS_DQ_IS_LOCKED(udq));
@@ -810,10 +767,9 @@ xfs_qm_dqattach_grouphint(
810 XFS_DQHOLD(gdq); 767 XFS_DQHOLD(gdq);
811 udq->q_gdquot = gdq; 768 udq->q_gdquot = gdq;
812 } 769 }
813 if (! locked) { 770
814 xfs_dqunlock(gdq); 771 xfs_dqunlock(gdq);
815 xfs_dqunlock(udq); 772 xfs_dqunlock(udq);
816 }
817} 773}
818 774
819 775
@@ -821,8 +777,6 @@ xfs_qm_dqattach_grouphint(
821 * Given a locked inode, attach dquot(s) to it, taking U/G/P-QUOTAON 777 * Given a locked inode, attach dquot(s) to it, taking U/G/P-QUOTAON
822 * into account. 778 * into account.
823 * If XFS_QMOPT_DQALLOC, the dquot(s) will be allocated if needed. 779 * If XFS_QMOPT_DQALLOC, the dquot(s) will be allocated if needed.
824 * If XFS_QMOPT_DQLOCK, the dquot(s) will be returned locked. This option pretty
825 * much made this code a complete mess, but it has been pretty useful.
826 * If XFS_QMOPT_ILOCKED, then inode sent is already locked EXCL. 780 * If XFS_QMOPT_ILOCKED, then inode sent is already locked EXCL.
827 * Inode may get unlocked and relocked in here, and the caller must deal with 781 * Inode may get unlocked and relocked in here, and the caller must deal with
828 * the consequences. 782 * the consequences.
@@ -851,7 +805,6 @@ xfs_qm_dqattach(
851 if (XFS_IS_UQUOTA_ON(mp)) { 805 if (XFS_IS_UQUOTA_ON(mp)) {
852 error = xfs_qm_dqattach_one(ip, ip->i_d.di_uid, XFS_DQ_USER, 806 error = xfs_qm_dqattach_one(ip, ip->i_d.di_uid, XFS_DQ_USER,
853 flags & XFS_QMOPT_DQALLOC, 807 flags & XFS_QMOPT_DQALLOC,
854 flags & XFS_QMOPT_DQLOCK,
855 NULL, &ip->i_udquot); 808 NULL, &ip->i_udquot);
856 if (error) 809 if (error)
857 goto done; 810 goto done;
@@ -863,11 +816,9 @@ xfs_qm_dqattach(
863 error = XFS_IS_GQUOTA_ON(mp) ? 816 error = XFS_IS_GQUOTA_ON(mp) ?
864 xfs_qm_dqattach_one(ip, ip->i_d.di_gid, XFS_DQ_GROUP, 817 xfs_qm_dqattach_one(ip, ip->i_d.di_gid, XFS_DQ_GROUP,
865 flags & XFS_QMOPT_DQALLOC, 818 flags & XFS_QMOPT_DQALLOC,
866 flags & XFS_QMOPT_DQLOCK,
867 ip->i_udquot, &ip->i_gdquot) : 819 ip->i_udquot, &ip->i_gdquot) :
868 xfs_qm_dqattach_one(ip, ip->i_d.di_projid, XFS_DQ_PROJ, 820 xfs_qm_dqattach_one(ip, ip->i_d.di_projid, XFS_DQ_PROJ,
869 flags & XFS_QMOPT_DQALLOC, 821 flags & XFS_QMOPT_DQALLOC,
870 flags & XFS_QMOPT_DQLOCK,
871 ip->i_udquot, &ip->i_gdquot); 822 ip->i_udquot, &ip->i_gdquot);
872 /* 823 /*
873 * Don't worry about the udquot that we may have 824 * Don't worry about the udquot that we may have
@@ -898,22 +849,13 @@ xfs_qm_dqattach(
898 /* 849 /*
899 * Attach i_gdquot to the gdquot hint inside the i_udquot. 850 * Attach i_gdquot to the gdquot hint inside the i_udquot.
900 */ 851 */
901 xfs_qm_dqattach_grouphint(ip->i_udquot, ip->i_gdquot, 852 xfs_qm_dqattach_grouphint(ip->i_udquot, ip->i_gdquot);
902 flags & XFS_QMOPT_DQLOCK);
903 } 853 }
904 854
905 done: 855 done:
906 856
907#ifdef QUOTADEBUG 857#ifdef QUOTADEBUG
908 if (! error) { 858 if (! error) {
909 if (ip->i_udquot) {
910 if (flags & XFS_QMOPT_DQLOCK)
911 ASSERT(XFS_DQ_IS_LOCKED(ip->i_udquot));
912 }
913 if (ip->i_gdquot) {
914 if (flags & XFS_QMOPT_DQLOCK)
915 ASSERT(XFS_DQ_IS_LOCKED(ip->i_gdquot));
916 }
917 if (XFS_IS_UQUOTA_ON(mp)) 859 if (XFS_IS_UQUOTA_ON(mp))
918 ASSERT(ip->i_udquot); 860 ASSERT(ip->i_udquot);
919 if (XFS_IS_OQUOTA_ON(mp)) 861 if (XFS_IS_OQUOTA_ON(mp))
diff --git a/fs/xfs/quota/xfs_trans_dquot.c b/fs/xfs/quota/xfs_trans_dquot.c
index 99611381e740..447173bcf96d 100644
--- a/fs/xfs/quota/xfs_trans_dquot.c
+++ b/fs/xfs/quota/xfs_trans_dquot.c
@@ -624,10 +624,9 @@ xfs_trans_dqresv(
624 xfs_qcnt_t *resbcountp; 624 xfs_qcnt_t *resbcountp;
625 xfs_quotainfo_t *q = mp->m_quotainfo; 625 xfs_quotainfo_t *q = mp->m_quotainfo;
626 626
627 if (! (flags & XFS_QMOPT_DQLOCK)) { 627
628 xfs_dqlock(dqp); 628 xfs_dqlock(dqp);
629 } 629
630 ASSERT(XFS_DQ_IS_LOCKED(dqp));
631 if (flags & XFS_TRANS_DQ_RES_BLKS) { 630 if (flags & XFS_TRANS_DQ_RES_BLKS) {
632 hardlimit = be64_to_cpu(dqp->q_core.d_blk_hardlimit); 631 hardlimit = be64_to_cpu(dqp->q_core.d_blk_hardlimit);
633 if (!hardlimit) 632 if (!hardlimit)
@@ -740,10 +739,8 @@ xfs_trans_dqresv(
740 ASSERT(dqp->q_res_icount >= be64_to_cpu(dqp->q_core.d_icount)); 739 ASSERT(dqp->q_res_icount >= be64_to_cpu(dqp->q_core.d_icount));
741 740
742error_return: 741error_return:
743 if (! (flags & XFS_QMOPT_DQLOCK)) { 742 xfs_dqunlock(dqp);
744 xfs_dqunlock(dqp); 743 return error;
745 }
746 return (error);
747} 744}
748 745
749 746
@@ -753,8 +750,7 @@ error_return:
753 * grp/prj quotas is important, because this follows a both-or-nothing 750 * grp/prj quotas is important, because this follows a both-or-nothing
754 * approach. 751 * approach.
755 * 752 *
756 * flags = XFS_QMOPT_DQLOCK indicate if dquot(s) need to be locked. 753 * flags = XFS_QMOPT_FORCE_RES evades limit enforcement. Used by chown.
757 * XFS_QMOPT_FORCE_RES evades limit enforcement. Used by chown.
758 * XFS_QMOPT_ENOSPC returns ENOSPC not EDQUOT. Used by pquota. 754 * XFS_QMOPT_ENOSPC returns ENOSPC not EDQUOT. Used by pquota.
759 * XFS_TRANS_DQ_RES_BLKS reserves regular disk blocks 755 * XFS_TRANS_DQ_RES_BLKS reserves regular disk blocks
760 * XFS_TRANS_DQ_RES_RTBLKS reserves realtime disk blocks 756 * XFS_TRANS_DQ_RES_RTBLKS reserves realtime disk blocks
diff --git a/fs/xfs/xfs_attr_leaf.c b/fs/xfs/xfs_attr_leaf.c
index 6c323f8a4cd1..aa001629b596 100644
--- a/fs/xfs/xfs_attr_leaf.c
+++ b/fs/xfs/xfs_attr_leaf.c
@@ -298,6 +298,26 @@ xfs_attr_shortform_add(xfs_da_args_t *args, int forkoff)
298} 298}
299 299
300/* 300/*
301 * After the last attribute is removed revert to original inode format,
302 * making all literal area available to the data fork once more.
303 */
304STATIC void
305xfs_attr_fork_reset(
306 struct xfs_inode *ip,
307 struct xfs_trans *tp)
308{
309 xfs_idestroy_fork(ip, XFS_ATTR_FORK);
310 ip->i_d.di_forkoff = 0;
311 ip->i_d.di_aformat = XFS_DINODE_FMT_EXTENTS;
312
313 ASSERT(ip->i_d.di_anextents == 0);
314 ASSERT(ip->i_afp == NULL);
315
316 ip->i_df.if_ext_max = XFS_IFORK_DSIZE(ip) / sizeof(xfs_bmbt_rec_t);
317 xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
318}
319
320/*
301 * Remove an attribute from the shortform attribute list structure. 321 * Remove an attribute from the shortform attribute list structure.
302 */ 322 */
303int 323int
@@ -344,22 +364,10 @@ xfs_attr_shortform_remove(xfs_da_args_t *args)
344 */ 364 */
345 totsize -= size; 365 totsize -= size;
346 if (totsize == sizeof(xfs_attr_sf_hdr_t) && 366 if (totsize == sizeof(xfs_attr_sf_hdr_t) &&
347 !(args->op_flags & XFS_DA_OP_ADDNAME) && 367 (mp->m_flags & XFS_MOUNT_ATTR2) &&
348 (mp->m_flags & XFS_MOUNT_ATTR2) && 368 (dp->i_d.di_format != XFS_DINODE_FMT_BTREE) &&
349 (dp->i_d.di_format != XFS_DINODE_FMT_BTREE)) { 369 !(args->op_flags & XFS_DA_OP_ADDNAME)) {
350 /* 370 xfs_attr_fork_reset(dp, args->trans);
351 * Last attribute now removed, revert to original
352 * inode format making all literal area available
353 * to the data fork once more.
354 */
355 xfs_idestroy_fork(dp, XFS_ATTR_FORK);
356 dp->i_d.di_forkoff = 0;
357 dp->i_d.di_aformat = XFS_DINODE_FMT_EXTENTS;
358 ASSERT(dp->i_d.di_anextents == 0);
359 ASSERT(dp->i_afp == NULL);
360 dp->i_df.if_ext_max =
361 XFS_IFORK_DSIZE(dp) / (uint)sizeof(xfs_bmbt_rec_t);
362 xfs_trans_log_inode(args->trans, dp, XFS_ILOG_CORE);
363 } else { 371 } else {
364 xfs_idata_realloc(dp, -size, XFS_ATTR_FORK); 372 xfs_idata_realloc(dp, -size, XFS_ATTR_FORK);
365 dp->i_d.di_forkoff = xfs_attr_shortform_bytesfit(dp, totsize); 373 dp->i_d.di_forkoff = xfs_attr_shortform_bytesfit(dp, totsize);
@@ -786,20 +794,7 @@ xfs_attr_leaf_to_shortform(xfs_dabuf_t *bp, xfs_da_args_t *args, int forkoff)
786 if (forkoff == -1) { 794 if (forkoff == -1) {
787 ASSERT(dp->i_mount->m_flags & XFS_MOUNT_ATTR2); 795 ASSERT(dp->i_mount->m_flags & XFS_MOUNT_ATTR2);
788 ASSERT(dp->i_d.di_format != XFS_DINODE_FMT_BTREE); 796 ASSERT(dp->i_d.di_format != XFS_DINODE_FMT_BTREE);
789 797 xfs_attr_fork_reset(dp, args->trans);
790 /*
791 * Last attribute was removed, revert to original
792 * inode format making all literal area available
793 * to the data fork once more.
794 */
795 xfs_idestroy_fork(dp, XFS_ATTR_FORK);
796 dp->i_d.di_forkoff = 0;
797 dp->i_d.di_aformat = XFS_DINODE_FMT_EXTENTS;
798 ASSERT(dp->i_d.di_anextents == 0);
799 ASSERT(dp->i_afp == NULL);
800 dp->i_df.if_ext_max =
801 XFS_IFORK_DSIZE(dp) / (uint)sizeof(xfs_bmbt_rec_t);
802 xfs_trans_log_inode(args->trans, dp, XFS_ILOG_CORE);
803 goto out; 798 goto out;
804 } 799 }
805 800
diff --git a/fs/xfs/xfs_dfrag.c b/fs/xfs/xfs_dfrag.c
index f8278cfcc1d3..ac96ab9f70a2 100644
--- a/fs/xfs/xfs_dfrag.c
+++ b/fs/xfs/xfs_dfrag.c
@@ -118,19 +118,17 @@ xfs_swap_extents(
118 xfs_bstat_t *sbp = &sxp->sx_stat; 118 xfs_bstat_t *sbp = &sxp->sx_stat;
119 xfs_ifork_t *tempifp, *ifp, *tifp; 119 xfs_ifork_t *tempifp, *ifp, *tifp;
120 int ilf_fields, tilf_fields; 120 int ilf_fields, tilf_fields;
121 static uint lock_flags = XFS_ILOCK_EXCL | XFS_IOLOCK_EXCL;
122 int error = 0; 121 int error = 0;
123 int aforkblks = 0; 122 int aforkblks = 0;
124 int taforkblks = 0; 123 int taforkblks = 0;
125 __uint64_t tmp; 124 __uint64_t tmp;
126 char locked = 0;
127 125
128 mp = ip->i_mount; 126 mp = ip->i_mount;
129 127
130 tempifp = kmem_alloc(sizeof(xfs_ifork_t), KM_MAYFAIL); 128 tempifp = kmem_alloc(sizeof(xfs_ifork_t), KM_MAYFAIL);
131 if (!tempifp) { 129 if (!tempifp) {
132 error = XFS_ERROR(ENOMEM); 130 error = XFS_ERROR(ENOMEM);
133 goto error0; 131 goto out;
134 } 132 }
135 133
136 sbp = &sxp->sx_stat; 134 sbp = &sxp->sx_stat;
@@ -143,25 +141,24 @@ xfs_swap_extents(
143 */ 141 */
144 xfs_lock_two_inodes(ip, tip, XFS_IOLOCK_EXCL); 142 xfs_lock_two_inodes(ip, tip, XFS_IOLOCK_EXCL);
145 xfs_lock_two_inodes(ip, tip, XFS_ILOCK_EXCL); 143 xfs_lock_two_inodes(ip, tip, XFS_ILOCK_EXCL);
146 locked = 1;
147 144
148 /* Verify that both files have the same format */ 145 /* Verify that both files have the same format */
149 if ((ip->i_d.di_mode & S_IFMT) != (tip->i_d.di_mode & S_IFMT)) { 146 if ((ip->i_d.di_mode & S_IFMT) != (tip->i_d.di_mode & S_IFMT)) {
150 error = XFS_ERROR(EINVAL); 147 error = XFS_ERROR(EINVAL);
151 goto error0; 148 goto out_unlock;
152 } 149 }
153 150
154 /* Verify both files are either real-time or non-realtime */ 151 /* Verify both files are either real-time or non-realtime */
155 if (XFS_IS_REALTIME_INODE(ip) != XFS_IS_REALTIME_INODE(tip)) { 152 if (XFS_IS_REALTIME_INODE(ip) != XFS_IS_REALTIME_INODE(tip)) {
156 error = XFS_ERROR(EINVAL); 153 error = XFS_ERROR(EINVAL);
157 goto error0; 154 goto out_unlock;
158 } 155 }
159 156
160 /* Should never get a local format */ 157 /* Should never get a local format */
161 if (ip->i_d.di_format == XFS_DINODE_FMT_LOCAL || 158 if (ip->i_d.di_format == XFS_DINODE_FMT_LOCAL ||
162 tip->i_d.di_format == XFS_DINODE_FMT_LOCAL) { 159 tip->i_d.di_format == XFS_DINODE_FMT_LOCAL) {
163 error = XFS_ERROR(EINVAL); 160 error = XFS_ERROR(EINVAL);
164 goto error0; 161 goto out_unlock;
165 } 162 }
166 163
167 if (VN_CACHED(VFS_I(tip)) != 0) { 164 if (VN_CACHED(VFS_I(tip)) != 0) {
@@ -169,13 +166,13 @@ xfs_swap_extents(
169 error = xfs_flushinval_pages(tip, 0, -1, 166 error = xfs_flushinval_pages(tip, 0, -1,
170 FI_REMAPF_LOCKED); 167 FI_REMAPF_LOCKED);
171 if (error) 168 if (error)
172 goto error0; 169 goto out_unlock;
173 } 170 }
174 171
175 /* Verify O_DIRECT for ftmp */ 172 /* Verify O_DIRECT for ftmp */
176 if (VN_CACHED(VFS_I(tip)) != 0) { 173 if (VN_CACHED(VFS_I(tip)) != 0) {
177 error = XFS_ERROR(EINVAL); 174 error = XFS_ERROR(EINVAL);
178 goto error0; 175 goto out_unlock;
179 } 176 }
180 177
181 /* Verify all data are being swapped */ 178 /* Verify all data are being swapped */
@@ -183,7 +180,7 @@ xfs_swap_extents(
183 sxp->sx_length != ip->i_d.di_size || 180 sxp->sx_length != ip->i_d.di_size ||
184 sxp->sx_length != tip->i_d.di_size) { 181 sxp->sx_length != tip->i_d.di_size) {
185 error = XFS_ERROR(EFAULT); 182 error = XFS_ERROR(EFAULT);
186 goto error0; 183 goto out_unlock;
187 } 184 }
188 185
189 /* 186 /*
@@ -193,7 +190,7 @@ xfs_swap_extents(
193 */ 190 */
194 if ( XFS_IFORK_Q(ip) != XFS_IFORK_Q(tip) ) { 191 if ( XFS_IFORK_Q(ip) != XFS_IFORK_Q(tip) ) {
195 error = XFS_ERROR(EINVAL); 192 error = XFS_ERROR(EINVAL);
196 goto error0; 193 goto out_unlock;
197 } 194 }
198 195
199 /* 196 /*
@@ -208,7 +205,7 @@ xfs_swap_extents(
208 (sbp->bs_mtime.tv_sec != ip->i_d.di_mtime.t_sec) || 205 (sbp->bs_mtime.tv_sec != ip->i_d.di_mtime.t_sec) ||
209 (sbp->bs_mtime.tv_nsec != ip->i_d.di_mtime.t_nsec)) { 206 (sbp->bs_mtime.tv_nsec != ip->i_d.di_mtime.t_nsec)) {
210 error = XFS_ERROR(EBUSY); 207 error = XFS_ERROR(EBUSY);
211 goto error0; 208 goto out_unlock;
212 } 209 }
213 210
214 /* We need to fail if the file is memory mapped. Once we have tossed 211 /* We need to fail if the file is memory mapped. Once we have tossed
@@ -219,7 +216,7 @@ xfs_swap_extents(
219 */ 216 */
220 if (VN_MAPPED(VFS_I(ip))) { 217 if (VN_MAPPED(VFS_I(ip))) {
221 error = XFS_ERROR(EBUSY); 218 error = XFS_ERROR(EBUSY);
222 goto error0; 219 goto out_unlock;
223 } 220 }
224 221
225 xfs_iunlock(ip, XFS_ILOCK_EXCL); 222 xfs_iunlock(ip, XFS_ILOCK_EXCL);
@@ -242,8 +239,7 @@ xfs_swap_extents(
242 xfs_iunlock(ip, XFS_IOLOCK_EXCL); 239 xfs_iunlock(ip, XFS_IOLOCK_EXCL);
243 xfs_iunlock(tip, XFS_IOLOCK_EXCL); 240 xfs_iunlock(tip, XFS_IOLOCK_EXCL);
244 xfs_trans_cancel(tp, 0); 241 xfs_trans_cancel(tp, 0);
245 locked = 0; 242 goto out;
246 goto error0;
247 } 243 }
248 xfs_lock_two_inodes(ip, tip, XFS_ILOCK_EXCL); 244 xfs_lock_two_inodes(ip, tip, XFS_ILOCK_EXCL);
249 245
@@ -253,19 +249,15 @@ xfs_swap_extents(
253 if ( ((XFS_IFORK_Q(ip) != 0) && (ip->i_d.di_anextents > 0)) && 249 if ( ((XFS_IFORK_Q(ip) != 0) && (ip->i_d.di_anextents > 0)) &&
254 (ip->i_d.di_aformat != XFS_DINODE_FMT_LOCAL)) { 250 (ip->i_d.di_aformat != XFS_DINODE_FMT_LOCAL)) {
255 error = xfs_bmap_count_blocks(tp, ip, XFS_ATTR_FORK, &aforkblks); 251 error = xfs_bmap_count_blocks(tp, ip, XFS_ATTR_FORK, &aforkblks);
256 if (error) { 252 if (error)
257 xfs_trans_cancel(tp, 0); 253 goto out_trans_cancel;
258 goto error0;
259 }
260 } 254 }
261 if ( ((XFS_IFORK_Q(tip) != 0) && (tip->i_d.di_anextents > 0)) && 255 if ( ((XFS_IFORK_Q(tip) != 0) && (tip->i_d.di_anextents > 0)) &&
262 (tip->i_d.di_aformat != XFS_DINODE_FMT_LOCAL)) { 256 (tip->i_d.di_aformat != XFS_DINODE_FMT_LOCAL)) {
263 error = xfs_bmap_count_blocks(tp, tip, XFS_ATTR_FORK, 257 error = xfs_bmap_count_blocks(tp, tip, XFS_ATTR_FORK,
264 &taforkblks); 258 &taforkblks);
265 if (error) { 259 if (error)
266 xfs_trans_cancel(tp, 0); 260 goto out_trans_cancel;
267 goto error0;
268 }
269 } 261 }
270 262
271 /* 263 /*
@@ -332,10 +324,10 @@ xfs_swap_extents(
332 324
333 325
334 IHOLD(ip); 326 IHOLD(ip);
335 xfs_trans_ijoin(tp, ip, lock_flags); 327 xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL | XFS_IOLOCK_EXCL);
336 328
337 IHOLD(tip); 329 IHOLD(tip);
338 xfs_trans_ijoin(tp, tip, lock_flags); 330 xfs_trans_ijoin(tp, tip, XFS_ILOCK_EXCL | XFS_IOLOCK_EXCL);
339 331
340 xfs_trans_log_inode(tp, ip, ilf_fields); 332 xfs_trans_log_inode(tp, ip, ilf_fields);
341 xfs_trans_log_inode(tp, tip, tilf_fields); 333 xfs_trans_log_inode(tp, tip, tilf_fields);
@@ -344,19 +336,19 @@ xfs_swap_extents(
344 * If this is a synchronous mount, make sure that the 336 * If this is a synchronous mount, make sure that the
345 * transaction goes to disk before returning to the user. 337 * transaction goes to disk before returning to the user.
346 */ 338 */
347 if (mp->m_flags & XFS_MOUNT_WSYNC) { 339 if (mp->m_flags & XFS_MOUNT_WSYNC)
348 xfs_trans_set_sync(tp); 340 xfs_trans_set_sync(tp);
349 }
350 341
351 error = xfs_trans_commit(tp, XFS_TRANS_SWAPEXT); 342 error = xfs_trans_commit(tp, XFS_TRANS_SWAPEXT);
352 locked = 0;
353 343
354 error0: 344out_unlock:
355 if (locked) { 345 xfs_iunlock(ip, XFS_ILOCK_EXCL | XFS_IOLOCK_EXCL);
356 xfs_iunlock(ip, lock_flags); 346 xfs_iunlock(tip, XFS_ILOCK_EXCL | XFS_IOLOCK_EXCL);
357 xfs_iunlock(tip, lock_flags); 347out:
358 } 348 kmem_free(tempifp);
359 if (tempifp != NULL)
360 kmem_free(tempifp);
361 return error; 349 return error;
350
351out_trans_cancel:
352 xfs_trans_cancel(tp, 0);
353 goto out_unlock;
362} 354}
diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c
index 35300250e86d..664961e45e02 100644
--- a/fs/xfs/xfs_mount.c
+++ b/fs/xfs/xfs_mount.c
@@ -886,8 +886,6 @@ xfs_check_sizes(xfs_mount_t *mp)
886} 886}
887 887
888/* 888/*
889 * xfs_mountfs
890 *
891 * This function does the following on an initial mount of a file system: 889 * This function does the following on an initial mount of a file system:
892 * - reads the superblock from disk and init the mount struct 890 * - reads the superblock from disk and init the mount struct
893 * - if we're a 32-bit kernel, do a size check on the superblock 891 * - if we're a 32-bit kernel, do a size check on the superblock
@@ -905,7 +903,6 @@ xfs_mountfs(
905 xfs_inode_t *rip; 903 xfs_inode_t *rip;
906 __uint64_t resblks; 904 __uint64_t resblks;
907 uint quotamount, quotaflags; 905 uint quotamount, quotaflags;
908 int uuid_mounted = 0;
909 int error = 0; 906 int error = 0;
910 907
911 xfs_mount_common(mp, sbp); 908 xfs_mount_common(mp, sbp);
@@ -960,7 +957,7 @@ xfs_mountfs(
960 */ 957 */
961 error = xfs_update_alignment(mp); 958 error = xfs_update_alignment(mp);
962 if (error) 959 if (error)
963 goto error1; 960 goto out;
964 961
965 xfs_alloc_compute_maxlevels(mp); 962 xfs_alloc_compute_maxlevels(mp);
966 xfs_bmap_compute_maxlevels(mp, XFS_DATA_FORK); 963 xfs_bmap_compute_maxlevels(mp, XFS_DATA_FORK);
@@ -977,12 +974,11 @@ xfs_mountfs(
977 * since a single partition filesystem is identical to a single 974 * since a single partition filesystem is identical to a single
978 * partition volume/filesystem. 975 * partition volume/filesystem.
979 */ 976 */
980 if ((mp->m_flags & XFS_MOUNT_NOUUID) == 0) { 977 if (!(mp->m_flags & XFS_MOUNT_NOUUID)) {
981 if (xfs_uuid_mount(mp)) { 978 if (xfs_uuid_mount(mp)) {
982 error = XFS_ERROR(EINVAL); 979 error = XFS_ERROR(EINVAL);
983 goto error1; 980 goto out;
984 } 981 }
985 uuid_mounted=1;
986 } 982 }
987 983
988 /* 984 /*
@@ -1007,7 +1003,7 @@ xfs_mountfs(
1007 */ 1003 */
1008 error = xfs_check_sizes(mp); 1004 error = xfs_check_sizes(mp);
1009 if (error) 1005 if (error)
1010 goto error1; 1006 goto out_remove_uuid;
1011 1007
1012 /* 1008 /*
1013 * Initialize realtime fields in the mount structure 1009 * Initialize realtime fields in the mount structure
@@ -1015,7 +1011,7 @@ xfs_mountfs(
1015 error = xfs_rtmount_init(mp); 1011 error = xfs_rtmount_init(mp);
1016 if (error) { 1012 if (error) {
1017 cmn_err(CE_WARN, "XFS: RT mount failed"); 1013 cmn_err(CE_WARN, "XFS: RT mount failed");
1018 goto error1; 1014 goto out_remove_uuid;
1019 } 1015 }
1020 1016
1021 /* 1017 /*
@@ -1045,26 +1041,26 @@ xfs_mountfs(
1045 mp->m_perag = kmem_zalloc(sbp->sb_agcount * sizeof(xfs_perag_t), 1041 mp->m_perag = kmem_zalloc(sbp->sb_agcount * sizeof(xfs_perag_t),
1046 KM_MAYFAIL); 1042 KM_MAYFAIL);
1047 if (!mp->m_perag) 1043 if (!mp->m_perag)
1048 goto error1; 1044 goto out_remove_uuid;
1049 1045
1050 mp->m_maxagi = xfs_initialize_perag(mp, sbp->sb_agcount); 1046 mp->m_maxagi = xfs_initialize_perag(mp, sbp->sb_agcount);
1051 1047
1048 if (!sbp->sb_logblocks) {
1049 cmn_err(CE_WARN, "XFS: no log defined");
1050 XFS_ERROR_REPORT("xfs_mountfs", XFS_ERRLEVEL_LOW, mp);
1051 error = XFS_ERROR(EFSCORRUPTED);
1052 goto out_free_perag;
1053 }
1054
1052 /* 1055 /*
1053 * log's mount-time initialization. Perform 1st part recovery if needed 1056 * log's mount-time initialization. Perform 1st part recovery if needed
1054 */ 1057 */
1055 if (likely(sbp->sb_logblocks > 0)) { /* check for volume case */ 1058 error = xfs_log_mount(mp, mp->m_logdev_targp,
1056 error = xfs_log_mount(mp, mp->m_logdev_targp, 1059 XFS_FSB_TO_DADDR(mp, sbp->sb_logstart),
1057 XFS_FSB_TO_DADDR(mp, sbp->sb_logstart), 1060 XFS_FSB_TO_BB(mp, sbp->sb_logblocks));
1058 XFS_FSB_TO_BB(mp, sbp->sb_logblocks)); 1061 if (error) {
1059 if (error) { 1062 cmn_err(CE_WARN, "XFS: log mount failed");
1060 cmn_err(CE_WARN, "XFS: log mount failed"); 1063 goto out_free_perag;
1061 goto error2;
1062 }
1063 } else { /* No log has been defined */
1064 cmn_err(CE_WARN, "XFS: no log defined");
1065 XFS_ERROR_REPORT("xfs_mountfs_int(1)", XFS_ERRLEVEL_LOW, mp);
1066 error = XFS_ERROR(EFSCORRUPTED);
1067 goto error2;
1068 } 1064 }
1069 1065
1070 /* 1066 /*
@@ -1086,15 +1082,14 @@ xfs_mountfs(
1086 * If we are currently making the filesystem, the initialisation will 1082 * If we are currently making the filesystem, the initialisation will
1087 * fail as the perag data is in an undefined state. 1083 * fail as the perag data is in an undefined state.
1088 */ 1084 */
1089
1090 if (xfs_sb_version_haslazysbcount(&mp->m_sb) && 1085 if (xfs_sb_version_haslazysbcount(&mp->m_sb) &&
1091 !XFS_LAST_UNMOUNT_WAS_CLEAN(mp) && 1086 !XFS_LAST_UNMOUNT_WAS_CLEAN(mp) &&
1092 !mp->m_sb.sb_inprogress) { 1087 !mp->m_sb.sb_inprogress) {
1093 error = xfs_initialize_perag_data(mp, sbp->sb_agcount); 1088 error = xfs_initialize_perag_data(mp, sbp->sb_agcount);
1094 if (error) { 1089 if (error)
1095 goto error2; 1090 goto out_free_perag;
1096 }
1097 } 1091 }
1092
1098 /* 1093 /*
1099 * Get and sanity-check the root inode. 1094 * Get and sanity-check the root inode.
1100 * Save the pointer to it in the mount structure. 1095 * Save the pointer to it in the mount structure.
@@ -1102,7 +1097,7 @@ xfs_mountfs(
1102 error = xfs_iget(mp, NULL, sbp->sb_rootino, 0, XFS_ILOCK_EXCL, &rip, 0); 1097 error = xfs_iget(mp, NULL, sbp->sb_rootino, 0, XFS_ILOCK_EXCL, &rip, 0);
1103 if (error) { 1098 if (error) {
1104 cmn_err(CE_WARN, "XFS: failed to read root inode"); 1099 cmn_err(CE_WARN, "XFS: failed to read root inode");
1105 goto error3; 1100 goto out_log_dealloc;
1106 } 1101 }
1107 1102
1108 ASSERT(rip != NULL); 1103 ASSERT(rip != NULL);
@@ -1116,7 +1111,7 @@ xfs_mountfs(
1116 XFS_ERROR_REPORT("xfs_mountfs_int(2)", XFS_ERRLEVEL_LOW, 1111 XFS_ERROR_REPORT("xfs_mountfs_int(2)", XFS_ERRLEVEL_LOW,
1117 mp); 1112 mp);
1118 error = XFS_ERROR(EFSCORRUPTED); 1113 error = XFS_ERROR(EFSCORRUPTED);
1119 goto error4; 1114 goto out_rele_rip;
1120 } 1115 }
1121 mp->m_rootip = rip; /* save it */ 1116 mp->m_rootip = rip; /* save it */
1122 1117
@@ -1131,7 +1126,7 @@ xfs_mountfs(
1131 * Free up the root inode. 1126 * Free up the root inode.
1132 */ 1127 */
1133 cmn_err(CE_WARN, "XFS: failed to read RT inodes"); 1128 cmn_err(CE_WARN, "XFS: failed to read RT inodes");
1134 goto error4; 1129 goto out_rele_rip;
1135 } 1130 }
1136 1131
1137 /* 1132 /*
@@ -1143,7 +1138,7 @@ xfs_mountfs(
1143 error = xfs_mount_log_sb(mp, mp->m_update_flags); 1138 error = xfs_mount_log_sb(mp, mp->m_update_flags);
1144 if (error) { 1139 if (error) {
1145 cmn_err(CE_WARN, "XFS: failed to write sb changes"); 1140 cmn_err(CE_WARN, "XFS: failed to write sb changes");
1146 goto error4; 1141 goto out_rtunmount;
1147 } 1142 }
1148 } 1143 }
1149 1144
@@ -1152,7 +1147,7 @@ xfs_mountfs(
1152 */ 1147 */
1153 error = XFS_QM_INIT(mp, &quotamount, &quotaflags); 1148 error = XFS_QM_INIT(mp, &quotamount, &quotaflags);
1154 if (error) 1149 if (error)
1155 goto error4; 1150 goto out_rtunmount;
1156 1151
1157 /* 1152 /*
1158 * Finish recovering the file system. This part needed to be 1153 * Finish recovering the file system. This part needed to be
@@ -1162,7 +1157,7 @@ xfs_mountfs(
1162 error = xfs_log_mount_finish(mp); 1157 error = xfs_log_mount_finish(mp);
1163 if (error) { 1158 if (error) {
1164 cmn_err(CE_WARN, "XFS: log mount finish failed"); 1159 cmn_err(CE_WARN, "XFS: log mount finish failed");
1165 goto error4; 1160 goto out_rtunmount;
1166 } 1161 }
1167 1162
1168 /* 1163 /*
@@ -1170,7 +1165,7 @@ xfs_mountfs(
1170 */ 1165 */
1171 error = XFS_QM_MOUNT(mp, quotamount, quotaflags); 1166 error = XFS_QM_MOUNT(mp, quotamount, quotaflags);
1172 if (error) 1167 if (error)
1173 goto error4; 1168 goto out_rtunmount;
1174 1169
1175 /* 1170 /*
1176 * Now we are mounted, reserve a small amount of unused space for 1171 * Now we are mounted, reserve a small amount of unused space for
@@ -1194,18 +1189,18 @@ xfs_mountfs(
1194 1189
1195 return 0; 1190 return 0;
1196 1191
1197 error4: 1192 out_rtunmount:
1198 /* 1193 xfs_rtunmount_inodes(mp);
1199 * Free up the root inode. 1194 out_rele_rip:
1200 */
1201 IRELE(rip); 1195 IRELE(rip);
1202 error3: 1196 out_log_dealloc:
1203 xfs_log_unmount_dealloc(mp); 1197 xfs_log_unmount_dealloc(mp);
1204 error2: 1198 out_free_perag:
1205 xfs_free_perag(mp); 1199 xfs_free_perag(mp);
1206 error1: 1200 out_remove_uuid:
1207 if (uuid_mounted) 1201 if (!(mp->m_flags & XFS_MOUNT_NOUUID))
1208 uuid_table_remove(&mp->m_sb.sb_uuid); 1202 uuid_table_remove(&mp->m_sb.sb_uuid);
1203 out:
1209 return error; 1204 return error;
1210} 1205}
1211 1206
@@ -1226,10 +1221,7 @@ xfs_unmountfs(
1226 */ 1221 */
1227 XFS_QM_UNMOUNT(mp); 1222 XFS_QM_UNMOUNT(mp);
1228 1223
1229 if (mp->m_rbmip) 1224 xfs_rtunmount_inodes(mp);
1230 IRELE(mp->m_rbmip);
1231 if (mp->m_rsumip)
1232 IRELE(mp->m_rsumip);
1233 IRELE(mp->m_rootip); 1225 IRELE(mp->m_rootip);
1234 1226
1235 /* 1227 /*
diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h
index f5e9937f9bdb..670c10e098a0 100644
--- a/fs/xfs/xfs_mount.h
+++ b/fs/xfs/xfs_mount.h
@@ -500,9 +500,6 @@ typedef struct xfs_mod_sb {
500 int64_t msb_delta; /* Change to make to specified field */ 500 int64_t msb_delta; /* Change to make to specified field */
501} xfs_mod_sb_t; 501} xfs_mod_sb_t;
502 502
503#define XFS_MOUNT_ILOCK(mp) mutex_lock(&((mp)->m_ilock))
504#define XFS_MOUNT_IUNLOCK(mp) mutex_unlock(&((mp)->m_ilock))
505
506extern int xfs_log_sbcount(xfs_mount_t *, uint); 503extern int xfs_log_sbcount(xfs_mount_t *, uint);
507extern int xfs_mountfs(xfs_mount_t *mp); 504extern int xfs_mountfs(xfs_mount_t *mp);
508extern void xfs_mountfs_check_barriers(xfs_mount_t *mp); 505extern void xfs_mountfs_check_barriers(xfs_mount_t *mp);
diff --git a/fs/xfs/xfs_quota.h b/fs/xfs/xfs_quota.h
index 48965ecaa155..63d41acf4533 100644
--- a/fs/xfs/xfs_quota.h
+++ b/fs/xfs/xfs_quota.h
@@ -185,7 +185,6 @@ typedef struct xfs_qoff_logformat {
185 * to a single function. None of these XFS_QMOPT_* flags are meant to have 185 * to a single function. None of these XFS_QMOPT_* flags are meant to have
186 * persistent values (ie. their values can and will change between versions) 186 * persistent values (ie. their values can and will change between versions)
187 */ 187 */
188#define XFS_QMOPT_DQLOCK 0x0000001 /* dqlock */
189#define XFS_QMOPT_DQALLOC 0x0000002 /* alloc dquot ondisk if needed */ 188#define XFS_QMOPT_DQALLOC 0x0000002 /* alloc dquot ondisk if needed */
190#define XFS_QMOPT_UQUOTA 0x0000004 /* user dquot requested */ 189#define XFS_QMOPT_UQUOTA 0x0000004 /* user dquot requested */
191#define XFS_QMOPT_PQUOTA 0x0000008 /* project dquot requested */ 190#define XFS_QMOPT_PQUOTA 0x0000008 /* project dquot requested */
diff --git a/fs/xfs/xfs_rtalloc.c b/fs/xfs/xfs_rtalloc.c
index c5bb86f3ec05..385f6dceba5d 100644
--- a/fs/xfs/xfs_rtalloc.c
+++ b/fs/xfs/xfs_rtalloc.c
@@ -2288,6 +2288,16 @@ xfs_rtmount_inodes(
2288 return 0; 2288 return 0;
2289} 2289}
2290 2290
2291void
2292xfs_rtunmount_inodes(
2293 struct xfs_mount *mp)
2294{
2295 if (mp->m_rbmip)
2296 IRELE(mp->m_rbmip);
2297 if (mp->m_rsumip)
2298 IRELE(mp->m_rsumip);
2299}
2300
2291/* 2301/*
2292 * Pick an extent for allocation at the start of a new realtime file. 2302 * Pick an extent for allocation at the start of a new realtime file.
2293 * Use the sequence number stored in the atime field of the bitmap inode. 2303 * Use the sequence number stored in the atime field of the bitmap inode.
diff --git a/fs/xfs/xfs_rtalloc.h b/fs/xfs/xfs_rtalloc.h
index 8d8dcd215716..3bac681218a4 100644
--- a/fs/xfs/xfs_rtalloc.h
+++ b/fs/xfs/xfs_rtalloc.h
@@ -108,6 +108,9 @@ xfs_rtfree_extent(
108int /* error */ 108int /* error */
109xfs_rtmount_init( 109xfs_rtmount_init(
110 struct xfs_mount *mp); /* file system mount structure */ 110 struct xfs_mount *mp); /* file system mount structure */
111void
112xfs_rtunmount_inodes(
113 struct xfs_mount *mp);
111 114
112/* 115/*
113 * Get the bitmap and summary inodes into the mount structure 116 * Get the bitmap and summary inodes into the mount structure
@@ -146,6 +149,7 @@ xfs_growfs_rt(
146# define xfs_growfs_rt(mp,in) (ENOSYS) 149# define xfs_growfs_rt(mp,in) (ENOSYS)
147# define xfs_rtmount_init(m) (((mp)->m_sb.sb_rblocks == 0)? 0 : (ENOSYS)) 150# define xfs_rtmount_init(m) (((mp)->m_sb.sb_rblocks == 0)? 0 : (ENOSYS))
148# define xfs_rtmount_inodes(m) (((mp)->m_sb.sb_rblocks == 0)? 0 : (ENOSYS)) 151# define xfs_rtmount_inodes(m) (((mp)->m_sb.sb_rblocks == 0)? 0 : (ENOSYS))
152# define xfs_rtunmount_inodes(m)
149#endif /* CONFIG_XFS_RT */ 153#endif /* CONFIG_XFS_RT */
150 154
151#endif /* __KERNEL__ */ 155#endif /* __KERNEL__ */
diff --git a/fs/xfs/xfs_vnodeops.c b/fs/xfs/xfs_vnodeops.c
index 0e55c5d7db5f..bc0a0a75b1d6 100644
--- a/fs/xfs/xfs_vnodeops.c
+++ b/fs/xfs/xfs_vnodeops.c
@@ -2004,8 +2004,10 @@ xfs_link(
2004 /* Return through std_return after this point. */ 2004 /* Return through std_return after this point. */
2005 2005
2006 error = XFS_QM_DQATTACH(mp, sip, 0); 2006 error = XFS_QM_DQATTACH(mp, sip, 0);
2007 if (!error && sip != tdp) 2007 if (error)
2008 error = XFS_QM_DQATTACH(mp, tdp, 0); 2008 goto std_return;
2009
2010 error = XFS_QM_DQATTACH(mp, tdp, 0);
2009 if (error) 2011 if (error)
2010 goto std_return; 2012 goto std_return;
2011 2013
@@ -2587,51 +2589,6 @@ std_return:
2587} 2589}
2588 2590
2589int 2591int
2590xfs_inode_flush(
2591 xfs_inode_t *ip,
2592 int flags)
2593{
2594 xfs_mount_t *mp = ip->i_mount;
2595 int error = 0;
2596
2597 if (XFS_FORCED_SHUTDOWN(mp))
2598 return XFS_ERROR(EIO);
2599
2600 /*
2601 * Bypass inodes which have already been cleaned by
2602 * the inode flush clustering code inside xfs_iflush
2603 */
2604 if (xfs_inode_clean(ip))
2605 return 0;
2606
2607 /*
2608 * We make this non-blocking if the inode is contended,
2609 * return EAGAIN to indicate to the caller that they
2610 * did not succeed. This prevents the flush path from
2611 * blocking on inodes inside another operation right
2612 * now, they get caught later by xfs_sync.
2613 */
2614 if (flags & FLUSH_SYNC) {
2615 xfs_ilock(ip, XFS_ILOCK_SHARED);
2616 xfs_iflock(ip);
2617 } else if (xfs_ilock_nowait(ip, XFS_ILOCK_SHARED)) {
2618 if (xfs_ipincount(ip) || !xfs_iflock_nowait(ip)) {
2619 xfs_iunlock(ip, XFS_ILOCK_SHARED);
2620 return EAGAIN;
2621 }
2622 } else {
2623 return EAGAIN;
2624 }
2625
2626 error = xfs_iflush(ip, (flags & FLUSH_SYNC) ? XFS_IFLUSH_SYNC
2627 : XFS_IFLUSH_ASYNC_NOBLOCK);
2628 xfs_iunlock(ip, XFS_ILOCK_SHARED);
2629
2630 return error;
2631}
2632
2633
2634int
2635xfs_set_dmattrs( 2592xfs_set_dmattrs(
2636 xfs_inode_t *ip, 2593 xfs_inode_t *ip,
2637 u_int evmask, 2594 u_int evmask,
diff --git a/fs/xfs/xfs_vnodeops.h b/fs/xfs/xfs_vnodeops.h
index 76df328c61b4..2258df3fae84 100644
--- a/fs/xfs/xfs_vnodeops.h
+++ b/fs/xfs/xfs_vnodeops.h
@@ -38,7 +38,6 @@ int xfs_readdir(struct xfs_inode *dp, void *dirent, size_t bufsize,
38int xfs_symlink(struct xfs_inode *dp, struct xfs_name *link_name, 38int xfs_symlink(struct xfs_inode *dp, struct xfs_name *link_name,
39 const char *target_path, mode_t mode, struct xfs_inode **ipp, 39 const char *target_path, mode_t mode, struct xfs_inode **ipp,
40 cred_t *credp); 40 cred_t *credp);
41int xfs_inode_flush(struct xfs_inode *ip, int flags);
42int xfs_set_dmattrs(struct xfs_inode *ip, u_int evmask, u_int16_t state); 41int xfs_set_dmattrs(struct xfs_inode *ip, u_int evmask, u_int16_t state);
43int xfs_reclaim(struct xfs_inode *ip); 42int xfs_reclaim(struct xfs_inode *ip);
44int xfs_change_file_space(struct xfs_inode *ip, int cmd, 43int xfs_change_file_space(struct xfs_inode *ip, int cmd,