aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/xfs_attr.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/xfs/xfs_attr.c')
-rw-r--r--fs/xfs/xfs_attr.c110
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 */
200int
201xfs_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
197STATIC int 237STATIC int
198xfs_attr_set_int(xfs_inode_t *dp, struct xfs_name *name, 238xfs_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);