diff options
Diffstat (limited to 'fs/xfs/xfs_dfrag.c')
-rw-r--r-- | fs/xfs/xfs_dfrag.c | 84 |
1 files changed, 35 insertions, 49 deletions
diff --git a/fs/xfs/xfs_dfrag.c b/fs/xfs/xfs_dfrag.c index 584f1ae85cd9..3f53fad356a3 100644 --- a/fs/xfs/xfs_dfrag.c +++ b/fs/xfs/xfs_dfrag.c | |||
@@ -52,76 +52,72 @@ xfs_swapext( | |||
52 | xfs_swapext_t __user *sxu) | 52 | xfs_swapext_t __user *sxu) |
53 | { | 53 | { |
54 | xfs_swapext_t *sxp; | 54 | xfs_swapext_t *sxp; |
55 | xfs_inode_t *ip=NULL, *tip=NULL; | 55 | xfs_inode_t *ip, *tip; |
56 | xfs_mount_t *mp; | 56 | struct file *file, *target_file; |
57 | struct file *fp = NULL, *tfp = NULL; | ||
58 | bhv_vnode_t *vp, *tvp; | ||
59 | int error = 0; | 57 | int error = 0; |
60 | 58 | ||
61 | sxp = kmem_alloc(sizeof(xfs_swapext_t), KM_MAYFAIL); | 59 | sxp = kmem_alloc(sizeof(xfs_swapext_t), KM_MAYFAIL); |
62 | if (!sxp) { | 60 | if (!sxp) { |
63 | error = XFS_ERROR(ENOMEM); | 61 | error = XFS_ERROR(ENOMEM); |
64 | goto error0; | 62 | goto out; |
65 | } | 63 | } |
66 | 64 | ||
67 | if (copy_from_user(sxp, sxu, sizeof(xfs_swapext_t))) { | 65 | if (copy_from_user(sxp, sxu, sizeof(xfs_swapext_t))) { |
68 | error = XFS_ERROR(EFAULT); | 66 | error = XFS_ERROR(EFAULT); |
69 | goto error0; | 67 | goto out_free_sxp; |
70 | } | 68 | } |
71 | 69 | ||
72 | /* Pull information for the target fd */ | 70 | /* Pull information for the target fd */ |
73 | if (((fp = fget((int)sxp->sx_fdtarget)) == NULL) || | 71 | file = fget((int)sxp->sx_fdtarget); |
74 | ((vp = vn_from_inode(fp->f_path.dentry->d_inode)) == NULL)) { | 72 | if (!file) { |
75 | error = XFS_ERROR(EINVAL); | 73 | error = XFS_ERROR(EINVAL); |
76 | goto error0; | 74 | goto out_free_sxp; |
77 | } | 75 | } |
78 | 76 | ||
79 | ip = xfs_vtoi(vp); | 77 | if (!(file->f_mode & FMODE_WRITE) || (file->f_flags & O_APPEND)) { |
80 | if (ip == NULL) { | ||
81 | error = XFS_ERROR(EBADF); | 78 | error = XFS_ERROR(EBADF); |
82 | goto error0; | 79 | goto out_put_file; |
83 | } | 80 | } |
84 | 81 | ||
85 | if (((tfp = fget((int)sxp->sx_fdtmp)) == NULL) || | 82 | target_file = fget((int)sxp->sx_fdtmp); |
86 | ((tvp = vn_from_inode(tfp->f_path.dentry->d_inode)) == NULL)) { | 83 | if (!target_file) { |
87 | error = XFS_ERROR(EINVAL); | 84 | error = XFS_ERROR(EINVAL); |
88 | goto error0; | 85 | goto out_put_file; |
89 | } | 86 | } |
90 | 87 | ||
91 | tip = xfs_vtoi(tvp); | 88 | if (!(target_file->f_mode & FMODE_WRITE) || |
92 | if (tip == NULL) { | 89 | (target_file->f_flags & O_APPEND)) { |
93 | error = XFS_ERROR(EBADF); | 90 | error = XFS_ERROR(EBADF); |
94 | goto error0; | 91 | goto out_put_target_file; |
95 | } | 92 | } |
96 | 93 | ||
94 | ip = XFS_I(file->f_path.dentry->d_inode); | ||
95 | tip = XFS_I(target_file->f_path.dentry->d_inode); | ||
96 | |||
97 | if (ip->i_mount != tip->i_mount) { | 97 | if (ip->i_mount != tip->i_mount) { |
98 | error = XFS_ERROR(EINVAL); | 98 | error = XFS_ERROR(EINVAL); |
99 | goto error0; | 99 | goto out_put_target_file; |
100 | } | 100 | } |
101 | 101 | ||
102 | if (ip->i_ino == tip->i_ino) { | 102 | if (ip->i_ino == tip->i_ino) { |
103 | error = XFS_ERROR(EINVAL); | 103 | error = XFS_ERROR(EINVAL); |
104 | goto error0; | 104 | goto out_put_target_file; |
105 | } | 105 | } |
106 | 106 | ||
107 | mp = ip->i_mount; | 107 | if (XFS_FORCED_SHUTDOWN(ip->i_mount)) { |
108 | 108 | error = XFS_ERROR(EIO); | |
109 | if (XFS_FORCED_SHUTDOWN(mp)) { | 109 | goto out_put_target_file; |
110 | error = XFS_ERROR(EIO); | ||
111 | goto error0; | ||
112 | } | 110 | } |
113 | 111 | ||
114 | error = XFS_SWAP_EXTENTS(mp, &ip->i_iocore, &tip->i_iocore, sxp); | 112 | error = xfs_swap_extents(ip, tip, sxp); |
115 | |||
116 | error0: | ||
117 | if (fp != NULL) | ||
118 | fput(fp); | ||
119 | if (tfp != NULL) | ||
120 | fput(tfp); | ||
121 | |||
122 | if (sxp != NULL) | ||
123 | kmem_free(sxp, sizeof(xfs_swapext_t)); | ||
124 | 113 | ||
114 | out_put_target_file: | ||
115 | fput(target_file); | ||
116 | out_put_file: | ||
117 | fput(file); | ||
118 | out_free_sxp: | ||
119 | kmem_free(sxp, sizeof(xfs_swapext_t)); | ||
120 | out: | ||
125 | return error; | 121 | return error; |
126 | } | 122 | } |
127 | 123 | ||
@@ -169,15 +165,6 @@ xfs_swap_extents( | |||
169 | xfs_lock_inodes(ips, 2, 0, lock_flags); | 165 | xfs_lock_inodes(ips, 2, 0, lock_flags); |
170 | locked = 1; | 166 | locked = 1; |
171 | 167 | ||
172 | /* Check permissions */ | ||
173 | error = xfs_iaccess(ip, S_IWUSR, NULL); | ||
174 | if (error) | ||
175 | goto error0; | ||
176 | |||
177 | error = xfs_iaccess(tip, S_IWUSR, NULL); | ||
178 | if (error) | ||
179 | goto error0; | ||
180 | |||
181 | /* Verify that both files have the same format */ | 168 | /* Verify that both files have the same format */ |
182 | if ((ip->i_d.di_mode & S_IFMT) != (tip->i_d.di_mode & S_IFMT)) { | 169 | if ((ip->i_d.di_mode & S_IFMT) != (tip->i_d.di_mode & S_IFMT)) { |
183 | error = XFS_ERROR(EINVAL); | 170 | error = XFS_ERROR(EINVAL); |
@@ -185,8 +172,7 @@ xfs_swap_extents( | |||
185 | } | 172 | } |
186 | 173 | ||
187 | /* Verify both files are either real-time or non-realtime */ | 174 | /* Verify both files are either real-time or non-realtime */ |
188 | if ((ip->i_d.di_flags & XFS_DIFLAG_REALTIME) != | 175 | if (XFS_IS_REALTIME_INODE(ip) != XFS_IS_REALTIME_INODE(tip)) { |
189 | (tip->i_d.di_flags & XFS_DIFLAG_REALTIME)) { | ||
190 | error = XFS_ERROR(EINVAL); | 176 | error = XFS_ERROR(EINVAL); |
191 | goto error0; | 177 | goto error0; |
192 | } | 178 | } |
@@ -199,7 +185,7 @@ xfs_swap_extents( | |||
199 | } | 185 | } |
200 | 186 | ||
201 | if (VN_CACHED(tvp) != 0) { | 187 | if (VN_CACHED(tvp) != 0) { |
202 | xfs_inval_cached_trace(&tip->i_iocore, 0, -1, 0, -1); | 188 | xfs_inval_cached_trace(tip, 0, -1, 0, -1); |
203 | error = xfs_flushinval_pages(tip, 0, -1, | 189 | error = xfs_flushinval_pages(tip, 0, -1, |
204 | FI_REMAPF_LOCKED); | 190 | FI_REMAPF_LOCKED); |
205 | if (error) | 191 | if (error) |