aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/xfs/linux-2.6/xfs_ioctl32.c44
-rw-r--r--fs/xfs/xfs_itable.c21
-rw-r--r--fs/xfs/xfs_itable.h2
3 files changed, 39 insertions, 28 deletions
diff --git a/fs/xfs/linux-2.6/xfs_ioctl32.c b/fs/xfs/linux-2.6/xfs_ioctl32.c
index a97022f2d9b0..2d336062831d 100644
--- a/fs/xfs/linux-2.6/xfs_ioctl32.c
+++ b/fs/xfs/linux-2.6/xfs_ioctl32.c
@@ -192,35 +192,43 @@ xfs_bstime_store_compat(
192 return 0; 192 return 0;
193} 193}
194 194
195/* Return 0 on success or positive error (to xfs_bulkstat()) */
195STATIC int 196STATIC int
196xfs_bulkstat_one_fmt_compat( 197xfs_bulkstat_one_fmt_compat(
197 void __user *ubuffer, 198 void __user *ubuffer,
199 int ubsize,
200 int *ubused,
198 const xfs_bstat_t *buffer) 201 const xfs_bstat_t *buffer)
199{ 202{
200 compat_xfs_bstat_t __user *p32 = ubuffer; 203 compat_xfs_bstat_t __user *p32 = ubuffer;
201 204
202 if (put_user(buffer->bs_ino, &p32->bs_ino) || 205 if (ubsize < sizeof(*p32))
203 put_user(buffer->bs_mode, &p32->bs_mode) || 206 return XFS_ERROR(ENOMEM);
204 put_user(buffer->bs_nlink, &p32->bs_nlink) || 207
205 put_user(buffer->bs_uid, &p32->bs_uid) || 208 if (put_user(buffer->bs_ino, &p32->bs_ino) ||
206 put_user(buffer->bs_gid, &p32->bs_gid) || 209 put_user(buffer->bs_mode, &p32->bs_mode) ||
207 put_user(buffer->bs_rdev, &p32->bs_rdev) || 210 put_user(buffer->bs_nlink, &p32->bs_nlink) ||
208 put_user(buffer->bs_blksize, &p32->bs_blksize) || 211 put_user(buffer->bs_uid, &p32->bs_uid) ||
209 put_user(buffer->bs_size, &p32->bs_size) || 212 put_user(buffer->bs_gid, &p32->bs_gid) ||
213 put_user(buffer->bs_rdev, &p32->bs_rdev) ||
214 put_user(buffer->bs_blksize, &p32->bs_blksize) ||
215 put_user(buffer->bs_size, &p32->bs_size) ||
210 xfs_bstime_store_compat(&p32->bs_atime, &buffer->bs_atime) || 216 xfs_bstime_store_compat(&p32->bs_atime, &buffer->bs_atime) ||
211 xfs_bstime_store_compat(&p32->bs_mtime, &buffer->bs_mtime) || 217 xfs_bstime_store_compat(&p32->bs_mtime, &buffer->bs_mtime) ||
212 xfs_bstime_store_compat(&p32->bs_ctime, &buffer->bs_ctime) || 218 xfs_bstime_store_compat(&p32->bs_ctime, &buffer->bs_ctime) ||
213 put_user(buffer->bs_blocks, &p32->bs_blocks) || 219 put_user(buffer->bs_blocks, &p32->bs_blocks) ||
214 put_user(buffer->bs_xflags, &p32->bs_xflags) || 220 put_user(buffer->bs_xflags, &p32->bs_xflags) ||
215 put_user(buffer->bs_extsize, &p32->bs_extsize) || 221 put_user(buffer->bs_extsize, &p32->bs_extsize) ||
216 put_user(buffer->bs_extents, &p32->bs_extents) || 222 put_user(buffer->bs_extents, &p32->bs_extents) ||
217 put_user(buffer->bs_gen, &p32->bs_gen) || 223 put_user(buffer->bs_gen, &p32->bs_gen) ||
218 put_user(buffer->bs_projid, &p32->bs_projid) || 224 put_user(buffer->bs_projid, &p32->bs_projid) ||
219 put_user(buffer->bs_dmevmask, &p32->bs_dmevmask) || 225 put_user(buffer->bs_dmevmask, &p32->bs_dmevmask) ||
220 put_user(buffer->bs_dmstate, &p32->bs_dmstate) || 226 put_user(buffer->bs_dmstate, &p32->bs_dmstate) ||
221 put_user(buffer->bs_aextents, &p32->bs_aextents)) 227 put_user(buffer->bs_aextents, &p32->bs_aextents))
222 return -XFS_ERROR(EFAULT); 228 return XFS_ERROR(EFAULT);
223 return sizeof(*p32); 229 if (ubused)
230 *ubused = sizeof(*p32);
231 return 0;
224} 232}
225 233
226STATIC int 234STATIC int
diff --git a/fs/xfs/xfs_itable.c b/fs/xfs/xfs_itable.c
index 7bd49b87160c..e19d0a8d5618 100644
--- a/fs/xfs/xfs_itable.c
+++ b/fs/xfs/xfs_itable.c
@@ -188,14 +188,21 @@ xfs_bulkstat_one_dinode(
188 } 188 }
189} 189}
190 190
191/* Return 0 on success or positive error */
191STATIC int 192STATIC int
192xfs_bulkstat_one_fmt( 193xfs_bulkstat_one_fmt(
193 void __user *ubuffer, 194 void __user *ubuffer,
195 int ubsize,
196 int *ubused,
194 const xfs_bstat_t *buffer) 197 const xfs_bstat_t *buffer)
195{ 198{
199 if (ubsize < sizeof(*buffer))
200 return XFS_ERROR(ENOMEM);
196 if (copy_to_user(ubuffer, buffer, sizeof(*buffer))) 201 if (copy_to_user(ubuffer, buffer, sizeof(*buffer)))
197 return -EFAULT; 202 return XFS_ERROR(EFAULT);
198 return sizeof(*buffer); 203 if (ubused)
204 *ubused = sizeof(*buffer);
205 return 0;
199} 206}
200 207
201/* 208/*
@@ -223,8 +230,6 @@ xfs_bulkstat_one_int(
223 230
224 if (!buffer || xfs_internal_inum(mp, ino)) 231 if (!buffer || xfs_internal_inum(mp, ino))
225 return XFS_ERROR(EINVAL); 232 return XFS_ERROR(EINVAL);
226 if (ubsize < sizeof(*buf))
227 return XFS_ERROR(ENOMEM);
228 233
229 buf = kmem_alloc(sizeof(*buf), KM_SLEEP); 234 buf = kmem_alloc(sizeof(*buf), KM_SLEEP);
230 235
@@ -239,15 +244,11 @@ xfs_bulkstat_one_int(
239 xfs_bulkstat_one_dinode(mp, ino, dip, buf); 244 xfs_bulkstat_one_dinode(mp, ino, dip, buf);
240 } 245 }
241 246
242 error = formatter(buffer, buf); 247 error = formatter(buffer, ubsize, ubused, buf);
243 if (error < 0) { 248 if (error)
244 error = EFAULT;
245 goto out_free; 249 goto out_free;
246 }
247 250
248 *stat = BULKSTAT_RV_DIDONE; 251 *stat = BULKSTAT_RV_DIDONE;
249 if (ubused)
250 *ubused = error;
251 252
252 out_free: 253 out_free:
253 kmem_free(buf); 254 kmem_free(buf);
diff --git a/fs/xfs/xfs_itable.h b/fs/xfs/xfs_itable.h
index e210a4c06569..1fb04e7deb61 100644
--- a/fs/xfs/xfs_itable.h
+++ b/fs/xfs/xfs_itable.h
@@ -71,6 +71,8 @@ xfs_bulkstat_single(
71 71
72typedef int (*bulkstat_one_fmt_pf)( /* used size in bytes or negative error */ 72typedef int (*bulkstat_one_fmt_pf)( /* used size in bytes or negative error */
73 void __user *ubuffer, /* buffer to write to */ 73 void __user *ubuffer, /* buffer to write to */
74 int ubsize, /* remaining user buffer sz */
75 int *ubused, /* bytes used by formatter */
74 const xfs_bstat_t *buffer); /* buffer to read from */ 76 const xfs_bstat_t *buffer); /* buffer to read from */
75 77
76int 78int