X-Git-Url: http://pilppa.org/gitweb/?a=blobdiff_plain;f=fs%2Fxfs%2Fxfs_vnodeops.c;h=51305242ff8cb8b8793e4d19412adfdc309aa555;hb=52833e897fd8c6f62b3e5e27291fa9bc803f7460;hp=1a5ad8cd97b00d3d8cd24c04961ea075cb5e1635;hpb=2fe83b3ad12d43799af5f3156886eca443a88bac;p=linux-2.6-omap-h63xx.git diff --git a/fs/xfs/xfs_vnodeops.c b/fs/xfs/xfs_vnodeops.c index 1a5ad8cd97b..51305242ff8 100644 --- a/fs/xfs/xfs_vnodeops.c +++ b/fs/xfs/xfs_vnodeops.c @@ -52,15 +52,13 @@ #include "xfs_trans_space.h" #include "xfs_log_priv.h" #include "xfs_filestream.h" +#include "xfs_vnodeops.h" -STATIC int +int xfs_open( - bhv_desc_t *bdp, - cred_t *credp) + xfs_inode_t *ip) { int mode; - bhv_vnode_t *vp = BHV_TO_VNODE(bdp); - xfs_inode_t *ip = XFS_BHVTOI(bdp); if (XFS_FORCED_SHUTDOWN(ip->i_mount)) return XFS_ERROR(EIO); @@ -69,7 +67,7 @@ xfs_open( * If it's a directory with any blocks, read-ahead block 0 * as we're almost certain to have the next operation be a read there. */ - if (VN_ISDIR(vp) && ip->i_d.di_nextents > 0) { + if (S_ISDIR(ip->i_d.di_mode) && ip->i_d.di_nextents > 0) { mode = xfs_ilock_map_shared(ip); if (ip->i_d.di_nextents > 0) (void)xfs_da_reada_buf(NULL, ip, 0, XFS_DATA_FORK); @@ -81,22 +79,16 @@ xfs_open( /* * xfs_getattr */ -STATIC int +int xfs_getattr( - bhv_desc_t *bdp, + xfs_inode_t *ip, bhv_vattr_t *vap, - int flags, - cred_t *credp) + int flags) { - xfs_inode_t *ip; - xfs_mount_t *mp; - bhv_vnode_t *vp; + bhv_vnode_t *vp = XFS_ITOV(ip); + xfs_mount_t *mp = ip->i_mount; - vp = BHV_TO_VNODE(bdp); - vn_trace_entry(vp, __FUNCTION__, (inst_t *)__return_address); - - ip = XFS_BHVTOI(bdp); - mp = ip->i_mount; + xfs_itrace_entry(ip); if (XFS_FORCED_SHUTDOWN(mp)) return XFS_ERROR(EIO); @@ -144,7 +136,7 @@ xfs_getattr( default: vap->va_rdev = 0; - if (!(ip->i_d.di_flags & XFS_DIFLAG_REALTIME)) { + if (!(XFS_IS_REALTIME_INODE(ip))) { vap->va_blocksize = xfs_preferred_iosize(mp); } else { @@ -215,14 +207,14 @@ xfs_getattr( */ int xfs_setattr( - bhv_desc_t *bdp, + xfs_inode_t *ip, bhv_vattr_t *vap, int flags, cred_t *credp) { - xfs_inode_t *ip; + bhv_vnode_t *vp = XFS_ITOV(ip); + xfs_mount_t *mp = ip->i_mount; xfs_trans_t *tp; - xfs_mount_t *mp; int mask; int code; uint lock_flags; @@ -230,17 +222,15 @@ xfs_setattr( uid_t uid=0, iuid=0; gid_t gid=0, igid=0; int timeflags = 0; - bhv_vnode_t *vp; xfs_prid_t projid=0, iprojid=0; int mandlock_before, mandlock_after; struct xfs_dquot *udqp, *gdqp, *olddquot1, *olddquot2; int file_owner; int need_iolock = 1; - vp = BHV_TO_VNODE(bdp); - vn_trace_entry(vp, __FUNCTION__, (inst_t *)__return_address); + xfs_itrace_entry(ip); - if (vp->v_vfsp->vfs_flag & VFS_RDONLY) + if (mp->m_flags & XFS_MOUNT_RDONLY) return XFS_ERROR(EROFS); /* @@ -251,9 +241,6 @@ xfs_setattr( return XFS_ERROR(EINVAL); } - ip = XFS_BHVTOI(bdp); - mp = ip->i_mount; - if (XFS_FORCED_SHUTDOWN(mp)) return XFS_ERROR(EIO); @@ -337,7 +324,7 @@ xfs_setattr( } } } else { - if (DM_EVENT_ENABLED (vp->v_vfsp, ip, DM_EVENT_TRUNCATE) && + if (DM_EVENT_ENABLED(ip, DM_EVENT_TRUNCATE) && !(flags & ATTR_DMI)) { int dmflags = AT_DELAY_FLAG(flags) | DM_SEM_FLAG_WR; code = XFS_SEND_DATA(mp, DM_EVENT_TRUNCATE, vp, @@ -521,7 +508,7 @@ xfs_setattr( */ if ((ip->i_d.di_nextents || ip->i_delayed_blks) && (mask & XFS_AT_XFLAGS) && - (ip->i_d.di_flags & XFS_DIFLAG_REALTIME) != + (XFS_IS_REALTIME_INODE(ip)) != (vap->va_xflags & XFS_XFLAG_REALTIME)) { code = XFS_ERROR(EINVAL); /* EFBIG? */ goto error_return; @@ -533,7 +520,7 @@ xfs_setattr( if ((mask & XFS_AT_EXTSIZE) && vap->va_extsize != 0) { xfs_extlen_t size; - if ((ip->i_d.di_flags & XFS_DIFLAG_REALTIME) || + if (XFS_IS_REALTIME_INODE(ip) || ((mask & XFS_AT_XFLAGS) && (vap->va_xflags & XFS_XFLAG_REALTIME))) { size = mp->m_sb.sb_rextsize << @@ -605,13 +592,13 @@ xfs_setattr( if (!code && (ip->i_size != ip->i_d.di_size) && (vap->va_size > ip->i_d.di_size)) { - code = bhv_vop_flush_pages(XFS_ITOV(ip), + code = xfs_flush_pages(ip, ip->i_d.di_size, vap->va_size, XFS_B_ASYNC, FI_NONE); } /* wait for all I/O to complete */ - vn_iowait(vp); + vn_iowait(ip); if (!code) code = xfs_itruncate_data(ip, vap->va_size); @@ -673,7 +660,7 @@ xfs_setattr( * vnode and flush it when the file is closed, and * do not wait the usual (long) time for writeout. */ - VTRUNCATE(vp); + xfs_iflags_set(ip, XFS_ITRUNCATED); } /* * Have to do this even if the file's size doesn't change. @@ -817,12 +804,8 @@ xfs_setattr( if (vap->va_xflags & XFS_XFLAG_EXTSZINHERIT) di_flags |= XFS_DIFLAG_EXTSZINHERIT; } else if ((ip->i_d.di_mode & S_IFMT) == S_IFREG) { - if (vap->va_xflags & XFS_XFLAG_REALTIME) { + if (vap->va_xflags & XFS_XFLAG_REALTIME) di_flags |= XFS_DIFLAG_REALTIME; - ip->i_iocore.io_flags |= XFS_IOCORE_RT; - } else { - ip->i_iocore.io_flags &= ~XFS_IOCORE_RT; - } if (vap->va_xflags & XFS_XFLAG_EXTSIZE) di_flags |= XFS_DIFLAG_EXTSIZE; } @@ -877,10 +860,6 @@ xfs_setattr( * racing calls to vop_vnode_change. */ mandlock_after = MANDLOCK(vp, ip->i_d.di_mode); - if (mandlock_before != mandlock_after) { - bhv_vop_vnode_change(vp, VCHANGE_FLAGS_ENF_LOCKING, - mandlock_after); - } xfs_iunlock(ip, lock_flags); @@ -896,7 +875,7 @@ xfs_setattr( return code; } - if (DM_EVENT_ENABLED(vp->v_vfsp, ip, DM_EVENT_ATTRIBUTE) && + if (DM_EVENT_ENABLED(ip, DM_EVENT_ATTRIBUTE) && !(flags & ATTR_DMI)) { (void) XFS_SEND_NAMESP(mp, DM_EVENT_ATTRIBUTE, vp, DM_RIGHT_NULL, NULL, DM_RIGHT_NULL, NULL, NULL, @@ -919,31 +898,6 @@ xfs_setattr( return code; } - -/* - * xfs_access - * Null conversion from vnode mode bits to inode mode bits, as in efs. - */ -STATIC int -xfs_access( - bhv_desc_t *bdp, - int mode, - cred_t *credp) -{ - xfs_inode_t *ip; - int error; - - vn_trace_entry(BHV_TO_VNODE(bdp), __FUNCTION__, - (inst_t *)__return_address); - - ip = XFS_BHVTOI(bdp); - xfs_ilock(ip, XFS_ILOCK_SHARED); - error = xfs_iaccess(ip, mode, credp); - xfs_iunlock(ip, XFS_ILOCK_SHARED); - return error; -} - - /* * The maximum pathlen is 1024 bytes. Since the minimum file system * blocksize is 512 bytes, we can get a max of 2 extents back from @@ -951,105 +905,88 @@ xfs_access( */ #define SYMLINK_MAPS 2 -/* - * xfs_readlink - * - */ STATIC int -xfs_readlink( - bhv_desc_t *bdp, - uio_t *uiop, - int ioflags, - cred_t *credp) +xfs_readlink_bmap( + xfs_inode_t *ip, + char *link) { - xfs_inode_t *ip; - int count; - xfs_off_t offset; - int pathlen; - bhv_vnode_t *vp; - int error = 0; - xfs_mount_t *mp; - int nmaps; + xfs_mount_t *mp = ip->i_mount; + int pathlen = ip->i_d.di_size; + int nmaps = SYMLINK_MAPS; xfs_bmbt_irec_t mval[SYMLINK_MAPS]; xfs_daddr_t d; int byte_cnt; int n; xfs_buf_t *bp; + int error = 0; - vp = BHV_TO_VNODE(bdp); - vn_trace_entry(vp, __FUNCTION__, (inst_t *)__return_address); - - ip = XFS_BHVTOI(bdp); - mp = ip->i_mount; + error = xfs_bmapi(NULL, ip, 0, XFS_B_TO_FSB(mp, pathlen), 0, NULL, 0, + mval, &nmaps, NULL, NULL); + if (error) + goto out; - if (XFS_FORCED_SHUTDOWN(mp)) - return XFS_ERROR(EIO); + for (n = 0; n < nmaps; n++) { + d = XFS_FSB_TO_DADDR(mp, mval[n].br_startblock); + byte_cnt = XFS_FSB_TO_B(mp, mval[n].br_blockcount); - xfs_ilock(ip, XFS_ILOCK_SHARED); + bp = xfs_buf_read(mp->m_ddev_targp, d, BTOBB(byte_cnt), 0); + error = XFS_BUF_GETERROR(bp); + if (error) { + xfs_ioerror_alert("xfs_readlink", + ip->i_mount, bp, XFS_BUF_ADDR(bp)); + xfs_buf_relse(bp); + goto out; + } + if (pathlen < byte_cnt) + byte_cnt = pathlen; + pathlen -= byte_cnt; - ASSERT((ip->i_d.di_mode & S_IFMT) == S_IFLNK); + memcpy(link, XFS_BUF_PTR(bp), byte_cnt); + xfs_buf_relse(bp); + } - offset = uiop->uio_offset; - count = uiop->uio_resid; + link[ip->i_d.di_size] = '\0'; + error = 0; - if (offset < 0) { - error = XFS_ERROR(EINVAL); - goto error_return; - } - if (count <= 0) { - error = 0; - goto error_return; - } + out: + return error; +} - /* - * See if the symlink is stored inline. - */ - pathlen = (int)ip->i_d.di_size; +int +xfs_readlink( + xfs_inode_t *ip, + char *link) +{ + xfs_mount_t *mp = ip->i_mount; + int pathlen; + int error = 0; - if (ip->i_df.if_flags & XFS_IFINLINE) { - error = xfs_uio_read(ip->i_df.if_u1.if_data, pathlen, uiop); - } - else { - /* - * Symlink not inline. Call bmap to get it in. - */ - nmaps = SYMLINK_MAPS; + xfs_itrace_entry(ip); - error = xfs_bmapi(NULL, ip, 0, XFS_B_TO_FSB(mp, pathlen), - 0, NULL, 0, mval, &nmaps, NULL, NULL); + if (XFS_FORCED_SHUTDOWN(mp)) + return XFS_ERROR(EIO); - if (error) { - goto error_return; - } + xfs_ilock(ip, XFS_ILOCK_SHARED); - for (n = 0; n < nmaps; n++) { - d = XFS_FSB_TO_DADDR(mp, mval[n].br_startblock); - byte_cnt = XFS_FSB_TO_B(mp, mval[n].br_blockcount); - bp = xfs_buf_read(mp->m_ddev_targp, d, - BTOBB(byte_cnt), 0); - error = XFS_BUF_GETERROR(bp); - if (error) { - xfs_ioerror_alert("xfs_readlink", - ip->i_mount, bp, XFS_BUF_ADDR(bp)); - xfs_buf_relse(bp); - goto error_return; - } - if (pathlen < byte_cnt) - byte_cnt = pathlen; - pathlen -= byte_cnt; + ASSERT((ip->i_d.di_mode & S_IFMT) == S_IFLNK); + ASSERT(ip->i_d.di_size <= MAXPATHLEN); - error = xfs_uio_read(XFS_BUF_PTR(bp), byte_cnt, uiop); - xfs_buf_relse (bp); - } + pathlen = ip->i_d.di_size; + if (!pathlen) + goto out; + if (ip->i_df.if_flags & XFS_IFINLINE) { + memcpy(link, ip->i_df.if_u1.if_data, pathlen); + link[pathlen] = '\0'; + } else { + error = xfs_readlink_bmap(ip, link); } -error_return: + out: xfs_iunlock(ip, XFS_ILOCK_SHARED); return error; } - /* * xfs_fsync * @@ -1059,29 +996,27 @@ error_return: * be held while flushing the data, so acquire after we're done * with that. */ -STATIC int +int xfs_fsync( - bhv_desc_t *bdp, + xfs_inode_t *ip, int flag, - cred_t *credp, xfs_off_t start, xfs_off_t stop) { - xfs_inode_t *ip; xfs_trans_t *tp; int error; int log_flushed = 0, changed = 1; - vn_trace_entry(BHV_TO_VNODE(bdp), - __FUNCTION__, (inst_t *)__return_address); - - ip = XFS_BHVTOI(bdp); + xfs_itrace_entry(ip); ASSERT(start >= 0 && stop >= -1); if (XFS_FORCED_SHUTDOWN(ip->i_mount)) return XFS_ERROR(EIO); + if (flag & FSYNC_DATA) + filemap_fdatawait(vn_to_inode(XFS_ITOV(ip))->i_mapping); + /* * We always need to make sure that the required inode state * is safe on disk. The vnode might be clean but because @@ -1188,7 +1123,7 @@ xfs_fsync( * If this inode is on the RT dev we need to flush that * cache as well. */ - if (ip->i_d.di_flags & XFS_DIFLAG_REALTIME) + if (XFS_IS_REALTIME_INODE(ip)) xfs_blkdev_issue_flush(ip->i_mount->m_rtdev_targp); } @@ -1227,7 +1162,7 @@ xfs_free_eofblocks( nimaps = 1; xfs_ilock(ip, XFS_ILOCK_SHARED); - error = XFS_BMAPI(mp, NULL, &ip->i_iocore, end_fsb, map_len, 0, + error = xfs_bmapi(NULL, ip, end_fsb, map_len, 0, NULL, 0, &imap, &nimaps, NULL, NULL); xfs_iunlock(ip, XFS_ILOCK_SHARED); @@ -1542,27 +1477,24 @@ xfs_inactive_attrs( return 0; } -STATIC int +int xfs_release( - bhv_desc_t *bdp) + xfs_inode_t *ip) { - xfs_inode_t *ip; - bhv_vnode_t *vp; - xfs_mount_t *mp; + bhv_vnode_t *vp = XFS_ITOV(ip); + xfs_mount_t *mp = ip->i_mount; int error; - vp = BHV_TO_VNODE(bdp); - ip = XFS_BHVTOI(bdp); - mp = ip->i_mount; - if (!VN_ISREG(vp) || (ip->i_d.di_mode == 0)) return 0; /* If this is a read-only mount, don't do this (would generate I/O) */ - if (vp->v_vfsp->vfs_flag & VFS_RDONLY) + if (mp->m_flags & XFS_MOUNT_RDONLY) return 0; if (!XFS_FORCED_SHUTDOWN(mp)) { + int truncated; + /* * If we are using filestreams, and we have an unlinked * file that we are processing the last close on, then nothing @@ -1583,8 +1515,9 @@ xfs_release( * significantly reducing the time window where we'd otherwise * be exposed to that problem. */ - if (VUNTRUNCATE(vp) && VN_DIRTY(vp) && ip->i_delayed_blks > 0) - bhv_vop_flush_pages(vp, 0, -1, XFS_B_ASYNC, FI_NONE); + truncated = xfs_iflags_test_and_clear(ip, XFS_ITRUNCATED); + if (truncated && VN_DIRTY(vp) && ip->i_delayed_blks > 0) + xfs_flush_pages(ip, 0, -1, XFS_B_ASYNC, FI_NONE); } #ifdef HAVE_REFCACHE @@ -1603,9 +1536,6 @@ xfs_release( error = xfs_free_eofblocks(mp, ip, XFS_FREE_EOF_LOCK); if (error) return error; - /* Update linux inode block count after free above */ - vn_to_inode(vp)->i_blocks = XFS_FSB_TO_BB(mp, - ip->i_d.di_nblocks + ip->i_delayed_blks); } } @@ -1620,13 +1550,11 @@ xfs_release( * now be truncated. Also, we clear all of the read-ahead state * kept for the inode here since the file is now closed. */ -STATIC int +int xfs_inactive( - bhv_desc_t *bdp, - cred_t *credp) + xfs_inode_t *ip) { - xfs_inode_t *ip; - bhv_vnode_t *vp; + bhv_vnode_t *vp = XFS_ITOV(ip); xfs_bmap_free_t free_list; xfs_fsblock_t first_block; int committed; @@ -1635,10 +1563,7 @@ xfs_inactive( int error; int truncate; - vp = BHV_TO_VNODE(bdp); - vn_trace_entry(vp, __FUNCTION__, (inst_t *)__return_address); - - ip = XFS_BHVTOI(bdp); + xfs_itrace_entry(ip); /* * If the inode is already free, then there can be nothing @@ -1663,15 +1588,14 @@ xfs_inactive( mp = ip->i_mount; - if (ip->i_d.di_nlink == 0 && - DM_EVENT_ENABLED(vp->v_vfsp, ip, DM_EVENT_DESTROY)) { + if (ip->i_d.di_nlink == 0 && DM_EVENT_ENABLED(ip, DM_EVENT_DESTROY)) { (void) XFS_SEND_DESTROY(mp, vp, DM_RIGHT_NULL); } error = 0; /* If this is a read-only mount, don't do this (would generate I/O) */ - if (vp->v_vfsp->vfs_flag & VFS_RDONLY) + if (mp->m_flags & XFS_MOUNT_RDONLY) goto out; if (ip->i_d.di_nlink != 0) { @@ -1685,9 +1609,6 @@ xfs_inactive( error = xfs_free_eofblocks(mp, ip, XFS_FREE_EOF_LOCK); if (error) return VN_INACTIVE_CACHE; - /* Update linux inode block count after free above */ - vn_to_inode(vp)->i_blocks = XFS_FSB_TO_BB(mp, - ip->i_d.di_nblocks + ip->i_delayed_blks); } goto out; } @@ -1841,89 +1762,69 @@ xfs_inactive( } -/* - * xfs_lookup - */ -STATIC int +int xfs_lookup( - bhv_desc_t *dir_bdp, + xfs_inode_t *dp, bhv_vname_t *dentry, - bhv_vnode_t **vpp, - int flags, - bhv_vnode_t *rdir, - cred_t *credp) + bhv_vnode_t **vpp) { - xfs_inode_t *dp, *ip; + xfs_inode_t *ip; xfs_ino_t e_inum; int error; uint lock_mode; - bhv_vnode_t *dir_vp; - - dir_vp = BHV_TO_VNODE(dir_bdp); - vn_trace_entry(dir_vp, __FUNCTION__, (inst_t *)__return_address); - dp = XFS_BHVTOI(dir_bdp); + xfs_itrace_entry(dp); if (XFS_FORCED_SHUTDOWN(dp->i_mount)) return XFS_ERROR(EIO); lock_mode = xfs_ilock_map_shared(dp); - error = xfs_dir_lookup_int(dir_bdp, lock_mode, dentry, &e_inum, &ip); + error = xfs_dir_lookup_int(dp, lock_mode, dentry, &e_inum, &ip); if (!error) { *vpp = XFS_ITOV(ip); - ITRACE(ip); + xfs_itrace_ref(ip); } xfs_iunlock_map_shared(dp, lock_mode); return error; } - -/* - * xfs_create (create a new file). - */ -STATIC int +int xfs_create( - bhv_desc_t *dir_bdp, + xfs_inode_t *dp, bhv_vname_t *dentry, - bhv_vattr_t *vap, + mode_t mode, + xfs_dev_t rdev, bhv_vnode_t **vpp, cred_t *credp) { char *name = VNAME(dentry); - bhv_vnode_t *dir_vp; - xfs_inode_t *dp, *ip; + xfs_mount_t *mp = dp->i_mount; + bhv_vnode_t *dir_vp = XFS_ITOV(dp); + xfs_inode_t *ip; bhv_vnode_t *vp = NULL; xfs_trans_t *tp; - xfs_mount_t *mp; - xfs_dev_t rdev; int error; xfs_bmap_free_t free_list; xfs_fsblock_t first_block; - boolean_t dp_joined_to_trans; + boolean_t unlock_dp_on_error = B_FALSE; int dm_event_sent = 0; uint cancel_flags; int committed; xfs_prid_t prid; struct xfs_dquot *udqp, *gdqp; uint resblks; - int dm_di_mode; int namelen; ASSERT(!*vpp); - dir_vp = BHV_TO_VNODE(dir_bdp); - vn_trace_entry(dir_vp, __FUNCTION__, (inst_t *)__return_address); + xfs_itrace_entry(dp); - dp = XFS_BHVTOI(dir_bdp); - mp = dp->i_mount; - - dm_di_mode = vap->va_mode; namelen = VNAMELEN(dentry); - if (DM_EVENT_ENABLED(dir_vp->v_vfsp, dp, DM_EVENT_CREATE)) { + if (DM_EVENT_ENABLED(dp, DM_EVENT_CREATE)) { error = XFS_SEND_NAMESP(mp, DM_EVENT_CREATE, dir_vp, DM_RIGHT_NULL, NULL, DM_RIGHT_NULL, name, NULL, - dm_di_mode, 0, 0); + mode, 0, 0); if (error) return error; @@ -1938,8 +1839,6 @@ xfs_create( udqp = gdqp = NULL; if (dp->i_d.di_flags & XFS_DIFLAG_PROJINHERIT) prid = dp->i_d.di_projid; - else if (vap->va_mask & XFS_AT_PROJID) - prid = (xfs_prid_t)vap->va_projid; else prid = (xfs_prid_t)dfltprid; @@ -1953,7 +1852,6 @@ xfs_create( goto std_return; ip = NULL; - dp_joined_to_trans = B_FALSE; tp = xfs_trans_alloc(mp, XFS_TRANS_CREATE); cancel_flags = XFS_TRANS_RELEASE_LOG_RES; @@ -1973,11 +1871,11 @@ xfs_create( } if (error) { cancel_flags = 0; - dp = NULL; goto error_return; } xfs_ilock(dp, XFS_ILOCK_EXCL | XFS_ILOCK_PARENT); + unlock_dp_on_error = B_TRUE; XFS_BMAP_INIT(&free_list, &first_block); @@ -1992,8 +1890,7 @@ xfs_create( if (resblks == 0 && (error = xfs_dir_canenter(tp, dp, name, namelen))) goto error_return; - rdev = (vap->va_mask & XFS_AT_RDEV) ? vap->va_rdev : 0; - error = xfs_dir_ialloc(&tp, dp, vap->va_mode, 1, + error = xfs_dir_ialloc(&tp, dp, mode, 1, rdev, credp, prid, resblks > 0, &ip, &committed); if (error) { @@ -2001,7 +1898,7 @@ xfs_create( goto error_return; goto abort_return; } - ITRACE(ip); + xfs_itrace_ref(ip); /* * At this point, we've gotten a newly allocated inode. @@ -2011,15 +1908,15 @@ xfs_create( ASSERT(ismrlocked (&ip->i_lock, MR_UPDATE)); /* - * Now we join the directory inode to the transaction. - * We do not do it earlier because xfs_dir_ialloc - * might commit the previous transaction (and release - * all the locks). + * Now we join the directory inode to the transaction. We do not do it + * earlier because xfs_dir_ialloc might commit the previous transaction + * (and release all the locks). An error from here on will result in + * the transaction cancel unlocking dp so don't do it explicitly in the + * error path. */ - VN_HOLD(dir_vp); xfs_trans_ijoin(tp, dp, XFS_ILOCK_EXCL); - dp_joined_to_trans = B_TRUE; + unlock_dp_on_error = B_FALSE; error = xfs_dir_createname(tp, dp, name, namelen, ip->i_ino, &first_block, &free_list, resblks ? @@ -2073,25 +1970,18 @@ xfs_create( XFS_QM_DQRELE(mp, udqp); XFS_QM_DQRELE(mp, gdqp); - /* - * Propagate the fact that the vnode changed after the - * xfs_inode locks have been released. - */ - bhv_vop_vnode_change(vp, VCHANGE_FLAGS_TRUNCATED, 3); - *vpp = vp; /* Fallthrough to std_return with error = 0 */ std_return: - if ( (*vpp || (error != 0 && dm_event_sent != 0)) && - DM_EVENT_ENABLED(dir_vp->v_vfsp, XFS_BHVTOI(dir_bdp), - DM_EVENT_POSTCREATE)) { + if ((*vpp || (error != 0 && dm_event_sent != 0)) && + DM_EVENT_ENABLED(dp, DM_EVENT_POSTCREATE)) { (void) XFS_SEND_NAMESP(mp, DM_EVENT_POSTCREATE, dir_vp, DM_RIGHT_NULL, *vpp ? vp:NULL, DM_RIGHT_NULL, name, NULL, - dm_di_mode, error, 0); + mode, error, 0); } return error; @@ -2103,11 +1993,12 @@ std_return: if (tp != NULL) xfs_trans_cancel(tp, cancel_flags); - if (!dp_joined_to_trans && (dp != NULL)) - xfs_iunlock(dp, XFS_ILOCK_EXCL); XFS_QM_DQRELE(mp, udqp); XFS_QM_DQRELE(mp, gdqp); + if (unlock_dp_on_error) + xfs_iunlock(dp, XFS_ILOCK_EXCL); + goto std_return; abort_rele: @@ -2175,7 +2066,7 @@ again: e_inum = ip->i_ino; - ITRACE(ip); + xfs_itrace_ref(ip); /* * We want to lock in increasing inum. Since we've already @@ -2378,22 +2269,16 @@ int remove_which_error_return = 0; #define REMOVE_DEBUG_TRACE(x) #endif /* ! DEBUG */ - -/* - * xfs_remove - * - */ -STATIC int +int xfs_remove( - bhv_desc_t *dir_bdp, - bhv_vname_t *dentry, - cred_t *credp) + xfs_inode_t *dp, + bhv_vname_t *dentry) { - bhv_vnode_t *dir_vp; + bhv_vnode_t *dir_vp = XFS_ITOV(dp); char *name = VNAME(dentry); - xfs_inode_t *dp, *ip; + xfs_mount_t *mp = dp->i_mount; + xfs_inode_t *ip; xfs_trans_t *tp = NULL; - xfs_mount_t *mp; int error = 0; xfs_bmap_free_t free_list; xfs_fsblock_t first_block; @@ -2404,11 +2289,7 @@ xfs_remove( uint resblks; int namelen; - dir_vp = BHV_TO_VNODE(dir_bdp); - vn_trace_entry(dir_vp, __FUNCTION__, (inst_t *)__return_address); - - dp = XFS_BHVTOI(dir_bdp); - mp = dp->i_mount; + xfs_itrace_entry(dp); if (XFS_FORCED_SHUTDOWN(mp)) return XFS_ERROR(EIO); @@ -2420,7 +2301,7 @@ xfs_remove( IRELE(ip); } - if (DM_EVENT_ENABLED(dir_vp->v_vfsp, dp, DM_EVENT_REMOVE)) { + if (DM_EVENT_ENABLED(dp, DM_EVENT_REMOVE)) { error = XFS_SEND_NAMESP(mp, DM_EVENT_REMOVE, dir_vp, DM_RIGHT_NULL, NULL, DM_RIGHT_NULL, name, NULL, dm_di_mode, 0, 0); @@ -2451,9 +2332,8 @@ xfs_remove( dm_di_mode = ip->i_d.di_mode; - vn_trace_entry(XFS_ITOV(ip), __FUNCTION__, (inst_t *)__return_address); - - ITRACE(ip); + xfs_itrace_entry(ip); + xfs_itrace_ref(ip); error = XFS_QM_DQATTACH(mp, dp, 0); if (!error && dp != ip) @@ -2585,19 +2465,12 @@ xfs_remove( if (link_zero && xfs_inode_is_filestream(ip)) xfs_filestream_deassociate(ip); - vn_trace_exit(XFS_ITOV(ip), __FUNCTION__, (inst_t *)__return_address); - - /* - * Let interposed file systems know about removed links. - */ - bhv_vop_link_removed(XFS_ITOV(ip), dir_vp, link_zero); - + xfs_itrace_exit(ip); IRELE(ip); /* Fall through to std_return with error = 0 */ std_return: - if (DM_EVENT_ENABLED(dir_vp->v_vfsp, dp, - DM_EVENT_POSTREMOVE)) { + if (DM_EVENT_ENABLED(dp, DM_EVENT_POSTREMOVE)) { (void) XFS_SEND_NAMESP(mp, DM_EVENT_POSTREMOVE, dir_vp, DM_RIGHT_NULL, NULL, DM_RIGHT_NULL, @@ -2635,46 +2508,36 @@ xfs_remove( goto std_return; } - -/* - * xfs_link - * - */ -STATIC int +int xfs_link( - bhv_desc_t *target_dir_bdp, + xfs_inode_t *tdp, bhv_vnode_t *src_vp, - bhv_vname_t *dentry, - cred_t *credp) + bhv_vname_t *dentry) { - xfs_inode_t *tdp, *sip; + bhv_vnode_t *target_dir_vp = XFS_ITOV(tdp); + xfs_mount_t *mp = tdp->i_mount; + xfs_inode_t *sip = xfs_vtoi(src_vp); xfs_trans_t *tp; - xfs_mount_t *mp; xfs_inode_t *ips[2]; int error; xfs_bmap_free_t free_list; xfs_fsblock_t first_block; int cancel_flags; int committed; - bhv_vnode_t *target_dir_vp; int resblks; char *target_name = VNAME(dentry); int target_namelen; - target_dir_vp = BHV_TO_VNODE(target_dir_bdp); - vn_trace_entry(target_dir_vp, __FUNCTION__, (inst_t *)__return_address); - vn_trace_entry(src_vp, __FUNCTION__, (inst_t *)__return_address); + xfs_itrace_entry(tdp); + xfs_itrace_entry(xfs_vtoi(src_vp)); target_namelen = VNAMELEN(dentry); ASSERT(!VN_ISDIR(src_vp)); - sip = xfs_vtoi(src_vp); - tdp = XFS_BHVTOI(target_dir_bdp); - mp = tdp->i_mount; if (XFS_FORCED_SHUTDOWN(mp)) return XFS_ERROR(EIO); - if (DM_EVENT_ENABLED(src_vp->v_vfsp, tdp, DM_EVENT_LINK)) { + if (DM_EVENT_ENABLED(tdp, DM_EVENT_LINK)) { error = XFS_SEND_NAMESP(mp, DM_EVENT_LINK, target_dir_vp, DM_RIGHT_NULL, src_vp, DM_RIGHT_NULL, @@ -2785,8 +2648,7 @@ xfs_link( /* Fall through to std_return with error = 0. */ std_return: - if (DM_EVENT_ENABLED(src_vp->v_vfsp, sip, - DM_EVENT_POSTLINK)) { + if (DM_EVENT_ENABLED(sip, DM_EVENT_POSTLINK)) { (void) XFS_SEND_NAMESP(mp, DM_EVENT_POSTLINK, target_dir_vp, DM_RIGHT_NULL, src_vp, DM_RIGHT_NULL, @@ -2804,57 +2666,43 @@ std_return: } -/* - * xfs_mkdir - * - */ -STATIC int +int xfs_mkdir( - bhv_desc_t *dir_bdp, + xfs_inode_t *dp, bhv_vname_t *dentry, - bhv_vattr_t *vap, + mode_t mode, bhv_vnode_t **vpp, cred_t *credp) { + bhv_vnode_t *dir_vp = XFS_ITOV(dp); char *dir_name = VNAME(dentry); - xfs_inode_t *dp; + int dir_namelen = VNAMELEN(dentry); + xfs_mount_t *mp = dp->i_mount; xfs_inode_t *cdp; /* inode of created dir */ bhv_vnode_t *cvp; /* vnode of created dir */ xfs_trans_t *tp; - xfs_mount_t *mp; int cancel_flags; int error; int committed; xfs_bmap_free_t free_list; xfs_fsblock_t first_block; - bhv_vnode_t *dir_vp; - boolean_t dp_joined_to_trans; + boolean_t unlock_dp_on_error = B_FALSE; boolean_t created = B_FALSE; int dm_event_sent = 0; xfs_prid_t prid; struct xfs_dquot *udqp, *gdqp; uint resblks; - int dm_di_mode; - int dir_namelen; - - dir_vp = BHV_TO_VNODE(dir_bdp); - dp = XFS_BHVTOI(dir_bdp); - mp = dp->i_mount; if (XFS_FORCED_SHUTDOWN(mp)) return XFS_ERROR(EIO); - dir_namelen = VNAMELEN(dentry); - tp = NULL; - dp_joined_to_trans = B_FALSE; - dm_di_mode = vap->va_mode; - if (DM_EVENT_ENABLED(dir_vp->v_vfsp, dp, DM_EVENT_CREATE)) { + if (DM_EVENT_ENABLED(dp, DM_EVENT_CREATE)) { error = XFS_SEND_NAMESP(mp, DM_EVENT_CREATE, dir_vp, DM_RIGHT_NULL, NULL, DM_RIGHT_NULL, dir_name, NULL, - dm_di_mode, 0, 0); + mode, 0, 0); if (error) return error; dm_event_sent = 1; @@ -2862,14 +2710,12 @@ xfs_mkdir( /* Return through std_return after this point. */ - vn_trace_entry(dir_vp, __FUNCTION__, (inst_t *)__return_address); + xfs_itrace_entry(dp); mp = dp->i_mount; udqp = gdqp = NULL; if (dp->i_d.di_flags & XFS_DIFLAG_PROJINHERIT) prid = dp->i_d.di_projid; - else if (vap->va_mask & XFS_AT_PROJID) - prid = (xfs_prid_t)vap->va_projid; else prid = (xfs_prid_t)dfltprid; @@ -2895,11 +2741,11 @@ xfs_mkdir( } if (error) { cancel_flags = 0; - dp = NULL; goto error_return; } xfs_ilock(dp, XFS_ILOCK_EXCL | XFS_ILOCK_PARENT); + unlock_dp_on_error = B_TRUE; /* * Check for directory link count overflow. @@ -2922,7 +2768,7 @@ xfs_mkdir( /* * create the directory inode. */ - error = xfs_dir_ialloc(&tp, dp, vap->va_mode, 2, + error = xfs_dir_ialloc(&tp, dp, mode, 2, 0, credp, prid, resblks > 0, &cdp, NULL); if (error) { @@ -2930,17 +2776,19 @@ xfs_mkdir( goto error_return; goto abort_return; } - ITRACE(cdp); + xfs_itrace_ref(cdp); /* * Now we add the directory inode to the transaction. * We waited until now since xfs_dir_ialloc might start * a new transaction. Had we joined the transaction - * earlier, the locks might have gotten released. + * earlier, the locks might have gotten released. An error + * from here on will result in the transaction cancel + * unlocking dp so don't do it explicitly in the error path. */ VN_HOLD(dir_vp); xfs_trans_ijoin(tp, dp, XFS_ILOCK_EXCL); - dp_joined_to_trans = B_TRUE; + unlock_dp_on_error = B_FALSE; XFS_BMAP_INIT(&free_list, &first_block); @@ -3007,15 +2855,14 @@ xfs_mkdir( * xfs_trans_commit. */ std_return: - if ( (created || (error != 0 && dm_event_sent != 0)) && - DM_EVENT_ENABLED(dir_vp->v_vfsp, XFS_BHVTOI(dir_bdp), - DM_EVENT_POSTCREATE)) { + if ((created || (error != 0 && dm_event_sent != 0)) && + DM_EVENT_ENABLED(dp, DM_EVENT_POSTCREATE)) { (void) XFS_SEND_NAMESP(mp, DM_EVENT_POSTCREATE, dir_vp, DM_RIGHT_NULL, created ? XFS_ITOV(cdp):NULL, DM_RIGHT_NULL, dir_name, NULL, - dm_di_mode, error, 0); + mode, error, 0); } return error; @@ -3029,56 +2876,43 @@ std_return: XFS_QM_DQRELE(mp, udqp); XFS_QM_DQRELE(mp, gdqp); - if (!dp_joined_to_trans && (dp != NULL)) { + if (unlock_dp_on_error) xfs_iunlock(dp, XFS_ILOCK_EXCL); - } goto std_return; } - -/* - * xfs_rmdir - * - */ -STATIC int +int xfs_rmdir( - bhv_desc_t *dir_bdp, - bhv_vname_t *dentry, - cred_t *credp) + xfs_inode_t *dp, + bhv_vname_t *dentry) { + bhv_vnode_t *dir_vp = XFS_ITOV(dp); char *name = VNAME(dentry); - xfs_inode_t *dp; - xfs_inode_t *cdp; /* child directory */ + int namelen = VNAMELEN(dentry); + xfs_mount_t *mp = dp->i_mount; + xfs_inode_t *cdp; /* child directory */ xfs_trans_t *tp; - xfs_mount_t *mp; int error; xfs_bmap_free_t free_list; xfs_fsblock_t first_block; int cancel_flags; int committed; - bhv_vnode_t *dir_vp; int dm_di_mode = S_IFDIR; int last_cdp_link; - int namelen; uint resblks; - dir_vp = BHV_TO_VNODE(dir_bdp); - dp = XFS_BHVTOI(dir_bdp); - mp = dp->i_mount; + xfs_itrace_entry(dp); - vn_trace_entry(dir_vp, __FUNCTION__, (inst_t *)__return_address); - - if (XFS_FORCED_SHUTDOWN(XFS_BHVTOI(dir_bdp)->i_mount)) + if (XFS_FORCED_SHUTDOWN(mp)) return XFS_ERROR(EIO); - namelen = VNAMELEN(dentry); if (!xfs_get_dir_entry(dentry, &cdp)) { dm_di_mode = cdp->i_d.di_mode; IRELE(cdp); } - if (DM_EVENT_ENABLED(dir_vp->v_vfsp, dp, DM_EVENT_REMOVE)) { + if (DM_EVENT_ENABLED(dp, DM_EVENT_REMOVE)) { error = XFS_SEND_NAMESP(mp, DM_EVENT_REMOVE, dir_vp, DM_RIGHT_NULL, NULL, DM_RIGHT_NULL, @@ -3173,7 +3007,7 @@ xfs_rmdir( VN_HOLD(dir_vp); } - ITRACE(cdp); + xfs_itrace_ref(cdp); xfs_trans_ijoin(tp, cdp, XFS_ILOCK_EXCL); ASSERT(cdp->i_d.di_nlink >= 2); @@ -3257,17 +3091,12 @@ xfs_rmdir( } - /* - * Let interposed file systems know about removed links. - */ - bhv_vop_link_removed(XFS_ITOV(cdp), dir_vp, last_cdp_link); - IRELE(cdp); /* Fall through to std_return with error = 0 or the errno * from xfs_trans_commit. */ std_return: - if (DM_EVENT_ENABLED(dir_vp->v_vfsp, dp, DM_EVENT_POSTREMOVE)) { + if (DM_EVENT_ENABLED(dp, DM_EVENT_POSTREMOVE)) { (void) XFS_SEND_NAMESP(mp, DM_EVENT_POSTREMOVE, dir_vp, DM_RIGHT_NULL, NULL, DM_RIGHT_NULL, @@ -3286,56 +3115,24 @@ xfs_rmdir( goto std_return; } - -/* - * Read dp's entries starting at uiop->uio_offset and translate them into - * bufsize bytes worth of struct dirents starting at bufbase. - */ -STATIC int -xfs_readdir( - bhv_desc_t *dir_bdp, - uio_t *uiop, - cred_t *credp, - int *eofp) -{ - xfs_inode_t *dp; - xfs_trans_t *tp = NULL; - int error = 0; - uint lock_mode; - - vn_trace_entry(BHV_TO_VNODE(dir_bdp), __FUNCTION__, - (inst_t *)__return_address); - dp = XFS_BHVTOI(dir_bdp); - - if (XFS_FORCED_SHUTDOWN(dp->i_mount)) - return XFS_ERROR(EIO); - - lock_mode = xfs_ilock_map_shared(dp); - error = xfs_dir_getdents(tp, dp, uiop, eofp); - xfs_iunlock_map_shared(dp, lock_mode); - return error; -} - - -STATIC int +int xfs_symlink( - bhv_desc_t *dir_bdp, + xfs_inode_t *dp, bhv_vname_t *dentry, - bhv_vattr_t *vap, char *target_path, + mode_t mode, bhv_vnode_t **vpp, cred_t *credp) { + bhv_vnode_t *dir_vp = XFS_ITOV(dp); + xfs_mount_t *mp = dp->i_mount; xfs_trans_t *tp; - xfs_mount_t *mp; - xfs_inode_t *dp; xfs_inode_t *ip; int error; int pathlen; xfs_bmap_free_t free_list; xfs_fsblock_t first_block; - boolean_t dp_joined_to_trans; - bhv_vnode_t *dir_vp; + boolean_t unlock_dp_on_error = B_FALSE; uint cancel_flags; int committed; xfs_fileoff_t first_fsb; @@ -3354,16 +3151,11 @@ xfs_symlink( int link_namelen; *vpp = NULL; - dir_vp = BHV_TO_VNODE(dir_bdp); - dp = XFS_BHVTOI(dir_bdp); - dp_joined_to_trans = B_FALSE; error = 0; ip = NULL; tp = NULL; - vn_trace_entry(dir_vp, __FUNCTION__, (inst_t *)__return_address); - - mp = dp->i_mount; + xfs_itrace_entry(dp); if (XFS_FORCED_SHUTDOWN(mp)) return XFS_ERROR(EIO); @@ -3402,7 +3194,7 @@ xfs_symlink( } } - if (DM_EVENT_ENABLED(dir_vp->v_vfsp, dp, DM_EVENT_SYMLINK)) { + if (DM_EVENT_ENABLED(dp, DM_EVENT_SYMLINK)) { error = XFS_SEND_NAMESP(mp, DM_EVENT_SYMLINK, dir_vp, DM_RIGHT_NULL, NULL, DM_RIGHT_NULL, link_name, target_path, 0, 0, 0); @@ -3415,8 +3207,6 @@ xfs_symlink( udqp = gdqp = NULL; if (dp->i_d.di_flags & XFS_DIFLAG_PROJINHERIT) prid = dp->i_d.di_projid; - else if (vap->va_mask & XFS_AT_PROJID) - prid = (xfs_prid_t)vap->va_projid; else prid = (xfs_prid_t)dfltprid; @@ -3449,11 +3239,11 @@ xfs_symlink( } if (error) { cancel_flags = 0; - dp = NULL; goto error_return; } xfs_ilock(dp, XFS_ILOCK_EXCL | XFS_ILOCK_PARENT); + unlock_dp_on_error = B_TRUE; /* * Check whether the directory allows new symlinks or not. @@ -3485,18 +3275,23 @@ xfs_symlink( /* * Allocate an inode for the symlink. */ - error = xfs_dir_ialloc(&tp, dp, S_IFLNK | (vap->va_mode&~S_IFMT), + error = xfs_dir_ialloc(&tp, dp, S_IFLNK | (mode & ~S_IFMT), 1, 0, credp, prid, resblks > 0, &ip, NULL); if (error) { if (error == ENOSPC) goto error_return; goto error1; } - ITRACE(ip); + xfs_itrace_ref(ip); + /* + * An error after we've joined dp to the transaction will result in the + * transaction cancel unlocking dp so don't do it explicitly in the + * error path. + */ VN_HOLD(dir_vp); xfs_trans_ijoin(tp, dp, XFS_ILOCK_EXCL); - dp_joined_to_trans = B_TRUE; + unlock_dp_on_error = B_FALSE; /* * Also attach the dquot(s) to it, if applicable. @@ -3602,8 +3397,7 @@ xfs_symlink( /* Fall through to std_return with error = 0 or errno from * xfs_trans_commit */ std_return: - if (DM_EVENT_ENABLED(dir_vp->v_vfsp, XFS_BHVTOI(dir_bdp), - DM_EVENT_POSTSYMLINK)) { + if (DM_EVENT_ENABLED(dp, DM_EVENT_POSTSYMLINK)) { (void) XFS_SEND_NAMESP(mp, DM_EVENT_POSTSYMLINK, dir_vp, DM_RIGHT_NULL, error ? NULL : XFS_ITOV(ip), @@ -3630,62 +3424,19 @@ std_return: XFS_QM_DQRELE(mp, udqp); XFS_QM_DQRELE(mp, gdqp); - if (!dp_joined_to_trans && (dp != NULL)) { + if (unlock_dp_on_error) xfs_iunlock(dp, XFS_ILOCK_EXCL); - } goto std_return; } - -/* - * xfs_fid2 - * - * A fid routine that takes a pointer to a previously allocated - * fid structure (like xfs_fast_fid) but uses a 64 bit inode number. - */ -STATIC int -xfs_fid2( - bhv_desc_t *bdp, - fid_t *fidp) -{ - xfs_inode_t *ip; - xfs_fid2_t *xfid; - - vn_trace_entry(BHV_TO_VNODE(bdp), __FUNCTION__, - (inst_t *)__return_address); - ASSERT(sizeof(fid_t) >= sizeof(xfs_fid2_t)); - - xfid = (xfs_fid2_t *)fidp; - ip = XFS_BHVTOI(bdp); - xfid->fid_len = sizeof(xfs_fid2_t) - sizeof(xfid->fid_len); - xfid->fid_pad = 0; - /* - * use memcpy because the inode is a long long and there's no - * assurance that xfid->fid_ino is properly aligned. - */ - memcpy(&xfid->fid_ino, &ip->i_ino, sizeof(xfid->fid_ino)); - xfid->fid_gen = ip->i_d.di_gen; - - return 0; -} - - -/* - * xfs_rwlock - */ int xfs_rwlock( - bhv_desc_t *bdp, + xfs_inode_t *ip, bhv_vrwlock_t locktype) { - xfs_inode_t *ip; - bhv_vnode_t *vp; - - vp = BHV_TO_VNODE(bdp); - if (VN_ISDIR(vp)) + if (S_ISDIR(ip->i_d.di_mode)) return 1; - ip = XFS_BHVTOI(bdp); if (locktype == VRWLOCK_WRITE) { xfs_ilock(ip, XFS_IOLOCK_EXCL); } else if (locktype == VRWLOCK_TRY_READ) { @@ -3702,21 +3453,13 @@ xfs_rwlock( } -/* - * xfs_rwunlock - */ void xfs_rwunlock( - bhv_desc_t *bdp, + xfs_inode_t *ip, bhv_vrwlock_t locktype) { - xfs_inode_t *ip; - bhv_vnode_t *vp; - - vp = BHV_TO_VNODE(bdp); - if (VN_ISDIR(vp)) - return; - ip = XFS_BHVTOI(bdp); + if (S_ISDIR(ip->i_d.di_mode)) + return; if (locktype == VRWLOCK_WRITE) { /* * In the write case, we may have added a new entry to @@ -3734,20 +3477,16 @@ xfs_rwunlock( return; } -STATIC int + +int xfs_inode_flush( - bhv_desc_t *bdp, + xfs_inode_t *ip, int flags) { - xfs_inode_t *ip; - xfs_mount_t *mp; - xfs_inode_log_item_t *iip; + xfs_mount_t *mp = ip->i_mount; + xfs_inode_log_item_t *iip = ip->i_itemp; int error = 0; - ip = XFS_BHVTOI(bdp); - mp = ip->i_mount; - iip = ip->i_itemp; - if (XFS_FORCED_SHUTDOWN(mp)) return XFS_ERROR(EIO); @@ -3763,18 +3502,22 @@ xfs_inode_flush( if (iip && iip->ili_last_lsn) { xlog_t *log = mp->m_log; xfs_lsn_t sync_lsn; - int s, log_flags = XFS_LOG_FORCE; + int log_flags = XFS_LOG_FORCE; - s = GRANT_LOCK(log); + spin_lock(&log->l_grant_lock); sync_lsn = log->l_last_sync_lsn; - GRANT_UNLOCK(log, s); + spin_unlock(&log->l_grant_lock); - if ((XFS_LSN_CMP(iip->ili_last_lsn, sync_lsn) <= 0)) - return 0; + if ((XFS_LSN_CMP(iip->ili_last_lsn, sync_lsn) > 0)) { + if (flags & FLUSH_SYNC) + log_flags |= XFS_LOG_SYNC; + error = xfs_log_force(mp, iip->ili_last_lsn, log_flags); + if (error) + return error; + } - if (flags & FLUSH_SYNC) - log_flags |= XFS_LOG_SYNC; - return xfs_log_force(mp, iip->ili_last_lsn, log_flags); + if (ip->i_update_core == 0) + return 0; } } @@ -3788,9 +3531,6 @@ xfs_inode_flush( if (flags & FLUSH_INODE) { int flush_flags; - if (xfs_ipincount(ip)) - return EAGAIN; - if (flags & FLUSH_SYNC) { xfs_ilock(ip, XFS_ILOCK_SHARED); xfs_iflock(ip); @@ -3815,24 +3555,20 @@ xfs_inode_flush( return error; } + int -xfs_set_dmattrs ( - bhv_desc_t *bdp, +xfs_set_dmattrs( + xfs_inode_t *ip, u_int evmask, - u_int16_t state, - cred_t *credp) + u_int16_t state) { - xfs_inode_t *ip; + xfs_mount_t *mp = ip->i_mount; xfs_trans_t *tp; - xfs_mount_t *mp; int error; if (!capable(CAP_SYS_ADMIN)) return XFS_ERROR(EPERM); - ip = XFS_BHVTOI(bdp); - mp = ip->i_mount; - if (XFS_FORCED_SHUTDOWN(mp)) return XFS_ERROR(EIO); @@ -3845,8 +3581,8 @@ xfs_set_dmattrs ( xfs_ilock(ip, XFS_ILOCK_EXCL); xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL); - ip->i_iocore.io_dmevmask = ip->i_d.di_dmevmask = evmask; - ip->i_iocore.io_dmstate = ip->i_d.di_dmstate = state; + ip->i_d.di_dmevmask = evmask; + ip->i_d.di_dmstate = state; xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); IHOLD(ip); @@ -3855,17 +3591,13 @@ xfs_set_dmattrs ( return error; } -STATIC int +int xfs_reclaim( - bhv_desc_t *bdp) + xfs_inode_t *ip) { - xfs_inode_t *ip; - bhv_vnode_t *vp; + bhv_vnode_t *vp = XFS_ITOV(ip); - vp = BHV_TO_VNODE(bdp); - ip = XFS_BHVTOI(bdp); - - vn_trace_entry(vp, __FUNCTION__, (inst_t *)__return_address); + xfs_itrace_entry(ip); ASSERT(!VN_MAPPED(vp)); @@ -3875,7 +3607,7 @@ xfs_reclaim( return 0; } - vn_iowait(vp); + vn_iowait(ip); ASSERT(XFS_FORCED_SHUTDOWN(ip->i_mount) || ip->i_delayed_blks == 0); @@ -3907,7 +3639,8 @@ xfs_reclaim( XFS_MOUNT_ILOCK(mp); spin_lock(&ip->i_flags_lock); __xfs_iflags_set(ip, XFS_IRECLAIMABLE); - vn_bhv_remove(VN_BHV_HEAD(vp), XFS_ITOBHV(ip)); + vn_to_inode(vp)->i_private = NULL; + ip->i_vnode = NULL; spin_unlock(&ip->i_flags_lock); list_add_tail(&ip->i_reclaim, &mp->m_del_inodes); XFS_MOUNT_IUNLOCK(mp); @@ -3921,7 +3654,7 @@ xfs_finish_reclaim( int locked, int sync_mode) { - xfs_ihash_t *ih = ip->i_hash; + xfs_perag_t *pag = xfs_get_perag(ip->i_mount, ip->i_ino); bhv_vnode_t *vp = XFS_ITOV_NULL(ip); int error; @@ -3933,12 +3666,12 @@ xfs_finish_reclaim( * Once we have the XFS_IRECLAIM flag set it will not touch * us. */ - write_lock(&ih->ih_lock); + write_lock(&pag->pag_ici_lock); spin_lock(&ip->i_flags_lock); if (__xfs_iflags_test(ip, XFS_IRECLAIM) || (!__xfs_iflags_test(ip, XFS_IRECLAIMABLE) && vp == NULL)) { spin_unlock(&ip->i_flags_lock); - write_unlock(&ih->ih_lock); + write_unlock(&pag->pag_ici_lock); if (locked) { xfs_ifunlock(ip); xfs_iunlock(ip, XFS_ILOCK_EXCL); @@ -3947,7 +3680,8 @@ xfs_finish_reclaim( } __xfs_iflags_set(ip, XFS_IRECLAIM); spin_unlock(&ip->i_flags_lock); - write_unlock(&ih->ih_lock); + write_unlock(&pag->pag_ici_lock); + xfs_put_perag(ip->i_mount, pag); /* * If the inode is still dirty, then flush it out. If the inode @@ -4081,7 +3815,7 @@ xfs_alloc_file_space( int committed; int error; - vn_trace_entry(XFS_ITOV(ip), __FUNCTION__, (inst_t *)__return_address); + xfs_itrace_entry(ip); if (XFS_FORCED_SHUTDOWN(mp)) return XFS_ERROR(EIO); @@ -4105,7 +3839,7 @@ xfs_alloc_file_space( /* Generate a DMAPI event if needed. */ if (alloc_type != 0 && offset < ip->i_size && (attr_flags&ATTR_DMI) == 0 && - DM_EVENT_ENABLED(XFS_MTOVFS(mp), ip, DM_EVENT_WRITE)) { + DM_EVENT_ENABLED(ip, DM_EVENT_WRITE)) { xfs_off_t end_dmi_offset; end_dmi_offset = offset+len; @@ -4186,7 +3920,7 @@ retry: * Issue the xfs_bmapi() call to allocate the blocks */ XFS_BMAP_INIT(&free_list, &firstfsb); - error = XFS_BMAPI(mp, tp, &ip->i_iocore, startoffset_fsb, + error = xfs_bmapi(tp, ip, startoffset_fsb, allocatesize_fsb, bmapi_flag, &firstfsb, 0, imapp, &nimaps, &free_list, NULL); @@ -4219,9 +3953,8 @@ retry: allocatesize_fsb -= allocated_fsb; } dmapi_enospc_check: - if (error == ENOSPC && (attr_flags&ATTR_DMI) == 0 && - DM_EVENT_ENABLED(XFS_MTOVFS(mp), ip, DM_EVENT_NOSPACE)) { - + if (error == ENOSPC && (attr_flags & ATTR_DMI) == 0 && + DM_EVENT_ENABLED(ip, DM_EVENT_NOSPACE)) { error = XFS_SEND_NAMESP(mp, DM_EVENT_NOSPACE, XFS_ITOV(ip), DM_RIGHT_NULL, XFS_ITOV(ip), DM_RIGHT_NULL, @@ -4263,13 +3996,13 @@ xfs_zero_remaining_bytes( int error = 0; bp = xfs_buf_get_noaddr(mp->m_sb.sb_blocksize, - ip->i_d.di_flags & XFS_DIFLAG_REALTIME ? + XFS_IS_REALTIME_INODE(ip) ? mp->m_rtdev_targp : mp->m_ddev_targp); for (offset = startoff; offset <= endoff; offset = lastoffset + 1) { offset_fsb = XFS_B_TO_FSBT(mp, offset); nimap = 1; - error = XFS_BMAPI(mp, NULL, &ip->i_iocore, offset_fsb, 1, 0, + error = xfs_bmapi(NULL, ip, offset_fsb, 1, 0, NULL, 0, &imap, &nimap, NULL, NULL); if (error || nimap < 1) break; @@ -4352,7 +4085,7 @@ xfs_free_file_space( vp = XFS_ITOV(ip); mp = ip->i_mount; - vn_trace_entry(vp, __FUNCTION__, (inst_t *)__return_address); + xfs_itrace_entry(ip); if ((error = XFS_QM_DQATTACH(mp, ip, 0))) return error; @@ -4360,14 +4093,13 @@ xfs_free_file_space( error = 0; if (len <= 0) /* if nothing being freed */ return error; - rt = (ip->i_d.di_flags & XFS_DIFLAG_REALTIME); + rt = XFS_IS_REALTIME_INODE(ip); startoffset_fsb = XFS_B_TO_FSB(mp, offset); end_dmi_offset = offset + len; endoffset_fsb = XFS_B_TO_FSBT(mp, end_dmi_offset); - if (offset < ip->i_size && - (attr_flags & ATTR_DMI) == 0 && - DM_EVENT_ENABLED(XFS_MTOVFS(mp), ip, DM_EVENT_WRITE)) { + if (offset < ip->i_size && (attr_flags & ATTR_DMI) == 0 && + DM_EVENT_ENABLED(ip, DM_EVENT_WRITE)) { if (end_dmi_offset > ip->i_size) end_dmi_offset = ip->i_size; error = XFS_SEND_DATA(mp, DM_EVENT_WRITE, vp, @@ -4381,17 +4113,15 @@ xfs_free_file_space( need_iolock = 0; if (need_iolock) { xfs_ilock(ip, XFS_IOLOCK_EXCL); - vn_iowait(vp); /* wait for the completion of any pending DIOs */ + vn_iowait(ip); /* wait for the completion of any pending DIOs */ } - rounding = max_t(uint, 1 << mp->m_sb.sb_blocklog, NBPP); + rounding = max_t(uint, 1 << mp->m_sb.sb_blocklog, PAGE_CACHE_SIZE); ioffset = offset & ~(rounding - 1); if (VN_CACHED(vp) != 0) { - xfs_inval_cached_trace(&ip->i_iocore, ioffset, -1, - ctooff(offtoct(ioffset)), -1); - error = bhv_vop_flushinval_pages(vp, ctooff(offtoct(ioffset)), - -1, FI_REMAPF_LOCKED); + xfs_inval_cached_trace(ip, ioffset, -1, ioffset, -1); + error = xfs_flushinval_pages(ip, ioffset, -1, FI_REMAPF_LOCKED); if (error) goto out_unlock_iolock; } @@ -4404,7 +4134,7 @@ xfs_free_file_space( */ if (rt && !XFS_SB_VERSION_HASEXTFLGBIT(&mp->m_sb)) { nimap = 1; - error = XFS_BMAPI(mp, NULL, &ip->i_iocore, startoffset_fsb, + error = xfs_bmapi(NULL, ip, startoffset_fsb, 1, 0, NULL, 0, &imap, &nimap, NULL, NULL); if (error) goto out_unlock_iolock; @@ -4419,7 +4149,7 @@ xfs_free_file_space( startoffset_fsb += mp->m_sb.sb_rextsize - mod; } nimap = 1; - error = XFS_BMAPI(mp, NULL, &ip->i_iocore, endoffset_fsb - 1, + error = xfs_bmapi(NULL, ip, endoffset_fsb - 1, 1, 0, NULL, 0, &imap, &nimap, NULL, NULL); if (error) goto out_unlock_iolock; @@ -4495,7 +4225,7 @@ xfs_free_file_space( * issue the bunmapi() call to free the blocks */ XFS_BMAP_INIT(&free_list, &firstfsb); - error = XFS_BUNMAPI(mp, tp, &ip->i_iocore, startoffset_fsb, + error = xfs_bunmapi(tp, ip, startoffset_fsb, endoffset_fsb - startoffset_fsb, 0, 2, &firstfsb, &free_list, NULL, &done); if (error) { @@ -4541,46 +4271,28 @@ xfs_free_file_space( */ int xfs_change_file_space( - bhv_desc_t *bdp, + xfs_inode_t *ip, int cmd, xfs_flock64_t *bf, xfs_off_t offset, cred_t *credp, int attr_flags) { + xfs_mount_t *mp = ip->i_mount; int clrprealloc; int error; xfs_fsize_t fsize; - xfs_inode_t *ip; - xfs_mount_t *mp; int setprealloc; xfs_off_t startoffset; xfs_off_t llen; xfs_trans_t *tp; bhv_vattr_t va; - bhv_vnode_t *vp; - vp = BHV_TO_VNODE(bdp); - vn_trace_entry(vp, __FUNCTION__, (inst_t *)__return_address); - - ip = XFS_BHVTOI(bdp); - mp = ip->i_mount; + xfs_itrace_entry(ip); - /* - * must be a regular file and have write permission - */ - if (!VN_ISREG(vp)) + if (!S_ISREG(ip->i_d.di_mode)) return XFS_ERROR(EINVAL); - xfs_ilock(ip, XFS_ILOCK_SHARED); - - if ((error = xfs_iaccess(ip, S_IWUSR, credp))) { - xfs_iunlock(ip, XFS_ILOCK_SHARED); - return error; - } - - xfs_iunlock(ip, XFS_ILOCK_SHARED); - switch (bf->l_whence) { case 0: /*SEEK_SET*/ break; @@ -4651,7 +4363,7 @@ xfs_change_file_space( va.va_mask = XFS_AT_SIZE; va.va_size = startoffset; - error = xfs_setattr(bdp, &va, attr_flags, credp); + error = xfs_setattr(ip, &va, attr_flags, credp); if (error) return error; @@ -4710,46 +4422,3 @@ xfs_change_file_space( return error; } - -bhv_vnodeops_t xfs_vnodeops = { - BHV_IDENTITY_INIT(VN_BHV_XFS,VNODE_POSITION_XFS), - .vop_open = xfs_open, - .vop_read = xfs_read, -#ifdef HAVE_SPLICE - .vop_splice_read = xfs_splice_read, - .vop_splice_write = xfs_splice_write, -#endif - .vop_write = xfs_write, - .vop_ioctl = xfs_ioctl, - .vop_getattr = xfs_getattr, - .vop_setattr = xfs_setattr, - .vop_access = xfs_access, - .vop_lookup = xfs_lookup, - .vop_create = xfs_create, - .vop_remove = xfs_remove, - .vop_link = xfs_link, - .vop_rename = xfs_rename, - .vop_mkdir = xfs_mkdir, - .vop_rmdir = xfs_rmdir, - .vop_readdir = xfs_readdir, - .vop_symlink = xfs_symlink, - .vop_readlink = xfs_readlink, - .vop_fsync = xfs_fsync, - .vop_inactive = xfs_inactive, - .vop_fid2 = xfs_fid2, - .vop_rwlock = xfs_rwlock, - .vop_rwunlock = xfs_rwunlock, - .vop_bmap = xfs_bmap, - .vop_reclaim = xfs_reclaim, - .vop_attr_get = xfs_attr_get, - .vop_attr_set = xfs_attr_set, - .vop_attr_remove = xfs_attr_remove, - .vop_attr_list = xfs_attr_list, - .vop_link_removed = (vop_link_removed_t)fs_noval, - .vop_vnode_change = (vop_vnode_change_t)fs_noval, - .vop_tosspages = fs_tosspages, - .vop_flushinval_pages = fs_flushinval_pages, - .vop_flush_pages = fs_flush_pages, - .vop_release = xfs_release, - .vop_iflush = xfs_inode_flush, -};