diff options
author | Felix Blyakher <felixb@sgi.com> | 2009-02-09 11:07:00 -0500 |
---|---|---|
committer | Felix Blyakher <felixb@sgi.com> | 2009-02-09 11:07:00 -0500 |
commit | 9483c89eae58bee79b0280c625ca35a7b78fa300 (patch) | |
tree | 5aab7aee070c3011b93662eb9db3f6abfafba479 | |
parent | d41d4113f49e16bfab02eff0248282200be21807 (diff) | |
parent | 8e9b6e7fa4544ea8a0e030c8987b918509c8ff47 (diff) |
Merge branch 'master' of git://git.kernel.org/pub/scm/fs/xfs/xfs
-rw-r--r-- | fs/xfs/linux-2.6/xfs_ioctl.c | 106 | ||||
-rw-r--r-- | fs/xfs/linux-2.6/xfs_super.c | 43 | ||||
-rw-r--r-- | fs/xfs/linux-2.6/xfs_vnode.h | 5 | ||||
-rw-r--r-- | fs/xfs/quota/xfs_qm.c | 146 | ||||
-rw-r--r-- | fs/xfs/quota/xfs_trans_dquot.c | 16 | ||||
-rw-r--r-- | fs/xfs/xfs_attr_leaf.c | 55 | ||||
-rw-r--r-- | fs/xfs/xfs_dfrag.c | 62 | ||||
-rw-r--r-- | fs/xfs/xfs_mount.c | 84 | ||||
-rw-r--r-- | fs/xfs/xfs_mount.h | 3 | ||||
-rw-r--r-- | fs/xfs/xfs_quota.h | 1 | ||||
-rw-r--r-- | fs/xfs/xfs_rtalloc.c | 10 | ||||
-rw-r--r-- | fs/xfs/xfs_rtalloc.h | 4 | ||||
-rw-r--r-- | fs/xfs/xfs_vnodeops.c | 51 | ||||
-rw-r--r-- | fs/xfs/xfs_vnodeops.h | 1 |
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 | ||
1005 | out_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( | |||
754 | STATIC void | 724 | STATIC void |
755 | xfs_qm_dqattach_grouphint( | 725 | xfs_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 | ||
742 | error_return: | 741 | error_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 | */ | ||
304 | STATIC void | ||
305 | xfs_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 | */ |
303 | int | 323 | int |
@@ -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: | 344 | out_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); | 347 | out: |
358 | } | 348 | kmem_free(tempifp); |
359 | if (tempifp != NULL) | ||
360 | kmem_free(tempifp); | ||
361 | return error; | 349 | return error; |
350 | |||
351 | out_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, "amount, "aflags); | 1148 | error = XFS_QM_INIT(mp, "amount, "aflags); |
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 | |||
506 | extern int xfs_log_sbcount(xfs_mount_t *, uint); | 503 | extern int xfs_log_sbcount(xfs_mount_t *, uint); |
507 | extern int xfs_mountfs(xfs_mount_t *mp); | 504 | extern int xfs_mountfs(xfs_mount_t *mp); |
508 | extern void xfs_mountfs_check_barriers(xfs_mount_t *mp); | 505 | extern 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 | ||
2291 | void | ||
2292 | xfs_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( | |||
108 | int /* error */ | 108 | int /* error */ |
109 | xfs_rtmount_init( | 109 | xfs_rtmount_init( |
110 | struct xfs_mount *mp); /* file system mount structure */ | 110 | struct xfs_mount *mp); /* file system mount structure */ |
111 | void | ||
112 | xfs_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 | ||
2589 | int | 2591 | int |
2590 | xfs_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 | |||
2634 | int | ||
2635 | xfs_set_dmattrs( | 2592 | xfs_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, | |||
38 | int xfs_symlink(struct xfs_inode *dp, struct xfs_name *link_name, | 38 | int 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); |
41 | int xfs_inode_flush(struct xfs_inode *ip, int flags); | ||
42 | int xfs_set_dmattrs(struct xfs_inode *ip, u_int evmask, u_int16_t state); | 41 | int xfs_set_dmattrs(struct xfs_inode *ip, u_int evmask, u_int16_t state); |
43 | int xfs_reclaim(struct xfs_inode *ip); | 42 | int xfs_reclaim(struct xfs_inode *ip); |
44 | int xfs_change_file_space(struct xfs_inode *ip, int cmd, | 43 | int xfs_change_file_space(struct xfs_inode *ip, int cmd, |