提交 d3cf2094 编写于 作者: L Lachlan McIlroy 提交者: Tim Shimmin

[XFS] propogate return codes from flush routines

This patch handles error return values in fs_flush_pages and
fs_flushinval_pages. It changes the prototype of fs_flushinval_pages so we
can propogate the errors and handle them at higher layers. I also modified
xfs_itruncate_start so that it could propogate the error further.

SGI-PV: 961990
SGI-Modid: xfs-linux-melb:xfs-kern:28231a
Signed-off-by: NLachlan McIlroy <lachlan@sgi.com>
Signed-off-by: NStewart Smith <stewart@flamingspork.com>
Signed-off-by: NTim Shimmin <tes@sgi.com>
上级 424ea91b
...@@ -35,7 +35,7 @@ fs_tosspages( ...@@ -35,7 +35,7 @@ fs_tosspages(
truncate_inode_pages(ip->i_mapping, first); truncate_inode_pages(ip->i_mapping, first);
} }
void int
fs_flushinval_pages( fs_flushinval_pages(
bhv_desc_t *bdp, bhv_desc_t *bdp,
xfs_off_t first, xfs_off_t first,
...@@ -44,13 +44,16 @@ fs_flushinval_pages( ...@@ -44,13 +44,16 @@ fs_flushinval_pages(
{ {
bhv_vnode_t *vp = BHV_TO_VNODE(bdp); bhv_vnode_t *vp = BHV_TO_VNODE(bdp);
struct inode *ip = vn_to_inode(vp); struct inode *ip = vn_to_inode(vp);
int ret = 0;
if (VN_CACHED(vp)) { if (VN_CACHED(vp)) {
if (VN_TRUNC(vp)) if (VN_TRUNC(vp))
VUNTRUNCATE(vp); VUNTRUNCATE(vp);
filemap_write_and_wait(ip->i_mapping); ret = filemap_write_and_wait(ip->i_mapping);
truncate_inode_pages(ip->i_mapping, first); if (!ret)
truncate_inode_pages(ip->i_mapping, first);
} }
return ret;
} }
int int
...@@ -63,14 +66,18 @@ fs_flush_pages( ...@@ -63,14 +66,18 @@ fs_flush_pages(
{ {
bhv_vnode_t *vp = BHV_TO_VNODE(bdp); bhv_vnode_t *vp = BHV_TO_VNODE(bdp);
struct inode *ip = vn_to_inode(vp); struct inode *ip = vn_to_inode(vp);
int ret = 0;
int ret2;
if (VN_DIRTY(vp)) { if (VN_DIRTY(vp)) {
if (VN_TRUNC(vp)) if (VN_TRUNC(vp))
VUNTRUNCATE(vp); VUNTRUNCATE(vp);
filemap_fdatawrite(ip->i_mapping); ret = filemap_fdatawrite(ip->i_mapping);
if (flags & XFS_B_ASYNC) if (flags & XFS_B_ASYNC)
return 0; return ret;
filemap_fdatawait(ip->i_mapping); ret2 = filemap_fdatawait(ip->i_mapping);
if (!ret)
ret = ret2;
} }
return 0; return ret;
} }
...@@ -23,7 +23,7 @@ extern int fs_noerr(void); ...@@ -23,7 +23,7 @@ extern int fs_noerr(void);
extern int fs_nosys(void); extern int fs_nosys(void);
extern void fs_noval(void); extern void fs_noval(void);
extern void fs_tosspages(bhv_desc_t *, xfs_off_t, xfs_off_t, int); extern void fs_tosspages(bhv_desc_t *, xfs_off_t, xfs_off_t, int);
extern void fs_flushinval_pages(bhv_desc_t *, xfs_off_t, xfs_off_t, int); extern int fs_flushinval_pages(bhv_desc_t *, xfs_off_t, xfs_off_t, int);
extern int fs_flush_pages(bhv_desc_t *, xfs_off_t, xfs_off_t, uint64_t, int); extern int fs_flush_pages(bhv_desc_t *, xfs_off_t, xfs_off_t, uint64_t, int);
#endif /* __XFS_FS_SUBR_H__ */ #endif /* __XFS_FS_SUBR_H__ */
...@@ -191,7 +191,7 @@ xfs_read( ...@@ -191,7 +191,7 @@ xfs_read(
struct file *file = iocb->ki_filp; struct file *file = iocb->ki_filp;
struct inode *inode = file->f_mapping->host; struct inode *inode = file->f_mapping->host;
size_t size = 0; size_t size = 0;
ssize_t ret; ssize_t ret = 0;
xfs_fsize_t n; xfs_fsize_t n;
xfs_inode_t *ip; xfs_inode_t *ip;
xfs_mount_t *mp; xfs_mount_t *mp;
...@@ -263,9 +263,13 @@ xfs_read( ...@@ -263,9 +263,13 @@ xfs_read(
if (unlikely(ioflags & IO_ISDIRECT)) { if (unlikely(ioflags & IO_ISDIRECT)) {
if (VN_CACHED(vp)) if (VN_CACHED(vp))
bhv_vop_flushinval_pages(vp, ctooff(offtoct(*offset)), ret = bhv_vop_flushinval_pages(vp, ctooff(offtoct(*offset)),
-1, FI_REMAPF_LOCKED); -1, FI_REMAPF_LOCKED);
mutex_unlock(&inode->i_mutex); mutex_unlock(&inode->i_mutex);
if (ret) {
xfs_iunlock(ip, XFS_IOLOCK_SHARED);
return ret;
}
} }
xfs_rw_enter_trace(XFS_READ_ENTER, &ip->i_iocore, xfs_rw_enter_trace(XFS_READ_ENTER, &ip->i_iocore,
...@@ -814,8 +818,10 @@ xfs_write( ...@@ -814,8 +818,10 @@ xfs_write(
if (need_flush) { if (need_flush) {
xfs_inval_cached_trace(io, pos, -1, xfs_inval_cached_trace(io, pos, -1,
ctooff(offtoct(pos)), -1); ctooff(offtoct(pos)), -1);
bhv_vop_flushinval_pages(vp, ctooff(offtoct(pos)), error = bhv_vop_flushinval_pages(vp, ctooff(offtoct(pos)),
-1, FI_REMAPF_LOCKED); -1, FI_REMAPF_LOCKED);
if (error)
goto out_unlock_internal;
} }
if (need_i_mutex) { if (need_i_mutex) {
......
...@@ -194,7 +194,7 @@ typedef int (*vop_attr_list_t)(bhv_desc_t *, char *, int, int, ...@@ -194,7 +194,7 @@ typedef int (*vop_attr_list_t)(bhv_desc_t *, char *, int, int,
typedef void (*vop_link_removed_t)(bhv_desc_t *, bhv_vnode_t *, int); typedef void (*vop_link_removed_t)(bhv_desc_t *, bhv_vnode_t *, int);
typedef void (*vop_vnode_change_t)(bhv_desc_t *, bhv_vchange_t, __psint_t); typedef void (*vop_vnode_change_t)(bhv_desc_t *, bhv_vchange_t, __psint_t);
typedef void (*vop_ptossvp_t)(bhv_desc_t *, xfs_off_t, xfs_off_t, int); typedef void (*vop_ptossvp_t)(bhv_desc_t *, xfs_off_t, xfs_off_t, int);
typedef void (*vop_pflushinvalvp_t)(bhv_desc_t *, xfs_off_t, xfs_off_t, int); typedef int (*vop_pflushinvalvp_t)(bhv_desc_t *, xfs_off_t, xfs_off_t, int);
typedef int (*vop_pflushvp_t)(bhv_desc_t *, xfs_off_t, xfs_off_t, typedef int (*vop_pflushvp_t)(bhv_desc_t *, xfs_off_t, xfs_off_t,
uint64_t, int); uint64_t, int);
typedef int (*vop_iflush_t)(bhv_desc_t *, int); typedef int (*vop_iflush_t)(bhv_desc_t *, int);
......
...@@ -199,7 +199,9 @@ xfs_swap_extents( ...@@ -199,7 +199,9 @@ xfs_swap_extents(
if (VN_CACHED(tvp) != 0) { if (VN_CACHED(tvp) != 0) {
xfs_inval_cached_trace(&tip->i_iocore, 0, -1, 0, -1); xfs_inval_cached_trace(&tip->i_iocore, 0, -1, 0, -1);
bhv_vop_flushinval_pages(tvp, 0, -1, FI_REMAPF_LOCKED); error = bhv_vop_flushinval_pages(tvp, 0, -1, FI_REMAPF_LOCKED);
if (error)
goto error0;
} }
/* Verify O_DIRECT for ftmp */ /* Verify O_DIRECT for ftmp */
......
...@@ -1421,7 +1421,7 @@ xfs_itrunc_trace( ...@@ -1421,7 +1421,7 @@ xfs_itrunc_trace(
* must be called again with all the same restrictions as the initial * must be called again with all the same restrictions as the initial
* call. * call.
*/ */
void int
xfs_itruncate_start( xfs_itruncate_start(
xfs_inode_t *ip, xfs_inode_t *ip,
uint flags, uint flags,
...@@ -1431,6 +1431,7 @@ xfs_itruncate_start( ...@@ -1431,6 +1431,7 @@ xfs_itruncate_start(
xfs_off_t toss_start; xfs_off_t toss_start;
xfs_mount_t *mp; xfs_mount_t *mp;
bhv_vnode_t *vp; bhv_vnode_t *vp;
int error = 0;
ASSERT(ismrlocked(&ip->i_iolock, MR_UPDATE) != 0); ASSERT(ismrlocked(&ip->i_iolock, MR_UPDATE) != 0);
ASSERT((new_size == 0) || (new_size <= ip->i_d.di_size)); ASSERT((new_size == 0) || (new_size <= ip->i_d.di_size));
...@@ -1468,7 +1469,7 @@ xfs_itruncate_start( ...@@ -1468,7 +1469,7 @@ xfs_itruncate_start(
* file size, so there is no way that the data extended * file size, so there is no way that the data extended
* out there. * out there.
*/ */
return; return 0;
} }
last_byte = xfs_file_last_byte(ip); last_byte = xfs_file_last_byte(ip);
xfs_itrunc_trace(XFS_ITRUNC_START, ip, flags, new_size, toss_start, xfs_itrunc_trace(XFS_ITRUNC_START, ip, flags, new_size, toss_start,
...@@ -1477,7 +1478,7 @@ xfs_itruncate_start( ...@@ -1477,7 +1478,7 @@ xfs_itruncate_start(
if (flags & XFS_ITRUNC_DEFINITE) { if (flags & XFS_ITRUNC_DEFINITE) {
bhv_vop_toss_pages(vp, toss_start, -1, FI_REMAPF_LOCKED); bhv_vop_toss_pages(vp, toss_start, -1, FI_REMAPF_LOCKED);
} else { } else {
bhv_vop_flushinval_pages(vp, toss_start, -1, FI_REMAPF_LOCKED); error = bhv_vop_flushinval_pages(vp, toss_start, -1, FI_REMAPF_LOCKED);
} }
} }
...@@ -1486,6 +1487,7 @@ xfs_itruncate_start( ...@@ -1486,6 +1487,7 @@ xfs_itruncate_start(
ASSERT(VN_CACHED(vp) == 0); ASSERT(VN_CACHED(vp) == 0);
} }
#endif #endif
return error;
} }
/* /*
......
...@@ -481,7 +481,7 @@ uint xfs_ip2xflags(struct xfs_inode *); ...@@ -481,7 +481,7 @@ uint xfs_ip2xflags(struct xfs_inode *);
uint xfs_dic2xflags(struct xfs_dinode_core *); uint xfs_dic2xflags(struct xfs_dinode_core *);
int xfs_ifree(struct xfs_trans *, xfs_inode_t *, int xfs_ifree(struct xfs_trans *, xfs_inode_t *,
struct xfs_bmap_free *); struct xfs_bmap_free *);
void xfs_itruncate_start(xfs_inode_t *, uint, xfs_fsize_t); int xfs_itruncate_start(xfs_inode_t *, uint, xfs_fsize_t);
int xfs_itruncate_finish(struct xfs_trans **, xfs_inode_t *, int xfs_itruncate_finish(struct xfs_trans **, xfs_inode_t *,
xfs_fsize_t, int, int); xfs_fsize_t, int, int);
int xfs_iunlink(struct xfs_trans *, xfs_inode_t *); int xfs_iunlink(struct xfs_trans *, xfs_inode_t *);
......
...@@ -420,7 +420,11 @@ xfs_truncate_file( ...@@ -420,7 +420,11 @@ xfs_truncate_file(
* in a transaction. * in a transaction.
*/ */
xfs_ilock(ip, XFS_IOLOCK_EXCL); xfs_ilock(ip, XFS_IOLOCK_EXCL);
xfs_itruncate_start(ip, XFS_ITRUNC_DEFINITE, (xfs_fsize_t)0); error = xfs_itruncate_start(ip, XFS_ITRUNC_DEFINITE, (xfs_fsize_t)0);
if (error) {
xfs_iunlock(ip, XFS_IOLOCK_EXCL);
return error;
}
tp = xfs_trans_alloc(mp, XFS_TRANS_TRUNCATE_FILE); tp = xfs_trans_alloc(mp, XFS_TRANS_TRUNCATE_FILE);
if ((error = xfs_trans_reserve(tp, 0, XFS_ITRUNCATE_LOG_RES(mp), 0, if ((error = xfs_trans_reserve(tp, 0, XFS_ITRUNCATE_LOG_RES(mp), 0,
......
...@@ -1147,7 +1147,7 @@ xfs_sync_inodes( ...@@ -1147,7 +1147,7 @@ xfs_sync_inodes(
if (XFS_FORCED_SHUTDOWN(mp)) { if (XFS_FORCED_SHUTDOWN(mp)) {
bhv_vop_toss_pages(vp, 0, -1, FI_REMAPF); bhv_vop_toss_pages(vp, 0, -1, FI_REMAPF);
} else { } else {
bhv_vop_flushinval_pages(vp, 0, -1, FI_REMAPF); error = bhv_vop_flushinval_pages(vp, 0, -1, FI_REMAPF);
} }
xfs_ilock(ip, XFS_ILOCK_SHARED); xfs_ilock(ip, XFS_ILOCK_SHARED);
......
...@@ -1257,8 +1257,12 @@ xfs_inactive_free_eofblocks( ...@@ -1257,8 +1257,12 @@ xfs_inactive_free_eofblocks(
* do that within a transaction. * do that within a transaction.
*/ */
xfs_ilock(ip, XFS_IOLOCK_EXCL); xfs_ilock(ip, XFS_IOLOCK_EXCL);
xfs_itruncate_start(ip, XFS_ITRUNC_DEFINITE, error = xfs_itruncate_start(ip, XFS_ITRUNC_DEFINITE,
ip->i_d.di_size); ip->i_d.di_size);
if (error) {
xfs_iunlock(ip, XFS_IOLOCK_EXCL);
return error;
}
error = xfs_trans_reserve(tp, 0, error = xfs_trans_reserve(tp, 0,
XFS_ITRUNCATE_LOG_RES(mp), XFS_ITRUNCATE_LOG_RES(mp),
...@@ -1674,7 +1678,11 @@ xfs_inactive( ...@@ -1674,7 +1678,11 @@ xfs_inactive(
*/ */
xfs_ilock(ip, XFS_IOLOCK_EXCL); xfs_ilock(ip, XFS_IOLOCK_EXCL);
xfs_itruncate_start(ip, XFS_ITRUNC_DEFINITE, 0); error = xfs_itruncate_start(ip, XFS_ITRUNC_DEFINITE, 0);
if (error) {
xfs_iunlock(ip, XFS_IOLOCK_EXCL);
return VN_INACTIVE_CACHE;
}
error = xfs_trans_reserve(tp, 0, error = xfs_trans_reserve(tp, 0,
XFS_ITRUNCATE_LOG_RES(mp), XFS_ITRUNCATE_LOG_RES(mp),
...@@ -4338,8 +4346,10 @@ xfs_free_file_space( ...@@ -4338,8 +4346,10 @@ xfs_free_file_space(
if (VN_CACHED(vp) != 0) { if (VN_CACHED(vp) != 0) {
xfs_inval_cached_trace(&ip->i_iocore, ioffset, -1, xfs_inval_cached_trace(&ip->i_iocore, ioffset, -1,
ctooff(offtoct(ioffset)), -1); ctooff(offtoct(ioffset)), -1);
bhv_vop_flushinval_pages(vp, ctooff(offtoct(ioffset)), error = bhv_vop_flushinval_pages(vp, ctooff(offtoct(ioffset)),
-1, FI_REMAPF_LOCKED); -1, FI_REMAPF_LOCKED);
if (error)
goto out_unlock_iolock;
} }
/* /*
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册