Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

xfs: factor out a xfs_update_prealloc_flags() helper

This logic is duplicated in xfs_file_fallocate and xfs_ioc_space, and
we'll need another copy of it for pNFS block support.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Dave Chinner <dchinner@redhat.com>
Signed-off-by: Dave Chinner <david@fromorbit.com>

authored by

Christoph Hellwig and committed by
Dave Chinner
8add71ca 4d949021

+63 -60
+42 -22
fs/xfs/xfs_file.c
··· 127 127 return (-status); 128 128 } 129 129 130 + int 131 + xfs_update_prealloc_flags( 132 + struct xfs_inode *ip, 133 + enum xfs_prealloc_flags flags) 134 + { 135 + struct xfs_trans *tp; 136 + int error; 137 + 138 + tp = xfs_trans_alloc(ip->i_mount, XFS_TRANS_WRITEID); 139 + error = xfs_trans_reserve(tp, &M_RES(ip->i_mount)->tr_writeid, 0, 0); 140 + if (error) { 141 + xfs_trans_cancel(tp, 0); 142 + return error; 143 + } 144 + 145 + xfs_ilock(ip, XFS_ILOCK_EXCL); 146 + xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL); 147 + 148 + if (!(flags & XFS_PREALLOC_INVISIBLE)) { 149 + ip->i_d.di_mode &= ~S_ISUID; 150 + if (ip->i_d.di_mode & S_IXGRP) 151 + ip->i_d.di_mode &= ~S_ISGID; 152 + xfs_trans_ichgtime(tp, ip, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG); 153 + } 154 + 155 + if (flags & XFS_PREALLOC_SET) 156 + ip->i_d.di_flags |= XFS_DIFLAG_PREALLOC; 157 + if (flags & XFS_PREALLOC_CLEAR) 158 + ip->i_d.di_flags &= ~XFS_DIFLAG_PREALLOC; 159 + 160 + xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); 161 + if (flags & XFS_PREALLOC_SYNC) 162 + xfs_trans_set_sync(tp); 163 + return xfs_trans_commit(tp, 0); 164 + } 165 + 130 166 /* 131 167 * Fsync operations on directories are much simpler than on regular files, 132 168 * as there is no file data to flush, and thus also no need for explicit ··· 820 784 { 821 785 struct inode *inode = file_inode(file); 822 786 struct xfs_inode *ip = XFS_I(inode); 823 - struct xfs_trans *tp; 824 787 long error; 788 + enum xfs_prealloc_flags flags = 0; 825 789 loff_t new_size = 0; 826 790 827 791 if (!S_ISREG(inode->i_mode)) ··· 858 822 if (error) 859 823 goto out_unlock; 860 824 } else { 825 + flags |= XFS_PREALLOC_SET; 826 + 861 827 if (!(mode & FALLOC_FL_KEEP_SIZE) && 862 828 offset + len > i_size_read(inode)) { 863 829 new_size = offset + len; ··· 877 839 goto out_unlock; 878 840 } 879 841 880 - tp = xfs_trans_alloc(ip->i_mount, XFS_TRANS_WRITEID); 881 - error = xfs_trans_reserve(tp, &M_RES(ip->i_mount)->tr_writeid, 0, 0); 882 - if (error) { 883 - xfs_trans_cancel(tp, 0); 884 - goto out_unlock; 885 - } 886 - 887 - xfs_ilock(ip, XFS_ILOCK_EXCL); 888 - xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL); 889 - ip->i_d.di_mode &= ~S_ISUID; 890 - if (ip->i_d.di_mode & S_IXGRP) 891 - ip->i_d.di_mode &= ~S_ISGID; 892 - 893 - if (!(mode & (FALLOC_FL_PUNCH_HOLE | FALLOC_FL_COLLAPSE_RANGE))) 894 - ip->i_d.di_flags |= XFS_DIFLAG_PREALLOC; 895 - 896 - xfs_trans_ichgtime(tp, ip, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG); 897 - xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); 898 - 899 842 if (file->f_flags & O_DSYNC) 900 - xfs_trans_set_sync(tp); 901 - error = xfs_trans_commit(tp, 0); 843 + flags |= XFS_PREALLOC_SYNC; 844 + 845 + error = xfs_update_prealloc_flags(ip, flags); 902 846 if (error) 903 847 goto out_unlock; 904 848
+9
fs/xfs/xfs_inode.h
··· 377 377 int xfs_bumplink(struct xfs_trans *, struct xfs_inode *); 378 378 379 379 /* from xfs_file.c */ 380 + enum xfs_prealloc_flags { 381 + XFS_PREALLOC_SET = (1 << 1), 382 + XFS_PREALLOC_CLEAR = (1 << 2), 383 + XFS_PREALLOC_SYNC = (1 << 3), 384 + XFS_PREALLOC_INVISIBLE = (1 << 4), 385 + }; 386 + 387 + int xfs_update_prealloc_flags(struct xfs_inode *, 388 + enum xfs_prealloc_flags); 380 389 int xfs_zero_eof(struct xfs_inode *, xfs_off_t, xfs_fsize_t); 381 390 int xfs_iozero(struct xfs_inode *, loff_t, size_t); 382 391
+12 -38
fs/xfs/xfs_ioctl.c
··· 606 606 unsigned int cmd, 607 607 xfs_flock64_t *bf) 608 608 { 609 - struct xfs_mount *mp = ip->i_mount; 610 - struct xfs_trans *tp; 611 609 struct iattr iattr; 612 - bool setprealloc = false; 613 - bool clrprealloc = false; 610 + enum xfs_prealloc_flags flags = 0; 614 611 int error; 615 612 616 613 /* ··· 626 629 627 630 if (!S_ISREG(inode->i_mode)) 628 631 return -EINVAL; 632 + 633 + if (filp->f_flags & O_DSYNC) 634 + flags |= XFS_PREALLOC_SYNC; 635 + if (ioflags & XFS_IO_INVIS) 636 + flags |= XFS_PREALLOC_INVISIBLE; 629 637 630 638 error = mnt_want_write_file(filp); 631 639 if (error) ··· 675 673 } 676 674 677 675 if (bf->l_start < 0 || 678 - bf->l_start > mp->m_super->s_maxbytes || 676 + bf->l_start > inode->i_sb->s_maxbytes || 679 677 bf->l_start + bf->l_len < 0 || 680 - bf->l_start + bf->l_len >= mp->m_super->s_maxbytes) { 678 + bf->l_start + bf->l_len >= inode->i_sb->s_maxbytes) { 681 679 error = -EINVAL; 682 680 goto out_unlock; 683 681 } 684 682 685 683 switch (cmd) { 686 684 case XFS_IOC_ZERO_RANGE: 685 + flags |= XFS_PREALLOC_SET; 687 686 error = xfs_zero_file_space(ip, bf->l_start, bf->l_len); 688 - if (!error) 689 - setprealloc = true; 690 687 break; 691 688 case XFS_IOC_RESVSP: 692 689 case XFS_IOC_RESVSP64: 690 + flags |= XFS_PREALLOC_SET; 693 691 error = xfs_alloc_file_space(ip, bf->l_start, bf->l_len, 694 692 XFS_BMAPI_PREALLOC); 695 - if (!error) 696 - setprealloc = true; 697 693 break; 698 694 case XFS_IOC_UNRESVSP: 699 695 case XFS_IOC_UNRESVSP64: ··· 701 701 case XFS_IOC_ALLOCSP64: 702 702 case XFS_IOC_FREESP: 703 703 case XFS_IOC_FREESP64: 704 + flags |= XFS_PREALLOC_CLEAR; 704 705 if (bf->l_start > XFS_ISIZE(ip)) { 705 706 error = xfs_alloc_file_space(ip, XFS_ISIZE(ip), 706 707 bf->l_start - XFS_ISIZE(ip), 0); ··· 713 712 iattr.ia_size = bf->l_start; 714 713 715 714 error = xfs_setattr_size(ip, &iattr); 716 - if (!error) 717 - clrprealloc = true; 718 715 break; 719 716 default: 720 717 ASSERT(0); ··· 722 723 if (error) 723 724 goto out_unlock; 724 725 725 - tp = xfs_trans_alloc(mp, XFS_TRANS_WRITEID); 726 - error = xfs_trans_reserve(tp, &M_RES(mp)->tr_writeid, 0, 0); 727 - if (error) { 728 - xfs_trans_cancel(tp, 0); 729 - goto out_unlock; 730 - } 731 - 732 - xfs_ilock(ip, XFS_ILOCK_EXCL); 733 - xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL); 734 - 735 - if (!(ioflags & XFS_IO_INVIS)) { 736 - ip->i_d.di_mode &= ~S_ISUID; 737 - if (ip->i_d.di_mode & S_IXGRP) 738 - ip->i_d.di_mode &= ~S_ISGID; 739 - xfs_trans_ichgtime(tp, ip, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG); 740 - } 741 - 742 - if (setprealloc) 743 - ip->i_d.di_flags |= XFS_DIFLAG_PREALLOC; 744 - else if (clrprealloc) 745 - ip->i_d.di_flags &= ~XFS_DIFLAG_PREALLOC; 746 - 747 - xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); 748 - if (filp->f_flags & O_DSYNC) 749 - xfs_trans_set_sync(tp); 750 - error = xfs_trans_commit(tp, 0); 726 + error = xfs_update_prealloc_flags(ip, flags); 751 727 752 728 out_unlock: 753 729 xfs_iunlock(ip, XFS_IOLOCK_EXCL);