}
/*
- * exported through ioctl XFS_IOC_SET_RESBLKS & XFS_IOC_GET_RESBLKS
- *
- * xfs_reserve_blocks is called to set m_resblks
- * in the in-core mount table. The number of unused reserved blocks
- * is kept in m_resblks_avail.
- *
* Reserve the requested number of blocks if available. Otherwise return
* as many as possible to satisfy the request. The actual number
- * reserved are returned in outval
- *
- * A null inval pointer indicates that only the current reserved blocks
- * available should be returned no settings are changed.
+ * reserved are returned in outval.
*/
-
int
xfs_reserve_blocks(
- xfs_mount_t *mp,
- uint64_t *inval,
- xfs_fsop_resblks_t *outval)
+ struct xfs_mount *mp,
+ uint64_t request)
{
int64_t lcounter, delta;
int64_t fdblks_delta = 0;
- uint64_t request;
int64_t free;
int error = 0;
- /* If inval is null, report current values and return */
- if (inval == (uint64_t *)NULL) {
- if (!outval)
- return -EINVAL;
- outval->resblks = mp->m_resblks;
- outval->resblks_avail = mp->m_resblks_avail;
- return 0;
- }
-
- request = *inval;
-
/*
* With per-cpu counters, this becomes an interesting problem. we need
* to work out if we are freeing or allocation blocks first, then we can
spin_lock(&mp->m_sb_lock);
}
out:
- if (outval) {
- outval->resblks = mp->m_resblks;
- outval->resblks_avail = mp->m_resblks_avail;
- }
-
spin_unlock(&mp->m_sb_lock);
return error;
}
extern int xfs_growfs_data(struct xfs_mount *mp, struct xfs_growfs_data *in);
extern int xfs_growfs_log(struct xfs_mount *mp, struct xfs_growfs_log *in);
-extern int xfs_reserve_blocks(xfs_mount_t *mp, uint64_t *inval,
- xfs_fsop_resblks_t *outval);
+int xfs_reserve_blocks(struct xfs_mount *mp, uint64_t request);
extern int xfs_fs_goingdown(xfs_mount_t *mp, uint32_t inflags);
extern int xfs_fs_reserve_ag_blocks(struct xfs_mount *mp);
struct xfs_mount *mp = XFS_I(file_inode(filp))->i_mount;
struct xfs_fsop_resblks fsop = { };
int error;
- uint64_t in;
if (!capable(CAP_SYS_ADMIN))
return -EPERM;
error = mnt_want_write_file(filp);
if (error)
return error;
- in = fsop.resblks;
- error = xfs_reserve_blocks(mp, &in, &fsop);
+ error = xfs_reserve_blocks(mp, fsop.resblks);
mnt_drop_write_file(filp);
if (error)
return error;
- } else {
- error = xfs_reserve_blocks(mp, NULL, &fsop);
- if (error)
- return error;
}
+ spin_lock(&mp->m_sb_lock);
+ fsop.resblks = mp->m_resblks;
+ fsop.resblks_avail = mp->m_resblks_avail;
+ spin_unlock(&mp->m_sb_lock);
+
if (copy_to_user(arg, &fsop, sizeof(fsop)))
return -EFAULT;
return 0;
struct xfs_sb *sbp = &(mp->m_sb);
struct xfs_inode *rip;
struct xfs_ino_geometry *igeo = M_IGEO(mp);
- uint64_t resblks;
uint quotamount = 0;
uint quotaflags = 0;
int error = 0;
* we were already there on the last unmount. Warn if this occurs.
*/
if (!xfs_is_readonly(mp)) {
- resblks = xfs_default_resblks(mp);
- error = xfs_reserve_blocks(mp, &resblks, NULL);
+ error = xfs_reserve_blocks(mp, xfs_default_resblks(mp));
if (error)
xfs_warn(mp,
"Unable to allocate reserve blocks. Continuing without reserve pool.");
xfs_unmountfs(
struct xfs_mount *mp)
{
- uint64_t resblks;
int error;
/*
* we only every apply deltas to the superblock and hence the incore
* value does not matter....
*/
- resblks = 0;
- error = xfs_reserve_blocks(mp, &resblks, NULL);
+ error = xfs_reserve_blocks(mp, 0);
if (error)
xfs_warn(mp, "Unable to free reserved block pool. "
"Freespace may not be correct on next mount.");
STATIC void
xfs_save_resvblks(struct xfs_mount *mp)
{
- uint64_t resblks = 0;
-
mp->m_resblks_save = mp->m_resblks;
- xfs_reserve_blocks(mp, &resblks, NULL);
+ xfs_reserve_blocks(mp, 0);
}
STATIC void
} else
resblks = xfs_default_resblks(mp);
- xfs_reserve_blocks(mp, &resblks, NULL);
+ xfs_reserve_blocks(mp, resblks);
}
/*