aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/xfs_attr_remote.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/xfs/xfs_attr_remote.c')
-rw-r--r--fs/xfs/xfs_attr_remote.c37
1 files changed, 18 insertions, 19 deletions
diff --git a/fs/xfs/xfs_attr_remote.c b/fs/xfs/xfs_attr_remote.c
index bcdc07c4e8f4..e207bf0004b6 100644
--- a/fs/xfs/xfs_attr_remote.c
+++ b/fs/xfs/xfs_attr_remote.c
@@ -296,10 +296,7 @@ xfs_attr_rmtval_set(
296 * and we may not need that many, so we have to handle this when 296 * and we may not need that many, so we have to handle this when
297 * allocating the blocks below. 297 * allocating the blocks below.
298 */ 298 */
299 if (!crcs) 299 blkcnt = xfs_attr3_rmt_blocks(mp, args->valuelen);
300 blkcnt = XFS_B_TO_FSB(mp, args->valuelen);
301 else
302 blkcnt = xfs_attr3_rmt_blocks(mp, args->valuelen);
303 300
304 error = xfs_bmap_first_unused(args->trans, args->dp, blkcnt, &lfileoff, 301 error = xfs_bmap_first_unused(args->trans, args->dp, blkcnt, &lfileoff,
305 XFS_ATTR_FORK); 302 XFS_ATTR_FORK);
@@ -394,8 +391,11 @@ xfs_attr_rmtval_set(
394 */ 391 */
395 lblkno = args->rmtblkno; 392 lblkno = args->rmtblkno;
396 valuelen = args->valuelen; 393 valuelen = args->valuelen;
394 blkcnt = args->rmtblkcnt;
397 while (valuelen > 0) { 395 while (valuelen > 0) {
398 int byte_cnt; 396 int byte_cnt;
397 int hdr_size;
398 int dblkcnt;
399 char *buf; 399 char *buf;
400 400
401 /* 401 /*
@@ -404,7 +404,7 @@ xfs_attr_rmtval_set(
404 xfs_bmap_init(args->flist, args->firstblock); 404 xfs_bmap_init(args->flist, args->firstblock);
405 nmap = 1; 405 nmap = 1;
406 error = xfs_bmapi_read(dp, (xfs_fileoff_t)lblkno, 406 error = xfs_bmapi_read(dp, (xfs_fileoff_t)lblkno,
407 args->rmtblkcnt, &map, &nmap, 407 blkcnt, &map, &nmap,
408 XFS_BMAPI_ATTRFORK); 408 XFS_BMAPI_ATTRFORK);
409 if (error) 409 if (error)
410 return(error); 410 return(error);
@@ -413,26 +413,25 @@ xfs_attr_rmtval_set(
413 (map.br_startblock != HOLESTARTBLOCK)); 413 (map.br_startblock != HOLESTARTBLOCK));
414 414
415 dblkno = XFS_FSB_TO_DADDR(mp, map.br_startblock), 415 dblkno = XFS_FSB_TO_DADDR(mp, map.br_startblock),
416 blkcnt = XFS_FSB_TO_BB(mp, map.br_blockcount); 416 dblkcnt = XFS_FSB_TO_BB(mp, map.br_blockcount);
417 417
418 bp = xfs_buf_get(mp->m_ddev_targp, dblkno, blkcnt, 0); 418 bp = xfs_buf_get(mp->m_ddev_targp, dblkno, dblkcnt, 0);
419 if (!bp) 419 if (!bp)
420 return ENOMEM; 420 return ENOMEM;
421 bp->b_ops = &xfs_attr3_rmt_buf_ops; 421 bp->b_ops = &xfs_attr3_rmt_buf_ops;
422
423 byte_cnt = BBTOB(bp->b_length);
424 byte_cnt = XFS_ATTR3_RMT_BUF_SPACE(mp, byte_cnt);
425 if (valuelen < byte_cnt)
426 byte_cnt = valuelen;
427
428 buf = bp->b_addr; 422 buf = bp->b_addr;
429 buf += xfs_attr3_rmt_hdr_set(mp, dp->i_ino, offset, 423
424 byte_cnt = XFS_ATTR3_RMT_BUF_SPACE(mp, BBTOB(bp->b_length));
425 byte_cnt = min_t(int, valuelen, byte_cnt);
426 hdr_size = xfs_attr3_rmt_hdr_set(mp, dp->i_ino, offset,
430 byte_cnt, bp); 427 byte_cnt, bp);
431 memcpy(buf, src, byte_cnt); 428 ASSERT(hdr_size + byte_cnt <= BBTOB(bp->b_length));
432 429
433 if (byte_cnt < BBTOB(bp->b_length)) 430 memcpy(buf + hdr_size, src, byte_cnt);
434 xfs_buf_zero(bp, byte_cnt, 431
435 BBTOB(bp->b_length) - byte_cnt); 432 if (byte_cnt + hdr_size < BBTOB(bp->b_length))
433 xfs_buf_zero(bp, byte_cnt + hdr_size,
434 BBTOB(bp->b_length) - byte_cnt - hdr_size);
436 435
437 error = xfs_bwrite(bp); /* GROT: NOTE: synchronous write */ 436 error = xfs_bwrite(bp); /* GROT: NOTE: synchronous write */
438 xfs_buf_relse(bp); 437 xfs_buf_relse(bp);
@@ -442,9 +441,9 @@ xfs_attr_rmtval_set(
442 src += byte_cnt; 441 src += byte_cnt;
443 valuelen -= byte_cnt; 442 valuelen -= byte_cnt;
444 offset += byte_cnt; 443 offset += byte_cnt;
445 hdrcnt--;
446 444
447 lblkno += map.br_blockcount; 445 lblkno += map.br_blockcount;
446 blkcnt -= map.br_blockcount;
448 } 447 }
449 ASSERT(valuelen == 0); 448 ASSERT(valuelen == 0);
450 return 0; 449 return 0;