History

Merge tag 'xfs-6.10-fixes-1' of git://git.kernel.org/pub/scm/fs/xfs/xfs-linux

Pull xfs fixes from Chandan Babu: - Fix a livelock by dropping an xfarray sortinfo folio when an error is encountered - During extended attribute operations, Initialize transaction reservation computation based on attribute operation code - Relax symbolic link's ondisk verification code to allow symbolic links with short remote targets - Prevent soft lockups when unmapping file ranges and also during remapping blocks during a reflink operation - Fix compilation warnings when XFS is built with W=1 option * tag 'xfs-6.10-fixes-1' of git://git.kernel.org/pub/scm/fs/xfs/xfs-linux: xfs: Add cond_resched to block unmap range and reflink remap path xfs: don't open-code u64_to_user_ptr xfs: allow symlinks with short remote targets xfs: fix xfs_init_attr_trans not handling explicit operation codes xfs: drop xfarray sortinfo folio on error xfs: Stop using __maybe_unused in xfs_alloc.c xfs: Clear W=1 warning in xfs_iwalk_run_callbacks()

Linus Torvalds committed 2 years ago

Commit bbeb1212 parents f26ee67 b0c6bcd11 files · +73 −46Browse files

Unified · Split

11 files
  1. fs/xfs/libxfs/xfs_alloc.c +2 −4
  2. fs/xfs/libxfs/xfs_attr.c +19 −21
  3. fs/xfs/libxfs/xfs_attr.h +1 −2
  4. fs/xfs/libxfs/xfs_bmap.c +1 −0
  5. fs/xfs/libxfs/xfs_inode_buf.c +24 −4
  6. fs/xfs/scrub/scrub.c +1 −1
  7. fs/xfs/scrub/xfarray.c +6 −3
  8. fs/xfs/xfs_attr_item.c +15 −2
  9. fs/xfs/xfs_handle.c +1 −6
  10. fs/xfs/xfs_iwalk.c +2 −3
  11. fs/xfs/xfs_reflink.c +1 −0
fs/xfs/libxfs/xfs_alloc.c+2−4
@@ -1008,13 +1008,12 @@ xfs_alloc_cur_finish( · 1007 unmodified lines
1008 struct xfs_alloc_arg *args,1008 struct xfs_alloc_arg *args,
1009 struct xfs_alloc_cur *acur)1009 struct xfs_alloc_cur *acur)
1010{1010{
1011 struct xfs_agf __maybe_unused *agf = args->agbp->b_addr;
1012 int error;1011 int error;
1013 1012
1014 ASSERT(acur->cnt && acur->bnolt);1013 ASSERT(acur->cnt && acur->bnolt);
1015 ASSERT(acur->bno >= acur->rec_bno);1014 ASSERT(acur->bno >= acur->rec_bno);
1016 ASSERT(acur->bno + acur->len <= acur->rec_bno + acur->rec_len);1015 ASSERT(acur->bno + acur->len <= acur->rec_bno + acur->rec_len);
1017 ASSERT(acur->rec_bno + acur->rec_len <= be32_to_cpu(agf->agf_length));1016 ASSERT(xfs_verify_agbext(args->pag, acur->rec_bno, acur->rec_len));
1018 1017
1019 error = xfs_alloc_fixup_trees(acur->cnt, acur->bnolt, acur->rec_bno,1018 error = xfs_alloc_fixup_trees(acur->cnt, acur->bnolt, acur->rec_bno,
1020 acur->rec_len, acur->bno, acur->len, 0);1019 acur->rec_len, acur->bno, acur->len, 0);
@@ -1217,7 +1216,6 @@ STATIC int /* error */ · 196 unmodified lines
1217xfs_alloc_ag_vextent_exact(1216xfs_alloc_ag_vextent_exact(
1218 xfs_alloc_arg_t *args) /* allocation argument structure */1217 xfs_alloc_arg_t *args) /* allocation argument structure */
1219{1218{
1220 struct xfs_agf __maybe_unused *agf = args->agbp->b_addr;
1221 struct xfs_btree_cur *bno_cur;/* by block-number btree cursor */1219 struct xfs_btree_cur *bno_cur;/* by block-number btree cursor */
1222 struct xfs_btree_cur *cnt_cur;/* by count btree cursor */1220 struct xfs_btree_cur *cnt_cur;/* by count btree cursor */
1223 int error;1221 int error;
@@ -1297,7 +1295,7 @@ xfs_alloc_ag_vextent_exact( · 73 unmodified lines
1297 */1295 */
1298 cnt_cur = xfs_cntbt_init_cursor(args->mp, args->tp, args->agbp,1296 cnt_cur = xfs_cntbt_init_cursor(args->mp, args->tp, args->agbp,
1299 args->pag);1297 args->pag);
1300 ASSERT(args->agbno + args->len <= be32_to_cpu(agf->agf_length));1298 ASSERT(xfs_verify_agbext(args->pag, args->agbno, args->len));
1301 error = xfs_alloc_fixup_trees(cnt_cur, bno_cur, fbno, flen, args->agbno,1299 error = xfs_alloc_fixup_trees(cnt_cur, bno_cur, fbno, flen, args->agbno,
1302 args->len, XFSA_FIXUP_BNO_OK);1300 args->len, XFSA_FIXUP_BNO_OK);
1303 if (error) {1301 if (error) {
fs/xfs/libxfs/xfs_attr.c+19−21
@@ -329,26 +329,20 @@ xfs_attr_calc_size( · 328 unmodified lines
329 return nblks;329 return nblks;
330}330}
331 331
332/* Initialize transaction reservation for attr operations */332/* Initialize transaction reservation for an xattr set/replace/upsert */
333void333inline struct xfs_trans_res
334xfs_init_attr_trans(334xfs_attr_set_resv(
335 struct xfs_da_args *args,335 const struct xfs_da_args *args)
336 struct xfs_trans_res *tres,
337 unsigned int *total)
338{336{
339 struct xfs_mount *mp = args->dp->i_mount;337 struct xfs_mount *mp = args->dp->i_mount;
340 338 struct xfs_trans_res ret = {
341 if (args->value) {339 .tr_logres = M_RES(mp)->tr_attrsetm.tr_logres +
342 tres->tr_logres = M_RES(mp)->tr_attrsetm.tr_logres +340 M_RES(mp)->tr_attrsetrt.tr_logres * args->total,
343 M_RES(mp)->tr_attrsetrt.tr_logres *341 .tr_logcount = XFS_ATTRSET_LOG_COUNT,
344 args->total;342 .tr_logflags = XFS_TRANS_PERM_LOG_RES,
345 tres->tr_logcount = XFS_ATTRSET_LOG_COUNT;343 };
346 tres->tr_logflags = XFS_TRANS_PERM_LOG_RES;344
347 *total = args->total;345 return ret;
348 } else {
349 *tres = M_RES(mp)->tr_attrrm;
350 *total = XFS_ATTRRM_SPACE_RES(mp);
351 }
352}346}
353 347
354/*348/*
@@ -1006,7 +1000,7 @@ xfs_attr_set( · 651 unmodified lines
1006 struct xfs_trans_res tres;1000 struct xfs_trans_res tres;
1007 int error, local;1001 int error, local;
1008 int rmt_blks = 0;1002 int rmt_blks = 0;
1009 unsigned int total;1003 unsigned int total = 0;
1010 1004
1011 ASSERT(!args->trans);1005 ASSERT(!args->trans);
1012 1006
@@ -1033,10 +1027,15 @@ xfs_attr_set( · 20 unmodified lines
1033 1027
1034 if (!local)1028 if (!local)
1035 rmt_blks = xfs_attr3_rmt_blocks(mp, args->valuelen);1029 rmt_blks = xfs_attr3_rmt_blocks(mp, args->valuelen);
1030
1031 tres = xfs_attr_set_resv(args);
1032 total = args->total;
1036 break;1033 break;
1037 case XFS_ATTRUPDATE_REMOVE:1034 case XFS_ATTRUPDATE_REMOVE:
1038 XFS_STATS_INC(mp, xs_attr_remove);1035 XFS_STATS_INC(mp, xs_attr_remove);
1039 rmt_blks = xfs_attr3_max_rmt_blocks(mp);1036 rmt_blks = xfs_attr3_max_rmt_blocks(mp);
1037 tres = M_RES(mp)->tr_attrrm;
1038 total = XFS_ATTRRM_SPACE_RES(mp);
1040 break;1039 break;
1041 }1040 }
1042 1041
@@ -1044,7 +1043,6 @@ xfs_attr_set( · 1 unmodified line
1044 * Root fork attributes can use reserved data blocks for this1043 * Root fork attributes can use reserved data blocks for this
1045 * operation if necessary1044 * operation if necessary
1046 */1045 */
1047 xfs_init_attr_trans(args, &tres, &total);
1048 error = xfs_trans_alloc_inode(dp, &tres, total, 0, rsvd, &args->trans);1046 error = xfs_trans_alloc_inode(dp, &tres, total, 0, rsvd, &args->trans);
1049 if (error)1047 if (error)
1050 return error;1048 return error;
fs/xfs/libxfs/xfs_attr.h+1−2
@@ -565,8 +565,7 @@ bool xfs_attr_check_namespace(unsigned int attr_flags); · 564 unmodified lines
565bool xfs_attr_namecheck(unsigned int attr_flags, const void *name,565bool xfs_attr_namecheck(unsigned int attr_flags, const void *name,
566 size_t length);566 size_t length);
567int xfs_attr_calc_size(struct xfs_da_args *args, int *local);567int xfs_attr_calc_size(struct xfs_da_args *args, int *local);
568void xfs_init_attr_trans(struct xfs_da_args *args, struct xfs_trans_res *tres,568struct xfs_trans_res xfs_attr_set_resv(const struct xfs_da_args *args);
569 unsigned int *total);
570 569
571/*570/*
572 * Check to see if the attr should be upgraded from non-existent or shortform to571 * Check to see if the attr should be upgraded from non-existent or shortform to
fs/xfs/libxfs/xfs_bmap.c+1−0
@@ -6383,6 +6383,7 @@ xfs_bunmapi_range( · 6382 unmodified lines
6383 error = xfs_defer_finish(tpp);6383 error = xfs_defer_finish(tpp);
6384 if (error)6384 if (error)
6385 goto out;6385 goto out;
6386 cond_resched();
6386 }6387 }
6387out:6388out:
6388 return error;6389 return error;
fs/xfs/libxfs/xfs_inode_buf.c+24−4
@@ -374,17 +374,37 @@ xfs_dinode_verify_fork( · 373 unmodified lines
374 /*374 /*
375 * For fork types that can contain local data, check that the fork375 * For fork types that can contain local data, check that the fork
376 * format matches the size of local data contained within the fork.376 * format matches the size of local data contained within the fork.
377 *
378 * For all types, check that when the size says the should be in extent
379 * or btree format, the inode isn't claiming it is in local format.
380 */377 */
381 if (whichfork == XFS_DATA_FORK) {378 if (whichfork == XFS_DATA_FORK) {
382 if (S_ISDIR(mode) || S_ISLNK(mode)) {379 /*
380 * A directory small enough to fit in the inode must be stored
381 * in local format. The directory sf <-> extents conversion
382 * code updates the directory size accordingly.
383 */
384 if (S_ISDIR(mode)) {
385 if (be64_to_cpu(dip->di_size) <= fork_size &&
386 fork_format != XFS_DINODE_FMT_LOCAL)
387 return __this_address;
388 }
389
390 /*
391 * A symlink with a target small enough to fit in the inode can
392 * be stored in extents format if xattrs were added (thus
393 * converting the data fork from shortform to remote format)
394 * and then removed.
395 */
396 if (S_ISLNK(mode)) {
383 if (be64_to_cpu(dip->di_size) <= fork_size &&397 if (be64_to_cpu(dip->di_size) <= fork_size &&
398 fork_format != XFS_DINODE_FMT_EXTENTS &&
384 fork_format != XFS_DINODE_FMT_LOCAL)399 fork_format != XFS_DINODE_FMT_LOCAL)
385 return __this_address;400 return __this_address;
386 }401 }
387 402
403 /*
404 * For all types, check that when the size says the fork should
405 * be in extent or btree format, the inode isn't claiming to be
406 * in local format.
407 */
388 if (be64_to_cpu(dip->di_size) > fork_size &&408 if (be64_to_cpu(dip->di_size) > fork_size &&
389 fork_format == XFS_DINODE_FMT_LOCAL)409 fork_format == XFS_DINODE_FMT_LOCAL)
390 return __this_address;410 return __this_address;
fs/xfs/scrub/scrub.c+1−1
@@ -856,7 +856,7 @@ xfs_ioc_scrubv_metadata( · 855 unmodified lines
856 if (vec_bytes > PAGE_SIZE)856 if (vec_bytes > PAGE_SIZE)
857 return -ENOMEM;857 return -ENOMEM;
858 858
859 uvectors = (void __user *)(uintptr_t)head.svh_vectors;859 uvectors = u64_to_user_ptr(head.svh_vectors);
860 vectors = memdup_user(uvectors, vec_bytes);860 vectors = memdup_user(uvectors, vec_bytes);
861 if (IS_ERR(vectors))861 if (IS_ERR(vectors))
862 return PTR_ERR(vectors);862 return PTR_ERR(vectors);
fs/xfs/scrub/xfarray.c+6−3
@@ -822,12 +822,14 @@ xfarray_sort_scan( · 821 unmodified lines
822 822
823 /* Grab the first folio that backs this array element. */823 /* Grab the first folio that backs this array element. */
824 if (!si->folio) {824 if (!si->folio) {
825 struct folio *folio;
825 loff_t next_pos;826 loff_t next_pos;
826 827
827 si->folio = xfile_get_folio(si->array->xfile, idx_pos,828 folio = xfile_get_folio(si->array->xfile, idx_pos,
828 si->array->obj_size, XFILE_ALLOC);829 si->array->obj_size, XFILE_ALLOC);
829 if (IS_ERR(si->folio))830 if (IS_ERR(folio))
830 return PTR_ERR(si->folio);831 return PTR_ERR(folio);
832 si->folio = folio;
831 833
832 si->first_folio_idx = xfarray_idx(si->array,834 si->first_folio_idx = xfarray_idx(si->array,
833 folio_pos(si->folio) + si->array->obj_size - 1);835 folio_pos(si->folio) + si->array->obj_size - 1);
@@ -1048,6 +1050,7 @@ xfarray_sort( · 214 unmodified lines
1048 1050
1049out_free:1051out_free:
1050 trace_xfarray_sort_stats(si, error);1052 trace_xfarray_sort_stats(si, error);
1053 xfarray_sort_scan_done(si);
1051 kvfree(si);1054 kvfree(si);
1052 return error;1055 return error;
1053}1056}
fs/xfs/xfs_attr_item.c+15−2
@@ -746,7 +746,7 @@ xfs_attr_recover_work( · 745 unmodified lines
746 struct xfs_attri_log_format *attrp;746 struct xfs_attri_log_format *attrp;
747 struct xfs_attri_log_nameval *nv = attrip->attri_nameval;747 struct xfs_attri_log_nameval *nv = attrip->attri_nameval;
748 int error;748 int error;
749 int total;749 unsigned int total = 0;
750 750
751 /*751 /*
752 * First check the validity of the attr described by the ATTRI. If any752 * First check the validity of the attr described by the ATTRI. If any
@@ -763,7 +763,20 @@ xfs_attr_recover_work( · 10 unmodified lines
763 return PTR_ERR(attr);763 return PTR_ERR(attr);
764 args = attr->xattri_da_args;764 args = attr->xattri_da_args;
765 765
766 xfs_init_attr_trans(args, &resv, &total);766 switch (xfs_attr_intent_op(attr)) {
767 case XFS_ATTRI_OP_FLAGS_PPTR_SET:
768 case XFS_ATTRI_OP_FLAGS_PPTR_REPLACE:
769 case XFS_ATTRI_OP_FLAGS_SET:
770 case XFS_ATTRI_OP_FLAGS_REPLACE:
771 resv = xfs_attr_set_resv(args);
772 total = args->total;
773 break;
774 case XFS_ATTRI_OP_FLAGS_PPTR_REMOVE:
775 case XFS_ATTRI_OP_FLAGS_REMOVE:
776 resv = M_RES(mp)->tr_attrrm;
777 total = XFS_ATTRRM_SPACE_RES(mp);
778 break;
779 }
767 resv = xlog_recover_resv(&resv);780 resv = xlog_recover_resv(&resv);
768 error = xfs_trans_alloc(mp, &resv, total, 0, XFS_TRANS_RESERVE, &tp);781 error = xfs_trans_alloc(mp, &resv, total, 0, XFS_TRANS_RESERVE, &tp);
769 if (error)782 if (error)
fs/xfs/xfs_handle.c+1−6
@@ -773,11 +773,6 @@ xfs_getparents_expand_lastrec( · 772 unmodified lines
773 trace_xfs_getparents_expand_lastrec(gpx->ip, gp, &gpx->context, gpr);773 trace_xfs_getparents_expand_lastrec(gpx->ip, gp, &gpx->context, gpr);
774}774}
775 775
776static inline void __user *u64_to_uptr(u64 val)
777{
778 return (void __user *)(uintptr_t)val;
779}
780
781/* Retrieve the parent pointers for a given inode. */776/* Retrieve the parent pointers for a given inode. */
782STATIC int777STATIC int
783xfs_getparents(778xfs_getparents(
@@ -862,7 +857,7 @@ xfs_getparents( · 78 unmodified lines
862 ASSERT(gpx->context.firstu <= gpx->gph.gph_request.gp_bufsize);857 ASSERT(gpx->context.firstu <= gpx->gph.gph_request.gp_bufsize);
863 858
864 /* Copy the records to userspace. */859 /* Copy the records to userspace. */
865 if (copy_to_user(u64_to_uptr(gpx->gph.gph_request.gp_buffer),860 if (copy_to_user(u64_to_user_ptr(gpx->gph.gph_request.gp_buffer),
866 gpx->krecords, gpx->context.firstu))861 gpx->krecords, gpx->context.firstu))
867 error = -EFAULT;862 error = -EFAULT;
868 863
fs/xfs/xfs_iwalk.c+2−3
@@ -351,7 +351,6 @@ xfs_iwalk_run_callbacks( · 350 unmodified lines
351 int *has_more)351 int *has_more)
352{352{
353 struct xfs_mount *mp = iwag->mp;353 struct xfs_mount *mp = iwag->mp;
354 struct xfs_inobt_rec_incore *irec;
355 xfs_agino_t next_agino;354 xfs_agino_t next_agino;
356 int error;355 int error;
357 356
@@ -361,8 +360,8 @@ xfs_iwalk_run_callbacks( · 3 unmodified lines
361 360
362 /* Delete cursor but remember the last record we cached... */361 /* Delete cursor but remember the last record we cached... */
363 xfs_iwalk_del_inobt(iwag->tp, curpp, agi_bpp, 0);362 xfs_iwalk_del_inobt(iwag->tp, curpp, agi_bpp, 0);
364 irec = &iwag->recs[iwag->nr_recs - 1];363 ASSERT(next_agino >= iwag->recs[iwag->nr_recs - 1].ir_startino +
365 ASSERT(next_agino >= irec->ir_startino + XFS_INODES_PER_CHUNK);364 XFS_INODES_PER_CHUNK);
366 365
367 if (iwag->drop_trans) {366 if (iwag->drop_trans) {
368 xfs_trans_cancel(iwag->tp);367 xfs_trans_cancel(iwag->tp);
fs/xfs/xfs_reflink.c+1−0
@@ -1387,6 +1387,7 @@ xfs_reflink_remap_blocks( · 1386 unmodified lines
1387 destoff += imap.br_blockcount;1387 destoff += imap.br_blockcount;
1388 len -= imap.br_blockcount;1388 len -= imap.br_blockcount;
1389 remapped_len += imap.br_blockcount;1389 remapped_len += imap.br_blockcount;
1390 cond_resched();
1390 }1391 }
1391 1392
1392 if (error)1393 if (error)