diff options
author | Felix Blyakher <felixb@sgi.com> | 2009-02-09 12:52:34 -0500 |
---|---|---|
committer | Felix Blyakher <felixb@sgi.com> | 2009-02-09 12:52:34 -0500 |
commit | 8e08f6eb34af13b78d379a025e4c9f8612b47b95 (patch) | |
tree | 663bb4dcfa4552bb8daf19055d7e4d86a0ad84c2 | |
parent | 9483c89eae58bee79b0280c625ca35a7b78fa300 (diff) | |
parent | fcafb71b57a039f2113b0321b3b5535fea3a0aca (diff) |
Merge branch 'master' of git://git.kernel.org/pub/scm/fs/xfs/xfs
30 files changed, 346 insertions, 734 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_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 faf3aa3ca154..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. |
@@ -1333,57 +1332,6 @@ xfs_fs_show_options( | |||
1333 | return -xfs_showargs(XFS_M(mnt->mnt_sb), m); | 1332 | return -xfs_showargs(XFS_M(mnt->mnt_sb), m); |
1334 | } | 1333 | } |
1335 | 1334 | ||
1336 | STATIC int | ||
1337 | xfs_fs_quotasync( | ||
1338 | struct super_block *sb, | ||
1339 | int type) | ||
1340 | { | ||
1341 | return -XFS_QM_QUOTACTL(XFS_M(sb), Q_XQUOTASYNC, 0, NULL); | ||
1342 | } | ||
1343 | |||
1344 | STATIC int | ||
1345 | xfs_fs_getxstate( | ||
1346 | struct super_block *sb, | ||
1347 | struct fs_quota_stat *fqs) | ||
1348 | { | ||
1349 | return -XFS_QM_QUOTACTL(XFS_M(sb), Q_XGETQSTAT, 0, (caddr_t)fqs); | ||
1350 | } | ||
1351 | |||
1352 | STATIC int | ||
1353 | xfs_fs_setxstate( | ||
1354 | struct super_block *sb, | ||
1355 | unsigned int flags, | ||
1356 | int op) | ||
1357 | { | ||
1358 | return -XFS_QM_QUOTACTL(XFS_M(sb), op, 0, (caddr_t)&flags); | ||
1359 | } | ||
1360 | |||
1361 | STATIC int | ||
1362 | xfs_fs_getxquota( | ||
1363 | struct super_block *sb, | ||
1364 | int type, | ||
1365 | qid_t id, | ||
1366 | struct fs_disk_quota *fdq) | ||
1367 | { | ||
1368 | return -XFS_QM_QUOTACTL(XFS_M(sb), | ||
1369 | (type == USRQUOTA) ? Q_XGETQUOTA : | ||
1370 | ((type == GRPQUOTA) ? Q_XGETGQUOTA : | ||
1371 | Q_XGETPQUOTA), id, (caddr_t)fdq); | ||
1372 | } | ||
1373 | |||
1374 | STATIC int | ||
1375 | xfs_fs_setxquota( | ||
1376 | struct super_block *sb, | ||
1377 | int type, | ||
1378 | qid_t id, | ||
1379 | struct fs_disk_quota *fdq) | ||
1380 | { | ||
1381 | return -XFS_QM_QUOTACTL(XFS_M(sb), | ||
1382 | (type == USRQUOTA) ? Q_XSETQLIM : | ||
1383 | ((type == GRPQUOTA) ? Q_XSETGQLIM : | ||
1384 | Q_XSETPQLIM), id, (caddr_t)fdq); | ||
1385 | } | ||
1386 | |||
1387 | /* | 1335 | /* |
1388 | * 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. |
1389 | * Note: the superblock _has_ now been read in. | 1337 | * Note: the superblock _has_ now been read in. |
@@ -1466,7 +1414,9 @@ xfs_fs_fill_super( | |||
1466 | sb_min_blocksize(sb, BBSIZE); | 1414 | sb_min_blocksize(sb, BBSIZE); |
1467 | sb->s_xattr = xfs_xattr_handlers; | 1415 | sb->s_xattr = xfs_xattr_handlers; |
1468 | sb->s_export_op = &xfs_export_operations; | 1416 | sb->s_export_op = &xfs_export_operations; |
1417 | #ifdef CONFIG_XFS_QUOTA | ||
1469 | sb->s_qcop = &xfs_quotactl_operations; | 1418 | sb->s_qcop = &xfs_quotactl_operations; |
1419 | #endif | ||
1470 | sb->s_op = &xfs_super_operations; | 1420 | sb->s_op = &xfs_super_operations; |
1471 | 1421 | ||
1472 | error = xfs_dmops_get(mp); | 1422 | error = xfs_dmops_get(mp); |
@@ -1609,14 +1559,6 @@ static struct super_operations xfs_super_operations = { | |||
1609 | .show_options = xfs_fs_show_options, | 1559 | .show_options = xfs_fs_show_options, |
1610 | }; | 1560 | }; |
1611 | 1561 | ||
1612 | static struct quotactl_ops xfs_quotactl_operations = { | ||
1613 | .quota_sync = xfs_fs_quotasync, | ||
1614 | .get_xstate = xfs_fs_getxstate, | ||
1615 | .set_xstate = xfs_fs_setxstate, | ||
1616 | .get_xquota = xfs_fs_getxquota, | ||
1617 | .set_xquota = xfs_fs_setxquota, | ||
1618 | }; | ||
1619 | |||
1620 | static struct file_system_type xfs_fs_type = { | 1562 | static struct file_system_type xfs_fs_type = { |
1621 | .owner = THIS_MODULE, | 1563 | .owner = THIS_MODULE, |
1622 | .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/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 fd0b383d72a5..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 | } |
@@ -2028,7 +2025,7 @@ xfs_qm_shake_freelist( | |||
2028 | * a dqlookup process that holds the hashlock that is | 2025 | * a dqlookup process that holds the hashlock that is |
2029 | * waiting for the freelist lock. | 2026 | * waiting for the freelist lock. |
2030 | */ | 2027 | */ |
2031 | if (! xfs_qm_dqhashlock_nowait(dqp)) { | 2028 | if (!mutex_trylock(&dqp->q_hash->qh_lock)) { |
2032 | xfs_dqfunlock(dqp); | 2029 | xfs_dqfunlock(dqp); |
2033 | xfs_dqunlock(dqp); | 2030 | xfs_dqunlock(dqp); |
2034 | dqp = dqp->dq_flnext; | 2031 | dqp = dqp->dq_flnext; |
@@ -2045,7 +2042,7 @@ xfs_qm_shake_freelist( | |||
2045 | /* XXX put a sentinel so that we can come back here */ | 2042 | /* XXX put a sentinel so that we can come back here */ |
2046 | xfs_dqfunlock(dqp); | 2043 | xfs_dqfunlock(dqp); |
2047 | xfs_dqunlock(dqp); | 2044 | xfs_dqunlock(dqp); |
2048 | XFS_DQ_HASH_UNLOCK(hash); | 2045 | mutex_unlock(&hash->qh_lock); |
2049 | xfs_qm_freelist_unlock(xfs_Gqm); | 2046 | xfs_qm_freelist_unlock(xfs_Gqm); |
2050 | if (++restarts >= XFS_QM_RECLAIM_MAX_RESTARTS) | 2047 | if (++restarts >= XFS_QM_RECLAIM_MAX_RESTARTS) |
2051 | return nreclaimed; | 2048 | return nreclaimed; |
@@ -2062,7 +2059,7 @@ xfs_qm_shake_freelist( | |||
2062 | XQM_HASHLIST_REMOVE(hash, dqp); | 2059 | XQM_HASHLIST_REMOVE(hash, dqp); |
2063 | xfs_dqfunlock(dqp); | 2060 | xfs_dqfunlock(dqp); |
2064 | xfs_qm_mplist_unlock(dqp->q_mount); | 2061 | xfs_qm_mplist_unlock(dqp->q_mount); |
2065 | XFS_DQ_HASH_UNLOCK(hash); | 2062 | mutex_unlock(&hash->qh_lock); |
2066 | 2063 | ||
2067 | off_freelist: | 2064 | off_freelist: |
2068 | XQM_FREELIST_REMOVE(dqp); | 2065 | XQM_FREELIST_REMOVE(dqp); |
@@ -2204,7 +2201,7 @@ xfs_qm_dqreclaim_one(void) | |||
2204 | continue; | 2201 | continue; |
2205 | } | 2202 | } |
2206 | 2203 | ||
2207 | if (! xfs_qm_dqhashlock_nowait(dqp)) | 2204 | if (!mutex_trylock(&dqp->q_hash->qh_lock)) |
2208 | goto mplistunlock; | 2205 | goto mplistunlock; |
2209 | 2206 | ||
2210 | ASSERT(dqp->q_nrefs == 0); | 2207 | ASSERT(dqp->q_nrefs == 0); |
@@ -2213,7 +2210,7 @@ xfs_qm_dqreclaim_one(void) | |||
2213 | XQM_HASHLIST_REMOVE(dqp->q_hash, dqp); | 2210 | XQM_HASHLIST_REMOVE(dqp->q_hash, dqp); |
2214 | XQM_FREELIST_REMOVE(dqp); | 2211 | XQM_FREELIST_REMOVE(dqp); |
2215 | dqpout = dqp; | 2212 | dqpout = dqp; |
2216 | XFS_DQ_HASH_UNLOCK(dqp->q_hash); | 2213 | mutex_unlock(&dqp->q_hash->qh_lock); |
2217 | mplistunlock: | 2214 | mplistunlock: |
2218 | xfs_qm_mplist_unlock(dqp->q_mount); | 2215 | xfs_qm_mplist_unlock(dqp->q_mount); |
2219 | xfs_dqfunlock(dqp); | 2216 | xfs_dqfunlock(dqp); |
@@ -2716,34 +2713,3 @@ xfs_qm_freelist_append(xfs_frlist_t *ql, xfs_dquot_t *dq) | |||
2716 | { | 2713 | { |
2717 | xfs_qm_freelist_insert((xfs_frlist_t *)ql->qh_prev, dq); | 2714 | xfs_qm_freelist_insert((xfs_frlist_t *)ql->qh_prev, dq); |
2718 | } | 2715 | } |
2719 | |||
2720 | STATIC int | ||
2721 | xfs_qm_dqhashlock_nowait( | ||
2722 | xfs_dquot_t *dqp) | ||
2723 | { | ||
2724 | int locked; | ||
2725 | |||
2726 | locked = mutex_trylock(&((dqp)->q_hash->qh_lock)); | ||
2727 | return locked; | ||
2728 | } | ||
2729 | |||
2730 | int | ||
2731 | xfs_qm_freelist_lock_nowait( | ||
2732 | xfs_qm_t *xqm) | ||
2733 | { | ||
2734 | int locked; | ||
2735 | |||
2736 | locked = mutex_trylock(&(xqm->qm_dqfreelist.qh_lock)); | ||
2737 | return locked; | ||
2738 | } | ||
2739 | |||
2740 | STATIC int | ||
2741 | xfs_qm_mplist_nowait( | ||
2742 | xfs_mount_t *mp) | ||
2743 | { | ||
2744 | int locked; | ||
2745 | |||
2746 | ASSERT(mp->m_quotainfo); | ||
2747 | locked = mutex_trylock(&(XFS_QI_MPLLOCK(mp))); | ||
2748 | return locked; | ||
2749 | } | ||
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/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_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_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_log.c b/fs/xfs/xfs_log.c index f4726f702a9e..493c07f6a99a 100644 --- a/fs/xfs/xfs_log.c +++ b/fs/xfs/xfs_log.c | |||
@@ -1164,32 +1164,8 @@ xlog_get_iclog_buffer_size(xfs_mount_t *mp, | |||
1164 | log->l_iclog_hsize = BBSIZE; | 1164 | log->l_iclog_hsize = BBSIZE; |
1165 | log->l_iclog_heads = 1; | 1165 | log->l_iclog_heads = 1; |
1166 | 1166 | ||
1167 | /* | 1167 | done: |
1168 | * For 16KB, we use 3 32KB buffers. For 32KB block sizes, we use | 1168 | /* 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) | 1169 | if (mp->m_logbufs == 0) |
1194 | mp->m_logbufs = log->l_iclog_bufs; | 1170 | mp->m_logbufs = log->l_iclog_bufs; |
1195 | if (mp->m_logbsize == 0) | 1171 | 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.h b/fs/xfs/xfs_mount.h index 670c10e098a0..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 */ |
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 63d41acf4533..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 | */ |
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 bc0a0a75b1d6..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 |
@@ -2112,209 +2130,6 @@ std_return: | |||
2112 | goto std_return; | 2130 | goto std_return; |
2113 | } | 2131 | } |
2114 | 2132 | ||
2115 | |||
2116 | int | ||
2117 | xfs_mkdir( | ||
2118 | xfs_inode_t *dp, | ||
2119 | struct xfs_name *dir_name, | ||
2120 | mode_t mode, | ||
2121 | xfs_inode_t **ipp, | ||
2122 | cred_t *credp) | ||
2123 | { | ||
2124 | xfs_mount_t *mp = dp->i_mount; | ||
2125 | xfs_inode_t *cdp; /* inode of created dir */ | ||
2126 | xfs_trans_t *tp; | ||
2127 | int cancel_flags; | ||
2128 | int error; | ||
2129 | int committed; | ||
2130 | xfs_bmap_free_t free_list; | ||
2131 | xfs_fsblock_t first_block; | ||
2132 | boolean_t unlock_dp_on_error = B_FALSE; | ||
2133 | boolean_t created = B_FALSE; | ||
2134 | int dm_event_sent = 0; | ||
2135 | xfs_prid_t prid; | ||
2136 | struct xfs_dquot *udqp, *gdqp; | ||
2137 | uint resblks; | ||
2138 | |||
2139 | if (XFS_FORCED_SHUTDOWN(mp)) | ||
2140 | return XFS_ERROR(EIO); | ||
2141 | |||
2142 | tp = NULL; | ||
2143 | |||
2144 | if (DM_EVENT_ENABLED(dp, DM_EVENT_CREATE)) { | ||
2145 | error = XFS_SEND_NAMESP(mp, DM_EVENT_CREATE, | ||
2146 | dp, DM_RIGHT_NULL, NULL, | ||
2147 | DM_RIGHT_NULL, dir_name->name, NULL, | ||
2148 | mode, 0, 0); | ||
2149 | if (error) | ||
2150 | return error; | ||
2151 | dm_event_sent = 1; | ||
2152 | } | ||
2153 | |||
2154 | /* Return through std_return after this point. */ | ||
2155 | |||
2156 | xfs_itrace_entry(dp); | ||
2157 | |||
2158 | mp = dp->i_mount; | ||
2159 | udqp = gdqp = NULL; | ||
2160 | if (dp->i_d.di_flags & XFS_DIFLAG_PROJINHERIT) | ||
2161 | prid = dp->i_d.di_projid; | ||
2162 | else | ||
2163 | prid = (xfs_prid_t)dfltprid; | ||
2164 | |||
2165 | /* | ||
2166 | * Make sure that we have allocated dquot(s) on disk. | ||
2167 | */ | ||
2168 | error = XFS_QM_DQVOPALLOC(mp, dp, | ||
2169 | current_fsuid(), current_fsgid(), prid, | ||
2170 | XFS_QMOPT_QUOTALL | XFS_QMOPT_INHERIT, &udqp, &gdqp); | ||
2171 | if (error) | ||
2172 | goto std_return; | ||
2173 | |||
2174 | tp = xfs_trans_alloc(mp, XFS_TRANS_MKDIR); | ||
2175 | cancel_flags = XFS_TRANS_RELEASE_LOG_RES; | ||
2176 | resblks = XFS_MKDIR_SPACE_RES(mp, dir_name->len); | ||
2177 | error = xfs_trans_reserve(tp, resblks, XFS_MKDIR_LOG_RES(mp), 0, | ||
2178 | XFS_TRANS_PERM_LOG_RES, XFS_MKDIR_LOG_COUNT); | ||
2179 | if (error == ENOSPC) { | ||
2180 | resblks = 0; | ||
2181 | error = xfs_trans_reserve(tp, 0, XFS_MKDIR_LOG_RES(mp), 0, | ||
2182 | XFS_TRANS_PERM_LOG_RES, | ||
2183 | XFS_MKDIR_LOG_COUNT); | ||
2184 | } | ||
2185 | if (error) { | ||
2186 | cancel_flags = 0; | ||
2187 | goto error_return; | ||
2188 | } | ||
2189 | |||
2190 | xfs_ilock(dp, XFS_ILOCK_EXCL | XFS_ILOCK_PARENT); | ||
2191 | unlock_dp_on_error = B_TRUE; | ||
2192 | |||
2193 | /* | ||
2194 | * Check for directory link count overflow. | ||
2195 | */ | ||
2196 | if (dp->i_d.di_nlink >= XFS_MAXLINK) { | ||
2197 | error = XFS_ERROR(EMLINK); | ||
2198 | goto error_return; | ||
2199 | } | ||
2200 | |||
2201 | /* | ||
2202 | * Reserve disk quota and the inode. | ||
2203 | */ | ||
2204 | error = XFS_TRANS_RESERVE_QUOTA(mp, tp, udqp, gdqp, resblks, 1, 0); | ||
2205 | if (error) | ||
2206 | goto error_return; | ||
2207 | |||
2208 | error = xfs_dir_canenter(tp, dp, dir_name, resblks); | ||
2209 | if (error) | ||
2210 | goto error_return; | ||
2211 | /* | ||
2212 | * create the directory inode. | ||
2213 | */ | ||
2214 | error = xfs_dir_ialloc(&tp, dp, mode, 2, | ||
2215 | 0, credp, prid, resblks > 0, | ||
2216 | &cdp, NULL); | ||
2217 | if (error) { | ||
2218 | if (error == ENOSPC) | ||
2219 | goto error_return; | ||
2220 | goto abort_return; | ||
2221 | } | ||
2222 | xfs_itrace_ref(cdp); | ||
2223 | |||
2224 | /* | ||
2225 | * Now we add the directory inode to the transaction. | ||
2226 | * We waited until now since xfs_dir_ialloc might start | ||
2227 | * a new transaction. Had we joined the transaction | ||
2228 | * earlier, the locks might have gotten released. An error | ||
2229 | * from here on will result in the transaction cancel | ||
2230 | * unlocking dp so don't do it explicitly in the error path. | ||
2231 | */ | ||
2232 | IHOLD(dp); | ||
2233 | xfs_trans_ijoin(tp, dp, XFS_ILOCK_EXCL); | ||
2234 | unlock_dp_on_error = B_FALSE; | ||
2235 | |||
2236 | xfs_bmap_init(&free_list, &first_block); | ||
2237 | |||
2238 | error = xfs_dir_createname(tp, dp, dir_name, cdp->i_ino, | ||
2239 | &first_block, &free_list, resblks ? | ||
2240 | resblks - XFS_IALLOC_SPACE_RES(mp) : 0); | ||
2241 | if (error) { | ||
2242 | ASSERT(error != ENOSPC); | ||
2243 | goto error1; | ||
2244 | } | ||
2245 | xfs_ichgtime(dp, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG); | ||
2246 | |||
2247 | error = xfs_dir_init(tp, cdp, dp); | ||
2248 | if (error) | ||
2249 | goto error2; | ||
2250 | |||
2251 | error = xfs_bumplink(tp, dp); | ||
2252 | if (error) | ||
2253 | goto error2; | ||
2254 | |||
2255 | created = B_TRUE; | ||
2256 | |||
2257 | *ipp = cdp; | ||
2258 | IHOLD(cdp); | ||
2259 | |||
2260 | /* | ||
2261 | * Attach the dquots to the new inode and modify the icount incore. | ||
2262 | */ | ||
2263 | XFS_QM_DQVOPCREATE(mp, tp, cdp, udqp, gdqp); | ||
2264 | |||
2265 | /* | ||
2266 | * If this is a synchronous mount, make sure that the | ||
2267 | * mkdir transaction goes to disk before returning to | ||
2268 | * the user. | ||
2269 | */ | ||
2270 | if (mp->m_flags & (XFS_MOUNT_WSYNC|XFS_MOUNT_DIRSYNC)) { | ||
2271 | xfs_trans_set_sync(tp); | ||
2272 | } | ||
2273 | |||
2274 | error = xfs_bmap_finish(&tp, &free_list, &committed); | ||
2275 | if (error) { | ||
2276 | IRELE(cdp); | ||
2277 | goto error2; | ||
2278 | } | ||
2279 | |||
2280 | error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES); | ||
2281 | XFS_QM_DQRELE(mp, udqp); | ||
2282 | XFS_QM_DQRELE(mp, gdqp); | ||
2283 | if (error) { | ||
2284 | IRELE(cdp); | ||
2285 | } | ||
2286 | |||
2287 | /* Fall through to std_return with error = 0 or errno from | ||
2288 | * xfs_trans_commit. */ | ||
2289 | |||
2290 | std_return: | ||
2291 | if ((created || (error != 0 && dm_event_sent != 0)) && | ||
2292 | DM_EVENT_ENABLED(dp, DM_EVENT_POSTCREATE)) { | ||
2293 | (void) XFS_SEND_NAMESP(mp, DM_EVENT_POSTCREATE, | ||
2294 | dp, DM_RIGHT_NULL, | ||
2295 | created ? cdp : NULL, | ||
2296 | DM_RIGHT_NULL, | ||
2297 | dir_name->name, NULL, | ||
2298 | mode, error, 0); | ||
2299 | } | ||
2300 | return error; | ||
2301 | |||
2302 | error2: | ||
2303 | error1: | ||
2304 | xfs_bmap_cancel(&free_list); | ||
2305 | abort_return: | ||
2306 | cancel_flags |= XFS_TRANS_ABORT; | ||
2307 | error_return: | ||
2308 | xfs_trans_cancel(tp, cancel_flags); | ||
2309 | XFS_QM_DQRELE(mp, udqp); | ||
2310 | XFS_QM_DQRELE(mp, gdqp); | ||
2311 | |||
2312 | if (unlock_dp_on_error) | ||
2313 | xfs_iunlock(dp, XFS_ILOCK_EXCL); | ||
2314 | |||
2315 | goto std_return; | ||
2316 | } | ||
2317 | |||
2318 | int | 2133 | int |
2319 | xfs_symlink( | 2134 | xfs_symlink( |
2320 | xfs_inode_t *dp, | 2135 | xfs_inode_t *dp, |
diff --git a/fs/xfs/xfs_vnodeops.h b/fs/xfs/xfs_vnodeops.h index 2258df3fae84..04373c6c61ff 100644 --- a/fs/xfs/xfs_vnodeops.h +++ b/fs/xfs/xfs_vnodeops.h | |||
@@ -31,8 +31,6 @@ 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, |