diff options
author | Dave Chinner <david@fromorbit.com> | 2014-03-13 04:14:43 -0400 |
---|---|---|
committer | Dave Chinner <david@fromorbit.com> | 2014-03-13 04:14:43 -0400 |
commit | fe986f9d88ab8079c91669b7f175081f15491a80 (patch) | |
tree | 73be54e2c5378750dee0ebc0720af5143d2c4dc6 | |
parent | 5f44e4c185ec5a4a438841cbd4983d0c4a106a4a (diff) | |
parent | ab29743117f9f4c22ac44c13c1647fb24fb2bafe (diff) |
Merge branch 'xfs-O_TMPFILE-support' into for-next
Conflicts:
fs/xfs/xfs_trans_resv.c
- fix for XFS_INODE_CLUSTER_SIZE macro removal
-rw-r--r-- | fs/xfs/xfs_inode.c | 123 | ||||
-rw-r--r-- | fs/xfs/xfs_inode.h | 12 | ||||
-rw-r--r-- | fs/xfs/xfs_iops.c | 16 | ||||
-rw-r--r-- | fs/xfs/xfs_shared.h | 4 | ||||
-rw-r--r-- | fs/xfs/xfs_symlink.c | 5 | ||||
-rw-r--r-- | fs/xfs/xfs_trans_resv.c | 54 | ||||
-rw-r--r-- | fs/xfs/xfs_trans_resv.h | 2 |
7 files changed, 201 insertions, 15 deletions
diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c index 3a137e9f9a7d..5e7a38fa6ee6 100644 --- a/fs/xfs/xfs_inode.c +++ b/fs/xfs/xfs_inode.c | |||
@@ -42,7 +42,6 @@ | |||
42 | #include "xfs_bmap_util.h" | 42 | #include "xfs_bmap_util.h" |
43 | #include "xfs_error.h" | 43 | #include "xfs_error.h" |
44 | #include "xfs_quota.h" | 44 | #include "xfs_quota.h" |
45 | #include "xfs_dinode.h" | ||
46 | #include "xfs_filestream.h" | 45 | #include "xfs_filestream.h" |
47 | #include "xfs_cksum.h" | 46 | #include "xfs_cksum.h" |
48 | #include "xfs_trace.h" | 47 | #include "xfs_trace.h" |
@@ -62,6 +61,8 @@ kmem_zone_t *xfs_inode_zone; | |||
62 | 61 | ||
63 | STATIC int xfs_iflush_int(xfs_inode_t *, xfs_buf_t *); | 62 | STATIC int xfs_iflush_int(xfs_inode_t *, xfs_buf_t *); |
64 | 63 | ||
64 | STATIC int xfs_iunlink_remove(xfs_trans_t *, xfs_inode_t *); | ||
65 | |||
65 | /* | 66 | /* |
66 | * helper function to extract extent size hint from inode | 67 | * helper function to extract extent size hint from inode |
67 | */ | 68 | */ |
@@ -1115,7 +1116,7 @@ xfs_bumplink( | |||
1115 | { | 1116 | { |
1116 | xfs_trans_ichgtime(tp, ip, XFS_ICHGTIME_CHG); | 1117 | xfs_trans_ichgtime(tp, ip, XFS_ICHGTIME_CHG); |
1117 | 1118 | ||
1118 | ASSERT(ip->i_d.di_nlink > 0); | 1119 | ASSERT(ip->i_d.di_nlink > 0 || (VFS_I(ip)->i_state & I_LINKABLE)); |
1119 | ip->i_d.di_nlink++; | 1120 | ip->i_d.di_nlink++; |
1120 | inc_nlink(VFS_I(ip)); | 1121 | inc_nlink(VFS_I(ip)); |
1121 | if ((ip->i_d.di_version == 1) && | 1122 | if ((ip->i_d.di_version == 1) && |
@@ -1165,10 +1166,7 @@ xfs_create( | |||
1165 | if (XFS_FORCED_SHUTDOWN(mp)) | 1166 | if (XFS_FORCED_SHUTDOWN(mp)) |
1166 | return XFS_ERROR(EIO); | 1167 | return XFS_ERROR(EIO); |
1167 | 1168 | ||
1168 | if (dp->i_d.di_flags & XFS_DIFLAG_PROJINHERIT) | 1169 | prid = xfs_get_initial_prid(dp); |
1169 | prid = xfs_get_projid(dp); | ||
1170 | else | ||
1171 | prid = XFS_PROJID_DEFAULT; | ||
1172 | 1170 | ||
1173 | /* | 1171 | /* |
1174 | * Make sure that we have allocated dquot(s) on disk. | 1172 | * Make sure that we have allocated dquot(s) on disk. |
@@ -1333,6 +1331,113 @@ xfs_create( | |||
1333 | } | 1331 | } |
1334 | 1332 | ||
1335 | int | 1333 | int |
1334 | xfs_create_tmpfile( | ||
1335 | struct xfs_inode *dp, | ||
1336 | struct dentry *dentry, | ||
1337 | umode_t mode) | ||
1338 | { | ||
1339 | struct xfs_mount *mp = dp->i_mount; | ||
1340 | struct xfs_inode *ip = NULL; | ||
1341 | struct xfs_trans *tp = NULL; | ||
1342 | int error; | ||
1343 | uint cancel_flags = XFS_TRANS_RELEASE_LOG_RES; | ||
1344 | prid_t prid; | ||
1345 | struct xfs_dquot *udqp = NULL; | ||
1346 | struct xfs_dquot *gdqp = NULL; | ||
1347 | struct xfs_dquot *pdqp = NULL; | ||
1348 | struct xfs_trans_res *tres; | ||
1349 | uint resblks; | ||
1350 | |||
1351 | if (XFS_FORCED_SHUTDOWN(mp)) | ||
1352 | return XFS_ERROR(EIO); | ||
1353 | |||
1354 | prid = xfs_get_initial_prid(dp); | ||
1355 | |||
1356 | /* | ||
1357 | * Make sure that we have allocated dquot(s) on disk. | ||
1358 | */ | ||
1359 | error = xfs_qm_vop_dqalloc(dp, xfs_kuid_to_uid(current_fsuid()), | ||
1360 | xfs_kgid_to_gid(current_fsgid()), prid, | ||
1361 | XFS_QMOPT_QUOTALL | XFS_QMOPT_INHERIT, | ||
1362 | &udqp, &gdqp, &pdqp); | ||
1363 | if (error) | ||
1364 | return error; | ||
1365 | |||
1366 | resblks = XFS_IALLOC_SPACE_RES(mp); | ||
1367 | tp = xfs_trans_alloc(mp, XFS_TRANS_CREATE_TMPFILE); | ||
1368 | |||
1369 | tres = &M_RES(mp)->tr_create_tmpfile; | ||
1370 | error = xfs_trans_reserve(tp, tres, resblks, 0); | ||
1371 | if (error == ENOSPC) { | ||
1372 | /* No space at all so try a "no-allocation" reservation */ | ||
1373 | resblks = 0; | ||
1374 | error = xfs_trans_reserve(tp, tres, 0, 0); | ||
1375 | } | ||
1376 | if (error) { | ||
1377 | cancel_flags = 0; | ||
1378 | goto out_trans_cancel; | ||
1379 | } | ||
1380 | |||
1381 | error = xfs_trans_reserve_quota(tp, mp, udqp, gdqp, | ||
1382 | pdqp, resblks, 1, 0); | ||
1383 | if (error) | ||
1384 | goto out_trans_cancel; | ||
1385 | |||
1386 | error = xfs_dir_ialloc(&tp, dp, mode, 1, 0, | ||
1387 | prid, resblks > 0, &ip, NULL); | ||
1388 | if (error) { | ||
1389 | if (error == ENOSPC) | ||
1390 | goto out_trans_cancel; | ||
1391 | goto out_trans_abort; | ||
1392 | } | ||
1393 | |||
1394 | if (mp->m_flags & XFS_MOUNT_WSYNC) | ||
1395 | xfs_trans_set_sync(tp); | ||
1396 | |||
1397 | /* | ||
1398 | * Attach the dquot(s) to the inodes and modify them incore. | ||
1399 | * These ids of the inode couldn't have changed since the new | ||
1400 | * inode has been locked ever since it was created. | ||
1401 | */ | ||
1402 | xfs_qm_vop_create_dqattach(tp, ip, udqp, gdqp, pdqp); | ||
1403 | |||
1404 | ip->i_d.di_nlink--; | ||
1405 | d_tmpfile(dentry, VFS_I(ip)); | ||
1406 | error = xfs_iunlink(tp, ip); | ||
1407 | if (error) | ||
1408 | goto out_trans_abort; | ||
1409 | |||
1410 | error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES); | ||
1411 | if (error) | ||
1412 | goto out_release_inode; | ||
1413 | |||
1414 | xfs_qm_dqrele(udqp); | ||
1415 | xfs_qm_dqrele(gdqp); | ||
1416 | xfs_qm_dqrele(pdqp); | ||
1417 | |||
1418 | return 0; | ||
1419 | |||
1420 | out_trans_abort: | ||
1421 | cancel_flags |= XFS_TRANS_ABORT; | ||
1422 | out_trans_cancel: | ||
1423 | xfs_trans_cancel(tp, cancel_flags); | ||
1424 | out_release_inode: | ||
1425 | /* | ||
1426 | * Wait until after the current transaction is aborted to | ||
1427 | * release the inode. This prevents recursive transactions | ||
1428 | * and deadlocks from xfs_inactive. | ||
1429 | */ | ||
1430 | if (ip) | ||
1431 | IRELE(ip); | ||
1432 | |||
1433 | xfs_qm_dqrele(udqp); | ||
1434 | xfs_qm_dqrele(gdqp); | ||
1435 | xfs_qm_dqrele(pdqp); | ||
1436 | |||
1437 | return error; | ||
1438 | } | ||
1439 | |||
1440 | int | ||
1336 | xfs_link( | 1441 | xfs_link( |
1337 | xfs_inode_t *tdp, | 1442 | xfs_inode_t *tdp, |
1338 | xfs_inode_t *sip, | 1443 | xfs_inode_t *sip, |
@@ -1397,6 +1502,12 @@ xfs_link( | |||
1397 | 1502 | ||
1398 | xfs_bmap_init(&free_list, &first_block); | 1503 | xfs_bmap_init(&free_list, &first_block); |
1399 | 1504 | ||
1505 | if (sip->i_d.di_nlink == 0) { | ||
1506 | error = xfs_iunlink_remove(tp, sip); | ||
1507 | if (error) | ||
1508 | goto abort_return; | ||
1509 | } | ||
1510 | |||
1400 | error = xfs_dir_createname(tp, tdp, target_name, sip->i_ino, | 1511 | error = xfs_dir_createname(tp, tdp, target_name, sip->i_ino, |
1401 | &first_block, &free_list, resblks); | 1512 | &first_block, &free_list, resblks); |
1402 | if (error) | 1513 | if (error) |
diff --git a/fs/xfs/xfs_inode.h b/fs/xfs/xfs_inode.h index 65e2350f449c..396cc1fafd0d 100644 --- a/fs/xfs/xfs_inode.h +++ b/fs/xfs/xfs_inode.h | |||
@@ -20,6 +20,7 @@ | |||
20 | 20 | ||
21 | #include "xfs_inode_buf.h" | 21 | #include "xfs_inode_buf.h" |
22 | #include "xfs_inode_fork.h" | 22 | #include "xfs_inode_fork.h" |
23 | #include "xfs_dinode.h" | ||
23 | 24 | ||
24 | /* | 25 | /* |
25 | * Kernel only inode definitions | 26 | * Kernel only inode definitions |
@@ -192,6 +193,15 @@ xfs_set_projid(struct xfs_inode *ip, | |||
192 | ip->i_d.di_projid_lo = (__uint16_t) (projid & 0xffff); | 193 | ip->i_d.di_projid_lo = (__uint16_t) (projid & 0xffff); |
193 | } | 194 | } |
194 | 195 | ||
196 | static inline prid_t | ||
197 | xfs_get_initial_prid(struct xfs_inode *dp) | ||
198 | { | ||
199 | if (dp->i_d.di_flags & XFS_DIFLAG_PROJINHERIT) | ||
200 | return xfs_get_projid(dp); | ||
201 | |||
202 | return XFS_PROJID_DEFAULT; | ||
203 | } | ||
204 | |||
195 | /* | 205 | /* |
196 | * In-core inode flags. | 206 | * In-core inode flags. |
197 | */ | 207 | */ |
@@ -323,6 +333,8 @@ int xfs_lookup(struct xfs_inode *dp, struct xfs_name *name, | |||
323 | struct xfs_inode **ipp, struct xfs_name *ci_name); | 333 | struct xfs_inode **ipp, struct xfs_name *ci_name); |
324 | int xfs_create(struct xfs_inode *dp, struct xfs_name *name, | 334 | int xfs_create(struct xfs_inode *dp, struct xfs_name *name, |
325 | umode_t mode, xfs_dev_t rdev, struct xfs_inode **ipp); | 335 | umode_t mode, xfs_dev_t rdev, struct xfs_inode **ipp); |
336 | int xfs_create_tmpfile(struct xfs_inode *dp, struct dentry *dentry, | ||
337 | umode_t mode); | ||
326 | int xfs_remove(struct xfs_inode *dp, struct xfs_name *name, | 338 | int xfs_remove(struct xfs_inode *dp, struct xfs_name *name, |
327 | struct xfs_inode *ip); | 339 | struct xfs_inode *ip); |
328 | int xfs_link(struct xfs_inode *tdp, struct xfs_inode *sip, | 340 | int xfs_link(struct xfs_inode *tdp, struct xfs_inode *sip, |
diff --git a/fs/xfs/xfs_iops.c b/fs/xfs/xfs_iops.c index bb3bb658e39c..89b07e43ca28 100644 --- a/fs/xfs/xfs_iops.c +++ b/fs/xfs/xfs_iops.c | |||
@@ -39,6 +39,7 @@ | |||
39 | #include "xfs_da_btree.h" | 39 | #include "xfs_da_btree.h" |
40 | #include "xfs_dir2_priv.h" | 40 | #include "xfs_dir2_priv.h" |
41 | #include "xfs_dinode.h" | 41 | #include "xfs_dinode.h" |
42 | #include "xfs_trans_space.h" | ||
42 | 43 | ||
43 | #include <linux/capability.h> | 44 | #include <linux/capability.h> |
44 | #include <linux/xattr.h> | 45 | #include <linux/xattr.h> |
@@ -1046,6 +1047,19 @@ xfs_vn_fiemap( | |||
1046 | return 0; | 1047 | return 0; |
1047 | } | 1048 | } |
1048 | 1049 | ||
1050 | STATIC int | ||
1051 | xfs_vn_tmpfile( | ||
1052 | struct inode *dir, | ||
1053 | struct dentry *dentry, | ||
1054 | umode_t mode) | ||
1055 | { | ||
1056 | int error; | ||
1057 | |||
1058 | error = xfs_create_tmpfile(XFS_I(dir), dentry, mode); | ||
1059 | |||
1060 | return -error; | ||
1061 | } | ||
1062 | |||
1049 | static const struct inode_operations xfs_inode_operations = { | 1063 | static const struct inode_operations xfs_inode_operations = { |
1050 | .get_acl = xfs_get_acl, | 1064 | .get_acl = xfs_get_acl, |
1051 | .set_acl = xfs_set_acl, | 1065 | .set_acl = xfs_set_acl, |
@@ -1084,6 +1098,7 @@ static const struct inode_operations xfs_dir_inode_operations = { | |||
1084 | .removexattr = generic_removexattr, | 1098 | .removexattr = generic_removexattr, |
1085 | .listxattr = xfs_vn_listxattr, | 1099 | .listxattr = xfs_vn_listxattr, |
1086 | .update_time = xfs_vn_update_time, | 1100 | .update_time = xfs_vn_update_time, |
1101 | .tmpfile = xfs_vn_tmpfile, | ||
1087 | }; | 1102 | }; |
1088 | 1103 | ||
1089 | static const struct inode_operations xfs_dir_ci_inode_operations = { | 1104 | static const struct inode_operations xfs_dir_ci_inode_operations = { |
@@ -1111,6 +1126,7 @@ static const struct inode_operations xfs_dir_ci_inode_operations = { | |||
1111 | .removexattr = generic_removexattr, | 1126 | .removexattr = generic_removexattr, |
1112 | .listxattr = xfs_vn_listxattr, | 1127 | .listxattr = xfs_vn_listxattr, |
1113 | .update_time = xfs_vn_update_time, | 1128 | .update_time = xfs_vn_update_time, |
1129 | .tmpfile = xfs_vn_tmpfile, | ||
1114 | }; | 1130 | }; |
1115 | 1131 | ||
1116 | static const struct inode_operations xfs_symlink_inode_operations = { | 1132 | static const struct inode_operations xfs_symlink_inode_operations = { |
diff --git a/fs/xfs/xfs_shared.h b/fs/xfs/xfs_shared.h index 8c5035a13df1..4484e5151395 100644 --- a/fs/xfs/xfs_shared.h +++ b/fs/xfs/xfs_shared.h | |||
@@ -104,7 +104,8 @@ extern const struct xfs_buf_ops xfs_symlink_buf_ops; | |||
104 | #define XFS_TRANS_SB_COUNT 41 | 104 | #define XFS_TRANS_SB_COUNT 41 |
105 | #define XFS_TRANS_CHECKPOINT 42 | 105 | #define XFS_TRANS_CHECKPOINT 42 |
106 | #define XFS_TRANS_ICREATE 43 | 106 | #define XFS_TRANS_ICREATE 43 |
107 | #define XFS_TRANS_TYPE_MAX 43 | 107 | #define XFS_TRANS_CREATE_TMPFILE 44 |
108 | #define XFS_TRANS_TYPE_MAX 44 | ||
108 | /* new transaction types need to be reflected in xfs_logprint(8) */ | 109 | /* new transaction types need to be reflected in xfs_logprint(8) */ |
109 | 110 | ||
110 | #define XFS_TRANS_TYPES \ | 111 | #define XFS_TRANS_TYPES \ |
@@ -112,6 +113,7 @@ extern const struct xfs_buf_ops xfs_symlink_buf_ops; | |||
112 | { XFS_TRANS_SETATTR_SIZE, "SETATTR_SIZE" }, \ | 113 | { XFS_TRANS_SETATTR_SIZE, "SETATTR_SIZE" }, \ |
113 | { XFS_TRANS_INACTIVE, "INACTIVE" }, \ | 114 | { XFS_TRANS_INACTIVE, "INACTIVE" }, \ |
114 | { XFS_TRANS_CREATE, "CREATE" }, \ | 115 | { XFS_TRANS_CREATE, "CREATE" }, \ |
116 | { XFS_TRANS_CREATE_TMPFILE, "CREATE_TMPFILE" }, \ | ||
115 | { XFS_TRANS_CREATE_TRUNC, "CREATE_TRUNC" }, \ | 117 | { XFS_TRANS_CREATE_TRUNC, "CREATE_TRUNC" }, \ |
116 | { XFS_TRANS_TRUNCATE_FILE, "TRUNCATE_FILE" }, \ | 118 | { XFS_TRANS_TRUNCATE_FILE, "TRUNCATE_FILE" }, \ |
117 | { XFS_TRANS_REMOVE, "REMOVE" }, \ | 119 | { XFS_TRANS_REMOVE, "REMOVE" }, \ |
diff --git a/fs/xfs/xfs_symlink.c b/fs/xfs/xfs_symlink.c index 5fda18919d3b..52979aa90986 100644 --- a/fs/xfs/xfs_symlink.c +++ b/fs/xfs/xfs_symlink.c | |||
@@ -212,10 +212,7 @@ xfs_symlink( | |||
212 | return XFS_ERROR(ENAMETOOLONG); | 212 | return XFS_ERROR(ENAMETOOLONG); |
213 | 213 | ||
214 | udqp = gdqp = NULL; | 214 | udqp = gdqp = NULL; |
215 | if (dp->i_d.di_flags & XFS_DIFLAG_PROJINHERIT) | 215 | prid = xfs_get_initial_prid(dp); |
216 | prid = xfs_get_projid(dp); | ||
217 | else | ||
218 | prid = XFS_PROJID_DEFAULT; | ||
219 | 216 | ||
220 | /* | 217 | /* |
221 | * Make sure that we have allocated dquot(s) on disk. | 218 | * Make sure that we have allocated dquot(s) on disk. |
diff --git a/fs/xfs/xfs_trans_resv.c b/fs/xfs/xfs_trans_resv.c index d2c8e4a6ee2a..ae368165244d 100644 --- a/fs/xfs/xfs_trans_resv.c +++ b/fs/xfs/xfs_trans_resv.c | |||
@@ -212,6 +212,19 @@ xfs_calc_rename_reservation( | |||
212 | } | 212 | } |
213 | 213 | ||
214 | /* | 214 | /* |
215 | * For removing an inode from unlinked list at first, we can modify: | ||
216 | * the agi hash list and counters: sector size | ||
217 | * the on disk inode before ours in the agi hash list: inode cluster size | ||
218 | */ | ||
219 | STATIC uint | ||
220 | xfs_calc_iunlink_remove_reservation( | ||
221 | struct xfs_mount *mp) | ||
222 | { | ||
223 | return xfs_calc_buf_res(1, mp->m_sb.sb_sectsize) + | ||
224 | max_t(uint, XFS_FSB_TO_B(mp, 1), mp->m_inode_cluster_size); | ||
225 | } | ||
226 | |||
227 | /* | ||
215 | * For creating a link to an inode: | 228 | * For creating a link to an inode: |
216 | * the parent directory inode: inode size | 229 | * the parent directory inode: inode size |
217 | * the linked inode: inode size | 230 | * the linked inode: inode size |
@@ -228,6 +241,7 @@ xfs_calc_link_reservation( | |||
228 | struct xfs_mount *mp) | 241 | struct xfs_mount *mp) |
229 | { | 242 | { |
230 | return XFS_DQUOT_LOGRES(mp) + | 243 | return XFS_DQUOT_LOGRES(mp) + |
244 | xfs_calc_iunlink_remove_reservation(mp) + | ||
231 | MAX((xfs_calc_inode_res(mp, 2) + | 245 | MAX((xfs_calc_inode_res(mp, 2) + |
232 | xfs_calc_buf_res(XFS_DIROP_LOG_COUNT(mp), | 246 | xfs_calc_buf_res(XFS_DIROP_LOG_COUNT(mp), |
233 | XFS_FSB_TO_B(mp, 1))), | 247 | XFS_FSB_TO_B(mp, 1))), |
@@ -237,6 +251,18 @@ xfs_calc_link_reservation( | |||
237 | } | 251 | } |
238 | 252 | ||
239 | /* | 253 | /* |
254 | * For adding an inode to unlinked list we can modify: | ||
255 | * the agi hash list: sector size | ||
256 | * the unlinked inode: inode size | ||
257 | */ | ||
258 | STATIC uint | ||
259 | xfs_calc_iunlink_add_reservation(xfs_mount_t *mp) | ||
260 | { | ||
261 | return xfs_calc_buf_res(1, mp->m_sb.sb_sectsize) + | ||
262 | xfs_calc_inode_res(mp, 1); | ||
263 | } | ||
264 | |||
265 | /* | ||
240 | * For removing a directory entry we can modify: | 266 | * For removing a directory entry we can modify: |
241 | * the parent directory inode: inode size | 267 | * the parent directory inode: inode size |
242 | * the removed inode: inode size | 268 | * the removed inode: inode size |
@@ -253,10 +279,11 @@ xfs_calc_remove_reservation( | |||
253 | struct xfs_mount *mp) | 279 | struct xfs_mount *mp) |
254 | { | 280 | { |
255 | return XFS_DQUOT_LOGRES(mp) + | 281 | return XFS_DQUOT_LOGRES(mp) + |
256 | MAX((xfs_calc_inode_res(mp, 2) + | 282 | xfs_calc_iunlink_add_reservation(mp) + |
283 | MAX((xfs_calc_inode_res(mp, 1) + | ||
257 | xfs_calc_buf_res(XFS_DIROP_LOG_COUNT(mp), | 284 | xfs_calc_buf_res(XFS_DIROP_LOG_COUNT(mp), |
258 | XFS_FSB_TO_B(mp, 1))), | 285 | XFS_FSB_TO_B(mp, 1))), |
259 | (xfs_calc_buf_res(5, mp->m_sb.sb_sectsize) + | 286 | (xfs_calc_buf_res(4, mp->m_sb.sb_sectsize) + |
260 | xfs_calc_buf_res(XFS_ALLOCFREE_LOG_COUNT(mp, 2), | 287 | xfs_calc_buf_res(XFS_ALLOCFREE_LOG_COUNT(mp, 2), |
261 | XFS_FSB_TO_B(mp, 1)))); | 288 | XFS_FSB_TO_B(mp, 1)))); |
262 | } | 289 | } |
@@ -351,6 +378,20 @@ xfs_calc_create_reservation( | |||
351 | 378 | ||
352 | } | 379 | } |
353 | 380 | ||
381 | STATIC uint | ||
382 | xfs_calc_create_tmpfile_reservation( | ||
383 | struct xfs_mount *mp) | ||
384 | { | ||
385 | uint res = XFS_DQUOT_LOGRES(mp); | ||
386 | |||
387 | if (xfs_sb_version_hascrc(&mp->m_sb)) | ||
388 | res += xfs_calc_icreate_resv_alloc(mp); | ||
389 | else | ||
390 | res += xfs_calc_create_resv_alloc(mp); | ||
391 | |||
392 | return res + xfs_calc_iunlink_add_reservation(mp); | ||
393 | } | ||
394 | |||
354 | /* | 395 | /* |
355 | * Making a new directory is the same as creating a new file. | 396 | * Making a new directory is the same as creating a new file. |
356 | */ | 397 | */ |
@@ -391,9 +432,9 @@ xfs_calc_ifree_reservation( | |||
391 | { | 432 | { |
392 | return XFS_DQUOT_LOGRES(mp) + | 433 | return XFS_DQUOT_LOGRES(mp) + |
393 | xfs_calc_inode_res(mp, 1) + | 434 | xfs_calc_inode_res(mp, 1) + |
394 | xfs_calc_buf_res(2, mp->m_sb.sb_sectsize) + | 435 | xfs_calc_buf_res(1, mp->m_sb.sb_sectsize) + |
395 | xfs_calc_buf_res(1, XFS_FSB_TO_B(mp, 1)) + | 436 | xfs_calc_buf_res(1, XFS_FSB_TO_B(mp, 1)) + |
396 | max_t(uint, XFS_FSB_TO_B(mp, 1), mp->m_inode_cluster_size) + | 437 | xfs_calc_iunlink_remove_reservation(mp) + |
397 | xfs_calc_buf_res(1, 0) + | 438 | xfs_calc_buf_res(1, 0) + |
398 | xfs_calc_buf_res(2 + mp->m_ialloc_blks + | 439 | xfs_calc_buf_res(2 + mp->m_ialloc_blks + |
399 | mp->m_in_maxlevels, 0) + | 440 | mp->m_in_maxlevels, 0) + |
@@ -736,6 +777,11 @@ xfs_trans_resv_calc( | |||
736 | resp->tr_create.tr_logcount = XFS_CREATE_LOG_COUNT; | 777 | resp->tr_create.tr_logcount = XFS_CREATE_LOG_COUNT; |
737 | resp->tr_create.tr_logflags |= XFS_TRANS_PERM_LOG_RES; | 778 | resp->tr_create.tr_logflags |= XFS_TRANS_PERM_LOG_RES; |
738 | 779 | ||
780 | resp->tr_create_tmpfile.tr_logres = | ||
781 | xfs_calc_create_tmpfile_reservation(mp); | ||
782 | resp->tr_create_tmpfile.tr_logcount = XFS_CREATE_TMPFILE_LOG_COUNT; | ||
783 | resp->tr_create_tmpfile.tr_logflags |= XFS_TRANS_PERM_LOG_RES; | ||
784 | |||
739 | resp->tr_mkdir.tr_logres = xfs_calc_mkdir_reservation(mp); | 785 | resp->tr_mkdir.tr_logres = xfs_calc_mkdir_reservation(mp); |
740 | resp->tr_mkdir.tr_logcount = XFS_MKDIR_LOG_COUNT; | 786 | resp->tr_mkdir.tr_logcount = XFS_MKDIR_LOG_COUNT; |
741 | resp->tr_mkdir.tr_logflags |= XFS_TRANS_PERM_LOG_RES; | 787 | resp->tr_mkdir.tr_logflags |= XFS_TRANS_PERM_LOG_RES; |
diff --git a/fs/xfs/xfs_trans_resv.h b/fs/xfs/xfs_trans_resv.h index f76c1297b83f..1097d14cd583 100644 --- a/fs/xfs/xfs_trans_resv.h +++ b/fs/xfs/xfs_trans_resv.h | |||
@@ -38,6 +38,7 @@ struct xfs_trans_resv { | |||
38 | struct xfs_trans_res tr_remove; /* unlink trans */ | 38 | struct xfs_trans_res tr_remove; /* unlink trans */ |
39 | struct xfs_trans_res tr_symlink; /* symlink trans */ | 39 | struct xfs_trans_res tr_symlink; /* symlink trans */ |
40 | struct xfs_trans_res tr_create; /* create trans */ | 40 | struct xfs_trans_res tr_create; /* create trans */ |
41 | struct xfs_trans_res tr_create_tmpfile; /* create O_TMPFILE trans */ | ||
41 | struct xfs_trans_res tr_mkdir; /* mkdir trans */ | 42 | struct xfs_trans_res tr_mkdir; /* mkdir trans */ |
42 | struct xfs_trans_res tr_ifree; /* inode free trans */ | 43 | struct xfs_trans_res tr_ifree; /* inode free trans */ |
43 | struct xfs_trans_res tr_ichange; /* inode update trans */ | 44 | struct xfs_trans_res tr_ichange; /* inode update trans */ |
@@ -99,6 +100,7 @@ struct xfs_trans_resv { | |||
99 | #define XFS_ITRUNCATE_LOG_COUNT 2 | 100 | #define XFS_ITRUNCATE_LOG_COUNT 2 |
100 | #define XFS_INACTIVE_LOG_COUNT 2 | 101 | #define XFS_INACTIVE_LOG_COUNT 2 |
101 | #define XFS_CREATE_LOG_COUNT 2 | 102 | #define XFS_CREATE_LOG_COUNT 2 |
103 | #define XFS_CREATE_TMPFILE_LOG_COUNT 2 | ||
102 | #define XFS_MKDIR_LOG_COUNT 3 | 104 | #define XFS_MKDIR_LOG_COUNT 3 |
103 | #define XFS_SYMLINK_LOG_COUNT 3 | 105 | #define XFS_SYMLINK_LOG_COUNT 3 |
104 | #define XFS_REMOVE_LOG_COUNT 2 | 106 | #define XFS_REMOVE_LOG_COUNT 2 |