Skip to content

Commit

Permalink
[PATCH 1/2] ocfs2: Add group extend for online resize
Browse files Browse the repository at this point in the history
This patch adds the ability for a userspace program to request an extend of
last cluster group on an Ocfs2 file system. The request is made via ioctl,
OCFS2_IOC_GROUP_EXTEND. This is derived from EXT3_IOC_GROUP_EXTEND, but is
obviously Ocfs2 specific.

tunefs.ocfs2 would call this for an online-resize operation if the last
cluster group isn't full.

Signed-off-by: Tao Ma <tao.ma@oracle.com>
Signed-off-by: Mark Fasheh <mark.fasheh@oracle.com>
  • Loading branch information
Tao Ma authored and Mark Fasheh committed Jan 25, 2008
1 parent 7f68fc2 commit d659072
Show file tree
Hide file tree
Showing 10 changed files with 518 additions and 7 deletions.
1 change: 1 addition & 0 deletions fs/ocfs2/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ ocfs2-objs := \
localalloc.o \
mmap.o \
namei.o \
resize.o \
slot_map.o \
suballoc.o \
super.o \
Expand Down
61 changes: 61 additions & 0 deletions fs/ocfs2/buffer_head_io.c
Original file line number Diff line number Diff line change
Expand Up @@ -280,3 +280,64 @@ int ocfs2_read_blocks(struct ocfs2_super *osb, u64 block, int nr,
mlog_exit(status);
return status;
}

/* Check whether the blkno is the super block or one of the backups. */
static void ocfs2_check_super_or_backup(struct super_block *sb,
sector_t blkno)
{
int i;
u64 backup_blkno;

if (blkno == OCFS2_SUPER_BLOCK_BLKNO)
return;

for (i = 0; i < OCFS2_MAX_BACKUP_SUPERBLOCKS; i++) {
backup_blkno = ocfs2_backup_super_blkno(sb, i);
if (backup_blkno == blkno)
return;
}

BUG();
}

/*
* Write super block and backups doesn't need to collaborate with journal,
* so we don't need to lock ip_io_mutex and inode doesn't need to bea passed
* into this function.
*/
int ocfs2_write_super_or_backup(struct ocfs2_super *osb,
struct buffer_head *bh)
{
int ret = 0;

mlog_entry_void();

BUG_ON(buffer_jbd(bh));
ocfs2_check_super_or_backup(osb->sb, bh->b_blocknr);

if (ocfs2_is_hard_readonly(osb) || ocfs2_is_soft_readonly(osb)) {
ret = -EROFS;
goto out;
}

lock_buffer(bh);
set_buffer_uptodate(bh);

/* remove from dirty list before I/O. */
clear_buffer_dirty(bh);

get_bh(bh); /* for end_buffer_write_sync() */
bh->b_end_io = end_buffer_write_sync;
submit_bh(WRITE, bh);

wait_on_buffer(bh);

if (!buffer_uptodate(bh)) {
ret = -EIO;
brelse(bh);
}

out:
mlog_exit(ret);
return ret;
}
2 changes: 2 additions & 0 deletions fs/ocfs2/buffer_head_io.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ int ocfs2_read_blocks(struct ocfs2_super *osb,
int flags,
struct inode *inode);

int ocfs2_write_super_or_backup(struct ocfs2_super *osb,
struct buffer_head *bh);

#define OCFS2_BH_CACHED 1
#define OCFS2_BH_READAHEAD 8
Expand Down
8 changes: 8 additions & 0 deletions fs/ocfs2/ioctl.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@

#include "ocfs2_fs.h"
#include "ioctl.h"
#include "resize.h"

#include <linux/ext2_fs.h>

Expand Down Expand Up @@ -115,6 +116,7 @@ int ocfs2_ioctl(struct inode * inode, struct file * filp,
unsigned int cmd, unsigned long arg)
{
unsigned int flags;
int new_clusters;
int status;
struct ocfs2_space_resv sr;

Expand All @@ -140,6 +142,11 @@ int ocfs2_ioctl(struct inode * inode, struct file * filp,
return -EFAULT;

return ocfs2_change_file_space(filp, cmd, &sr);
case OCFS2_IOC_GROUP_EXTEND:
if (get_user(new_clusters, (int __user *)arg))
return -EFAULT;

return ocfs2_group_extend(inode, new_clusters);
default:
return -ENOTTY;
}
Expand All @@ -162,6 +169,7 @@ long ocfs2_compat_ioctl(struct file *file, unsigned cmd, unsigned long arg)
case OCFS2_IOC_RESVSP64:
case OCFS2_IOC_UNRESVSP:
case OCFS2_IOC_UNRESVSP64:
case OCFS2_IOC_GROUP_EXTEND:
break;
default:
return -ENOIOCTLCMD;
Expand Down
3 changes: 3 additions & 0 deletions fs/ocfs2/journal.h
Original file line number Diff line number Diff line change
Expand Up @@ -278,6 +278,9 @@ int ocfs2_journal_dirty_data(handle_t *handle,
/* simple file updates like chmod, etc. */
#define OCFS2_INODE_UPDATE_CREDITS 1

/* group extend. inode update and last group update. */
#define OCFS2_GROUP_EXTEND_CREDITS (OCFS2_INODE_UPDATE_CREDITS + 1)

/* get one bit out of a suballocator: dinode + group descriptor +
* prev. group desc. if we relink. */
#define OCFS2_SUBALLOC_ALLOC (3)
Expand Down
2 changes: 2 additions & 0 deletions fs/ocfs2/ocfs2_fs.h
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,8 @@ struct ocfs2_space_resv {
#define OCFS2_IOC_RESVSP64 _IOW ('X', 42, struct ocfs2_space_resv)
#define OCFS2_IOC_UNRESVSP64 _IOW ('X', 43, struct ocfs2_space_resv)

#define OCFS2_IOC_GROUP_EXTEND _IOW('o', 1, int)

/*
* Journal Flags (ocfs2_dinode.id1.journal1.i_flags)
*/
Expand Down
Loading

0 comments on commit d659072

Please sign in to comment.