From: Mingming Cao <cmm@us.ibm.com>
To: Mingming Cao <cmm@us.ibm.com>
Cc: Andrew Morton <akpm@osdl.org>,
tytso@mit.edu, pbadari@us.ibm.com, linux-kernel@vger.kernel.org,
ext2-devel@lists.sourceforge.net
Subject: [PATCH 3/4] ext3 block reservation patch set --mount and ioctl feature
Date: 13 Apr 2004 17:58:53 -0700 [thread overview]
Message-ID: <1081904335.4714.6847.camel@localhost.localdomain> (raw)
In-Reply-To: <1081903949.3548.6837.camel@localhost.localdomain>
[-- Attachment #1: Type: text/plain, Size: 844 bytes --]
> [patch 3]ext3_rsv_mount.patch: Adds features on top of the
> ext3_rsv_base.patch:
> - deal with earlier bogus -ENOSPC error
> - do block reservation only for regular file
> - make the ext3 reservation feature as a mount option:
> new mount option added: reservation
> - A pair of file ioctl commands are added for application to control
> the block reservation window size.
>
diffstat ext3_rsv_mount.patch
fs/ext3/balloc.c | 49
++++++++++++++++++++++++++++++++++++----------
fs/ext3/ialloc.c | 2 -
fs/ext3/inode.c | 2 -
fs/ext3/ioctl.c | 23 +++++++++++++++++++++
fs/ext3/super.c | 20 ++++++++++++++++--
include/linux/ext3_fs.h | 42
++++++++++++++++++++++-----------------
include/linux/ext3_fs_i.h | 2 -
7 files changed, 107 insertions(+), 33 deletions(-)
[-- Attachment #2: ext3_rsv_mount.patch --]
[-- Type: text/x-patch, Size: 12330 bytes --]
diff -urNp 264-rsv-cleanup-base/fs/ext3/balloc.c 264-rsv-cleanup-base-mount/fs/ext3/balloc.c
--- 264-rsv-cleanup-base/fs/ext3/balloc.c 2004-04-13 01:42:40.352200376 -0700
+++ 264-rsv-cleanup-base-mount/fs/ext3/balloc.c 2004-04-13 01:44:50.091477008 -0700
@@ -707,7 +707,7 @@ static int alloc_new_reservation(struct
else
start_block = goal + group_first_block;
- size = my_rsv->rsv_goal_size;
+ size = atomic_read(&my_rsv->rsv_goal_size);
/* if we have a old reservation, discard it first */
if (!rsv_is_empty(my_rsv)) {
/*
@@ -853,7 +853,16 @@ ext3_try_to_allocate_with_rsv(struct sup
return -1;
}
-#ifdef EXT3_RESERVATION
+ /*
+ * we don't deal with reservation when
+ * filesystem is mounted without reservation
+ * or the file is not a regular file
+ * of last attemp of allocating a block with reservation turn on failed
+ */
+ if (my_rsv == NULL ) {
+ ret = ext3_try_to_allocate(sb, handle, group, bitmap_bh, goal, NULL);
+ goto out;
+ }
rsv_lock = &EXT3_SB(sb)->s_rsv_window_lock;
/*
* goal is a group relative block number (if there is a goal)
@@ -895,10 +904,7 @@ ext3_try_to_allocate_with_rsv(struct sup
if (ret >= 0)
break; /* succeed */
}
-#else
- ret = ext3_try_to_allocate(sb, handle, group, bitmap_bh, goal, NULL);
-#endif
-
+out:
if (ret >= 0) {
BUFFER_TRACE(bitmap_bh, "journal_dirty_metadata for bitmap block");
fatal = ext3_journal_dirty_metadata(handle, bitmap_bh);
@@ -927,7 +933,7 @@ ext3_new_block(handle_t *handle, struct
{
struct buffer_head *bitmap_bh = NULL; /* bh */
struct buffer_head *gdp_bh; /* bh2 */
- int group_no; /* i */
+ int group_no, goal_group; /* i */
int ret_block; /* j */
int bgi; /* blockgroup iteration index */
int target_block; /* tmp */
@@ -938,7 +944,7 @@ ext3_new_block(handle_t *handle, struct
struct ext3_group_desc *gdp;
struct ext3_super_block *es;
struct ext3_sb_info *sbi;
- struct reserve_window *my_rsv = &EXT3_I(inode)->i_rsv_window;
+ struct reserve_window *my_rsv = NULL;
#ifdef EXT3FS_DEBUG
static int goal_hits, goal_attempts;
#endif
@@ -960,7 +966,10 @@ ext3_new_block(handle_t *handle, struct
sbi = EXT3_SB(sb);
es = EXT3_SB(sb)->s_es;
ext3_debug("goal=%lu.\n", goal);
-
+#ifdef EXT3_RESERVATION
+ if (test_opt(sb, RESERVATION) && S_ISREG(inode->i_mode))
+ my_rsv = &EXT3_I(inode)->i_rsv_window;
+#endif
free_blocks = percpu_counter_read_positive(&sbi->s_freeblocks_counter);
root_blocks = le32_to_cpu(es->s_r_blocks_count);
if (free_blocks < root_blocks + 1 && !capable(CAP_SYS_RESOURCE) &&
@@ -982,6 +991,8 @@ ext3_new_block(handle_t *handle, struct
if (!gdp)
goto io_error;
+ goal_group = group_no;
+retry:
free_blocks = le16_to_cpu(gdp->bg_free_blocks_count);
if (free_blocks > 0) {
ret_block = ((goal - le32_to_cpu(es->s_first_data_block)) %
@@ -1025,7 +1036,25 @@ ext3_new_block(handle_t *handle, struct
if (ret_block >= 0)
goto allocated;
}
-
+#ifdef EXT3_RESERVATION
+ /*
+ * We may end up a bogus ealier ENOSPC error due to
+ * filesystem is "full" of reservations, but
+ * there maybe indeed free blocks avaliable on disk
+ * In this case, we just forget about the reservations
+ * just do block allocation as without reservations.
+ */
+ if (my_rsv) {
+#ifdef EXT3_RESERVATION_DEBUG
+ printk("filesystem is full reserved. Actual free blocks is %d. "
+ "Try to do allocation without reservation, goal_group is %d\n",
+ free_blocks, goal_group);
+#endif
+ my_rsv = NULL;
+ group_no = goal_group;
+ goto retry;
+ }
+#endif
/* No space left on the device */
*errp = -ENOSPC;
goto out;
diff -urNp 264-rsv-cleanup-base/fs/ext3/ialloc.c 264-rsv-cleanup-base-mount/fs/ext3/ialloc.c
--- 264-rsv-cleanup-base/fs/ext3/ialloc.c 2004-04-06 01:54:16.000000000 -0700
+++ 264-rsv-cleanup-base-mount/fs/ext3/ialloc.c 2004-04-10 01:19:52.705503744 -0700
@@ -584,7 +584,7 @@ got:
ei->i_dtime = 0;
ei->i_rsv_window.rsv_start = 0;
ei->i_rsv_window.rsv_end= 0;
- ei->i_rsv_window.rsv_goal_size = EXT3_DEFAULT_RESERVE_BLOCKS;
+ atomic_set(&ei->i_rsv_window.rsv_goal_size, EXT3_DEFAULT_RESERVE_BLOCKS);
INIT_LIST_HEAD(&ei->i_rsv_window.rsv_list);
ei->i_block_group = group;
diff -urNp 264-rsv-cleanup-base/fs/ext3/inode.c 264-rsv-cleanup-base-mount/fs/ext3/inode.c
--- 264-rsv-cleanup-base/fs/ext3/inode.c 2004-04-06 01:56:16.000000000 -0700
+++ 264-rsv-cleanup-base-mount/fs/ext3/inode.c 2004-04-10 01:19:52.712502680 -0700
@@ -2452,7 +2452,7 @@ void ext3_read_inode(struct inode * inod
ei->i_block_group = iloc.block_group;
ei->i_rsv_window.rsv_start = 0;
ei->i_rsv_window.rsv_end= 0;
- ei->i_rsv_window.rsv_goal_size = EXT3_DEFAULT_RESERVE_BLOCKS;
+ atomic_set(&ei->i_rsv_window.rsv_goal_size, EXT3_DEFAULT_RESERVE_BLOCKS);
INIT_LIST_HEAD(&ei->i_rsv_window.rsv_list);
/*
* NOTE! The in-memory inode i_data array is in little-endian order
diff -urNp 264-rsv-cleanup-base/fs/ext3/ioctl.c 264-rsv-cleanup-base-mount/fs/ext3/ioctl.c
--- 264-rsv-cleanup-base/fs/ext3/ioctl.c 2004-04-06 00:30:07.000000000 -0700
+++ 264-rsv-cleanup-base-mount/fs/ext3/ioctl.c 2004-04-10 01:19:52.713502528 -0700
@@ -20,6 +20,7 @@ int ext3_ioctl (struct inode * inode, st
{
struct ext3_inode_info *ei = EXT3_I(inode);
unsigned int flags;
+ unsigned short rsv_window_size;
ext3_debug ("cmd = %u, arg = %lu\n", cmd, arg);
@@ -151,6 +152,28 @@ flags_err:
return ret;
}
#endif
+#ifdef EXT3_RESERVATION
+ case EXT3_IOC_GETRSVSZ:
+ rsv_window_size = atomic_read(&ei->i_rsv_window.rsv_goal_size);
+ return put_user(rsv_window_size, (int *) arg);
+ return 0;
+ case EXT3_IOC_SETRSVSZ:
+ {
+ if (IS_RDONLY(inode))
+ return -EROFS;
+
+ if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER))
+ return -EACCES;
+
+ if (get_user(rsv_window_size, (int *) arg))
+ return -EFAULT;
+
+ if (rsv_window_size > EXT3_MAX_RESERVE_BLOCKS)
+ rsv_window_size = EXT3_MAX_RESERVE_BLOCKS;
+ atomic_set(&ei->i_rsv_window.rsv_goal_size, rsv_window_size);
+ return 0;
+ }
+#endif
default:
return -ENOTTY;
}
diff -urNp 264-rsv-cleanup-base/fs/ext3/super.c 264-rsv-cleanup-base-mount/fs/ext3/super.c
--- 264-rsv-cleanup-base/fs/ext3/super.c 2004-04-06 01:50:03.000000000 -0700
+++ 264-rsv-cleanup-base-mount/fs/ext3/super.c 2004-04-10 01:19:52.719501616 -0700
@@ -533,7 +533,8 @@ enum {
Opt_bsd_df, Opt_minix_df, Opt_grpid, Opt_nogrpid,
Opt_resgid, Opt_resuid, Opt_sb, Opt_err_cont, Opt_err_panic, Opt_err_ro,
Opt_nouid32, Opt_check, Opt_nocheck, Opt_debug, Opt_oldalloc, Opt_orlov,
- Opt_user_xattr, Opt_nouser_xattr, Opt_acl, Opt_noacl, Opt_noload,
+ Opt_user_xattr, Opt_nouser_xattr, Opt_acl, Opt_noacl,
+ Opt_reservation, Opt_noreservation, Opt_noload,
Opt_commit, Opt_journal_update, Opt_journal_inum,
Opt_abort, Opt_data_journal, Opt_data_ordered, Opt_data_writeback,
Opt_ignore, Opt_err,
@@ -563,6 +564,8 @@ static match_table_t tokens = {
{Opt_nouser_xattr, "nouser_xattr"},
{Opt_acl, "acl"},
{Opt_noacl, "noacl"},
+ {Opt_reservation, "reservation"},
+ {Opt_noreservation, "noreservation"},
{Opt_noload, "noload"},
{Opt_commit, "commit=%u"},
{Opt_journal_update, "journal=update"},
@@ -706,6 +709,19 @@ static int parse_options (char * options
printk("EXT3 (no)acl options not supported\n");
break;
#endif
+#ifdef EXT3_RESERVATION
+ case Opt_reservation:
+ set_opt(sbi->s_mount_opt, RESERVATION);
+ break;
+ case Opt_noreservation:
+ clear_opt(sbi->s_mount_opt, RESERVATION);
+ break;
+#else
+ case Opt_reservation:
+ case Opt_noreservation:
+ printk("EXT3 block reservation options not supported\n");
+ break;
+#endif
case Opt_journal_update:
/* @@@ FIXME */
/* Eventually we will want to be able to create
@@ -1296,7 +1312,7 @@ static int ext3_fill_super (struct super
INIT_LIST_HEAD(&sbi->s_rsv_window_head.rsv_list);
sbi->s_rsv_window_head.rsv_start = 0;
sbi->s_rsv_window_head.rsv_end = 0;
- sbi->s_rsv_window_head.rsv_goal_size = 0;
+ atomic_set(&sbi->s_rsv_window_head.rsv_goal_size, 0);
/*
* set up enough so that it can read an inode
diff -urNp 264-rsv-cleanup-base/include/linux/ext3_fs.h 264-rsv-cleanup-base-mount/include/linux/ext3_fs.h
--- 264-rsv-cleanup-base/include/linux/ext3_fs.h 2004-04-06 01:59:01.000000000 -0700
+++ 264-rsv-cleanup-base-mount/include/linux/ext3_fs.h 2004-04-13 01:43:53.159132040 -0700
@@ -37,6 +37,7 @@ struct statfs;
*/
#define EXT3_RESERVATION
#define EXT3_DEFAULT_RESERVE_BLOCKS 8
+#define EXT3_MAX_RESERVE_BLOCKS 1024
/*
* Always enable hashed directories
*/
@@ -207,6 +208,10 @@ struct ext3_group_desc
#ifdef CONFIG_JBD_DEBUG
#define EXT3_IOC_WAIT_FOR_READONLY _IOR('f', 99, long)
#endif
+#ifdef EXT3_RESERVATION
+#define EXT3_IOC_GETRSVSZ _IOR('r', 1, long)
+#define EXT3_IOC_SETRSVSZ _IOW('r', 2, long)
+#endif
/*
* Structure of an inode on the disk
@@ -305,24 +310,25 @@ struct ext3_inode {
/*
* Mount flags
*/
-#define EXT3_MOUNT_CHECK 0x0001 /* Do mount-time checks */
-#define EXT3_MOUNT_OLDALLOC 0x0002 /* Don't use the new Orlov allocator */
-#define EXT3_MOUNT_GRPID 0x0004 /* Create files with directory's group */
-#define EXT3_MOUNT_DEBUG 0x0008 /* Some debugging messages */
-#define EXT3_MOUNT_ERRORS_CONT 0x0010 /* Continue on errors */
-#define EXT3_MOUNT_ERRORS_RO 0x0020 /* Remount fs ro on errors */
-#define EXT3_MOUNT_ERRORS_PANIC 0x0040 /* Panic on errors */
-#define EXT3_MOUNT_MINIX_DF 0x0080 /* Mimics the Minix statfs */
-#define EXT3_MOUNT_NOLOAD 0x0100 /* Don't use existing journal*/
-#define EXT3_MOUNT_ABORT 0x0200 /* Fatal error detected */
-#define EXT3_MOUNT_DATA_FLAGS 0x0C00 /* Mode for data writes: */
- #define EXT3_MOUNT_JOURNAL_DATA 0x0400 /* Write data to journal */
- #define EXT3_MOUNT_ORDERED_DATA 0x0800 /* Flush data before commit */
- #define EXT3_MOUNT_WRITEBACK_DATA 0x0C00 /* No data ordering */
-#define EXT3_MOUNT_UPDATE_JOURNAL 0x1000 /* Update the journal format */
-#define EXT3_MOUNT_NO_UID32 0x2000 /* Disable 32-bit UIDs */
-#define EXT3_MOUNT_XATTR_USER 0x4000 /* Extended user attributes */
-#define EXT3_MOUNT_POSIX_ACL 0x8000 /* POSIX Access Control Lists */
+#define EXT3_MOUNT_CHECK 0x00001 /* Do mount-time checks */
+#define EXT3_MOUNT_OLDALLOC 0x00002 /* Don't use the new Orlov allocator */
+#define EXT3_MOUNT_GRPID 0x00004 /* Create files with directory's group */
+#define EXT3_MOUNT_DEBUG 0x00008 /* Some debugging messages */
+#define EXT3_MOUNT_ERRORS_CONT 0x00010 /* Continue on errors */
+#define EXT3_MOUNT_ERRORS_RO 0x00020 /* Remount fs ro on errors */
+#define EXT3_MOUNT_ERRORS_PANIC 0x00040 /* Panic on errors */
+#define EXT3_MOUNT_MINIX_DF 0x00080 /* Mimics the Minix statfs */
+#define EXT3_MOUNT_NOLOAD 0x00100 /* Don't use existing journal*/
+#define EXT3_MOUNT_ABORT 0x00200 /* Fatal error detected */
+#define EXT3_MOUNT_DATA_FLAGS 0x00C00 /* Mode for data writes: */
+#define EXT3_MOUNT_JOURNAL_DATA 0x00400 /* Write data to journal */
+#define EXT3_MOUNT_ORDERED_DATA 0x00800 /* Flush data before commit */
+#define EXT3_MOUNT_WRITEBACK_DATA 0x00C00 /* No data ordering */
+#define EXT3_MOUNT_UPDATE_JOURNAL 0x01000 /* Update the journal format */
+#define EXT3_MOUNT_NO_UID32 0x02000 /* Disable 32-bit UIDs */
+#define EXT3_MOUNT_XATTR_USER 0x04000 /* Extended user attributes */
+#define EXT3_MOUNT_POSIX_ACL 0x08000 /* POSIX Access Control Lists */
+#define EXT3_MOUNT_RESERVATION 0x10000 /* Preallocation */
/* Compatibility, for having both ext2_fs.h and ext3_fs.h included at once */
#ifndef _LINUX_EXT2_FS_H
diff -urNp 264-rsv-cleanup-base/include/linux/ext3_fs_i.h 264-rsv-cleanup-base-mount/include/linux/ext3_fs_i.h
--- 264-rsv-cleanup-base/include/linux/ext3_fs_i.h 2004-04-06 02:00:35.000000000 -0700
+++ 264-rsv-cleanup-base-mount/include/linux/ext3_fs_i.h 2004-04-10 01:19:52.723501008 -0700
@@ -22,7 +22,7 @@ struct reserve_window{
struct list_head rsv_list;
__u32 rsv_start;
__u32 rsv_end;
- unsigned short rsv_goal_size;
+ atomic_t rsv_goal_size;
};
/*
next prev parent reply other threads:[~2004-04-14 0:52 UTC|newest]
Thread overview: 28+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <200403190846.56955.pbadari@us.ibm.com>
[not found] ` <20040321015746.14b3c0dc.akpm@osdl.org>
2004-03-30 8:55 ` [RFC, PATCH] Reservation based ext3 preallocation Mingming Cao
2004-03-30 9:45 ` Andrew Morton
2004-03-30 17:07 ` Badari Pulavarty
2004-03-30 17:12 ` [Ext2-devel] " Alex Tomas
2004-03-30 18:07 ` Badari Pulavarty
2004-03-30 18:23 ` Mingming Cao
2004-03-30 18:36 ` Andrew Morton
2004-04-03 1:45 ` [Ext2-devel] " Mingming Cao
2004-04-03 1:50 ` Andrew Morton
2004-04-03 2:37 ` Mingming Cao
2004-04-03 2:50 ` Andrew Morton
2004-04-05 16:49 ` Mingming Cao
2004-04-14 0:52 ` [PATCH 0/4] ext3 block reservation patch set Mingming Cao
2004-04-14 0:54 ` [PATCH 1/4] ext3 block reservation patch set -- ext3 preallocation cleanup Mingming Cao
2004-04-14 0:57 ` [PATCH 2/4] ext3 block reservation patch set --ext3 block reservation Mingming Cao
2004-04-14 0:58 ` Mingming Cao [this message]
2004-04-14 1:00 ` [PATCH 4/4] ext3 block reservation patch set -- dynamically increase reservation window Mingming Cao
2004-04-14 2:47 ` [PATCH 0/4] ext3 block reservation patch set Andrew Morton
2004-04-14 16:11 ` Badari Pulavarty
2004-04-14 17:44 ` Mingming Cao
2004-04-14 23:02 ` Andrew Morton
2004-04-14 23:12 ` Badari Pulavarty
2004-04-14 16:42 ` Badari Pulavarty
2004-04-14 17:30 ` Mingming Cao
2004-04-14 23:07 ` Andrew Morton
2004-04-14 23:42 ` Mingming Cao
2004-04-21 23:34 ` [PATCH] Lazy discard ext3 reservation window patch Mingming Cao
2004-04-27 15:19 ` [PATCH 0/4] ext3 block reservation patch set Mary Edie Meredith
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1081904335.4714.6847.camel@localhost.localdomain \
--to=cmm@us.ibm.com \
--cc=akpm@osdl.org \
--cc=ext2-devel@lists.sourceforge.net \
--cc=linux-kernel@vger.kernel.org \
--cc=pbadari@us.ibm.com \
--cc=tytso@mit.edu \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.