diff options
Diffstat (limited to 'fs')
40 files changed, 599 insertions, 1096 deletions
diff --git a/fs/xfs/Makefile b/fs/xfs/Makefile index c3dc491fff89..60f107e47fe9 100644 --- a/fs/xfs/Makefile +++ b/fs/xfs/Makefile | |||
@@ -33,6 +33,7 @@ xfs-$(CONFIG_XFS_QUOTA) += $(addprefix quota/, \ | |||
33 | xfs_qm_syscalls.o \ | 33 | xfs_qm_syscalls.o \ |
34 | xfs_qm_bhv.o \ | 34 | xfs_qm_bhv.o \ |
35 | xfs_qm.o) | 35 | xfs_qm.o) |
36 | xfs-$(CONFIG_XFS_QUOTA) += linux-2.6/xfs_quotaops.o | ||
36 | 37 | ||
37 | ifeq ($(CONFIG_XFS_QUOTA),y) | 38 | ifeq ($(CONFIG_XFS_QUOTA),y) |
38 | xfs-$(CONFIG_PROC_FS) += quota/xfs_qm_stats.o | 39 | xfs-$(CONFIG_PROC_FS) += quota/xfs_qm_stats.o |
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_iops.c b/fs/xfs/linux-2.6/xfs_iops.c index 7aa53fefc67f..e103b05dc777 100644 --- a/fs/xfs/linux-2.6/xfs_iops.c +++ b/fs/xfs/linux-2.6/xfs_iops.c | |||
@@ -211,8 +211,13 @@ xfs_vn_mknod( | |||
211 | * Irix uses Missed'em'V split, but doesn't want to see | 211 | * Irix uses Missed'em'V split, but doesn't want to see |
212 | * the upper 5 bits of (14bit) major. | 212 | * the upper 5 bits of (14bit) major. |
213 | */ | 213 | */ |
214 | if (unlikely(!sysv_valid_dev(rdev) || MAJOR(rdev) & ~0x1ff)) | 214 | if (S_ISCHR(mode) || S_ISBLK(mode)) { |
215 | return -EINVAL; | 215 | if (unlikely(!sysv_valid_dev(rdev) || MAJOR(rdev) & ~0x1ff)) |
216 | return -EINVAL; | ||
217 | rdev = sysv_encode_dev(rdev); | ||
218 | } else { | ||
219 | rdev = 0; | ||
220 | } | ||
216 | 221 | ||
217 | if (test_default_acl && test_default_acl(dir)) { | 222 | if (test_default_acl && test_default_acl(dir)) { |
218 | if (!_ACL_ALLOC(default_acl)) { | 223 | if (!_ACL_ALLOC(default_acl)) { |
@@ -224,28 +229,11 @@ xfs_vn_mknod( | |||
224 | } | 229 | } |
225 | } | 230 | } |
226 | 231 | ||
227 | xfs_dentry_to_name(&name, dentry); | ||
228 | |||
229 | if (IS_POSIXACL(dir) && !default_acl) | 232 | if (IS_POSIXACL(dir) && !default_acl) |
230 | mode &= ~current->fs->umask; | 233 | mode &= ~current->fs->umask; |
231 | 234 | ||
232 | switch (mode & S_IFMT) { | 235 | xfs_dentry_to_name(&name, dentry); |
233 | case S_IFCHR: | 236 | error = xfs_create(XFS_I(dir), &name, mode, rdev, &ip, NULL); |
234 | case S_IFBLK: | ||
235 | case S_IFIFO: | ||
236 | case S_IFSOCK: | ||
237 | rdev = sysv_encode_dev(rdev); | ||
238 | case S_IFREG: | ||
239 | error = xfs_create(XFS_I(dir), &name, mode, rdev, &ip, NULL); | ||
240 | break; | ||
241 | case S_IFDIR: | ||
242 | error = xfs_mkdir(XFS_I(dir), &name, mode, &ip, NULL); | ||
243 | break; | ||
244 | default: | ||
245 | error = EINVAL; | ||
246 | break; | ||
247 | } | ||
248 | |||
249 | if (unlikely(error)) | 237 | if (unlikely(error)) |
250 | goto out_free_acl; | 238 | goto out_free_acl; |
251 | 239 | ||
diff --git a/fs/xfs/linux-2.6/xfs_linux.h b/fs/xfs/linux-2.6/xfs_linux.h index 507492d6dccd..fc8d776ba05b 100644 --- a/fs/xfs/linux-2.6/xfs_linux.h +++ b/fs/xfs/linux-2.6/xfs_linux.h | |||
@@ -147,17 +147,6 @@ | |||
147 | #define SYNCHRONIZE() barrier() | 147 | #define SYNCHRONIZE() barrier() |
148 | #define __return_address __builtin_return_address(0) | 148 | #define __return_address __builtin_return_address(0) |
149 | 149 | ||
150 | /* | ||
151 | * IRIX (BSD) quotactl makes use of separate commands for user/group, | ||
152 | * whereas on Linux the syscall encodes this information into the cmd | ||
153 | * field (see the QCMD macro in quota.h). These macros help keep the | ||
154 | * code portable - they are not visible from the syscall interface. | ||
155 | */ | ||
156 | #define Q_XSETGQLIM XQM_CMD(8) /* set groups disk limits */ | ||
157 | #define Q_XGETGQUOTA XQM_CMD(9) /* get groups disk limits */ | ||
158 | #define Q_XSETPQLIM XQM_CMD(10) /* set projects disk limits */ | ||
159 | #define Q_XGETPQUOTA XQM_CMD(11) /* get projects disk limits */ | ||
160 | |||
161 | #define dfltprid 0 | 150 | #define dfltprid 0 |
162 | #define MAXPATHLEN 1024 | 151 | #define MAXPATHLEN 1024 |
163 | 152 | ||
diff --git a/fs/xfs/linux-2.6/xfs_quotaops.c b/fs/xfs/linux-2.6/xfs_quotaops.c new file mode 100644 index 000000000000..94d9a633d3d9 --- /dev/null +++ b/fs/xfs/linux-2.6/xfs_quotaops.c | |||
@@ -0,0 +1,157 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2008, Christoph Hellwig | ||
3 | * All Rights Reserved. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or | ||
6 | * modify it under the terms of the GNU General Public License as | ||
7 | * published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope that it would be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License | ||
15 | * along with this program; if not, write the Free Software Foundation, | ||
16 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
17 | */ | ||
18 | #include "xfs.h" | ||
19 | #include "xfs_dmapi.h" | ||
20 | #include "xfs_sb.h" | ||
21 | #include "xfs_inum.h" | ||
22 | #include "xfs_ag.h" | ||
23 | #include "xfs_mount.h" | ||
24 | #include "xfs_quota.h" | ||
25 | #include "xfs_log.h" | ||
26 | #include "xfs_trans.h" | ||
27 | #include "xfs_bmap_btree.h" | ||
28 | #include "xfs_inode.h" | ||
29 | #include "quota/xfs_qm.h" | ||
30 | #include <linux/quota.h> | ||
31 | |||
32 | |||
33 | STATIC int | ||
34 | xfs_quota_type(int type) | ||
35 | { | ||
36 | switch (type) { | ||
37 | case USRQUOTA: | ||
38 | return XFS_DQ_USER; | ||
39 | case GRPQUOTA: | ||
40 | return XFS_DQ_GROUP; | ||
41 | default: | ||
42 | return XFS_DQ_PROJ; | ||
43 | } | ||
44 | } | ||
45 | |||
46 | STATIC int | ||
47 | xfs_fs_quota_sync( | ||
48 | struct super_block *sb, | ||
49 | int type) | ||
50 | { | ||
51 | struct xfs_mount *mp = XFS_M(sb); | ||
52 | |||
53 | if (!XFS_IS_QUOTA_RUNNING(mp)) | ||
54 | return -ENOSYS; | ||
55 | return -xfs_sync_inodes(mp, SYNC_DELWRI); | ||
56 | } | ||
57 | |||
58 | STATIC int | ||
59 | xfs_fs_get_xstate( | ||
60 | struct super_block *sb, | ||
61 | struct fs_quota_stat *fqs) | ||
62 | { | ||
63 | struct xfs_mount *mp = XFS_M(sb); | ||
64 | |||
65 | if (!XFS_IS_QUOTA_RUNNING(mp)) | ||
66 | return -ENOSYS; | ||
67 | return -xfs_qm_scall_getqstat(mp, fqs); | ||
68 | } | ||
69 | |||
70 | STATIC int | ||
71 | xfs_fs_set_xstate( | ||
72 | struct super_block *sb, | ||
73 | unsigned int uflags, | ||
74 | int op) | ||
75 | { | ||
76 | struct xfs_mount *mp = XFS_M(sb); | ||
77 | unsigned int flags = 0; | ||
78 | |||
79 | if (sb->s_flags & MS_RDONLY) | ||
80 | return -EROFS; | ||
81 | if (!XFS_IS_QUOTA_RUNNING(mp)) | ||
82 | return -ENOSYS; | ||
83 | if (!capable(CAP_SYS_ADMIN)) | ||
84 | return -EPERM; | ||
85 | |||
86 | if (uflags & XFS_QUOTA_UDQ_ACCT) | ||
87 | flags |= XFS_UQUOTA_ACCT; | ||
88 | if (uflags & XFS_QUOTA_PDQ_ACCT) | ||
89 | flags |= XFS_PQUOTA_ACCT; | ||
90 | if (uflags & XFS_QUOTA_GDQ_ACCT) | ||
91 | flags |= XFS_GQUOTA_ACCT; | ||
92 | if (uflags & XFS_QUOTA_UDQ_ENFD) | ||
93 | flags |= XFS_UQUOTA_ENFD; | ||
94 | if (uflags & (XFS_QUOTA_PDQ_ENFD|XFS_QUOTA_GDQ_ENFD)) | ||
95 | flags |= XFS_OQUOTA_ENFD; | ||
96 | |||
97 | switch (op) { | ||
98 | case Q_XQUOTAON: | ||
99 | return -xfs_qm_scall_quotaon(mp, flags); | ||
100 | case Q_XQUOTAOFF: | ||
101 | if (!XFS_IS_QUOTA_ON(mp)) | ||
102 | return -EINVAL; | ||
103 | return -xfs_qm_scall_quotaoff(mp, flags); | ||
104 | case Q_XQUOTARM: | ||
105 | if (XFS_IS_QUOTA_ON(mp)) | ||
106 | return -EINVAL; | ||
107 | return -xfs_qm_scall_trunc_qfiles(mp, flags); | ||
108 | } | ||
109 | |||
110 | return -EINVAL; | ||
111 | } | ||
112 | |||
113 | STATIC int | ||
114 | xfs_fs_get_xquota( | ||
115 | struct super_block *sb, | ||
116 | int type, | ||
117 | qid_t id, | ||
118 | struct fs_disk_quota *fdq) | ||
119 | { | ||
120 | struct xfs_mount *mp = XFS_M(sb); | ||
121 | |||
122 | if (!XFS_IS_QUOTA_RUNNING(mp)) | ||
123 | return -ENOSYS; | ||
124 | if (!XFS_IS_QUOTA_ON(mp)) | ||
125 | return -ESRCH; | ||
126 | |||
127 | return -xfs_qm_scall_getquota(mp, id, xfs_quota_type(type), fdq); | ||
128 | } | ||
129 | |||
130 | STATIC int | ||
131 | xfs_fs_set_xquota( | ||
132 | struct super_block *sb, | ||
133 | int type, | ||
134 | qid_t id, | ||
135 | struct fs_disk_quota *fdq) | ||
136 | { | ||
137 | struct xfs_mount *mp = XFS_M(sb); | ||
138 | |||
139 | if (sb->s_flags & MS_RDONLY) | ||
140 | return -EROFS; | ||
141 | if (!XFS_IS_QUOTA_RUNNING(mp)) | ||
142 | return -ENOSYS; | ||
143 | if (!XFS_IS_QUOTA_ON(mp)) | ||
144 | return -ESRCH; | ||
145 | if (!capable(CAP_SYS_ADMIN)) | ||
146 | return -EPERM; | ||
147 | |||
148 | return -xfs_qm_scall_setqlim(mp, id, xfs_quota_type(type), fdq); | ||
149 | } | ||
150 | |||
151 | struct quotactl_ops xfs_quotactl_operations = { | ||
152 | .quota_sync = xfs_fs_quota_sync, | ||
153 | .get_xstate = xfs_fs_get_xstate, | ||
154 | .set_xstate = xfs_fs_set_xstate, | ||
155 | .get_xquota = xfs_fs_get_xquota, | ||
156 | .set_xquota = xfs_fs_set_xquota, | ||
157 | }; | ||
diff --git a/fs/xfs/linux-2.6/xfs_super.c b/fs/xfs/linux-2.6/xfs_super.c index c71e226da7f5..bc1e64708e2b 100644 --- a/fs/xfs/linux-2.6/xfs_super.c +++ b/fs/xfs/linux-2.6/xfs_super.c | |||
@@ -68,7 +68,6 @@ | |||
68 | #include <linux/freezer.h> | 68 | #include <linux/freezer.h> |
69 | #include <linux/parser.h> | 69 | #include <linux/parser.h> |
70 | 70 | ||
71 | static struct quotactl_ops xfs_quotactl_operations; | ||
72 | static struct super_operations xfs_super_operations; | 71 | static struct super_operations xfs_super_operations; |
73 | static kmem_zone_t *xfs_ioend_zone; | 72 | static kmem_zone_t *xfs_ioend_zone; |
74 | mempool_t *xfs_ioend_pool; | 73 | mempool_t *xfs_ioend_pool; |
@@ -180,7 +179,7 @@ xfs_parseargs( | |||
180 | int dswidth = 0; | 179 | int dswidth = 0; |
181 | int iosize = 0; | 180 | int iosize = 0; |
182 | int dmapi_implies_ikeep = 1; | 181 | int dmapi_implies_ikeep = 1; |
183 | uchar_t iosizelog = 0; | 182 | __uint8_t iosizelog = 0; |
184 | 183 | ||
185 | /* | 184 | /* |
186 | * Copy binary VFS mount flags we are interested in. | 185 | * Copy binary VFS mount flags we are interested in. |
@@ -990,26 +989,57 @@ xfs_fs_write_inode( | |||
990 | int sync) | 989 | int sync) |
991 | { | 990 | { |
992 | struct xfs_inode *ip = XFS_I(inode); | 991 | struct xfs_inode *ip = XFS_I(inode); |
992 | struct xfs_mount *mp = ip->i_mount; | ||
993 | int error = 0; | 993 | int error = 0; |
994 | int flags = 0; | ||
995 | 994 | ||
996 | xfs_itrace_entry(ip); | 995 | xfs_itrace_entry(ip); |
996 | |||
997 | if (XFS_FORCED_SHUTDOWN(mp)) | ||
998 | return XFS_ERROR(EIO); | ||
999 | |||
997 | if (sync) { | 1000 | if (sync) { |
998 | error = xfs_wait_on_pages(ip, 0, -1); | 1001 | error = xfs_wait_on_pages(ip, 0, -1); |
999 | if (error) | 1002 | if (error) |
1000 | goto out_error; | 1003 | goto out; |
1001 | flags |= FLUSH_SYNC; | ||
1002 | } | 1004 | } |
1003 | error = xfs_inode_flush(ip, flags); | ||
1004 | 1005 | ||
1005 | out_error: | 1006 | /* |
1007 | * Bypass inodes which have already been cleaned by | ||
1008 | * the inode flush clustering code inside xfs_iflush | ||
1009 | */ | ||
1010 | if (xfs_inode_clean(ip)) | ||
1011 | goto out; | ||
1012 | |||
1013 | /* | ||
1014 | * We make this non-blocking if the inode is contended, return | ||
1015 | * EAGAIN to indicate to the caller that they did not succeed. | ||
1016 | * This prevents the flush path from blocking on inodes inside | ||
1017 | * another operation right now, they get caught later by xfs_sync. | ||
1018 | */ | ||
1019 | if (sync) { | ||
1020 | xfs_ilock(ip, XFS_ILOCK_SHARED); | ||
1021 | xfs_iflock(ip); | ||
1022 | |||
1023 | error = xfs_iflush(ip, XFS_IFLUSH_SYNC); | ||
1024 | } else { | ||
1025 | error = EAGAIN; | ||
1026 | if (!xfs_ilock_nowait(ip, XFS_ILOCK_SHARED)) | ||
1027 | goto out; | ||
1028 | if (xfs_ipincount(ip) || !xfs_iflock_nowait(ip)) | ||
1029 | goto out_unlock; | ||
1030 | |||
1031 | error = xfs_iflush(ip, XFS_IFLUSH_ASYNC_NOBLOCK); | ||
1032 | } | ||
1033 | |||
1034 | out_unlock: | ||
1035 | xfs_iunlock(ip, XFS_ILOCK_SHARED); | ||
1036 | out: | ||
1006 | /* | 1037 | /* |
1007 | * if we failed to write out the inode then mark | 1038 | * if we failed to write out the inode then mark |
1008 | * it dirty again so we'll try again later. | 1039 | * it dirty again so we'll try again later. |
1009 | */ | 1040 | */ |
1010 | if (error) | 1041 | if (error) |
1011 | xfs_mark_inode_dirty_sync(ip); | 1042 | xfs_mark_inode_dirty_sync(ip); |
1012 | |||
1013 | return -error; | 1043 | return -error; |
1014 | } | 1044 | } |
1015 | 1045 | ||
@@ -1302,57 +1332,6 @@ xfs_fs_show_options( | |||
1302 | return -xfs_showargs(XFS_M(mnt->mnt_sb), m); | 1332 | return -xfs_showargs(XFS_M(mnt->mnt_sb), m); |
1303 | } | 1333 | } |
1304 | 1334 | ||
1305 | STATIC int | ||
1306 | xfs_fs_quotasync( | ||
1307 | struct super_block *sb, | ||
1308 | int type) | ||
1309 | { | ||
1310 | return -XFS_QM_QUOTACTL(XFS_M(sb), Q_XQUOTASYNC, 0, NULL); | ||
1311 | } | ||
1312 | |||
1313 | STATIC int | ||
1314 | xfs_fs_getxstate( | ||
1315 | struct super_block *sb, | ||
1316 | struct fs_quota_stat *fqs) | ||
1317 | { | ||
1318 | return -XFS_QM_QUOTACTL(XFS_M(sb), Q_XGETQSTAT, 0, (caddr_t)fqs); | ||
1319 | } | ||
1320 | |||
1321 | STATIC int | ||
1322 | xfs_fs_setxstate( | ||
1323 | struct super_block *sb, | ||
1324 | unsigned int flags, | ||
1325 | int op) | ||
1326 | { | ||
1327 | return -XFS_QM_QUOTACTL(XFS_M(sb), op, 0, (caddr_t)&flags); | ||
1328 | } | ||
1329 | |||
1330 | STATIC int | ||
1331 | xfs_fs_getxquota( | ||
1332 | struct super_block *sb, | ||
1333 | int type, | ||
1334 | qid_t id, | ||
1335 | struct fs_disk_quota *fdq) | ||
1336 | { | ||
1337 | return -XFS_QM_QUOTACTL(XFS_M(sb), | ||
1338 | (type == USRQUOTA) ? Q_XGETQUOTA : | ||
1339 | ((type == GRPQUOTA) ? Q_XGETGQUOTA : | ||
1340 | Q_XGETPQUOTA), id, (caddr_t)fdq); | ||
1341 | } | ||
1342 | |||
1343 | STATIC int | ||
1344 | xfs_fs_setxquota( | ||
1345 | struct super_block *sb, | ||
1346 | int type, | ||
1347 | qid_t id, | ||
1348 | struct fs_disk_quota *fdq) | ||
1349 | { | ||
1350 | return -XFS_QM_QUOTACTL(XFS_M(sb), | ||
1351 | (type == USRQUOTA) ? Q_XSETQLIM : | ||
1352 | ((type == GRPQUOTA) ? Q_XSETGQLIM : | ||
1353 | Q_XSETPQLIM), id, (caddr_t)fdq); | ||
1354 | } | ||
1355 | |||
1356 | /* | 1335 | /* |
1357 | * This function fills in xfs_mount_t fields based on mount args. | 1336 | * This function fills in xfs_mount_t fields based on mount args. |
1358 | * Note: the superblock _has_ now been read in. | 1337 | * Note: the superblock _has_ now been read in. |
@@ -1435,7 +1414,9 @@ xfs_fs_fill_super( | |||
1435 | sb_min_blocksize(sb, BBSIZE); | 1414 | sb_min_blocksize(sb, BBSIZE); |
1436 | sb->s_xattr = xfs_xattr_handlers; | 1415 | sb->s_xattr = xfs_xattr_handlers; |
1437 | sb->s_export_op = &xfs_export_operations; | 1416 | sb->s_export_op = &xfs_export_operations; |
1417 | #ifdef CONFIG_XFS_QUOTA | ||
1438 | sb->s_qcop = &xfs_quotactl_operations; | 1418 | sb->s_qcop = &xfs_quotactl_operations; |
1419 | #endif | ||
1439 | sb->s_op = &xfs_super_operations; | 1420 | sb->s_op = &xfs_super_operations; |
1440 | 1421 | ||
1441 | error = xfs_dmops_get(mp); | 1422 | error = xfs_dmops_get(mp); |
@@ -1578,14 +1559,6 @@ static struct super_operations xfs_super_operations = { | |||
1578 | .show_options = xfs_fs_show_options, | 1559 | .show_options = xfs_fs_show_options, |
1579 | }; | 1560 | }; |
1580 | 1561 | ||
1581 | static struct quotactl_ops xfs_quotactl_operations = { | ||
1582 | .quota_sync = xfs_fs_quotasync, | ||
1583 | .get_xstate = xfs_fs_getxstate, | ||
1584 | .set_xstate = xfs_fs_setxstate, | ||
1585 | .get_xquota = xfs_fs_getxquota, | ||
1586 | .set_xquota = xfs_fs_setxquota, | ||
1587 | }; | ||
1588 | |||
1589 | static struct file_system_type xfs_fs_type = { | 1562 | static struct file_system_type xfs_fs_type = { |
1590 | .owner = THIS_MODULE, | 1563 | .owner = THIS_MODULE, |
1591 | .name = "xfs", | 1564 | .name = "xfs", |
diff --git a/fs/xfs/linux-2.6/xfs_super.h b/fs/xfs/linux-2.6/xfs_super.h index d5d776d4cd67..5a2ea3a21781 100644 --- a/fs/xfs/linux-2.6/xfs_super.h +++ b/fs/xfs/linux-2.6/xfs_super.h | |||
@@ -93,6 +93,7 @@ extern void xfs_blkdev_issue_flush(struct xfs_buftarg *); | |||
93 | 93 | ||
94 | extern const struct export_operations xfs_export_operations; | 94 | extern const struct export_operations xfs_export_operations; |
95 | extern struct xattr_handler *xfs_xattr_handlers[]; | 95 | extern struct xattr_handler *xfs_xattr_handlers[]; |
96 | extern struct quotactl_ops xfs_quotactl_operations; | ||
96 | 97 | ||
97 | #define XFS_M(sb) ((struct xfs_mount *)((sb)->s_fs_info)) | 98 | #define XFS_M(sb) ((struct xfs_mount *)((sb)->s_fs_info)) |
98 | 99 | ||
diff --git a/fs/xfs/linux-2.6/xfs_sync.h b/fs/xfs/linux-2.6/xfs_sync.h index 5f6de1efe1f6..04f058c848ae 100644 --- a/fs/xfs/linux-2.6/xfs_sync.h +++ b/fs/xfs/linux-2.6/xfs_sync.h | |||
@@ -19,6 +19,7 @@ | |||
19 | #define XFS_SYNC_H 1 | 19 | #define XFS_SYNC_H 1 |
20 | 20 | ||
21 | struct xfs_mount; | 21 | struct xfs_mount; |
22 | struct xfs_perag; | ||
22 | 23 | ||
23 | typedef struct bhv_vfs_sync_work { | 24 | typedef struct bhv_vfs_sync_work { |
24 | struct list_head w_list; | 25 | struct list_head w_list; |
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_dquot.c b/fs/xfs/quota/xfs_dquot.c index 6543c0b29753..e4babcc63423 100644 --- a/fs/xfs/quota/xfs_dquot.c +++ b/fs/xfs/quota/xfs_dquot.c | |||
@@ -804,7 +804,7 @@ xfs_qm_dqlookup( | |||
804 | uint flist_locked; | 804 | uint flist_locked; |
805 | xfs_dquot_t *d; | 805 | xfs_dquot_t *d; |
806 | 806 | ||
807 | ASSERT(XFS_DQ_IS_HASH_LOCKED(qh)); | 807 | ASSERT(mutex_is_locked(&qh->qh_lock)); |
808 | 808 | ||
809 | flist_locked = B_FALSE; | 809 | flist_locked = B_FALSE; |
810 | 810 | ||
@@ -877,7 +877,7 @@ xfs_qm_dqlookup( | |||
877 | /* | 877 | /* |
878 | * move the dquot to the front of the hashchain | 878 | * move the dquot to the front of the hashchain |
879 | */ | 879 | */ |
880 | ASSERT(XFS_DQ_IS_HASH_LOCKED(qh)); | 880 | ASSERT(mutex_is_locked(&qh->qh_lock)); |
881 | if (dqp->HL_PREVP != &qh->qh_next) { | 881 | if (dqp->HL_PREVP != &qh->qh_next) { |
882 | xfs_dqtrace_entry(dqp, | 882 | xfs_dqtrace_entry(dqp, |
883 | "DQLOOKUP: HASH MOVETOFRONT"); | 883 | "DQLOOKUP: HASH MOVETOFRONT"); |
@@ -892,13 +892,13 @@ xfs_qm_dqlookup( | |||
892 | } | 892 | } |
893 | xfs_dqtrace_entry(dqp, "LOOKUP END"); | 893 | xfs_dqtrace_entry(dqp, "LOOKUP END"); |
894 | *O_dqpp = dqp; | 894 | *O_dqpp = dqp; |
895 | ASSERT(XFS_DQ_IS_HASH_LOCKED(qh)); | 895 | ASSERT(mutex_is_locked(&qh->qh_lock)); |
896 | return (0); | 896 | return (0); |
897 | } | 897 | } |
898 | } | 898 | } |
899 | 899 | ||
900 | *O_dqpp = NULL; | 900 | *O_dqpp = NULL; |
901 | ASSERT(XFS_DQ_IS_HASH_LOCKED(qh)); | 901 | ASSERT(mutex_is_locked(&qh->qh_lock)); |
902 | return (1); | 902 | return (1); |
903 | } | 903 | } |
904 | 904 | ||
@@ -956,7 +956,7 @@ xfs_qm_dqget( | |||
956 | ASSERT(ip->i_gdquot == NULL); | 956 | ASSERT(ip->i_gdquot == NULL); |
957 | } | 957 | } |
958 | #endif | 958 | #endif |
959 | XFS_DQ_HASH_LOCK(h); | 959 | mutex_lock(&h->qh_lock); |
960 | 960 | ||
961 | /* | 961 | /* |
962 | * Look in the cache (hashtable). | 962 | * Look in the cache (hashtable). |
@@ -971,7 +971,7 @@ xfs_qm_dqget( | |||
971 | */ | 971 | */ |
972 | ASSERT(*O_dqpp); | 972 | ASSERT(*O_dqpp); |
973 | ASSERT(XFS_DQ_IS_LOCKED(*O_dqpp)); | 973 | ASSERT(XFS_DQ_IS_LOCKED(*O_dqpp)); |
974 | XFS_DQ_HASH_UNLOCK(h); | 974 | mutex_unlock(&h->qh_lock); |
975 | xfs_dqtrace_entry(*O_dqpp, "DQGET DONE (FROM CACHE)"); | 975 | xfs_dqtrace_entry(*O_dqpp, "DQGET DONE (FROM CACHE)"); |
976 | return (0); /* success */ | 976 | return (0); /* success */ |
977 | } | 977 | } |
@@ -991,7 +991,7 @@ xfs_qm_dqget( | |||
991 | * we don't keep the lock across a disk read | 991 | * we don't keep the lock across a disk read |
992 | */ | 992 | */ |
993 | version = h->qh_version; | 993 | version = h->qh_version; |
994 | XFS_DQ_HASH_UNLOCK(h); | 994 | mutex_unlock(&h->qh_lock); |
995 | 995 | ||
996 | /* | 996 | /* |
997 | * Allocate the dquot on the kernel heap, and read the ondisk | 997 | * Allocate the dquot on the kernel heap, and read the ondisk |
@@ -1056,7 +1056,7 @@ xfs_qm_dqget( | |||
1056 | /* | 1056 | /* |
1057 | * Hashlock comes after ilock in lock order | 1057 | * Hashlock comes after ilock in lock order |
1058 | */ | 1058 | */ |
1059 | XFS_DQ_HASH_LOCK(h); | 1059 | mutex_lock(&h->qh_lock); |
1060 | if (version != h->qh_version) { | 1060 | if (version != h->qh_version) { |
1061 | xfs_dquot_t *tmpdqp; | 1061 | xfs_dquot_t *tmpdqp; |
1062 | /* | 1062 | /* |
@@ -1072,7 +1072,7 @@ xfs_qm_dqget( | |||
1072 | * and start over. | 1072 | * and start over. |
1073 | */ | 1073 | */ |
1074 | xfs_qm_dqput(tmpdqp); | 1074 | xfs_qm_dqput(tmpdqp); |
1075 | XFS_DQ_HASH_UNLOCK(h); | 1075 | mutex_unlock(&h->qh_lock); |
1076 | xfs_qm_dqdestroy(dqp); | 1076 | xfs_qm_dqdestroy(dqp); |
1077 | XQM_STATS_INC(xqmstats.xs_qm_dquot_dups); | 1077 | XQM_STATS_INC(xqmstats.xs_qm_dquot_dups); |
1078 | goto again; | 1078 | goto again; |
@@ -1083,7 +1083,7 @@ xfs_qm_dqget( | |||
1083 | * Put the dquot at the beginning of the hash-chain and mp's list | 1083 | * Put the dquot at the beginning of the hash-chain and mp's list |
1084 | * LOCK ORDER: hashlock, freelistlock, mplistlock, udqlock, gdqlock .. | 1084 | * LOCK ORDER: hashlock, freelistlock, mplistlock, udqlock, gdqlock .. |
1085 | */ | 1085 | */ |
1086 | ASSERT(XFS_DQ_IS_HASH_LOCKED(h)); | 1086 | ASSERT(mutex_is_locked(&h->qh_lock)); |
1087 | dqp->q_hash = h; | 1087 | dqp->q_hash = h; |
1088 | XQM_HASHLIST_INSERT(h, dqp); | 1088 | XQM_HASHLIST_INSERT(h, dqp); |
1089 | 1089 | ||
@@ -1102,7 +1102,7 @@ xfs_qm_dqget( | |||
1102 | XQM_MPLIST_INSERT(&(XFS_QI_MPL_LIST(mp)), dqp); | 1102 | XQM_MPLIST_INSERT(&(XFS_QI_MPL_LIST(mp)), dqp); |
1103 | 1103 | ||
1104 | xfs_qm_mplist_unlock(mp); | 1104 | xfs_qm_mplist_unlock(mp); |
1105 | XFS_DQ_HASH_UNLOCK(h); | 1105 | mutex_unlock(&h->qh_lock); |
1106 | dqret: | 1106 | dqret: |
1107 | ASSERT((ip == NULL) || xfs_isilocked(ip, XFS_ILOCK_EXCL)); | 1107 | ASSERT((ip == NULL) || xfs_isilocked(ip, XFS_ILOCK_EXCL)); |
1108 | xfs_dqtrace_entry(dqp, "DQGET DONE"); | 1108 | xfs_dqtrace_entry(dqp, "DQGET DONE"); |
@@ -1440,7 +1440,7 @@ xfs_qm_dqpurge( | |||
1440 | xfs_mount_t *mp = dqp->q_mount; | 1440 | xfs_mount_t *mp = dqp->q_mount; |
1441 | 1441 | ||
1442 | ASSERT(XFS_QM_IS_MPLIST_LOCKED(mp)); | 1442 | ASSERT(XFS_QM_IS_MPLIST_LOCKED(mp)); |
1443 | ASSERT(XFS_DQ_IS_HASH_LOCKED(dqp->q_hash)); | 1443 | ASSERT(mutex_is_locked(&dqp->q_hash->qh_lock)); |
1444 | 1444 | ||
1445 | xfs_dqlock(dqp); | 1445 | xfs_dqlock(dqp); |
1446 | /* | 1446 | /* |
@@ -1453,7 +1453,7 @@ xfs_qm_dqpurge( | |||
1453 | */ | 1453 | */ |
1454 | if (dqp->q_nrefs != 0) { | 1454 | if (dqp->q_nrefs != 0) { |
1455 | xfs_dqunlock(dqp); | 1455 | xfs_dqunlock(dqp); |
1456 | XFS_DQ_HASH_UNLOCK(dqp->q_hash); | 1456 | mutex_unlock(&dqp->q_hash->qh_lock); |
1457 | return (1); | 1457 | return (1); |
1458 | } | 1458 | } |
1459 | 1459 | ||
@@ -1517,7 +1517,7 @@ xfs_qm_dqpurge( | |||
1517 | memset(&dqp->q_core, 0, sizeof(dqp->q_core)); | 1517 | memset(&dqp->q_core, 0, sizeof(dqp->q_core)); |
1518 | xfs_dqfunlock(dqp); | 1518 | xfs_dqfunlock(dqp); |
1519 | xfs_dqunlock(dqp); | 1519 | xfs_dqunlock(dqp); |
1520 | XFS_DQ_HASH_UNLOCK(thishash); | 1520 | mutex_unlock(&thishash->qh_lock); |
1521 | return (0); | 1521 | return (0); |
1522 | } | 1522 | } |
1523 | 1523 | ||
diff --git a/fs/xfs/quota/xfs_dquot.h b/fs/xfs/quota/xfs_dquot.h index d443e93b4331..d1f726e0e5a4 100644 --- a/fs/xfs/quota/xfs_dquot.h +++ b/fs/xfs/quota/xfs_dquot.h | |||
@@ -109,19 +109,6 @@ enum { | |||
109 | 109 | ||
110 | #define XFS_DQHOLD(dqp) ((dqp)->q_nrefs++) | 110 | #define XFS_DQHOLD(dqp) ((dqp)->q_nrefs++) |
111 | 111 | ||
112 | #ifdef DEBUG | ||
113 | static inline int | ||
114 | XFS_DQ_IS_LOCKED(xfs_dquot_t *dqp) | ||
115 | { | ||
116 | if (mutex_trylock(&dqp->q_qlock)) { | ||
117 | mutex_unlock(&dqp->q_qlock); | ||
118 | return 0; | ||
119 | } | ||
120 | return 1; | ||
121 | } | ||
122 | #endif | ||
123 | |||
124 | |||
125 | /* | 112 | /* |
126 | * Manage the q_flush completion queue embedded in the dquot. This completion | 113 | * Manage the q_flush completion queue embedded in the dquot. This completion |
127 | * queue synchronizes processes attempting to flush the in-core dquot back to | 114 | * queue synchronizes processes attempting to flush the in-core dquot back to |
@@ -142,6 +129,7 @@ static inline void xfs_dqfunlock(xfs_dquot_t *dqp) | |||
142 | complete(&dqp->q_flush); | 129 | complete(&dqp->q_flush); |
143 | } | 130 | } |
144 | 131 | ||
132 | #define XFS_DQ_IS_LOCKED(dqp) (mutex_is_locked(&((dqp)->q_qlock))) | ||
145 | #define XFS_DQ_IS_ON_FREELIST(dqp) ((dqp)->dq_flnext != (dqp)) | 133 | #define XFS_DQ_IS_ON_FREELIST(dqp) ((dqp)->dq_flnext != (dqp)) |
146 | #define XFS_DQ_IS_DIRTY(dqp) ((dqp)->dq_flags & XFS_DQ_DIRTY) | 134 | #define XFS_DQ_IS_DIRTY(dqp) ((dqp)->dq_flags & XFS_DQ_DIRTY) |
147 | #define XFS_QM_ISUDQ(dqp) ((dqp)->dq_flags & XFS_DQ_USER) | 135 | #define XFS_QM_ISUDQ(dqp) ((dqp)->dq_flags & XFS_DQ_USER) |
diff --git a/fs/xfs/quota/xfs_qm.c b/fs/xfs/quota/xfs_qm.c index 7a2beb64314f..11d0a4f89a0e 100644 --- a/fs/xfs/quota/xfs_qm.c +++ b/fs/xfs/quota/xfs_qm.c | |||
@@ -69,8 +69,6 @@ STATIC void xfs_qm_list_destroy(xfs_dqlist_t *); | |||
69 | 69 | ||
70 | STATIC void xfs_qm_freelist_init(xfs_frlist_t *); | 70 | STATIC void xfs_qm_freelist_init(xfs_frlist_t *); |
71 | STATIC void xfs_qm_freelist_destroy(xfs_frlist_t *); | 71 | STATIC void xfs_qm_freelist_destroy(xfs_frlist_t *); |
72 | STATIC int xfs_qm_mplist_nowait(xfs_mount_t *); | ||
73 | STATIC int xfs_qm_dqhashlock_nowait(xfs_dquot_t *); | ||
74 | 72 | ||
75 | STATIC int xfs_qm_init_quotainos(xfs_mount_t *); | 73 | STATIC int xfs_qm_init_quotainos(xfs_mount_t *); |
76 | STATIC int xfs_qm_init_quotainfo(xfs_mount_t *); | 74 | STATIC int xfs_qm_init_quotainfo(xfs_mount_t *); |
@@ -219,7 +217,7 @@ xfs_qm_hold_quotafs_ref( | |||
219 | * the structure could disappear between the entry to this routine and | 217 | * the structure could disappear between the entry to this routine and |
220 | * a HOLD operation if not locked. | 218 | * a HOLD operation if not locked. |
221 | */ | 219 | */ |
222 | XFS_QM_LOCK(xfs_Gqm); | 220 | mutex_lock(&xfs_Gqm_lock); |
223 | 221 | ||
224 | if (xfs_Gqm == NULL) | 222 | if (xfs_Gqm == NULL) |
225 | xfs_Gqm = xfs_Gqm_init(); | 223 | xfs_Gqm = xfs_Gqm_init(); |
@@ -228,8 +226,8 @@ xfs_qm_hold_quotafs_ref( | |||
228 | * debugging and statistical purposes, but ... | 226 | * debugging and statistical purposes, but ... |
229 | * Just take a reference and get out. | 227 | * Just take a reference and get out. |
230 | */ | 228 | */ |
231 | XFS_QM_HOLD(xfs_Gqm); | 229 | xfs_Gqm->qm_nrefs++; |
232 | XFS_QM_UNLOCK(xfs_Gqm); | 230 | mutex_unlock(&xfs_Gqm_lock); |
233 | 231 | ||
234 | return 0; | 232 | return 0; |
235 | } | 233 | } |
@@ -277,13 +275,12 @@ xfs_qm_rele_quotafs_ref( | |||
277 | * Destroy the entire XQM. If somebody mounts with quotaon, this'll | 275 | * Destroy the entire XQM. If somebody mounts with quotaon, this'll |
278 | * be restarted. | 276 | * be restarted. |
279 | */ | 277 | */ |
280 | XFS_QM_LOCK(xfs_Gqm); | 278 | mutex_lock(&xfs_Gqm_lock); |
281 | XFS_QM_RELE(xfs_Gqm); | 279 | if (--xfs_Gqm->qm_nrefs == 0) { |
282 | if (xfs_Gqm->qm_nrefs == 0) { | ||
283 | xfs_qm_destroy(xfs_Gqm); | 280 | xfs_qm_destroy(xfs_Gqm); |
284 | xfs_Gqm = NULL; | 281 | xfs_Gqm = NULL; |
285 | } | 282 | } |
286 | XFS_QM_UNLOCK(xfs_Gqm); | 283 | mutex_unlock(&xfs_Gqm_lock); |
287 | } | 284 | } |
288 | 285 | ||
289 | /* | 286 | /* |
@@ -577,10 +574,10 @@ xfs_qm_dqpurge_int( | |||
577 | continue; | 574 | continue; |
578 | } | 575 | } |
579 | 576 | ||
580 | if (! xfs_qm_dqhashlock_nowait(dqp)) { | 577 | if (!mutex_trylock(&dqp->q_hash->qh_lock)) { |
581 | nrecl = XFS_QI_MPLRECLAIMS(mp); | 578 | nrecl = XFS_QI_MPLRECLAIMS(mp); |
582 | xfs_qm_mplist_unlock(mp); | 579 | xfs_qm_mplist_unlock(mp); |
583 | XFS_DQ_HASH_LOCK(dqp->q_hash); | 580 | mutex_lock(&dqp->q_hash->qh_lock); |
584 | xfs_qm_mplist_lock(mp); | 581 | xfs_qm_mplist_lock(mp); |
585 | 582 | ||
586 | /* | 583 | /* |
@@ -590,7 +587,7 @@ xfs_qm_dqpurge_int( | |||
590 | * this point, but somebody might be taking things off. | 587 | * this point, but somebody might be taking things off. |
591 | */ | 588 | */ |
592 | if (nrecl != XFS_QI_MPLRECLAIMS(mp)) { | 589 | if (nrecl != XFS_QI_MPLRECLAIMS(mp)) { |
593 | XFS_DQ_HASH_UNLOCK(dqp->q_hash); | 590 | mutex_unlock(&dqp->q_hash->qh_lock); |
594 | goto again; | 591 | goto again; |
595 | } | 592 | } |
596 | } | 593 | } |
@@ -632,7 +629,6 @@ xfs_qm_dqattach_one( | |||
632 | xfs_dqid_t id, | 629 | xfs_dqid_t id, |
633 | uint type, | 630 | uint type, |
634 | uint doalloc, | 631 | uint doalloc, |
635 | uint dolock, | ||
636 | xfs_dquot_t *udqhint, /* hint */ | 632 | xfs_dquot_t *udqhint, /* hint */ |
637 | xfs_dquot_t **IO_idqpp) | 633 | xfs_dquot_t **IO_idqpp) |
638 | { | 634 | { |
@@ -641,16 +637,16 @@ xfs_qm_dqattach_one( | |||
641 | 637 | ||
642 | ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL)); | 638 | ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL)); |
643 | error = 0; | 639 | error = 0; |
640 | |||
644 | /* | 641 | /* |
645 | * See if we already have it in the inode itself. IO_idqpp is | 642 | * 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 | 643 | * &i_udquot or &i_gdquot. This made the code look weird, but |
647 | * made the logic a lot simpler. | 644 | * made the logic a lot simpler. |
648 | */ | 645 | */ |
649 | if ((dqp = *IO_idqpp)) { | 646 | dqp = *IO_idqpp; |
650 | if (dolock) | 647 | if (dqp) { |
651 | xfs_dqlock(dqp); | ||
652 | xfs_dqtrace_entry(dqp, "DQATTACH: found in ip"); | 648 | xfs_dqtrace_entry(dqp, "DQATTACH: found in ip"); |
653 | goto done; | 649 | return 0; |
654 | } | 650 | } |
655 | 651 | ||
656 | /* | 652 | /* |
@@ -659,38 +655,38 @@ xfs_qm_dqattach_one( | |||
659 | * lookup by dqid (xfs_qm_dqget) by caching a group dquot inside | 655 | * lookup by dqid (xfs_qm_dqget) by caching a group dquot inside |
660 | * the user dquot. | 656 | * the user dquot. |
661 | */ | 657 | */ |
662 | ASSERT(!udqhint || type == XFS_DQ_GROUP || type == XFS_DQ_PROJ); | 658 | if (udqhint) { |
663 | if (udqhint && !dolock) | 659 | ASSERT(type == XFS_DQ_GROUP || type == XFS_DQ_PROJ); |
664 | xfs_dqlock(udqhint); | 660 | xfs_dqlock(udqhint); |
665 | 661 | ||
666 | /* | 662 | /* |
667 | * No need to take dqlock to look at the id. | 663 | * No need to take dqlock to look at the id. |
668 | * The ID can't change until it gets reclaimed, and it won't | 664 | * |
669 | * be reclaimed as long as we have a ref from inode and we hold | 665 | * The ID can't change until it gets reclaimed, and it won't |
670 | * the ilock. | 666 | * be reclaimed as long as we have a ref from inode and we |
671 | */ | 667 | * hold the ilock. |
672 | if (udqhint && | 668 | */ |
673 | (dqp = udqhint->q_gdquot) && | 669 | dqp = udqhint->q_gdquot; |
674 | (be32_to_cpu(dqp->q_core.d_id) == id)) { | 670 | if (dqp && be32_to_cpu(dqp->q_core.d_id) == id) { |
675 | ASSERT(XFS_DQ_IS_LOCKED(udqhint)); | 671 | xfs_dqlock(dqp); |
676 | xfs_dqlock(dqp); | 672 | XFS_DQHOLD(dqp); |
677 | XFS_DQHOLD(dqp); | 673 | ASSERT(*IO_idqpp == NULL); |
678 | ASSERT(*IO_idqpp == NULL); | 674 | *IO_idqpp = dqp; |
679 | *IO_idqpp = dqp; | 675 | |
680 | if (!dolock) { | ||
681 | xfs_dqunlock(dqp); | 676 | xfs_dqunlock(dqp); |
682 | xfs_dqunlock(udqhint); | 677 | xfs_dqunlock(udqhint); |
678 | return 0; | ||
683 | } | 679 | } |
684 | goto done; | 680 | |
685 | } | 681 | /* |
686 | /* | 682 | * 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. | 683 | * We'll deadlock in no time, because of (not conforming to) |
688 | * We'll deadlock in no time, because of (not conforming to) | 684 | * lock ordering - the inodelock comes before any dquot lock, |
689 | * lock ordering - the inodelock comes before any dquot lock, | 685 | * 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(). | 686 | */ |
691 | */ | ||
692 | if (udqhint) | ||
693 | xfs_dqunlock(udqhint); | 687 | xfs_dqunlock(udqhint); |
688 | } | ||
689 | |||
694 | /* | 690 | /* |
695 | * Find the dquot from somewhere. This bumps the | 691 | * Find the dquot from somewhere. This bumps the |
696 | * reference count of dquot and returns it locked. | 692 | * reference count of dquot and returns it locked. |
@@ -698,48 +694,19 @@ xfs_qm_dqattach_one( | |||
698 | * disk and we didn't ask it to allocate; | 694 | * disk and we didn't ask it to allocate; |
699 | * ESRCH if quotas got turned off suddenly. | 695 | * ESRCH if quotas got turned off suddenly. |
700 | */ | 696 | */ |
701 | if ((error = xfs_qm_dqget(ip->i_mount, ip, id, type, | 697 | error = xfs_qm_dqget(ip->i_mount, ip, id, type, XFS_QMOPT_DOWARN, &dqp); |
702 | doalloc|XFS_QMOPT_DOWARN, &dqp))) { | 698 | if (error) |
703 | if (udqhint && dolock) | 699 | return error; |
704 | xfs_dqlock(udqhint); | ||
705 | goto done; | ||
706 | } | ||
707 | 700 | ||
708 | xfs_dqtrace_entry(dqp, "DQATTACH: found by dqget"); | 701 | xfs_dqtrace_entry(dqp, "DQATTACH: found by dqget"); |
702 | |||
709 | /* | 703 | /* |
710 | * dqget may have dropped and re-acquired the ilock, but it guarantees | 704 | * 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. | 705 | * that the dquot returned is the one that should go in the inode. |
712 | */ | 706 | */ |
713 | *IO_idqpp = dqp; | 707 | *IO_idqpp = dqp; |
714 | ASSERT(dqp); | 708 | xfs_dqunlock(dqp); |
715 | ASSERT(XFS_DQ_IS_LOCKED(dqp)); | 709 | 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 | } | 710 | } |
744 | 711 | ||
745 | 712 | ||
@@ -754,24 +721,15 @@ xfs_qm_dqattach_one( | |||
754 | STATIC void | 721 | STATIC void |
755 | xfs_qm_dqattach_grouphint( | 722 | xfs_qm_dqattach_grouphint( |
756 | xfs_dquot_t *udq, | 723 | xfs_dquot_t *udq, |
757 | xfs_dquot_t *gdq, | 724 | xfs_dquot_t *gdq) |
758 | uint locked) | ||
759 | { | 725 | { |
760 | xfs_dquot_t *tmp; | 726 | xfs_dquot_t *tmp; |
761 | 727 | ||
762 | #ifdef QUOTADEBUG | 728 | 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 | 729 | ||
771 | if ((tmp = udq->q_gdquot)) { | 730 | if ((tmp = udq->q_gdquot)) { |
772 | if (tmp == gdq) { | 731 | if (tmp == gdq) { |
773 | if (! locked) | 732 | xfs_dqunlock(udq); |
774 | xfs_dqunlock(udq); | ||
775 | return; | 733 | return; |
776 | } | 734 | } |
777 | 735 | ||
@@ -781,8 +739,6 @@ xfs_qm_dqattach_grouphint( | |||
781 | * because the freelist lock comes before dqlocks. | 739 | * because the freelist lock comes before dqlocks. |
782 | */ | 740 | */ |
783 | xfs_dqunlock(udq); | 741 | xfs_dqunlock(udq); |
784 | if (locked) | ||
785 | xfs_dqunlock(gdq); | ||
786 | /* | 742 | /* |
787 | * we took a hard reference once upon a time in dqget, | 743 | * we took a hard reference once upon a time in dqget, |
788 | * so give it back when the udquot no longer points at it | 744 | * so give it back when the udquot no longer points at it |
@@ -795,9 +751,7 @@ xfs_qm_dqattach_grouphint( | |||
795 | 751 | ||
796 | } else { | 752 | } else { |
797 | ASSERT(XFS_DQ_IS_LOCKED(udq)); | 753 | ASSERT(XFS_DQ_IS_LOCKED(udq)); |
798 | if (! locked) { | 754 | xfs_dqlock(gdq); |
799 | xfs_dqlock(gdq); | ||
800 | } | ||
801 | } | 755 | } |
802 | 756 | ||
803 | ASSERT(XFS_DQ_IS_LOCKED(udq)); | 757 | ASSERT(XFS_DQ_IS_LOCKED(udq)); |
@@ -810,10 +764,9 @@ xfs_qm_dqattach_grouphint( | |||
810 | XFS_DQHOLD(gdq); | 764 | XFS_DQHOLD(gdq); |
811 | udq->q_gdquot = gdq; | 765 | udq->q_gdquot = gdq; |
812 | } | 766 | } |
813 | if (! locked) { | 767 | |
814 | xfs_dqunlock(gdq); | 768 | xfs_dqunlock(gdq); |
815 | xfs_dqunlock(udq); | 769 | xfs_dqunlock(udq); |
816 | } | ||
817 | } | 770 | } |
818 | 771 | ||
819 | 772 | ||
@@ -821,8 +774,6 @@ xfs_qm_dqattach_grouphint( | |||
821 | * Given a locked inode, attach dquot(s) to it, taking U/G/P-QUOTAON | 774 | * Given a locked inode, attach dquot(s) to it, taking U/G/P-QUOTAON |
822 | * into account. | 775 | * into account. |
823 | * If XFS_QMOPT_DQALLOC, the dquot(s) will be allocated if needed. | 776 | * 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. | 777 | * 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 | 778 | * Inode may get unlocked and relocked in here, and the caller must deal with |
828 | * the consequences. | 779 | * the consequences. |
@@ -851,7 +802,6 @@ xfs_qm_dqattach( | |||
851 | if (XFS_IS_UQUOTA_ON(mp)) { | 802 | if (XFS_IS_UQUOTA_ON(mp)) { |
852 | error = xfs_qm_dqattach_one(ip, ip->i_d.di_uid, XFS_DQ_USER, | 803 | error = xfs_qm_dqattach_one(ip, ip->i_d.di_uid, XFS_DQ_USER, |
853 | flags & XFS_QMOPT_DQALLOC, | 804 | flags & XFS_QMOPT_DQALLOC, |
854 | flags & XFS_QMOPT_DQLOCK, | ||
855 | NULL, &ip->i_udquot); | 805 | NULL, &ip->i_udquot); |
856 | if (error) | 806 | if (error) |
857 | goto done; | 807 | goto done; |
@@ -863,11 +813,9 @@ xfs_qm_dqattach( | |||
863 | error = XFS_IS_GQUOTA_ON(mp) ? | 813 | error = XFS_IS_GQUOTA_ON(mp) ? |
864 | xfs_qm_dqattach_one(ip, ip->i_d.di_gid, XFS_DQ_GROUP, | 814 | xfs_qm_dqattach_one(ip, ip->i_d.di_gid, XFS_DQ_GROUP, |
865 | flags & XFS_QMOPT_DQALLOC, | 815 | flags & XFS_QMOPT_DQALLOC, |
866 | flags & XFS_QMOPT_DQLOCK, | ||
867 | ip->i_udquot, &ip->i_gdquot) : | 816 | ip->i_udquot, &ip->i_gdquot) : |
868 | xfs_qm_dqattach_one(ip, ip->i_d.di_projid, XFS_DQ_PROJ, | 817 | xfs_qm_dqattach_one(ip, ip->i_d.di_projid, XFS_DQ_PROJ, |
869 | flags & XFS_QMOPT_DQALLOC, | 818 | flags & XFS_QMOPT_DQALLOC, |
870 | flags & XFS_QMOPT_DQLOCK, | ||
871 | ip->i_udquot, &ip->i_gdquot); | 819 | ip->i_udquot, &ip->i_gdquot); |
872 | /* | 820 | /* |
873 | * Don't worry about the udquot that we may have | 821 | * Don't worry about the udquot that we may have |
@@ -898,22 +846,13 @@ xfs_qm_dqattach( | |||
898 | /* | 846 | /* |
899 | * Attach i_gdquot to the gdquot hint inside the i_udquot. | 847 | * Attach i_gdquot to the gdquot hint inside the i_udquot. |
900 | */ | 848 | */ |
901 | xfs_qm_dqattach_grouphint(ip->i_udquot, ip->i_gdquot, | 849 | xfs_qm_dqattach_grouphint(ip->i_udquot, ip->i_gdquot); |
902 | flags & XFS_QMOPT_DQLOCK); | ||
903 | } | 850 | } |
904 | 851 | ||
905 | done: | 852 | done: |
906 | 853 | ||
907 | #ifdef QUOTADEBUG | 854 | #ifdef QUOTADEBUG |
908 | if (! error) { | 855 | 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)) | 856 | if (XFS_IS_UQUOTA_ON(mp)) |
918 | ASSERT(ip->i_udquot); | 857 | ASSERT(ip->i_udquot); |
919 | if (XFS_IS_OQUOTA_ON(mp)) | 858 | if (XFS_IS_OQUOTA_ON(mp)) |
@@ -2086,7 +2025,7 @@ xfs_qm_shake_freelist( | |||
2086 | * a dqlookup process that holds the hashlock that is | 2025 | * a dqlookup process that holds the hashlock that is |
2087 | * waiting for the freelist lock. | 2026 | * waiting for the freelist lock. |
2088 | */ | 2027 | */ |
2089 | if (! xfs_qm_dqhashlock_nowait(dqp)) { | 2028 | if (!mutex_trylock(&dqp->q_hash->qh_lock)) { |
2090 | xfs_dqfunlock(dqp); | 2029 | xfs_dqfunlock(dqp); |
2091 | xfs_dqunlock(dqp); | 2030 | xfs_dqunlock(dqp); |
2092 | dqp = dqp->dq_flnext; | 2031 | dqp = dqp->dq_flnext; |
@@ -2103,7 +2042,7 @@ xfs_qm_shake_freelist( | |||
2103 | /* XXX put a sentinel so that we can come back here */ | 2042 | /* XXX put a sentinel so that we can come back here */ |
2104 | xfs_dqfunlock(dqp); | 2043 | xfs_dqfunlock(dqp); |
2105 | xfs_dqunlock(dqp); | 2044 | xfs_dqunlock(dqp); |
2106 | XFS_DQ_HASH_UNLOCK(hash); | 2045 | mutex_unlock(&hash->qh_lock); |
2107 | xfs_qm_freelist_unlock(xfs_Gqm); | 2046 | xfs_qm_freelist_unlock(xfs_Gqm); |
2108 | if (++restarts >= XFS_QM_RECLAIM_MAX_RESTARTS) | 2047 | if (++restarts >= XFS_QM_RECLAIM_MAX_RESTARTS) |
2109 | return nreclaimed; | 2048 | return nreclaimed; |
@@ -2120,7 +2059,7 @@ xfs_qm_shake_freelist( | |||
2120 | XQM_HASHLIST_REMOVE(hash, dqp); | 2059 | XQM_HASHLIST_REMOVE(hash, dqp); |
2121 | xfs_dqfunlock(dqp); | 2060 | xfs_dqfunlock(dqp); |
2122 | xfs_qm_mplist_unlock(dqp->q_mount); | 2061 | xfs_qm_mplist_unlock(dqp->q_mount); |
2123 | XFS_DQ_HASH_UNLOCK(hash); | 2062 | mutex_unlock(&hash->qh_lock); |
2124 | 2063 | ||
2125 | off_freelist: | 2064 | off_freelist: |
2126 | XQM_FREELIST_REMOVE(dqp); | 2065 | XQM_FREELIST_REMOVE(dqp); |
@@ -2262,7 +2201,7 @@ xfs_qm_dqreclaim_one(void) | |||
2262 | continue; | 2201 | continue; |
2263 | } | 2202 | } |
2264 | 2203 | ||
2265 | if (! xfs_qm_dqhashlock_nowait(dqp)) | 2204 | if (!mutex_trylock(&dqp->q_hash->qh_lock)) |
2266 | goto mplistunlock; | 2205 | goto mplistunlock; |
2267 | 2206 | ||
2268 | ASSERT(dqp->q_nrefs == 0); | 2207 | ASSERT(dqp->q_nrefs == 0); |
@@ -2271,7 +2210,7 @@ xfs_qm_dqreclaim_one(void) | |||
2271 | XQM_HASHLIST_REMOVE(dqp->q_hash, dqp); | 2210 | XQM_HASHLIST_REMOVE(dqp->q_hash, dqp); |
2272 | XQM_FREELIST_REMOVE(dqp); | 2211 | XQM_FREELIST_REMOVE(dqp); |
2273 | dqpout = dqp; | 2212 | dqpout = dqp; |
2274 | XFS_DQ_HASH_UNLOCK(dqp->q_hash); | 2213 | mutex_unlock(&dqp->q_hash->qh_lock); |
2275 | mplistunlock: | 2214 | mplistunlock: |
2276 | xfs_qm_mplist_unlock(dqp->q_mount); | 2215 | xfs_qm_mplist_unlock(dqp->q_mount); |
2277 | xfs_dqfunlock(dqp); | 2216 | xfs_dqfunlock(dqp); |
@@ -2774,34 +2713,3 @@ xfs_qm_freelist_append(xfs_frlist_t *ql, xfs_dquot_t *dq) | |||
2774 | { | 2713 | { |
2775 | xfs_qm_freelist_insert((xfs_frlist_t *)ql->qh_prev, dq); | 2714 | xfs_qm_freelist_insert((xfs_frlist_t *)ql->qh_prev, dq); |
2776 | } | 2715 | } |
2777 | |||
2778 | STATIC int | ||
2779 | xfs_qm_dqhashlock_nowait( | ||
2780 | xfs_dquot_t *dqp) | ||
2781 | { | ||
2782 | int locked; | ||
2783 | |||
2784 | locked = mutex_trylock(&((dqp)->q_hash->qh_lock)); | ||
2785 | return locked; | ||
2786 | } | ||
2787 | |||
2788 | int | ||
2789 | xfs_qm_freelist_lock_nowait( | ||
2790 | xfs_qm_t *xqm) | ||
2791 | { | ||
2792 | int locked; | ||
2793 | |||
2794 | locked = mutex_trylock(&(xqm->qm_dqfreelist.qh_lock)); | ||
2795 | return locked; | ||
2796 | } | ||
2797 | |||
2798 | STATIC int | ||
2799 | xfs_qm_mplist_nowait( | ||
2800 | xfs_mount_t *mp) | ||
2801 | { | ||
2802 | int locked; | ||
2803 | |||
2804 | ASSERT(mp->m_quotainfo); | ||
2805 | locked = mutex_trylock(&(XFS_QI_MPLLOCK(mp))); | ||
2806 | return locked; | ||
2807 | } | ||
diff --git a/fs/xfs/quota/xfs_qm.h b/fs/xfs/quota/xfs_qm.h index ddf09166387c..933df4204fc7 100644 --- a/fs/xfs/quota/xfs_qm.h +++ b/fs/xfs/quota/xfs_qm.h | |||
@@ -158,11 +158,6 @@ typedef struct xfs_dquot_acct { | |||
158 | #define XFS_QM_IWARNLIMIT 5 | 158 | #define XFS_QM_IWARNLIMIT 5 |
159 | #define XFS_QM_RTBWARNLIMIT 5 | 159 | #define XFS_QM_RTBWARNLIMIT 5 |
160 | 160 | ||
161 | #define XFS_QM_LOCK(xqm) (mutex_lock(&xqm##_lock)) | ||
162 | #define XFS_QM_UNLOCK(xqm) (mutex_unlock(&xqm##_lock)) | ||
163 | #define XFS_QM_HOLD(xqm) ((xqm)->qm_nrefs++) | ||
164 | #define XFS_QM_RELE(xqm) ((xqm)->qm_nrefs--) | ||
165 | |||
166 | extern void xfs_qm_destroy_quotainfo(xfs_mount_t *); | 161 | extern void xfs_qm_destroy_quotainfo(xfs_mount_t *); |
167 | extern void xfs_qm_mount_quotas(xfs_mount_t *); | 162 | extern void xfs_qm_mount_quotas(xfs_mount_t *); |
168 | extern int xfs_qm_quotacheck(xfs_mount_t *); | 163 | extern int xfs_qm_quotacheck(xfs_mount_t *); |
@@ -178,6 +173,16 @@ extern void xfs_qm_dqdetach(xfs_inode_t *); | |||
178 | extern int xfs_qm_dqpurge_all(xfs_mount_t *, uint); | 173 | extern int xfs_qm_dqpurge_all(xfs_mount_t *, uint); |
179 | extern void xfs_qm_dqrele_all_inodes(xfs_mount_t *, uint); | 174 | extern void xfs_qm_dqrele_all_inodes(xfs_mount_t *, uint); |
180 | 175 | ||
176 | /* quota ops */ | ||
177 | extern int xfs_qm_scall_trunc_qfiles(xfs_mount_t *, uint); | ||
178 | extern int xfs_qm_scall_getquota(xfs_mount_t *, xfs_dqid_t, uint, | ||
179 | fs_disk_quota_t *); | ||
180 | extern int xfs_qm_scall_setqlim(xfs_mount_t *, xfs_dqid_t, uint, | ||
181 | fs_disk_quota_t *); | ||
182 | extern int xfs_qm_scall_getqstat(xfs_mount_t *, fs_quota_stat_t *); | ||
183 | extern int xfs_qm_scall_quotaon(xfs_mount_t *, uint); | ||
184 | extern int xfs_qm_scall_quotaoff(xfs_mount_t *, uint); | ||
185 | |||
181 | /* vop stuff */ | 186 | /* vop stuff */ |
182 | extern int xfs_qm_vop_dqalloc(xfs_mount_t *, xfs_inode_t *, | 187 | extern int xfs_qm_vop_dqalloc(xfs_mount_t *, xfs_inode_t *, |
183 | uid_t, gid_t, prid_t, uint, | 188 | uid_t, gid_t, prid_t, uint, |
@@ -194,11 +199,6 @@ extern int xfs_qm_vop_chown_reserve(xfs_trans_t *, xfs_inode_t *, | |||
194 | /* list stuff */ | 199 | /* list stuff */ |
195 | extern void xfs_qm_freelist_append(xfs_frlist_t *, xfs_dquot_t *); | 200 | extern void xfs_qm_freelist_append(xfs_frlist_t *, xfs_dquot_t *); |
196 | extern void xfs_qm_freelist_unlink(xfs_dquot_t *); | 201 | extern void xfs_qm_freelist_unlink(xfs_dquot_t *); |
197 | extern int xfs_qm_freelist_lock_nowait(xfs_qm_t *); | ||
198 | |||
199 | /* system call interface */ | ||
200 | extern int xfs_qm_quotactl(struct xfs_mount *, int, int, | ||
201 | xfs_caddr_t); | ||
202 | 202 | ||
203 | #ifdef DEBUG | 203 | #ifdef DEBUG |
204 | extern int xfs_qm_internalqcheck(xfs_mount_t *); | 204 | extern int xfs_qm_internalqcheck(xfs_mount_t *); |
diff --git a/fs/xfs/quota/xfs_qm_bhv.c b/fs/xfs/quota/xfs_qm_bhv.c index bc6c5cca3e12..63037c689a4b 100644 --- a/fs/xfs/quota/xfs_qm_bhv.c +++ b/fs/xfs/quota/xfs_qm_bhv.c | |||
@@ -235,7 +235,6 @@ struct xfs_qmops xfs_qmcore_xfs = { | |||
235 | .xfs_dqvopchownresv = xfs_qm_vop_chown_reserve, | 235 | .xfs_dqvopchownresv = xfs_qm_vop_chown_reserve, |
236 | .xfs_dqstatvfs = xfs_qm_statvfs, | 236 | .xfs_dqstatvfs = xfs_qm_statvfs, |
237 | .xfs_dqsync = xfs_qm_sync, | 237 | .xfs_dqsync = xfs_qm_sync, |
238 | .xfs_quotactl = xfs_qm_quotactl, | ||
239 | .xfs_dqtrxops = &xfs_trans_dquot_ops, | 238 | .xfs_dqtrxops = &xfs_trans_dquot_ops, |
240 | }; | 239 | }; |
241 | EXPORT_SYMBOL(xfs_qmcore_xfs); | 240 | EXPORT_SYMBOL(xfs_qmcore_xfs); |
diff --git a/fs/xfs/quota/xfs_qm_syscalls.c b/fs/xfs/quota/xfs_qm_syscalls.c index 68139b38aede..b00c8d484aa9 100644 --- a/fs/xfs/quota/xfs_qm_syscalls.c +++ b/fs/xfs/quota/xfs_qm_syscalls.c | |||
@@ -57,135 +57,16 @@ | |||
57 | # define qdprintk(s, args...) do { } while (0) | 57 | # define qdprintk(s, args...) do { } while (0) |
58 | #endif | 58 | #endif |
59 | 59 | ||
60 | STATIC int xfs_qm_scall_trunc_qfiles(xfs_mount_t *, uint); | ||
61 | STATIC int xfs_qm_scall_getquota(xfs_mount_t *, xfs_dqid_t, uint, | ||
62 | fs_disk_quota_t *); | ||
63 | STATIC int xfs_qm_scall_getqstat(xfs_mount_t *, fs_quota_stat_t *); | ||
64 | STATIC int xfs_qm_scall_setqlim(xfs_mount_t *, xfs_dqid_t, uint, | ||
65 | fs_disk_quota_t *); | ||
66 | STATIC int xfs_qm_scall_quotaon(xfs_mount_t *, uint); | ||
67 | STATIC int xfs_qm_scall_quotaoff(xfs_mount_t *, uint, boolean_t); | ||
68 | STATIC int xfs_qm_log_quotaoff(xfs_mount_t *, xfs_qoff_logitem_t **, uint); | 60 | STATIC int xfs_qm_log_quotaoff(xfs_mount_t *, xfs_qoff_logitem_t **, uint); |
69 | STATIC int xfs_qm_log_quotaoff_end(xfs_mount_t *, xfs_qoff_logitem_t *, | 61 | STATIC int xfs_qm_log_quotaoff_end(xfs_mount_t *, xfs_qoff_logitem_t *, |
70 | uint); | 62 | uint); |
71 | STATIC uint xfs_qm_import_flags(uint); | ||
72 | STATIC uint xfs_qm_export_flags(uint); | 63 | STATIC uint xfs_qm_export_flags(uint); |
73 | STATIC uint xfs_qm_import_qtype_flags(uint); | ||
74 | STATIC uint xfs_qm_export_qtype_flags(uint); | 64 | STATIC uint xfs_qm_export_qtype_flags(uint); |
75 | STATIC void xfs_qm_export_dquot(xfs_mount_t *, xfs_disk_dquot_t *, | 65 | STATIC void xfs_qm_export_dquot(xfs_mount_t *, xfs_disk_dquot_t *, |
76 | fs_disk_quota_t *); | 66 | fs_disk_quota_t *); |
77 | 67 | ||
78 | 68 | ||
79 | /* | 69 | /* |
80 | * The main distribution switch of all XFS quotactl system calls. | ||
81 | */ | ||
82 | int | ||
83 | xfs_qm_quotactl( | ||
84 | xfs_mount_t *mp, | ||
85 | int cmd, | ||
86 | int id, | ||
87 | xfs_caddr_t addr) | ||
88 | { | ||
89 | int error; | ||
90 | |||
91 | ASSERT(addr != NULL || cmd == Q_XQUOTASYNC); | ||
92 | |||
93 | /* | ||
94 | * The following commands are valid even when quotaoff. | ||
95 | */ | ||
96 | switch (cmd) { | ||
97 | case Q_XQUOTARM: | ||
98 | /* | ||
99 | * Truncate quota files. quota must be off. | ||
100 | */ | ||
101 | if (XFS_IS_QUOTA_ON(mp)) | ||
102 | return XFS_ERROR(EINVAL); | ||
103 | if (mp->m_flags & XFS_MOUNT_RDONLY) | ||
104 | return XFS_ERROR(EROFS); | ||
105 | return (xfs_qm_scall_trunc_qfiles(mp, | ||
106 | xfs_qm_import_qtype_flags(*(uint *)addr))); | ||
107 | |||
108 | case Q_XGETQSTAT: | ||
109 | /* | ||
110 | * Get quota status information. | ||
111 | */ | ||
112 | return (xfs_qm_scall_getqstat(mp, (fs_quota_stat_t *)addr)); | ||
113 | |||
114 | case Q_XQUOTAON: | ||
115 | /* | ||
116 | * QUOTAON - enabling quota enforcement. | ||
117 | * Quota accounting must be turned on at mount time. | ||
118 | */ | ||
119 | if (mp->m_flags & XFS_MOUNT_RDONLY) | ||
120 | return XFS_ERROR(EROFS); | ||
121 | return (xfs_qm_scall_quotaon(mp, | ||
122 | xfs_qm_import_flags(*(uint *)addr))); | ||
123 | |||
124 | case Q_XQUOTAOFF: | ||
125 | if (mp->m_flags & XFS_MOUNT_RDONLY) | ||
126 | return XFS_ERROR(EROFS); | ||
127 | break; | ||
128 | |||
129 | case Q_XQUOTASYNC: | ||
130 | return xfs_sync_inodes(mp, SYNC_DELWRI); | ||
131 | |||
132 | default: | ||
133 | break; | ||
134 | } | ||
135 | |||
136 | if (! XFS_IS_QUOTA_ON(mp)) | ||
137 | return XFS_ERROR(ESRCH); | ||
138 | |||
139 | switch (cmd) { | ||
140 | case Q_XQUOTAOFF: | ||
141 | if (mp->m_flags & XFS_MOUNT_RDONLY) | ||
142 | return XFS_ERROR(EROFS); | ||
143 | error = xfs_qm_scall_quotaoff(mp, | ||
144 | xfs_qm_import_flags(*(uint *)addr), | ||
145 | B_FALSE); | ||
146 | break; | ||
147 | |||
148 | case Q_XGETQUOTA: | ||
149 | error = xfs_qm_scall_getquota(mp, (xfs_dqid_t)id, XFS_DQ_USER, | ||
150 | (fs_disk_quota_t *)addr); | ||
151 | break; | ||
152 | case Q_XGETGQUOTA: | ||
153 | error = xfs_qm_scall_getquota(mp, (xfs_dqid_t)id, XFS_DQ_GROUP, | ||
154 | (fs_disk_quota_t *)addr); | ||
155 | break; | ||
156 | case Q_XGETPQUOTA: | ||
157 | error = xfs_qm_scall_getquota(mp, (xfs_dqid_t)id, XFS_DQ_PROJ, | ||
158 | (fs_disk_quota_t *)addr); | ||
159 | break; | ||
160 | |||
161 | case Q_XSETQLIM: | ||
162 | if (mp->m_flags & XFS_MOUNT_RDONLY) | ||
163 | return XFS_ERROR(EROFS); | ||
164 | error = xfs_qm_scall_setqlim(mp, (xfs_dqid_t)id, XFS_DQ_USER, | ||
165 | (fs_disk_quota_t *)addr); | ||
166 | break; | ||
167 | case Q_XSETGQLIM: | ||
168 | if (mp->m_flags & XFS_MOUNT_RDONLY) | ||
169 | return XFS_ERROR(EROFS); | ||
170 | error = xfs_qm_scall_setqlim(mp, (xfs_dqid_t)id, XFS_DQ_GROUP, | ||
171 | (fs_disk_quota_t *)addr); | ||
172 | break; | ||
173 | case Q_XSETPQLIM: | ||
174 | if (mp->m_flags & XFS_MOUNT_RDONLY) | ||
175 | return XFS_ERROR(EROFS); | ||
176 | error = xfs_qm_scall_setqlim(mp, (xfs_dqid_t)id, XFS_DQ_PROJ, | ||
177 | (fs_disk_quota_t *)addr); | ||
178 | break; | ||
179 | |||
180 | default: | ||
181 | error = XFS_ERROR(EINVAL); | ||
182 | break; | ||
183 | } | ||
184 | |||
185 | return (error); | ||
186 | } | ||
187 | |||
188 | /* | ||
189 | * Turn off quota accounting and/or enforcement for all udquots and/or | 70 | * Turn off quota accounting and/or enforcement for all udquots and/or |
190 | * gdquots. Called only at unmount time. | 71 | * gdquots. Called only at unmount time. |
191 | * | 72 | * |
@@ -193,11 +74,10 @@ xfs_qm_quotactl( | |||
193 | * incore, and modifies the ondisk dquot directly. Therefore, for example, | 74 | * incore, and modifies the ondisk dquot directly. Therefore, for example, |
194 | * it is an error to call this twice, without purging the cache. | 75 | * it is an error to call this twice, without purging the cache. |
195 | */ | 76 | */ |
196 | STATIC int | 77 | int |
197 | xfs_qm_scall_quotaoff( | 78 | xfs_qm_scall_quotaoff( |
198 | xfs_mount_t *mp, | 79 | xfs_mount_t *mp, |
199 | uint flags, | 80 | uint flags) |
200 | boolean_t force) | ||
201 | { | 81 | { |
202 | uint dqtype; | 82 | uint dqtype; |
203 | int error; | 83 | int error; |
@@ -205,8 +85,6 @@ xfs_qm_scall_quotaoff( | |||
205 | xfs_qoff_logitem_t *qoffstart; | 85 | xfs_qoff_logitem_t *qoffstart; |
206 | int nculprits; | 86 | int nculprits; |
207 | 87 | ||
208 | if (!force && !capable(CAP_SYS_ADMIN)) | ||
209 | return XFS_ERROR(EPERM); | ||
210 | /* | 88 | /* |
211 | * No file system can have quotas enabled on disk but not in core. | 89 | * No file system can have quotas enabled on disk but not in core. |
212 | * Note that quota utilities (like quotaoff) _expect_ | 90 | * Note that quota utilities (like quotaoff) _expect_ |
@@ -375,7 +253,7 @@ out_error: | |||
375 | return (error); | 253 | return (error); |
376 | } | 254 | } |
377 | 255 | ||
378 | STATIC int | 256 | int |
379 | xfs_qm_scall_trunc_qfiles( | 257 | xfs_qm_scall_trunc_qfiles( |
380 | xfs_mount_t *mp, | 258 | xfs_mount_t *mp, |
381 | uint flags) | 259 | uint flags) |
@@ -383,8 +261,6 @@ xfs_qm_scall_trunc_qfiles( | |||
383 | int error = 0, error2 = 0; | 261 | int error = 0, error2 = 0; |
384 | xfs_inode_t *qip; | 262 | xfs_inode_t *qip; |
385 | 263 | ||
386 | if (!capable(CAP_SYS_ADMIN)) | ||
387 | return XFS_ERROR(EPERM); | ||
388 | if (!xfs_sb_version_hasquota(&mp->m_sb) || flags == 0) { | 264 | if (!xfs_sb_version_hasquota(&mp->m_sb) || flags == 0) { |
389 | qdprintk("qtrunc flags=%x m_qflags=%x\n", flags, mp->m_qflags); | 265 | qdprintk("qtrunc flags=%x m_qflags=%x\n", flags, mp->m_qflags); |
390 | return XFS_ERROR(EINVAL); | 266 | return XFS_ERROR(EINVAL); |
@@ -416,7 +292,7 @@ xfs_qm_scall_trunc_qfiles( | |||
416 | * effect immediately. | 292 | * effect immediately. |
417 | * (Switching on quota accounting must be done at mount time.) | 293 | * (Switching on quota accounting must be done at mount time.) |
418 | */ | 294 | */ |
419 | STATIC int | 295 | int |
420 | xfs_qm_scall_quotaon( | 296 | xfs_qm_scall_quotaon( |
421 | xfs_mount_t *mp, | 297 | xfs_mount_t *mp, |
422 | uint flags) | 298 | uint flags) |
@@ -426,9 +302,6 @@ xfs_qm_scall_quotaon( | |||
426 | uint accflags; | 302 | uint accflags; |
427 | __int64_t sbflags; | 303 | __int64_t sbflags; |
428 | 304 | ||
429 | if (!capable(CAP_SYS_ADMIN)) | ||
430 | return XFS_ERROR(EPERM); | ||
431 | |||
432 | flags &= (XFS_ALL_QUOTA_ACCT | XFS_ALL_QUOTA_ENFD); | 305 | flags &= (XFS_ALL_QUOTA_ACCT | XFS_ALL_QUOTA_ENFD); |
433 | /* | 306 | /* |
434 | * Switching on quota accounting must be done at mount time. | 307 | * Switching on quota accounting must be done at mount time. |
@@ -517,7 +390,7 @@ xfs_qm_scall_quotaon( | |||
517 | /* | 390 | /* |
518 | * Return quota status information, such as uquota-off, enforcements, etc. | 391 | * Return quota status information, such as uquota-off, enforcements, etc. |
519 | */ | 392 | */ |
520 | STATIC int | 393 | int |
521 | xfs_qm_scall_getqstat( | 394 | xfs_qm_scall_getqstat( |
522 | xfs_mount_t *mp, | 395 | xfs_mount_t *mp, |
523 | fs_quota_stat_t *out) | 396 | fs_quota_stat_t *out) |
@@ -582,7 +455,7 @@ xfs_qm_scall_getqstat( | |||
582 | /* | 455 | /* |
583 | * Adjust quota limits, and start/stop timers accordingly. | 456 | * Adjust quota limits, and start/stop timers accordingly. |
584 | */ | 457 | */ |
585 | STATIC int | 458 | int |
586 | xfs_qm_scall_setqlim( | 459 | xfs_qm_scall_setqlim( |
587 | xfs_mount_t *mp, | 460 | xfs_mount_t *mp, |
588 | xfs_dqid_t id, | 461 | xfs_dqid_t id, |
@@ -595,9 +468,6 @@ xfs_qm_scall_setqlim( | |||
595 | int error; | 468 | int error; |
596 | xfs_qcnt_t hard, soft; | 469 | xfs_qcnt_t hard, soft; |
597 | 470 | ||
598 | if (!capable(CAP_SYS_ADMIN)) | ||
599 | return XFS_ERROR(EPERM); | ||
600 | |||
601 | if ((newlim->d_fieldmask & | 471 | if ((newlim->d_fieldmask & |
602 | (FS_DQ_LIMIT_MASK|FS_DQ_TIMER_MASK|FS_DQ_WARNS_MASK)) == 0) | 472 | (FS_DQ_LIMIT_MASK|FS_DQ_TIMER_MASK|FS_DQ_WARNS_MASK)) == 0) |
603 | return (0); | 473 | return (0); |
@@ -742,7 +612,7 @@ xfs_qm_scall_setqlim( | |||
742 | return error; | 612 | return error; |
743 | } | 613 | } |
744 | 614 | ||
745 | STATIC int | 615 | int |
746 | xfs_qm_scall_getquota( | 616 | xfs_qm_scall_getquota( |
747 | xfs_mount_t *mp, | 617 | xfs_mount_t *mp, |
748 | xfs_dqid_t id, | 618 | xfs_dqid_t id, |
@@ -935,30 +805,6 @@ xfs_qm_export_dquot( | |||
935 | } | 805 | } |
936 | 806 | ||
937 | STATIC uint | 807 | STATIC uint |
938 | xfs_qm_import_qtype_flags( | ||
939 | uint uflags) | ||
940 | { | ||
941 | uint oflags = 0; | ||
942 | |||
943 | /* | ||
944 | * Can't be more than one, or none. | ||
945 | */ | ||
946 | if (((uflags & (XFS_GROUP_QUOTA | XFS_USER_QUOTA)) == | ||
947 | (XFS_GROUP_QUOTA | XFS_USER_QUOTA)) || | ||
948 | ((uflags & (XFS_GROUP_QUOTA | XFS_PROJ_QUOTA)) == | ||
949 | (XFS_GROUP_QUOTA | XFS_PROJ_QUOTA)) || | ||
950 | ((uflags & (XFS_USER_QUOTA | XFS_PROJ_QUOTA)) == | ||
951 | (XFS_USER_QUOTA | XFS_PROJ_QUOTA)) || | ||
952 | ((uflags & (XFS_GROUP_QUOTA|XFS_USER_QUOTA|XFS_PROJ_QUOTA)) == 0)) | ||
953 | return (0); | ||
954 | |||
955 | oflags |= (uflags & XFS_USER_QUOTA) ? XFS_DQ_USER : 0; | ||
956 | oflags |= (uflags & XFS_PROJ_QUOTA) ? XFS_DQ_PROJ : 0; | ||
957 | oflags |= (uflags & XFS_GROUP_QUOTA) ? XFS_DQ_GROUP: 0; | ||
958 | return oflags; | ||
959 | } | ||
960 | |||
961 | STATIC uint | ||
962 | xfs_qm_export_qtype_flags( | 808 | xfs_qm_export_qtype_flags( |
963 | uint flags) | 809 | uint flags) |
964 | { | 810 | { |
@@ -979,26 +825,6 @@ xfs_qm_export_qtype_flags( | |||
979 | } | 825 | } |
980 | 826 | ||
981 | STATIC uint | 827 | STATIC uint |
982 | xfs_qm_import_flags( | ||
983 | uint uflags) | ||
984 | { | ||
985 | uint flags = 0; | ||
986 | |||
987 | if (uflags & XFS_QUOTA_UDQ_ACCT) | ||
988 | flags |= XFS_UQUOTA_ACCT; | ||
989 | if (uflags & XFS_QUOTA_PDQ_ACCT) | ||
990 | flags |= XFS_PQUOTA_ACCT; | ||
991 | if (uflags & XFS_QUOTA_GDQ_ACCT) | ||
992 | flags |= XFS_GQUOTA_ACCT; | ||
993 | if (uflags & XFS_QUOTA_UDQ_ENFD) | ||
994 | flags |= XFS_UQUOTA_ENFD; | ||
995 | if (uflags & (XFS_QUOTA_PDQ_ENFD|XFS_QUOTA_GDQ_ENFD)) | ||
996 | flags |= XFS_OQUOTA_ENFD; | ||
997 | return (flags); | ||
998 | } | ||
999 | |||
1000 | |||
1001 | STATIC uint | ||
1002 | xfs_qm_export_flags( | 828 | xfs_qm_export_flags( |
1003 | uint flags) | 829 | uint flags) |
1004 | { | 830 | { |
diff --git a/fs/xfs/quota/xfs_quota_priv.h b/fs/xfs/quota/xfs_quota_priv.h index c4fcea600bc2..8286b2842b6b 100644 --- a/fs/xfs/quota/xfs_quota_priv.h +++ b/fs/xfs/quota/xfs_quota_priv.h | |||
@@ -42,34 +42,24 @@ | |||
42 | #define XFS_QI_QOFFLOCK(mp) ((mp)->m_quotainfo->qi_quotaofflock) | 42 | #define XFS_QI_QOFFLOCK(mp) ((mp)->m_quotainfo->qi_quotaofflock) |
43 | 43 | ||
44 | #define XFS_QI_MPL_LIST(mp) ((mp)->m_quotainfo->qi_dqlist) | 44 | #define XFS_QI_MPL_LIST(mp) ((mp)->m_quotainfo->qi_dqlist) |
45 | #define XFS_QI_MPLLOCK(mp) ((mp)->m_quotainfo->qi_dqlist.qh_lock) | ||
46 | #define XFS_QI_MPLNEXT(mp) ((mp)->m_quotainfo->qi_dqlist.qh_next) | 45 | #define XFS_QI_MPLNEXT(mp) ((mp)->m_quotainfo->qi_dqlist.qh_next) |
47 | #define XFS_QI_MPLNDQUOTS(mp) ((mp)->m_quotainfo->qi_dqlist.qh_nelems) | 46 | #define XFS_QI_MPLNDQUOTS(mp) ((mp)->m_quotainfo->qi_dqlist.qh_nelems) |
48 | 47 | ||
49 | #define XQMLCK(h) (mutex_lock(&((h)->qh_lock))) | 48 | #define xfs_qm_mplist_lock(mp) \ |
50 | #define XQMUNLCK(h) (mutex_unlock(&((h)->qh_lock))) | 49 | mutex_lock(&(XFS_QI_MPL_LIST(mp).qh_lock)) |
51 | #ifdef DEBUG | 50 | #define xfs_qm_mplist_nowait(mp) \ |
52 | struct xfs_dqhash; | 51 | mutex_trylock(&(XFS_QI_MPL_LIST(mp).qh_lock)) |
53 | static inline int XQMISLCKD(struct xfs_dqhash *h) | 52 | #define xfs_qm_mplist_unlock(mp) \ |
54 | { | 53 | mutex_unlock(&(XFS_QI_MPL_LIST(mp).qh_lock)) |
55 | if (mutex_trylock(&h->qh_lock)) { | 54 | #define XFS_QM_IS_MPLIST_LOCKED(mp) \ |
56 | mutex_unlock(&h->qh_lock); | 55 | mutex_is_locked(&(XFS_QI_MPL_LIST(mp).qh_lock)) |
57 | return 0; | 56 | |
58 | } | 57 | #define xfs_qm_freelist_lock(qm) \ |
59 | return 1; | 58 | mutex_lock(&((qm)->qm_dqfreelist.qh_lock)) |
60 | } | 59 | #define xfs_qm_freelist_lock_nowait(qm) \ |
61 | #endif | 60 | mutex_trylock(&((qm)->qm_dqfreelist.qh_lock)) |
62 | 61 | #define xfs_qm_freelist_unlock(qm) \ | |
63 | #define XFS_DQ_HASH_LOCK(h) XQMLCK(h) | 62 | mutex_unlock(&((qm)->qm_dqfreelist.qh_lock)) |
64 | #define XFS_DQ_HASH_UNLOCK(h) XQMUNLCK(h) | ||
65 | #define XFS_DQ_IS_HASH_LOCKED(h) XQMISLCKD(h) | ||
66 | |||
67 | #define xfs_qm_mplist_lock(mp) XQMLCK(&(XFS_QI_MPL_LIST(mp))) | ||
68 | #define xfs_qm_mplist_unlock(mp) XQMUNLCK(&(XFS_QI_MPL_LIST(mp))) | ||
69 | #define XFS_QM_IS_MPLIST_LOCKED(mp) XQMISLCKD(&(XFS_QI_MPL_LIST(mp))) | ||
70 | |||
71 | #define xfs_qm_freelist_lock(qm) XQMLCK(&((qm)->qm_dqfreelist)) | ||
72 | #define xfs_qm_freelist_unlock(qm) XQMUNLCK(&((qm)->qm_dqfreelist)) | ||
73 | 63 | ||
74 | /* | 64 | /* |
75 | * Hash into a bucket in the dquot hash table, based on <mp, id>. | 65 | * Hash into a bucket in the dquot hash table, based on <mp, id>. |
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_ag.h b/fs/xfs/xfs_ag.h index 143d63ecb20a..c8641f713caa 100644 --- a/fs/xfs/xfs_ag.h +++ b/fs/xfs/xfs_ag.h | |||
@@ -223,8 +223,8 @@ typedef struct xfs_perag | |||
223 | be32_to_cpu((a)->agf_levels[XFS_BTNUM_CNTi]), mp)) | 223 | be32_to_cpu((a)->agf_levels[XFS_BTNUM_CNTi]), mp)) |
224 | #define XFS_MIN_FREELIST_PAG(pag,mp) \ | 224 | #define XFS_MIN_FREELIST_PAG(pag,mp) \ |
225 | (XFS_MIN_FREELIST_RAW( \ | 225 | (XFS_MIN_FREELIST_RAW( \ |
226 | (uint_t)(pag)->pagf_levels[XFS_BTNUM_BNOi], \ | 226 | (unsigned int)(pag)->pagf_levels[XFS_BTNUM_BNOi], \ |
227 | (uint_t)(pag)->pagf_levels[XFS_BTNUM_CNTi], mp)) | 227 | (unsigned int)(pag)->pagf_levels[XFS_BTNUM_CNTi], mp)) |
228 | 228 | ||
229 | #define XFS_AGB_TO_FSB(mp,agno,agbno) \ | 229 | #define XFS_AGB_TO_FSB(mp,agno,agbno) \ |
230 | (((xfs_fsblock_t)(agno) << (mp)->m_sb.sb_agblklog) | (agbno)) | 230 | (((xfs_fsblock_t)(agno) << (mp)->m_sb.sb_agblklog) | (agbno)) |
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_da_btree.c b/fs/xfs/xfs_da_btree.c index c45f74ff1a5b..9ff6e57a5075 100644 --- a/fs/xfs/xfs_da_btree.c +++ b/fs/xfs/xfs_da_btree.c | |||
@@ -1503,7 +1503,7 @@ xfs_da_path_shift(xfs_da_state_t *state, xfs_da_state_path_t *path, | |||
1503 | * This is implemented with some source-level loop unrolling. | 1503 | * This is implemented with some source-level loop unrolling. |
1504 | */ | 1504 | */ |
1505 | xfs_dahash_t | 1505 | xfs_dahash_t |
1506 | xfs_da_hashname(const uchar_t *name, int namelen) | 1506 | xfs_da_hashname(const __uint8_t *name, int namelen) |
1507 | { | 1507 | { |
1508 | xfs_dahash_t hash; | 1508 | xfs_dahash_t hash; |
1509 | 1509 | ||
diff --git a/fs/xfs/xfs_da_btree.h b/fs/xfs/xfs_da_btree.h index 70b710c1792d..9d5a7e8c38fe 100644 --- a/fs/xfs/xfs_da_btree.h +++ b/fs/xfs/xfs_da_btree.h | |||
@@ -91,9 +91,9 @@ enum xfs_dacmp { | |||
91 | * Structure to ease passing around component names. | 91 | * Structure to ease passing around component names. |
92 | */ | 92 | */ |
93 | typedef struct xfs_da_args { | 93 | typedef struct xfs_da_args { |
94 | const uchar_t *name; /* string (maybe not NULL terminated) */ | 94 | const __uint8_t *name; /* string (maybe not NULL terminated) */ |
95 | int namelen; /* length of string (maybe no NULL) */ | 95 | int namelen; /* length of string (maybe no NULL) */ |
96 | uchar_t *value; /* set of bytes (maybe contain NULLs) */ | 96 | __uint8_t *value; /* set of bytes (maybe contain NULLs) */ |
97 | int valuelen; /* length of value */ | 97 | int valuelen; /* length of value */ |
98 | int flags; /* argument flags (eg: ATTR_NOCREATE) */ | 98 | int flags; /* argument flags (eg: ATTR_NOCREATE) */ |
99 | xfs_dahash_t hashval; /* hash value of name */ | 99 | xfs_dahash_t hashval; /* hash value of name */ |
@@ -251,7 +251,7 @@ xfs_daddr_t xfs_da_reada_buf(struct xfs_trans *trans, struct xfs_inode *dp, | |||
251 | int xfs_da_shrink_inode(xfs_da_args_t *args, xfs_dablk_t dead_blkno, | 251 | int xfs_da_shrink_inode(xfs_da_args_t *args, xfs_dablk_t dead_blkno, |
252 | xfs_dabuf_t *dead_buf); | 252 | xfs_dabuf_t *dead_buf); |
253 | 253 | ||
254 | uint xfs_da_hashname(const uchar_t *name_string, int name_length); | 254 | uint xfs_da_hashname(const __uint8_t *name_string, int name_length); |
255 | enum xfs_dacmp xfs_da_compname(struct xfs_da_args *args, | 255 | enum xfs_dacmp xfs_da_compname(struct xfs_da_args *args, |
256 | const char *name, int len); | 256 | const char *name, int len); |
257 | 257 | ||
diff --git a/fs/xfs/xfs_dfrag.c b/fs/xfs/xfs_dfrag.c index f8278cfcc1d3..e6d839bddbf0 100644 --- a/fs/xfs/xfs_dfrag.c +++ b/fs/xfs/xfs_dfrag.c | |||
@@ -79,6 +79,12 @@ xfs_swapext( | |||
79 | goto out_put_target_file; | 79 | goto out_put_target_file; |
80 | } | 80 | } |
81 | 81 | ||
82 | if (IS_SWAPFILE(file->f_path.dentry->d_inode) || | ||
83 | IS_SWAPFILE(target_file->f_path.dentry->d_inode)) { | ||
84 | error = XFS_ERROR(EINVAL); | ||
85 | goto out_put_target_file; | ||
86 | } | ||
87 | |||
82 | ip = XFS_I(file->f_path.dentry->d_inode); | 88 | ip = XFS_I(file->f_path.dentry->d_inode); |
83 | tip = XFS_I(target_file->f_path.dentry->d_inode); | 89 | tip = XFS_I(target_file->f_path.dentry->d_inode); |
84 | 90 | ||
@@ -118,19 +124,17 @@ xfs_swap_extents( | |||
118 | xfs_bstat_t *sbp = &sxp->sx_stat; | 124 | xfs_bstat_t *sbp = &sxp->sx_stat; |
119 | xfs_ifork_t *tempifp, *ifp, *tifp; | 125 | xfs_ifork_t *tempifp, *ifp, *tifp; |
120 | int ilf_fields, tilf_fields; | 126 | int ilf_fields, tilf_fields; |
121 | static uint lock_flags = XFS_ILOCK_EXCL | XFS_IOLOCK_EXCL; | ||
122 | int error = 0; | 127 | int error = 0; |
123 | int aforkblks = 0; | 128 | int aforkblks = 0; |
124 | int taforkblks = 0; | 129 | int taforkblks = 0; |
125 | __uint64_t tmp; | 130 | __uint64_t tmp; |
126 | char locked = 0; | ||
127 | 131 | ||
128 | mp = ip->i_mount; | 132 | mp = ip->i_mount; |
129 | 133 | ||
130 | tempifp = kmem_alloc(sizeof(xfs_ifork_t), KM_MAYFAIL); | 134 | tempifp = kmem_alloc(sizeof(xfs_ifork_t), KM_MAYFAIL); |
131 | if (!tempifp) { | 135 | if (!tempifp) { |
132 | error = XFS_ERROR(ENOMEM); | 136 | error = XFS_ERROR(ENOMEM); |
133 | goto error0; | 137 | goto out; |
134 | } | 138 | } |
135 | 139 | ||
136 | sbp = &sxp->sx_stat; | 140 | sbp = &sxp->sx_stat; |
@@ -143,25 +147,24 @@ xfs_swap_extents( | |||
143 | */ | 147 | */ |
144 | xfs_lock_two_inodes(ip, tip, XFS_IOLOCK_EXCL); | 148 | xfs_lock_two_inodes(ip, tip, XFS_IOLOCK_EXCL); |
145 | xfs_lock_two_inodes(ip, tip, XFS_ILOCK_EXCL); | 149 | xfs_lock_two_inodes(ip, tip, XFS_ILOCK_EXCL); |
146 | locked = 1; | ||
147 | 150 | ||
148 | /* Verify that both files have the same format */ | 151 | /* Verify that both files have the same format */ |
149 | if ((ip->i_d.di_mode & S_IFMT) != (tip->i_d.di_mode & S_IFMT)) { | 152 | if ((ip->i_d.di_mode & S_IFMT) != (tip->i_d.di_mode & S_IFMT)) { |
150 | error = XFS_ERROR(EINVAL); | 153 | error = XFS_ERROR(EINVAL); |
151 | goto error0; | 154 | goto out_unlock; |
152 | } | 155 | } |
153 | 156 | ||
154 | /* Verify both files are either real-time or non-realtime */ | 157 | /* Verify both files are either real-time or non-realtime */ |
155 | if (XFS_IS_REALTIME_INODE(ip) != XFS_IS_REALTIME_INODE(tip)) { | 158 | if (XFS_IS_REALTIME_INODE(ip) != XFS_IS_REALTIME_INODE(tip)) { |
156 | error = XFS_ERROR(EINVAL); | 159 | error = XFS_ERROR(EINVAL); |
157 | goto error0; | 160 | goto out_unlock; |
158 | } | 161 | } |
159 | 162 | ||
160 | /* Should never get a local format */ | 163 | /* Should never get a local format */ |
161 | if (ip->i_d.di_format == XFS_DINODE_FMT_LOCAL || | 164 | if (ip->i_d.di_format == XFS_DINODE_FMT_LOCAL || |
162 | tip->i_d.di_format == XFS_DINODE_FMT_LOCAL) { | 165 | tip->i_d.di_format == XFS_DINODE_FMT_LOCAL) { |
163 | error = XFS_ERROR(EINVAL); | 166 | error = XFS_ERROR(EINVAL); |
164 | goto error0; | 167 | goto out_unlock; |
165 | } | 168 | } |
166 | 169 | ||
167 | if (VN_CACHED(VFS_I(tip)) != 0) { | 170 | if (VN_CACHED(VFS_I(tip)) != 0) { |
@@ -169,13 +172,13 @@ xfs_swap_extents( | |||
169 | error = xfs_flushinval_pages(tip, 0, -1, | 172 | error = xfs_flushinval_pages(tip, 0, -1, |
170 | FI_REMAPF_LOCKED); | 173 | FI_REMAPF_LOCKED); |
171 | if (error) | 174 | if (error) |
172 | goto error0; | 175 | goto out_unlock; |
173 | } | 176 | } |
174 | 177 | ||
175 | /* Verify O_DIRECT for ftmp */ | 178 | /* Verify O_DIRECT for ftmp */ |
176 | if (VN_CACHED(VFS_I(tip)) != 0) { | 179 | if (VN_CACHED(VFS_I(tip)) != 0) { |
177 | error = XFS_ERROR(EINVAL); | 180 | error = XFS_ERROR(EINVAL); |
178 | goto error0; | 181 | goto out_unlock; |
179 | } | 182 | } |
180 | 183 | ||
181 | /* Verify all data are being swapped */ | 184 | /* Verify all data are being swapped */ |
@@ -183,7 +186,7 @@ xfs_swap_extents( | |||
183 | sxp->sx_length != ip->i_d.di_size || | 186 | sxp->sx_length != ip->i_d.di_size || |
184 | sxp->sx_length != tip->i_d.di_size) { | 187 | sxp->sx_length != tip->i_d.di_size) { |
185 | error = XFS_ERROR(EFAULT); | 188 | error = XFS_ERROR(EFAULT); |
186 | goto error0; | 189 | goto out_unlock; |
187 | } | 190 | } |
188 | 191 | ||
189 | /* | 192 | /* |
@@ -193,7 +196,7 @@ xfs_swap_extents( | |||
193 | */ | 196 | */ |
194 | if ( XFS_IFORK_Q(ip) != XFS_IFORK_Q(tip) ) { | 197 | if ( XFS_IFORK_Q(ip) != XFS_IFORK_Q(tip) ) { |
195 | error = XFS_ERROR(EINVAL); | 198 | error = XFS_ERROR(EINVAL); |
196 | goto error0; | 199 | goto out_unlock; |
197 | } | 200 | } |
198 | 201 | ||
199 | /* | 202 | /* |
@@ -208,7 +211,7 @@ xfs_swap_extents( | |||
208 | (sbp->bs_mtime.tv_sec != ip->i_d.di_mtime.t_sec) || | 211 | (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)) { | 212 | (sbp->bs_mtime.tv_nsec != ip->i_d.di_mtime.t_nsec)) { |
210 | error = XFS_ERROR(EBUSY); | 213 | error = XFS_ERROR(EBUSY); |
211 | goto error0; | 214 | goto out_unlock; |
212 | } | 215 | } |
213 | 216 | ||
214 | /* We need to fail if the file is memory mapped. Once we have tossed | 217 | /* We need to fail if the file is memory mapped. Once we have tossed |
@@ -219,7 +222,7 @@ xfs_swap_extents( | |||
219 | */ | 222 | */ |
220 | if (VN_MAPPED(VFS_I(ip))) { | 223 | if (VN_MAPPED(VFS_I(ip))) { |
221 | error = XFS_ERROR(EBUSY); | 224 | error = XFS_ERROR(EBUSY); |
222 | goto error0; | 225 | goto out_unlock; |
223 | } | 226 | } |
224 | 227 | ||
225 | xfs_iunlock(ip, XFS_ILOCK_EXCL); | 228 | xfs_iunlock(ip, XFS_ILOCK_EXCL); |
@@ -242,8 +245,7 @@ xfs_swap_extents( | |||
242 | xfs_iunlock(ip, XFS_IOLOCK_EXCL); | 245 | xfs_iunlock(ip, XFS_IOLOCK_EXCL); |
243 | xfs_iunlock(tip, XFS_IOLOCK_EXCL); | 246 | xfs_iunlock(tip, XFS_IOLOCK_EXCL); |
244 | xfs_trans_cancel(tp, 0); | 247 | xfs_trans_cancel(tp, 0); |
245 | locked = 0; | 248 | goto out; |
246 | goto error0; | ||
247 | } | 249 | } |
248 | xfs_lock_two_inodes(ip, tip, XFS_ILOCK_EXCL); | 250 | xfs_lock_two_inodes(ip, tip, XFS_ILOCK_EXCL); |
249 | 251 | ||
@@ -253,19 +255,15 @@ xfs_swap_extents( | |||
253 | if ( ((XFS_IFORK_Q(ip) != 0) && (ip->i_d.di_anextents > 0)) && | 255 | if ( ((XFS_IFORK_Q(ip) != 0) && (ip->i_d.di_anextents > 0)) && |
254 | (ip->i_d.di_aformat != XFS_DINODE_FMT_LOCAL)) { | 256 | (ip->i_d.di_aformat != XFS_DINODE_FMT_LOCAL)) { |
255 | error = xfs_bmap_count_blocks(tp, ip, XFS_ATTR_FORK, &aforkblks); | 257 | error = xfs_bmap_count_blocks(tp, ip, XFS_ATTR_FORK, &aforkblks); |
256 | if (error) { | 258 | if (error) |
257 | xfs_trans_cancel(tp, 0); | 259 | goto out_trans_cancel; |
258 | goto error0; | ||
259 | } | ||
260 | } | 260 | } |
261 | if ( ((XFS_IFORK_Q(tip) != 0) && (tip->i_d.di_anextents > 0)) && | 261 | if ( ((XFS_IFORK_Q(tip) != 0) && (tip->i_d.di_anextents > 0)) && |
262 | (tip->i_d.di_aformat != XFS_DINODE_FMT_LOCAL)) { | 262 | (tip->i_d.di_aformat != XFS_DINODE_FMT_LOCAL)) { |
263 | error = xfs_bmap_count_blocks(tp, tip, XFS_ATTR_FORK, | 263 | error = xfs_bmap_count_blocks(tp, tip, XFS_ATTR_FORK, |
264 | &taforkblks); | 264 | &taforkblks); |
265 | if (error) { | 265 | if (error) |
266 | xfs_trans_cancel(tp, 0); | 266 | goto out_trans_cancel; |
267 | goto error0; | ||
268 | } | ||
269 | } | 267 | } |
270 | 268 | ||
271 | /* | 269 | /* |
@@ -332,10 +330,10 @@ xfs_swap_extents( | |||
332 | 330 | ||
333 | 331 | ||
334 | IHOLD(ip); | 332 | IHOLD(ip); |
335 | xfs_trans_ijoin(tp, ip, lock_flags); | 333 | xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL | XFS_IOLOCK_EXCL); |
336 | 334 | ||
337 | IHOLD(tip); | 335 | IHOLD(tip); |
338 | xfs_trans_ijoin(tp, tip, lock_flags); | 336 | xfs_trans_ijoin(tp, tip, XFS_ILOCK_EXCL | XFS_IOLOCK_EXCL); |
339 | 337 | ||
340 | xfs_trans_log_inode(tp, ip, ilf_fields); | 338 | xfs_trans_log_inode(tp, ip, ilf_fields); |
341 | xfs_trans_log_inode(tp, tip, tilf_fields); | 339 | xfs_trans_log_inode(tp, tip, tilf_fields); |
@@ -344,19 +342,19 @@ xfs_swap_extents( | |||
344 | * If this is a synchronous mount, make sure that the | 342 | * If this is a synchronous mount, make sure that the |
345 | * transaction goes to disk before returning to the user. | 343 | * transaction goes to disk before returning to the user. |
346 | */ | 344 | */ |
347 | if (mp->m_flags & XFS_MOUNT_WSYNC) { | 345 | if (mp->m_flags & XFS_MOUNT_WSYNC) |
348 | xfs_trans_set_sync(tp); | 346 | xfs_trans_set_sync(tp); |
349 | } | ||
350 | 347 | ||
351 | error = xfs_trans_commit(tp, XFS_TRANS_SWAPEXT); | 348 | error = xfs_trans_commit(tp, XFS_TRANS_SWAPEXT); |
352 | locked = 0; | ||
353 | 349 | ||
354 | error0: | 350 | out_unlock: |
355 | if (locked) { | 351 | xfs_iunlock(ip, XFS_ILOCK_EXCL | XFS_IOLOCK_EXCL); |
356 | xfs_iunlock(ip, lock_flags); | 352 | xfs_iunlock(tip, XFS_ILOCK_EXCL | XFS_IOLOCK_EXCL); |
357 | xfs_iunlock(tip, lock_flags); | 353 | out: |
358 | } | 354 | kmem_free(tempifp); |
359 | if (tempifp != NULL) | ||
360 | kmem_free(tempifp); | ||
361 | return error; | 355 | return error; |
356 | |||
357 | out_trans_cancel: | ||
358 | xfs_trans_cancel(tp, 0); | ||
359 | goto out_unlock; | ||
362 | } | 360 | } |
diff --git a/fs/xfs/xfs_extfree_item.h b/fs/xfs/xfs_extfree_item.h index 2f049f63e85f..0d22c56fdf64 100644 --- a/fs/xfs/xfs_extfree_item.h +++ b/fs/xfs/xfs_extfree_item.h | |||
@@ -33,12 +33,10 @@ typedef struct xfs_extent { | |||
33 | * conversion routine. | 33 | * conversion routine. |
34 | */ | 34 | */ |
35 | 35 | ||
36 | #ifndef HAVE_FORMAT32 | ||
37 | typedef struct xfs_extent_32 { | 36 | typedef struct xfs_extent_32 { |
38 | __uint64_t ext_start; | 37 | __uint64_t ext_start; |
39 | __uint32_t ext_len; | 38 | __uint32_t ext_len; |
40 | } __attribute__((packed)) xfs_extent_32_t; | 39 | } __attribute__((packed)) xfs_extent_32_t; |
41 | #endif | ||
42 | 40 | ||
43 | typedef struct xfs_extent_64 { | 41 | typedef struct xfs_extent_64 { |
44 | __uint64_t ext_start; | 42 | __uint64_t ext_start; |
@@ -59,7 +57,6 @@ typedef struct xfs_efi_log_format { | |||
59 | xfs_extent_t efi_extents[1]; /* array of extents to free */ | 57 | xfs_extent_t efi_extents[1]; /* array of extents to free */ |
60 | } xfs_efi_log_format_t; | 58 | } xfs_efi_log_format_t; |
61 | 59 | ||
62 | #ifndef HAVE_FORMAT32 | ||
63 | typedef struct xfs_efi_log_format_32 { | 60 | typedef struct xfs_efi_log_format_32 { |
64 | __uint16_t efi_type; /* efi log item type */ | 61 | __uint16_t efi_type; /* efi log item type */ |
65 | __uint16_t efi_size; /* size of this item */ | 62 | __uint16_t efi_size; /* size of this item */ |
@@ -67,7 +64,6 @@ typedef struct xfs_efi_log_format_32 { | |||
67 | __uint64_t efi_id; /* efi identifier */ | 64 | __uint64_t efi_id; /* efi identifier */ |
68 | xfs_extent_32_t efi_extents[1]; /* array of extents to free */ | 65 | xfs_extent_32_t efi_extents[1]; /* array of extents to free */ |
69 | } __attribute__((packed)) xfs_efi_log_format_32_t; | 66 | } __attribute__((packed)) xfs_efi_log_format_32_t; |
70 | #endif | ||
71 | 67 | ||
72 | typedef struct xfs_efi_log_format_64 { | 68 | typedef struct xfs_efi_log_format_64 { |
73 | __uint16_t efi_type; /* efi log item type */ | 69 | __uint16_t efi_type; /* efi log item type */ |
@@ -90,7 +86,6 @@ typedef struct xfs_efd_log_format { | |||
90 | xfs_extent_t efd_extents[1]; /* array of extents freed */ | 86 | xfs_extent_t efd_extents[1]; /* array of extents freed */ |
91 | } xfs_efd_log_format_t; | 87 | } xfs_efd_log_format_t; |
92 | 88 | ||
93 | #ifndef HAVE_FORMAT32 | ||
94 | typedef struct xfs_efd_log_format_32 { | 89 | typedef struct xfs_efd_log_format_32 { |
95 | __uint16_t efd_type; /* efd log item type */ | 90 | __uint16_t efd_type; /* efd log item type */ |
96 | __uint16_t efd_size; /* size of this item */ | 91 | __uint16_t efd_size; /* size of this item */ |
@@ -98,7 +93,6 @@ typedef struct xfs_efd_log_format_32 { | |||
98 | __uint64_t efd_efi_id; /* id of corresponding efi */ | 93 | __uint64_t efd_efi_id; /* id of corresponding efi */ |
99 | xfs_extent_32_t efd_extents[1]; /* array of extents freed */ | 94 | xfs_extent_32_t efd_extents[1]; /* array of extents freed */ |
100 | } __attribute__((packed)) xfs_efd_log_format_32_t; | 95 | } __attribute__((packed)) xfs_efd_log_format_32_t; |
101 | #endif | ||
102 | 96 | ||
103 | typedef struct xfs_efd_log_format_64 { | 97 | typedef struct xfs_efd_log_format_64 { |
104 | __uint16_t efd_type; /* efd log item type */ | 98 | __uint16_t efd_type; /* efd log item type */ |
diff --git a/fs/xfs/xfs_ialloc.c b/fs/xfs/xfs_ialloc.c index ab016e5ae7be..62d1ceae0943 100644 --- a/fs/xfs/xfs_ialloc.c +++ b/fs/xfs/xfs_ialloc.c | |||
@@ -230,7 +230,7 @@ xfs_ialloc_ag_alloc( | |||
230 | args.minalignslop = xfs_ialloc_cluster_alignment(&args) - 1; | 230 | args.minalignslop = xfs_ialloc_cluster_alignment(&args) - 1; |
231 | 231 | ||
232 | /* Allow space for the inode btree to split. */ | 232 | /* Allow space for the inode btree to split. */ |
233 | args.minleft = XFS_IN_MAXLEVELS(args.mp) - 1; | 233 | args.minleft = args.mp->m_in_maxlevels - 1; |
234 | if ((error = xfs_alloc_vextent(&args))) | 234 | if ((error = xfs_alloc_vextent(&args))) |
235 | return error; | 235 | return error; |
236 | } else | 236 | } else |
@@ -270,7 +270,7 @@ xfs_ialloc_ag_alloc( | |||
270 | /* | 270 | /* |
271 | * Allow space for the inode btree to split. | 271 | * Allow space for the inode btree to split. |
272 | */ | 272 | */ |
273 | args.minleft = XFS_IN_MAXLEVELS(args.mp) - 1; | 273 | args.minleft = args.mp->m_in_maxlevels - 1; |
274 | if ((error = xfs_alloc_vextent(&args))) | 274 | if ((error = xfs_alloc_vextent(&args))) |
275 | return error; | 275 | return error; |
276 | } | 276 | } |
@@ -943,7 +943,7 @@ nextag: | |||
943 | ASSERT((XFS_AGINO_TO_OFFSET(mp, rec.ir_startino) % | 943 | ASSERT((XFS_AGINO_TO_OFFSET(mp, rec.ir_startino) % |
944 | XFS_INODES_PER_CHUNK) == 0); | 944 | XFS_INODES_PER_CHUNK) == 0); |
945 | ino = XFS_AGINO_TO_INO(mp, agno, rec.ir_startino + offset); | 945 | ino = XFS_AGINO_TO_INO(mp, agno, rec.ir_startino + offset); |
946 | XFS_INOBT_CLR_FREE(&rec, offset); | 946 | rec.ir_free &= ~XFS_INOBT_MASK(offset); |
947 | rec.ir_freecount--; | 947 | rec.ir_freecount--; |
948 | if ((error = xfs_inobt_update(cur, rec.ir_startino, rec.ir_freecount, | 948 | if ((error = xfs_inobt_update(cur, rec.ir_startino, rec.ir_freecount, |
949 | rec.ir_free))) | 949 | rec.ir_free))) |
@@ -1105,11 +1105,11 @@ xfs_difree( | |||
1105 | */ | 1105 | */ |
1106 | off = agino - rec.ir_startino; | 1106 | off = agino - rec.ir_startino; |
1107 | ASSERT(off >= 0 && off < XFS_INODES_PER_CHUNK); | 1107 | ASSERT(off >= 0 && off < XFS_INODES_PER_CHUNK); |
1108 | ASSERT(!XFS_INOBT_IS_FREE(&rec, off)); | 1108 | ASSERT(!(rec.ir_free & XFS_INOBT_MASK(off))); |
1109 | /* | 1109 | /* |
1110 | * Mark the inode free & increment the count. | 1110 | * Mark the inode free & increment the count. |
1111 | */ | 1111 | */ |
1112 | XFS_INOBT_SET_FREE(&rec, off); | 1112 | rec.ir_free |= XFS_INOBT_MASK(off); |
1113 | rec.ir_freecount++; | 1113 | rec.ir_freecount++; |
1114 | 1114 | ||
1115 | /* | 1115 | /* |
diff --git a/fs/xfs/xfs_ialloc_btree.h b/fs/xfs/xfs_ialloc_btree.h index 5580e255ff06..f782ad0c4769 100644 --- a/fs/xfs/xfs_ialloc_btree.h +++ b/fs/xfs/xfs_ialloc_btree.h | |||
@@ -32,14 +32,14 @@ struct xfs_mount; | |||
32 | #define XFS_IBT_MAGIC 0x49414254 /* 'IABT' */ | 32 | #define XFS_IBT_MAGIC 0x49414254 /* 'IABT' */ |
33 | 33 | ||
34 | typedef __uint64_t xfs_inofree_t; | 34 | typedef __uint64_t xfs_inofree_t; |
35 | #define XFS_INODES_PER_CHUNK (NBBY * sizeof(xfs_inofree_t)) | 35 | #define XFS_INODES_PER_CHUNK (NBBY * sizeof(xfs_inofree_t)) |
36 | #define XFS_INODES_PER_CHUNK_LOG (XFS_NBBYLOG + 3) | 36 | #define XFS_INODES_PER_CHUNK_LOG (XFS_NBBYLOG + 3) |
37 | #define XFS_INOBT_ALL_FREE ((xfs_inofree_t)-1) | 37 | #define XFS_INOBT_ALL_FREE ((xfs_inofree_t)-1) |
38 | #define XFS_INOBT_MASK(i) ((xfs_inofree_t)1 << (i)) | ||
38 | 39 | ||
39 | static inline xfs_inofree_t xfs_inobt_maskn(int i, int n) | 40 | static inline xfs_inofree_t xfs_inobt_maskn(int i, int n) |
40 | { | 41 | { |
41 | return (((n) >= XFS_INODES_PER_CHUNK ? \ | 42 | return ((n >= XFS_INODES_PER_CHUNK ? 0 : XFS_INOBT_MASK(n)) - 1) << i; |
42 | (xfs_inofree_t)0 : ((xfs_inofree_t)1 << (n))) - 1) << (i); | ||
43 | } | 43 | } |
44 | 44 | ||
45 | /* | 45 | /* |
@@ -69,20 +69,6 @@ typedef struct xfs_inobt_key { | |||
69 | typedef __be32 xfs_inobt_ptr_t; | 69 | typedef __be32 xfs_inobt_ptr_t; |
70 | 70 | ||
71 | /* | 71 | /* |
72 | * Bit manipulations for ir_free. | ||
73 | */ | ||
74 | #define XFS_INOBT_MASK(i) ((xfs_inofree_t)1 << (i)) | ||
75 | #define XFS_INOBT_IS_FREE(rp,i) \ | ||
76 | (((rp)->ir_free & XFS_INOBT_MASK(i)) != 0) | ||
77 | #define XFS_INOBT_SET_FREE(rp,i) ((rp)->ir_free |= XFS_INOBT_MASK(i)) | ||
78 | #define XFS_INOBT_CLR_FREE(rp,i) ((rp)->ir_free &= ~XFS_INOBT_MASK(i)) | ||
79 | |||
80 | /* | ||
81 | * Maximum number of inode btree levels. | ||
82 | */ | ||
83 | #define XFS_IN_MAXLEVELS(mp) ((mp)->m_in_maxlevels) | ||
84 | |||
85 | /* | ||
86 | * block numbers in the AG. | 72 | * block numbers in the AG. |
87 | */ | 73 | */ |
88 | #define XFS_IBT_BLOCK(mp) ((xfs_agblock_t)(XFS_CNT_BLOCK(mp) + 1)) | 74 | #define XFS_IBT_BLOCK(mp) ((xfs_agblock_t)(XFS_CNT_BLOCK(mp) + 1)) |
diff --git a/fs/xfs/xfs_inode_item.h b/fs/xfs/xfs_inode_item.h index 9957d0602d54..a52ac125f055 100644 --- a/fs/xfs/xfs_inode_item.h +++ b/fs/xfs/xfs_inode_item.h | |||
@@ -40,7 +40,6 @@ typedef struct xfs_inode_log_format { | |||
40 | __int32_t ilf_boffset; /* off of inode in buffer */ | 40 | __int32_t ilf_boffset; /* off of inode in buffer */ |
41 | } xfs_inode_log_format_t; | 41 | } xfs_inode_log_format_t; |
42 | 42 | ||
43 | #ifndef HAVE_FORMAT32 | ||
44 | typedef struct xfs_inode_log_format_32 { | 43 | typedef struct xfs_inode_log_format_32 { |
45 | __uint16_t ilf_type; /* inode log item type */ | 44 | __uint16_t ilf_type; /* inode log item type */ |
46 | __uint16_t ilf_size; /* size of this item */ | 45 | __uint16_t ilf_size; /* size of this item */ |
@@ -56,7 +55,6 @@ typedef struct xfs_inode_log_format_32 { | |||
56 | __int32_t ilf_len; /* len of inode buffer */ | 55 | __int32_t ilf_len; /* len of inode buffer */ |
57 | __int32_t ilf_boffset; /* off of inode in buffer */ | 56 | __int32_t ilf_boffset; /* off of inode in buffer */ |
58 | } __attribute__((packed)) xfs_inode_log_format_32_t; | 57 | } __attribute__((packed)) xfs_inode_log_format_32_t; |
59 | #endif | ||
60 | 58 | ||
61 | typedef struct xfs_inode_log_format_64 { | 59 | typedef struct xfs_inode_log_format_64 { |
62 | __uint16_t ilf_type; /* inode log item type */ | 60 | __uint16_t ilf_type; /* inode log item type */ |
diff --git a/fs/xfs/xfs_log.c b/fs/xfs/xfs_log.c index f4726f702a9e..c8f300897728 100644 --- a/fs/xfs/xfs_log.c +++ b/fs/xfs/xfs_log.c | |||
@@ -574,7 +574,7 @@ xfs_log_mount( | |||
574 | error = xfs_trans_ail_init(mp); | 574 | error = xfs_trans_ail_init(mp); |
575 | if (error) { | 575 | if (error) { |
576 | cmn_err(CE_WARN, "XFS: AIL initialisation failed: error %d", error); | 576 | cmn_err(CE_WARN, "XFS: AIL initialisation failed: error %d", error); |
577 | goto error; | 577 | goto out_free_log; |
578 | } | 578 | } |
579 | mp->m_log->l_ailp = mp->m_ail; | 579 | mp->m_log->l_ailp = mp->m_ail; |
580 | 580 | ||
@@ -594,20 +594,22 @@ xfs_log_mount( | |||
594 | mp->m_flags |= XFS_MOUNT_RDONLY; | 594 | mp->m_flags |= XFS_MOUNT_RDONLY; |
595 | if (error) { | 595 | if (error) { |
596 | cmn_err(CE_WARN, "XFS: log mount/recovery failed: error %d", error); | 596 | cmn_err(CE_WARN, "XFS: log mount/recovery failed: error %d", error); |
597 | goto error; | 597 | goto out_destroy_ail; |
598 | } | 598 | } |
599 | } | 599 | } |
600 | 600 | ||
601 | /* Normal transactions can now occur */ | 601 | /* Normal transactions can now occur */ |
602 | mp->m_log->l_flags &= ~XLOG_ACTIVE_RECOVERY; | 602 | mp->m_log->l_flags &= ~XLOG_ACTIVE_RECOVERY; |
603 | 603 | ||
604 | /* End mounting message in xfs_log_mount_finish */ | ||
605 | return 0; | 604 | return 0; |
606 | error: | 605 | |
607 | xfs_log_unmount_dealloc(mp); | 606 | out_destroy_ail: |
607 | xfs_trans_ail_destroy(mp); | ||
608 | out_free_log: | ||
609 | xlog_dealloc_log(mp->m_log); | ||
608 | out: | 610 | out: |
609 | return error; | 611 | return error; |
610 | } /* xfs_log_mount */ | 612 | } |
611 | 613 | ||
612 | /* | 614 | /* |
613 | * Finish the recovery of the file system. This is separate from | 615 | * Finish the recovery of the file system. This is separate from |
@@ -1164,32 +1166,8 @@ xlog_get_iclog_buffer_size(xfs_mount_t *mp, | |||
1164 | log->l_iclog_hsize = BBSIZE; | 1166 | log->l_iclog_hsize = BBSIZE; |
1165 | log->l_iclog_heads = 1; | 1167 | log->l_iclog_heads = 1; |
1166 | 1168 | ||
1167 | /* | 1169 | done: |
1168 | * For 16KB, we use 3 32KB buffers. For 32KB block sizes, we use | 1170 | /* are we being asked to make the sizes selected above visible? */ |
1169 | * 4 32KB buffers. For 64KB block sizes, we use 8 32KB buffers. | ||
1170 | */ | ||
1171 | if (mp->m_sb.sb_blocksize >= 16*1024) { | ||
1172 | log->l_iclog_size = XLOG_BIG_RECORD_BSIZE; | ||
1173 | log->l_iclog_size_log = XLOG_BIG_RECORD_BSHIFT; | ||
1174 | if (mp->m_logbufs <= 0) { | ||
1175 | switch (mp->m_sb.sb_blocksize) { | ||
1176 | case 16*1024: /* 16 KB */ | ||
1177 | log->l_iclog_bufs = 3; | ||
1178 | break; | ||
1179 | case 32*1024: /* 32 KB */ | ||
1180 | log->l_iclog_bufs = 4; | ||
1181 | break; | ||
1182 | case 64*1024: /* 64 KB */ | ||
1183 | log->l_iclog_bufs = 8; | ||
1184 | break; | ||
1185 | default: | ||
1186 | xlog_panic("XFS: Invalid blocksize"); | ||
1187 | break; | ||
1188 | } | ||
1189 | } | ||
1190 | } | ||
1191 | |||
1192 | done: /* are we being asked to make the sizes selected above visible? */ | ||
1193 | if (mp->m_logbufs == 0) | 1171 | if (mp->m_logbufs == 0) |
1194 | mp->m_logbufs = log->l_iclog_bufs; | 1172 | mp->m_logbufs = log->l_iclog_bufs; |
1195 | if (mp->m_logbsize == 0) | 1173 | if (mp->m_logbsize == 0) |
diff --git a/fs/xfs/xfs_log_priv.h b/fs/xfs/xfs_log_priv.h index 654167be0efb..3670d48fd774 100644 --- a/fs/xfs/xfs_log_priv.h +++ b/fs/xfs/xfs_log_priv.h | |||
@@ -359,7 +359,7 @@ typedef struct xlog_in_core { | |||
359 | int ic_size; | 359 | int ic_size; |
360 | int ic_offset; | 360 | int ic_offset; |
361 | int ic_bwritecnt; | 361 | int ic_bwritecnt; |
362 | ushort_t ic_state; | 362 | unsigned short ic_state; |
363 | char *ic_datap; /* pointer to iclog data */ | 363 | char *ic_datap; /* pointer to iclog data */ |
364 | #ifdef XFS_LOG_TRACE | 364 | #ifdef XFS_LOG_TRACE |
365 | struct ktrace *ic_trace; | 365 | struct ktrace *ic_trace; |
diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c index b1047de2fffd..504d540e0e2c 100644 --- a/fs/xfs/xfs_log_recover.c +++ b/fs/xfs/xfs_log_recover.c | |||
@@ -211,11 +211,11 @@ xlog_header_check_dump( | |||
211 | 211 | ||
212 | cmn_err(CE_DEBUG, "%s: SB : uuid = ", __func__); | 212 | cmn_err(CE_DEBUG, "%s: SB : uuid = ", __func__); |
213 | for (b = 0; b < 16; b++) | 213 | for (b = 0; b < 16; b++) |
214 | cmn_err(CE_DEBUG, "%02x", ((uchar_t *)&mp->m_sb.sb_uuid)[b]); | 214 | cmn_err(CE_DEBUG, "%02x", ((__uint8_t *)&mp->m_sb.sb_uuid)[b]); |
215 | cmn_err(CE_DEBUG, ", fmt = %d\n", XLOG_FMT); | 215 | cmn_err(CE_DEBUG, ", fmt = %d\n", XLOG_FMT); |
216 | cmn_err(CE_DEBUG, " log : uuid = "); | 216 | cmn_err(CE_DEBUG, " log : uuid = "); |
217 | for (b = 0; b < 16; b++) | 217 | for (b = 0; b < 16; b++) |
218 | cmn_err(CE_DEBUG, "%02x",((uchar_t *)&head->h_fs_uuid)[b]); | 218 | cmn_err(CE_DEBUG, "%02x", ((__uint8_t *)&head->h_fs_uuid)[b]); |
219 | cmn_err(CE_DEBUG, ", fmt = %d\n", be32_to_cpu(head->h_fmt)); | 219 | cmn_err(CE_DEBUG, ", fmt = %d\n", be32_to_cpu(head->h_fmt)); |
220 | } | 220 | } |
221 | #else | 221 | #else |
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..1438dd4dc909 100644 --- a/fs/xfs/xfs_mount.h +++ b/fs/xfs/xfs_mount.h | |||
@@ -136,7 +136,6 @@ typedef int (*xfs_dqvopchownresv_t)(struct xfs_trans *, struct xfs_inode *, | |||
136 | struct xfs_dquot *, struct xfs_dquot *, uint); | 136 | struct xfs_dquot *, struct xfs_dquot *, uint); |
137 | typedef void (*xfs_dqstatvfs_t)(struct xfs_inode *, struct kstatfs *); | 137 | typedef void (*xfs_dqstatvfs_t)(struct xfs_inode *, struct kstatfs *); |
138 | typedef int (*xfs_dqsync_t)(struct xfs_mount *, int flags); | 138 | typedef int (*xfs_dqsync_t)(struct xfs_mount *, int flags); |
139 | typedef int (*xfs_quotactl_t)(struct xfs_mount *, int, int, xfs_caddr_t); | ||
140 | 139 | ||
141 | typedef struct xfs_qmops { | 140 | typedef struct xfs_qmops { |
142 | xfs_qminit_t xfs_qminit; | 141 | xfs_qminit_t xfs_qminit; |
@@ -154,7 +153,6 @@ typedef struct xfs_qmops { | |||
154 | xfs_dqvopchownresv_t xfs_dqvopchownresv; | 153 | xfs_dqvopchownresv_t xfs_dqvopchownresv; |
155 | xfs_dqstatvfs_t xfs_dqstatvfs; | 154 | xfs_dqstatvfs_t xfs_dqstatvfs; |
156 | xfs_dqsync_t xfs_dqsync; | 155 | xfs_dqsync_t xfs_dqsync; |
157 | xfs_quotactl_t xfs_quotactl; | ||
158 | struct xfs_dqtrxops *xfs_dqtrxops; | 156 | struct xfs_dqtrxops *xfs_dqtrxops; |
159 | } xfs_qmops_t; | 157 | } xfs_qmops_t; |
160 | 158 | ||
@@ -188,8 +186,6 @@ typedef struct xfs_qmops { | |||
188 | (*(ip)->i_mount->m_qm_ops->xfs_dqstatvfs)(ip, statp) | 186 | (*(ip)->i_mount->m_qm_ops->xfs_dqstatvfs)(ip, statp) |
189 | #define XFS_QM_DQSYNC(mp, flags) \ | 187 | #define XFS_QM_DQSYNC(mp, flags) \ |
190 | (*(mp)->m_qm_ops->xfs_dqsync)(mp, flags) | 188 | (*(mp)->m_qm_ops->xfs_dqsync)(mp, flags) |
191 | #define XFS_QM_QUOTACTL(mp, cmd, id, addr) \ | ||
192 | (*(mp)->m_qm_ops->xfs_quotactl)(mp, cmd, id, addr) | ||
193 | 189 | ||
194 | #ifdef HAVE_PERCPU_SB | 190 | #ifdef HAVE_PERCPU_SB |
195 | 191 | ||
@@ -273,7 +269,7 @@ typedef struct xfs_mount { | |||
273 | uint m_inobt_mnr[2]; /* min inobt btree records */ | 269 | uint m_inobt_mnr[2]; /* min inobt btree records */ |
274 | uint m_ag_maxlevels; /* XFS_AG_MAXLEVELS */ | 270 | uint m_ag_maxlevels; /* XFS_AG_MAXLEVELS */ |
275 | uint m_bm_maxlevels[2]; /* XFS_BM_MAXLEVELS */ | 271 | uint m_bm_maxlevels[2]; /* XFS_BM_MAXLEVELS */ |
276 | uint m_in_maxlevels; /* XFS_IN_MAXLEVELS */ | 272 | uint m_in_maxlevels; /* max inobt btree levels. */ |
277 | struct xfs_perag *m_perag; /* per-ag accounting info */ | 273 | struct xfs_perag *m_perag; /* per-ag accounting info */ |
278 | struct rw_semaphore m_peraglock; /* lock for m_perag (pointer) */ | 274 | struct rw_semaphore m_peraglock; /* lock for m_perag (pointer) */ |
279 | struct mutex m_growlock; /* growfs mutex */ | 275 | struct mutex m_growlock; /* growfs mutex */ |
@@ -500,9 +496,6 @@ typedef struct xfs_mod_sb { | |||
500 | int64_t msb_delta; /* Change to make to specified field */ | 496 | int64_t msb_delta; /* Change to make to specified field */ |
501 | } xfs_mod_sb_t; | 497 | } xfs_mod_sb_t; |
502 | 498 | ||
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); | 499 | extern int xfs_log_sbcount(xfs_mount_t *, uint); |
507 | extern int xfs_mountfs(xfs_mount_t *mp); | 500 | extern int xfs_mountfs(xfs_mount_t *mp); |
508 | extern void xfs_mountfs_check_barriers(xfs_mount_t *mp); | 501 | extern void xfs_mountfs_check_barriers(xfs_mount_t *mp); |
diff --git a/fs/xfs/xfs_qmops.c b/fs/xfs/xfs_qmops.c index 27f80581520a..e101790ea8e7 100644 --- a/fs/xfs/xfs_qmops.c +++ b/fs/xfs/xfs_qmops.c | |||
@@ -126,7 +126,6 @@ static struct xfs_qmops xfs_qmcore_stub = { | |||
126 | .xfs_dqvopchownresv = (xfs_dqvopchownresv_t) fs_noerr, | 126 | .xfs_dqvopchownresv = (xfs_dqvopchownresv_t) fs_noerr, |
127 | .xfs_dqstatvfs = (xfs_dqstatvfs_t) fs_noval, | 127 | .xfs_dqstatvfs = (xfs_dqstatvfs_t) fs_noval, |
128 | .xfs_dqsync = (xfs_dqsync_t) fs_noerr, | 128 | .xfs_dqsync = (xfs_dqsync_t) fs_noerr, |
129 | .xfs_quotactl = (xfs_quotactl_t) fs_nosys, | ||
130 | }; | 129 | }; |
131 | 130 | ||
132 | int | 131 | int |
diff --git a/fs/xfs/xfs_quota.h b/fs/xfs/xfs_quota.h index 48965ecaa155..f5d1202dde25 100644 --- a/fs/xfs/xfs_quota.h +++ b/fs/xfs/xfs_quota.h | |||
@@ -18,6 +18,8 @@ | |||
18 | #ifndef __XFS_QUOTA_H__ | 18 | #ifndef __XFS_QUOTA_H__ |
19 | #define __XFS_QUOTA_H__ | 19 | #define __XFS_QUOTA_H__ |
20 | 20 | ||
21 | struct xfs_trans; | ||
22 | |||
21 | /* | 23 | /* |
22 | * The ondisk form of a dquot structure. | 24 | * The ondisk form of a dquot structure. |
23 | */ | 25 | */ |
@@ -185,7 +187,6 @@ typedef struct xfs_qoff_logformat { | |||
185 | * to a single function. None of these XFS_QMOPT_* flags are meant to have | 187 | * 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) | 188 | * persistent values (ie. their values can and will change between versions) |
187 | */ | 189 | */ |
188 | #define XFS_QMOPT_DQLOCK 0x0000001 /* dqlock */ | ||
189 | #define XFS_QMOPT_DQALLOC 0x0000002 /* alloc dquot ondisk if needed */ | 190 | #define XFS_QMOPT_DQALLOC 0x0000002 /* alloc dquot ondisk if needed */ |
190 | #define XFS_QMOPT_UQUOTA 0x0000004 /* user dquot requested */ | 191 | #define XFS_QMOPT_UQUOTA 0x0000004 /* user dquot requested */ |
191 | #define XFS_QMOPT_PQUOTA 0x0000008 /* project dquot requested */ | 192 | #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_trans.h b/fs/xfs/xfs_trans.h index d6fe4a88d79f..166f728bea70 100644 --- a/fs/xfs/xfs_trans.h +++ b/fs/xfs/xfs_trans.h | |||
@@ -343,7 +343,7 @@ xfs_lic_desc_to_chunk(xfs_log_item_desc_t *dp) | |||
343 | (128 * (9 + XFS_ALLOCFREE_LOG_COUNT(mp, 4))) + \ | 343 | (128 * (9 + XFS_ALLOCFREE_LOG_COUNT(mp, 4))) + \ |
344 | (128 * 5) + \ | 344 | (128 * 5) + \ |
345 | XFS_ALLOCFREE_LOG_RES(mp, 1) + \ | 345 | XFS_ALLOCFREE_LOG_RES(mp, 1) + \ |
346 | (128 * (2 + XFS_IALLOC_BLOCKS(mp) + XFS_IN_MAXLEVELS(mp) + \ | 346 | (128 * (2 + XFS_IALLOC_BLOCKS(mp) + (mp)->m_in_maxlevels + \ |
347 | XFS_ALLOCFREE_LOG_COUNT(mp, 1)))))) | 347 | XFS_ALLOCFREE_LOG_COUNT(mp, 1)))))) |
348 | 348 | ||
349 | #define XFS_ITRUNCATE_LOG_RES(mp) ((mp)->m_reservations.tr_itruncate) | 349 | #define XFS_ITRUNCATE_LOG_RES(mp) ((mp)->m_reservations.tr_itruncate) |
@@ -449,9 +449,9 @@ xfs_lic_desc_to_chunk(xfs_log_item_desc_t *dp) | |||
449 | (128 * (4 + XFS_DIROP_LOG_COUNT(mp)))), \ | 449 | (128 * (4 + XFS_DIROP_LOG_COUNT(mp)))), \ |
450 | (2 * (mp)->m_sb.sb_sectsize + \ | 450 | (2 * (mp)->m_sb.sb_sectsize + \ |
451 | XFS_FSB_TO_B((mp), XFS_IALLOC_BLOCKS((mp))) + \ | 451 | XFS_FSB_TO_B((mp), XFS_IALLOC_BLOCKS((mp))) + \ |
452 | XFS_FSB_TO_B((mp), XFS_IN_MAXLEVELS(mp)) + \ | 452 | XFS_FSB_TO_B((mp), (mp)->m_in_maxlevels) + \ |
453 | XFS_ALLOCFREE_LOG_RES(mp, 1) + \ | 453 | XFS_ALLOCFREE_LOG_RES(mp, 1) + \ |
454 | (128 * (2 + XFS_IALLOC_BLOCKS(mp) + XFS_IN_MAXLEVELS(mp) + \ | 454 | (128 * (2 + XFS_IALLOC_BLOCKS(mp) + (mp)->m_in_maxlevels + \ |
455 | XFS_ALLOCFREE_LOG_COUNT(mp, 1)))))) | 455 | XFS_ALLOCFREE_LOG_COUNT(mp, 1)))))) |
456 | 456 | ||
457 | #define XFS_SYMLINK_LOG_RES(mp) ((mp)->m_reservations.tr_symlink) | 457 | #define XFS_SYMLINK_LOG_RES(mp) ((mp)->m_reservations.tr_symlink) |
@@ -481,9 +481,9 @@ xfs_lic_desc_to_chunk(xfs_log_item_desc_t *dp) | |||
481 | (128 * (3 + XFS_DIROP_LOG_COUNT(mp)))), \ | 481 | (128 * (3 + XFS_DIROP_LOG_COUNT(mp)))), \ |
482 | (3 * (mp)->m_sb.sb_sectsize + \ | 482 | (3 * (mp)->m_sb.sb_sectsize + \ |
483 | XFS_FSB_TO_B((mp), XFS_IALLOC_BLOCKS((mp))) + \ | 483 | XFS_FSB_TO_B((mp), XFS_IALLOC_BLOCKS((mp))) + \ |
484 | XFS_FSB_TO_B((mp), XFS_IN_MAXLEVELS(mp)) + \ | 484 | XFS_FSB_TO_B((mp), (mp)->m_in_maxlevels) + \ |
485 | XFS_ALLOCFREE_LOG_RES(mp, 1) + \ | 485 | XFS_ALLOCFREE_LOG_RES(mp, 1) + \ |
486 | (128 * (2 + XFS_IALLOC_BLOCKS(mp) + XFS_IN_MAXLEVELS(mp) + \ | 486 | (128 * (2 + XFS_IALLOC_BLOCKS(mp) + (mp)->m_in_maxlevels + \ |
487 | XFS_ALLOCFREE_LOG_COUNT(mp, 1)))))) | 487 | XFS_ALLOCFREE_LOG_COUNT(mp, 1)))))) |
488 | 488 | ||
489 | #define XFS_CREATE_LOG_RES(mp) ((mp)->m_reservations.tr_create) | 489 | #define XFS_CREATE_LOG_RES(mp) ((mp)->m_reservations.tr_create) |
@@ -513,7 +513,7 @@ xfs_lic_desc_to_chunk(xfs_log_item_desc_t *dp) | |||
513 | MAX((__uint16_t)XFS_FSB_TO_B((mp), 1), XFS_INODE_CLUSTER_SIZE(mp)) + \ | 513 | MAX((__uint16_t)XFS_FSB_TO_B((mp), 1), XFS_INODE_CLUSTER_SIZE(mp)) + \ |
514 | (128 * 5) + \ | 514 | (128 * 5) + \ |
515 | XFS_ALLOCFREE_LOG_RES(mp, 1) + \ | 515 | XFS_ALLOCFREE_LOG_RES(mp, 1) + \ |
516 | (128 * (2 + XFS_IALLOC_BLOCKS(mp) + XFS_IN_MAXLEVELS(mp) + \ | 516 | (128 * (2 + XFS_IALLOC_BLOCKS(mp) + (mp)->m_in_maxlevels + \ |
517 | XFS_ALLOCFREE_LOG_COUNT(mp, 1)))) | 517 | XFS_ALLOCFREE_LOG_COUNT(mp, 1)))) |
518 | 518 | ||
519 | 519 | ||
diff --git a/fs/xfs/xfs_trans_space.h b/fs/xfs/xfs_trans_space.h index 4ea2e5074bdd..7d2c920dfb9c 100644 --- a/fs/xfs/xfs_trans_space.h +++ b/fs/xfs/xfs_trans_space.h | |||
@@ -47,7 +47,7 @@ | |||
47 | #define XFS_DIRREMOVE_SPACE_RES(mp) \ | 47 | #define XFS_DIRREMOVE_SPACE_RES(mp) \ |
48 | XFS_DAREMOVE_SPACE_RES(mp, XFS_DATA_FORK) | 48 | XFS_DAREMOVE_SPACE_RES(mp, XFS_DATA_FORK) |
49 | #define XFS_IALLOC_SPACE_RES(mp) \ | 49 | #define XFS_IALLOC_SPACE_RES(mp) \ |
50 | (XFS_IALLOC_BLOCKS(mp) + XFS_IN_MAXLEVELS(mp)-1) | 50 | (XFS_IALLOC_BLOCKS(mp) + (mp)->m_in_maxlevels - 1) |
51 | 51 | ||
52 | /* | 52 | /* |
53 | * Space reservation values for various transactions. | 53 | * Space reservation values for various transactions. |
diff --git a/fs/xfs/xfs_types.h b/fs/xfs/xfs_types.h index b2f724502f1b..d725428c9df6 100644 --- a/fs/xfs/xfs_types.h +++ b/fs/xfs/xfs_types.h | |||
@@ -21,14 +21,6 @@ | |||
21 | #ifdef __KERNEL__ | 21 | #ifdef __KERNEL__ |
22 | 22 | ||
23 | /* | 23 | /* |
24 | * POSIX Extensions | ||
25 | */ | ||
26 | typedef unsigned char uchar_t; | ||
27 | typedef unsigned short ushort_t; | ||
28 | typedef unsigned int uint_t; | ||
29 | typedef unsigned long ulong_t; | ||
30 | |||
31 | /* | ||
32 | * Additional type declarations for XFS | 24 | * Additional type declarations for XFS |
33 | */ | 25 | */ |
34 | typedef signed char __int8_t; | 26 | typedef signed char __int8_t; |
diff --git a/fs/xfs/xfs_vnodeops.c b/fs/xfs/xfs_vnodeops.c index 0e55c5d7db5f..59de04954bc8 100644 --- a/fs/xfs/xfs_vnodeops.c +++ b/fs/xfs/xfs_vnodeops.c | |||
@@ -1387,23 +1387,28 @@ xfs_create( | |||
1387 | xfs_inode_t **ipp, | 1387 | xfs_inode_t **ipp, |
1388 | cred_t *credp) | 1388 | cred_t *credp) |
1389 | { | 1389 | { |
1390 | xfs_mount_t *mp = dp->i_mount; | 1390 | int is_dir = S_ISDIR(mode); |
1391 | xfs_inode_t *ip; | 1391 | struct xfs_mount *mp = dp->i_mount; |
1392 | xfs_trans_t *tp; | 1392 | struct xfs_inode *ip = NULL; |
1393 | struct xfs_trans *tp = NULL; | ||
1393 | int error; | 1394 | int error; |
1394 | xfs_bmap_free_t free_list; | 1395 | xfs_bmap_free_t free_list; |
1395 | xfs_fsblock_t first_block; | 1396 | xfs_fsblock_t first_block; |
1396 | boolean_t unlock_dp_on_error = B_FALSE; | 1397 | boolean_t unlock_dp_on_error = B_FALSE; |
1397 | int dm_event_sent = 0; | ||
1398 | uint cancel_flags; | 1398 | uint cancel_flags; |
1399 | int committed; | 1399 | int committed; |
1400 | xfs_prid_t prid; | 1400 | xfs_prid_t prid; |
1401 | struct xfs_dquot *udqp, *gdqp; | 1401 | struct xfs_dquot *udqp = NULL; |
1402 | struct xfs_dquot *gdqp = NULL; | ||
1402 | uint resblks; | 1403 | uint resblks; |
1404 | uint log_res; | ||
1405 | uint log_count; | ||
1403 | 1406 | ||
1404 | ASSERT(!*ipp); | ||
1405 | xfs_itrace_entry(dp); | 1407 | xfs_itrace_entry(dp); |
1406 | 1408 | ||
1409 | if (XFS_FORCED_SHUTDOWN(mp)) | ||
1410 | return XFS_ERROR(EIO); | ||
1411 | |||
1407 | if (DM_EVENT_ENABLED(dp, DM_EVENT_CREATE)) { | 1412 | if (DM_EVENT_ENABLED(dp, DM_EVENT_CREATE)) { |
1408 | error = XFS_SEND_NAMESP(mp, DM_EVENT_CREATE, | 1413 | error = XFS_SEND_NAMESP(mp, DM_EVENT_CREATE, |
1409 | dp, DM_RIGHT_NULL, NULL, | 1414 | dp, DM_RIGHT_NULL, NULL, |
@@ -1412,84 +1417,97 @@ xfs_create( | |||
1412 | 1417 | ||
1413 | if (error) | 1418 | if (error) |
1414 | return error; | 1419 | return error; |
1415 | dm_event_sent = 1; | ||
1416 | } | 1420 | } |
1417 | 1421 | ||
1418 | if (XFS_FORCED_SHUTDOWN(mp)) | ||
1419 | return XFS_ERROR(EIO); | ||
1420 | |||
1421 | /* Return through std_return after this point. */ | ||
1422 | |||
1423 | udqp = gdqp = NULL; | ||
1424 | if (dp->i_d.di_flags & XFS_DIFLAG_PROJINHERIT) | 1422 | if (dp->i_d.di_flags & XFS_DIFLAG_PROJINHERIT) |
1425 | prid = dp->i_d.di_projid; | 1423 | prid = dp->i_d.di_projid; |
1426 | else | 1424 | else |
1427 | prid = (xfs_prid_t)dfltprid; | 1425 | prid = dfltprid; |
1428 | 1426 | ||
1429 | /* | 1427 | /* |
1430 | * Make sure that we have allocated dquot(s) on disk. | 1428 | * Make sure that we have allocated dquot(s) on disk. |
1431 | */ | 1429 | */ |
1432 | error = XFS_QM_DQVOPALLOC(mp, dp, | 1430 | error = XFS_QM_DQVOPALLOC(mp, dp, |
1433 | current_fsuid(), current_fsgid(), prid, | 1431 | current_fsuid(), current_fsgid(), prid, |
1434 | XFS_QMOPT_QUOTALL|XFS_QMOPT_INHERIT, &udqp, &gdqp); | 1432 | XFS_QMOPT_QUOTALL | XFS_QMOPT_INHERIT, &udqp, &gdqp); |
1435 | if (error) | 1433 | if (error) |
1436 | goto std_return; | 1434 | goto std_return; |
1437 | 1435 | ||
1438 | ip = NULL; | 1436 | if (is_dir) { |
1437 | rdev = 0; | ||
1438 | resblks = XFS_MKDIR_SPACE_RES(mp, name->len); | ||
1439 | log_res = XFS_MKDIR_LOG_RES(mp); | ||
1440 | log_count = XFS_MKDIR_LOG_COUNT; | ||
1441 | tp = xfs_trans_alloc(mp, XFS_TRANS_MKDIR); | ||
1442 | } else { | ||
1443 | resblks = XFS_CREATE_SPACE_RES(mp, name->len); | ||
1444 | log_res = XFS_CREATE_LOG_RES(mp); | ||
1445 | log_count = XFS_CREATE_LOG_COUNT; | ||
1446 | tp = xfs_trans_alloc(mp, XFS_TRANS_CREATE); | ||
1447 | } | ||
1439 | 1448 | ||
1440 | tp = xfs_trans_alloc(mp, XFS_TRANS_CREATE); | ||
1441 | cancel_flags = XFS_TRANS_RELEASE_LOG_RES; | 1449 | cancel_flags = XFS_TRANS_RELEASE_LOG_RES; |
1442 | resblks = XFS_CREATE_SPACE_RES(mp, name->len); | 1450 | |
1443 | /* | 1451 | /* |
1444 | * Initially assume that the file does not exist and | 1452 | * Initially assume that the file does not exist and |
1445 | * reserve the resources for that case. If that is not | 1453 | * reserve the resources for that case. If that is not |
1446 | * the case we'll drop the one we have and get a more | 1454 | * the case we'll drop the one we have and get a more |
1447 | * appropriate transaction later. | 1455 | * appropriate transaction later. |
1448 | */ | 1456 | */ |
1449 | error = xfs_trans_reserve(tp, resblks, XFS_CREATE_LOG_RES(mp), 0, | 1457 | error = xfs_trans_reserve(tp, resblks, log_res, 0, |
1450 | XFS_TRANS_PERM_LOG_RES, XFS_CREATE_LOG_COUNT); | 1458 | XFS_TRANS_PERM_LOG_RES, log_count); |
1451 | if (error == ENOSPC) { | 1459 | if (error == ENOSPC) { |
1452 | resblks = 0; | 1460 | resblks = 0; |
1453 | error = xfs_trans_reserve(tp, 0, XFS_CREATE_LOG_RES(mp), 0, | 1461 | error = xfs_trans_reserve(tp, 0, log_res, 0, |
1454 | XFS_TRANS_PERM_LOG_RES, XFS_CREATE_LOG_COUNT); | 1462 | XFS_TRANS_PERM_LOG_RES, log_count); |
1455 | } | 1463 | } |
1456 | if (error) { | 1464 | if (error) { |
1457 | cancel_flags = 0; | 1465 | cancel_flags = 0; |
1458 | goto error_return; | 1466 | goto out_trans_cancel; |
1459 | } | 1467 | } |
1460 | 1468 | ||
1461 | xfs_ilock(dp, XFS_ILOCK_EXCL | XFS_ILOCK_PARENT); | 1469 | xfs_ilock(dp, XFS_ILOCK_EXCL | XFS_ILOCK_PARENT); |
1462 | unlock_dp_on_error = B_TRUE; | 1470 | unlock_dp_on_error = B_TRUE; |
1463 | 1471 | ||
1464 | xfs_bmap_init(&free_list, &first_block); | 1472 | /* |
1473 | * Check for directory link count overflow. | ||
1474 | */ | ||
1475 | if (is_dir && dp->i_d.di_nlink >= XFS_MAXLINK) { | ||
1476 | error = XFS_ERROR(EMLINK); | ||
1477 | goto out_trans_cancel; | ||
1478 | } | ||
1465 | 1479 | ||
1466 | ASSERT(ip == NULL); | 1480 | xfs_bmap_init(&free_list, &first_block); |
1467 | 1481 | ||
1468 | /* | 1482 | /* |
1469 | * Reserve disk quota and the inode. | 1483 | * Reserve disk quota and the inode. |
1470 | */ | 1484 | */ |
1471 | error = XFS_TRANS_RESERVE_QUOTA(mp, tp, udqp, gdqp, resblks, 1, 0); | 1485 | error = XFS_TRANS_RESERVE_QUOTA(mp, tp, udqp, gdqp, resblks, 1, 0); |
1472 | if (error) | 1486 | if (error) |
1473 | goto error_return; | 1487 | goto out_trans_cancel; |
1474 | 1488 | ||
1475 | error = xfs_dir_canenter(tp, dp, name, resblks); | 1489 | error = xfs_dir_canenter(tp, dp, name, resblks); |
1476 | if (error) | 1490 | if (error) |
1477 | goto error_return; | 1491 | goto out_trans_cancel; |
1478 | error = xfs_dir_ialloc(&tp, dp, mode, 1, | 1492 | |
1479 | rdev, credp, prid, resblks > 0, | 1493 | /* |
1480 | &ip, &committed); | 1494 | * A newly created regular or special file just has one directory |
1495 | * entry pointing to them, but a directory also the "." entry | ||
1496 | * pointing to itself. | ||
1497 | */ | ||
1498 | error = xfs_dir_ialloc(&tp, dp, mode, is_dir ? 2 : 1, rdev, credp, | ||
1499 | prid, resblks > 0, &ip, &committed); | ||
1481 | if (error) { | 1500 | if (error) { |
1482 | if (error == ENOSPC) | 1501 | if (error == ENOSPC) |
1483 | goto error_return; | 1502 | goto out_trans_cancel; |
1484 | goto abort_return; | 1503 | goto out_trans_abort; |
1485 | } | 1504 | } |
1486 | xfs_itrace_ref(ip); | ||
1487 | 1505 | ||
1488 | /* | 1506 | /* |
1489 | * At this point, we've gotten a newly allocated inode. | 1507 | * At this point, we've gotten a newly allocated inode. |
1490 | * It is locked (and joined to the transaction). | 1508 | * It is locked (and joined to the transaction). |
1491 | */ | 1509 | */ |
1492 | 1510 | xfs_itrace_ref(ip); | |
1493 | ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL)); | 1511 | ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL)); |
1494 | 1512 | ||
1495 | /* | 1513 | /* |
@@ -1508,19 +1526,28 @@ xfs_create( | |||
1508 | resblks - XFS_IALLOC_SPACE_RES(mp) : 0); | 1526 | resblks - XFS_IALLOC_SPACE_RES(mp) : 0); |
1509 | if (error) { | 1527 | if (error) { |
1510 | ASSERT(error != ENOSPC); | 1528 | ASSERT(error != ENOSPC); |
1511 | goto abort_return; | 1529 | goto out_trans_abort; |
1512 | } | 1530 | } |
1513 | xfs_ichgtime(dp, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG); | 1531 | xfs_ichgtime(dp, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG); |
1514 | xfs_trans_log_inode(tp, dp, XFS_ILOG_CORE); | 1532 | xfs_trans_log_inode(tp, dp, XFS_ILOG_CORE); |
1515 | 1533 | ||
1534 | if (is_dir) { | ||
1535 | error = xfs_dir_init(tp, ip, dp); | ||
1536 | if (error) | ||
1537 | goto out_bmap_cancel; | ||
1538 | |||
1539 | error = xfs_bumplink(tp, dp); | ||
1540 | if (error) | ||
1541 | goto out_bmap_cancel; | ||
1542 | } | ||
1543 | |||
1516 | /* | 1544 | /* |
1517 | * If this is a synchronous mount, make sure that the | 1545 | * If this is a synchronous mount, make sure that the |
1518 | * create transaction goes to disk before returning to | 1546 | * create transaction goes to disk before returning to |
1519 | * the user. | 1547 | * the user. |
1520 | */ | 1548 | */ |
1521 | if (mp->m_flags & (XFS_MOUNT_WSYNC|XFS_MOUNT_DIRSYNC)) { | 1549 | if (mp->m_flags & (XFS_MOUNT_WSYNC|XFS_MOUNT_DIRSYNC)) |
1522 | xfs_trans_set_sync(tp); | 1550 | xfs_trans_set_sync(tp); |
1523 | } | ||
1524 | 1551 | ||
1525 | /* | 1552 | /* |
1526 | * Attach the dquot(s) to the inodes and modify them incore. | 1553 | * Attach the dquot(s) to the inodes and modify them incore. |
@@ -1537,16 +1564,13 @@ xfs_create( | |||
1537 | IHOLD(ip); | 1564 | IHOLD(ip); |
1538 | 1565 | ||
1539 | error = xfs_bmap_finish(&tp, &free_list, &committed); | 1566 | error = xfs_bmap_finish(&tp, &free_list, &committed); |
1540 | if (error) { | 1567 | if (error) |
1541 | xfs_bmap_cancel(&free_list); | 1568 | goto out_abort_rele; |
1542 | goto abort_rele; | ||
1543 | } | ||
1544 | 1569 | ||
1545 | error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES); | 1570 | error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES); |
1546 | if (error) { | 1571 | if (error) { |
1547 | IRELE(ip); | 1572 | IRELE(ip); |
1548 | tp = NULL; | 1573 | goto out_dqrele; |
1549 | goto error_return; | ||
1550 | } | 1574 | } |
1551 | 1575 | ||
1552 | XFS_QM_DQRELE(mp, udqp); | 1576 | XFS_QM_DQRELE(mp, udqp); |
@@ -1555,26 +1579,22 @@ xfs_create( | |||
1555 | *ipp = ip; | 1579 | *ipp = ip; |
1556 | 1580 | ||
1557 | /* Fallthrough to std_return with error = 0 */ | 1581 | /* Fallthrough to std_return with error = 0 */ |
1558 | 1582 | std_return: | |
1559 | std_return: | 1583 | if (DM_EVENT_ENABLED(dp, DM_EVENT_POSTCREATE)) { |
1560 | if ((*ipp || (error != 0 && dm_event_sent != 0)) && | 1584 | XFS_SEND_NAMESP(mp, DM_EVENT_POSTCREATE, dp, DM_RIGHT_NULL, |
1561 | DM_EVENT_ENABLED(dp, DM_EVENT_POSTCREATE)) { | 1585 | ip, DM_RIGHT_NULL, name->name, NULL, mode, |
1562 | (void) XFS_SEND_NAMESP(mp, DM_EVENT_POSTCREATE, | 1586 | error, 0); |
1563 | dp, DM_RIGHT_NULL, | ||
1564 | *ipp ? ip : NULL, | ||
1565 | DM_RIGHT_NULL, name->name, NULL, | ||
1566 | mode, error, 0); | ||
1567 | } | 1587 | } |
1588 | |||
1568 | return error; | 1589 | return error; |
1569 | 1590 | ||
1570 | abort_return: | 1591 | out_bmap_cancel: |
1592 | xfs_bmap_cancel(&free_list); | ||
1593 | out_trans_abort: | ||
1571 | cancel_flags |= XFS_TRANS_ABORT; | 1594 | cancel_flags |= XFS_TRANS_ABORT; |
1572 | /* FALLTHROUGH */ | 1595 | out_trans_cancel: |
1573 | 1596 | xfs_trans_cancel(tp, cancel_flags); | |
1574 | error_return: | 1597 | out_dqrele: |
1575 | if (tp != NULL) | ||
1576 | xfs_trans_cancel(tp, cancel_flags); | ||
1577 | |||
1578 | XFS_QM_DQRELE(mp, udqp); | 1598 | XFS_QM_DQRELE(mp, udqp); |
1579 | XFS_QM_DQRELE(mp, gdqp); | 1599 | XFS_QM_DQRELE(mp, gdqp); |
1580 | 1600 | ||
@@ -1583,20 +1603,18 @@ std_return: | |||
1583 | 1603 | ||
1584 | goto std_return; | 1604 | goto std_return; |
1585 | 1605 | ||
1586 | abort_rele: | 1606 | out_abort_rele: |
1587 | /* | 1607 | /* |
1588 | * Wait until after the current transaction is aborted to | 1608 | * Wait until after the current transaction is aborted to |
1589 | * release the inode. This prevents recursive transactions | 1609 | * release the inode. This prevents recursive transactions |
1590 | * and deadlocks from xfs_inactive. | 1610 | * and deadlocks from xfs_inactive. |
1591 | */ | 1611 | */ |
1612 | xfs_bmap_cancel(&free_list); | ||
1592 | cancel_flags |= XFS_TRANS_ABORT; | 1613 | cancel_flags |= XFS_TRANS_ABORT; |
1593 | xfs_trans_cancel(tp, cancel_flags); | 1614 | xfs_trans_cancel(tp, cancel_flags); |
1594 | IRELE(ip); | 1615 | IRELE(ip); |
1595 | 1616 | unlock_dp_on_error = B_FALSE; | |
1596 | XFS_QM_DQRELE(mp, udqp); | 1617 | goto out_dqrele; |
1597 | XFS_QM_DQRELE(mp, gdqp); | ||
1598 | |||
1599 | goto std_return; | ||
1600 | } | 1618 | } |
1601 | 1619 | ||
1602 | #ifdef DEBUG | 1620 | #ifdef DEBUG |
@@ -2004,8 +2022,10 @@ xfs_link( | |||
2004 | /* Return through std_return after this point. */ | 2022 | /* Return through std_return after this point. */ |
2005 | 2023 | ||
2006 | error = XFS_QM_DQATTACH(mp, sip, 0); | 2024 | error = XFS_QM_DQATTACH(mp, sip, 0); |
2007 | if (!error && sip != tdp) | 2025 | if (error) |
2008 | error = XFS_QM_DQATTACH(mp, tdp, 0); | 2026 | goto std_return; |
2027 | |||
2028 | error = XFS_QM_DQATTACH(mp, tdp, 0); | ||
2009 | if (error) | 2029 | if (error) |
2010 | goto std_return; | 2030 | goto std_return; |
2011 | 2031 | ||
@@ -2110,209 +2130,6 @@ std_return: | |||
2110 | goto std_return; | 2130 | goto std_return; |
2111 | } | 2131 | } |
2112 | 2132 | ||
2113 | |||
2114 | int | ||
2115 | xfs_mkdir( | ||
2116 | xfs_inode_t *dp, | ||
2117 | struct xfs_name *dir_name, | ||
2118 | mode_t mode, | ||
2119 | xfs_inode_t **ipp, | ||
2120 | cred_t *credp) | ||
2121 | { | ||
2122 | xfs_mount_t *mp = dp->i_mount; | ||
2123 | xfs_inode_t *cdp; /* inode of created dir */ | ||
2124 | xfs_trans_t *tp; | ||
2125 | int cancel_flags; | ||
2126 | int error; | ||
2127 | int committed; | ||
2128 | xfs_bmap_free_t free_list; | ||
2129 | xfs_fsblock_t first_block; | ||
2130 | boolean_t unlock_dp_on_error = B_FALSE; | ||
2131 | boolean_t created = B_FALSE; | ||
2132 | int dm_event_sent = 0; | ||
2133 | xfs_prid_t prid; | ||
2134 | struct xfs_dquot *udqp, *gdqp; | ||
2135 | uint resblks; | ||
2136 | |||
2137 | if (XFS_FORCED_SHUTDOWN(mp)) | ||
2138 | return XFS_ERROR(EIO); | ||
2139 | |||
2140 | tp = NULL; | ||
2141 | |||
2142 | if (DM_EVENT_ENABLED(dp, DM_EVENT_CREATE)) { | ||
2143 | error = XFS_SEND_NAMESP(mp, DM_EVENT_CREATE, | ||
2144 | dp, DM_RIGHT_NULL, NULL, | ||
2145 | DM_RIGHT_NULL, dir_name->name, NULL, | ||
2146 | mode, 0, 0); | ||
2147 | if (error) | ||
2148 | return error; | ||
2149 | dm_event_sent = 1; | ||
2150 | } | ||
2151 | |||
2152 | /* Return through std_return after this point. */ | ||
2153 | |||
2154 | xfs_itrace_entry(dp); | ||
2155 | |||
2156 | mp = dp->i_mount; | ||
2157 | udqp = gdqp = NULL; | ||
2158 | if (dp->i_d.di_flags & XFS_DIFLAG_PROJINHERIT) | ||
2159 | prid = dp->i_d.di_projid; | ||
2160 | else | ||
2161 | prid = (xfs_prid_t)dfltprid; | ||
2162 | |||
2163 | /* | ||
2164 | * Make sure that we have allocated dquot(s) on disk. | ||
2165 | */ | ||
2166 | error = XFS_QM_DQVOPALLOC(mp, dp, | ||
2167 | current_fsuid(), current_fsgid(), prid, | ||
2168 | XFS_QMOPT_QUOTALL | XFS_QMOPT_INHERIT, &udqp, &gdqp); | ||
2169 | if (error) | ||
2170 | goto std_return; | ||
2171 | |||
2172 | tp = xfs_trans_alloc(mp, XFS_TRANS_MKDIR); | ||
2173 | cancel_flags = XFS_TRANS_RELEASE_LOG_RES; | ||
2174 | resblks = XFS_MKDIR_SPACE_RES(mp, dir_name->len); | ||
2175 | error = xfs_trans_reserve(tp, resblks, XFS_MKDIR_LOG_RES(mp), 0, | ||
2176 | XFS_TRANS_PERM_LOG_RES, XFS_MKDIR_LOG_COUNT); | ||
2177 | if (error == ENOSPC) { | ||
2178 | resblks = 0; | ||
2179 | error = xfs_trans_reserve(tp, 0, XFS_MKDIR_LOG_RES(mp), 0, | ||
2180 | XFS_TRANS_PERM_LOG_RES, | ||
2181 | XFS_MKDIR_LOG_COUNT); | ||
2182 | } | ||
2183 | if (error) { | ||
2184 | cancel_flags = 0; | ||
2185 | goto error_return; | ||
2186 | } | ||
2187 | |||
2188 | xfs_ilock(dp, XFS_ILOCK_EXCL | XFS_ILOCK_PARENT); | ||
2189 | unlock_dp_on_error = B_TRUE; | ||
2190 | |||
2191 | /* | ||
2192 | * Check for directory link count overflow. | ||
2193 | */ | ||
2194 | if (dp->i_d.di_nlink >= XFS_MAXLINK) { | ||
2195 | error = XFS_ERROR(EMLINK); | ||
2196 | goto error_return; | ||
2197 | } | ||
2198 | |||
2199 | /* | ||
2200 | * Reserve disk quota and the inode. | ||
2201 | */ | ||
2202 | error = XFS_TRANS_RESERVE_QUOTA(mp, tp, udqp, gdqp, resblks, 1, 0); | ||
2203 | if (error) | ||
2204 | goto error_return; | ||
2205 | |||
2206 | error = xfs_dir_canenter(tp, dp, dir_name, resblks); | ||
2207 | if (error) | ||
2208 | goto error_return; | ||
2209 | /* | ||
2210 | * create the directory inode. | ||
2211 | */ | ||
2212 | error = xfs_dir_ialloc(&tp, dp, mode, 2, | ||
2213 | 0, credp, prid, resblks > 0, | ||
2214 | &cdp, NULL); | ||
2215 | if (error) { | ||
2216 | if (error == ENOSPC) | ||
2217 | goto error_return; | ||
2218 | goto abort_return; | ||
2219 | } | ||
2220 | xfs_itrace_ref(cdp); | ||
2221 | |||
2222 | /* | ||
2223 | * Now we add the directory inode to the transaction. | ||
2224 | * We waited until now since xfs_dir_ialloc might start | ||
2225 | * a new transaction. Had we joined the transaction | ||
2226 | * earlier, the locks might have gotten released. An error | ||
2227 | * from here on will result in the transaction cancel | ||
2228 | * unlocking dp so don't do it explicitly in the error path. | ||
2229 | */ | ||
2230 | IHOLD(dp); | ||
2231 | xfs_trans_ijoin(tp, dp, XFS_ILOCK_EXCL); | ||
2232 | unlock_dp_on_error = B_FALSE; | ||
2233 | |||
2234 | xfs_bmap_init(&free_list, &first_block); | ||
2235 | |||
2236 | error = xfs_dir_createname(tp, dp, dir_name, cdp->i_ino, | ||
2237 | &first_block, &free_list, resblks ? | ||
2238 | resblks - XFS_IALLOC_SPACE_RES(mp) : 0); | ||
2239 | if (error) { | ||
2240 | ASSERT(error != ENOSPC); | ||
2241 | goto error1; | ||
2242 | } | ||
2243 | xfs_ichgtime(dp, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG); | ||
2244 | |||
2245 | error = xfs_dir_init(tp, cdp, dp); | ||
2246 | if (error) | ||
2247 | goto error2; | ||
2248 | |||
2249 | error = xfs_bumplink(tp, dp); | ||
2250 | if (error) | ||
2251 | goto error2; | ||
2252 | |||
2253 | created = B_TRUE; | ||
2254 | |||
2255 | *ipp = cdp; | ||
2256 | IHOLD(cdp); | ||
2257 | |||
2258 | /* | ||
2259 | * Attach the dquots to the new inode and modify the icount incore. | ||
2260 | */ | ||
2261 | XFS_QM_DQVOPCREATE(mp, tp, cdp, udqp, gdqp); | ||
2262 | |||
2263 | /* | ||
2264 | * If this is a synchronous mount, make sure that the | ||
2265 | * mkdir transaction goes to disk before returning to | ||
2266 | * the user. | ||
2267 | */ | ||
2268 | if (mp->m_flags & (XFS_MOUNT_WSYNC|XFS_MOUNT_DIRSYNC)) { | ||
2269 | xfs_trans_set_sync(tp); | ||
2270 | } | ||
2271 | |||
2272 | error = xfs_bmap_finish(&tp, &free_list, &committed); | ||
2273 | if (error) { | ||
2274 | IRELE(cdp); | ||
2275 | goto error2; | ||
2276 | } | ||
2277 | |||
2278 | error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES); | ||
2279 | XFS_QM_DQRELE(mp, udqp); | ||
2280 | XFS_QM_DQRELE(mp, gdqp); | ||
2281 | if (error) { | ||
2282 | IRELE(cdp); | ||
2283 | } | ||
2284 | |||
2285 | /* Fall through to std_return with error = 0 or errno from | ||
2286 | * xfs_trans_commit. */ | ||
2287 | |||
2288 | std_return: | ||
2289 | if ((created || (error != 0 && dm_event_sent != 0)) && | ||
2290 | DM_EVENT_ENABLED(dp, DM_EVENT_POSTCREATE)) { | ||
2291 | (void) XFS_SEND_NAMESP(mp, DM_EVENT_POSTCREATE, | ||
2292 | dp, DM_RIGHT_NULL, | ||
2293 | created ? cdp : NULL, | ||
2294 | DM_RIGHT_NULL, | ||
2295 | dir_name->name, NULL, | ||
2296 | mode, error, 0); | ||
2297 | } | ||
2298 | return error; | ||
2299 | |||
2300 | error2: | ||
2301 | error1: | ||
2302 | xfs_bmap_cancel(&free_list); | ||
2303 | abort_return: | ||
2304 | cancel_flags |= XFS_TRANS_ABORT; | ||
2305 | error_return: | ||
2306 | xfs_trans_cancel(tp, cancel_flags); | ||
2307 | XFS_QM_DQRELE(mp, udqp); | ||
2308 | XFS_QM_DQRELE(mp, gdqp); | ||
2309 | |||
2310 | if (unlock_dp_on_error) | ||
2311 | xfs_iunlock(dp, XFS_ILOCK_EXCL); | ||
2312 | |||
2313 | goto std_return; | ||
2314 | } | ||
2315 | |||
2316 | int | 2133 | int |
2317 | xfs_symlink( | 2134 | xfs_symlink( |
2318 | xfs_inode_t *dp, | 2135 | xfs_inode_t *dp, |
@@ -2587,51 +2404,6 @@ std_return: | |||
2587 | } | 2404 | } |
2588 | 2405 | ||
2589 | int | 2406 | 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( | 2407 | xfs_set_dmattrs( |
2636 | xfs_inode_t *ip, | 2408 | xfs_inode_t *ip, |
2637 | u_int evmask, | 2409 | u_int evmask, |
diff --git a/fs/xfs/xfs_vnodeops.h b/fs/xfs/xfs_vnodeops.h index 76df328c61b4..04373c6c61ff 100644 --- a/fs/xfs/xfs_vnodeops.h +++ b/fs/xfs/xfs_vnodeops.h | |||
@@ -31,14 +31,11 @@ int xfs_remove(struct xfs_inode *dp, struct xfs_name *name, | |||
31 | struct xfs_inode *ip); | 31 | struct xfs_inode *ip); |
32 | int xfs_link(struct xfs_inode *tdp, struct xfs_inode *sip, | 32 | int xfs_link(struct xfs_inode *tdp, struct xfs_inode *sip, |
33 | struct xfs_name *target_name); | 33 | struct xfs_name *target_name); |
34 | int xfs_mkdir(struct xfs_inode *dp, struct xfs_name *dir_name, | ||
35 | mode_t mode, struct xfs_inode **ipp, cred_t *credp); | ||
36 | int xfs_readdir(struct xfs_inode *dp, void *dirent, size_t bufsize, | 34 | int xfs_readdir(struct xfs_inode *dp, void *dirent, size_t bufsize, |
37 | xfs_off_t *offset, filldir_t filldir); | 35 | xfs_off_t *offset, filldir_t filldir); |
38 | int xfs_symlink(struct xfs_inode *dp, struct xfs_name *link_name, | 36 | int xfs_symlink(struct xfs_inode *dp, struct xfs_name *link_name, |
39 | const char *target_path, mode_t mode, struct xfs_inode **ipp, | 37 | const char *target_path, mode_t mode, struct xfs_inode **ipp, |
40 | cred_t *credp); | 38 | 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); | 39 | int xfs_set_dmattrs(struct xfs_inode *ip, u_int evmask, u_int16_t state); |
43 | int xfs_reclaim(struct xfs_inode *ip); | 40 | int xfs_reclaim(struct xfs_inode *ip); |
44 | int xfs_change_file_space(struct xfs_inode *ip, int cmd, | 41 | int xfs_change_file_space(struct xfs_inode *ip, int cmd, |