diff options
Diffstat (limited to 'fs/xfs/xfs_attr.c')
-rw-r--r-- | fs/xfs/xfs_attr.c | 110 |
1 files changed, 68 insertions, 42 deletions
diff --git a/fs/xfs/xfs_attr.c b/fs/xfs/xfs_attr.c index 78de80e3caa2..f7cdc28aff41 100644 --- a/fs/xfs/xfs_attr.c +++ b/fs/xfs/xfs_attr.c | |||
@@ -194,6 +194,46 @@ xfs_attr_get( | |||
194 | return(error); | 194 | return(error); |
195 | } | 195 | } |
196 | 196 | ||
197 | /* | ||
198 | * Calculate how many blocks we need for the new attribute, | ||
199 | */ | ||
200 | int | ||
201 | xfs_attr_calc_size( | ||
202 | struct xfs_inode *ip, | ||
203 | int namelen, | ||
204 | int valuelen, | ||
205 | int *local) | ||
206 | { | ||
207 | struct xfs_mount *mp = ip->i_mount; | ||
208 | int size; | ||
209 | int nblks; | ||
210 | |||
211 | /* | ||
212 | * Determine space new attribute will use, and if it would be | ||
213 | * "local" or "remote" (note: local != inline). | ||
214 | */ | ||
215 | size = xfs_attr_leaf_newentsize(namelen, valuelen, | ||
216 | mp->m_sb.sb_blocksize, local); | ||
217 | |||
218 | nblks = XFS_DAENTER_SPACE_RES(mp, XFS_ATTR_FORK); | ||
219 | if (*local) { | ||
220 | if (size > (mp->m_sb.sb_blocksize >> 1)) { | ||
221 | /* Double split possible */ | ||
222 | nblks *= 2; | ||
223 | } | ||
224 | } else { | ||
225 | /* | ||
226 | * Out of line attribute, cannot double split, but | ||
227 | * make room for the attribute value itself. | ||
228 | */ | ||
229 | uint dblocks = XFS_B_TO_FSB(mp, valuelen); | ||
230 | nblks += dblocks; | ||
231 | nblks += XFS_NEXTENTADD_SPACE_RES(mp, dblocks, XFS_ATTR_FORK); | ||
232 | } | ||
233 | |||
234 | return nblks; | ||
235 | } | ||
236 | |||
197 | STATIC int | 237 | STATIC int |
198 | xfs_attr_set_int(xfs_inode_t *dp, struct xfs_name *name, | 238 | xfs_attr_set_int(xfs_inode_t *dp, struct xfs_name *name, |
199 | char *value, int valuelen, int flags) | 239 | char *value, int valuelen, int flags) |
@@ -202,10 +242,9 @@ xfs_attr_set_int(xfs_inode_t *dp, struct xfs_name *name, | |||
202 | xfs_fsblock_t firstblock; | 242 | xfs_fsblock_t firstblock; |
203 | xfs_bmap_free_t flist; | 243 | xfs_bmap_free_t flist; |
204 | int error, err2, committed; | 244 | int error, err2, committed; |
205 | int local, size; | ||
206 | uint nblks; | ||
207 | xfs_mount_t *mp = dp->i_mount; | 245 | xfs_mount_t *mp = dp->i_mount; |
208 | int rsvd = (flags & ATTR_ROOT) != 0; | 246 | int rsvd = (flags & ATTR_ROOT) != 0; |
247 | int local; | ||
209 | 248 | ||
210 | /* | 249 | /* |
211 | * Attach the dquots to the inode. | 250 | * Attach the dquots to the inode. |
@@ -241,30 +280,8 @@ xfs_attr_set_int(xfs_inode_t *dp, struct xfs_name *name, | |||
241 | args.whichfork = XFS_ATTR_FORK; | 280 | args.whichfork = XFS_ATTR_FORK; |
242 | args.op_flags = XFS_DA_OP_ADDNAME | XFS_DA_OP_OKNOENT; | 281 | args.op_flags = XFS_DA_OP_ADDNAME | XFS_DA_OP_OKNOENT; |
243 | 282 | ||
244 | /* | ||
245 | * Determine space new attribute will use, and if it would be | ||
246 | * "local" or "remote" (note: local != inline). | ||
247 | */ | ||
248 | size = xfs_attr_leaf_newentsize(name->len, valuelen, | ||
249 | mp->m_sb.sb_blocksize, &local); | ||
250 | |||
251 | nblks = XFS_DAENTER_SPACE_RES(mp, XFS_ATTR_FORK); | ||
252 | if (local) { | ||
253 | if (size > (mp->m_sb.sb_blocksize >> 1)) { | ||
254 | /* Double split possible */ | ||
255 | nblks <<= 1; | ||
256 | } | ||
257 | } else { | ||
258 | uint dblocks = XFS_B_TO_FSB(mp, valuelen); | ||
259 | /* Out of line attribute, cannot double split, but make | ||
260 | * room for the attribute value itself. | ||
261 | */ | ||
262 | nblks += dblocks; | ||
263 | nblks += XFS_NEXTENTADD_SPACE_RES(mp, dblocks, XFS_ATTR_FORK); | ||
264 | } | ||
265 | |||
266 | /* Size is now blocks for attribute data */ | 283 | /* Size is now blocks for attribute data */ |
267 | args.total = nblks; | 284 | args.total = xfs_attr_calc_size(dp, name->len, valuelen, &local); |
268 | 285 | ||
269 | /* | 286 | /* |
270 | * Start our first transaction of the day. | 287 | * Start our first transaction of the day. |
@@ -286,18 +303,17 @@ xfs_attr_set_int(xfs_inode_t *dp, struct xfs_name *name, | |||
286 | if (rsvd) | 303 | if (rsvd) |
287 | args.trans->t_flags |= XFS_TRANS_RESERVE; | 304 | args.trans->t_flags |= XFS_TRANS_RESERVE; |
288 | 305 | ||
289 | if ((error = xfs_trans_reserve(args.trans, (uint) nblks, | 306 | if ((error = xfs_trans_reserve(args.trans, args.total, |
290 | XFS_ATTRSET_LOG_RES(mp, nblks), | 307 | XFS_ATTRSET_LOG_RES(mp, args.total), 0, |
291 | 0, XFS_TRANS_PERM_LOG_RES, | 308 | XFS_TRANS_PERM_LOG_RES, XFS_ATTRSET_LOG_COUNT))) { |
292 | XFS_ATTRSET_LOG_COUNT))) { | ||
293 | xfs_trans_cancel(args.trans, 0); | 309 | xfs_trans_cancel(args.trans, 0); |
294 | return(error); | 310 | return(error); |
295 | } | 311 | } |
296 | xfs_ilock(dp, XFS_ILOCK_EXCL); | 312 | xfs_ilock(dp, XFS_ILOCK_EXCL); |
297 | 313 | ||
298 | error = XFS_TRANS_RESERVE_QUOTA_NBLKS(mp, args.trans, dp, nblks, 0, | 314 | error = XFS_TRANS_RESERVE_QUOTA_NBLKS(mp, args.trans, dp, args.total, 0, |
299 | rsvd ? XFS_QMOPT_RES_REGBLKS | XFS_QMOPT_FORCE_RES : | 315 | rsvd ? XFS_QMOPT_RES_REGBLKS | XFS_QMOPT_FORCE_RES : |
300 | XFS_QMOPT_RES_REGBLKS); | 316 | XFS_QMOPT_RES_REGBLKS); |
301 | if (error) { | 317 | if (error) { |
302 | xfs_iunlock(dp, XFS_ILOCK_EXCL); | 318 | xfs_iunlock(dp, XFS_ILOCK_EXCL); |
303 | xfs_trans_cancel(args.trans, XFS_TRANS_RELEASE_LOG_RES); | 319 | xfs_trans_cancel(args.trans, XFS_TRANS_RELEASE_LOG_RES); |
@@ -384,7 +400,9 @@ xfs_attr_set_int(xfs_inode_t *dp, struct xfs_name *name, | |||
384 | * Commit the leaf transformation. We'll need another (linked) | 400 | * Commit the leaf transformation. We'll need another (linked) |
385 | * transaction to add the new attribute to the leaf. | 401 | * transaction to add the new attribute to the leaf. |
386 | */ | 402 | */ |
387 | if ((error = xfs_attr_rolltrans(&args.trans, dp))) | 403 | |
404 | error = xfs_trans_roll(&args.trans, dp); | ||
405 | if (error) | ||
388 | goto out; | 406 | goto out; |
389 | 407 | ||
390 | } | 408 | } |
@@ -964,7 +982,8 @@ xfs_attr_leaf_addname(xfs_da_args_t *args) | |||
964 | * Commit the current trans (including the inode) and start | 982 | * Commit the current trans (including the inode) and start |
965 | * a new one. | 983 | * a new one. |
966 | */ | 984 | */ |
967 | if ((error = xfs_attr_rolltrans(&args->trans, dp))) | 985 | error = xfs_trans_roll(&args->trans, dp); |
986 | if (error) | ||
968 | return (error); | 987 | return (error); |
969 | 988 | ||
970 | /* | 989 | /* |
@@ -978,7 +997,8 @@ xfs_attr_leaf_addname(xfs_da_args_t *args) | |||
978 | * Commit the transaction that added the attr name so that | 997 | * Commit the transaction that added the attr name so that |
979 | * later routines can manage their own transactions. | 998 | * later routines can manage their own transactions. |
980 | */ | 999 | */ |
981 | if ((error = xfs_attr_rolltrans(&args->trans, dp))) | 1000 | error = xfs_trans_roll(&args->trans, dp); |
1001 | if (error) | ||
982 | return (error); | 1002 | return (error); |
983 | 1003 | ||
984 | /* | 1004 | /* |
@@ -1067,7 +1087,7 @@ xfs_attr_leaf_addname(xfs_da_args_t *args) | |||
1067 | /* | 1087 | /* |
1068 | * Commit the remove and start the next trans in series. | 1088 | * Commit the remove and start the next trans in series. |
1069 | */ | 1089 | */ |
1070 | error = xfs_attr_rolltrans(&args->trans, dp); | 1090 | error = xfs_trans_roll(&args->trans, dp); |
1071 | 1091 | ||
1072 | } else if (args->rmtblkno > 0) { | 1092 | } else if (args->rmtblkno > 0) { |
1073 | /* | 1093 | /* |
@@ -1298,7 +1318,8 @@ restart: | |||
1298 | * Commit the node conversion and start the next | 1318 | * Commit the node conversion and start the next |
1299 | * trans in the chain. | 1319 | * trans in the chain. |
1300 | */ | 1320 | */ |
1301 | if ((error = xfs_attr_rolltrans(&args->trans, dp))) | 1321 | error = xfs_trans_roll(&args->trans, dp); |
1322 | if (error) | ||
1302 | goto out; | 1323 | goto out; |
1303 | 1324 | ||
1304 | goto restart; | 1325 | goto restart; |
@@ -1349,7 +1370,8 @@ restart: | |||
1349 | * Commit the leaf addition or btree split and start the next | 1370 | * Commit the leaf addition or btree split and start the next |
1350 | * trans in the chain. | 1371 | * trans in the chain. |
1351 | */ | 1372 | */ |
1352 | if ((error = xfs_attr_rolltrans(&args->trans, dp))) | 1373 | error = xfs_trans_roll(&args->trans, dp); |
1374 | if (error) | ||
1353 | goto out; | 1375 | goto out; |
1354 | 1376 | ||
1355 | /* | 1377 | /* |
@@ -1449,7 +1471,8 @@ restart: | |||
1449 | /* | 1471 | /* |
1450 | * Commit and start the next trans in the chain. | 1472 | * Commit and start the next trans in the chain. |
1451 | */ | 1473 | */ |
1452 | if ((error = xfs_attr_rolltrans(&args->trans, dp))) | 1474 | error = xfs_trans_roll(&args->trans, dp); |
1475 | if (error) | ||
1453 | goto out; | 1476 | goto out; |
1454 | 1477 | ||
1455 | } else if (args->rmtblkno > 0) { | 1478 | } else if (args->rmtblkno > 0) { |
@@ -1581,7 +1604,8 @@ xfs_attr_node_removename(xfs_da_args_t *args) | |||
1581 | /* | 1604 | /* |
1582 | * Commit the Btree join operation and start a new trans. | 1605 | * Commit the Btree join operation and start a new trans. |
1583 | */ | 1606 | */ |
1584 | if ((error = xfs_attr_rolltrans(&args->trans, dp))) | 1607 | error = xfs_trans_roll(&args->trans, dp); |
1608 | if (error) | ||
1585 | goto out; | 1609 | goto out; |
1586 | } | 1610 | } |
1587 | 1611 | ||
@@ -2082,7 +2106,8 @@ xfs_attr_rmtval_set(xfs_da_args_t *args) | |||
2082 | /* | 2106 | /* |
2083 | * Start the next trans in the chain. | 2107 | * Start the next trans in the chain. |
2084 | */ | 2108 | */ |
2085 | if ((error = xfs_attr_rolltrans(&args->trans, dp))) | 2109 | error = xfs_trans_roll(&args->trans, dp); |
2110 | if (error) | ||
2086 | return (error); | 2111 | return (error); |
2087 | } | 2112 | } |
2088 | 2113 | ||
@@ -2232,7 +2257,8 @@ xfs_attr_rmtval_remove(xfs_da_args_t *args) | |||
2232 | /* | 2257 | /* |
2233 | * Close out trans and start the next one in the chain. | 2258 | * Close out trans and start the next one in the chain. |
2234 | */ | 2259 | */ |
2235 | if ((error = xfs_attr_rolltrans(&args->trans, args->dp))) | 2260 | error = xfs_trans_roll(&args->trans, args->dp); |
2261 | if (error) | ||
2236 | return (error); | 2262 | return (error); |
2237 | } | 2263 | } |
2238 | return(0); | 2264 | return(0); |