mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-08-21 08:19:28 +00:00
![Dave Chinner](/assets/img/avatar_default.png)
The xfs_bulkstat_agichunk formatting cursor takes buffer values from the main loop and passes them via the structure to the chunk formatter, and the writes the changed values back into the main loop local variables. Unfortunately, this complex dance is full of corner cases that aren't handled correctly. The biggest problem is that it is double handling the information in both the main loop and the chunk formatting function, leading to inconsistent updates and endless loops where progress is not made. To fix this, push the struct xfs_bulkstat_agichunk outwards to be the primary holder of user buffer information. this removes the double handling in the main loop. Also, pass the last inode processed by the chunk formatter as a separate parameter as it purely an output variable and is not related to the user buffer consumption cursor. Finally, the chunk formatting code is not shared by anyone, so make it local to xfs_itable.c. cc: <stable@vger.kernel.org> # 3.17 Signed-off-by: Dave Chinner <dchinner@redhat.com> Reviewed-by: Brian Foster <bfoster@redhat.com> Signed-off-by: Dave Chinner <david@fromorbit.com>
99 lines
3.1 KiB
C
99 lines
3.1 KiB
C
/*
|
|
* Copyright (c) 2000-2001 Silicon Graphics, Inc. All Rights Reserved.
|
|
*
|
|
* This program is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU General Public License as
|
|
* published by the Free Software Foundation.
|
|
*
|
|
* This program is distributed in the hope that it would be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write the Free Software Foundation,
|
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
*/
|
|
#ifndef __XFS_ITABLE_H__
|
|
#define __XFS_ITABLE_H__
|
|
|
|
/*
|
|
* xfs_bulkstat() is used to fill in xfs_bstat structures as well as dm_stat
|
|
* structures (by the dmi library). This is a pointer to a formatter function
|
|
* that will iget the inode and fill in the appropriate structure.
|
|
* see xfs_bulkstat_one() and xfs_dm_bulkstat_one() in dmapi_xfs.c
|
|
*/
|
|
typedef int (*bulkstat_one_pf)(struct xfs_mount *mp,
|
|
xfs_ino_t ino,
|
|
void __user *buffer,
|
|
int ubsize,
|
|
int *ubused,
|
|
int *stat);
|
|
|
|
/*
|
|
* Values for stat return value.
|
|
*/
|
|
#define BULKSTAT_RV_NOTHING 0
|
|
#define BULKSTAT_RV_DIDONE 1
|
|
#define BULKSTAT_RV_GIVEUP 2
|
|
|
|
/*
|
|
* Return stat information in bulk (by-inode) for the filesystem.
|
|
*/
|
|
int /* error status */
|
|
xfs_bulkstat(
|
|
xfs_mount_t *mp, /* mount point for filesystem */
|
|
xfs_ino_t *lastino, /* last inode returned */
|
|
int *count, /* size of buffer/count returned */
|
|
bulkstat_one_pf formatter, /* func that'd fill a single buf */
|
|
size_t statstruct_size,/* sizeof struct that we're filling */
|
|
char __user *ubuffer,/* buffer with inode stats */
|
|
int *done); /* 1 if there are more stats to get */
|
|
|
|
typedef int (*bulkstat_one_fmt_pf)( /* used size in bytes or negative error */
|
|
void __user *ubuffer, /* buffer to write to */
|
|
int ubsize, /* remaining user buffer sz */
|
|
int *ubused, /* bytes used by formatter */
|
|
const xfs_bstat_t *buffer); /* buffer to read from */
|
|
|
|
int
|
|
xfs_bulkstat_one_int(
|
|
xfs_mount_t *mp,
|
|
xfs_ino_t ino,
|
|
void __user *buffer,
|
|
int ubsize,
|
|
bulkstat_one_fmt_pf formatter,
|
|
int *ubused,
|
|
int *stat);
|
|
|
|
int
|
|
xfs_bulkstat_one(
|
|
xfs_mount_t *mp,
|
|
xfs_ino_t ino,
|
|
void __user *buffer,
|
|
int ubsize,
|
|
int *ubused,
|
|
int *stat);
|
|
|
|
typedef int (*inumbers_fmt_pf)(
|
|
void __user *ubuffer, /* buffer to write to */
|
|
const xfs_inogrp_t *buffer, /* buffer to read from */
|
|
long count, /* # of elements to read */
|
|
long *written); /* # of bytes written */
|
|
|
|
int
|
|
xfs_inumbers_fmt(
|
|
void __user *ubuffer, /* buffer to write to */
|
|
const xfs_inogrp_t *buffer, /* buffer to read from */
|
|
long count, /* # of elements to read */
|
|
long *written); /* # of bytes written */
|
|
|
|
int /* error status */
|
|
xfs_inumbers(
|
|
xfs_mount_t *mp, /* mount point for filesystem */
|
|
xfs_ino_t *last, /* last inode returned */
|
|
int *count, /* size of buffer/count returned */
|
|
void __user *buffer, /* buffer with inode info */
|
|
inumbers_fmt_pf formatter);
|
|
|
|
#endif /* __XFS_ITABLE_H__ */
|