From 461aa8a22595e3bd3e6f4dc2894d7c4315ea2bb9 Mon Sep 17 00:00:00 2001 From: Lachlan McIlroy Date: Thu, 6 Mar 2008 13:43:11 +1100 Subject: [XFS] make inode reclaim synchronise with xfs_iflush_done() On a forced shutdown, xfs_finish_reclaim() will skip flushing the inode. If the inode flush lock is not already held and there is an outstanding xfs_iflush_done() then we might free the inode prematurely. By acquiring and releasing the flush lock we will synchronise with xfs_iflush_done(). SGI-PV: 909874 SGI-Modid: xfs-linux-melb:xfs-kern:30468a Signed-off-by: Lachlan McIlroy Signed-off-by: David Chinner --- fs/xfs/xfs_vnodeops.c | 22 ++++++++-------------- 1 file changed, 8 insertions(+), 14 deletions(-) (limited to 'fs/xfs/xfs_vnodeops.c') diff --git a/fs/xfs/xfs_vnodeops.c b/fs/xfs/xfs_vnodeops.c index 64c5953feca..ce82a2d0acb 100644 --- a/fs/xfs/xfs_vnodeops.c +++ b/fs/xfs/xfs_vnodeops.c @@ -3694,12 +3694,12 @@ xfs_finish_reclaim( * We get the flush lock regardless, though, just to make sure * we don't free it while it is being flushed. */ - if (!XFS_FORCED_SHUTDOWN(ip->i_mount)) { - if (!locked) { - xfs_ilock(ip, XFS_ILOCK_EXCL); - xfs_iflock(ip); - } + if (!locked) { + xfs_ilock(ip, XFS_ILOCK_EXCL); + xfs_iflock(ip); + } + if (!XFS_FORCED_SHUTDOWN(ip->i_mount)) { if (ip->i_update_core || ((ip->i_itemp != NULL) && (ip->i_itemp->ili_format.ilf_fields != 0))) { @@ -3719,17 +3719,11 @@ xfs_finish_reclaim( ASSERT(ip->i_update_core == 0); ASSERT(ip->i_itemp == NULL || ip->i_itemp->ili_format.ilf_fields == 0); - xfs_iunlock(ip, XFS_ILOCK_EXCL); - } else if (locked) { - /* - * We are not interested in doing an iflush if we're - * in the process of shutting down the filesystem forcibly. - * So, just reclaim the inode. - */ - xfs_ifunlock(ip); - xfs_iunlock(ip, XFS_ILOCK_EXCL); } + xfs_ifunlock(ip); + xfs_iunlock(ip, XFS_ILOCK_EXCL); + reclaim: xfs_ireclaim(ip); return 0; -- cgit v1.2.3 From 163d3686bb09d88e2120bffe780a3f2d7cc4c948 Mon Sep 17 00:00:00 2001 From: Donald Douwsma Date: Thu, 6 Mar 2008 13:43:20 +1100 Subject: [XFS] Remove the xfs_refcache Remove the xfs_refcache, it was only needed while we were still building for 2.4 kernels. SGI-PV: 971186 SGI-Modid: xfs-linux-melb:xfs-kern:30472a Signed-off-by: Donald Douwsma Signed-off-by: Christoph Hellwig Signed-off-by: Lachlan McIlroy --- fs/xfs/xfs_vnodeops.c | 34 +--------------------------------- 1 file changed, 1 insertion(+), 33 deletions(-) (limited to 'fs/xfs/xfs_vnodeops.c') diff --git a/fs/xfs/xfs_vnodeops.c b/fs/xfs/xfs_vnodeops.c index ce82a2d0acb..35ac59dabf8 100644 --- a/fs/xfs/xfs_vnodeops.c +++ b/fs/xfs/xfs_vnodeops.c @@ -48,7 +48,6 @@ #include "xfs_quota.h" #include "xfs_utils.h" #include "xfs_rtalloc.h" -#include "xfs_refcache.h" #include "xfs_trans_space.h" #include "xfs_log_priv.h" #include "xfs_filestream.h" @@ -1520,12 +1519,6 @@ xfs_release( xfs_flush_pages(ip, 0, -1, XFS_B_ASYNC, FI_NONE); } -#ifdef HAVE_REFCACHE - /* If we are in the NFS reference cache then don't do this now */ - if (ip->i_refcache) - return 0; -#endif - if (ip->i_d.di_nlink != 0) { if ((((ip->i_d.di_mode & S_IFMT) == S_IFREG) && ((ip->i_size > 0) || (VN_CACHED(vp) > 0 || @@ -2448,14 +2441,6 @@ xfs_remove( goto std_return; } - /* - * Before we drop our extra reference to the inode, purge it - * from the refcache if it is there. By waiting until afterwards - * to do the IRELE, we ensure that we won't go inactive in the - * xfs_refcache_purge_ip routine (although that would be OK). - */ - xfs_refcache_purge_ip(ip); - /* * If we are using filestreams, kill the stream association. * If the file is still open it may get a new one but that @@ -2495,14 +2480,6 @@ xfs_remove( cancel_flags |= XFS_TRANS_ABORT; xfs_trans_cancel(tp, cancel_flags); - /* - * Before we drop our extra reference to the inode, purge it - * from the refcache if it is there. By waiting until afterwards - * to do the IRELE, we ensure that we won't go inactive in the - * xfs_refcache_purge_ip routine (although that would be OK). - */ - xfs_refcache_purge_ip(ip); - IRELE(ip); goto std_return; @@ -3460,16 +3437,7 @@ xfs_rwunlock( { 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 - * the reference cache. This might store a pointer to - * an inode to be released in this inode. If it is there, - * clear the pointer and release the inode after unlocking - * this one. - */ - xfs_refcache_iunlock(ip, XFS_IOLOCK_EXCL); - } else { + if (locktype != VRWLOCK_WRITE) { ASSERT((locktype == VRWLOCK_READ) || (locktype == VRWLOCK_WRITE_DIRECT)); xfs_iunlock(ip, XFS_IOLOCK_SHARED); -- cgit v1.2.3 From e9a56b7cdaf6129892fd7c8d950b71a1a4304bb0 Mon Sep 17 00:00:00 2001 From: Lachlan McIlroy Date: Thu, 6 Mar 2008 13:43:27 +1100 Subject: [XFS] Fix regression due to refcache removal SGI-PV: 971186 SGI-Modid: xfs-linux-melb:xfs-kern:30490a Signed-off-by: Lachlan McIlroy Signed-off-by: Donald Douwsma --- fs/xfs/xfs_vnodeops.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'fs/xfs/xfs_vnodeops.c') diff --git a/fs/xfs/xfs_vnodeops.c b/fs/xfs/xfs_vnodeops.c index 35ac59dabf8..40b95e3a88b 100644 --- a/fs/xfs/xfs_vnodeops.c +++ b/fs/xfs/xfs_vnodeops.c @@ -3437,7 +3437,9 @@ xfs_rwunlock( { if (S_ISDIR(ip->i_d.di_mode)) return; - if (locktype != VRWLOCK_WRITE) { + if (locktype == VRWLOCK_WRITE) { + xfs_iunlock(ip, XFS_IOLOCK_EXCL); + } else { ASSERT((locktype == VRWLOCK_READ) || (locktype == VRWLOCK_WRITE_DIRECT)); xfs_iunlock(ip, XFS_IOLOCK_SHARED); -- cgit v1.2.3 From a3f74ffb6d1448d9a8f482e593b80ec15f1695d4 Mon Sep 17 00:00:00 2001 From: David Chinner Date: Thu, 6 Mar 2008 13:43:42 +1100 Subject: [XFS] Don't block pdflush when writing back inodes When pdflush is writing back inodes, it can get stuck on inode cluster buffers that are currently under I/O. This occurs when we write data to multiple inodes in the same inode cluster at the same time. Effectively, delayed allocation marks the inode dirty during the data writeback. Hence if the inode cluster was flushed during the writeback of the first inode, the writeback of the second inode will block waiting for the inode cluster write to complete before writing it again for the newly dirtied inode. Basically, we want to avoid this from happening so we don't block pdflush and slow down all of writeback. Hence we introduce a non-blocking async inode flush flag that pdflush uses. If this flag is set, we use non-blocking operations (e.g. try locks) whereever we can to avoid blocking or extra I/O being issued. SGI-PV: 970925 SGI-Modid: xfs-linux-melb:xfs-kern:30501a Signed-off-by: David Chinner Signed-off-by: Lachlan McIlroy --- fs/xfs/xfs_vnodeops.c | 55 +++++++++++---------------------------------------- 1 file changed, 12 insertions(+), 43 deletions(-) (limited to 'fs/xfs/xfs_vnodeops.c') diff --git a/fs/xfs/xfs_vnodeops.c b/fs/xfs/xfs_vnodeops.c index 40b95e3a88b..14140f6225b 100644 --- a/fs/xfs/xfs_vnodeops.c +++ b/fs/xfs/xfs_vnodeops.c @@ -3468,29 +3468,6 @@ xfs_inode_flush( ((iip == NULL) || !(iip->ili_format.ilf_fields & XFS_ILOG_ALL))) return 0; - if (flags & FLUSH_LOG) { - if (iip && iip->ili_last_lsn) { - xlog_t *log = mp->m_log; - xfs_lsn_t sync_lsn; - int log_flags = XFS_LOG_FORCE; - - spin_lock(&log->l_grant_lock); - sync_lsn = log->l_last_sync_lsn; - spin_unlock(&log->l_grant_lock); - - 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 (ip->i_update_core == 0) - return 0; - } - } - /* * We make this non-blocking if the inode is contended, * return EAGAIN to indicate to the caller that they @@ -3498,30 +3475,22 @@ xfs_inode_flush( * blocking on inodes inside another operation right * now, they get caught later by xfs_sync. */ - if (flags & FLUSH_INODE) { - int flush_flags; - - if (flags & FLUSH_SYNC) { - xfs_ilock(ip, XFS_ILOCK_SHARED); - xfs_iflock(ip); - } else if (xfs_ilock_nowait(ip, XFS_ILOCK_SHARED)) { - if (xfs_ipincount(ip) || !xfs_iflock_nowait(ip)) { - xfs_iunlock(ip, XFS_ILOCK_SHARED); - return EAGAIN; - } - } else { + if (flags & FLUSH_SYNC) { + xfs_ilock(ip, XFS_ILOCK_SHARED); + xfs_iflock(ip); + } else if (xfs_ilock_nowait(ip, XFS_ILOCK_SHARED)) { + if (xfs_ipincount(ip) || !xfs_iflock_nowait(ip)) { + xfs_iunlock(ip, XFS_ILOCK_SHARED); return EAGAIN; } - - if (flags & FLUSH_SYNC) - flush_flags = XFS_IFLUSH_SYNC; - else - flush_flags = XFS_IFLUSH_ASYNC; - - error = xfs_iflush(ip, flush_flags); - xfs_iunlock(ip, XFS_ILOCK_SHARED); + } else { + return EAGAIN; } + error = xfs_iflush(ip, (flags & FLUSH_SYNC) ? XFS_IFLUSH_SYNC + : XFS_IFLUSH_ASYNC_NOBLOCK); + xfs_iunlock(ip, XFS_ILOCK_SHARED); + return error; } -- cgit v1.2.3 From 3354040897f828644be6ca5783588e9f64a53b8e Mon Sep 17 00:00:00 2001 From: David Chinner Date: Thu, 6 Mar 2008 13:43:59 +1100 Subject: [XFS] Use xfs_inode_clean() in more places Remove open coded checks for the whether the inode is clean and replace them with an inlined function. SGI-PV: 977461 SGI-Modid: xfs-linux-melb:xfs-kern:30503a Signed-off-by: David Chinner Signed-off-by: Christoph Hellwig Signed-off-by: Lachlan McIlroy --- fs/xfs/xfs_vnodeops.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'fs/xfs/xfs_vnodeops.c') diff --git a/fs/xfs/xfs_vnodeops.c b/fs/xfs/xfs_vnodeops.c index 14140f6225b..5390d124ad3 100644 --- a/fs/xfs/xfs_vnodeops.c +++ b/fs/xfs/xfs_vnodeops.c @@ -3454,7 +3454,6 @@ xfs_inode_flush( int flags) { xfs_mount_t *mp = ip->i_mount; - xfs_inode_log_item_t *iip = ip->i_itemp; int error = 0; if (XFS_FORCED_SHUTDOWN(mp)) @@ -3464,8 +3463,7 @@ xfs_inode_flush( * Bypass inodes which have already been cleaned by * the inode flush clustering code inside xfs_iflush */ - if ((ip->i_update_core == 0) && - ((iip == NULL) || !(iip->ili_format.ilf_fields & XFS_ILOG_ALL))) + if (xfs_inode_clean(ip)) return 0; /* -- cgit v1.2.3 From 43973964a386348af0a392266f008ba24170aa30 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Thu, 6 Mar 2008 13:44:50 +1100 Subject: [XFS] kill xfs_get_dir_entry Instead of of xfs_get_dir_entry use a macro to get the xfs_inode from the dentry in the callers and grab the reference manually. Only grab the reference once as it's fine to keep it over the dmapi calls. (And even that reference is actually superflous in Linux but I'll leave that for another patch) SGI-PV: 976035 SGI-Modid: xfs-linux-melb:xfs-kern:30531a Signed-off-by: Christoph Hellwig Signed-off-by: Lachlan McIlroy --- fs/xfs/xfs_vnodeops.c | 51 +++++++++------------------------------------------ 1 file changed, 9 insertions(+), 42 deletions(-) (limited to 'fs/xfs/xfs_vnodeops.c') diff --git a/fs/xfs/xfs_vnodeops.c b/fs/xfs/xfs_vnodeops.c index 5390d124ad3..4765e7c4b75 100644 --- a/fs/xfs/xfs_vnodeops.c +++ b/fs/xfs/xfs_vnodeops.c @@ -2270,41 +2270,30 @@ xfs_remove( bhv_vnode_t *dir_vp = XFS_ITOV(dp); char *name = VNAME(dentry); xfs_mount_t *mp = dp->i_mount; - xfs_inode_t *ip; + xfs_inode_t *ip = VNAME_TO_INODE(dentry); + int namelen = VNAMELEN(dentry); xfs_trans_t *tp = NULL; int error = 0; xfs_bmap_free_t free_list; xfs_fsblock_t first_block; int cancel_flags; int committed; - int dm_di_mode = 0; int link_zero; uint resblks; - int namelen; xfs_itrace_entry(dp); if (XFS_FORCED_SHUTDOWN(mp)) return XFS_ERROR(EIO); - namelen = VNAMELEN(dentry); - - if (!xfs_get_dir_entry(dentry, &ip)) { - dm_di_mode = ip->i_d.di_mode; - IRELE(ip); - } - 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); + name, NULL, ip->i_d.di_mode, 0, 0); if (error) return error; } - /* From this point on, return through std_return */ - ip = NULL; - /* * We need to get a reference to ip before we get our log * reservation. The reason for this is that we cannot call @@ -2317,13 +2306,7 @@ xfs_remove( * when we call xfs_iget. Instead we get an unlocked reference * to the inode before getting our log reservation. */ - error = xfs_get_dir_entry(dentry, &ip); - if (error) { - REMOVE_DEBUG_TRACE(__LINE__); - goto std_return; - } - - dm_di_mode = ip->i_d.di_mode; + IHOLD(ip); xfs_itrace_entry(ip); xfs_itrace_ref(ip); @@ -2459,7 +2442,7 @@ xfs_remove( (void) XFS_SEND_NAMESP(mp, DM_EVENT_POSTREMOVE, dir_vp, DM_RIGHT_NULL, NULL, DM_RIGHT_NULL, - name, NULL, dm_di_mode, error, 0); + name, NULL, ip->i_d.di_mode, error, 0); } return error; @@ -2868,14 +2851,13 @@ xfs_rmdir( char *name = VNAME(dentry); int namelen = VNAMELEN(dentry); xfs_mount_t *mp = dp->i_mount; - xfs_inode_t *cdp; /* child directory */ + xfs_inode_t *cdp = VNAME_TO_INODE(dentry); xfs_trans_t *tp; int error; xfs_bmap_free_t free_list; xfs_fsblock_t first_block; int cancel_flags; int committed; - int dm_di_mode = S_IFDIR; int last_cdp_link; uint resblks; @@ -2884,24 +2866,15 @@ xfs_rmdir( if (XFS_FORCED_SHUTDOWN(mp)) return XFS_ERROR(EIO); - if (!xfs_get_dir_entry(dentry, &cdp)) { - dm_di_mode = cdp->i_d.di_mode; - IRELE(cdp); - } - 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); + name, NULL, cdp->i_d.di_mode, 0, 0); if (error) return XFS_ERROR(error); } - /* Return through std_return after this point. */ - - cdp = NULL; - /* * We need to get a reference to cdp before we get our log * reservation. The reason for this is that we cannot call @@ -2914,13 +2887,7 @@ xfs_rmdir( * when we call xfs_iget. Instead we get an unlocked reference * to the inode before getting our log reservation. */ - error = xfs_get_dir_entry(dentry, &cdp); - if (error) { - REMOVE_DEBUG_TRACE(__LINE__); - goto std_return; - } - mp = dp->i_mount; - dm_di_mode = cdp->i_d.di_mode; + IHOLD(cdp); /* * Get the dquots for the inodes. @@ -3077,7 +3044,7 @@ xfs_rmdir( (void) XFS_SEND_NAMESP(mp, DM_EVENT_POSTREMOVE, dir_vp, DM_RIGHT_NULL, NULL, DM_RIGHT_NULL, - name, NULL, dm_di_mode, + name, NULL, cdp->i_d.di_mode, error, 0); } return error; -- cgit v1.2.3 From 126468b1156211e26d97f74b2f1767acd141005a Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Thu, 6 Mar 2008 13:44:57 +1100 Subject: [XFS] kill xfs_rwlock/xfs_rwunlock We can just use xfs_ilock/xfs_iunlock instead and get rid of the ugly bhv_vrwlock_t. SGI-PV: 976035 SGI-Modid: xfs-linux-melb:xfs-kern:30533a Signed-off-by: Christoph Hellwig Signed-off-by: Lachlan McIlroy --- fs/xfs/xfs_vnodeops.c | 41 ----------------------------------------- 1 file changed, 41 deletions(-) (limited to 'fs/xfs/xfs_vnodeops.c') diff --git a/fs/xfs/xfs_vnodeops.c b/fs/xfs/xfs_vnodeops.c index 4765e7c4b75..811ee874d86 100644 --- a/fs/xfs/xfs_vnodeops.c +++ b/fs/xfs/xfs_vnodeops.c @@ -3374,47 +3374,6 @@ std_return: goto std_return; } -int -xfs_rwlock( - xfs_inode_t *ip, - bhv_vrwlock_t locktype) -{ - if (S_ISDIR(ip->i_d.di_mode)) - return 1; - if (locktype == VRWLOCK_WRITE) { - xfs_ilock(ip, XFS_IOLOCK_EXCL); - } else if (locktype == VRWLOCK_TRY_READ) { - return xfs_ilock_nowait(ip, XFS_IOLOCK_SHARED); - } else if (locktype == VRWLOCK_TRY_WRITE) { - return xfs_ilock_nowait(ip, XFS_IOLOCK_EXCL); - } else { - ASSERT((locktype == VRWLOCK_READ) || - (locktype == VRWLOCK_WRITE_DIRECT)); - xfs_ilock(ip, XFS_IOLOCK_SHARED); - } - - return 1; -} - - -void -xfs_rwunlock( - xfs_inode_t *ip, - bhv_vrwlock_t locktype) -{ - if (S_ISDIR(ip->i_d.di_mode)) - return; - if (locktype == VRWLOCK_WRITE) { - xfs_iunlock(ip, XFS_IOLOCK_EXCL); - } else { - ASSERT((locktype == VRWLOCK_READ) || - (locktype == VRWLOCK_WRITE_DIRECT)); - xfs_iunlock(ip, XFS_IOLOCK_SHARED); - } - return; -} - - int xfs_inode_flush( xfs_inode_t *ip, -- cgit v1.2.3 From 44d814ced4cffbfe6a775c5bb8b941a6e734e7d9 Mon Sep 17 00:00:00 2001 From: David Chinner Date: Thu, 6 Mar 2008 13:45:29 +1100 Subject: [XFS] Update c/mtime correctly on truncates XFS changes the c/mtime of an inode when truncating it to the same size. The c/mtime is only supposed to change if the size is changed. Not to be confused with ftruncate, where the c/mtime is supposed to be changed even if the size is not changed. The Linux VFS encodes this semantic difference in the flags it sends down to ->setattr, which XFS currently ignores. We need to make XFS pay attention to the VFS flags and hence Do The Right Thing. SGI-PV: 977547 SGI-Modid: xfs-linux-melb:xfs-kern:30536a Signed-off-by: David Chinner Signed-off-by: Christoph Hellwig Signed-off-by: Lachlan McIlroy --- fs/xfs/xfs_vnodeops.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) (limited to 'fs/xfs/xfs_vnodeops.c') diff --git a/fs/xfs/xfs_vnodeops.c b/fs/xfs/xfs_vnodeops.c index 811ee874d86..b77dede91b7 100644 --- a/fs/xfs/xfs_vnodeops.c +++ b/fs/xfs/xfs_vnodeops.c @@ -633,6 +633,15 @@ xfs_setattr( * Truncate file. Must have write permission and not be a directory. */ if (mask & XFS_AT_SIZE) { + /* + * Only change the c/mtime if we are changing the size + * or we are explicitly asked to change it. This handles + * the semantic difference between truncate() and ftruncate() + * as implemented in the VFS. + */ + if (vap->va_size != ip->i_size || (mask & XFS_AT_CTIME)) + timeflags |= XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG; + if (vap->va_size > ip->i_size) { xfs_igrow_finish(tp, ip, vap->va_size, !(flags & ATTR_DMI)); @@ -661,10 +670,6 @@ xfs_setattr( */ xfs_iflags_set(ip, XFS_ITRUNCATED); } - /* - * Have to do this even if the file's size doesn't change. - */ - timeflags |= XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG; } /* -- cgit v1.2.3 From bc4ac74a4e5bd7db02976eb1b681e1d11f81c9ce Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Thu, 6 Mar 2008 13:45:58 +1100 Subject: [XFS] cleanup vnode use in dmapi calls SGI-PV: 976035 SGI-Modid: xfs-linux-melb:xfs-kern:30545a Signed-off-by: Christoph Hellwig Signed-off-by: Lachlan McIlroy --- fs/xfs/xfs_vnodeops.c | 55 ++++++++++++++++++++++++--------------------------- 1 file changed, 26 insertions(+), 29 deletions(-) (limited to 'fs/xfs/xfs_vnodeops.c') diff --git a/fs/xfs/xfs_vnodeops.c b/fs/xfs/xfs_vnodeops.c index b77dede91b7..7e124b55c26 100644 --- a/fs/xfs/xfs_vnodeops.c +++ b/fs/xfs/xfs_vnodeops.c @@ -326,7 +326,7 @@ xfs_setattr( 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, + code = XFS_SEND_DATA(mp, DM_EVENT_TRUNCATE, ip, vap->va_size, 0, dmflags, NULL); if (code) { lock_flags = 0; @@ -881,7 +881,7 @@ xfs_setattr( if (DM_EVENT_ENABLED(ip, DM_EVENT_ATTRIBUTE) && !(flags & ATTR_DMI)) { - (void) XFS_SEND_NAMESP(mp, DM_EVENT_ATTRIBUTE, vp, DM_RIGHT_NULL, + (void) XFS_SEND_NAMESP(mp, DM_EVENT_ATTRIBUTE, ip, DM_RIGHT_NULL, NULL, DM_RIGHT_NULL, NULL, NULL, 0, 0, AT_DELAY_FLAG(flags)); } @@ -1586,9 +1586,8 @@ xfs_inactive( mp = ip->i_mount; - if (ip->i_d.di_nlink == 0 && DM_EVENT_ENABLED(ip, DM_EVENT_DESTROY)) { - (void) XFS_SEND_DESTROY(mp, vp, DM_RIGHT_NULL); - } + if (ip->i_d.di_nlink == 0 && DM_EVENT_ENABLED(ip, DM_EVENT_DESTROY)) + XFS_SEND_DESTROY(mp, ip, DM_RIGHT_NULL); error = 0; @@ -1820,7 +1819,7 @@ xfs_create( if (DM_EVENT_ENABLED(dp, DM_EVENT_CREATE)) { error = XFS_SEND_NAMESP(mp, DM_EVENT_CREATE, - dir_vp, DM_RIGHT_NULL, NULL, + dp, DM_RIGHT_NULL, NULL, DM_RIGHT_NULL, name, NULL, mode, 0, 0); @@ -1976,8 +1975,8 @@ std_return: 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, + dp, DM_RIGHT_NULL, + *vpp ? ip : NULL, DM_RIGHT_NULL, name, NULL, mode, error, 0); } @@ -2272,7 +2271,6 @@ xfs_remove( xfs_inode_t *dp, bhv_vname_t *dentry) { - bhv_vnode_t *dir_vp = XFS_ITOV(dp); char *name = VNAME(dentry); xfs_mount_t *mp = dp->i_mount; xfs_inode_t *ip = VNAME_TO_INODE(dentry); @@ -2292,7 +2290,7 @@ xfs_remove( return XFS_ERROR(EIO); if (DM_EVENT_ENABLED(dp, DM_EVENT_REMOVE)) { - error = XFS_SEND_NAMESP(mp, DM_EVENT_REMOVE, dir_vp, + error = XFS_SEND_NAMESP(mp, DM_EVENT_REMOVE, dp, DM_RIGHT_NULL, NULL, DM_RIGHT_NULL, name, NULL, ip->i_d.di_mode, 0, 0); if (error) @@ -2445,7 +2443,7 @@ xfs_remove( std_return: if (DM_EVENT_ENABLED(dp, DM_EVENT_POSTREMOVE)) { (void) XFS_SEND_NAMESP(mp, DM_EVENT_POSTREMOVE, - dir_vp, DM_RIGHT_NULL, + dp, DM_RIGHT_NULL, NULL, DM_RIGHT_NULL, name, NULL, ip->i_d.di_mode, error, 0); } @@ -2504,8 +2502,8 @@ xfs_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, + tdp, DM_RIGHT_NULL, + sip, DM_RIGHT_NULL, target_name, NULL, 0, 0, 0); if (error) return error; @@ -2615,8 +2613,8 @@ xfs_link( std_return: 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, + tdp, DM_RIGHT_NULL, + sip, DM_RIGHT_NULL, target_name, NULL, 0, error, 0); } return error; @@ -2665,7 +2663,7 @@ xfs_mkdir( if (DM_EVENT_ENABLED(dp, DM_EVENT_CREATE)) { error = XFS_SEND_NAMESP(mp, DM_EVENT_CREATE, - dir_vp, DM_RIGHT_NULL, NULL, + dp, DM_RIGHT_NULL, NULL, DM_RIGHT_NULL, dir_name, NULL, mode, 0, 0); if (error) @@ -2823,8 +2821,8 @@ std_return: 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, + dp, DM_RIGHT_NULL, + created ? cdp : NULL, DM_RIGHT_NULL, dir_name, NULL, mode, error, 0); @@ -2873,7 +2871,7 @@ xfs_rmdir( if (DM_EVENT_ENABLED(dp, DM_EVENT_REMOVE)) { error = XFS_SEND_NAMESP(mp, DM_EVENT_REMOVE, - dir_vp, DM_RIGHT_NULL, + dp, DM_RIGHT_NULL, NULL, DM_RIGHT_NULL, name, NULL, cdp->i_d.di_mode, 0, 0); if (error) @@ -3047,7 +3045,7 @@ xfs_rmdir( std_return: if (DM_EVENT_ENABLED(dp, DM_EVENT_POSTREMOVE)) { (void) XFS_SEND_NAMESP(mp, DM_EVENT_POSTREMOVE, - dir_vp, DM_RIGHT_NULL, + dp, DM_RIGHT_NULL, NULL, DM_RIGHT_NULL, name, NULL, cdp->i_d.di_mode, error, 0); @@ -3144,7 +3142,7 @@ xfs_symlink( } if (DM_EVENT_ENABLED(dp, DM_EVENT_SYMLINK)) { - error = XFS_SEND_NAMESP(mp, DM_EVENT_SYMLINK, dir_vp, + error = XFS_SEND_NAMESP(mp, DM_EVENT_SYMLINK, dp, DM_RIGHT_NULL, NULL, DM_RIGHT_NULL, link_name, target_path, 0, 0, 0); if (error) @@ -3348,8 +3346,8 @@ xfs_symlink( std_return: 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), + dp, DM_RIGHT_NULL, + error ? NULL : ip, DM_RIGHT_NULL, link_name, target_path, 0, error, 0); } @@ -3707,9 +3705,8 @@ xfs_alloc_file_space( end_dmi_offset = offset+len; if (end_dmi_offset > ip->i_size) end_dmi_offset = ip->i_size; - error = XFS_SEND_DATA(mp, DM_EVENT_WRITE, XFS_ITOV(ip), - offset, end_dmi_offset - offset, - 0, NULL); + error = XFS_SEND_DATA(mp, DM_EVENT_WRITE, ip, offset, + end_dmi_offset - offset, 0, NULL); if (error) return error; } @@ -3818,8 +3815,8 @@ dmapi_enospc_check: 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, + ip, DM_RIGHT_NULL, + ip, DM_RIGHT_NULL, NULL, NULL, 0, 0, 0); /* Delay flag intentionally unused */ if (error == 0) goto retry; /* Maybe DMAPI app. has made space */ @@ -3964,7 +3961,7 @@ xfs_free_file_space( 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, + error = XFS_SEND_DATA(mp, DM_EVENT_WRITE, ip, offset, end_dmi_offset - offset, AT_DELAY_FLAG(attr_flags), NULL); if (error) -- cgit v1.2.3 From 979ebab11623894528d4d37b947533ea4e8649d1 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Thu, 6 Mar 2008 13:46:05 +1100 Subject: [XFS] cleanup vnode use in xfs_create/mknod/mkdir SGI-PV: 976035 SGI-Modid: xfs-linux-melb:xfs-kern:30546a Signed-off-by: Christoph Hellwig Signed-off-by: Lachlan McIlroy --- fs/xfs/xfs_vnodeops.c | 25 +++++++++---------------- 1 file changed, 9 insertions(+), 16 deletions(-) (limited to 'fs/xfs/xfs_vnodeops.c') diff --git a/fs/xfs/xfs_vnodeops.c b/fs/xfs/xfs_vnodeops.c index 7e124b55c26..a42d7fe6a5e 100644 --- a/fs/xfs/xfs_vnodeops.c +++ b/fs/xfs/xfs_vnodeops.c @@ -1791,14 +1791,12 @@ xfs_create( bhv_vname_t *dentry, mode_t mode, xfs_dev_t rdev, - bhv_vnode_t **vpp, + xfs_inode_t **ipp, cred_t *credp) { char *name = VNAME(dentry); 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; int error; xfs_bmap_free_t free_list; @@ -1812,7 +1810,7 @@ xfs_create( uint resblks; int namelen; - ASSERT(!*vpp); + ASSERT(!*ipp); xfs_itrace_entry(dp); namelen = VNAMELEN(dentry); @@ -1911,7 +1909,7 @@ xfs_create( * the transaction cancel unlocking dp so don't do it explicitly in the * error path. */ - VN_HOLD(dir_vp); + IHOLD(dp); xfs_trans_ijoin(tp, dp, XFS_ILOCK_EXCL); unlock_dp_on_error = B_FALSE; @@ -1949,7 +1947,6 @@ xfs_create( * vnode to the caller, we bump the vnode ref count now. */ IHOLD(ip); - vp = XFS_ITOV(ip); error = xfs_bmap_finish(&tp, &free_list, &committed); if (error) { @@ -1967,16 +1964,16 @@ xfs_create( XFS_QM_DQRELE(mp, udqp); XFS_QM_DQRELE(mp, gdqp); - *vpp = vp; + *ipp = ip; /* Fallthrough to std_return with error = 0 */ std_return: - if ((*vpp || (error != 0 && dm_event_sent != 0)) && + if ((*ipp || (error != 0 && dm_event_sent != 0)) && DM_EVENT_ENABLED(dp, DM_EVENT_POSTCREATE)) { (void) XFS_SEND_NAMESP(mp, DM_EVENT_POSTCREATE, dp, DM_RIGHT_NULL, - *vpp ? ip : NULL, + *ipp ? ip : NULL, DM_RIGHT_NULL, name, NULL, mode, error, 0); } @@ -2634,15 +2631,13 @@ xfs_mkdir( xfs_inode_t *dp, bhv_vname_t *dentry, mode_t mode, - bhv_vnode_t **vpp, + xfs_inode_t **ipp, cred_t *credp) { - bhv_vnode_t *dir_vp = XFS_ITOV(dp); char *dir_name = VNAME(dentry); 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; int cancel_flags; int error; @@ -2749,7 +2744,7 @@ xfs_mkdir( * 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); + IHOLD(dp); xfs_trans_ijoin(tp, dp, XFS_ILOCK_EXCL); unlock_dp_on_error = B_FALSE; @@ -2780,11 +2775,9 @@ xfs_mkdir( if (error) goto error2; - cvp = XFS_ITOV(cdp); - created = B_TRUE; - *vpp = cvp; + *ipp = cdp; IHOLD(cdp); /* -- cgit v1.2.3 From a3da789640871c897901c5f766e33be78d56f35a Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Thu, 6 Mar 2008 13:46:12 +1100 Subject: [XFS] cleanup vnode use in xfs_link SGI-PV: 976035 SGI-Modid: xfs-linux-melb:xfs-kern:30547a Signed-off-by: Christoph Hellwig Signed-off-by: Lachlan McIlroy --- fs/xfs/xfs_vnodeops.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) (limited to 'fs/xfs/xfs_vnodeops.c') diff --git a/fs/xfs/xfs_vnodeops.c b/fs/xfs/xfs_vnodeops.c index a42d7fe6a5e..10d2d22eb03 100644 --- a/fs/xfs/xfs_vnodeops.c +++ b/fs/xfs/xfs_vnodeops.c @@ -2471,12 +2471,10 @@ xfs_remove( int xfs_link( xfs_inode_t *tdp, - bhv_vnode_t *src_vp, + xfs_inode_t *sip, bhv_vname_t *dentry) { - 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_inode_t *ips[2]; int error; @@ -2489,10 +2487,10 @@ xfs_link( int target_namelen; xfs_itrace_entry(tdp); - xfs_itrace_entry(xfs_vtoi(src_vp)); + xfs_itrace_entry(sip); target_namelen = VNAMELEN(dentry); - ASSERT(!VN_ISDIR(src_vp)); + ASSERT(!S_ISDIR(sip->i_d.di_mode)); if (XFS_FORCED_SHUTDOWN(mp)) return XFS_ERROR(EIO); @@ -2544,8 +2542,8 @@ xfs_link( * xfs_trans_cancel will both unlock the inodes and * decrement the associated ref counts. */ - VN_HOLD(src_vp); - VN_HOLD(target_dir_vp); + IHOLD(sip); + IHOLD(tdp); xfs_trans_ijoin(tp, sip, XFS_ILOCK_EXCL); xfs_trans_ijoin(tp, tdp, XFS_ILOCK_EXCL); -- cgit v1.2.3 From 3937be5ba836a204d3d1df96b518eecd6cdacbb9 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Thu, 6 Mar 2008 13:46:19 +1100 Subject: [XFS] cleanup vnode use in xfs_symlink and xfs_rename SGI-PV: 976035 SGI-Modid: xfs-linux-melb:xfs-kern:30548a Signed-off-by: Christoph Hellwig Signed-off-by: Lachlan McIlroy --- fs/xfs/xfs_vnodeops.c | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) (limited to 'fs/xfs/xfs_vnodeops.c') diff --git a/fs/xfs/xfs_vnodeops.c b/fs/xfs/xfs_vnodeops.c index 10d2d22eb03..fa694dc5d30 100644 --- a/fs/xfs/xfs_vnodeops.c +++ b/fs/xfs/xfs_vnodeops.c @@ -3059,10 +3059,9 @@ xfs_symlink( bhv_vname_t *dentry, char *target_path, mode_t mode, - bhv_vnode_t **vpp, + xfs_inode_t **ipp, cred_t *credp) { - bhv_vnode_t *dir_vp = XFS_ITOV(dp); xfs_mount_t *mp = dp->i_mount; xfs_trans_t *tp; xfs_inode_t *ip; @@ -3088,7 +3087,7 @@ xfs_symlink( char *link_name = VNAME(dentry); int link_namelen; - *vpp = NULL; + *ipp = NULL; error = 0; ip = NULL; tp = NULL; @@ -3227,7 +3226,7 @@ xfs_symlink( * transaction cancel unlocking dp so don't do it explicitly in the * error path. */ - VN_HOLD(dir_vp); + IHOLD(dp); xfs_trans_ijoin(tp, dp, XFS_ILOCK_EXCL); unlock_dp_on_error = B_FALSE; @@ -3343,13 +3342,8 @@ std_return: 0, error, 0); } - if (!error) { - bhv_vnode_t *vp; - - ASSERT(ip); - vp = XFS_ITOV(ip); - *vpp = vp; - } + if (!error) + *ipp = ip; return error; error2: -- cgit v1.2.3 From ef1f5e7ad38e5414d016983a8cc5a8db7654a61d Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Thu, 6 Mar 2008 13:46:25 +1100 Subject: [XFS] cleanup vnode use in xfs_lookup SGI-PV: 976035 SGI-Modid: xfs-linux-melb:xfs-kern:30550a Signed-off-by: Christoph Hellwig Signed-off-by: Lachlan McIlroy --- fs/xfs/xfs_vnodeops.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'fs/xfs/xfs_vnodeops.c') diff --git a/fs/xfs/xfs_vnodeops.c b/fs/xfs/xfs_vnodeops.c index fa694dc5d30..3418c94bcf1 100644 --- a/fs/xfs/xfs_vnodeops.c +++ b/fs/xfs/xfs_vnodeops.c @@ -1763,7 +1763,7 @@ int xfs_lookup( xfs_inode_t *dp, bhv_vname_t *dentry, - bhv_vnode_t **vpp) + xfs_inode_t **ipp) { xfs_inode_t *ip; xfs_ino_t e_inum; @@ -1778,7 +1778,7 @@ xfs_lookup( lock_mode = xfs_ilock_map_shared(dp); error = xfs_dir_lookup_int(dp, lock_mode, dentry, &e_inum, &ip); if (!error) { - *vpp = XFS_ITOV(ip); + *ipp = ip; xfs_itrace_ref(ip); } xfs_iunlock_map_shared(dp, lock_mode); -- cgit v1.2.3 From b6ddc4e6fed9c6f4adb273c8b36e1731f90ec17e Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Thu, 10 Apr 2008 12:19:27 +1000 Subject: [XFS] Don't validate symlink target component length This target component validation is not POSIX conformant and it is not done by any other Linux filesystem so remove it from XFS. SGI-PV: 980080 SGI-Modid: xfs-linux-melb:xfs-kern:30776a Signed-off-by: Christoph Hellwig Signed-off-by: David Chinner Signed-off-by: Lachlan McIlroy --- fs/xfs/xfs_vnodeops.c | 25 ------------------------- 1 file changed, 25 deletions(-) (limited to 'fs/xfs/xfs_vnodeops.c') diff --git a/fs/xfs/xfs_vnodeops.c b/fs/xfs/xfs_vnodeops.c index 3418c94bcf1..d46f24c6849 100644 --- a/fs/xfs/xfs_vnodeops.c +++ b/fs/xfs/xfs_vnodeops.c @@ -3105,31 +3105,6 @@ xfs_symlink( pathlen = strlen(target_path); if (pathlen >= MAXPATHLEN) /* total string too long */ return XFS_ERROR(ENAMETOOLONG); - if (pathlen >= MAXNAMELEN) { /* is any component too long? */ - int len, total; - char *path; - - for (total = 0, path = target_path; total < pathlen;) { - /* - * Skip any slashes. - */ - while(*path == '/') { - total++; - path++; - } - - /* - * Count up to the next slash or end of path. - * Error out if the component is bigger than MAXNAMELEN. - */ - for(len = 0; *path != '/' && total < pathlen;total++, path++) { - if (++len >= MAXNAMELEN) { - error = ENAMETOOLONG; - return error; - } - } - } - } if (DM_EVENT_ENABLED(dp, DM_EVENT_SYMLINK)) { error = XFS_SEND_NAMESP(mp, DM_EVENT_SYMLINK, dp, -- cgit v1.2.3 From e5720eec0548c08943d759e39db0388d8fe59287 Mon Sep 17 00:00:00 2001 From: David Chinner Date: Thu, 10 Apr 2008 12:21:18 +1000 Subject: [XFS] Propagate errors from xfs_trans_commit(). xfs_trans_commit() can return errors when there are problems in the transaction subsystem. They are indicative that the entire transaction may be incomplete, and hence the error should be propagated as there is a good possibility that there is something fatally wrong in the filesystem. Catch and propagate or warn about commit errors in the places where they are currently ignored. SGI-PV: 980084 SGI-Modid: xfs-linux-melb:xfs-kern:30795a Signed-off-by: David Chinner Signed-off-by: Niv Sardi Signed-off-by: Lachlan McIlroy --- fs/xfs/xfs_vnodeops.c | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) (limited to 'fs/xfs/xfs_vnodeops.c') diff --git a/fs/xfs/xfs_vnodeops.c b/fs/xfs/xfs_vnodeops.c index d46f24c6849..bc0a4707189 100644 --- a/fs/xfs/xfs_vnodeops.c +++ b/fs/xfs/xfs_vnodeops.c @@ -1447,28 +1447,22 @@ xfs_inactive_attrs( tp = *tpp; mp = ip->i_mount; ASSERT(ip->i_d.di_forkoff != 0); - xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES); + error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES); xfs_iunlock(ip, XFS_ILOCK_EXCL); + if (error) + goto error_unlock; error = xfs_attr_inactive(ip); - if (error) { - *tpp = NULL; - xfs_iunlock(ip, XFS_IOLOCK_EXCL); - return error; /* goto out */ - } + if (error) + goto error_unlock; tp = xfs_trans_alloc(mp, XFS_TRANS_INACTIVE); error = xfs_trans_reserve(tp, 0, XFS_IFREE_LOG_RES(mp), 0, XFS_TRANS_PERM_LOG_RES, XFS_INACTIVE_LOG_COUNT); - if (error) { - ASSERT(XFS_FORCED_SHUTDOWN(mp)); - xfs_trans_cancel(tp, 0); - *tpp = NULL; - xfs_iunlock(ip, XFS_IOLOCK_EXCL); - return error; - } + if (error) + goto error_cancel; xfs_ilock(ip, XFS_ILOCK_EXCL); xfs_trans_ijoin(tp, ip, XFS_IOLOCK_EXCL | XFS_ILOCK_EXCL); @@ -1479,6 +1473,14 @@ xfs_inactive_attrs( *tpp = tp; return 0; + +error_cancel: + ASSERT(XFS_FORCED_SHUTDOWN(mp)); + xfs_trans_cancel(tp, 0); +error_unlock: + *tpp = NULL; + xfs_iunlock(ip, XFS_IOLOCK_EXCL); + return error; } int -- cgit v1.2.3 From 556b8b166c9514b5f940047a41dad8fe8cd9a778 Mon Sep 17 00:00:00 2001 From: Barry Naujok Date: Thu, 10 Apr 2008 12:22:07 +1000 Subject: [XFS] remove bhv_vname_t and xfs_rename code SGI-PV: 976035 SGI-Modid: xfs-linux-melb:xfs-kern:30804a Signed-off-by: Barry Naujok Signed-off-by: Christoph Hellwig Signed-off-by: Lachlan McIlroy --- fs/xfs/xfs_vnodeops.c | 121 ++++++++++++++++++++++---------------------------- 1 file changed, 52 insertions(+), 69 deletions(-) (limited to 'fs/xfs/xfs_vnodeops.c') diff --git a/fs/xfs/xfs_vnodeops.c b/fs/xfs/xfs_vnodeops.c index bc0a4707189..ca38fb9a993 100644 --- a/fs/xfs/xfs_vnodeops.c +++ b/fs/xfs/xfs_vnodeops.c @@ -1764,7 +1764,7 @@ xfs_inactive( int xfs_lookup( xfs_inode_t *dp, - bhv_vname_t *dentry, + struct xfs_name *name, xfs_inode_t **ipp) { xfs_inode_t *ip; @@ -1778,7 +1778,7 @@ xfs_lookup( return XFS_ERROR(EIO); lock_mode = xfs_ilock_map_shared(dp); - error = xfs_dir_lookup_int(dp, lock_mode, dentry, &e_inum, &ip); + error = xfs_dir_lookup_int(dp, lock_mode, name, &e_inum, &ip); if (!error) { *ipp = ip; xfs_itrace_ref(ip); @@ -1790,17 +1790,16 @@ xfs_lookup( int xfs_create( xfs_inode_t *dp, - bhv_vname_t *dentry, + struct xfs_name *name, mode_t mode, xfs_dev_t rdev, xfs_inode_t **ipp, cred_t *credp) { - char *name = VNAME(dentry); - xfs_mount_t *mp = dp->i_mount; + xfs_mount_t *mp = dp->i_mount; xfs_inode_t *ip; xfs_trans_t *tp; - int error; + int error; xfs_bmap_free_t free_list; xfs_fsblock_t first_block; boolean_t unlock_dp_on_error = B_FALSE; @@ -1810,17 +1809,14 @@ xfs_create( xfs_prid_t prid; struct xfs_dquot *udqp, *gdqp; uint resblks; - int namelen; ASSERT(!*ipp); xfs_itrace_entry(dp); - namelen = VNAMELEN(dentry); - if (DM_EVENT_ENABLED(dp, DM_EVENT_CREATE)) { error = XFS_SEND_NAMESP(mp, DM_EVENT_CREATE, dp, DM_RIGHT_NULL, NULL, - DM_RIGHT_NULL, name, NULL, + DM_RIGHT_NULL, name->name, NULL, mode, 0, 0); if (error) @@ -1852,7 +1848,7 @@ xfs_create( tp = xfs_trans_alloc(mp, XFS_TRANS_CREATE); cancel_flags = XFS_TRANS_RELEASE_LOG_RES; - resblks = XFS_CREATE_SPACE_RES(mp, namelen); + resblks = XFS_CREATE_SPACE_RES(mp, name->len); /* * Initially assume that the file does not exist and * reserve the resources for that case. If that is not @@ -1885,7 +1881,8 @@ xfs_create( if (error) goto error_return; - if (resblks == 0 && (error = xfs_dir_canenter(tp, dp, name, namelen))) + error = xfs_dir_canenter(tp, dp, name, resblks); + if (error) goto error_return; error = xfs_dir_ialloc(&tp, dp, mode, 1, rdev, credp, prid, resblks > 0, @@ -1915,7 +1912,7 @@ xfs_create( xfs_trans_ijoin(tp, dp, XFS_ILOCK_EXCL); unlock_dp_on_error = B_FALSE; - error = xfs_dir_createname(tp, dp, name, namelen, ip->i_ino, + error = xfs_dir_createname(tp, dp, name, ip->i_ino, &first_block, &free_list, resblks ? resblks - XFS_IALLOC_SPACE_RES(mp) : 0); if (error) { @@ -1976,7 +1973,7 @@ std_return: (void) XFS_SEND_NAMESP(mp, DM_EVENT_POSTCREATE, dp, DM_RIGHT_NULL, *ipp ? ip : NULL, - DM_RIGHT_NULL, name, NULL, + DM_RIGHT_NULL, name->name, NULL, mode, error, 0); } return error; @@ -2268,12 +2265,10 @@ int remove_which_error_return = 0; int xfs_remove( xfs_inode_t *dp, - bhv_vname_t *dentry) + struct xfs_name *name, + xfs_inode_t *ip) { - char *name = VNAME(dentry); xfs_mount_t *mp = dp->i_mount; - xfs_inode_t *ip = VNAME_TO_INODE(dentry); - int namelen = VNAMELEN(dentry); xfs_trans_t *tp = NULL; int error = 0; xfs_bmap_free_t free_list; @@ -2289,9 +2284,9 @@ xfs_remove( return XFS_ERROR(EIO); if (DM_EVENT_ENABLED(dp, DM_EVENT_REMOVE)) { - error = XFS_SEND_NAMESP(mp, DM_EVENT_REMOVE, dp, - DM_RIGHT_NULL, NULL, DM_RIGHT_NULL, - name, NULL, ip->i_d.di_mode, 0, 0); + error = XFS_SEND_NAMESP(mp, DM_EVENT_REMOVE, dp, DM_RIGHT_NULL, + NULL, DM_RIGHT_NULL, name->name, NULL, + ip->i_d.di_mode, 0, 0); if (error) return error; } @@ -2376,7 +2371,7 @@ xfs_remove( * Entry must exist since we did a lookup in xfs_lock_dir_and_entry. */ XFS_BMAP_INIT(&free_list, &first_block); - error = xfs_dir_removename(tp, dp, name, namelen, ip->i_ino, + error = xfs_dir_removename(tp, dp, name, ip->i_ino, &first_block, &free_list, 0); if (error) { ASSERT(error != ENOENT); @@ -2444,7 +2439,7 @@ xfs_remove( (void) XFS_SEND_NAMESP(mp, DM_EVENT_POSTREMOVE, dp, DM_RIGHT_NULL, NULL, DM_RIGHT_NULL, - name, NULL, ip->i_d.di_mode, error, 0); + name->name, NULL, ip->i_d.di_mode, error, 0); } return error; @@ -2474,7 +2469,7 @@ int xfs_link( xfs_inode_t *tdp, xfs_inode_t *sip, - bhv_vname_t *dentry) + struct xfs_name *target_name) { xfs_mount_t *mp = tdp->i_mount; xfs_trans_t *tp; @@ -2485,13 +2480,10 @@ xfs_link( int cancel_flags; int committed; int resblks; - char *target_name = VNAME(dentry); - int target_namelen; xfs_itrace_entry(tdp); xfs_itrace_entry(sip); - target_namelen = VNAMELEN(dentry); ASSERT(!S_ISDIR(sip->i_d.di_mode)); if (XFS_FORCED_SHUTDOWN(mp)) @@ -2501,7 +2493,7 @@ xfs_link( error = XFS_SEND_NAMESP(mp, DM_EVENT_LINK, tdp, DM_RIGHT_NULL, sip, DM_RIGHT_NULL, - target_name, NULL, 0, 0, 0); + target_name->name, NULL, 0, 0, 0); if (error) return error; } @@ -2516,7 +2508,7 @@ xfs_link( tp = xfs_trans_alloc(mp, XFS_TRANS_LINK); cancel_flags = XFS_TRANS_RELEASE_LOG_RES; - resblks = XFS_LINK_SPACE_RES(mp, target_namelen); + resblks = XFS_LINK_SPACE_RES(mp, target_name->len); error = xfs_trans_reserve(tp, resblks, XFS_LINK_LOG_RES(mp), 0, XFS_TRANS_PERM_LOG_RES, XFS_LINK_LOG_COUNT); if (error == ENOSPC) { @@ -2568,15 +2560,14 @@ xfs_link( goto error_return; } - if (resblks == 0 && - (error = xfs_dir_canenter(tp, tdp, target_name, target_namelen))) + error = xfs_dir_canenter(tp, tdp, target_name, resblks); + if (error) goto error_return; XFS_BMAP_INIT(&free_list, &first_block); - error = xfs_dir_createname(tp, tdp, target_name, target_namelen, - sip->i_ino, &first_block, &free_list, - resblks); + error = xfs_dir_createname(tp, tdp, target_name, sip->i_ino, + &first_block, &free_list, resblks); if (error) goto abort_return; xfs_ichgtime(tdp, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG); @@ -2612,7 +2603,7 @@ std_return: (void) XFS_SEND_NAMESP(mp, DM_EVENT_POSTLINK, tdp, DM_RIGHT_NULL, sip, DM_RIGHT_NULL, - target_name, NULL, 0, error, 0); + target_name->name, NULL, 0, error, 0); } return error; @@ -2629,13 +2620,11 @@ std_return: int xfs_mkdir( xfs_inode_t *dp, - bhv_vname_t *dentry, + struct xfs_name *dir_name, mode_t mode, xfs_inode_t **ipp, cred_t *credp) { - char *dir_name = VNAME(dentry); - int dir_namelen = VNAMELEN(dentry); xfs_mount_t *mp = dp->i_mount; xfs_inode_t *cdp; /* inode of created dir */ xfs_trans_t *tp; @@ -2659,7 +2648,7 @@ xfs_mkdir( if (DM_EVENT_ENABLED(dp, DM_EVENT_CREATE)) { error = XFS_SEND_NAMESP(mp, DM_EVENT_CREATE, dp, DM_RIGHT_NULL, NULL, - DM_RIGHT_NULL, dir_name, NULL, + DM_RIGHT_NULL, dir_name->name, NULL, mode, 0, 0); if (error) return error; @@ -2688,7 +2677,7 @@ xfs_mkdir( tp = xfs_trans_alloc(mp, XFS_TRANS_MKDIR); cancel_flags = XFS_TRANS_RELEASE_LOG_RES; - resblks = XFS_MKDIR_SPACE_RES(mp, dir_namelen); + resblks = XFS_MKDIR_SPACE_RES(mp, dir_name->len); error = xfs_trans_reserve(tp, resblks, XFS_MKDIR_LOG_RES(mp), 0, XFS_TRANS_PERM_LOG_RES, XFS_MKDIR_LOG_COUNT); if (error == ENOSPC) { @@ -2720,8 +2709,8 @@ xfs_mkdir( if (error) goto error_return; - if (resblks == 0 && - (error = xfs_dir_canenter(tp, dp, dir_name, dir_namelen))) + error = xfs_dir_canenter(tp, dp, dir_name, resblks); + if (error) goto error_return; /* * create the directory inode. @@ -2750,9 +2739,9 @@ xfs_mkdir( XFS_BMAP_INIT(&free_list, &first_block); - error = xfs_dir_createname(tp, dp, dir_name, dir_namelen, cdp->i_ino, - &first_block, &free_list, resblks ? - resblks - XFS_IALLOC_SPACE_RES(mp) : 0); + error = xfs_dir_createname(tp, dp, dir_name, cdp->i_ino, + &first_block, &free_list, resblks ? + resblks - XFS_IALLOC_SPACE_RES(mp) : 0); if (error) { ASSERT(error != ENOSPC); goto error1; @@ -2817,7 +2806,7 @@ std_return: dp, DM_RIGHT_NULL, created ? cdp : NULL, DM_RIGHT_NULL, - dir_name, NULL, + dir_name->name, NULL, mode, error, 0); } return error; @@ -2841,13 +2830,11 @@ std_return: int xfs_rmdir( xfs_inode_t *dp, - bhv_vname_t *dentry) + struct xfs_name *name, + xfs_inode_t *cdp) { bhv_vnode_t *dir_vp = XFS_ITOV(dp); - char *name = VNAME(dentry); - int namelen = VNAMELEN(dentry); xfs_mount_t *mp = dp->i_mount; - xfs_inode_t *cdp = VNAME_TO_INODE(dentry); xfs_trans_t *tp; int error; xfs_bmap_free_t free_list; @@ -2865,8 +2852,8 @@ xfs_rmdir( if (DM_EVENT_ENABLED(dp, DM_EVENT_REMOVE)) { error = XFS_SEND_NAMESP(mp, DM_EVENT_REMOVE, dp, DM_RIGHT_NULL, - NULL, DM_RIGHT_NULL, - name, NULL, cdp->i_d.di_mode, 0, 0); + NULL, DM_RIGHT_NULL, name->name, + NULL, cdp->i_d.di_mode, 0, 0); if (error) return XFS_ERROR(error); } @@ -2960,7 +2947,7 @@ xfs_rmdir( goto error_return; } - error = xfs_dir_removename(tp, dp, name, namelen, cdp->i_ino, + error = xfs_dir_removename(tp, dp, name, cdp->i_ino, &first_block, &free_list, resblks); if (error) goto error1; @@ -3040,7 +3027,7 @@ xfs_rmdir( (void) XFS_SEND_NAMESP(mp, DM_EVENT_POSTREMOVE, dp, DM_RIGHT_NULL, NULL, DM_RIGHT_NULL, - name, NULL, cdp->i_d.di_mode, + name->name, NULL, cdp->i_d.di_mode, error, 0); } return error; @@ -3058,8 +3045,8 @@ xfs_rmdir( int xfs_symlink( xfs_inode_t *dp, - bhv_vname_t *dentry, - char *target_path, + struct xfs_name *link_name, + const char *target_path, mode_t mode, xfs_inode_t **ipp, cred_t *credp) @@ -3079,15 +3066,13 @@ xfs_symlink( int nmaps; xfs_bmbt_irec_t mval[SYMLINK_MAPS]; xfs_daddr_t d; - char *cur_chunk; + const char *cur_chunk; int byte_cnt; int n; xfs_buf_t *bp; xfs_prid_t prid; struct xfs_dquot *udqp, *gdqp; uint resblks; - char *link_name = VNAME(dentry); - int link_namelen; *ipp = NULL; error = 0; @@ -3099,8 +3084,6 @@ xfs_symlink( if (XFS_FORCED_SHUTDOWN(mp)) return XFS_ERROR(EIO); - link_namelen = VNAMELEN(dentry); - /* * Check component lengths of the target path name. */ @@ -3111,7 +3094,7 @@ xfs_symlink( if (DM_EVENT_ENABLED(dp, DM_EVENT_SYMLINK)) { error = XFS_SEND_NAMESP(mp, DM_EVENT_SYMLINK, dp, DM_RIGHT_NULL, NULL, DM_RIGHT_NULL, - link_name, target_path, 0, 0, 0); + link_name->name, target_path, 0, 0, 0); if (error) return error; } @@ -3143,7 +3126,7 @@ xfs_symlink( fs_blocks = 0; else fs_blocks = XFS_B_TO_FSB(mp, pathlen); - resblks = XFS_SYMLINK_SPACE_RES(mp, link_namelen, fs_blocks); + resblks = XFS_SYMLINK_SPACE_RES(mp, link_name->len, fs_blocks); error = xfs_trans_reserve(tp, resblks, XFS_SYMLINK_LOG_RES(mp), 0, XFS_TRANS_PERM_LOG_RES, XFS_SYMLINK_LOG_COUNT); if (error == ENOSPC && fs_blocks == 0) { @@ -3177,8 +3160,8 @@ xfs_symlink( /* * Check for ability to enter directory entry, if no space reserved. */ - if (resblks == 0 && - (error = xfs_dir_canenter(tp, dp, link_name, link_namelen))) + error = xfs_dir_canenter(tp, dp, link_name, resblks); + if (error) goto error_return; /* * Initialize the bmap freelist prior to calling either @@ -3270,8 +3253,8 @@ xfs_symlink( /* * Create the directory entry for the symlink. */ - error = xfs_dir_createname(tp, dp, link_name, link_namelen, ip->i_ino, - &first_block, &free_list, resblks); + error = xfs_dir_createname(tp, dp, link_name, ip->i_ino, + &first_block, &free_list, resblks); if (error) goto error1; xfs_ichgtime(dp, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG); @@ -3315,8 +3298,8 @@ std_return: (void) XFS_SEND_NAMESP(mp, DM_EVENT_POSTSYMLINK, dp, DM_RIGHT_NULL, error ? NULL : ip, - DM_RIGHT_NULL, link_name, target_path, - 0, error, 0); + DM_RIGHT_NULL, link_name->name, + target_path, 0, error, 0); } if (!error) -- cgit v1.2.3 From d64e31a2f53cdcb2f95b782196faacb0995ca0c0 Mon Sep 17 00:00:00 2001 From: David Chinner Date: Thu, 10 Apr 2008 12:22:17 +1000 Subject: [XFS] Ensure errors from xfs_bdstrat() are correctly checked. xfsbdstrat() is declared to return an error. That is never checked because the error is propagated by the xfs_buf_t that is passed through the function. Mark xfsbdstrat() as returning void and comment the prototype on the methods needed for error checking. SGI-PV: 980084 SGI-Modid: xfs-linux-melb:xfs-kern:30823a Signed-off-by: David Chinner Signed-off-by: Niv Sardi Signed-off-by: Lachlan McIlroy --- fs/xfs/xfs_vnodeops.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'fs/xfs/xfs_vnodeops.c') diff --git a/fs/xfs/xfs_vnodeops.c b/fs/xfs/xfs_vnodeops.c index ca38fb9a993..dd4621e0ab3 100644 --- a/fs/xfs/xfs_vnodeops.c +++ b/fs/xfs/xfs_vnodeops.c @@ -3825,7 +3825,8 @@ xfs_zero_remaining_bytes( XFS_BUF_READ(bp); XFS_BUF_SET_ADDR(bp, XFS_FSB_TO_DB(ip, imap.br_startblock)); xfsbdstrat(mp, bp); - if ((error = xfs_iowait(bp))) { + error = xfs_iowait(bp); + if (error) { xfs_ioerror_alert("xfs_zero_remaining_bytes(read)", mp, bp, XFS_BUF_ADDR(bp)); break; @@ -3837,7 +3838,8 @@ xfs_zero_remaining_bytes( XFS_BUF_UNREAD(bp); XFS_BUF_WRITE(bp); xfsbdstrat(mp, bp); - if ((error = xfs_iowait(bp))) { + error = xfs_iowait(bp); + if (error) { xfs_ioerror_alert("xfs_zero_remaining_bytes(write)", mp, bp, XFS_BUF_ADDR(bp)); break; -- cgit v1.2.3 From 78e9da77f1bf265fe750b9223ec15707473fb6e8 Mon Sep 17 00:00:00 2001 From: David Chinner Date: Thu, 10 Apr 2008 12:24:17 +1000 Subject: [XFS] Don't allow silent errors in xfs_inactive(). xfs_inactive() fails to report errors when committing the inactive transaction. Hence we can get silent failures either finishing off the truncation or committing the transaction. Even if we get errors, we need to continue, so simply warn loudly to the system if we get errors here. SGI-PV: 980084 SGI-Modid: xfs-linux-melb:xfs-kern:30830a Signed-off-by: David Chinner Signed-off-by: Niv Sardi Signed-off-by: Lachlan McIlroy --- fs/xfs/xfs_vnodeops.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) (limited to 'fs/xfs/xfs_vnodeops.c') diff --git a/fs/xfs/xfs_vnodeops.c b/fs/xfs/xfs_vnodeops.c index dd4621e0ab3..6650601c64f 100644 --- a/fs/xfs/xfs_vnodeops.c +++ b/fs/xfs/xfs_vnodeops.c @@ -1743,11 +1743,18 @@ xfs_inactive( XFS_TRANS_MOD_DQUOT_BYINO(mp, tp, ip, XFS_TRANS_DQ_ICOUNT, -1); /* - * Just ignore errors at this point. There is - * nothing we can do except to try to keep going. + * Just ignore errors at this point. There is nothing we can + * do except to try to keep going. Make sure it's not a silent + * error. */ - (void) xfs_bmap_finish(&tp, &free_list, &committed); - (void) xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES); + error = xfs_bmap_finish(&tp, &free_list, &committed); + if (error) + xfs_fs_cmn_err(CE_NOTE, mp, "xfs_inactive: " + "xfs_bmap_finish() returned error %d", error); + error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES); + if (error) + xfs_fs_cmn_err(CE_NOTE, mp, "xfs_inactive: " + "xfs_trans_commit() returned error %d", error); } /* * Release the dquots held by inode, if any. -- cgit v1.2.3