Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 181814
b: refs/heads/master
c: d5db0f9
h: refs/heads/master
v: v3
  • Loading branch information
Eric Sandeen authored and Alex Elder committed Feb 8, 2010
1 parent eed9daf commit 88bcffd
Show file tree
Hide file tree
Showing 5 changed files with 65 additions and 26 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 388f1f0c346b533b06d8bc792f7204ebc3e4b7da
refs/heads/master: d5db0f97fbbeff11c88dec1aaf1536a975afbaeb
3 changes: 3 additions & 0 deletions trunk/fs/xfs/linux-2.6/xfs_ioctl.c
Original file line number Diff line number Diff line change
Expand Up @@ -1431,6 +1431,9 @@ xfs_file_ioctl(
if (!capable(CAP_SYS_ADMIN))
return -EPERM;

if (mp->m_flags & XFS_MOUNT_RDONLY)
return -XFS_ERROR(EROFS);

if (copy_from_user(&inout, arg, sizeof(inout)))
return -XFS_ERROR(EFAULT);

Expand Down
51 changes: 37 additions & 14 deletions trunk/fs/xfs/linux-2.6/xfs_super.c
Original file line number Diff line number Diff line change
Expand Up @@ -1256,6 +1256,29 @@ xfs_fs_statfs(
return 0;
}

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);
}

STATIC void
xfs_restore_resvblks(struct xfs_mount *mp)
{
__uint64_t resblks;

if (mp->m_resblks_save) {
resblks = mp->m_resblks_save;
mp->m_resblks_save = 0;
} else
resblks = xfs_default_resblks(mp);

xfs_reserve_blocks(mp, &resblks, NULL);
}

STATIC int
xfs_fs_remount(
struct super_block *sb,
Expand Down Expand Up @@ -1318,8 +1341,6 @@ xfs_fs_remount(

/* ro -> rw */
if ((mp->m_flags & XFS_MOUNT_RDONLY) && !(*flags & MS_RDONLY)) {
__uint64_t resblks;

mp->m_flags &= ~XFS_MOUNT_RDONLY;
if (mp->m_flags & XFS_MOUNT_BARRIER)
xfs_mountfs_check_barriers(mp);
Expand All @@ -1342,15 +1363,7 @@ xfs_fs_remount(
* Fill out the reserve pool if it is empty. Use the stashed
* value if it is non-zero, otherwise go with the default.
*/
if (mp->m_resblks_save) {
resblks = mp->m_resblks_save;
mp->m_resblks_save = 0;
} else {
resblks = mp->m_sb.sb_dblocks;
do_div(resblks, 20);
resblks = min_t(__uint64_t, resblks, 1024);
}
xfs_reserve_blocks(mp, &resblks, NULL);
xfs_restore_resvblks(mp);
}

/* rw -> ro */
Expand All @@ -1363,11 +1376,9 @@ xfs_fs_remount(
* so that if we get remounted rw, we can return it to the same
* size.
*/
__uint64_t resblks = 0;

xfs_quiesce_data(mp);
mp->m_resblks_save = mp->m_resblks;
xfs_reserve_blocks(mp, &resblks, NULL);
xfs_save_resvblks(mp);
xfs_quiesce_attr(mp);
mp->m_flags |= XFS_MOUNT_RDONLY;
}
Expand All @@ -1386,10 +1397,21 @@ xfs_fs_freeze(
{
struct xfs_mount *mp = XFS_M(sb);

xfs_save_resvblks(mp);
xfs_quiesce_attr(mp);
return -xfs_fs_log_dummy(mp);
}

STATIC int
xfs_fs_unfreeze(
struct super_block *sb)
{
struct xfs_mount *mp = XFS_M(sb);

xfs_restore_resvblks(mp);
return 0;
}

STATIC int
xfs_fs_show_options(
struct seq_file *m,
Expand Down Expand Up @@ -1612,6 +1634,7 @@ static const struct super_operations xfs_super_operations = {
.put_super = xfs_fs_put_super,
.sync_fs = xfs_fs_sync_fs,
.freeze_fs = xfs_fs_freeze,
.unfreeze_fs = xfs_fs_unfreeze,
.statfs = xfs_fs_statfs,
.remount_fs = xfs_fs_remount,
.show_options = xfs_fs_show_options,
Expand Down
34 changes: 23 additions & 11 deletions trunk/fs/xfs/xfs_mount.c
Original file line number Diff line number Diff line change
Expand Up @@ -1091,6 +1091,22 @@ xfs_mount_reset_sbqflags(
return xfs_trans_commit(tp, 0);
}

__uint64_t
xfs_default_resblks(xfs_mount_t *mp)
{
__uint64_t resblks;

/*
* We default to 5% or 1024 fsbs of space reserved, whichever is smaller.
* This may drive us straight to ENOSPC on mount, but that implies
* we were already there on the last unmount. Warn if this occurs.
*/
resblks = mp->m_sb.sb_dblocks;
do_div(resblks, 20);
resblks = min_t(__uint64_t, resblks, 1024);
return resblks;
}

/*
* This function does the following on an initial mount of a file system:
* - reads the superblock from disk and init the mount struct
Expand Down Expand Up @@ -1401,18 +1417,14 @@ xfs_mountfs(
* when at ENOSPC. This is needed for operations like create with
* attr, unwritten extent conversion at ENOSPC, etc. Data allocations
* are not allowed to use this reserved space.
*
* We default to 5% or 1024 fsbs of space reserved, whichever is smaller.
* This may drive us straight to ENOSPC on mount, but that implies
* we were already there on the last unmount. Warn if this occurs.
*/
resblks = mp->m_sb.sb_dblocks;
do_div(resblks, 20);
resblks = min_t(__uint64_t, resblks, 1024);
error = xfs_reserve_blocks(mp, &resblks, NULL);
if (error)
cmn_err(CE_WARN, "XFS: Unable to allocate reserve blocks. "
"Continuing without a reserve pool.");
if (!(mp->m_flags & XFS_MOUNT_RDONLY)) {
resblks = xfs_default_resblks(mp);
error = xfs_reserve_blocks(mp, &resblks, NULL);
if (error)
cmn_err(CE_WARN, "XFS: Unable to allocate reserve "
"blocks. Continuing without a reserve pool.");
}

return 0;

Expand Down
1 change: 1 addition & 0 deletions trunk/fs/xfs/xfs_mount.h
Original file line number Diff line number Diff line change
Expand Up @@ -421,6 +421,7 @@ typedef struct xfs_mod_sb {
} xfs_mod_sb_t;

extern int xfs_log_sbcount(xfs_mount_t *, uint);
extern __uint64_t xfs_default_resblks(xfs_mount_t *mp);
extern int xfs_mountfs(xfs_mount_t *mp);

extern void xfs_unmountfs(xfs_mount_t *);
Expand Down

0 comments on commit 88bcffd

Please sign in to comment.