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

Merge git://oss.sgi.com:8090/xfs/linux-2.6

* git://oss.sgi.com:8090/xfs/linux-2.6: (45 commits)
[XFS] Fix use after free in xfs_log_done().
[XFS] Make xfs_bmap_*_count_leaves void.
[XFS] Use KM_NOFS for debug trace buffers
[XFS] use KM_MAYFAIL in xfs_mountfs
[XFS] refactor xfs_mount_free
[XFS] don't call xfs_freesb from xfs_unmountfs
[XFS] xfs_unmountfs should return void
[XFS] cleanup xfs_mountfs
[XFS] move root inode IRELE into xfs_unmountfs
[XFS] stop using file_update_time
[XFS] optimize xfs_ichgtime
[XFS] update timestamp in xfs_ialloc manually
[XFS] remove the sema_t from XFS.
[XFS] replace dquot flush semaphore with a completion
[XFS] replace inode flush semaphore with a completion
[XFS] extend completions to provide XFS object flush requirements
[XFS] replace the XFS buf iodone semaphore with a completion
[XFS] clean up stale references to semaphores
[XFS] use get_unaligned_* helpers
[XFS] Fix compile failure in xfs_buf_trace()
...

+884 -1327
-52
fs/xfs/linux-2.6/sema.h
··· 1 - /* 2 - * Copyright (c) 2000-2002,2005 Silicon Graphics, Inc. 3 - * All Rights Reserved. 4 - * 5 - * This program is free software; you can redistribute it and/or 6 - * modify it under the terms of the GNU General Public License as 7 - * published by the Free Software Foundation. 8 - * 9 - * This program is distributed in the hope that it would be useful, 10 - * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 - * GNU General Public License for more details. 13 - * 14 - * You should have received a copy of the GNU General Public License 15 - * along with this program; if not, write the Free Software Foundation, 16 - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 17 - */ 18 - #ifndef __XFS_SUPPORT_SEMA_H__ 19 - #define __XFS_SUPPORT_SEMA_H__ 20 - 21 - #include <linux/time.h> 22 - #include <linux/wait.h> 23 - #include <linux/semaphore.h> 24 - #include <asm/atomic.h> 25 - 26 - /* 27 - * sema_t structure just maps to struct semaphore in Linux kernel. 28 - */ 29 - 30 - typedef struct semaphore sema_t; 31 - 32 - #define initnsema(sp, val, name) sema_init(sp, val) 33 - #define psema(sp, b) down(sp) 34 - #define vsema(sp) up(sp) 35 - #define freesema(sema) do { } while (0) 36 - 37 - static inline int issemalocked(sema_t *sp) 38 - { 39 - return down_trylock(sp) || (up(sp), 0); 40 - } 41 - 42 - /* 43 - * Map cpsema (try to get the sema) to down_trylock. We need to switch 44 - * the return values since cpsema returns 1 (acquired) 0 (failed) and 45 - * down_trylock returns the reverse 0 (acquired) 1 (failed). 46 - */ 47 - static inline int cpsema(sema_t *sp) 48 - { 49 - return down_trylock(sp) ? 0 : 1; 50 - } 51 - 52 - #endif /* __XFS_SUPPORT_SEMA_H__ */
+1 -2
fs/xfs/linux-2.6/xfs_aops.c
··· 73 73 unsigned long pgoff) 74 74 { 75 75 xfs_inode_t *ip; 76 - bhv_vnode_t *vp = vn_from_inode(inode); 77 76 loff_t isize = i_size_read(inode); 78 77 loff_t offset = page_offset(page); 79 78 int delalloc = -1, unmapped = -1, unwritten = -1; ··· 80 81 if (page_has_buffers(page)) 81 82 xfs_count_page_state(page, &delalloc, &unmapped, &unwritten); 82 83 83 - ip = xfs_vtoi(vp); 84 + ip = XFS_I(inode); 84 85 if (!ip->i_rwtrace) 85 86 return; 86 87
+6 -10
fs/xfs/linux-2.6/xfs_buf.c
··· 58 58 bp, id, 59 59 (void *)(unsigned long)bp->b_flags, 60 60 (void *)(unsigned long)bp->b_hold.counter, 61 - (void *)(unsigned long)bp->b_sema.count.counter, 61 + (void *)(unsigned long)bp->b_sema.count, 62 62 (void *)current, 63 63 data, ra, 64 64 (void *)(unsigned long)((bp->b_file_offset>>32) & 0xffffffff), ··· 253 253 254 254 memset(bp, 0, sizeof(xfs_buf_t)); 255 255 atomic_set(&bp->b_hold, 1); 256 - init_MUTEX_LOCKED(&bp->b_iodonesema); 256 + init_completion(&bp->b_iowait); 257 257 INIT_LIST_HEAD(&bp->b_list); 258 258 INIT_LIST_HEAD(&bp->b_hash_list); 259 259 init_MUTEX_LOCKED(&bp->b_sema); /* held, no waiters */ ··· 838 838 return; 839 839 } 840 840 841 + ASSERT(atomic_read(&bp->b_hold) > 0); 841 842 if (atomic_dec_and_lock(&bp->b_hold, &hash->bh_lock)) { 842 843 if (bp->b_relse) { 843 844 atomic_inc(&bp->b_hold); ··· 852 851 spin_unlock(&hash->bh_lock); 853 852 xfs_buf_free(bp); 854 853 } 855 - } else { 856 - /* 857 - * Catch reference count leaks 858 - */ 859 - ASSERT(atomic_read(&bp->b_hold) >= 0); 860 854 } 861 855 } 862 856 ··· 1033 1037 xfs_buf_iodone_work(&bp->b_iodone_work); 1034 1038 } 1035 1039 } else { 1036 - up(&bp->b_iodonesema); 1040 + complete(&bp->b_iowait); 1037 1041 } 1038 1042 } 1039 1043 ··· 1271 1275 XB_TRACE(bp, "iowait", 0); 1272 1276 if (atomic_read(&bp->b_io_remaining)) 1273 1277 blk_run_address_space(bp->b_target->bt_mapping); 1274 - down(&bp->b_iodonesema); 1278 + wait_for_completion(&bp->b_iowait); 1275 1279 XB_TRACE(bp, "iowaited", (long)bp->b_error); 1276 1280 return bp->b_error; 1277 1281 } ··· 1795 1799 xfs_buf_init(void) 1796 1800 { 1797 1801 #ifdef XFS_BUF_TRACE 1798 - xfs_buf_trace_buf = ktrace_alloc(XFS_BUF_TRACE_SIZE, KM_SLEEP); 1802 + xfs_buf_trace_buf = ktrace_alloc(XFS_BUF_TRACE_SIZE, KM_NOFS); 1799 1803 #endif 1800 1804 1801 1805 xfs_buf_zone = kmem_zone_init_flags(sizeof(xfs_buf_t), "xfs_buf",
+2 -2
fs/xfs/linux-2.6/xfs_buf.h
··· 157 157 xfs_buf_iodone_t b_iodone; /* I/O completion function */ 158 158 xfs_buf_relse_t b_relse; /* releasing function */ 159 159 xfs_buf_bdstrat_t b_strat; /* pre-write function */ 160 - struct semaphore b_iodonesema; /* Semaphore for I/O waiters */ 160 + struct completion b_iowait; /* queue for I/O waiters */ 161 161 void *b_fspriv; 162 162 void *b_fspriv2; 163 163 void *b_fspriv3; ··· 352 352 #define XFS_BUF_CPSEMA(bp) (xfs_buf_cond_lock(bp) == 0) 353 353 #define XFS_BUF_VSEMA(bp) xfs_buf_unlock(bp) 354 354 #define XFS_BUF_PSEMA(bp,x) xfs_buf_lock(bp) 355 - #define XFS_BUF_V_IODONESEMA(bp) up(&bp->b_iodonesema); 355 + #define XFS_BUF_FINISH_IOWAIT(bp) complete(&bp->b_iowait); 356 356 357 357 #define XFS_BUF_SET_TARGET(bp, target) ((bp)->b_target = (target)) 358 358 #define XFS_BUF_TARGET(bp) ((bp)->b_target)
+5 -5
fs/xfs/linux-2.6/xfs_export.c
··· 139 139 } 140 140 141 141 xfs_iunlock(ip, XFS_ILOCK_SHARED); 142 - return ip->i_vnode; 142 + return VFS_I(ip); 143 143 } 144 144 145 145 STATIC struct dentry * ··· 167 167 if (!inode) 168 168 return NULL; 169 169 if (IS_ERR(inode)) 170 - return ERR_PTR(PTR_ERR(inode)); 170 + return ERR_CAST(inode); 171 171 result = d_alloc_anon(inode); 172 172 if (!result) { 173 173 iput(inode); ··· 198 198 if (!inode) 199 199 return NULL; 200 200 if (IS_ERR(inode)) 201 - return ERR_PTR(PTR_ERR(inode)); 201 + return ERR_CAST(inode); 202 202 result = d_alloc_anon(inode); 203 203 if (!result) { 204 204 iput(inode); ··· 219 219 if (unlikely(error)) 220 220 return ERR_PTR(-error); 221 221 222 - parent = d_alloc_anon(cip->i_vnode); 222 + parent = d_alloc_anon(VFS_I(cip)); 223 223 if (unlikely(!parent)) { 224 - iput(cip->i_vnode); 224 + iput(VFS_I(cip)); 225 225 return ERR_PTR(-ENOMEM); 226 226 } 227 227 return parent;
+3 -3
fs/xfs/linux-2.6/xfs_fs_subr.c
··· 31 31 xfs_off_t last, 32 32 int fiopt) 33 33 { 34 - struct address_space *mapping = ip->i_vnode->i_mapping; 34 + struct address_space *mapping = VFS_I(ip)->i_mapping; 35 35 36 36 if (mapping->nrpages) 37 37 truncate_inode_pages(mapping, first); ··· 44 44 xfs_off_t last, 45 45 int fiopt) 46 46 { 47 - struct address_space *mapping = ip->i_vnode->i_mapping; 47 + struct address_space *mapping = VFS_I(ip)->i_mapping; 48 48 int ret = 0; 49 49 50 50 if (mapping->nrpages) { ··· 64 64 uint64_t flags, 65 65 int fiopt) 66 66 { 67 - struct address_space *mapping = ip->i_vnode->i_mapping; 67 + struct address_space *mapping = VFS_I(ip)->i_mapping; 68 68 int ret = 0; 69 69 int ret2; 70 70
+2 -2
fs/xfs/linux-2.6/xfs_ioctl.c
··· 245 245 246 246 xfs_iunlock(ip, XFS_ILOCK_SHARED); 247 247 248 - *inode = XFS_ITOV(ip); 248 + *inode = VFS_I(ip); 249 249 return 0; 250 250 } 251 251 ··· 927 927 xfs_diflags_to_linux( 928 928 struct xfs_inode *ip) 929 929 { 930 - struct inode *inode = XFS_ITOV(ip); 930 + struct inode *inode = VFS_I(ip); 931 931 unsigned int xflags = xfs_ip2xflags(ip); 932 932 933 933 if (xflags & XFS_XFLAG_IMMUTABLE)
+119 -73
fs/xfs/linux-2.6/xfs_iops.c
··· 62 62 xfs_synchronize_atime( 63 63 xfs_inode_t *ip) 64 64 { 65 - struct inode *inode = ip->i_vnode; 65 + struct inode *inode = VFS_I(ip); 66 66 67 67 if (inode) { 68 68 ip->i_d.di_atime.t_sec = (__int32_t)inode->i_atime.tv_sec; ··· 79 79 xfs_mark_inode_dirty_sync( 80 80 xfs_inode_t *ip) 81 81 { 82 - struct inode *inode = ip->i_vnode; 82 + struct inode *inode = VFS_I(ip); 83 83 84 84 if (inode) 85 85 mark_inode_dirty_sync(inode); ··· 89 89 * Change the requested timestamp in the given inode. 90 90 * We don't lock across timestamp updates, and we don't log them but 91 91 * we do record the fact that there is dirty information in core. 92 - * 93 - * NOTE -- callers MUST combine XFS_ICHGTIME_MOD or XFS_ICHGTIME_CHG 94 - * with XFS_ICHGTIME_ACC to be sure that access time 95 - * update will take. Calling first with XFS_ICHGTIME_ACC 96 - * and then XFS_ICHGTIME_MOD may fail to modify the access 97 - * timestamp if the filesystem is mounted noacctm. 98 92 */ 99 93 void 100 94 xfs_ichgtime( 101 95 xfs_inode_t *ip, 102 96 int flags) 103 97 { 104 - struct inode *inode = vn_to_inode(XFS_ITOV(ip)); 98 + struct inode *inode = VFS_I(ip); 105 99 timespec_t tv; 100 + int sync_it = 0; 106 101 107 - nanotime(&tv); 108 - if (flags & XFS_ICHGTIME_MOD) { 102 + tv = current_fs_time(inode->i_sb); 103 + 104 + if ((flags & XFS_ICHGTIME_MOD) && 105 + !timespec_equal(&inode->i_mtime, &tv)) { 109 106 inode->i_mtime = tv; 110 107 ip->i_d.di_mtime.t_sec = (__int32_t)tv.tv_sec; 111 108 ip->i_d.di_mtime.t_nsec = (__int32_t)tv.tv_nsec; 109 + sync_it = 1; 112 110 } 113 - if (flags & XFS_ICHGTIME_ACC) { 114 - inode->i_atime = tv; 115 - ip->i_d.di_atime.t_sec = (__int32_t)tv.tv_sec; 116 - ip->i_d.di_atime.t_nsec = (__int32_t)tv.tv_nsec; 117 - } 118 - if (flags & XFS_ICHGTIME_CHG) { 111 + if ((flags & XFS_ICHGTIME_CHG) && 112 + !timespec_equal(&inode->i_ctime, &tv)) { 119 113 inode->i_ctime = tv; 120 114 ip->i_d.di_ctime.t_sec = (__int32_t)tv.tv_sec; 121 115 ip->i_d.di_ctime.t_nsec = (__int32_t)tv.tv_nsec; 116 + sync_it = 1; 122 117 } 123 118 124 119 /* ··· 125 130 * ensure that the compiler does not reorder the update 126 131 * of i_update_core above the timestamp updates above. 127 132 */ 128 - SYNCHRONIZE(); 129 - ip->i_update_core = 1; 130 - if (!(inode->i_state & I_NEW)) 133 + if (sync_it) { 134 + SYNCHRONIZE(); 135 + ip->i_update_core = 1; 131 136 mark_inode_dirty_sync(inode); 132 - } 133 - 134 - /* 135 - * Variant on the above which avoids querying the system clock 136 - * in situations where we know the Linux inode timestamps have 137 - * just been updated (and so we can update our inode cheaply). 138 - */ 139 - void 140 - xfs_ichgtime_fast( 141 - xfs_inode_t *ip, 142 - struct inode *inode, 143 - int flags) 144 - { 145 - timespec_t *tvp; 146 - 147 - /* 148 - * Atime updates for read() & friends are handled lazily now, and 149 - * explicit updates must go through xfs_ichgtime() 150 - */ 151 - ASSERT((flags & XFS_ICHGTIME_ACC) == 0); 152 - 153 - if (flags & XFS_ICHGTIME_MOD) { 154 - tvp = &inode->i_mtime; 155 - ip->i_d.di_mtime.t_sec = (__int32_t)tvp->tv_sec; 156 - ip->i_d.di_mtime.t_nsec = (__int32_t)tvp->tv_nsec; 157 137 } 158 - if (flags & XFS_ICHGTIME_CHG) { 159 - tvp = &inode->i_ctime; 160 - ip->i_d.di_ctime.t_sec = (__int32_t)tvp->tv_sec; 161 - ip->i_d.di_ctime.t_nsec = (__int32_t)tvp->tv_nsec; 162 - } 163 - 164 - /* 165 - * We update the i_update_core field _after_ changing 166 - * the timestamps in order to coordinate properly with 167 - * xfs_iflush() so that we don't lose timestamp updates. 168 - * This keeps us from having to hold the inode lock 169 - * while doing this. We use the SYNCHRONIZE macro to 170 - * ensure that the compiler does not reorder the update 171 - * of i_update_core above the timestamp updates above. 172 - */ 173 - SYNCHRONIZE(); 174 - ip->i_update_core = 1; 175 - if (!(inode->i_state & I_NEW)) 176 - mark_inode_dirty_sync(inode); 177 138 } 178 139 179 140 /* ··· 250 299 if (unlikely(error)) 251 300 goto out_free_acl; 252 301 253 - inode = ip->i_vnode; 302 + inode = VFS_I(ip); 254 303 255 304 error = xfs_init_security(inode, dir); 256 305 if (unlikely(error)) ··· 317 366 return NULL; 318 367 } 319 368 320 - return d_splice_alias(cip->i_vnode, dentry); 369 + return d_splice_alias(VFS_I(cip), dentry); 321 370 } 322 371 323 372 STATIC struct dentry * ··· 350 399 351 400 /* if exact match, just splice and exit */ 352 401 if (!ci_name.name) 353 - return d_splice_alias(ip->i_vnode, dentry); 402 + return d_splice_alias(VFS_I(ip), dentry); 354 403 355 404 /* else case-insensitive match... */ 356 405 dname.name = ci_name.name; 357 406 dname.len = ci_name.len; 358 - dentry = d_add_ci(ip->i_vnode, dentry, &dname); 407 + dentry = d_add_ci(VFS_I(ip), dentry, &dname); 359 408 kmem_free(ci_name.name); 360 409 return dentry; 361 410 } ··· 429 478 if (unlikely(error)) 430 479 goto out; 431 480 432 - inode = cip->i_vnode; 481 + inode = VFS_I(cip); 433 482 434 483 error = xfs_init_security(inode, dir); 435 484 if (unlikely(error)) ··· 661 710 return error; 662 711 } 663 712 664 - const struct inode_operations xfs_inode_operations = { 713 + static const struct inode_operations xfs_inode_operations = { 665 714 .permission = xfs_vn_permission, 666 715 .truncate = xfs_vn_truncate, 667 716 .getattr = xfs_vn_getattr, ··· 673 722 .fallocate = xfs_vn_fallocate, 674 723 }; 675 724 676 - const struct inode_operations xfs_dir_inode_operations = { 725 + static const struct inode_operations xfs_dir_inode_operations = { 677 726 .create = xfs_vn_create, 678 727 .lookup = xfs_vn_lookup, 679 728 .link = xfs_vn_link, ··· 698 747 .listxattr = xfs_vn_listxattr, 699 748 }; 700 749 701 - const struct inode_operations xfs_dir_ci_inode_operations = { 750 + static const struct inode_operations xfs_dir_ci_inode_operations = { 702 751 .create = xfs_vn_create, 703 752 .lookup = xfs_vn_ci_lookup, 704 753 .link = xfs_vn_link, ··· 723 772 .listxattr = xfs_vn_listxattr, 724 773 }; 725 774 726 - const struct inode_operations xfs_symlink_inode_operations = { 775 + static const struct inode_operations xfs_symlink_inode_operations = { 727 776 .readlink = generic_readlink, 728 777 .follow_link = xfs_vn_follow_link, 729 778 .put_link = xfs_vn_put_link, ··· 735 784 .removexattr = generic_removexattr, 736 785 .listxattr = xfs_vn_listxattr, 737 786 }; 787 + 788 + STATIC void 789 + xfs_diflags_to_iflags( 790 + struct inode *inode, 791 + struct xfs_inode *ip) 792 + { 793 + if (ip->i_d.di_flags & XFS_DIFLAG_IMMUTABLE) 794 + inode->i_flags |= S_IMMUTABLE; 795 + else 796 + inode->i_flags &= ~S_IMMUTABLE; 797 + if (ip->i_d.di_flags & XFS_DIFLAG_APPEND) 798 + inode->i_flags |= S_APPEND; 799 + else 800 + inode->i_flags &= ~S_APPEND; 801 + if (ip->i_d.di_flags & XFS_DIFLAG_SYNC) 802 + inode->i_flags |= S_SYNC; 803 + else 804 + inode->i_flags &= ~S_SYNC; 805 + if (ip->i_d.di_flags & XFS_DIFLAG_NOATIME) 806 + inode->i_flags |= S_NOATIME; 807 + else 808 + inode->i_flags &= ~S_NOATIME; 809 + } 810 + 811 + /* 812 + * Initialize the Linux inode, set up the operation vectors and 813 + * unlock the inode. 814 + * 815 + * When reading existing inodes from disk this is called directly 816 + * from xfs_iget, when creating a new inode it is called from 817 + * xfs_ialloc after setting up the inode. 818 + */ 819 + void 820 + xfs_setup_inode( 821 + struct xfs_inode *ip) 822 + { 823 + struct inode *inode = ip->i_vnode; 824 + 825 + inode->i_mode = ip->i_d.di_mode; 826 + inode->i_nlink = ip->i_d.di_nlink; 827 + inode->i_uid = ip->i_d.di_uid; 828 + inode->i_gid = ip->i_d.di_gid; 829 + 830 + switch (inode->i_mode & S_IFMT) { 831 + case S_IFBLK: 832 + case S_IFCHR: 833 + inode->i_rdev = 834 + MKDEV(sysv_major(ip->i_df.if_u2.if_rdev) & 0x1ff, 835 + sysv_minor(ip->i_df.if_u2.if_rdev)); 836 + break; 837 + default: 838 + inode->i_rdev = 0; 839 + break; 840 + } 841 + 842 + inode->i_generation = ip->i_d.di_gen; 843 + i_size_write(inode, ip->i_d.di_size); 844 + inode->i_atime.tv_sec = ip->i_d.di_atime.t_sec; 845 + inode->i_atime.tv_nsec = ip->i_d.di_atime.t_nsec; 846 + inode->i_mtime.tv_sec = ip->i_d.di_mtime.t_sec; 847 + inode->i_mtime.tv_nsec = ip->i_d.di_mtime.t_nsec; 848 + inode->i_ctime.tv_sec = ip->i_d.di_ctime.t_sec; 849 + inode->i_ctime.tv_nsec = ip->i_d.di_ctime.t_nsec; 850 + xfs_diflags_to_iflags(inode, ip); 851 + xfs_iflags_clear(ip, XFS_IMODIFIED); 852 + 853 + switch (inode->i_mode & S_IFMT) { 854 + case S_IFREG: 855 + inode->i_op = &xfs_inode_operations; 856 + inode->i_fop = &xfs_file_operations; 857 + inode->i_mapping->a_ops = &xfs_address_space_operations; 858 + break; 859 + case S_IFDIR: 860 + if (xfs_sb_version_hasasciici(&XFS_M(inode->i_sb)->m_sb)) 861 + inode->i_op = &xfs_dir_ci_inode_operations; 862 + else 863 + inode->i_op = &xfs_dir_inode_operations; 864 + inode->i_fop = &xfs_dir_file_operations; 865 + break; 866 + case S_IFLNK: 867 + inode->i_op = &xfs_symlink_inode_operations; 868 + if (!(ip->i_df.if_flags & XFS_IFINLINE)) 869 + inode->i_mapping->a_ops = &xfs_address_space_operations; 870 + break; 871 + default: 872 + inode->i_op = &xfs_inode_operations; 873 + init_special_inode(inode, inode->i_mode, inode->i_rdev); 874 + break; 875 + } 876 + 877 + xfs_iflags_clear(ip, XFS_INEW); 878 + barrier(); 879 + 880 + unlock_new_inode(inode); 881 + }
+2 -13
fs/xfs/linux-2.6/xfs_iops.h
··· 18 18 #ifndef __XFS_IOPS_H__ 19 19 #define __XFS_IOPS_H__ 20 20 21 - extern const struct inode_operations xfs_inode_operations; 22 - extern const struct inode_operations xfs_dir_inode_operations; 23 - extern const struct inode_operations xfs_dir_ci_inode_operations; 24 - extern const struct inode_operations xfs_symlink_inode_operations; 21 + struct xfs_inode; 25 22 26 23 extern const struct file_operations xfs_file_operations; 27 24 extern const struct file_operations xfs_dir_file_operations; ··· 26 29 27 30 extern ssize_t xfs_vn_listxattr(struct dentry *, char *data, size_t size); 28 31 29 - struct xfs_inode; 30 - extern void xfs_ichgtime(struct xfs_inode *, int); 31 - extern void xfs_ichgtime_fast(struct xfs_inode *, struct inode *, int); 32 - 33 - #define xfs_vtoi(vp) \ 34 - ((struct xfs_inode *)vn_to_inode(vp)->i_private) 35 - 36 - #define XFS_I(inode) \ 37 - ((struct xfs_inode *)(inode)->i_private) 32 + extern void xfs_setup_inode(struct xfs_inode *); 38 33 39 34 #endif /* __XFS_IOPS_H__ */
+2 -2
fs/xfs/linux-2.6/xfs_linux.h
··· 45 45 #include <mrlock.h> 46 46 #include <sv.h> 47 47 #include <mutex.h> 48 - #include <sema.h> 49 48 #include <time.h> 50 49 51 50 #include <support/ktrace.h> 52 51 #include <support/debug.h> 53 52 #include <support/uuid.h> 54 53 54 + #include <linux/semaphore.h> 55 55 #include <linux/mm.h> 56 56 #include <linux/kernel.h> 57 57 #include <linux/blkdev.h> ··· 180 180 #define xfs_sort(a,n,s,fn) sort(a,n,s,fn,NULL) 181 181 #define xfs_stack_trace() dump_stack() 182 182 #define xfs_itruncate_data(ip, off) \ 183 - (-vmtruncate(vn_to_inode(XFS_ITOV(ip)), (off))) 183 + (-vmtruncate(VFS_I(ip), (off))) 184 184 185 185 186 186 /* Move the kernel do_div definition off to one side */
+2 -4
fs/xfs/linux-2.6/xfs_lrw.c
··· 137 137 struct address_space *mapping; 138 138 int status; 139 139 140 - mapping = ip->i_vnode->i_mapping; 140 + mapping = VFS_I(ip)->i_mapping; 141 141 do { 142 142 unsigned offset, bytes; 143 143 void *fsdata; ··· 674 674 */ 675 675 if (likely(!(ioflags & IO_INVIS) && 676 676 !mnt_want_write(file->f_path.mnt))) { 677 - file_update_time(file); 678 - xfs_ichgtime_fast(xip, inode, 679 - XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG); 677 + xfs_ichgtime(xip, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG); 680 678 mnt_drop_write(file->f_path.mnt); 681 679 } 682 680
+50 -139
fs/xfs/linux-2.6/xfs_super.c
··· 581 581 return (((__uint64_t)pagefactor) << bitshift) - 1; 582 582 } 583 583 584 - STATIC_INLINE void 585 - xfs_set_inodeops( 586 - struct inode *inode) 587 - { 588 - switch (inode->i_mode & S_IFMT) { 589 - case S_IFREG: 590 - inode->i_op = &xfs_inode_operations; 591 - inode->i_fop = &xfs_file_operations; 592 - inode->i_mapping->a_ops = &xfs_address_space_operations; 593 - break; 594 - case S_IFDIR: 595 - if (xfs_sb_version_hasasciici(&XFS_M(inode->i_sb)->m_sb)) 596 - inode->i_op = &xfs_dir_ci_inode_operations; 597 - else 598 - inode->i_op = &xfs_dir_inode_operations; 599 - inode->i_fop = &xfs_dir_file_operations; 600 - break; 601 - case S_IFLNK: 602 - inode->i_op = &xfs_symlink_inode_operations; 603 - if (!(XFS_I(inode)->i_df.if_flags & XFS_IFINLINE)) 604 - inode->i_mapping->a_ops = &xfs_address_space_operations; 605 - break; 606 - default: 607 - inode->i_op = &xfs_inode_operations; 608 - init_special_inode(inode, inode->i_mode, inode->i_rdev); 609 - break; 610 - } 611 - } 612 - 613 - STATIC_INLINE void 614 - xfs_revalidate_inode( 615 - xfs_mount_t *mp, 616 - bhv_vnode_t *vp, 617 - xfs_inode_t *ip) 618 - { 619 - struct inode *inode = vn_to_inode(vp); 620 - 621 - inode->i_mode = ip->i_d.di_mode; 622 - inode->i_nlink = ip->i_d.di_nlink; 623 - inode->i_uid = ip->i_d.di_uid; 624 - inode->i_gid = ip->i_d.di_gid; 625 - 626 - switch (inode->i_mode & S_IFMT) { 627 - case S_IFBLK: 628 - case S_IFCHR: 629 - inode->i_rdev = 630 - MKDEV(sysv_major(ip->i_df.if_u2.if_rdev) & 0x1ff, 631 - sysv_minor(ip->i_df.if_u2.if_rdev)); 632 - break; 633 - default: 634 - inode->i_rdev = 0; 635 - break; 636 - } 637 - 638 - inode->i_generation = ip->i_d.di_gen; 639 - i_size_write(inode, ip->i_d.di_size); 640 - inode->i_atime.tv_sec = ip->i_d.di_atime.t_sec; 641 - inode->i_atime.tv_nsec = ip->i_d.di_atime.t_nsec; 642 - inode->i_mtime.tv_sec = ip->i_d.di_mtime.t_sec; 643 - inode->i_mtime.tv_nsec = ip->i_d.di_mtime.t_nsec; 644 - inode->i_ctime.tv_sec = ip->i_d.di_ctime.t_sec; 645 - inode->i_ctime.tv_nsec = ip->i_d.di_ctime.t_nsec; 646 - if (ip->i_d.di_flags & XFS_DIFLAG_IMMUTABLE) 647 - inode->i_flags |= S_IMMUTABLE; 648 - else 649 - inode->i_flags &= ~S_IMMUTABLE; 650 - if (ip->i_d.di_flags & XFS_DIFLAG_APPEND) 651 - inode->i_flags |= S_APPEND; 652 - else 653 - inode->i_flags &= ~S_APPEND; 654 - if (ip->i_d.di_flags & XFS_DIFLAG_SYNC) 655 - inode->i_flags |= S_SYNC; 656 - else 657 - inode->i_flags &= ~S_SYNC; 658 - if (ip->i_d.di_flags & XFS_DIFLAG_NOATIME) 659 - inode->i_flags |= S_NOATIME; 660 - else 661 - inode->i_flags &= ~S_NOATIME; 662 - xfs_iflags_clear(ip, XFS_IMODIFIED); 663 - } 664 - 665 - void 666 - xfs_initialize_vnode( 667 - struct xfs_mount *mp, 668 - bhv_vnode_t *vp, 669 - struct xfs_inode *ip) 670 - { 671 - struct inode *inode = vn_to_inode(vp); 672 - 673 - if (!ip->i_vnode) { 674 - ip->i_vnode = vp; 675 - inode->i_private = ip; 676 - } 677 - 678 - /* 679 - * We need to set the ops vectors, and unlock the inode, but if 680 - * we have been called during the new inode create process, it is 681 - * too early to fill in the Linux inode. We will get called a 682 - * second time once the inode is properly set up, and then we can 683 - * finish our work. 684 - */ 685 - if (ip->i_d.di_mode != 0 && (inode->i_state & I_NEW)) { 686 - xfs_revalidate_inode(mp, vp, ip); 687 - xfs_set_inodeops(inode); 688 - 689 - xfs_iflags_clear(ip, XFS_INEW); 690 - barrier(); 691 - 692 - unlock_new_inode(inode); 693 - } 694 - } 695 - 696 584 int 697 585 xfs_blkdev_get( 698 586 xfs_mount_t *mp, ··· 870 982 xfs_fs_alloc_inode( 871 983 struct super_block *sb) 872 984 { 873 - bhv_vnode_t *vp; 874 - 875 - vp = kmem_zone_alloc(xfs_vnode_zone, KM_SLEEP); 876 - if (unlikely(!vp)) 877 - return NULL; 878 - return vn_to_inode(vp); 985 + return kmem_zone_alloc(xfs_vnode_zone, KM_SLEEP); 879 986 } 880 987 881 988 STATIC void 882 989 xfs_fs_destroy_inode( 883 990 struct inode *inode) 884 991 { 885 - kmem_zone_free(xfs_vnode_zone, vn_from_inode(inode)); 992 + kmem_zone_free(xfs_vnode_zone, inode); 886 993 } 887 994 888 995 STATIC void 889 996 xfs_fs_inode_init_once( 890 997 void *vnode) 891 998 { 892 - inode_init_once(vn_to_inode((bhv_vnode_t *)vnode)); 999 + inode_init_once((struct inode *)vnode); 893 1000 } 894 1001 895 1002 /* ··· 989 1106 xfs_flush_inode( 990 1107 xfs_inode_t *ip) 991 1108 { 992 - struct inode *inode = ip->i_vnode; 1109 + struct inode *inode = VFS_I(ip); 993 1110 994 1111 igrab(inode); 995 1112 xfs_syncd_queue_work(ip->i_mount, inode, xfs_flush_inode_work); ··· 1014 1131 xfs_flush_device( 1015 1132 xfs_inode_t *ip) 1016 1133 { 1017 - struct inode *inode = vn_to_inode(XFS_ITOV(ip)); 1134 + struct inode *inode = VFS_I(ip); 1018 1135 1019 1136 igrab(inode); 1020 1137 xfs_syncd_queue_work(ip->i_mount, inode, xfs_flush_device_work); ··· 1084 1201 } 1085 1202 1086 1203 STATIC void 1204 + xfs_free_fsname( 1205 + struct xfs_mount *mp) 1206 + { 1207 + kfree(mp->m_fsname); 1208 + kfree(mp->m_rtname); 1209 + kfree(mp->m_logname); 1210 + } 1211 + 1212 + STATIC void 1087 1213 xfs_fs_put_super( 1088 1214 struct super_block *sb) 1089 1215 { ··· 1131 1239 error = xfs_unmount_flush(mp, 0); 1132 1240 WARN_ON(error); 1133 1241 1134 - IRELE(rip); 1135 - 1136 1242 /* 1137 1243 * If we're forcing a shutdown, typically because of a media error, 1138 1244 * we want to make sure we invalidate dirty pages that belong to ··· 1147 1257 } 1148 1258 1149 1259 xfs_unmountfs(mp); 1260 + xfs_freesb(mp); 1150 1261 xfs_icsb_destroy_counters(mp); 1151 1262 xfs_close_devices(mp); 1152 1263 xfs_qmops_put(mp); 1153 1264 xfs_dmops_put(mp); 1265 + xfs_free_fsname(mp); 1154 1266 kfree(mp); 1155 1267 } 1156 1268 ··· 1409 1517 struct xfs_mount_args *ap, 1410 1518 struct xfs_mount *mp) 1411 1519 { 1520 + int error; 1521 + 1412 1522 /* Values are in BBs */ 1413 1523 if ((ap->flags & XFSMNT_NOALIGN) != XFSMNT_NOALIGN) { 1414 1524 /* ··· 1443 1549 ap->logbufsize); 1444 1550 return XFS_ERROR(EINVAL); 1445 1551 } 1552 + 1553 + error = ENOMEM; 1554 + 1446 1555 mp->m_logbsize = ap->logbufsize; 1447 1556 mp->m_fsname_len = strlen(ap->fsname) + 1; 1448 - mp->m_fsname = kmem_alloc(mp->m_fsname_len, KM_SLEEP); 1449 - strcpy(mp->m_fsname, ap->fsname); 1557 + 1558 + mp->m_fsname = kstrdup(ap->fsname, GFP_KERNEL); 1559 + if (!mp->m_fsname) 1560 + goto out; 1561 + 1450 1562 if (ap->rtname[0]) { 1451 - mp->m_rtname = kmem_alloc(strlen(ap->rtname) + 1, KM_SLEEP); 1452 - strcpy(mp->m_rtname, ap->rtname); 1563 + mp->m_rtname = kstrdup(ap->rtname, GFP_KERNEL); 1564 + if (!mp->m_rtname) 1565 + goto out_free_fsname; 1566 + 1453 1567 } 1568 + 1454 1569 if (ap->logname[0]) { 1455 - mp->m_logname = kmem_alloc(strlen(ap->logname) + 1, KM_SLEEP); 1456 - strcpy(mp->m_logname, ap->logname); 1570 + mp->m_logname = kstrdup(ap->logname, GFP_KERNEL); 1571 + if (!mp->m_logname) 1572 + goto out_free_rtname; 1457 1573 } 1458 1574 1459 1575 if (ap->flags & XFSMNT_WSYNC) ··· 1536 1632 if (ap->flags & XFSMNT_DMAPI) 1537 1633 mp->m_flags |= XFS_MOUNT_DMAPI; 1538 1634 return 0; 1635 + 1636 + 1637 + out_free_rtname: 1638 + kfree(mp->m_rtname); 1639 + out_free_fsname: 1640 + kfree(mp->m_fsname); 1641 + out: 1642 + return error; 1539 1643 } 1540 1644 1541 1645 /* ··· 1704 1792 */ 1705 1793 error = xfs_start_flags(args, mp); 1706 1794 if (error) 1707 - goto out_destroy_counters; 1795 + goto out_free_fsname; 1708 1796 error = xfs_readsb(mp, flags); 1709 1797 if (error) 1710 - goto out_destroy_counters; 1798 + goto out_free_fsname; 1711 1799 error = xfs_finish_flags(args, mp); 1712 1800 if (error) 1713 1801 goto out_free_sb; ··· 1723 1811 if (error) 1724 1812 goto out_free_sb; 1725 1813 1726 - error = xfs_mountfs(mp, flags); 1814 + error = xfs_mountfs(mp); 1727 1815 if (error) 1728 1816 goto out_filestream_unmount; 1729 1817 ··· 1737 1825 sb->s_time_gran = 1; 1738 1826 set_posix_acl_flag(sb); 1739 1827 1740 - root = igrab(mp->m_rootip->i_vnode); 1828 + root = igrab(VFS_I(mp->m_rootip)); 1741 1829 if (!root) { 1742 1830 error = ENOENT; 1743 1831 goto fail_unmount; ··· 1769 1857 xfs_filestream_unmount(mp); 1770 1858 out_free_sb: 1771 1859 xfs_freesb(mp); 1772 - out_destroy_counters: 1860 + out_free_fsname: 1861 + xfs_free_fsname(mp); 1773 1862 xfs_icsb_destroy_counters(mp); 1774 1863 xfs_close_devices(mp); 1775 1864 out_put_qmops: ··· 1803 1890 error = xfs_unmount_flush(mp, 0); 1804 1891 WARN_ON(error); 1805 1892 1806 - IRELE(mp->m_rootip); 1807 - 1808 1893 xfs_unmountfs(mp); 1809 - goto out_destroy_counters; 1894 + goto out_free_sb; 1810 1895 } 1811 1896 1812 1897 STATIC int ··· 1925 2014 STATIC int __init 1926 2015 xfs_init_zones(void) 1927 2016 { 1928 - xfs_vnode_zone = kmem_zone_init_flags(sizeof(bhv_vnode_t), "xfs_vnode", 2017 + xfs_vnode_zone = kmem_zone_init_flags(sizeof(struct inode), "xfs_vnode", 1929 2018 KM_ZONE_HWALIGN | KM_ZONE_RECLAIM | 1930 2019 KM_ZONE_SPREAD, 1931 2020 xfs_fs_inode_init_once);
-3
fs/xfs/linux-2.6/xfs_super.h
··· 101 101 102 102 extern __uint64_t xfs_max_file_offset(unsigned int); 103 103 104 - extern void xfs_initialize_vnode(struct xfs_mount *mp, bhv_vnode_t *vp, 105 - struct xfs_inode *ip); 106 - 107 104 extern void xfs_flush_inode(struct xfs_inode *); 108 105 extern void xfs_flush_device(struct xfs_inode *); 109 106
+2 -20
fs/xfs/linux-2.6/xfs_vnode.c
··· 33 33 34 34 35 35 /* 36 - * Dedicated vnode inactive/reclaim sync semaphores. 36 + * Dedicated vnode inactive/reclaim sync wait queues. 37 37 * Prime number of hash buckets since address is used as the key. 38 38 */ 39 39 #define NVSYNC 37 ··· 82 82 xfs_do_force_shutdown(ip->i_mount, SHUTDOWN_DEVICE_REQ, f, l); 83 83 } 84 84 85 - 86 - /* 87 - * Add a reference to a referenced vnode. 88 - */ 89 - bhv_vnode_t * 90 - vn_hold( 91 - bhv_vnode_t *vp) 92 - { 93 - struct inode *inode; 94 - 95 - XFS_STATS_INC(vn_hold); 96 - 97 - inode = igrab(vn_to_inode(vp)); 98 - ASSERT(inode); 99 - 100 - return vp; 101 - } 102 - 103 85 #ifdef XFS_INODE_TRACE 104 86 105 87 /* ··· 90 108 */ 91 109 static inline int xfs_icount(struct xfs_inode *ip) 92 110 { 93 - bhv_vnode_t *vp = XFS_ITOV_NULL(ip); 111 + struct inode *vp = VFS_I(ip); 94 112 95 113 if (vp) 96 114 return vn_count(vp);
+23 -42
fs/xfs/linux-2.6/xfs_vnode.h
··· 22 22 struct xfs_iomap; 23 23 struct attrlist_cursor_kern; 24 24 25 - typedef struct inode bhv_vnode_t; 26 - 27 - /* 28 - * Vnode to Linux inode mapping. 29 - */ 30 - static inline bhv_vnode_t *vn_from_inode(struct inode *inode) 31 - { 32 - return inode; 33 - } 34 - static inline struct inode *vn_to_inode(bhv_vnode_t *vnode) 35 - { 36 - return vnode; 37 - } 38 - 39 25 /* 40 26 * Return values for xfs_inactive. A return value of 41 27 * VN_INACTIVE_NOCACHE implies that the file system behavior ··· 62 76 extern void vn_iowake(struct xfs_inode *ip); 63 77 extern void vn_ioerror(struct xfs_inode *ip, int error, char *f, int l); 64 78 65 - static inline int vn_count(bhv_vnode_t *vp) 79 + static inline int vn_count(struct inode *vp) 66 80 { 67 - return atomic_read(&vn_to_inode(vp)->i_count); 81 + return atomic_read(&vp->i_count); 68 82 } 69 83 70 - /* 71 - * Vnode reference counting functions (and macros for compatibility). 72 - */ 73 - extern bhv_vnode_t *vn_hold(bhv_vnode_t *); 84 + #define IHOLD(ip) \ 85 + do { \ 86 + ASSERT(atomic_read(&VFS_I(ip)->i_count) > 0) ; \ 87 + atomic_inc(&(VFS_I(ip)->i_count)); \ 88 + xfs_itrace_hold((ip), __FILE__, __LINE__, (inst_t *)__return_address); \ 89 + } while (0) 74 90 75 - #if defined(XFS_INODE_TRACE) 76 - #define VN_HOLD(vp) \ 77 - ((void)vn_hold(vp), \ 78 - xfs_itrace_hold(xfs_vtoi(vp), __FILE__, __LINE__, (inst_t *)__return_address)) 79 - #define VN_RELE(vp) \ 80 - (xfs_itrace_rele(xfs_vtoi(vp), __FILE__, __LINE__, (inst_t *)__return_address), \ 81 - iput(vn_to_inode(vp))) 82 - #else 83 - #define VN_HOLD(vp) ((void)vn_hold(vp)) 84 - #define VN_RELE(vp) (iput(vn_to_inode(vp))) 85 - #endif 91 + #define IRELE(ip) \ 92 + do { \ 93 + xfs_itrace_rele((ip), __FILE__, __LINE__, (inst_t *)__return_address); \ 94 + iput(VFS_I(ip)); \ 95 + } while (0) 86 96 87 - static inline bhv_vnode_t *vn_grab(bhv_vnode_t *vp) 97 + static inline struct inode *vn_grab(struct inode *vp) 88 98 { 89 - struct inode *inode = igrab(vn_to_inode(vp)); 90 - return inode ? vn_from_inode(inode) : NULL; 99 + return igrab(vp); 91 100 } 92 101 93 102 /* 94 103 * Dealing with bad inodes 95 104 */ 96 - static inline int VN_BAD(bhv_vnode_t *vp) 105 + static inline int VN_BAD(struct inode *vp) 97 106 { 98 - return is_bad_inode(vn_to_inode(vp)); 107 + return is_bad_inode(vp); 99 108 } 100 109 101 110 /* 102 111 * Extracting atime values in various formats 103 112 */ 104 - static inline void vn_atime_to_bstime(bhv_vnode_t *vp, xfs_bstime_t *bs_atime) 113 + static inline void vn_atime_to_bstime(struct inode *vp, xfs_bstime_t *bs_atime) 105 114 { 106 115 bs_atime->tv_sec = vp->i_atime.tv_sec; 107 116 bs_atime->tv_nsec = vp->i_atime.tv_nsec; 108 117 } 109 118 110 - static inline void vn_atime_to_timespec(bhv_vnode_t *vp, struct timespec *ts) 119 + static inline void vn_atime_to_timespec(struct inode *vp, struct timespec *ts) 111 120 { 112 121 *ts = vp->i_atime; 113 122 } 114 123 115 - static inline void vn_atime_to_time_t(bhv_vnode_t *vp, time_t *tt) 124 + static inline void vn_atime_to_time_t(struct inode *vp, time_t *tt) 116 125 { 117 126 *tt = vp->i_atime.tv_sec; 118 127 } ··· 115 134 /* 116 135 * Some useful predicates. 117 136 */ 118 - #define VN_MAPPED(vp) mapping_mapped(vn_to_inode(vp)->i_mapping) 119 - #define VN_CACHED(vp) (vn_to_inode(vp)->i_mapping->nrpages) 120 - #define VN_DIRTY(vp) mapping_tagged(vn_to_inode(vp)->i_mapping, \ 137 + #define VN_MAPPED(vp) mapping_mapped(vp->i_mapping) 138 + #define VN_CACHED(vp) (vp->i_mapping->nrpages) 139 + #define VN_DIRTY(vp) mapping_tagged(vp->i_mapping, \ 121 140 PAGECACHE_TAG_DIRTY) 122 141 123 142
+14 -24
fs/xfs/quota/xfs_dquot.c
··· 101 101 if (brandnewdquot) { 102 102 dqp->dq_flnext = dqp->dq_flprev = dqp; 103 103 mutex_init(&dqp->q_qlock); 104 - initnsema(&dqp->q_flock, 1, "fdq"); 105 104 sv_init(&dqp->q_pinwait, SV_DEFAULT, "pdq"); 106 105 106 + /* 107 + * Because we want to use a counting completion, complete 108 + * the flush completion once to allow a single access to 109 + * the flush completion without blocking. 110 + */ 111 + init_completion(&dqp->q_flush); 112 + complete(&dqp->q_flush); 113 + 107 114 #ifdef XFS_DQUOT_TRACE 108 - dqp->q_trace = ktrace_alloc(DQUOT_TRACE_SIZE, KM_SLEEP); 115 + dqp->q_trace = ktrace_alloc(DQUOT_TRACE_SIZE, KM_NOFS); 109 116 xfs_dqtrace_entry(dqp, "DQINIT"); 110 117 #endif 111 118 } else { ··· 157 150 ASSERT(! XFS_DQ_IS_ON_FREELIST(dqp)); 158 151 159 152 mutex_destroy(&dqp->q_qlock); 160 - freesema(&dqp->q_flock); 161 153 sv_destroy(&dqp->q_pinwait); 162 154 163 155 #ifdef XFS_DQUOT_TRACE ··· 437 431 * when it unlocks the inode. Since we want to keep the quota 438 432 * inode around, we bump the vnode ref count now. 439 433 */ 440 - VN_HOLD(XFS_ITOV(quotip)); 434 + IHOLD(quotip); 441 435 442 436 xfs_trans_ijoin(tp, quotip, XFS_ILOCK_EXCL); 443 437 nmaps = 1; ··· 1217 1211 int error; 1218 1212 1219 1213 ASSERT(XFS_DQ_IS_LOCKED(dqp)); 1220 - ASSERT(XFS_DQ_IS_FLUSH_LOCKED(dqp)); 1214 + ASSERT(!completion_done(&dqp->q_flush)); 1221 1215 xfs_dqtrace_entry(dqp, "DQFLUSH"); 1222 1216 1223 1217 /* ··· 1354 1348 xfs_dqfunlock(dqp); 1355 1349 } 1356 1350 1357 - 1358 - int 1359 - xfs_qm_dqflock_nowait( 1360 - xfs_dquot_t *dqp) 1361 - { 1362 - int locked; 1363 - 1364 - locked = cpsema(&((dqp)->q_flock)); 1365 - 1366 - /* XXX ifdef these out */ 1367 - if (locked) 1368 - (dqp)->dq_flags |= XFS_DQ_FLOCKED; 1369 - return (locked); 1370 - } 1371 - 1372 - 1373 1351 int 1374 1352 xfs_qm_dqlock_nowait( 1375 1353 xfs_dquot_t *dqp) 1376 1354 { 1377 - return (mutex_trylock(&((dqp)->q_qlock))); 1355 + return mutex_trylock(&dqp->q_qlock); 1378 1356 } 1379 1357 1380 1358 void 1381 1359 xfs_dqlock( 1382 1360 xfs_dquot_t *dqp) 1383 1361 { 1384 - mutex_lock(&(dqp->q_qlock)); 1362 + mutex_lock(&dqp->q_qlock); 1385 1363 } 1386 1364 1387 1365 void ··· 1458 1468 * if we're turning off quotas. Basically, we need this flush 1459 1469 * lock, and are willing to block on it. 1460 1470 */ 1461 - if (! xfs_qm_dqflock_nowait(dqp)) { 1471 + if (!xfs_dqflock_nowait(dqp)) { 1462 1472 /* 1463 1473 * Block on the flush lock after nudging dquot buffer, 1464 1474 * if it is incore.
+18 -11
fs/xfs/quota/xfs_dquot.h
··· 82 82 xfs_qcnt_t q_res_icount; /* total inos allocd+reserved */ 83 83 xfs_qcnt_t q_res_rtbcount;/* total realtime blks used+reserved */ 84 84 mutex_t q_qlock; /* quota lock */ 85 - sema_t q_flock; /* flush lock */ 85 + struct completion q_flush; /* flush completion queue */ 86 86 uint q_pincount; /* pin count for this dquot */ 87 87 sv_t q_pinwait; /* sync var for pinning */ 88 88 #ifdef XFS_DQUOT_TRACE ··· 113 113 114 114 115 115 /* 116 - * The following three routines simply manage the q_flock 117 - * semaphore embedded in the dquot. This semaphore synchronizes 118 - * processes attempting to flush the in-core dquot back to disk. 116 + * Manage the q_flush completion queue embedded in the dquot. This completion 117 + * queue synchronizes processes attempting to flush the in-core dquot back to 118 + * disk. 119 119 */ 120 - #define xfs_dqflock(dqp) { psema(&((dqp)->q_flock), PINOD | PRECALC);\ 121 - (dqp)->dq_flags |= XFS_DQ_FLOCKED; } 122 - #define xfs_dqfunlock(dqp) { ASSERT(issemalocked(&((dqp)->q_flock))); \ 123 - vsema(&((dqp)->q_flock)); \ 124 - (dqp)->dq_flags &= ~(XFS_DQ_FLOCKED); } 120 + static inline void xfs_dqflock(xfs_dquot_t *dqp) 121 + { 122 + wait_for_completion(&dqp->q_flush); 123 + } 125 124 126 - #define XFS_DQ_IS_FLUSH_LOCKED(dqp) (issemalocked(&((dqp)->q_flock))) 125 + static inline int xfs_dqflock_nowait(xfs_dquot_t *dqp) 126 + { 127 + return try_wait_for_completion(&dqp->q_flush); 128 + } 129 + 130 + static inline void xfs_dqfunlock(xfs_dquot_t *dqp) 131 + { 132 + complete(&dqp->q_flush); 133 + } 134 + 127 135 #define XFS_DQ_IS_ON_FREELIST(dqp) ((dqp)->dq_flnext != (dqp)) 128 136 #define XFS_DQ_IS_DIRTY(dqp) ((dqp)->dq_flags & XFS_DQ_DIRTY) 129 137 #define XFS_QM_ISUDQ(dqp) ((dqp)->dq_flags & XFS_DQ_USER) ··· 175 167 extern int xfs_qm_dqpurge(xfs_dquot_t *); 176 168 extern void xfs_qm_dqunpin_wait(xfs_dquot_t *); 177 169 extern int xfs_qm_dqlock_nowait(xfs_dquot_t *); 178 - extern int xfs_qm_dqflock_nowait(xfs_dquot_t *); 179 170 extern void xfs_qm_dqflock_pushbuf_wait(xfs_dquot_t *dqp); 180 171 extern void xfs_qm_adjust_dqtimers(xfs_mount_t *, 181 172 xfs_disk_dquot_t *);
+4 -4
fs/xfs/quota/xfs_dquot_item.c
··· 151 151 dqp = logitem->qli_dquot; 152 152 153 153 ASSERT(XFS_DQ_IS_LOCKED(dqp)); 154 - ASSERT(XFS_DQ_IS_FLUSH_LOCKED(dqp)); 154 + ASSERT(!completion_done(&dqp->q_flush)); 155 155 156 156 /* 157 157 * Since we were able to lock the dquot's flush lock and ··· 245 245 * inode flush completed and the inode was taken off the AIL. 246 246 * So, just get out. 247 247 */ 248 - if (!issemalocked(&(dqp->q_flock)) || 248 + if (completion_done(&dqp->q_flush) || 249 249 ((qip->qli_item.li_flags & XFS_LI_IN_AIL) == 0)) { 250 250 qip->qli_pushbuf_flag = 0; 251 251 xfs_dqunlock(dqp); ··· 258 258 if (bp != NULL) { 259 259 if (XFS_BUF_ISDELAYWRITE(bp)) { 260 260 dopush = ((qip->qli_item.li_flags & XFS_LI_IN_AIL) && 261 - issemalocked(&(dqp->q_flock))); 261 + !completion_done(&dqp->q_flush)); 262 262 qip->qli_pushbuf_flag = 0; 263 263 xfs_dqunlock(dqp); 264 264 ··· 317 317 return (XFS_ITEM_LOCKED); 318 318 319 319 retval = XFS_ITEM_SUCCESS; 320 - if (! xfs_qm_dqflock_nowait(dqp)) { 320 + if (!xfs_dqflock_nowait(dqp)) { 321 321 /* 322 322 * The dquot is already being flushed. It may have been 323 323 * flushed delayed write, however, and we don't want to
+6 -8
fs/xfs/quota/xfs_qm.c
··· 310 310 */ 311 311 void 312 312 xfs_qm_mount_quotas( 313 - xfs_mount_t *mp, 314 - int mfsi_flags) 313 + xfs_mount_t *mp) 315 314 { 316 315 int error = 0; 317 316 uint sbf; ··· 345 346 /* 346 347 * If any of the quotas are not consistent, do a quotacheck. 347 348 */ 348 - if (XFS_QM_NEED_QUOTACHECK(mp) && 349 - !(mfsi_flags & XFS_MFSI_NO_QUOTACHECK)) { 349 + if (XFS_QM_NEED_QUOTACHECK(mp)) { 350 350 error = xfs_qm_quotacheck(mp); 351 351 if (error) { 352 352 /* Quotacheck failed and disabled quotas. */ ··· 482 484 xfs_dqtrace_entry(dqp, "FLUSHALL: DQDIRTY"); 483 485 /* XXX a sentinel would be better */ 484 486 recl = XFS_QI_MPLRECLAIMS(mp); 485 - if (! xfs_qm_dqflock_nowait(dqp)) { 487 + if (!xfs_dqflock_nowait(dqp)) { 486 488 /* 487 489 * If we can't grab the flush lock then check 488 490 * to see if the dquot has been flushed delayed ··· 1060 1062 1061 1063 /* XXX a sentinel would be better */ 1062 1064 recl = XFS_QI_MPLRECLAIMS(mp); 1063 - if (! xfs_qm_dqflock_nowait(dqp)) { 1065 + if (!xfs_dqflock_nowait(dqp)) { 1064 1066 if (nowait) { 1065 1067 xfs_dqunlock(dqp); 1066 1068 continue; ··· 2077 2079 * Try to grab the flush lock. If this dquot is in the process of 2078 2080 * getting flushed to disk, we don't want to reclaim it. 2079 2081 */ 2080 - if (! xfs_qm_dqflock_nowait(dqp)) { 2082 + if (!xfs_dqflock_nowait(dqp)) { 2081 2083 xfs_dqunlock(dqp); 2082 2084 dqp = dqp->dq_flnext; 2083 2085 continue; ··· 2255 2257 * Try to grab the flush lock. If this dquot is in the process of 2256 2258 * getting flushed to disk, we don't want to reclaim it. 2257 2259 */ 2258 - if (! xfs_qm_dqflock_nowait(dqp)) { 2260 + if (!xfs_dqflock_nowait(dqp)) { 2259 2261 xfs_dqunlock(dqp); 2260 2262 continue; 2261 2263 }
+1 -1
fs/xfs/quota/xfs_qm.h
··· 165 165 #define XFS_QM_RELE(xqm) ((xqm)->qm_nrefs--) 166 166 167 167 extern void xfs_qm_destroy_quotainfo(xfs_mount_t *); 168 - extern void xfs_qm_mount_quotas(xfs_mount_t *, int); 168 + extern void xfs_qm_mount_quotas(xfs_mount_t *); 169 169 extern int xfs_qm_quotacheck(xfs_mount_t *); 170 170 extern void xfs_qm_unmount_quotadestroy(xfs_mount_t *); 171 171 extern int xfs_qm_unmount_quotas(xfs_mount_t *);
+3 -4
fs/xfs/quota/xfs_qm_bhv.c
··· 162 162 * mounting, and get on with the boring life 163 163 * without disk quotas. 164 164 */ 165 - xfs_qm_mount_quotas(mp, 0); 165 + xfs_qm_mount_quotas(mp); 166 166 } else { 167 167 /* 168 168 * Clear the quota flags, but remember them. This ··· 184 184 xfs_qm_endmount( 185 185 xfs_mount_t *mp, 186 186 uint needquotamount, 187 - uint quotaflags, 188 - int mfsi_flags) 187 + uint quotaflags) 189 188 { 190 189 if (needquotamount) { 191 190 ASSERT(mp->m_qflags == 0); 192 191 mp->m_qflags = quotaflags; 193 - xfs_qm_mount_quotas(mp, mfsi_flags); 192 + xfs_qm_mount_quotas(mp); 194 193 } 195 194 196 195 #if defined(DEBUG) && defined(XFS_LOUD_RECOVERY)
+2 -2
fs/xfs/quota/xfs_qm_syscalls.c
··· 1034 1034 { 1035 1035 xfs_inode_t *ip, *topino; 1036 1036 uint ireclaims; 1037 - bhv_vnode_t *vp; 1037 + struct inode *vp; 1038 1038 boolean_t vnode_refd; 1039 1039 1040 1040 ASSERT(mp->m_quotainfo); ··· 1059 1059 ip = ip->i_mnext; 1060 1060 continue; 1061 1061 } 1062 - vp = XFS_ITOV_NULL(ip); 1062 + vp = VFS_I(ip); 1063 1063 if (!vp) { 1064 1064 ASSERT(ip->i_udquot == NULL); 1065 1065 ASSERT(ip->i_gdquot == NULL);
+23 -29
fs/xfs/xfs_acl.c
··· 37 37 #include <linux/capability.h> 38 38 #include <linux/posix_acl_xattr.h> 39 39 40 - STATIC int xfs_acl_setmode(bhv_vnode_t *, xfs_acl_t *, int *); 40 + STATIC int xfs_acl_setmode(struct inode *, xfs_acl_t *, int *); 41 41 STATIC void xfs_acl_filter_mode(mode_t, xfs_acl_t *); 42 42 STATIC void xfs_acl_get_endian(xfs_acl_t *); 43 43 STATIC int xfs_acl_access(uid_t, gid_t, xfs_acl_t *, mode_t, cred_t *); 44 44 STATIC int xfs_acl_invalid(xfs_acl_t *); 45 45 STATIC void xfs_acl_sync_mode(mode_t, xfs_acl_t *); 46 - STATIC void xfs_acl_get_attr(bhv_vnode_t *, xfs_acl_t *, int, int, int *); 47 - STATIC void xfs_acl_set_attr(bhv_vnode_t *, xfs_acl_t *, int, int *); 48 - STATIC int xfs_acl_allow_set(bhv_vnode_t *, int); 46 + STATIC void xfs_acl_get_attr(struct inode *, xfs_acl_t *, int, int, int *); 47 + STATIC void xfs_acl_set_attr(struct inode *, xfs_acl_t *, int, int *); 48 + STATIC int xfs_acl_allow_set(struct inode *, int); 49 49 50 50 kmem_zone_t *xfs_acl_zone; 51 51 ··· 55 55 */ 56 56 int 57 57 xfs_acl_vhasacl_access( 58 - bhv_vnode_t *vp) 58 + struct inode *vp) 59 59 { 60 60 int error; 61 61 ··· 68 68 */ 69 69 int 70 70 xfs_acl_vhasacl_default( 71 - bhv_vnode_t *vp) 71 + struct inode *vp) 72 72 { 73 73 int error; 74 74 ··· 207 207 208 208 int 209 209 xfs_acl_vget( 210 - bhv_vnode_t *vp, 210 + struct inode *vp, 211 211 void *acl, 212 212 size_t size, 213 213 int kind) ··· 217 217 posix_acl_xattr_header *ext_acl = acl; 218 218 int flags = 0; 219 219 220 - VN_HOLD(vp); 221 220 if(size) { 222 221 if (!(_ACL_ALLOC(xfs_acl))) { 223 222 error = ENOMEM; ··· 238 239 goto out; 239 240 } 240 241 if (kind == _ACL_TYPE_ACCESS) 241 - xfs_acl_sync_mode(xfs_vtoi(vp)->i_d.di_mode, xfs_acl); 242 + xfs_acl_sync_mode(XFS_I(vp)->i_d.di_mode, xfs_acl); 242 243 error = -posix_acl_xfs_to_xattr(xfs_acl, ext_acl, size); 243 244 } 244 245 out: 245 - VN_RELE(vp); 246 246 if(xfs_acl) 247 247 _ACL_FREE(xfs_acl); 248 248 return -error; ··· 249 251 250 252 int 251 253 xfs_acl_vremove( 252 - bhv_vnode_t *vp, 254 + struct inode *vp, 253 255 int kind) 254 256 { 255 257 int error; 256 258 257 - VN_HOLD(vp); 258 259 error = xfs_acl_allow_set(vp, kind); 259 260 if (!error) { 260 - error = xfs_attr_remove(xfs_vtoi(vp), 261 + error = xfs_attr_remove(XFS_I(vp), 261 262 kind == _ACL_TYPE_DEFAULT? 262 263 SGI_ACL_DEFAULT: SGI_ACL_FILE, 263 264 ATTR_ROOT); 264 265 if (error == ENOATTR) 265 266 error = 0; /* 'scool */ 266 267 } 267 - VN_RELE(vp); 268 268 return -error; 269 269 } 270 270 271 271 int 272 272 xfs_acl_vset( 273 - bhv_vnode_t *vp, 273 + struct inode *vp, 274 274 void *acl, 275 275 size_t size, 276 276 int kind) ··· 294 298 return 0; 295 299 } 296 300 297 - VN_HOLD(vp); 298 301 error = xfs_acl_allow_set(vp, kind); 299 302 300 303 /* Incoming ACL exists, set file mode based on its value */ ··· 316 321 } 317 322 318 323 out: 319 - VN_RELE(vp); 320 324 _ACL_FREE(xfs_acl); 321 325 return -error; 322 326 } ··· 357 363 358 364 STATIC int 359 365 xfs_acl_allow_set( 360 - bhv_vnode_t *vp, 366 + struct inode *vp, 361 367 int kind) 362 368 { 363 369 if (vp->i_flags & (S_IMMUTABLE|S_APPEND)) ··· 366 372 return ENOTDIR; 367 373 if (vp->i_sb->s_flags & MS_RDONLY) 368 374 return EROFS; 369 - if (xfs_vtoi(vp)->i_d.di_uid != current->fsuid && !capable(CAP_FOWNER)) 375 + if (XFS_I(vp)->i_d.di_uid != current->fsuid && !capable(CAP_FOWNER)) 370 376 return EPERM; 371 377 return 0; 372 378 } ··· 560 566 */ 561 567 STATIC void 562 568 xfs_acl_get_attr( 563 - bhv_vnode_t *vp, 569 + struct inode *vp, 564 570 xfs_acl_t *aclp, 565 571 int kind, 566 572 int flags, ··· 570 576 571 577 ASSERT((flags & ATTR_KERNOVAL) ? (aclp == NULL) : 1); 572 578 flags |= ATTR_ROOT; 573 - *error = xfs_attr_get(xfs_vtoi(vp), 579 + *error = xfs_attr_get(XFS_I(vp), 574 580 kind == _ACL_TYPE_ACCESS ? 575 581 SGI_ACL_FILE : SGI_ACL_DEFAULT, 576 582 (char *)aclp, &len, flags); ··· 584 590 */ 585 591 STATIC void 586 592 xfs_acl_set_attr( 587 - bhv_vnode_t *vp, 593 + struct inode *vp, 588 594 xfs_acl_t *aclp, 589 595 int kind, 590 596 int *error) ··· 609 615 INT_SET(newace->ae_perm, ARCH_CONVERT, ace->ae_perm); 610 616 } 611 617 INT_SET(newacl->acl_cnt, ARCH_CONVERT, aclp->acl_cnt); 612 - *error = xfs_attr_set(xfs_vtoi(vp), 618 + *error = xfs_attr_set(XFS_I(vp), 613 619 kind == _ACL_TYPE_ACCESS ? 614 620 SGI_ACL_FILE: SGI_ACL_DEFAULT, 615 621 (char *)newacl, len, ATTR_ROOT); ··· 618 624 619 625 int 620 626 xfs_acl_vtoacl( 621 - bhv_vnode_t *vp, 627 + struct inode *vp, 622 628 xfs_acl_t *access_acl, 623 629 xfs_acl_t *default_acl) 624 630 { ··· 633 639 if (error) 634 640 access_acl->acl_cnt = XFS_ACL_NOT_PRESENT; 635 641 else /* We have a good ACL and the file mode, synchronize. */ 636 - xfs_acl_sync_mode(xfs_vtoi(vp)->i_d.di_mode, access_acl); 642 + xfs_acl_sync_mode(XFS_I(vp)->i_d.di_mode, access_acl); 637 643 } 638 644 639 645 if (default_acl) { ··· 650 656 */ 651 657 int 652 658 xfs_acl_inherit( 653 - bhv_vnode_t *vp, 659 + struct inode *vp, 654 660 mode_t mode, 655 661 xfs_acl_t *pdaclp) 656 662 { ··· 709 715 */ 710 716 STATIC int 711 717 xfs_acl_setmode( 712 - bhv_vnode_t *vp, 718 + struct inode *vp, 713 719 xfs_acl_t *acl, 714 720 int *basicperms) 715 721 { ··· 728 734 * mode. The m:: bits take precedence over the g:: bits. 729 735 */ 730 736 iattr.ia_valid = ATTR_MODE; 731 - iattr.ia_mode = xfs_vtoi(vp)->i_d.di_mode; 737 + iattr.ia_mode = XFS_I(vp)->i_d.di_mode; 732 738 iattr.ia_mode &= ~(S_IRWXU|S_IRWXG|S_IRWXO); 733 739 ap = acl->acl_entry; 734 740 for (i = 0; i < acl->acl_cnt; ++i) { ··· 758 764 if (gap && nomask) 759 765 iattr.ia_mode |= gap->ae_perm << 3; 760 766 761 - return xfs_setattr(xfs_vtoi(vp), &iattr, 0, sys_cred); 767 + return xfs_setattr(XFS_I(vp), &iattr, 0, sys_cred); 762 768 } 763 769 764 770 /*
+7 -7
fs/xfs/xfs_acl.h
··· 59 59 (zone) = kmem_zone_init(sizeof(xfs_acl_t), (name)) 60 60 #define xfs_acl_zone_destroy(zone) kmem_zone_destroy(zone) 61 61 62 - extern int xfs_acl_inherit(bhv_vnode_t *, mode_t mode, xfs_acl_t *); 62 + extern int xfs_acl_inherit(struct inode *, mode_t mode, xfs_acl_t *); 63 63 extern int xfs_acl_iaccess(struct xfs_inode *, mode_t, cred_t *); 64 - extern int xfs_acl_vtoacl(bhv_vnode_t *, xfs_acl_t *, xfs_acl_t *); 65 - extern int xfs_acl_vhasacl_access(bhv_vnode_t *); 66 - extern int xfs_acl_vhasacl_default(bhv_vnode_t *); 67 - extern int xfs_acl_vset(bhv_vnode_t *, void *, size_t, int); 68 - extern int xfs_acl_vget(bhv_vnode_t *, void *, size_t, int); 69 - extern int xfs_acl_vremove(bhv_vnode_t *, int); 64 + extern int xfs_acl_vtoacl(struct inode *, xfs_acl_t *, xfs_acl_t *); 65 + extern int xfs_acl_vhasacl_access(struct inode *); 66 + extern int xfs_acl_vhasacl_default(struct inode *); 67 + extern int xfs_acl_vset(struct inode *, void *, size_t, int); 68 + extern int xfs_acl_vget(struct inode *, void *, size_t, int); 69 + extern int xfs_acl_vremove(struct inode *, int); 70 70 71 71 #define _ACL_PERM_INVALID(perm) ((perm) & ~(ACL_READ|ACL_WRITE|ACL_EXECUTE)) 72 72
-68
fs/xfs/xfs_arch.h
··· 92 92 ((__u8*)(pointer))[1] = (((value) ) & 0xff); \ 93 93 } 94 94 95 - /* define generic INT_ macros */ 96 - 97 - #define INT_GET(reference,arch) \ 98 - (((arch) == ARCH_NOCONVERT) \ 99 - ? \ 100 - (reference) \ 101 - : \ 102 - INT_SWAP((reference),(reference)) \ 103 - ) 104 - 105 95 /* does not return a value */ 106 96 #define INT_SET(reference,arch,valueref) \ 107 97 (__builtin_constant_p(valueref) ? \ ··· 101 111 ( ((arch) != ARCH_NOCONVERT) ? (reference) = INT_SWAP((reference),(reference)) : 0 ) \ 102 112 ) \ 103 113 ) 104 - 105 - /* does not return a value */ 106 - #define INT_MOD_EXPR(reference,arch,code) \ 107 - (((arch) == ARCH_NOCONVERT) \ 108 - ? \ 109 - (void)((reference) code) \ 110 - : \ 111 - (void)( \ 112 - (reference) = INT_GET((reference),arch) , \ 113 - ((reference) code), \ 114 - INT_SET(reference, arch, reference) \ 115 - ) \ 116 - ) 117 - 118 - /* does not return a value */ 119 - #define INT_MOD(reference,arch,delta) \ 120 - (void)( \ 121 - INT_MOD_EXPR(reference,arch,+=(delta)) \ 122 - ) 123 - 124 - /* 125 - * INT_COPY - copy a value between two locations with the 126 - * _same architecture_ but _potentially different sizes_ 127 - * 128 - * if the types of the two parameters are equal or they are 129 - * in native architecture, a simple copy is done 130 - * 131 - * otherwise, architecture conversions are done 132 - * 133 - */ 134 - 135 - /* does not return a value */ 136 - #define INT_COPY(dst,src,arch) \ 137 - ( \ 138 - ((sizeof(dst) == sizeof(src)) || ((arch) == ARCH_NOCONVERT)) \ 139 - ? \ 140 - (void)((dst) = (src)) \ 141 - : \ 142 - INT_SET(dst, arch, INT_GET(src, arch)) \ 143 - ) 144 - 145 - /* 146 - * INT_XLATE - copy a value in either direction between two locations 147 - * with different architectures 148 - * 149 - * dir < 0 - copy from memory to buffer (native to arch) 150 - * dir > 0 - copy from buffer to memory (arch to native) 151 - */ 152 - 153 - /* does not return a value */ 154 - #define INT_XLATE(buf,mem,dir,arch) {\ 155 - ASSERT(dir); \ 156 - if (dir>0) { \ 157 - (mem)=INT_GET(buf, arch); \ 158 - } else { \ 159 - INT_SET(buf, arch, mem); \ 160 - } \ 161 - } 162 114 163 115 /* 164 116 * In directories inode numbers are stored as unaligned arrays of unsigned
+68 -42
fs/xfs/xfs_attr.c
··· 194 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 237 STATIC int 198 238 xfs_attr_set_int(xfs_inode_t *dp, struct xfs_name *name, 199 239 char *value, int valuelen, int flags) ··· 242 202 xfs_fsblock_t firstblock; 243 203 xfs_bmap_free_t flist; 244 204 int error, err2, committed; 245 - int local, size; 246 - uint nblks; 247 205 xfs_mount_t *mp = dp->i_mount; 248 206 int rsvd = (flags & ATTR_ROOT) != 0; 207 + int local; 249 208 250 209 /* 251 210 * Attach the dquots to the inode. ··· 280 241 args.whichfork = XFS_ATTR_FORK; 281 242 args.op_flags = XFS_DA_OP_ADDNAME | XFS_DA_OP_OKNOENT; 282 243 283 - /* 284 - * Determine space new attribute will use, and if it would be 285 - * "local" or "remote" (note: local != inline). 286 - */ 287 - size = xfs_attr_leaf_newentsize(name->len, valuelen, 288 - mp->m_sb.sb_blocksize, &local); 289 - 290 - nblks = XFS_DAENTER_SPACE_RES(mp, XFS_ATTR_FORK); 291 - if (local) { 292 - if (size > (mp->m_sb.sb_blocksize >> 1)) { 293 - /* Double split possible */ 294 - nblks <<= 1; 295 - } 296 - } else { 297 - uint dblocks = XFS_B_TO_FSB(mp, valuelen); 298 - /* Out of line attribute, cannot double split, but make 299 - * room for the attribute value itself. 300 - */ 301 - nblks += dblocks; 302 - nblks += XFS_NEXTENTADD_SPACE_RES(mp, dblocks, XFS_ATTR_FORK); 303 - } 304 - 305 244 /* Size is now blocks for attribute data */ 306 - args.total = nblks; 245 + args.total = xfs_attr_calc_size(dp, name->len, valuelen, &local); 307 246 308 247 /* 309 248 * Start our first transaction of the day. ··· 303 286 if (rsvd) 304 287 args.trans->t_flags |= XFS_TRANS_RESERVE; 305 288 306 - if ((error = xfs_trans_reserve(args.trans, (uint) nblks, 307 - XFS_ATTRSET_LOG_RES(mp, nblks), 308 - 0, XFS_TRANS_PERM_LOG_RES, 309 - XFS_ATTRSET_LOG_COUNT))) { 289 + if ((error = xfs_trans_reserve(args.trans, args.total, 290 + XFS_ATTRSET_LOG_RES(mp, args.total), 0, 291 + XFS_TRANS_PERM_LOG_RES, XFS_ATTRSET_LOG_COUNT))) { 310 292 xfs_trans_cancel(args.trans, 0); 311 293 return(error); 312 294 } 313 295 xfs_ilock(dp, XFS_ILOCK_EXCL); 314 296 315 - error = XFS_TRANS_RESERVE_QUOTA_NBLKS(mp, args.trans, dp, nblks, 0, 316 - rsvd ? XFS_QMOPT_RES_REGBLKS | XFS_QMOPT_FORCE_RES : 317 - XFS_QMOPT_RES_REGBLKS); 297 + error = XFS_TRANS_RESERVE_QUOTA_NBLKS(mp, args.trans, dp, args.total, 0, 298 + rsvd ? XFS_QMOPT_RES_REGBLKS | XFS_QMOPT_FORCE_RES : 299 + XFS_QMOPT_RES_REGBLKS); 318 300 if (error) { 319 301 xfs_iunlock(dp, XFS_ILOCK_EXCL); 320 302 xfs_trans_cancel(args.trans, XFS_TRANS_RELEASE_LOG_RES); ··· 400 384 * Commit the leaf transformation. We'll need another (linked) 401 385 * transaction to add the new attribute to the leaf. 402 386 */ 403 - if ((error = xfs_attr_rolltrans(&args.trans, dp))) 387 + 388 + error = xfs_trans_roll(&args.trans, dp); 389 + if (error) 404 390 goto out; 405 391 406 392 } ··· 982 964 * Commit the current trans (including the inode) and start 983 965 * a new one. 984 966 */ 985 - if ((error = xfs_attr_rolltrans(&args->trans, dp))) 967 + error = xfs_trans_roll(&args->trans, dp); 968 + if (error) 986 969 return (error); 987 970 988 971 /* ··· 997 978 * Commit the transaction that added the attr name so that 998 979 * later routines can manage their own transactions. 999 980 */ 1000 - if ((error = xfs_attr_rolltrans(&args->trans, dp))) 981 + error = xfs_trans_roll(&args->trans, dp); 982 + if (error) 1001 983 return (error); 1002 984 1003 985 /* ··· 1087 1067 /* 1088 1068 * Commit the remove and start the next trans in series. 1089 1069 */ 1090 - error = xfs_attr_rolltrans(&args->trans, dp); 1070 + error = xfs_trans_roll(&args->trans, dp); 1091 1071 1092 1072 } else if (args->rmtblkno > 0) { 1093 1073 /* ··· 1318 1298 * Commit the node conversion and start the next 1319 1299 * trans in the chain. 1320 1300 */ 1321 - if ((error = xfs_attr_rolltrans(&args->trans, dp))) 1301 + error = xfs_trans_roll(&args->trans, dp); 1302 + if (error) 1322 1303 goto out; 1323 1304 1324 1305 goto restart; ··· 1370 1349 * Commit the leaf addition or btree split and start the next 1371 1350 * trans in the chain. 1372 1351 */ 1373 - if ((error = xfs_attr_rolltrans(&args->trans, dp))) 1352 + error = xfs_trans_roll(&args->trans, dp); 1353 + if (error) 1374 1354 goto out; 1375 1355 1376 1356 /* ··· 1471 1449 /* 1472 1450 * Commit and start the next trans in the chain. 1473 1451 */ 1474 - if ((error = xfs_attr_rolltrans(&args->trans, dp))) 1452 + error = xfs_trans_roll(&args->trans, dp); 1453 + if (error) 1475 1454 goto out; 1476 1455 1477 1456 } else if (args->rmtblkno > 0) { ··· 1604 1581 /* 1605 1582 * Commit the Btree join operation and start a new trans. 1606 1583 */ 1607 - if ((error = xfs_attr_rolltrans(&args->trans, dp))) 1584 + error = xfs_trans_roll(&args->trans, dp); 1585 + if (error) 1608 1586 goto out; 1609 1587 } 1610 1588 ··· 2106 2082 /* 2107 2083 * Start the next trans in the chain. 2108 2084 */ 2109 - if ((error = xfs_attr_rolltrans(&args->trans, dp))) 2085 + error = xfs_trans_roll(&args->trans, dp); 2086 + if (error) 2110 2087 return (error); 2111 2088 } 2112 2089 ··· 2257 2232 /* 2258 2233 * Close out trans and start the next one in the chain. 2259 2234 */ 2260 - if ((error = xfs_attr_rolltrans(&args->trans, args->dp))) 2235 + error = xfs_trans_roll(&args->trans, args->dp); 2236 + if (error) 2261 2237 return (error); 2262 2238 } 2263 2239 return(0);
+1
fs/xfs/xfs_attr.h
··· 129 129 /* 130 130 * Overall external interface routines. 131 131 */ 132 + int xfs_attr_calc_size(struct xfs_inode *, int, int, int *); 132 133 int xfs_attr_inactive(struct xfs_inode *dp); 133 134 int xfs_attr_fetch(struct xfs_inode *, struct xfs_name *, char *, int *, int); 134 135 int xfs_attr_rmtval_get(struct xfs_da_args *args);
+8 -67
fs/xfs/xfs_attr_leaf.c
··· 2498 2498 /* 2499 2499 * Commit the flag value change and start the next trans in series. 2500 2500 */ 2501 - error = xfs_attr_rolltrans(&args->trans, args->dp); 2502 - 2503 - return(error); 2501 + return xfs_trans_roll(&args->trans, args->dp); 2504 2502 } 2505 2503 2506 2504 /* ··· 2545 2547 /* 2546 2548 * Commit the flag value change and start the next trans in series. 2547 2549 */ 2548 - error = xfs_attr_rolltrans(&args->trans, args->dp); 2549 - 2550 - return(error); 2550 + return xfs_trans_roll(&args->trans, args->dp); 2551 2551 } 2552 2552 2553 2553 /* ··· 2661 2665 /* 2662 2666 * Commit the flag value change and start the next trans in series. 2663 2667 */ 2664 - error = xfs_attr_rolltrans(&args->trans, args->dp); 2668 + error = xfs_trans_roll(&args->trans, args->dp); 2665 2669 2666 2670 return(error); 2667 2671 } ··· 2719 2723 /* 2720 2724 * Commit the invalidate and start the next transaction. 2721 2725 */ 2722 - error = xfs_attr_rolltrans(trans, dp); 2726 + error = xfs_trans_roll(trans, dp); 2723 2727 2724 2728 return (error); 2725 2729 } ··· 2821 2825 /* 2822 2826 * Atomically commit the whole invalidate stuff. 2823 2827 */ 2824 - if ((error = xfs_attr_rolltrans(trans, dp))) 2828 + error = xfs_trans_roll(trans, dp); 2829 + if (error) 2825 2830 return (error); 2826 2831 } 2827 2832 ··· 2961 2964 /* 2962 2965 * Roll to next transaction. 2963 2966 */ 2964 - if ((error = xfs_attr_rolltrans(trans, dp))) 2967 + error = xfs_trans_roll(trans, dp); 2968 + if (error) 2965 2969 return (error); 2966 2970 } 2967 2971 ··· 2971 2973 } 2972 2974 2973 2975 return(0); 2974 - } 2975 - 2976 - 2977 - /* 2978 - * Roll from one trans in the sequence of PERMANENT transactions to the next. 2979 - */ 2980 - int 2981 - xfs_attr_rolltrans(xfs_trans_t **transp, xfs_inode_t *dp) 2982 - { 2983 - xfs_trans_t *trans; 2984 - unsigned int logres, count; 2985 - int error; 2986 - 2987 - /* 2988 - * Ensure that the inode is always logged. 2989 - */ 2990 - trans = *transp; 2991 - xfs_trans_log_inode(trans, dp, XFS_ILOG_CORE); 2992 - 2993 - /* 2994 - * Copy the critical parameters from one trans to the next. 2995 - */ 2996 - logres = trans->t_log_res; 2997 - count = trans->t_log_count; 2998 - *transp = xfs_trans_dup(trans); 2999 - 3000 - /* 3001 - * Commit the current transaction. 3002 - * If this commit failed, then it'd just unlock those items that 3003 - * are not marked ihold. That also means that a filesystem shutdown 3004 - * is in progress. The caller takes the responsibility to cancel 3005 - * the duplicate transaction that gets returned. 3006 - */ 3007 - if ((error = xfs_trans_commit(trans, 0))) 3008 - return (error); 3009 - 3010 - trans = *transp; 3011 - 3012 - /* 3013 - * Reserve space in the log for th next transaction. 3014 - * This also pushes items in the "AIL", the list of logged items, 3015 - * out to disk if they are taking up space at the tail of the log 3016 - * that we want to use. This requires that either nothing be locked 3017 - * across this call, or that anything that is locked be logged in 3018 - * the prior and the next transactions. 3019 - */ 3020 - error = xfs_trans_reserve(trans, 0, logres, 0, 3021 - XFS_TRANS_PERM_LOG_RES, count); 3022 - /* 3023 - * Ensure that the inode is in the new transaction and locked. 3024 - */ 3025 - if (!error) { 3026 - xfs_trans_ijoin(trans, dp, XFS_ILOCK_EXCL); 3027 - xfs_trans_ihold(trans, dp); 3028 - } 3029 - return (error); 3030 - 3031 2976 }
-2
fs/xfs/xfs_attr_leaf.h
··· 274 274 struct xfs_dabuf *leaf2_bp); 275 275 int xfs_attr_leaf_newentsize(int namelen, int valuelen, int blocksize, 276 276 int *local); 277 - int xfs_attr_rolltrans(struct xfs_trans **transp, struct xfs_inode *dp); 278 - 279 277 #endif /* __XFS_ATTR_LEAF_H__ */
-103
fs/xfs/xfs_bit.c
··· 25 25 * XFS bit manipulation routines, used in non-realtime code. 26 26 */ 27 27 28 - #ifndef HAVE_ARCH_HIGHBIT 29 - /* 30 - * Index of high bit number in byte, -1 for none set, 0..7 otherwise. 31 - */ 32 - static const char xfs_highbit[256] = { 33 - -1, 0, 1, 1, 2, 2, 2, 2, /* 00 .. 07 */ 34 - 3, 3, 3, 3, 3, 3, 3, 3, /* 08 .. 0f */ 35 - 4, 4, 4, 4, 4, 4, 4, 4, /* 10 .. 17 */ 36 - 4, 4, 4, 4, 4, 4, 4, 4, /* 18 .. 1f */ 37 - 5, 5, 5, 5, 5, 5, 5, 5, /* 20 .. 27 */ 38 - 5, 5, 5, 5, 5, 5, 5, 5, /* 28 .. 2f */ 39 - 5, 5, 5, 5, 5, 5, 5, 5, /* 30 .. 37 */ 40 - 5, 5, 5, 5, 5, 5, 5, 5, /* 38 .. 3f */ 41 - 6, 6, 6, 6, 6, 6, 6, 6, /* 40 .. 47 */ 42 - 6, 6, 6, 6, 6, 6, 6, 6, /* 48 .. 4f */ 43 - 6, 6, 6, 6, 6, 6, 6, 6, /* 50 .. 57 */ 44 - 6, 6, 6, 6, 6, 6, 6, 6, /* 58 .. 5f */ 45 - 6, 6, 6, 6, 6, 6, 6, 6, /* 60 .. 67 */ 46 - 6, 6, 6, 6, 6, 6, 6, 6, /* 68 .. 6f */ 47 - 6, 6, 6, 6, 6, 6, 6, 6, /* 70 .. 77 */ 48 - 6, 6, 6, 6, 6, 6, 6, 6, /* 78 .. 7f */ 49 - 7, 7, 7, 7, 7, 7, 7, 7, /* 80 .. 87 */ 50 - 7, 7, 7, 7, 7, 7, 7, 7, /* 88 .. 8f */ 51 - 7, 7, 7, 7, 7, 7, 7, 7, /* 90 .. 97 */ 52 - 7, 7, 7, 7, 7, 7, 7, 7, /* 98 .. 9f */ 53 - 7, 7, 7, 7, 7, 7, 7, 7, /* a0 .. a7 */ 54 - 7, 7, 7, 7, 7, 7, 7, 7, /* a8 .. af */ 55 - 7, 7, 7, 7, 7, 7, 7, 7, /* b0 .. b7 */ 56 - 7, 7, 7, 7, 7, 7, 7, 7, /* b8 .. bf */ 57 - 7, 7, 7, 7, 7, 7, 7, 7, /* c0 .. c7 */ 58 - 7, 7, 7, 7, 7, 7, 7, 7, /* c8 .. cf */ 59 - 7, 7, 7, 7, 7, 7, 7, 7, /* d0 .. d7 */ 60 - 7, 7, 7, 7, 7, 7, 7, 7, /* d8 .. df */ 61 - 7, 7, 7, 7, 7, 7, 7, 7, /* e0 .. e7 */ 62 - 7, 7, 7, 7, 7, 7, 7, 7, /* e8 .. ef */ 63 - 7, 7, 7, 7, 7, 7, 7, 7, /* f0 .. f7 */ 64 - 7, 7, 7, 7, 7, 7, 7, 7, /* f8 .. ff */ 65 - }; 66 - #endif 67 - 68 - /* 69 - * xfs_highbit32: get high bit set out of 32-bit argument, -1 if none set. 70 - */ 71 - inline int 72 - xfs_highbit32( 73 - __uint32_t v) 74 - { 75 - #ifdef HAVE_ARCH_HIGHBIT 76 - return highbit32(v); 77 - #else 78 - int i; 79 - 80 - if (v & 0xffff0000) 81 - if (v & 0xff000000) 82 - i = 24; 83 - else 84 - i = 16; 85 - else if (v & 0x0000ffff) 86 - if (v & 0x0000ff00) 87 - i = 8; 88 - else 89 - i = 0; 90 - else 91 - return -1; 92 - return i + xfs_highbit[(v >> i) & 0xff]; 93 - #endif 94 - } 95 - 96 - /* 97 - * xfs_lowbit64: get low bit set out of 64-bit argument, -1 if none set. 98 - */ 99 - int 100 - xfs_lowbit64( 101 - __uint64_t v) 102 - { 103 - __uint32_t w = (__uint32_t)v; 104 - int n = 0; 105 - 106 - if (w) { /* lower bits */ 107 - n = ffs(w); 108 - } else { /* upper bits */ 109 - w = (__uint32_t)(v >> 32); 110 - if (w && (n = ffs(w))) 111 - n += 32; 112 - } 113 - return n - 1; 114 - } 115 - 116 - /* 117 - * xfs_highbit64: get high bit set out of 64-bit argument, -1 if none set. 118 - */ 119 - int 120 - xfs_highbit64( 121 - __uint64_t v) 122 - { 123 - __uint32_t h = (__uint32_t)(v >> 32); 124 - 125 - if (h) 126 - return xfs_highbit32(h) + 32; 127 - return xfs_highbit32((__uint32_t)v); 128 - } 129 - 130 - 131 28 /* 132 29 * Return whether bitmap is empty. 133 30 * Size is number of words in the bitmap, which is padded to word boundary
+31 -5
fs/xfs/xfs_bit.h
··· 47 47 } 48 48 49 49 /* Get high bit set out of 32-bit argument, -1 if none set */ 50 - extern int xfs_highbit32(__uint32_t v); 51 - 52 - /* Get low bit set out of 64-bit argument, -1 if none set */ 53 - extern int xfs_lowbit64(__uint64_t v); 50 + static inline int xfs_highbit32(__uint32_t v) 51 + { 52 + return fls(v) - 1; 53 + } 54 54 55 55 /* Get high bit set out of 64-bit argument, -1 if none set */ 56 - extern int xfs_highbit64(__uint64_t); 56 + static inline int xfs_highbit64(__uint64_t v) 57 + { 58 + return fls64(v) - 1; 59 + } 60 + 61 + /* Get low bit set out of 32-bit argument, -1 if none set */ 62 + static inline int xfs_lowbit32(__uint32_t v) 63 + { 64 + unsigned long t = v; 65 + return (v) ? find_first_bit(&t, 32) : -1; 66 + } 67 + 68 + /* Get low bit set out of 64-bit argument, -1 if none set */ 69 + static inline int xfs_lowbit64(__uint64_t v) 70 + { 71 + __uint32_t w = (__uint32_t)v; 72 + int n = 0; 73 + 74 + if (w) { /* lower bits */ 75 + n = ffs(w); 76 + } else { /* upper bits */ 77 + w = (__uint32_t)(v >> 32); 78 + if (w && (n = ffs(w))) 79 + n += 32; 80 + } 81 + return n - 1; 82 + } 57 83 58 84 /* Return whether bitmap is empty (1 == empty) */ 59 85 extern int xfs_bitmap_empty(uint *map, uint size);
+11 -23
fs/xfs/xfs_bmap.c
··· 384 384 int levelin, 385 385 int *count); 386 386 387 - STATIC int 387 + STATIC void 388 388 xfs_bmap_count_leaves( 389 389 xfs_ifork_t *ifp, 390 390 xfs_extnum_t idx, 391 391 int numrecs, 392 392 int *count); 393 393 394 - STATIC int 394 + STATIC void 395 395 xfs_bmap_disk_count_leaves( 396 396 xfs_extnum_t idx, 397 397 xfs_bmbt_block_t *block, ··· 4000 4000 ip->i_d.di_aformat = XFS_DINODE_FMT_EXTENTS; 4001 4001 } 4002 4002 ASSERT(ip->i_d.di_anextents == 0); 4003 - VN_HOLD(XFS_ITOV(ip)); 4003 + IHOLD(ip); 4004 4004 xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL); 4005 4005 xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); 4006 4006 switch (ip->i_d.di_format) { ··· 6096 6096 tp = cur->bc_tp; 6097 6097 licp = &tp->t_items; 6098 6098 while (!bp && licp != NULL) { 6099 - if (XFS_LIC_ARE_ALL_FREE(licp)) { 6099 + if (xfs_lic_are_all_free(licp)) { 6100 6100 licp = licp->lic_next; 6101 6101 continue; 6102 6102 } ··· 6106 6106 xfs_buf_log_item_t *bip; 6107 6107 xfs_buf_t *lbp; 6108 6108 6109 - if (XFS_LIC_ISFREE(licp, i)) { 6109 + if (xfs_lic_isfree(licp, i)) { 6110 6110 continue; 6111 6111 } 6112 6112 6113 - lidp = XFS_LIC_SLOT(licp, i); 6113 + lidp = xfs_lic_slot(licp, i); 6114 6114 lip = lidp->lid_item; 6115 6115 if (lip->li_type != XFS_LI_BUF) 6116 6116 continue; ··· 6367 6367 mp = ip->i_mount; 6368 6368 ifp = XFS_IFORK_PTR(ip, whichfork); 6369 6369 if ( XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_EXTENTS ) { 6370 - if (unlikely(xfs_bmap_count_leaves(ifp, 0, 6370 + xfs_bmap_count_leaves(ifp, 0, 6371 6371 ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t), 6372 - count) < 0)) { 6373 - XFS_ERROR_REPORT("xfs_bmap_count_blocks(1)", 6374 - XFS_ERRLEVEL_LOW, mp); 6375 - return XFS_ERROR(EFSCORRUPTED); 6376 - } 6372 + count); 6377 6373 return 0; 6378 6374 } 6379 6375 ··· 6450 6454 for (;;) { 6451 6455 nextbno = be64_to_cpu(block->bb_rightsib); 6452 6456 numrecs = be16_to_cpu(block->bb_numrecs); 6453 - if (unlikely(xfs_bmap_disk_count_leaves(0, 6454 - block, numrecs, count) < 0)) { 6455 - xfs_trans_brelse(tp, bp); 6456 - XFS_ERROR_REPORT("xfs_bmap_count_tree(2)", 6457 - XFS_ERRLEVEL_LOW, mp); 6458 - return XFS_ERROR(EFSCORRUPTED); 6459 - } 6457 + xfs_bmap_disk_count_leaves(0, block, numrecs, count); 6460 6458 xfs_trans_brelse(tp, bp); 6461 6459 if (nextbno == NULLFSBLOCK) 6462 6460 break; ··· 6468 6478 /* 6469 6479 * Count leaf blocks given a range of extent records. 6470 6480 */ 6471 - STATIC int 6481 + STATIC void 6472 6482 xfs_bmap_count_leaves( 6473 6483 xfs_ifork_t *ifp, 6474 6484 xfs_extnum_t idx, ··· 6481 6491 xfs_bmbt_rec_host_t *frp = xfs_iext_get_ext(ifp, idx + b); 6482 6492 *count += xfs_bmbt_get_blockcount(frp); 6483 6493 } 6484 - return 0; 6485 6494 } 6486 6495 6487 6496 /* 6488 6497 * Count leaf blocks given a range of extent records originally 6489 6498 * in btree format. 6490 6499 */ 6491 - STATIC int 6500 + STATIC void 6492 6501 xfs_bmap_disk_count_leaves( 6493 6502 xfs_extnum_t idx, 6494 6503 xfs_bmbt_block_t *block, ··· 6501 6512 frp = XFS_BTREE_REC_ADDR(xfs_bmbt, block, idx + b); 6502 6513 *count += xfs_bmbt_disk_get_blockcount(frp); 6503 6514 } 6504 - return 0; 6505 6515 }
+39 -66
fs/xfs/xfs_btree.c
··· 46 46 /* 47 47 * Btree magic numbers. 48 48 */ 49 - const __uint32_t xfs_magics[XFS_BTNUM_MAX] = 50 - { 49 + const __uint32_t xfs_magics[XFS_BTNUM_MAX] = { 51 50 XFS_ABTB_MAGIC, XFS_ABTC_MAGIC, XFS_BMAP_MAGIC, XFS_IBT_MAGIC 52 51 }; 53 - 54 - /* 55 - * Prototypes for internal routines. 56 - */ 57 - 58 - /* 59 - * Checking routine: return maxrecs for the block. 60 - */ 61 - STATIC int /* number of records fitting in block */ 62 - xfs_btree_maxrecs( 63 - xfs_btree_cur_t *cur, /* btree cursor */ 64 - xfs_btree_block_t *block);/* generic btree block pointer */ 65 - 66 - /* 67 - * Internal routines. 68 - */ 69 - 70 - /* 71 - * Retrieve the block pointer from the cursor at the given level. 72 - * This may be a bmap btree root or from a buffer. 73 - */ 74 - STATIC xfs_btree_block_t * /* generic btree block pointer */ 75 - xfs_btree_get_block( 76 - xfs_btree_cur_t *cur, /* btree cursor */ 77 - int level, /* level in btree */ 78 - struct xfs_buf **bpp); /* buffer containing the block */ 79 52 80 53 /* 81 54 * Checking routine: return maxrecs for the block. ··· 430 457 } 431 458 432 459 /* 433 - * Change the cursor to point to the first record at the given level. 434 - * Other levels are unaffected. 435 - */ 436 - int /* success=1, failure=0 */ 437 - xfs_btree_firstrec( 438 - xfs_btree_cur_t *cur, /* btree cursor */ 439 - int level) /* level to change */ 440 - { 441 - xfs_btree_block_t *block; /* generic btree block pointer */ 442 - xfs_buf_t *bp; /* buffer containing block */ 443 - 444 - /* 445 - * Get the block pointer for this level. 446 - */ 447 - block = xfs_btree_get_block(cur, level, &bp); 448 - xfs_btree_check_block(cur, block, level, bp); 449 - /* 450 - * It's empty, there is no such record. 451 - */ 452 - if (!block->bb_h.bb_numrecs) 453 - return 0; 454 - /* 455 - * Set the ptr value to 1, that's the first record/key. 456 - */ 457 - cur->bc_ptrs[level] = 1; 458 - return 1; 459 - } 460 - 461 - /* 462 460 * Retrieve the block pointer from the cursor at the given level. 463 461 * This may be a bmap btree root or from a buffer. 464 462 */ ··· 570 626 cur->bc_private.a.agbp = agbp; 571 627 cur->bc_private.a.agno = agno; 572 628 break; 629 + case XFS_BTNUM_INO: 630 + /* 631 + * Inode allocation btree fields. 632 + */ 633 + cur->bc_private.a.agbp = agbp; 634 + cur->bc_private.a.agno = agno; 635 + break; 573 636 case XFS_BTNUM_BMAP: 574 637 /* 575 638 * Bmap btree fields. ··· 588 637 cur->bc_private.b.allocated = 0; 589 638 cur->bc_private.b.flags = 0; 590 639 cur->bc_private.b.whichfork = whichfork; 591 - break; 592 - case XFS_BTNUM_INO: 593 - /* 594 - * Inode allocation btree fields. 595 - */ 596 - cur->bc_private.i.agbp = agbp; 597 - cur->bc_private.i.agno = agno; 598 640 break; 599 641 default: 600 642 ASSERT(0); ··· 612 668 return be64_to_cpu(block->bb_u.l.bb_rightsib) == NULLDFSBNO; 613 669 else 614 670 return be32_to_cpu(block->bb_u.s.bb_rightsib) == NULLAGBLOCK; 671 + } 672 + 673 + /* 674 + * Change the cursor to point to the first record at the given level. 675 + * Other levels are unaffected. 676 + */ 677 + int /* success=1, failure=0 */ 678 + xfs_btree_firstrec( 679 + xfs_btree_cur_t *cur, /* btree cursor */ 680 + int level) /* level to change */ 681 + { 682 + xfs_btree_block_t *block; /* generic btree block pointer */ 683 + xfs_buf_t *bp; /* buffer containing block */ 684 + 685 + /* 686 + * Get the block pointer for this level. 687 + */ 688 + block = xfs_btree_get_block(cur, level, &bp); 689 + xfs_btree_check_block(cur, block, level, bp); 690 + /* 691 + * It's empty, there is no such record. 692 + */ 693 + if (!block->bb_h.bb_numrecs) 694 + return 0; 695 + /* 696 + * Set the ptr value to 1, that's the first record/key. 697 + */ 698 + cur->bc_ptrs[level] = 1; 699 + return 1; 615 700 } 616 701 617 702 /* ··· 863 890 case XFS_BTNUM_INO: 864 891 i = XFS_BUF_TO_INOBT_BLOCK(cur->bc_bufs[lev]); 865 892 if ((lr & XFS_BTCUR_LEFTRA) && be32_to_cpu(i->bb_leftsib) != NULLAGBLOCK) { 866 - xfs_btree_reada_bufs(cur->bc_mp, cur->bc_private.i.agno, 893 + xfs_btree_reada_bufs(cur->bc_mp, cur->bc_private.a.agno, 867 894 be32_to_cpu(i->bb_leftsib), 1); 868 895 rval++; 869 896 } 870 897 if ((lr & XFS_BTCUR_RIGHTRA) && be32_to_cpu(i->bb_rightsib) != NULLAGBLOCK) { 871 - xfs_btree_reada_bufs(cur->bc_mp, cur->bc_private.i.agno, 898 + xfs_btree_reada_bufs(cur->bc_mp, cur->bc_private.a.agno, 872 899 be32_to_cpu(i->bb_rightsib), 1); 873 900 rval++; 874 901 }
+2 -6
fs/xfs/xfs_btree.h
··· 158 158 __uint8_t bc_blocklog; /* log2(blocksize) of btree blocks */ 159 159 xfs_btnum_t bc_btnum; /* identifies which btree type */ 160 160 union { 161 - struct { /* needed for BNO, CNT */ 162 - struct xfs_buf *agbp; /* agf buffer pointer */ 161 + struct { /* needed for BNO, CNT, INO */ 162 + struct xfs_buf *agbp; /* agf/agi buffer pointer */ 163 163 xfs_agnumber_t agno; /* ag number */ 164 164 } a; 165 165 struct { /* needed for BMAP */ ··· 172 172 char flags; /* flags */ 173 173 #define XFS_BTCUR_BPRV_WASDEL 1 /* was delayed */ 174 174 } b; 175 - struct { /* needed for INO */ 176 - struct xfs_buf *agbp; /* agi buffer pointer */ 177 - xfs_agnumber_t agno; /* ag number */ 178 - } i; 179 175 } bc_private; /* per-btree type data */ 180 176 } xfs_btree_cur_t; 181 177
+2 -2
fs/xfs/xfs_buf_item.c
··· 737 737 bip->bli_format.blf_len = (ushort)BTOBB(XFS_BUF_COUNT(bp)); 738 738 bip->bli_format.blf_map_size = map_size; 739 739 #ifdef XFS_BLI_TRACE 740 - bip->bli_trace = ktrace_alloc(XFS_BLI_TRACE_SIZE, KM_SLEEP); 740 + bip->bli_trace = ktrace_alloc(XFS_BLI_TRACE_SIZE, KM_NOFS); 741 741 #endif 742 742 743 743 #ifdef XFS_TRANS_DEBUG ··· 1056 1056 anyway. */ 1057 1057 XFS_BUF_SET_BRELSE_FUNC(bp,xfs_buf_error_relse); 1058 1058 XFS_BUF_DONE(bp); 1059 - XFS_BUF_V_IODONESEMA(bp); 1059 + XFS_BUF_FINISH_IOWAIT(bp); 1060 1060 } 1061 1061 return; 1062 1062 }
+8 -25
fs/xfs/xfs_dfrag.c
··· 128 128 xfs_swapext_t *sxp) 129 129 { 130 130 xfs_mount_t *mp; 131 - xfs_inode_t *ips[2]; 132 131 xfs_trans_t *tp; 133 132 xfs_bstat_t *sbp = &sxp->sx_stat; 134 - bhv_vnode_t *vp, *tvp; 135 133 xfs_ifork_t *tempifp, *ifp, *tifp; 136 134 int ilf_fields, tilf_fields; 137 135 static uint lock_flags = XFS_ILOCK_EXCL | XFS_IOLOCK_EXCL; ··· 148 150 } 149 151 150 152 sbp = &sxp->sx_stat; 151 - vp = XFS_ITOV(ip); 152 - tvp = XFS_ITOV(tip); 153 153 154 - /* Lock in i_ino order */ 155 - if (ip->i_ino < tip->i_ino) { 156 - ips[0] = ip; 157 - ips[1] = tip; 158 - } else { 159 - ips[0] = tip; 160 - ips[1] = ip; 161 - } 162 - 163 - xfs_lock_inodes(ips, 2, lock_flags); 154 + xfs_lock_two_inodes(ip, tip, lock_flags); 164 155 locked = 1; 165 156 166 157 /* Verify that both files have the same format */ ··· 171 184 goto error0; 172 185 } 173 186 174 - if (VN_CACHED(tvp) != 0) { 187 + if (VN_CACHED(VFS_I(tip)) != 0) { 175 188 xfs_inval_cached_trace(tip, 0, -1, 0, -1); 176 189 error = xfs_flushinval_pages(tip, 0, -1, 177 190 FI_REMAPF_LOCKED); ··· 180 193 } 181 194 182 195 /* Verify O_DIRECT for ftmp */ 183 - if (VN_CACHED(tvp) != 0) { 196 + if (VN_CACHED(VFS_I(tip)) != 0) { 184 197 error = XFS_ERROR(EINVAL); 185 198 goto error0; 186 199 } ··· 224 237 * vop_read (or write in the case of autogrow) they block on the iolock 225 238 * until we have switched the extents. 226 239 */ 227 - if (VN_MAPPED(vp)) { 240 + if (VN_MAPPED(VFS_I(ip))) { 228 241 error = XFS_ERROR(EBUSY); 229 242 goto error0; 230 243 } ··· 252 265 locked = 0; 253 266 goto error0; 254 267 } 255 - xfs_lock_inodes(ips, 2, XFS_ILOCK_EXCL); 268 + xfs_lock_two_inodes(ip, tip, XFS_ILOCK_EXCL); 256 269 257 270 /* 258 271 * Count the number of extended attribute blocks ··· 337 350 break; 338 351 } 339 352 340 - /* 341 - * Increment vnode ref counts since xfs_trans_commit & 342 - * xfs_trans_cancel will both unlock the inodes and 343 - * decrement the associated ref counts. 344 - */ 345 - VN_HOLD(vp); 346 - VN_HOLD(tvp); 347 353 354 + IHOLD(ip); 348 355 xfs_trans_ijoin(tp, ip, lock_flags); 356 + 357 + IHOLD(tip); 349 358 xfs_trans_ijoin(tp, tip, lock_flags); 350 359 351 360 xfs_trans_log_inode(tp, ip, ilf_fields);
+1 -4
fs/xfs/xfs_error.c
··· 58 58 } 59 59 return e; 60 60 } 61 - #endif 62 - 63 - #if (defined(DEBUG) || defined(INDUCE_IO_ERROR)) 64 61 65 62 int xfs_etest[XFS_NUM_INJECT_ERROR]; 66 63 int64_t xfs_etest_fsid[XFS_NUM_INJECT_ERROR]; ··· 151 154 152 155 return 0; 153 156 } 154 - #endif /* DEBUG || INDUCE_IO_ERROR */ 157 + #endif /* DEBUG */ 155 158 156 159 static void 157 160 xfs_fs_vcmn_err(int level, xfs_mount_t *mp, char *fmt, va_list ap)
+2 -10
fs/xfs/xfs_error.h
··· 125 125 #define XFS_RANDOM_DIOWRITE_IOERR (XFS_RANDOM_DEFAULT/10) 126 126 #define XFS_RANDOM_BMAPIFORMAT XFS_RANDOM_DEFAULT 127 127 128 - #if (defined(DEBUG) || defined(INDUCE_IO_ERROR)) 128 + #ifdef DEBUG 129 129 extern int xfs_error_test(int, int *, char *, int, char *, unsigned long); 130 130 131 131 #define XFS_NUM_INJECT_ERROR 10 132 - 133 - #ifdef __ANSI_CPP__ 134 - #define XFS_TEST_ERROR(expr, mp, tag, rf) \ 135 - ((expr) || \ 136 - xfs_error_test((tag), (mp)->m_fixedfsid, #expr, __LINE__, __FILE__, \ 137 - (rf))) 138 - #else 139 132 #define XFS_TEST_ERROR(expr, mp, tag, rf) \ 140 133 ((expr) || \ 141 134 xfs_error_test((tag), (mp)->m_fixedfsid, "expr", __LINE__, __FILE__, \ 142 135 (rf))) 143 - #endif /* __ANSI_CPP__ */ 144 136 145 137 extern int xfs_errortag_add(int error_tag, xfs_mount_t *mp); 146 138 extern int xfs_errortag_clearall(xfs_mount_t *mp, int loud); ··· 140 148 #define XFS_TEST_ERROR(expr, mp, tag, rf) (expr) 141 149 #define xfs_errortag_add(tag, mp) (ENOSYS) 142 150 #define xfs_errortag_clearall(mp, loud) (ENOSYS) 143 - #endif /* (DEBUG || INDUCE_IO_ERROR) */ 151 + #endif /* DEBUG */ 144 152 145 153 /* 146 154 * XFS panic tags -- allow a call to xfs_cmn_err() be turned into
+1 -1
fs/xfs/xfs_filestream.c
··· 400 400 if (!item_zone) 401 401 return -ENOMEM; 402 402 #ifdef XFS_FILESTREAMS_TRACE 403 - xfs_filestreams_trace_buf = ktrace_alloc(XFS_FSTRM_KTRACE_SIZE, KM_SLEEP); 403 + xfs_filestreams_trace_buf = ktrace_alloc(XFS_FSTRM_KTRACE_SIZE, KM_NOFS); 404 404 #endif 405 405 return 0; 406 406 }
+15 -15
fs/xfs/xfs_ialloc_btree.c
··· 181 181 * then we can get rid of this level. 182 182 */ 183 183 if (numrecs == 1 && level > 0) { 184 - agbp = cur->bc_private.i.agbp; 184 + agbp = cur->bc_private.a.agbp; 185 185 agi = XFS_BUF_TO_AGI(agbp); 186 186 /* 187 187 * pp is still set to the first pointer in the block. ··· 194 194 * Free the block. 195 195 */ 196 196 if ((error = xfs_free_extent(cur->bc_tp, 197 - XFS_AGB_TO_FSB(mp, cur->bc_private.i.agno, bno), 1))) 197 + XFS_AGB_TO_FSB(mp, cur->bc_private.a.agno, bno), 1))) 198 198 return error; 199 199 xfs_trans_binval(cur->bc_tp, bp); 200 200 xfs_ialloc_log_agi(cur->bc_tp, agbp, ··· 379 379 rrecs = be16_to_cpu(right->bb_numrecs); 380 380 rbp = bp; 381 381 if ((error = xfs_btree_read_bufs(mp, cur->bc_tp, 382 - cur->bc_private.i.agno, lbno, 0, &lbp, 382 + cur->bc_private.a.agno, lbno, 0, &lbp, 383 383 XFS_INO_BTREE_REF))) 384 384 return error; 385 385 left = XFS_BUF_TO_INOBT_BLOCK(lbp); ··· 401 401 lrecs = be16_to_cpu(left->bb_numrecs); 402 402 lbp = bp; 403 403 if ((error = xfs_btree_read_bufs(mp, cur->bc_tp, 404 - cur->bc_private.i.agno, rbno, 0, &rbp, 404 + cur->bc_private.a.agno, rbno, 0, &rbp, 405 405 XFS_INO_BTREE_REF))) 406 406 return error; 407 407 right = XFS_BUF_TO_INOBT_BLOCK(rbp); ··· 484 484 xfs_buf_t *rrbp; 485 485 486 486 if ((error = xfs_btree_read_bufs(mp, cur->bc_tp, 487 - cur->bc_private.i.agno, be32_to_cpu(left->bb_rightsib), 0, 487 + cur->bc_private.a.agno, be32_to_cpu(left->bb_rightsib), 0, 488 488 &rrbp, XFS_INO_BTREE_REF))) 489 489 return error; 490 490 rrblock = XFS_BUF_TO_INOBT_BLOCK(rrbp); ··· 497 497 * Free the deleting block. 498 498 */ 499 499 if ((error = xfs_free_extent(cur->bc_tp, XFS_AGB_TO_FSB(mp, 500 - cur->bc_private.i.agno, rbno), 1))) 500 + cur->bc_private.a.agno, rbno), 1))) 501 501 return error; 502 502 xfs_trans_binval(cur->bc_tp, rbp); 503 503 /* ··· 854 854 { 855 855 xfs_agi_t *agi; /* a.g. inode header */ 856 856 857 - agi = XFS_BUF_TO_AGI(cur->bc_private.i.agbp); 857 + agi = XFS_BUF_TO_AGI(cur->bc_private.a.agbp); 858 858 agno = be32_to_cpu(agi->agi_seqno); 859 859 agbno = be32_to_cpu(agi->agi_root); 860 860 } ··· 1089 1089 * Set up the left neighbor as "left". 1090 1090 */ 1091 1091 if ((error = xfs_btree_read_bufs(cur->bc_mp, cur->bc_tp, 1092 - cur->bc_private.i.agno, be32_to_cpu(right->bb_leftsib), 1092 + cur->bc_private.a.agno, be32_to_cpu(right->bb_leftsib), 1093 1093 0, &lbp, XFS_INO_BTREE_REF))) 1094 1094 return error; 1095 1095 left = XFS_BUF_TO_INOBT_BLOCK(lbp); ··· 1207 1207 /* 1208 1208 * Get a block & a buffer. 1209 1209 */ 1210 - agi = XFS_BUF_TO_AGI(cur->bc_private.i.agbp); 1210 + agi = XFS_BUF_TO_AGI(cur->bc_private.a.agbp); 1211 1211 args.tp = cur->bc_tp; 1212 1212 args.mp = cur->bc_mp; 1213 - args.fsbno = XFS_AGB_TO_FSB(args.mp, cur->bc_private.i.agno, 1213 + args.fsbno = XFS_AGB_TO_FSB(args.mp, cur->bc_private.a.agno, 1214 1214 be32_to_cpu(agi->agi_root)); 1215 1215 args.mod = args.minleft = args.alignment = args.total = args.wasdel = 1216 1216 args.isfl = args.userdata = args.minalignslop = 0; ··· 1233 1233 */ 1234 1234 agi->agi_root = cpu_to_be32(args.agbno); 1235 1235 be32_add_cpu(&agi->agi_level, 1); 1236 - xfs_ialloc_log_agi(args.tp, cur->bc_private.i.agbp, 1236 + xfs_ialloc_log_agi(args.tp, cur->bc_private.a.agbp, 1237 1237 XFS_AGI_ROOT | XFS_AGI_LEVEL); 1238 1238 /* 1239 1239 * At the previous root level there are now two blocks: the old ··· 1376 1376 * Set up the right neighbor as "right". 1377 1377 */ 1378 1378 if ((error = xfs_btree_read_bufs(cur->bc_mp, cur->bc_tp, 1379 - cur->bc_private.i.agno, be32_to_cpu(left->bb_rightsib), 1379 + cur->bc_private.a.agno, be32_to_cpu(left->bb_rightsib), 1380 1380 0, &rbp, XFS_INO_BTREE_REF))) 1381 1381 return error; 1382 1382 right = XFS_BUF_TO_INOBT_BLOCK(rbp); ··· 1492 1492 * Allocate the new block. 1493 1493 * If we can't do it, we're toast. Give up. 1494 1494 */ 1495 - args.fsbno = XFS_AGB_TO_FSB(args.mp, cur->bc_private.i.agno, lbno); 1495 + args.fsbno = XFS_AGB_TO_FSB(args.mp, cur->bc_private.a.agno, lbno); 1496 1496 args.mod = args.minleft = args.alignment = args.total = args.wasdel = 1497 1497 args.isfl = args.userdata = args.minalignslop = 0; 1498 1498 args.minlen = args.maxlen = args.prod = 1; ··· 1725 1725 1726 1726 agbno = be32_to_cpu(*XFS_INOBT_PTR_ADDR(block, cur->bc_ptrs[lev], cur)); 1727 1727 if ((error = xfs_btree_read_bufs(cur->bc_mp, cur->bc_tp, 1728 - cur->bc_private.i.agno, agbno, 0, &bp, 1728 + cur->bc_private.a.agno, agbno, 0, &bp, 1729 1729 XFS_INO_BTREE_REF))) 1730 1730 return error; 1731 1731 lev--; ··· 1897 1897 1898 1898 agbno = be32_to_cpu(*XFS_INOBT_PTR_ADDR(block, cur->bc_ptrs[lev], cur)); 1899 1899 if ((error = xfs_btree_read_bufs(cur->bc_mp, cur->bc_tp, 1900 - cur->bc_private.i.agno, agbno, 0, &bp, 1900 + cur->bc_private.a.agno, agbno, 0, &bp, 1901 1901 XFS_INO_BTREE_REF))) 1902 1902 return error; 1903 1903 lev--;
+20 -28
fs/xfs/xfs_iget.c
··· 216 216 mrlock_init(&ip->i_iolock, MRLOCK_BARRIER, "xfsio", ip->i_ino); 217 217 init_waitqueue_head(&ip->i_ipin_wait); 218 218 atomic_set(&ip->i_pincount, 0); 219 - initnsema(&ip->i_flock, 1, "xfsfino"); 219 + 220 + /* 221 + * Because we want to use a counting completion, complete 222 + * the flush completion once to allow a single access to 223 + * the flush completion without blocking. 224 + */ 225 + init_completion(&ip->i_flush); 226 + complete(&ip->i_flush); 220 227 221 228 if (lock_flags) 222 229 xfs_ilock(ip, lock_flags); ··· 295 288 *ipp = ip; 296 289 297 290 /* 291 + * Set up the Linux with the Linux inode. 292 + */ 293 + ip->i_vnode = inode; 294 + inode->i_private = ip; 295 + 296 + /* 298 297 * If we have a real type for an on-disk inode, we can set ops(&unlock) 299 298 * now. If it's a new inode being created, xfs_ialloc will handle it. 300 299 */ 301 - xfs_initialize_vnode(mp, inode, ip); 300 + if (ip->i_d.di_mode != 0) 301 + xfs_setup_inode(ip); 302 302 return 0; 303 303 } 304 304 ··· 425 411 * Special iput for brand-new inodes that are still locked 426 412 */ 427 413 void 428 - xfs_iput_new(xfs_inode_t *ip, 429 - uint lock_flags) 414 + xfs_iput_new( 415 + xfs_inode_t *ip, 416 + uint lock_flags) 430 417 { 431 - struct inode *inode = ip->i_vnode; 418 + struct inode *inode = VFS_I(ip); 432 419 433 420 xfs_itrace_entry(ip); 434 421 ··· 790 775 } 791 776 #endif 792 777 793 - /* 794 - * The following three routines simply manage the i_flock 795 - * semaphore embedded in the inode. This semaphore synchronizes 796 - * processes attempting to flush the in-core inode back to disk. 797 - */ 798 - void 799 - xfs_iflock(xfs_inode_t *ip) 800 - { 801 - psema(&(ip->i_flock), PINOD|PLTWAIT); 802 - } 803 - 804 - int 805 - xfs_iflock_nowait(xfs_inode_t *ip) 806 - { 807 - return (cpsema(&(ip->i_flock))); 808 - } 809 - 810 - void 811 - xfs_ifunlock(xfs_inode_t *ip) 812 - { 813 - ASSERT(issemalocked(&(ip->i_flock))); 814 - vsema(&(ip->i_flock)); 815 - }
+32 -34
fs/xfs/xfs_inode.c
··· 580 580 xfs_validate_extents(ifp, nex, XFS_EXTFMT_INODE(ip)); 581 581 for (i = 0; i < nex; i++, dp++) { 582 582 xfs_bmbt_rec_host_t *ep = xfs_iext_get_ext(ifp, i); 583 - ep->l0 = be64_to_cpu(get_unaligned(&dp->l0)); 584 - ep->l1 = be64_to_cpu(get_unaligned(&dp->l1)); 583 + ep->l0 = get_unaligned_be64(&dp->l0); 584 + ep->l1 = get_unaligned_be64(&dp->l1); 585 585 } 586 586 XFS_BMAP_TRACE_EXLIST(ip, nex, whichfork); 587 587 if (whichfork != XFS_DATA_FORK || ··· 835 835 * Do this before xfs_iformat in case it adds entries. 836 836 */ 837 837 #ifdef XFS_INODE_TRACE 838 - ip->i_trace = ktrace_alloc(INODE_TRACE_SIZE, KM_SLEEP); 838 + ip->i_trace = ktrace_alloc(INODE_TRACE_SIZE, KM_NOFS); 839 839 #endif 840 840 #ifdef XFS_BMAP_TRACE 841 - ip->i_xtrace = ktrace_alloc(XFS_BMAP_KTRACE_SIZE, KM_SLEEP); 841 + ip->i_xtrace = ktrace_alloc(XFS_BMAP_KTRACE_SIZE, KM_NOFS); 842 842 #endif 843 843 #ifdef XFS_BMBT_TRACE 844 - ip->i_btrace = ktrace_alloc(XFS_BMBT_KTRACE_SIZE, KM_SLEEP); 844 + ip->i_btrace = ktrace_alloc(XFS_BMBT_KTRACE_SIZE, KM_NOFS); 845 845 #endif 846 846 #ifdef XFS_RW_TRACE 847 - ip->i_rwtrace = ktrace_alloc(XFS_RW_KTRACE_SIZE, KM_SLEEP); 847 + ip->i_rwtrace = ktrace_alloc(XFS_RW_KTRACE_SIZE, KM_NOFS); 848 848 #endif 849 849 #ifdef XFS_ILOCK_TRACE 850 - ip->i_lock_trace = ktrace_alloc(XFS_ILOCK_KTRACE_SIZE, KM_SLEEP); 850 + ip->i_lock_trace = ktrace_alloc(XFS_ILOCK_KTRACE_SIZE, KM_NOFS); 851 851 #endif 852 852 #ifdef XFS_DIR2_TRACE 853 - ip->i_dir_trace = ktrace_alloc(XFS_DIR2_KTRACE_SIZE, KM_SLEEP); 853 + ip->i_dir_trace = ktrace_alloc(XFS_DIR2_KTRACE_SIZE, KM_NOFS); 854 854 #endif 855 855 856 856 /* ··· 1046 1046 { 1047 1047 xfs_ino_t ino; 1048 1048 xfs_inode_t *ip; 1049 - bhv_vnode_t *vp; 1050 1049 uint flags; 1051 1050 int error; 1051 + timespec_t tv; 1052 1052 1053 1053 /* 1054 1054 * Call the space management code to pick ··· 1077 1077 } 1078 1078 ASSERT(ip != NULL); 1079 1079 1080 - vp = XFS_ITOV(ip); 1081 1080 ip->i_d.di_mode = (__uint16_t)mode; 1082 1081 ip->i_d.di_onlink = 0; 1083 1082 ip->i_d.di_nlink = nlink; ··· 1129 1130 ip->i_size = 0; 1130 1131 ip->i_d.di_nextents = 0; 1131 1132 ASSERT(ip->i_d.di_nblocks == 0); 1132 - xfs_ichgtime(ip, XFS_ICHGTIME_CHG|XFS_ICHGTIME_ACC|XFS_ICHGTIME_MOD); 1133 + 1134 + nanotime(&tv); 1135 + ip->i_d.di_mtime.t_sec = (__int32_t)tv.tv_sec; 1136 + ip->i_d.di_mtime.t_nsec = (__int32_t)tv.tv_nsec; 1137 + ip->i_d.di_atime = ip->i_d.di_mtime; 1138 + ip->i_d.di_ctime = ip->i_d.di_mtime; 1139 + 1133 1140 /* 1134 1141 * di_gen will have been taken care of in xfs_iread. 1135 1142 */ ··· 1225 1220 xfs_trans_log_inode(tp, ip, flags); 1226 1221 1227 1222 /* now that we have an i_mode we can setup inode ops and unlock */ 1228 - xfs_initialize_vnode(tp->t_mountp, vp, ip); 1223 + xfs_setup_inode(ip); 1229 1224 1230 1225 *ipp = ip; 1231 1226 return 0; ··· 1404 1399 xfs_fsize_t last_byte; 1405 1400 xfs_off_t toss_start; 1406 1401 xfs_mount_t *mp; 1407 - bhv_vnode_t *vp; 1408 1402 int error = 0; 1409 1403 1410 1404 ASSERT(xfs_isilocked(ip, XFS_IOLOCK_EXCL)); ··· 1412 1408 (flags == XFS_ITRUNC_MAYBE)); 1413 1409 1414 1410 mp = ip->i_mount; 1415 - vp = XFS_ITOV(ip); 1416 1411 1417 1412 /* wait for the completion of any pending DIOs */ 1418 1413 if (new_size < ip->i_size) ··· 1460 1457 1461 1458 #ifdef DEBUG 1462 1459 if (new_size == 0) { 1463 - ASSERT(VN_CACHED(vp) == 0); 1460 + ASSERT(VN_CACHED(VFS_I(ip)) == 0); 1464 1461 } 1465 1462 #endif 1466 1463 return error; ··· 2633 2630 xfs_idestroy_fork(ip, XFS_ATTR_FORK); 2634 2631 mrfree(&ip->i_lock); 2635 2632 mrfree(&ip->i_iolock); 2636 - freesema(&ip->i_flock); 2637 2633 2638 2634 #ifdef XFS_INODE_TRACE 2639 2635 ktrace_free(ip->i_trace); ··· 3050 3048 /* 3051 3049 * xfs_iflush() will write a modified inode's changes out to the 3052 3050 * inode's on disk home. The caller must have the inode lock held 3053 - * in at least shared mode and the inode flush semaphore must be 3054 - * held as well. The inode lock will still be held upon return from 3051 + * in at least shared mode and the inode flush completion must be 3052 + * active as well. The inode lock will still be held upon return from 3055 3053 * the call and the caller is free to unlock it. 3056 - * The inode flush lock will be unlocked when the inode reaches the disk. 3054 + * The inode flush will be completed when the inode reaches the disk. 3057 3055 * The flags indicate how the inode's buffer should be written out. 3058 3056 */ 3059 3057 int ··· 3072 3070 XFS_STATS_INC(xs_iflush_count); 3073 3071 3074 3072 ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL|XFS_ILOCK_SHARED)); 3075 - ASSERT(issemalocked(&(ip->i_flock))); 3073 + ASSERT(!completion_done(&ip->i_flush)); 3076 3074 ASSERT(ip->i_d.di_format != XFS_DINODE_FMT_BTREE || 3077 3075 ip->i_d.di_nextents > ip->i_df.if_ext_max); 3078 3076 ··· 3235 3233 #endif 3236 3234 3237 3235 ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL|XFS_ILOCK_SHARED)); 3238 - ASSERT(issemalocked(&(ip->i_flock))); 3236 + ASSERT(!completion_done(&ip->i_flush)); 3239 3237 ASSERT(ip->i_d.di_format != XFS_DINODE_FMT_BTREE || 3240 3238 ip->i_d.di_nextents > ip->i_df.if_ext_max); 3241 3239 ··· 3467 3465 xfs_mount_t *mp) 3468 3466 { 3469 3467 xfs_inode_t *ip; 3470 - bhv_vnode_t *vp; 3471 3468 3472 3469 again: 3473 3470 XFS_MOUNT_ILOCK(mp); ··· 3481 3480 continue; 3482 3481 } 3483 3482 3484 - vp = XFS_ITOV_NULL(ip); 3485 - if (!vp) { 3483 + if (!VFS_I(ip)) { 3486 3484 XFS_MOUNT_IUNLOCK(mp); 3487 3485 xfs_finish_reclaim(ip, 0, XFS_IFLUSH_ASYNC); 3488 3486 goto again; 3489 3487 } 3490 3488 3491 - ASSERT(vn_count(vp) == 0); 3489 + ASSERT(vn_count(VFS_I(ip)) == 0); 3492 3490 3493 3491 ip = ip->i_mnext; 3494 3492 } while (ip != mp->m_inodes); ··· 3707 3707 * (all extents past */ 3708 3708 if (nex2) { 3709 3709 byte_diff = nex2 * sizeof(xfs_bmbt_rec_t); 3710 - nex2_ep = (xfs_bmbt_rec_t *) kmem_alloc(byte_diff, KM_SLEEP); 3710 + nex2_ep = (xfs_bmbt_rec_t *) kmem_alloc(byte_diff, KM_NOFS); 3711 3711 memmove(nex2_ep, &erp->er_extbuf[idx], byte_diff); 3712 3712 erp->er_extcount -= nex2; 3713 3713 xfs_iext_irec_update_extoffs(ifp, erp_idx + 1, -nex2); ··· 4007 4007 ifp->if_u1.if_extents = 4008 4008 kmem_realloc(ifp->if_u1.if_extents, 4009 4009 rnew_size, 4010 - ifp->if_real_bytes, 4011 - KM_SLEEP); 4010 + ifp->if_real_bytes, KM_NOFS); 4012 4011 } 4013 4012 if (rnew_size > ifp->if_real_bytes) { 4014 4013 memset(&ifp->if_u1.if_extents[ifp->if_bytes / ··· 4066 4067 xfs_ifork_t *ifp, /* inode fork pointer */ 4067 4068 int new_size) /* number of extents in file */ 4068 4069 { 4069 - ifp->if_u1.if_extents = kmem_alloc(new_size, KM_SLEEP); 4070 + ifp->if_u1.if_extents = kmem_alloc(new_size, KM_NOFS); 4070 4071 memset(ifp->if_u1.if_extents, 0, new_size); 4071 4072 if (ifp->if_bytes) { 4072 4073 memcpy(ifp->if_u1.if_extents, ifp->if_u2.if_inline_ext, ··· 4098 4099 } else { 4099 4100 ifp->if_u1.if_ext_irec = (xfs_ext_irec_t *) 4100 4101 kmem_realloc(ifp->if_u1.if_ext_irec, 4101 - new_size, size, KM_SLEEP); 4102 + new_size, size, KM_NOFS); 4102 4103 } 4103 4104 } 4104 4105 ··· 4340 4341 nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t); 4341 4342 ASSERT(nextents <= XFS_LINEAR_EXTS); 4342 4343 4343 - erp = (xfs_ext_irec_t *) 4344 - kmem_alloc(sizeof(xfs_ext_irec_t), KM_SLEEP); 4344 + erp = kmem_alloc(sizeof(xfs_ext_irec_t), KM_NOFS); 4345 4345 4346 4346 if (nextents == 0) { 4347 - ifp->if_u1.if_extents = kmem_alloc(XFS_IEXT_BUFSZ, KM_SLEEP); 4347 + ifp->if_u1.if_extents = kmem_alloc(XFS_IEXT_BUFSZ, KM_NOFS); 4348 4348 } else if (!ifp->if_real_bytes) { 4349 4349 xfs_iext_inline_to_direct(ifp, XFS_IEXT_BUFSZ); 4350 4350 } else if (ifp->if_real_bytes < XFS_IEXT_BUFSZ) { ··· 4391 4393 4392 4394 /* Initialize new extent record */ 4393 4395 erp = ifp->if_u1.if_ext_irec; 4394 - erp[erp_idx].er_extbuf = kmem_alloc(XFS_IEXT_BUFSZ, KM_SLEEP); 4396 + erp[erp_idx].er_extbuf = kmem_alloc(XFS_IEXT_BUFSZ, KM_NOFS); 4395 4397 ifp->if_real_bytes = nlists * XFS_IEXT_BUFSZ; 4396 4398 memset(erp[erp_idx].er_extbuf, 0, XFS_IEXT_BUFSZ); 4397 4399 erp[erp_idx].er_extcount = 0;
+36 -10
fs/xfs/xfs_inode.h
··· 87 87 * Flags for xfs_ichgtime(). 88 88 */ 89 89 #define XFS_ICHGTIME_MOD 0x1 /* data fork modification timestamp */ 90 - #define XFS_ICHGTIME_ACC 0x2 /* data fork access timestamp */ 91 - #define XFS_ICHGTIME_CHG 0x4 /* inode field change timestamp */ 90 + #define XFS_ICHGTIME_CHG 0x2 /* inode field change timestamp */ 92 91 93 92 /* 94 93 * Per-fork incore inode flags. ··· 203 204 struct xfs_inode *i_mprev; /* ptr to prev inode */ 204 205 struct xfs_mount *i_mount; /* fs mount struct ptr */ 205 206 struct list_head i_reclaim; /* reclaim list */ 206 - bhv_vnode_t *i_vnode; /* vnode backpointer */ 207 + struct inode *i_vnode; /* vnode backpointer */ 207 208 struct xfs_dquot *i_udquot; /* user dquot */ 208 209 struct xfs_dquot *i_gdquot; /* group dquot */ 209 210 ··· 222 223 struct xfs_inode_log_item *i_itemp; /* logging information */ 223 224 mrlock_t i_lock; /* inode lock */ 224 225 mrlock_t i_iolock; /* inode IO lock */ 225 - sema_t i_flock; /* inode flush lock */ 226 + struct completion i_flush; /* inode flush completion q */ 226 227 atomic_t i_pincount; /* inode pin count */ 227 228 wait_queue_head_t i_ipin_wait; /* inode pinning wait queue */ 228 229 spinlock_t i_flags_lock; /* inode i_flags lock */ ··· 261 262 262 263 #define XFS_ISIZE(ip) (((ip)->i_d.di_mode & S_IFMT) == S_IFREG) ? \ 263 264 (ip)->i_size : (ip)->i_d.di_size; 265 + 266 + /* Convert from vfs inode to xfs inode */ 267 + static inline struct xfs_inode *XFS_I(struct inode *inode) 268 + { 269 + return (struct xfs_inode *)inode->i_private; 270 + } 271 + 272 + /* convert from xfs inode to vfs inode */ 273 + static inline struct inode *VFS_I(struct xfs_inode *ip) 274 + { 275 + return (struct inode *)ip->i_vnode; 276 + } 264 277 265 278 /* 266 279 * i_flags helper functions ··· 450 439 #define XFS_ITRUNC_DEFINITE 0x1 451 440 #define XFS_ITRUNC_MAYBE 0x2 452 441 453 - #define XFS_ITOV(ip) ((ip)->i_vnode) 454 - #define XFS_ITOV_NULL(ip) ((ip)->i_vnode) 455 - 456 442 /* 457 443 * For multiple groups support: if S_ISGID bit is set in the parent 458 444 * directory, group of new file is set to that of the parent, and ··· 481 473 void xfs_iunlock(xfs_inode_t *, uint); 482 474 void xfs_ilock_demote(xfs_inode_t *, uint); 483 475 int xfs_isilocked(xfs_inode_t *, uint); 484 - void xfs_iflock(xfs_inode_t *); 485 - int xfs_iflock_nowait(xfs_inode_t *); 486 476 uint xfs_ilock_map_shared(xfs_inode_t *); 487 477 void xfs_iunlock_map_shared(xfs_inode_t *, uint); 488 - void xfs_ifunlock(xfs_inode_t *); 489 478 void xfs_ireclaim(xfs_inode_t *); 490 479 int xfs_finish_reclaim(xfs_inode_t *, int, int); 491 480 int xfs_finish_reclaim_all(struct xfs_mount *, int); ··· 527 522 void xfs_ichgtime(xfs_inode_t *, int); 528 523 xfs_fsize_t xfs_file_last_byte(xfs_inode_t *); 529 524 void xfs_lock_inodes(xfs_inode_t **, int, uint); 525 + void xfs_lock_two_inodes(xfs_inode_t *, xfs_inode_t *, uint); 530 526 531 527 void xfs_synchronize_atime(xfs_inode_t *); 532 528 void xfs_mark_inode_dirty_sync(xfs_inode_t *); ··· 575 569 extern struct kmem_zone *xfs_ifork_zone; 576 570 extern struct kmem_zone *xfs_inode_zone; 577 571 extern struct kmem_zone *xfs_ili_zone; 572 + 573 + /* 574 + * Manage the i_flush queue embedded in the inode. This completion 575 + * queue synchronizes processes attempting to flush the in-core 576 + * inode back to disk. 577 + */ 578 + static inline void xfs_iflock(xfs_inode_t *ip) 579 + { 580 + wait_for_completion(&ip->i_flush); 581 + } 582 + 583 + static inline int xfs_iflock_nowait(xfs_inode_t *ip) 584 + { 585 + return try_wait_for_completion(&ip->i_flush); 586 + } 587 + 588 + static inline void xfs_ifunlock(xfs_inode_t *ip) 589 + { 590 + complete(&ip->i_flush); 591 + } 578 592 579 593 #endif /* __KERNEL__ */ 580 594
+5 -6
fs/xfs/xfs_inode_item.c
··· 779 779 ASSERT(iip->ili_push_owner == current_pid()); 780 780 781 781 /* 782 - * If flushlock isn't locked anymore, chances are that the 783 - * inode flush completed and the inode was taken off the AIL. 784 - * So, just get out. 782 + * If a flush is not in progress anymore, chances are that the 783 + * inode was taken off the AIL. So, just get out. 785 784 */ 786 - if (!issemalocked(&(ip->i_flock)) || 785 + if (completion_done(&ip->i_flush) || 787 786 ((iip->ili_item.li_flags & XFS_LI_IN_AIL) == 0)) { 788 787 iip->ili_pushbuf_flag = 0; 789 788 xfs_iunlock(ip, XFS_ILOCK_SHARED); ··· 804 805 * If not, we can flush it async. 805 806 */ 806 807 dopush = ((iip->ili_item.li_flags & XFS_LI_IN_AIL) && 807 - issemalocked(&(ip->i_flock))); 808 + !completion_done(&ip->i_flush)); 808 809 iip->ili_pushbuf_flag = 0; 809 810 xfs_iunlock(ip, XFS_ILOCK_SHARED); 810 811 xfs_buftrace("INODE ITEM PUSH", bp); ··· 857 858 ip = iip->ili_inode; 858 859 859 860 ASSERT(xfs_isilocked(ip, XFS_ILOCK_SHARED)); 860 - ASSERT(issemalocked(&(ip->i_flock))); 861 + ASSERT(!completion_done(&ip->i_flush)); 861 862 /* 862 863 * Since we were able to lock the inode's flush lock and 863 864 * we found it on the AIL, the inode must be dirty. This
+1 -3
fs/xfs/xfs_itable.c
··· 59 59 { 60 60 xfs_icdinode_t *dic; /* dinode core info pointer */ 61 61 xfs_inode_t *ip; /* incore inode pointer */ 62 - bhv_vnode_t *vp; 63 62 int error; 64 63 65 64 error = xfs_iget(mp, NULL, ino, ··· 71 72 ASSERT(ip != NULL); 72 73 ASSERT(ip->i_blkno != (xfs_daddr_t)0); 73 74 74 - vp = XFS_ITOV(ip); 75 75 dic = &ip->i_d; 76 76 77 77 /* xfs_iget returns the following without needing ··· 83 85 buf->bs_uid = dic->di_uid; 84 86 buf->bs_gid = dic->di_gid; 85 87 buf->bs_size = dic->di_size; 86 - vn_atime_to_bstime(vp, &buf->bs_atime); 88 + vn_atime_to_bstime(VFS_I(ip), &buf->bs_atime); 87 89 buf->bs_mtime.tv_sec = dic->di_mtime.t_sec; 88 90 buf->bs_mtime.tv_nsec = dic->di_mtime.t_nsec; 89 91 buf->bs_ctime.tv_sec = dic->di_ctime.t_sec;
+40 -46
fs/xfs/xfs_log.c
··· 160 160 xlog_trace_iclog(xlog_in_core_t *iclog, uint state) 161 161 { 162 162 if (!iclog->ic_trace) 163 - iclog->ic_trace = ktrace_alloc(256, KM_SLEEP); 163 + iclog->ic_trace = ktrace_alloc(256, KM_NOFS); 164 164 ktrace_enter(iclog->ic_trace, 165 165 (void *)((unsigned long)state), 166 166 (void *)((unsigned long)current_pid()), ··· 336 336 } else { 337 337 xlog_trace_loggrant(log, ticket, "xfs_log_done: (permanent)"); 338 338 xlog_regrant_reserve_log_space(log, ticket); 339 - } 340 - 341 - /* If this ticket was a permanent reservation and we aren't 342 - * trying to release it, reset the inited flags; so next time 343 - * we write, a start record will be written out. 344 - */ 345 - if ((ticket->t_flags & XLOG_TIC_PERM_RESERV) && 346 - (flags & XFS_LOG_REL_PERM_RESERV) == 0) 339 + /* If this ticket was a permanent reservation and we aren't 340 + * trying to release it, reset the inited flags; so next time 341 + * we write, a start record will be written out. 342 + */ 347 343 ticket->t_flags |= XLOG_TIC_INITED; 344 + } 348 345 349 346 return lsn; 350 347 } /* xfs_log_done */ ··· 354 357 * Asynchronous forces are implemented by setting the WANT_SYNC 355 358 * bit in the appropriate in-core log and then returning. 356 359 * 357 - * Synchronous forces are implemented with a semaphore. All callers 358 - * to force a given lsn to disk will wait on a semaphore attached to the 360 + * Synchronous forces are implemented with a signal variable. All callers 361 + * to force a given lsn to disk will wait on a the sv attached to the 359 362 * specific in-core log. When given in-core log finally completes its 360 363 * write to disk, that thread will wake up all threads waiting on the 361 - * semaphore. 364 + * sv. 362 365 */ 363 366 int 364 367 _xfs_log_force( ··· 585 588 * mp - ubiquitous xfs mount point structure 586 589 */ 587 590 int 588 - xfs_log_mount_finish(xfs_mount_t *mp, int mfsi_flags) 591 + xfs_log_mount_finish(xfs_mount_t *mp) 589 592 { 590 593 int error; 591 594 592 595 if (!(mp->m_flags & XFS_MOUNT_NORECOVERY)) 593 - error = xlog_recover_finish(mp->m_log, mfsi_flags); 596 + error = xlog_recover_finish(mp->m_log); 594 597 else { 595 598 error = 0; 596 599 ASSERT(mp->m_flags & XFS_MOUNT_RDONLY); ··· 704 707 if (!(iclog->ic_state == XLOG_STATE_ACTIVE || 705 708 iclog->ic_state == XLOG_STATE_DIRTY)) { 706 709 if (!XLOG_FORCED_SHUTDOWN(log)) { 707 - sv_wait(&iclog->ic_forcesema, PMEM, 710 + sv_wait(&iclog->ic_force_wait, PMEM, 708 711 &log->l_icloglock, s); 709 712 } else { 710 713 spin_unlock(&log->l_icloglock); ··· 745 748 || iclog->ic_state == XLOG_STATE_DIRTY 746 749 || iclog->ic_state == XLOG_STATE_IOERROR) ) { 747 750 748 - sv_wait(&iclog->ic_forcesema, PMEM, 751 + sv_wait(&iclog->ic_force_wait, PMEM, 749 752 &log->l_icloglock, s); 750 753 } else { 751 754 spin_unlock(&log->l_icloglock); ··· 835 838 break; 836 839 tail_lsn = 0; 837 840 free_bytes -= tic->t_unit_res; 838 - sv_signal(&tic->t_sema); 841 + sv_signal(&tic->t_wait); 839 842 tic = tic->t_next; 840 843 } while (tic != log->l_write_headq); 841 844 } ··· 856 859 break; 857 860 tail_lsn = 0; 858 861 free_bytes -= need_bytes; 859 - sv_signal(&tic->t_sema); 862 + sv_signal(&tic->t_wait); 860 863 tic = tic->t_next; 861 864 } while (tic != log->l_reserve_headq); 862 865 } ··· 1282 1285 1283 1286 ASSERT(XFS_BUF_ISBUSY(iclog->ic_bp)); 1284 1287 ASSERT(XFS_BUF_VALUSEMA(iclog->ic_bp) <= 0); 1285 - sv_init(&iclog->ic_forcesema, SV_DEFAULT, "iclog-force"); 1286 - sv_init(&iclog->ic_writesema, SV_DEFAULT, "iclog-write"); 1288 + sv_init(&iclog->ic_force_wait, SV_DEFAULT, "iclog-force"); 1289 + sv_init(&iclog->ic_write_wait, SV_DEFAULT, "iclog-write"); 1287 1290 1288 1291 iclogp = &iclog->ic_next; 1289 1292 } ··· 1562 1565 1563 1566 iclog = log->l_iclog; 1564 1567 for (i=0; i<log->l_iclog_bufs; i++) { 1565 - sv_destroy(&iclog->ic_forcesema); 1566 - sv_destroy(&iclog->ic_writesema); 1568 + sv_destroy(&iclog->ic_force_wait); 1569 + sv_destroy(&iclog->ic_write_wait); 1567 1570 xfs_buf_free(iclog->ic_bp); 1568 1571 #ifdef XFS_LOG_TRACE 1569 1572 if (iclog->ic_trace != NULL) { ··· 1973 1976 /* Clean iclogs starting from the head. This ordering must be 1974 1977 * maintained, so an iclog doesn't become ACTIVE beyond one that 1975 1978 * is SYNCING. This is also required to maintain the notion that we use 1976 - * a counting semaphore to hold off would be writers to the log when every 1979 + * a ordered wait queue to hold off would be writers to the log when every 1977 1980 * iclog is trying to sync to disk. 1978 1981 * 1979 1982 * State Change: DIRTY -> ACTIVE ··· 2237 2240 xlog_state_clean_log(log); 2238 2241 2239 2242 /* wake up threads waiting in xfs_log_force() */ 2240 - sv_broadcast(&iclog->ic_forcesema); 2243 + sv_broadcast(&iclog->ic_force_wait); 2241 2244 2242 2245 iclog = iclog->ic_next; 2243 2246 } while (first_iclog != iclog); ··· 2299 2302 * the second completion goes through. 2300 2303 * 2301 2304 * Callbacks could take time, so they are done outside the scope of the 2302 - * global state machine log lock. Assume that the calls to cvsema won't 2303 - * take a long time. At least we know it won't sleep. 2305 + * global state machine log lock. 2304 2306 */ 2305 2307 STATIC void 2306 2308 xlog_state_done_syncing( ··· 2335 2339 * iclog buffer, we wake them all, one will get to do the 2336 2340 * I/O, the others get to wait for the result. 2337 2341 */ 2338 - sv_broadcast(&iclog->ic_writesema); 2342 + sv_broadcast(&iclog->ic_write_wait); 2339 2343 spin_unlock(&log->l_icloglock); 2340 2344 xlog_state_do_callback(log, aborted, iclog); /* also cleans log */ 2341 2345 } /* xlog_state_done_syncing */ ··· 2343 2347 2344 2348 /* 2345 2349 * If the head of the in-core log ring is not (ACTIVE or DIRTY), then we must 2346 - * sleep. The flush semaphore is set to the number of in-core buffers and 2347 - * decremented around disk syncing. Therefore, if all buffers are syncing, 2348 - * this semaphore will cause new writes to sleep until a sync completes. 2349 - * Otherwise, this code just does p() followed by v(). This approximates 2350 - * a sleep/wakeup except we can't race. 2350 + * sleep. We wait on the flush queue on the head iclog as that should be 2351 + * the first iclog to complete flushing. Hence if all iclogs are syncing, 2352 + * we will wait here and all new writes will sleep until a sync completes. 2351 2353 * 2352 2354 * The in-core logs are used in a circular fashion. They are not used 2353 2355 * out-of-order even when an iclog past the head is free. ··· 2502 2508 goto error_return; 2503 2509 2504 2510 XFS_STATS_INC(xs_sleep_logspace); 2505 - sv_wait(&tic->t_sema, PINOD|PLTWAIT, &log->l_grant_lock, s); 2511 + sv_wait(&tic->t_wait, PINOD|PLTWAIT, &log->l_grant_lock, s); 2506 2512 /* 2507 2513 * If we got an error, and the filesystem is shutting down, 2508 2514 * we'll catch it down below. So just continue... ··· 2528 2534 xlog_trace_loggrant(log, tic, 2529 2535 "xlog_grant_log_space: sleep 2"); 2530 2536 XFS_STATS_INC(xs_sleep_logspace); 2531 - sv_wait(&tic->t_sema, PINOD|PLTWAIT, &log->l_grant_lock, s); 2537 + sv_wait(&tic->t_wait, PINOD|PLTWAIT, &log->l_grant_lock, s); 2532 2538 2533 2539 if (XLOG_FORCED_SHUTDOWN(log)) { 2534 2540 spin_lock(&log->l_grant_lock); ··· 2627 2633 if (free_bytes < ntic->t_unit_res) 2628 2634 break; 2629 2635 free_bytes -= ntic->t_unit_res; 2630 - sv_signal(&ntic->t_sema); 2636 + sv_signal(&ntic->t_wait); 2631 2637 ntic = ntic->t_next; 2632 2638 } while (ntic != log->l_write_headq); 2633 2639 ··· 2638 2644 xlog_trace_loggrant(log, tic, 2639 2645 "xlog_regrant_write_log_space: sleep 1"); 2640 2646 XFS_STATS_INC(xs_sleep_logspace); 2641 - sv_wait(&tic->t_sema, PINOD|PLTWAIT, 2647 + sv_wait(&tic->t_wait, PINOD|PLTWAIT, 2642 2648 &log->l_grant_lock, s); 2643 2649 2644 2650 /* If we're shutting down, this tic is already ··· 2667 2673 if ((tic->t_flags & XLOG_TIC_IN_Q) == 0) 2668 2674 xlog_ins_ticketq(&log->l_write_headq, tic); 2669 2675 XFS_STATS_INC(xs_sleep_logspace); 2670 - sv_wait(&tic->t_sema, PINOD|PLTWAIT, &log->l_grant_lock, s); 2676 + sv_wait(&tic->t_wait, PINOD|PLTWAIT, &log->l_grant_lock, s); 2671 2677 2672 2678 /* If we're shutting down, this tic is already off the queue */ 2673 2679 if (XLOG_FORCED_SHUTDOWN(log)) { ··· 2910 2916 * 2. the current iclog is drity, and the previous iclog is in the 2911 2917 * active or dirty state. 2912 2918 * 2913 - * We may sleep (call psema) if: 2919 + * We may sleep if: 2914 2920 * 2915 2921 * 1. the current iclog is not in the active nor dirty state. 2916 2922 * 2. the current iclog dirty, and the previous iclog is not in the ··· 3007 3013 return XFS_ERROR(EIO); 3008 3014 } 3009 3015 XFS_STATS_INC(xs_log_force_sleep); 3010 - sv_wait(&iclog->ic_forcesema, PINOD, &log->l_icloglock, s); 3016 + sv_wait(&iclog->ic_force_wait, PINOD, &log->l_icloglock, s); 3011 3017 /* 3012 3018 * No need to grab the log lock here since we're 3013 3019 * only deciding whether or not to return EIO ··· 3090 3096 XLOG_STATE_SYNCING))) { 3091 3097 ASSERT(!(iclog->ic_state & XLOG_STATE_IOERROR)); 3092 3098 XFS_STATS_INC(xs_log_force_sleep); 3093 - sv_wait(&iclog->ic_prev->ic_writesema, PSWP, 3099 + sv_wait(&iclog->ic_prev->ic_write_wait, PSWP, 3094 3100 &log->l_icloglock, s); 3095 3101 *log_flushed = 1; 3096 3102 already_slept = 1; ··· 3110 3116 !(iclog->ic_state & (XLOG_STATE_ACTIVE | XLOG_STATE_DIRTY))) { 3111 3117 3112 3118 /* 3113 - * Don't wait on the forcesema if we know that we've 3119 + * Don't wait on completion if we know that we've 3114 3120 * gotten a log write error. 3115 3121 */ 3116 3122 if (iclog->ic_state & XLOG_STATE_IOERROR) { ··· 3118 3124 return XFS_ERROR(EIO); 3119 3125 } 3120 3126 XFS_STATS_INC(xs_log_force_sleep); 3121 - sv_wait(&iclog->ic_forcesema, PSWP, &log->l_icloglock, s); 3127 + sv_wait(&iclog->ic_force_wait, PSWP, &log->l_icloglock, s); 3122 3128 /* 3123 3129 * No need to grab the log lock here since we're 3124 3130 * only deciding whether or not to return EIO ··· 3174 3180 xlog_ticket_put(xlog_t *log, 3175 3181 xlog_ticket_t *ticket) 3176 3182 { 3177 - sv_destroy(&ticket->t_sema); 3183 + sv_destroy(&ticket->t_wait); 3178 3184 kmem_zone_free(xfs_log_ticket_zone, ticket); 3179 3185 } /* xlog_ticket_put */ 3180 3186 ··· 3264 3270 tic->t_trans_type = 0; 3265 3271 if (xflags & XFS_LOG_PERM_RESERV) 3266 3272 tic->t_flags |= XLOG_TIC_PERM_RESERV; 3267 - sv_init(&(tic->t_sema), SV_DEFAULT, "logtick"); 3273 + sv_init(&(tic->t_wait), SV_DEFAULT, "logtick"); 3268 3274 3269 3275 xlog_tic_reset_res(tic); 3270 3276 ··· 3551 3557 */ 3552 3558 if ((tic = log->l_reserve_headq)) { 3553 3559 do { 3554 - sv_signal(&tic->t_sema); 3560 + sv_signal(&tic->t_wait); 3555 3561 tic = tic->t_next; 3556 3562 } while (tic != log->l_reserve_headq); 3557 3563 } 3558 3564 3559 3565 if ((tic = log->l_write_headq)) { 3560 3566 do { 3561 - sv_signal(&tic->t_sema); 3567 + sv_signal(&tic->t_wait); 3562 3568 tic = tic->t_next; 3563 3569 } while (tic != log->l_write_headq); 3564 3570 }
+1 -1
fs/xfs/xfs_log.h
··· 149 149 struct xfs_buftarg *log_target, 150 150 xfs_daddr_t start_block, 151 151 int num_bblocks); 152 - int xfs_log_mount_finish(struct xfs_mount *mp, int); 152 + int xfs_log_mount_finish(struct xfs_mount *mp); 153 153 void xfs_log_move_tail(struct xfs_mount *mp, 154 154 xfs_lsn_t tail_lsn); 155 155 int xfs_log_notify(struct xfs_mount *mp,
+7 -7
fs/xfs/xfs_log_priv.h
··· 241 241 } xlog_res_t; 242 242 243 243 typedef struct xlog_ticket { 244 - sv_t t_sema; /* sleep on this semaphore : 20 */ 244 + sv_t t_wait; /* ticket wait queue : 20 */ 245 245 struct xlog_ticket *t_next; /* :4|8 */ 246 246 struct xlog_ticket *t_prev; /* :4|8 */ 247 247 xlog_tid_t t_tid; /* transaction identifier : 4 */ ··· 314 314 * xlog_rec_header_t into the reserved space. 315 315 * - ic_data follows, so a write to disk can start at the beginning of 316 316 * the iclog. 317 - * - ic_forcesema is used to implement synchronous forcing of the iclog to disk. 317 + * - ic_forcewait is used to implement synchronous forcing of the iclog to disk. 318 318 * - ic_next is the pointer to the next iclog in the ring. 319 319 * - ic_bp is a pointer to the buffer used to write this incore log to disk. 320 320 * - ic_log is a pointer back to the global log structure. ··· 339 339 * and move everything else out to subsequent cachelines. 340 340 */ 341 341 typedef struct xlog_iclog_fields { 342 - sv_t ic_forcesema; 343 - sv_t ic_writesema; 342 + sv_t ic_force_wait; 343 + sv_t ic_write_wait; 344 344 struct xlog_in_core *ic_next; 345 345 struct xlog_in_core *ic_prev; 346 346 struct xfs_buf *ic_bp; ··· 377 377 /* 378 378 * Defines to save our code from this glop. 379 379 */ 380 - #define ic_forcesema hic_fields.ic_forcesema 381 - #define ic_writesema hic_fields.ic_writesema 380 + #define ic_force_wait hic_fields.ic_force_wait 381 + #define ic_write_wait hic_fields.ic_write_wait 382 382 #define ic_next hic_fields.ic_next 383 383 #define ic_prev hic_fields.ic_prev 384 384 #define ic_bp hic_fields.ic_bp ··· 468 468 xfs_daddr_t *head_blk, 469 469 xfs_daddr_t *tail_blk); 470 470 extern int xlog_recover(xlog_t *log); 471 - extern int xlog_recover_finish(xlog_t *log, int mfsi_flags); 471 + extern int xlog_recover_finish(xlog_t *log); 472 472 extern void xlog_pack_data(xlog_t *log, xlog_in_core_t *iclog, int); 473 473 extern void xlog_recover_process_iunlinks(xlog_t *log); 474 474
+2 -5
fs/xfs/xfs_log_recover.c
··· 3940 3940 */ 3941 3941 int 3942 3942 xlog_recover_finish( 3943 - xlog_t *log, 3944 - int mfsi_flags) 3943 + xlog_t *log) 3945 3944 { 3946 3945 /* 3947 3946 * Now we're ready to do the transactions needed for the ··· 3968 3969 xfs_log_force(log->l_mp, (xfs_lsn_t)0, 3969 3970 (XFS_LOG_FORCE | XFS_LOG_SYNC)); 3970 3971 3971 - if ( (mfsi_flags & XFS_MFSI_NOUNLINK) == 0 ) { 3972 - xlog_recover_process_iunlinks(log); 3973 - } 3972 + xlog_recover_process_iunlinks(log); 3974 3973 3975 3974 xlog_recover_check_summary(log); 3976 3975
+27 -55
fs/xfs/xfs_mount.c
··· 128 128 * initialized. 129 129 */ 130 130 STATIC void 131 - xfs_mount_free( 131 + xfs_free_perag( 132 132 xfs_mount_t *mp) 133 133 { 134 134 if (mp->m_perag) { ··· 139 139 kmem_free(mp->m_perag[agno].pagb_list); 140 140 kmem_free(mp->m_perag); 141 141 } 142 - 143 - spinlock_destroy(&mp->m_ail_lock); 144 - spinlock_destroy(&mp->m_sb_lock); 145 - mutex_destroy(&mp->m_ilock); 146 - mutex_destroy(&mp->m_growlock); 147 - if (mp->m_quotainfo) 148 - XFS_QM_DONE(mp); 149 - 150 - if (mp->m_fsname != NULL) 151 - kmem_free(mp->m_fsname); 152 - if (mp->m_rtname != NULL) 153 - kmem_free(mp->m_rtname); 154 - if (mp->m_logname != NULL) 155 - kmem_free(mp->m_logname); 156 142 } 157 143 158 144 /* ··· 690 704 * Update alignment values based on mount options and sb values 691 705 */ 692 706 STATIC int 693 - xfs_update_alignment(xfs_mount_t *mp, int mfsi_flags, __uint64_t *update_flags) 707 + xfs_update_alignment(xfs_mount_t *mp, __uint64_t *update_flags) 694 708 { 695 709 xfs_sb_t *sbp = &(mp->m_sb); 696 710 697 - if (mp->m_dalign && !(mfsi_flags & XFS_MFSI_SECOND)) { 711 + if (mp->m_dalign) { 698 712 /* 699 713 * If stripe unit and stripe width are not multiples 700 714 * of the fs blocksize turn off alignment. ··· 850 864 * Check that the data (and log if separate) are an ok size. 851 865 */ 852 866 STATIC int 853 - xfs_check_sizes(xfs_mount_t *mp, int mfsi_flags) 867 + xfs_check_sizes(xfs_mount_t *mp) 854 868 { 855 869 xfs_buf_t *bp; 856 870 xfs_daddr_t d; ··· 873 887 return error; 874 888 } 875 889 876 - if (((mfsi_flags & XFS_MFSI_CLIENT) == 0) && 877 - mp->m_logdev_targp != mp->m_ddev_targp) { 890 + if (mp->m_logdev_targp != mp->m_ddev_targp) { 878 891 d = (xfs_daddr_t)XFS_FSB_TO_BB(mp, mp->m_sb.sb_logblocks); 879 892 if (XFS_BB_TO_FSB(mp, d) != mp->m_sb.sb_logblocks) { 880 893 cmn_err(CE_WARN, "XFS: size check 3 failed"); ··· 908 923 */ 909 924 int 910 925 xfs_mountfs( 911 - xfs_mount_t *mp, 912 - int mfsi_flags) 926 + xfs_mount_t *mp) 913 927 { 914 928 xfs_sb_t *sbp = &(mp->m_sb); 915 929 xfs_inode_t *rip; 916 930 __uint64_t resblks; 917 931 __int64_t update_flags = 0LL; 918 932 uint quotamount, quotaflags; 919 - int agno; 920 933 int uuid_mounted = 0; 921 934 int error = 0; 922 935 ··· 968 985 * allocator alignment is within an ag, therefore ag has 969 986 * to be aligned at stripe boundary. 970 987 */ 971 - error = xfs_update_alignment(mp, mfsi_flags, &update_flags); 988 + error = xfs_update_alignment(mp, &update_flags); 972 989 if (error) 973 990 goto error1; 974 991 ··· 987 1004 * since a single partition filesystem is identical to a single 988 1005 * partition volume/filesystem. 989 1006 */ 990 - if ((mfsi_flags & XFS_MFSI_SECOND) == 0 && 991 - (mp->m_flags & XFS_MOUNT_NOUUID) == 0) { 1007 + if ((mp->m_flags & XFS_MOUNT_NOUUID) == 0) { 992 1008 if (xfs_uuid_mount(mp)) { 993 1009 error = XFS_ERROR(EINVAL); 994 1010 goto error1; ··· 1015 1033 /* 1016 1034 * Check that the data (and log if separate) are an ok size. 1017 1035 */ 1018 - error = xfs_check_sizes(mp, mfsi_flags); 1036 + error = xfs_check_sizes(mp); 1019 1037 if (error) 1020 1038 goto error1; 1021 1039 ··· 1026 1044 if (error) { 1027 1045 cmn_err(CE_WARN, "XFS: RT mount failed"); 1028 1046 goto error1; 1029 - } 1030 - 1031 - /* 1032 - * For client case we are done now 1033 - */ 1034 - if (mfsi_flags & XFS_MFSI_CLIENT) { 1035 - return 0; 1036 1047 } 1037 1048 1038 1049 /* ··· 1052 1077 * Allocate and initialize the per-ag data. 1053 1078 */ 1054 1079 init_rwsem(&mp->m_peraglock); 1055 - mp->m_perag = 1056 - kmem_zalloc(sbp->sb_agcount * sizeof(xfs_perag_t), KM_SLEEP); 1080 + mp->m_perag = kmem_zalloc(sbp->sb_agcount * sizeof(xfs_perag_t), 1081 + KM_MAYFAIL); 1082 + if (!mp->m_perag) 1083 + goto error1; 1057 1084 1058 1085 mp->m_maxagi = xfs_initialize_perag(mp, sbp->sb_agcount); 1059 1086 ··· 1167 1190 * delayed until after the root and real-time bitmap inodes 1168 1191 * were consistently read in. 1169 1192 */ 1170 - error = xfs_log_mount_finish(mp, mfsi_flags); 1193 + error = xfs_log_mount_finish(mp); 1171 1194 if (error) { 1172 1195 cmn_err(CE_WARN, "XFS: log mount finish failed"); 1173 1196 goto error4; ··· 1176 1199 /* 1177 1200 * Complete the quota initialisation, post-log-replay component. 1178 1201 */ 1179 - error = XFS_QM_MOUNT(mp, quotamount, quotaflags, mfsi_flags); 1202 + error = XFS_QM_MOUNT(mp, quotamount, quotaflags); 1180 1203 if (error) 1181 1204 goto error4; 1182 1205 ··· 1210 1233 error3: 1211 1234 xfs_log_unmount_dealloc(mp); 1212 1235 error2: 1213 - for (agno = 0; agno < sbp->sb_agcount; agno++) 1214 - if (mp->m_perag[agno].pagb_list) 1215 - kmem_free(mp->m_perag[agno].pagb_list); 1216 - kmem_free(mp->m_perag); 1217 - mp->m_perag = NULL; 1218 - /* FALLTHROUGH */ 1236 + xfs_free_perag(mp); 1219 1237 error1: 1220 1238 if (uuid_mounted) 1221 1239 uuid_table_remove(&mp->m_sb.sb_uuid); ··· 1218 1246 } 1219 1247 1220 1248 /* 1221 - * xfs_unmountfs 1222 - * 1223 1249 * This flushes out the inodes,dquots and the superblock, unmounts the 1224 1250 * log and makes sure that incore structures are freed. 1225 1251 */ 1226 - int 1227 - xfs_unmountfs(xfs_mount_t *mp) 1252 + void 1253 + xfs_unmountfs( 1254 + struct xfs_mount *mp) 1228 1255 { 1229 - __uint64_t resblks; 1230 - int error = 0; 1256 + __uint64_t resblks; 1257 + int error; 1258 + 1259 + IRELE(mp->m_rootip); 1231 1260 1232 1261 /* 1233 1262 * We can potentially deadlock here if we have an inode cluster ··· 1285 1312 xfs_unmountfs_wait(mp); /* wait for async bufs */ 1286 1313 xfs_log_unmount(mp); /* Done! No more fs ops. */ 1287 1314 1288 - xfs_freesb(mp); 1289 - 1290 1315 /* 1291 1316 * All inodes from this mount point should be freed. 1292 1317 */ ··· 1293 1322 if ((mp->m_flags & XFS_MOUNT_NOUUID) == 0) 1294 1323 uuid_table_remove(&mp->m_sb.sb_uuid); 1295 1324 1296 - #if defined(DEBUG) || defined(INDUCE_IO_ERROR) 1325 + #if defined(DEBUG) 1297 1326 xfs_errortag_clearall(mp, 0); 1298 1327 #endif 1299 - xfs_mount_free(mp); 1300 - return 0; 1328 + xfs_free_perag(mp); 1329 + if (mp->m_quotainfo) 1330 + XFS_QM_DONE(mp); 1301 1331 } 1302 1332 1303 1333 STATIC void
+5 -12
fs/xfs/xfs_mount.h
··· 114 114 struct xfs_quotainfo; 115 115 116 116 typedef int (*xfs_qminit_t)(struct xfs_mount *, uint *, uint *); 117 - typedef int (*xfs_qmmount_t)(struct xfs_mount *, uint, uint, int); 117 + typedef int (*xfs_qmmount_t)(struct xfs_mount *, uint, uint); 118 118 typedef int (*xfs_qmunmount_t)(struct xfs_mount *); 119 119 typedef void (*xfs_qmdone_t)(struct xfs_mount *); 120 120 typedef void (*xfs_dqrele_t)(struct xfs_dquot *); ··· 158 158 159 159 #define XFS_QM_INIT(mp, mnt, fl) \ 160 160 (*(mp)->m_qm_ops->xfs_qminit)(mp, mnt, fl) 161 - #define XFS_QM_MOUNT(mp, mnt, fl, mfsi_flags) \ 162 - (*(mp)->m_qm_ops->xfs_qmmount)(mp, mnt, fl, mfsi_flags) 161 + #define XFS_QM_MOUNT(mp, mnt, fl) \ 162 + (*(mp)->m_qm_ops->xfs_qmmount)(mp, mnt, fl) 163 163 #define XFS_QM_UNMOUNT(mp) \ 164 164 (*(mp)->m_qm_ops->xfs_qmunmount)(mp) 165 165 #define XFS_QM_DONE(mp) \ ··· 442 442 /* 443 443 * Flags for xfs_mountfs 444 444 */ 445 - #define XFS_MFSI_SECOND 0x01 /* Secondary mount -- skip stuff */ 446 - #define XFS_MFSI_CLIENT 0x02 /* Is a client -- skip lots of stuff */ 447 - /* XFS_MFSI_RRINODES */ 448 - #define XFS_MFSI_NOUNLINK 0x08 /* Skip unlinked inode processing in */ 449 - /* log recovery */ 450 - #define XFS_MFSI_NO_QUOTACHECK 0x10 /* Skip quotacheck processing */ 451 - /* XFS_MFSI_CONVERT_SUNIT */ 452 445 #define XFS_MFSI_QUIET 0x40 /* Be silent if mount errors found */ 453 446 454 447 #define XFS_DADDR_TO_AGNO(mp,d) xfs_daddr_to_agno(mp,d) ··· 510 517 511 518 extern void xfs_mod_sb(xfs_trans_t *, __int64_t); 512 519 extern int xfs_log_sbcount(xfs_mount_t *, uint); 513 - extern int xfs_mountfs(xfs_mount_t *mp, int); 520 + extern int xfs_mountfs(xfs_mount_t *mp); 514 521 extern void xfs_mountfs_check_barriers(xfs_mount_t *mp); 515 522 516 - extern int xfs_unmountfs(xfs_mount_t *); 523 + extern void xfs_unmountfs(xfs_mount_t *); 517 524 extern int xfs_unmountfs_writesb(xfs_mount_t *); 518 525 extern int xfs_unmount_flush(xfs_mount_t *, int); 519 526 extern int xfs_mod_incore_sb(xfs_mount_t *, xfs_sb_field_t, int64_t, int);
+7 -12
fs/xfs/xfs_rtalloc.c
··· 74 74 */ 75 75 76 76 /* 77 - * xfs_lowbit32: get low bit set out of 32-bit argument, -1 if none set. 78 - */ 79 - STATIC int 80 - xfs_lowbit32( 81 - __uint32_t v) 82 - { 83 - if (v) 84 - return ffs(v) - 1; 85 - return -1; 86 - } 87 - 88 - /* 89 77 * Allocate space to the bitmap or summary file, and zero it, for growfs. 90 78 */ 91 79 STATIC int /* error */ ··· 438 450 } 439 451 bbno = XFS_BITTOBLOCK(mp, bno); 440 452 i = 0; 453 + ASSERT(minlen != 0); 441 454 log2len = xfs_highbit32(minlen); 442 455 /* 443 456 * Loop over all bitmap blocks (bbno + i is current block). ··· 607 618 xfs_suminfo_t sum; /* summary information for extents */ 608 619 609 620 ASSERT(minlen % prod == 0 && maxlen % prod == 0); 621 + ASSERT(maxlen != 0); 622 + 610 623 /* 611 624 * Loop over all the levels starting with maxlen. 612 625 * At each level, look at all the bitmap blocks, to see if there ··· 666 675 *rtblock = NULLRTBLOCK; 667 676 return 0; 668 677 } 678 + ASSERT(minlen != 0); 679 + ASSERT(maxlen != 0); 680 + 669 681 /* 670 682 * Loop over sizes, from maxlen down to minlen. 671 683 * This time, when we do the allocations, allow smaller ones ··· 1955 1961 nsbp->sb_blocksize * nsbp->sb_rextsize); 1956 1962 nsbp->sb_rextents = nsbp->sb_rblocks; 1957 1963 do_div(nsbp->sb_rextents, nsbp->sb_rextsize); 1964 + ASSERT(nsbp->sb_rextents != 0); 1958 1965 nsbp->sb_rextslog = xfs_highbit32(nsbp->sb_rextents); 1959 1966 nrsumlevels = nmp->m_rsumlevels = nsbp->sb_rextslog + 1; 1960 1967 nrsumsize =
+1 -1
fs/xfs/xfs_rw.c
··· 314 314 * ASYNC buffers. 315 315 */ 316 316 XFS_BUF_ERROR(bp, EIO); 317 - XFS_BUF_V_IODONESEMA(bp); 317 + XFS_BUF_FINISH_IOWAIT(bp); 318 318 } else { 319 319 xfs_buf_relse(bp); 320 320 }
+69 -6
fs/xfs/xfs_trans.c
··· 43 43 #include "xfs_quota.h" 44 44 #include "xfs_trans_priv.h" 45 45 #include "xfs_trans_space.h" 46 + #include "xfs_inode_item.h" 46 47 47 48 48 49 STATIC void xfs_trans_apply_sb_deltas(xfs_trans_t *); ··· 254 253 tp->t_mountp = mp; 255 254 tp->t_items_free = XFS_LIC_NUM_SLOTS; 256 255 tp->t_busy_free = XFS_LBC_NUM_SLOTS; 257 - XFS_LIC_INIT(&(tp->t_items)); 256 + xfs_lic_init(&(tp->t_items)); 258 257 XFS_LBC_INIT(&(tp->t_busy)); 259 258 return tp; 260 259 } ··· 283 282 ntp->t_mountp = tp->t_mountp; 284 283 ntp->t_items_free = XFS_LIC_NUM_SLOTS; 285 284 ntp->t_busy_free = XFS_LBC_NUM_SLOTS; 286 - XFS_LIC_INIT(&(ntp->t_items)); 285 + xfs_lic_init(&(ntp->t_items)); 287 286 XFS_LBC_INIT(&(ntp->t_busy)); 288 287 289 288 ASSERT(tp->t_flags & XFS_TRANS_PERM_LOG_RES); ··· 1170 1169 while (licp != NULL) { 1171 1170 lidp = licp->lic_descs; 1172 1171 for (i = 0; i < licp->lic_unused; i++, lidp++) { 1173 - if (XFS_LIC_ISFREE(licp, i)) { 1172 + if (xfs_lic_isfree(licp, i)) { 1174 1173 continue; 1175 1174 } 1176 1175 ··· 1217 1216 kmem_zone_free(xfs_trans_zone, tp); 1218 1217 } 1219 1218 1219 + /* 1220 + * Roll from one trans in the sequence of PERMANENT transactions to 1221 + * the next: permanent transactions are only flushed out when 1222 + * committed with XFS_TRANS_RELEASE_LOG_RES, but we still want as soon 1223 + * as possible to let chunks of it go to the log. So we commit the 1224 + * chunk we've been working on and get a new transaction to continue. 1225 + */ 1226 + int 1227 + xfs_trans_roll( 1228 + struct xfs_trans **tpp, 1229 + struct xfs_inode *dp) 1230 + { 1231 + struct xfs_trans *trans; 1232 + unsigned int logres, count; 1233 + int error; 1234 + 1235 + /* 1236 + * Ensure that the inode is always logged. 1237 + */ 1238 + trans = *tpp; 1239 + xfs_trans_log_inode(trans, dp, XFS_ILOG_CORE); 1240 + 1241 + /* 1242 + * Copy the critical parameters from one trans to the next. 1243 + */ 1244 + logres = trans->t_log_res; 1245 + count = trans->t_log_count; 1246 + *tpp = xfs_trans_dup(trans); 1247 + 1248 + /* 1249 + * Commit the current transaction. 1250 + * If this commit failed, then it'd just unlock those items that 1251 + * are not marked ihold. That also means that a filesystem shutdown 1252 + * is in progress. The caller takes the responsibility to cancel 1253 + * the duplicate transaction that gets returned. 1254 + */ 1255 + error = xfs_trans_commit(trans, 0); 1256 + if (error) 1257 + return (error); 1258 + 1259 + trans = *tpp; 1260 + 1261 + /* 1262 + * Reserve space in the log for th next transaction. 1263 + * This also pushes items in the "AIL", the list of logged items, 1264 + * out to disk if they are taking up space at the tail of the log 1265 + * that we want to use. This requires that either nothing be locked 1266 + * across this call, or that anything that is locked be logged in 1267 + * the prior and the next transactions. 1268 + */ 1269 + error = xfs_trans_reserve(trans, 0, logres, 0, 1270 + XFS_TRANS_PERM_LOG_RES, count); 1271 + /* 1272 + * Ensure that the inode is in the new transaction and locked. 1273 + */ 1274 + if (error) 1275 + return error; 1276 + 1277 + xfs_trans_ijoin(trans, dp, XFS_ILOCK_EXCL); 1278 + xfs_trans_ihold(trans, dp); 1279 + return 0; 1280 + } 1220 1281 1221 1282 /* 1222 1283 * THIS SHOULD BE REWRITTEN TO USE xfs_trans_next_item(). ··· 1316 1253 * Special case the chunk embedded in the transaction. 1317 1254 */ 1318 1255 licp = &(tp->t_items); 1319 - if (!(XFS_LIC_ARE_ALL_FREE(licp))) { 1256 + if (!(xfs_lic_are_all_free(licp))) { 1320 1257 xfs_trans_chunk_committed(licp, tp->t_lsn, abortflag); 1321 1258 } 1322 1259 ··· 1325 1262 */ 1326 1263 licp = licp->lic_next; 1327 1264 while (licp != NULL) { 1328 - ASSERT(!XFS_LIC_ARE_ALL_FREE(licp)); 1265 + ASSERT(!xfs_lic_are_all_free(licp)); 1329 1266 xfs_trans_chunk_committed(licp, tp->t_lsn, abortflag); 1330 1267 next_licp = licp->lic_next; 1331 1268 kmem_free(licp); ··· 1388 1325 1389 1326 lidp = licp->lic_descs; 1390 1327 for (i = 0; i < licp->lic_unused; i++, lidp++) { 1391 - if (XFS_LIC_ISFREE(licp, i)) { 1328 + if (xfs_lic_isfree(licp, i)) { 1392 1329 continue; 1393 1330 } 1394 1331
+1 -11
fs/xfs/xfs_trans.h
··· 210 210 * lic_unused to the right value (0 matches all free). The 211 211 * lic_descs.lid_index values are set up as each desc is allocated. 212 212 */ 213 - #define XFS_LIC_INIT(cp) xfs_lic_init(cp) 214 213 static inline void xfs_lic_init(xfs_log_item_chunk_t *cp) 215 214 { 216 215 cp->lic_free = XFS_LIC_FREEMASK; 217 216 } 218 217 219 - #define XFS_LIC_INIT_SLOT(cp,slot) xfs_lic_init_slot(cp, slot) 220 218 static inline void xfs_lic_init_slot(xfs_log_item_chunk_t *cp, int slot) 221 219 { 222 220 cp->lic_descs[slot].lid_index = (unsigned char)(slot); 223 221 } 224 222 225 - #define XFS_LIC_VACANCY(cp) xfs_lic_vacancy(cp) 226 223 static inline int xfs_lic_vacancy(xfs_log_item_chunk_t *cp) 227 224 { 228 225 return cp->lic_free & XFS_LIC_FREEMASK; 229 226 } 230 227 231 - #define XFS_LIC_ALL_FREE(cp) xfs_lic_all_free(cp) 232 228 static inline void xfs_lic_all_free(xfs_log_item_chunk_t *cp) 233 229 { 234 230 cp->lic_free = XFS_LIC_FREEMASK; 235 231 } 236 232 237 - #define XFS_LIC_ARE_ALL_FREE(cp) xfs_lic_are_all_free(cp) 238 233 static inline int xfs_lic_are_all_free(xfs_log_item_chunk_t *cp) 239 234 { 240 235 return ((cp->lic_free & XFS_LIC_FREEMASK) == XFS_LIC_FREEMASK); 241 236 } 242 237 243 - #define XFS_LIC_ISFREE(cp,slot) xfs_lic_isfree(cp,slot) 244 238 static inline int xfs_lic_isfree(xfs_log_item_chunk_t *cp, int slot) 245 239 { 246 240 return (cp->lic_free & (1 << slot)); 247 241 } 248 242 249 - #define XFS_LIC_CLAIM(cp,slot) xfs_lic_claim(cp,slot) 250 243 static inline void xfs_lic_claim(xfs_log_item_chunk_t *cp, int slot) 251 244 { 252 245 cp->lic_free &= ~(1 << slot); 253 246 } 254 247 255 - #define XFS_LIC_RELSE(cp,slot) xfs_lic_relse(cp,slot) 256 248 static inline void xfs_lic_relse(xfs_log_item_chunk_t *cp, int slot) 257 249 { 258 250 cp->lic_free |= 1 << slot; 259 251 } 260 252 261 - #define XFS_LIC_SLOT(cp,slot) xfs_lic_slot(cp,slot) 262 253 static inline xfs_log_item_desc_t * 263 254 xfs_lic_slot(xfs_log_item_chunk_t *cp, int slot) 264 255 { 265 256 return &(cp->lic_descs[slot]); 266 257 } 267 258 268 - #define XFS_LIC_DESC_TO_SLOT(dp) xfs_lic_desc_to_slot(dp) 269 259 static inline int xfs_lic_desc_to_slot(xfs_log_item_desc_t *dp) 270 260 { 271 261 return (uint)dp->lid_index; ··· 268 278 * All of this yields the address of the chunk, which is 269 279 * cast to a chunk pointer. 270 280 */ 271 - #define XFS_LIC_DESC_TO_CHUNK(dp) xfs_lic_desc_to_chunk(dp) 272 281 static inline xfs_log_item_chunk_t * 273 282 xfs_lic_desc_to_chunk(xfs_log_item_desc_t *dp) 274 283 { ··· 975 986 int *); 976 987 #define xfs_trans_commit(tp, flags) _xfs_trans_commit(tp, flags, NULL) 977 988 void xfs_trans_cancel(xfs_trans_t *, int); 989 + int xfs_trans_roll(struct xfs_trans **, struct xfs_inode *); 978 990 int xfs_trans_ail_init(struct xfs_mount *); 979 991 void xfs_trans_ail_destroy(struct xfs_mount *); 980 992 void xfs_trans_push_ail(struct xfs_mount *, xfs_lsn_t);
+6 -6
fs/xfs/xfs_trans_buf.c
··· 1021 1021 bp = NULL; 1022 1022 len = BBTOB(len); 1023 1023 licp = &tp->t_items; 1024 - if (!XFS_LIC_ARE_ALL_FREE(licp)) { 1024 + if (!xfs_lic_are_all_free(licp)) { 1025 1025 for (i = 0; i < licp->lic_unused; i++) { 1026 1026 /* 1027 1027 * Skip unoccupied slots. 1028 1028 */ 1029 - if (XFS_LIC_ISFREE(licp, i)) { 1029 + if (xfs_lic_isfree(licp, i)) { 1030 1030 continue; 1031 1031 } 1032 1032 1033 - lidp = XFS_LIC_SLOT(licp, i); 1033 + lidp = xfs_lic_slot(licp, i); 1034 1034 blip = (xfs_buf_log_item_t *)lidp->lid_item; 1035 1035 if (blip->bli_item.li_type != XFS_LI_BUF) { 1036 1036 continue; ··· 1074 1074 bp = NULL; 1075 1075 len = BBTOB(len); 1076 1076 for (licp = &tp->t_items; licp != NULL; licp = licp->lic_next) { 1077 - if (XFS_LIC_ARE_ALL_FREE(licp)) { 1077 + if (xfs_lic_are_all_free(licp)) { 1078 1078 ASSERT(licp == &tp->t_items); 1079 1079 ASSERT(licp->lic_next == NULL); 1080 1080 return NULL; ··· 1083 1083 /* 1084 1084 * Skip unoccupied slots. 1085 1085 */ 1086 - if (XFS_LIC_ISFREE(licp, i)) { 1086 + if (xfs_lic_isfree(licp, i)) { 1087 1087 continue; 1088 1088 } 1089 1089 1090 - lidp = XFS_LIC_SLOT(licp, i); 1090 + lidp = xfs_lic_slot(licp, i); 1091 1091 blip = (xfs_buf_log_item_t *)lidp->lid_item; 1092 1092 if (blip->bli_item.li_type != XFS_LI_BUF) { 1093 1093 continue;
+33 -33
fs/xfs/xfs_trans_item.c
··· 53 53 * Initialize the chunk, and then 54 54 * claim the first slot in the newly allocated chunk. 55 55 */ 56 - XFS_LIC_INIT(licp); 57 - XFS_LIC_CLAIM(licp, 0); 56 + xfs_lic_init(licp); 57 + xfs_lic_claim(licp, 0); 58 58 licp->lic_unused = 1; 59 - XFS_LIC_INIT_SLOT(licp, 0); 60 - lidp = XFS_LIC_SLOT(licp, 0); 59 + xfs_lic_init_slot(licp, 0); 60 + lidp = xfs_lic_slot(licp, 0); 61 61 62 62 /* 63 63 * Link in the new chunk and update the free count. ··· 88 88 */ 89 89 licp = &tp->t_items; 90 90 while (licp != NULL) { 91 - if (XFS_LIC_VACANCY(licp)) { 91 + if (xfs_lic_vacancy(licp)) { 92 92 if (licp->lic_unused <= XFS_LIC_MAX_SLOT) { 93 93 i = licp->lic_unused; 94 - ASSERT(XFS_LIC_ISFREE(licp, i)); 94 + ASSERT(xfs_lic_isfree(licp, i)); 95 95 break; 96 96 } 97 97 for (i = 0; i <= XFS_LIC_MAX_SLOT; i++) { 98 - if (XFS_LIC_ISFREE(licp, i)) 98 + if (xfs_lic_isfree(licp, i)) 99 99 break; 100 100 } 101 101 ASSERT(i <= XFS_LIC_MAX_SLOT); ··· 108 108 * If we find a free descriptor, claim it, 109 109 * initialize it, and return it. 110 110 */ 111 - XFS_LIC_CLAIM(licp, i); 111 + xfs_lic_claim(licp, i); 112 112 if (licp->lic_unused <= i) { 113 113 licp->lic_unused = i + 1; 114 - XFS_LIC_INIT_SLOT(licp, i); 114 + xfs_lic_init_slot(licp, i); 115 115 } 116 - lidp = XFS_LIC_SLOT(licp, i); 116 + lidp = xfs_lic_slot(licp, i); 117 117 tp->t_items_free--; 118 118 lidp->lid_item = lip; 119 119 lidp->lid_flags = 0; ··· 136 136 xfs_log_item_chunk_t *licp; 137 137 xfs_log_item_chunk_t **licpp; 138 138 139 - slot = XFS_LIC_DESC_TO_SLOT(lidp); 140 - licp = XFS_LIC_DESC_TO_CHUNK(lidp); 141 - XFS_LIC_RELSE(licp, slot); 139 + slot = xfs_lic_desc_to_slot(lidp); 140 + licp = xfs_lic_desc_to_chunk(lidp); 141 + xfs_lic_relse(licp, slot); 142 142 lidp->lid_item->li_desc = NULL; 143 143 tp->t_items_free++; 144 144 ··· 154 154 * Also decrement the transaction structure's count of free items 155 155 * by the number in a chunk since we are freeing an empty chunk. 156 156 */ 157 - if (XFS_LIC_ARE_ALL_FREE(licp) && (licp != &(tp->t_items))) { 157 + if (xfs_lic_are_all_free(licp) && (licp != &(tp->t_items))) { 158 158 licpp = &(tp->t_items.lic_next); 159 159 while (*licpp != licp) { 160 160 ASSERT(*licpp != NULL); ··· 207 207 /* 208 208 * If it's not in the first chunk, skip to the second. 209 209 */ 210 - if (XFS_LIC_ARE_ALL_FREE(licp)) { 210 + if (xfs_lic_are_all_free(licp)) { 211 211 licp = licp->lic_next; 212 212 } 213 213 214 214 /* 215 215 * Return the first non-free descriptor in the chunk. 216 216 */ 217 - ASSERT(!XFS_LIC_ARE_ALL_FREE(licp)); 217 + ASSERT(!xfs_lic_are_all_free(licp)); 218 218 for (i = 0; i < licp->lic_unused; i++) { 219 - if (XFS_LIC_ISFREE(licp, i)) { 219 + if (xfs_lic_isfree(licp, i)) { 220 220 continue; 221 221 } 222 222 223 - return XFS_LIC_SLOT(licp, i); 223 + return xfs_lic_slot(licp, i); 224 224 } 225 225 cmn_err(CE_WARN, "xfs_trans_first_item() -- no first item"); 226 226 return NULL; ··· 242 242 xfs_log_item_chunk_t *licp; 243 243 int i; 244 244 245 - licp = XFS_LIC_DESC_TO_CHUNK(lidp); 245 + licp = xfs_lic_desc_to_chunk(lidp); 246 246 247 247 /* 248 248 * First search the rest of the chunk. The for loop keeps us 249 249 * from referencing things beyond the end of the chunk. 250 250 */ 251 - for (i = (int)XFS_LIC_DESC_TO_SLOT(lidp) + 1; i < licp->lic_unused; i++) { 252 - if (XFS_LIC_ISFREE(licp, i)) { 251 + for (i = (int)xfs_lic_desc_to_slot(lidp) + 1; i < licp->lic_unused; i++) { 252 + if (xfs_lic_isfree(licp, i)) { 253 253 continue; 254 254 } 255 255 256 - return XFS_LIC_SLOT(licp, i); 256 + return xfs_lic_slot(licp, i); 257 257 } 258 258 259 259 /* ··· 266 266 } 267 267 268 268 licp = licp->lic_next; 269 - ASSERT(!XFS_LIC_ARE_ALL_FREE(licp)); 269 + ASSERT(!xfs_lic_are_all_free(licp)); 270 270 for (i = 0; i < licp->lic_unused; i++) { 271 - if (XFS_LIC_ISFREE(licp, i)) { 271 + if (xfs_lic_isfree(licp, i)) { 272 272 continue; 273 273 } 274 274 275 - return XFS_LIC_SLOT(licp, i); 275 + return xfs_lic_slot(licp, i); 276 276 } 277 277 ASSERT(0); 278 278 /* NOTREACHED */ ··· 300 300 /* 301 301 * Special case the embedded chunk so we don't free it below. 302 302 */ 303 - if (!XFS_LIC_ARE_ALL_FREE(licp)) { 303 + if (!xfs_lic_are_all_free(licp)) { 304 304 (void) xfs_trans_unlock_chunk(licp, 1, abort, NULLCOMMITLSN); 305 - XFS_LIC_ALL_FREE(licp); 305 + xfs_lic_all_free(licp); 306 306 licp->lic_unused = 0; 307 307 } 308 308 licp = licp->lic_next; ··· 311 311 * Unlock each item in each chunk and free the chunks. 312 312 */ 313 313 while (licp != NULL) { 314 - ASSERT(!XFS_LIC_ARE_ALL_FREE(licp)); 314 + ASSERT(!xfs_lic_are_all_free(licp)); 315 315 (void) xfs_trans_unlock_chunk(licp, 1, abort, NULLCOMMITLSN); 316 316 next_licp = licp->lic_next; 317 317 kmem_free(licp); ··· 347 347 /* 348 348 * Special case the embedded chunk so we don't free. 349 349 */ 350 - if (!XFS_LIC_ARE_ALL_FREE(licp)) { 350 + if (!xfs_lic_are_all_free(licp)) { 351 351 freed = xfs_trans_unlock_chunk(licp, 0, 0, commit_lsn); 352 352 } 353 353 licpp = &(tp->t_items.lic_next); ··· 358 358 * and free empty chunks. 359 359 */ 360 360 while (licp != NULL) { 361 - ASSERT(!XFS_LIC_ARE_ALL_FREE(licp)); 361 + ASSERT(!xfs_lic_are_all_free(licp)); 362 362 freed += xfs_trans_unlock_chunk(licp, 0, 0, commit_lsn); 363 363 next_licp = licp->lic_next; 364 - if (XFS_LIC_ARE_ALL_FREE(licp)) { 364 + if (xfs_lic_are_all_free(licp)) { 365 365 *licpp = next_licp; 366 366 kmem_free(licp); 367 367 freed -= XFS_LIC_NUM_SLOTS; ··· 402 402 freed = 0; 403 403 lidp = licp->lic_descs; 404 404 for (i = 0; i < licp->lic_unused; i++, lidp++) { 405 - if (XFS_LIC_ISFREE(licp, i)) { 405 + if (xfs_lic_isfree(licp, i)) { 406 406 continue; 407 407 } 408 408 lip = lidp->lid_item; ··· 421 421 */ 422 422 if (!(freeing_chunk) && 423 423 (!(lidp->lid_flags & XFS_LID_DIRTY) || abort)) { 424 - XFS_LIC_RELSE(licp, i); 424 + xfs_lic_relse(licp, i); 425 425 freed++; 426 426 } 427 427 }
+2 -2
fs/xfs/xfs_utils.c
··· 237 237 238 238 ASSERT (ip->i_d.di_nlink > 0); 239 239 ip->i_d.di_nlink--; 240 - drop_nlink(ip->i_vnode); 240 + drop_nlink(VFS_I(ip)); 241 241 xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); 242 242 243 243 error = 0; ··· 301 301 302 302 ASSERT(ip->i_d.di_nlink > 0); 303 303 ip->i_d.di_nlink++; 304 - inc_nlink(ip->i_vnode); 304 + inc_nlink(VFS_I(ip)); 305 305 if ((ip->i_d.di_version == XFS_DINODE_VERSION_1) && 306 306 (ip->i_d.di_nlink > XFS_MAXLINK_1)) { 307 307 /*
-3
fs/xfs/xfs_utils.h
··· 18 18 #ifndef __XFS_UTILS_H__ 19 19 #define __XFS_UTILS_H__ 20 20 21 - #define IRELE(ip) VN_RELE(XFS_ITOV(ip)) 22 - #define IHOLD(ip) VN_HOLD(XFS_ITOV(ip)) 23 - 24 21 extern int xfs_truncate_file(xfs_mount_t *, xfs_inode_t *); 25 22 extern int xfs_dir_ialloc(xfs_trans_t **, xfs_inode_t *, mode_t, xfs_nlink_t, 26 23 xfs_dev_t, cred_t *, prid_t, int,
+6 -7
fs/xfs/xfs_vfsops.c
··· 128 128 xfs_inode_t *rip = mp->m_rootip; 129 129 xfs_inode_t *rbmip; 130 130 xfs_inode_t *rsumip = NULL; 131 - bhv_vnode_t *rvp = XFS_ITOV(rip); 132 131 int error; 133 132 134 133 xfs_ilock(rip, XFS_ILOCK_EXCL | XFS_ILOCK_PARENT); ··· 145 146 if (error == EFSCORRUPTED) 146 147 goto fscorrupt_out; 147 148 148 - ASSERT(vn_count(XFS_ITOV(rbmip)) == 1); 149 + ASSERT(vn_count(VFS_I(rbmip)) == 1); 149 150 150 151 rsumip = mp->m_rsumip; 151 152 xfs_ilock(rsumip, XFS_ILOCK_EXCL); ··· 156 157 if (error == EFSCORRUPTED) 157 158 goto fscorrupt_out; 158 159 159 - ASSERT(vn_count(XFS_ITOV(rsumip)) == 1); 160 + ASSERT(vn_count(VFS_I(rsumip)) == 1); 160 161 } 161 162 162 163 /* ··· 166 167 if (error == EFSCORRUPTED) 167 168 goto fscorrupt_out2; 168 169 169 - if (vn_count(rvp) != 1 && !relocation) { 170 + if (vn_count(VFS_I(rip)) != 1 && !relocation) { 170 171 xfs_iunlock(rip, XFS_ILOCK_EXCL); 171 172 return XFS_ERROR(EBUSY); 172 173 } ··· 283 284 int *bypassed) 284 285 { 285 286 xfs_inode_t *ip = NULL; 286 - bhv_vnode_t *vp = NULL; 287 + struct inode *vp = NULL; 287 288 int error; 288 289 int last_error; 289 290 uint64_t fflag; ··· 403 404 continue; 404 405 } 405 406 406 - vp = XFS_ITOV_NULL(ip); 407 + vp = VFS_I(ip); 407 408 408 409 /* 409 410 * If the vnode is gone then this is being torn down, ··· 478 479 IPOINTER_INSERT(ip, mp); 479 480 xfs_ilock(ip, lock_flags); 480 481 481 - ASSERT(vp == XFS_ITOV(ip)); 482 + ASSERT(vp == VFS_I(ip)); 482 483 ASSERT(ip->i_mount == mp); 483 484 484 485 vnode_refed = B_TRUE;
+52 -138
fs/xfs/xfs_vnodeops.c
··· 83 83 cred_t *credp) 84 84 { 85 85 xfs_mount_t *mp = ip->i_mount; 86 - struct inode *inode = XFS_ITOV(ip); 86 + struct inode *inode = VFS_I(ip); 87 87 int mask = iattr->ia_valid; 88 88 xfs_trans_t *tp; 89 89 int code; ··· 513 513 ip->i_d.di_atime.t_sec = iattr->ia_atime.tv_sec; 514 514 ip->i_d.di_atime.t_nsec = iattr->ia_atime.tv_nsec; 515 515 ip->i_update_core = 1; 516 - timeflags &= ~XFS_ICHGTIME_ACC; 517 516 } 518 517 if (mask & ATTR_MTIME) { 519 518 inode->i_mtime = iattr->ia_mtime; ··· 713 714 return XFS_ERROR(EIO); 714 715 715 716 /* capture size updates in I/O completion before writing the inode. */ 716 - error = filemap_fdatawait(vn_to_inode(XFS_ITOV(ip))->i_mapping); 717 + error = filemap_fdatawait(VFS_I(ip)->i_mapping); 717 718 if (error) 718 719 return XFS_ERROR(error); 719 720 ··· 1159 1160 xfs_release( 1160 1161 xfs_inode_t *ip) 1161 1162 { 1162 - bhv_vnode_t *vp = XFS_ITOV(ip); 1163 1163 xfs_mount_t *mp = ip->i_mount; 1164 1164 int error; 1165 1165 ··· 1193 1195 * be exposed to that problem. 1194 1196 */ 1195 1197 truncated = xfs_iflags_test_and_clear(ip, XFS_ITRUNCATED); 1196 - if (truncated && VN_DIRTY(vp) && ip->i_delayed_blks > 0) 1198 + if (truncated && VN_DIRTY(VFS_I(ip)) && ip->i_delayed_blks > 0) 1197 1199 xfs_flush_pages(ip, 0, -1, XFS_B_ASYNC, FI_NONE); 1198 1200 } 1199 1201 1200 1202 if (ip->i_d.di_nlink != 0) { 1201 1203 if ((((ip->i_d.di_mode & S_IFMT) == S_IFREG) && 1202 - ((ip->i_size > 0) || (VN_CACHED(vp) > 0 || 1204 + ((ip->i_size > 0) || (VN_CACHED(VFS_I(ip)) > 0 || 1203 1205 ip->i_delayed_blks > 0)) && 1204 1206 (ip->i_df.if_flags & XFS_IFEXTENTS)) && 1205 1207 (!(ip->i_d.di_flags & ··· 1225 1227 xfs_inactive( 1226 1228 xfs_inode_t *ip) 1227 1229 { 1228 - bhv_vnode_t *vp = XFS_ITOV(ip); 1229 1230 xfs_bmap_free_t free_list; 1230 1231 xfs_fsblock_t first_block; 1231 1232 int committed; ··· 1239 1242 * If the inode is already free, then there can be nothing 1240 1243 * to clean up here. 1241 1244 */ 1242 - if (ip->i_d.di_mode == 0 || VN_BAD(vp)) { 1245 + if (ip->i_d.di_mode == 0 || VN_BAD(VFS_I(ip))) { 1243 1246 ASSERT(ip->i_df.if_real_bytes == 0); 1244 1247 ASSERT(ip->i_df.if_broot_bytes == 0); 1245 1248 return VN_INACTIVE_CACHE; ··· 1269 1272 1270 1273 if (ip->i_d.di_nlink != 0) { 1271 1274 if ((((ip->i_d.di_mode & S_IFMT) == S_IFREG) && 1272 - ((ip->i_size > 0) || (VN_CACHED(vp) > 0 || 1275 + ((ip->i_size > 0) || (VN_CACHED(VFS_I(ip)) > 0 || 1273 1276 ip->i_delayed_blks > 0)) && 1274 1277 (ip->i_df.if_flags & XFS_IFEXTENTS) && 1275 1278 (!(ip->i_d.di_flags & ··· 1705 1708 } 1706 1709 1707 1710 #ifdef DEBUG 1708 - /* 1709 - * Some counters to see if (and how often) we are hitting some deadlock 1710 - * prevention code paths. 1711 - */ 1712 - 1713 - int xfs_rm_locks; 1714 - int xfs_rm_lock_delays; 1715 - int xfs_rm_attempts; 1716 - #endif 1717 - 1718 - /* 1719 - * The following routine will lock the inodes associated with the 1720 - * directory and the named entry in the directory. The locks are 1721 - * acquired in increasing inode number. 1722 - * 1723 - * If the entry is "..", then only the directory is locked. The 1724 - * vnode ref count will still include that from the .. entry in 1725 - * this case. 1726 - * 1727 - * There is a deadlock we need to worry about. If the locked directory is 1728 - * in the AIL, it might be blocking up the log. The next inode we lock 1729 - * could be already locked by another thread waiting for log space (e.g 1730 - * a permanent log reservation with a long running transaction (see 1731 - * xfs_itruncate_finish)). To solve this, we must check if the directory 1732 - * is in the ail and use lock_nowait. If we can't lock, we need to 1733 - * drop the inode lock on the directory and try again. xfs_iunlock will 1734 - * potentially push the tail if we were holding up the log. 1735 - */ 1736 - STATIC int 1737 - xfs_lock_dir_and_entry( 1738 - xfs_inode_t *dp, 1739 - xfs_inode_t *ip) /* inode of entry 'name' */ 1740 - { 1741 - int attempts; 1742 - xfs_ino_t e_inum; 1743 - xfs_inode_t *ips[2]; 1744 - xfs_log_item_t *lp; 1745 - 1746 - #ifdef DEBUG 1747 - xfs_rm_locks++; 1748 - #endif 1749 - attempts = 0; 1750 - 1751 - again: 1752 - xfs_ilock(dp, XFS_ILOCK_EXCL | XFS_ILOCK_PARENT); 1753 - 1754 - e_inum = ip->i_ino; 1755 - 1756 - xfs_itrace_ref(ip); 1757 - 1758 - /* 1759 - * We want to lock in increasing inum. Since we've already 1760 - * acquired the lock on the directory, we may need to release 1761 - * if if the inum of the entry turns out to be less. 1762 - */ 1763 - if (e_inum > dp->i_ino) { 1764 - /* 1765 - * We are already in the right order, so just 1766 - * lock on the inode of the entry. 1767 - * We need to use nowait if dp is in the AIL. 1768 - */ 1769 - 1770 - lp = (xfs_log_item_t *)dp->i_itemp; 1771 - if (lp && (lp->li_flags & XFS_LI_IN_AIL)) { 1772 - if (!xfs_ilock_nowait(ip, XFS_ILOCK_EXCL)) { 1773 - attempts++; 1774 - #ifdef DEBUG 1775 - xfs_rm_attempts++; 1776 - #endif 1777 - 1778 - /* 1779 - * Unlock dp and try again. 1780 - * xfs_iunlock will try to push the tail 1781 - * if the inode is in the AIL. 1782 - */ 1783 - 1784 - xfs_iunlock(dp, XFS_ILOCK_EXCL); 1785 - 1786 - if ((attempts % 5) == 0) { 1787 - delay(1); /* Don't just spin the CPU */ 1788 - #ifdef DEBUG 1789 - xfs_rm_lock_delays++; 1790 - #endif 1791 - } 1792 - goto again; 1793 - } 1794 - } else { 1795 - xfs_ilock(ip, XFS_ILOCK_EXCL); 1796 - } 1797 - } else if (e_inum < dp->i_ino) { 1798 - xfs_iunlock(dp, XFS_ILOCK_EXCL); 1799 - 1800 - ips[0] = ip; 1801 - ips[1] = dp; 1802 - xfs_lock_inodes(ips, 2, XFS_ILOCK_EXCL); 1803 - } 1804 - /* else e_inum == dp->i_ino */ 1805 - /* This can happen if we're asked to lock /x/.. 1806 - * the entry is "..", which is also the parent directory. 1807 - */ 1808 - 1809 - return 0; 1810 - } 1811 - 1812 - #ifdef DEBUG 1813 1711 int xfs_locked_n; 1814 1712 int xfs_small_retries; 1815 1713 int xfs_middle_retries; ··· 1838 1946 #endif 1839 1947 } 1840 1948 1949 + void 1950 + xfs_lock_two_inodes( 1951 + xfs_inode_t *ip0, 1952 + xfs_inode_t *ip1, 1953 + uint lock_mode) 1954 + { 1955 + xfs_inode_t *temp; 1956 + int attempts = 0; 1957 + xfs_log_item_t *lp; 1958 + 1959 + ASSERT(ip0->i_ino != ip1->i_ino); 1960 + 1961 + if (ip0->i_ino > ip1->i_ino) { 1962 + temp = ip0; 1963 + ip0 = ip1; 1964 + ip1 = temp; 1965 + } 1966 + 1967 + again: 1968 + xfs_ilock(ip0, xfs_lock_inumorder(lock_mode, 0)); 1969 + 1970 + /* 1971 + * If the first lock we have locked is in the AIL, we must TRY to get 1972 + * the second lock. If we can't get it, we must release the first one 1973 + * and try again. 1974 + */ 1975 + lp = (xfs_log_item_t *)ip0->i_itemp; 1976 + if (lp && (lp->li_flags & XFS_LI_IN_AIL)) { 1977 + if (!xfs_ilock_nowait(ip1, xfs_lock_inumorder(lock_mode, 1))) { 1978 + xfs_iunlock(ip0, lock_mode); 1979 + if ((++attempts % 5) == 0) 1980 + delay(1); /* Don't just spin the CPU */ 1981 + goto again; 1982 + } 1983 + } else { 1984 + xfs_ilock(ip1, xfs_lock_inumorder(lock_mode, 1)); 1985 + } 1986 + } 1987 + 1841 1988 int 1842 1989 xfs_remove( 1843 1990 xfs_inode_t *dp, ··· 1949 2018 goto out_trans_cancel; 1950 2019 } 1951 2020 1952 - error = xfs_lock_dir_and_entry(dp, ip); 1953 - if (error) 1954 - goto out_trans_cancel; 2021 + xfs_lock_two_inodes(dp, ip, XFS_ILOCK_EXCL); 1955 2022 1956 2023 /* 1957 2024 * At this point, we've gotten both the directory and the entry ··· 1976 2047 } 1977 2048 } 1978 2049 1979 - /* 1980 - * Entry must exist since we did a lookup in xfs_lock_dir_and_entry. 1981 - */ 1982 2050 XFS_BMAP_INIT(&free_list, &first_block); 1983 2051 error = xfs_dir_removename(tp, dp, name, ip->i_ino, 1984 2052 &first_block, &free_list, resblks); ··· 2081 2155 { 2082 2156 xfs_mount_t *mp = tdp->i_mount; 2083 2157 xfs_trans_t *tp; 2084 - xfs_inode_t *ips[2]; 2085 2158 int error; 2086 2159 xfs_bmap_free_t free_list; 2087 2160 xfs_fsblock_t first_block; ··· 2128 2203 goto error_return; 2129 2204 } 2130 2205 2131 - if (sip->i_ino < tdp->i_ino) { 2132 - ips[0] = sip; 2133 - ips[1] = tdp; 2134 - } else { 2135 - ips[0] = tdp; 2136 - ips[1] = sip; 2137 - } 2138 - 2139 - xfs_lock_inodes(ips, 2, XFS_ILOCK_EXCL); 2206 + xfs_lock_two_inodes(sip, tdp, XFS_ILOCK_EXCL); 2140 2207 2141 2208 /* 2142 2209 * Increment vnode ref counts since xfs_trans_commit & ··· 2790 2873 xfs_reclaim( 2791 2874 xfs_inode_t *ip) 2792 2875 { 2793 - bhv_vnode_t *vp = XFS_ITOV(ip); 2794 2876 2795 2877 xfs_itrace_entry(ip); 2796 2878 2797 - ASSERT(!VN_MAPPED(vp)); 2879 + ASSERT(!VN_MAPPED(VFS_I(ip))); 2798 2880 2799 2881 /* bad inode, get out here ASAP */ 2800 - if (VN_BAD(vp)) { 2882 + if (VN_BAD(VFS_I(ip))) { 2801 2883 xfs_ireclaim(ip); 2802 2884 return 0; 2803 2885 } ··· 2833 2917 XFS_MOUNT_ILOCK(mp); 2834 2918 spin_lock(&ip->i_flags_lock); 2835 2919 __xfs_iflags_set(ip, XFS_IRECLAIMABLE); 2836 - vn_to_inode(vp)->i_private = NULL; 2920 + VFS_I(ip)->i_private = NULL; 2837 2921 ip->i_vnode = NULL; 2838 2922 spin_unlock(&ip->i_flags_lock); 2839 2923 list_add_tail(&ip->i_reclaim, &mp->m_del_inodes); ··· 2849 2933 int sync_mode) 2850 2934 { 2851 2935 xfs_perag_t *pag = xfs_get_perag(ip->i_mount, ip->i_ino); 2852 - bhv_vnode_t *vp = XFS_ITOV_NULL(ip); 2936 + struct inode *vp = VFS_I(ip); 2853 2937 2854 2938 if (vp && VN_BAD(vp)) 2855 2939 goto reclaim; ··· 3237 3321 xfs_off_t len, 3238 3322 int attr_flags) 3239 3323 { 3240 - bhv_vnode_t *vp; 3241 3324 int committed; 3242 3325 int done; 3243 3326 xfs_off_t end_dmi_offset; ··· 3256 3341 xfs_trans_t *tp; 3257 3342 int need_iolock = 1; 3258 3343 3259 - vp = XFS_ITOV(ip); 3260 3344 mp = ip->i_mount; 3261 3345 3262 3346 xfs_itrace_entry(ip); ··· 3292 3378 rounding = max_t(uint, 1 << mp->m_sb.sb_blocklog, PAGE_CACHE_SIZE); 3293 3379 ioffset = offset & ~(rounding - 1); 3294 3380 3295 - if (VN_CACHED(vp) != 0) { 3381 + if (VN_CACHED(VFS_I(ip)) != 0) { 3296 3382 xfs_inval_cached_trace(ip, ioffset, -1, ioffset, -1); 3297 3383 error = xfs_flushinval_pages(ip, ioffset, -1, FI_REMAPF_LOCKED); 3298 3384 if (error)
+45
include/linux/completion.h
··· 55 55 56 56 #define INIT_COMPLETION(x) ((x).done = 0) 57 57 58 + 59 + /** 60 + * try_wait_for_completion - try to decrement a completion without blocking 61 + * @x: completion structure 62 + * 63 + * Returns: 0 if a decrement cannot be done without blocking 64 + * 1 if a decrement succeeded. 65 + * 66 + * If a completion is being used as a counting completion, 67 + * attempt to decrement the counter without blocking. This 68 + * enables us to avoid waiting if the resource the completion 69 + * is protecting is not available. 70 + */ 71 + static inline bool try_wait_for_completion(struct completion *x) 72 + { 73 + int ret = 1; 74 + 75 + spin_lock_irq(&x->wait.lock); 76 + if (!x->done) 77 + ret = 0; 78 + else 79 + x->done--; 80 + spin_unlock_irq(&x->wait.lock); 81 + return ret; 82 + } 83 + 84 + /** 85 + * completion_done - Test to see if a completion has any waiters 86 + * @x: completion structure 87 + * 88 + * Returns: 0 if there are waiters (wait_for_completion() in progress) 89 + * 1 if there are no waiters. 90 + * 91 + */ 92 + static inline bool completion_done(struct completion *x) 93 + { 94 + int ret = 1; 95 + 96 + spin_lock_irq(&x->wait.lock); 97 + if (!x->done) 98 + ret = 0; 99 + spin_unlock_irq(&x->wait.lock); 100 + return ret; 101 + } 102 + 58 103 #endif