aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/xfs_dfrag.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/xfs/xfs_dfrag.c')
-rw-r--r--fs/xfs/xfs_dfrag.c84
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)