Tristan Ye
2010-Jan-08 08:51 UTC
[Ocfs2-devel] [PATCH 1/2] Ocfs2: Move ocfs2 ioctl definitions from ocfs2_fs.h to new added ocfs2_ioctl.h.
Currently we were adding ioctl cmds/structures for ocfs2 into ocfs2_fs.h which was used for define ocfs2 on-disk layout. That sounds a little bit confusing, and it may be quickly polluted espcially when growing the ocfs2_info_request ioctls afterwards(it will grow i bet). As a result, such OCFS2 IOCs do need to be placed somewhere other than ocfs2_fs.h, a separated ocfs2_ioctl.h will be added to store such ioctl structures and definitions which could also be used from userspace to invoke the ioctls. What's more, the patch also introduces new structures and definitions for the new OCFS2_IOC_INFO. Signed-off-by: Tristan Ye <tristan.ye at oracle.com> --- fs/ocfs2/file.h | 2 + fs/ocfs2/ioctl.h | 6 +- fs/ocfs2/ocfs2_fs.h | 57 -------------- fs/ocfs2/ocfs2_ioctl.h | 195 ++++++++++++++++++++++++++++++++++++++++++++++++ fs/ocfs2/resize.c | 1 + 5 files changed, 201 insertions(+), 60 deletions(-) create mode 100644 fs/ocfs2/ocfs2_ioctl.h diff --git a/fs/ocfs2/file.h b/fs/ocfs2/file.h index d66cf4f..eb891db 100644 --- a/fs/ocfs2/file.h +++ b/fs/ocfs2/file.h @@ -26,6 +26,8 @@ #ifndef OCFS2_FILE_H #define OCFS2_FILE_H +#include "ocfs2_ioctl.h" + extern const struct file_operations ocfs2_fops; extern const struct file_operations ocfs2_dops; extern const struct file_operations ocfs2_fops_no_plocks; diff --git a/fs/ocfs2/ioctl.h b/fs/ocfs2/ioctl.h index cf9a5ee..0cd5323 100644 --- a/fs/ocfs2/ioctl.h +++ b/fs/ocfs2/ioctl.h @@ -7,10 +7,10 @@ * */ -#ifndef OCFS2_IOCTL_H -#define OCFS2_IOCTL_H +#ifndef OCFS2_IOCTL_PROTO_H +#define OCFS2_IOCTL_PROTO_H long ocfs2_ioctl(struct file *filp, unsigned int cmd, unsigned long arg); long ocfs2_compat_ioctl(struct file *file, unsigned cmd, unsigned long arg); -#endif /* OCFS2_IOCTL_H */ +#endif /* OCFS2_IOCTL_PROTO_H */ diff --git a/fs/ocfs2/ocfs2_fs.h b/fs/ocfs2/ocfs2_fs.h index e9431e4..54e1de0 100644 --- a/fs/ocfs2/ocfs2_fs.h +++ b/fs/ocfs2/ocfs2_fs.h @@ -254,63 +254,6 @@ * refcount tree */ /* - * ioctl commands - */ -#define OCFS2_IOC_GETFLAGS _IOR('f', 1, long) -#define OCFS2_IOC_SETFLAGS _IOW('f', 2, long) -#define OCFS2_IOC32_GETFLAGS _IOR('f', 1, int) -#define OCFS2_IOC32_SETFLAGS _IOW('f', 2, int) - -/* - * Space reservation / allocation / free ioctls and argument structure - * are designed to be compatible with XFS. - * - * ALLOCSP* and FREESP* are not and will never be supported, but are - * included here for completeness. - */ -struct ocfs2_space_resv { - __s16 l_type; - __s16 l_whence; - __s64 l_start; - __s64 l_len; /* len == 0 means until end of file */ - __s32 l_sysid; - __u32 l_pid; - __s32 l_pad[4]; /* reserve area */ -}; - -#define OCFS2_IOC_ALLOCSP _IOW ('X', 10, struct ocfs2_space_resv) -#define OCFS2_IOC_FREESP _IOW ('X', 11, struct ocfs2_space_resv) -#define OCFS2_IOC_RESVSP _IOW ('X', 40, struct ocfs2_space_resv) -#define OCFS2_IOC_UNRESVSP _IOW ('X', 41, struct ocfs2_space_resv) -#define OCFS2_IOC_ALLOCSP64 _IOW ('X', 36, struct ocfs2_space_resv) -#define OCFS2_IOC_FREESP64 _IOW ('X', 37, 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) - -/* Used to pass group descriptor data when online resize is done */ -struct ocfs2_new_group_input { - __u64 group; /* Group descriptor's blkno. */ - __u32 clusters; /* Total number of clusters in this group */ - __u32 frees; /* Total free clusters in this group */ - __u16 chain; /* Chain for this group */ - __u16 reserved1; - __u32 reserved2; -}; - -#define OCFS2_IOC_GROUP_EXTEND _IOW('o', 1, int) -#define OCFS2_IOC_GROUP_ADD _IOW('o', 2,struct ocfs2_new_group_input) -#define OCFS2_IOC_GROUP_ADD64 _IOW('o', 3,struct ocfs2_new_group_input) - -/* Used to pass 2 file names to reflink. */ -struct reflink_arguments { - __u64 old_path; - __u64 new_path; - __u64 preserve; -}; -#define OCFS2_IOC_REFLINK _IOW('o', 4, struct reflink_arguments) - - -/* * Journal Flags (ocfs2_dinode.id1.journal1.i_flags) */ #define OCFS2_JOURNAL_DIRTY_FL (0x00000001) /* Journal needs recovery */ diff --git a/fs/ocfs2/ocfs2_ioctl.h b/fs/ocfs2/ocfs2_ioctl.h new file mode 100644 index 0000000..e15c84d --- /dev/null +++ b/fs/ocfs2/ocfs2_ioctl.h @@ -0,0 +1,195 @@ +/* -*- mode: c; c-basic-offset: 8; -*- + * vim: noexpandtab sw=8 ts=8 sts=0: + * + * ocfs2_ioctl.h + * + * Defines OCFS2 ioctls. + * + * Copyright (C) 2009 Oracle. 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, version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will 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. + */ + +#ifndef OCFS2_IOCTL_H +#define OCFS2_IOCTL_H + +/* + * ioctl commands + */ +#define OCFS2_IOC_GETFLAGS _IOR('f', 1, long) +#define OCFS2_IOC_SETFLAGS _IOW('f', 2, long) +#define OCFS2_IOC32_GETFLAGS _IOR('f', 1, int) +#define OCFS2_IOC32_SETFLAGS _IOW('f', 2, int) + +/* + * Space reservation / allocation / free ioctls and argument structure + * are designed to be compatible with XFS. + * + * ALLOCSP* and FREESP* are not and will never be supported, but are + * included here for completeness. + */ +struct ocfs2_space_resv { + __s16 l_type; + __s16 l_whence; + __s64 l_start; + __s64 l_len; /* len == 0 means until end of file */ + __s32 l_sysid; + __u32 l_pid; + __s32 l_pad[4]; /* reserve area */ +}; + +#define OCFS2_IOC_ALLOCSP _IOW ('X', 10, struct ocfs2_space_resv) +#define OCFS2_IOC_FREESP _IOW ('X', 11, struct ocfs2_space_resv) +#define OCFS2_IOC_RESVSP _IOW ('X', 40, struct ocfs2_space_resv) +#define OCFS2_IOC_UNRESVSP _IOW ('X', 41, struct ocfs2_space_resv) +#define OCFS2_IOC_ALLOCSP64 _IOW ('X', 36, struct ocfs2_space_resv) +#define OCFS2_IOC_FREESP64 _IOW ('X', 37, 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) + +/* Used to pass group descriptor data when online resize is done */ +struct ocfs2_new_group_input { + __u64 group; /* Group descriptor's blkno. */ + __u32 clusters; /* Total number of clusters in this group */ + __u32 frees; /* Total free clusters in this group */ + __u16 chain; /* Chain for this group */ + __u16 reserved1; + __u32 reserved2; +}; + +#define OCFS2_IOC_GROUP_EXTEND _IOW('o', 1, int) +#define OCFS2_IOC_GROUP_ADD _IOW('o', 2,struct ocfs2_new_group_input) +#define OCFS2_IOC_GROUP_ADD64 _IOW('o', 3,struct ocfs2_new_group_input) + +/* Used to pass 2 file names to reflink. */ +struct reflink_arguments { + __u64 old_path; + __u64 new_path; + __u64 preserve; +}; +#define OCFS2_IOC_REFLINK _IOW('o', 4, struct reflink_arguments) + + +/* Following definitions dedicated for ocfs2_info_request ioctls. */ + +#define OCFS2_INFO_VOL_UUID_LEN (16) +#define OCFS2_INFO_MAX_VOL_LABEL_LEN (64) +#define OCFS2_INFO_VOL_UUIDSTR_LEN (OCFS2_INFO_VOL_UUID_LEN * 2 + 1) +#define OCFS2_INFO_MAX_SLOTS (255) +#define OCFS2_INFO_MAX_HIST (32) + +#define OCFS2_INFO_MAX_REQUEST (50) + +/* Magic number of all requests */ +#define OCFS2_INFO_MAGIC (0x4F32494E) + +/* + * Always try to separate info request into small pieces to + * guarantee the backward&forward compatibility. + */ + +struct ocfs2_info { + __u64 info_requests; /* Array of __u64 pointers to requests */ + __u32 info_count; /* Number of requests in info_requests */ +}; + +struct ocfs2_info_request { +/*00*/ __u32 ir_magic; /* Magic number */ + __u32 ir_code; /* Info request code */ + __u32 ir_size; /* Size of request */ + __u32 ir_flags; /* Request flags */ +/*10*/ /* Request specific fields */ +}; + +struct ocfs2_info_clustersize { + struct ocfs2_info_request ir_request; + __u32 ir_clustersize; +}; + +struct ocfs2_info_blocksize { + struct ocfs2_info_request ir_request; + __u32 ir_blocksize; +}; + +struct ocfs2_info_slotnum { + struct ocfs2_info_request ir_request; + __u16 ir_slotnum; +}; + +struct ocfs2_info_label { + struct ocfs2_info_request ir_request; + __u8 ir_label[OCFS2_INFO_MAX_VOL_LABEL_LEN]; +}; + +struct ocfs2_info_uuid { + struct ocfs2_info_request ir_request; + __u8 ir_uuid_str[OCFS2_INFO_VOL_UUIDSTR_LEN]; +}; + +struct ocfs2_info_fs_features { + struct ocfs2_info_request ir_request; + __u32 ir_compat_features; + __u32 ir_incompat_features; + __u32 ir_ro_compat_features; +}; + +struct ocfs2_info_freefrag { + struct ocfs2_info_request ir_request; + __u32 ir_chunksize; /* chunksize in clusters(in) */ + struct ocfs2_info_freefrag_stats { /* (out) */ + __u32 ir_clusters; + __u32 ir_free_clusters; + __u32 ir_free_chunks; + __u32 ir_free_chunks_real; + __u32 ir_min; /* Minimum free chunksize in clusters */ + __u32 ir_max; + __u32 ir_avg; + struct ocfs2_info_free_chunk_list { + __u32 ir_fc_chunks[OCFS2_INFO_MAX_HIST]; + __u32 ir_fc_clusters[OCFS2_INFO_MAX_HIST]; + } ir_fc_hist; + } ir_ffg; +}; + +struct ocfs2_info_freeinode { + struct ocfs2_info_request ir_request; + __u32 ir_slotnum; /* out */ + struct ocfs2_info_local_fi { + __u64 ir_total; + __u64 ir_free; + } ir_fi_stat[OCFS2_INFO_MAX_SLOTS]; +}; + +/* Codes for ocfs2_info_request */ + +#define OCFS2_INFO_CLUSTERSIZE (0x00000001) +#define OCFS2_INFO_BLOCKSIZE (0x00000002) +#define OCFS2_INFO_SLOTNUM (0x00000004) +#define OCFS2_INFO_LABEL (0x00000008) +#define OCFS2_INFO_UUID (0x00000010) +#define OCFS2_INFO_FS_FEATURES (0x00000020) +#define OCFS2_INFO_FREEFRAG (0x00000040) +#define OCFS2_INFO_FREEINODE (0x00000080) + +/* Flags for struct ocfs2_info_request */ +/* Filled by the caller */ +#define OCFS2_INFO_FL_NON_COHERENT (0x00000001) /* Cluster coherency not + required. This is a hint. + It is up to ocfs2 whether + the request can be fulfilled + without locking. */ +/* Filled by ocfs2 */ +#define OCFS2_INFO_FL_FILLED (0x80000000) /* Filesystem understood + this request and + filled in the answer */ + +#define OCFS2_IOC_INFO _IOR('o', 5, struct ocfs2_info) + +#endif /* OCFS2_IOCTL_H */ diff --git a/fs/ocfs2/resize.c b/fs/ocfs2/resize.c index 3c3d673..9cf5da3 100644 --- a/fs/ocfs2/resize.c +++ b/fs/ocfs2/resize.c @@ -42,6 +42,7 @@ #include "buffer_head_io.h" #include "suballoc.h" +#include "ocfs2_ioctl.h" #include "resize.h" /* -- 1.5.5
Tristan Ye
2010-Jan-08 08:51 UTC
[Ocfs2-devel] [PATCH 2/2] Ocfs2: Add new OCFS2_IOC_INFO ioctl for ocfs2 v5.
Major changes from v4 to v5: Incorporate Joel minor comment. The reason why we need this ioctl is to offer the none-privileged end-user a possibility to get filesys info gathering. We use OCFS2_IOC_INFO to manipulate the new ioctl, userspace passes a structure to kernel containing an array of request pointers and request count, such as, * From userspace: struct ocfs2_info_blocksize brq = { .ir_request = { .ir_magic = OCFS2_INFO_MAGIC, .ir_code = OCFS2_INFO_BLOCKSIZE, ... } ... } struct ocfs2_info_clustersize crq = { ... } uint64_t reqs[2] = {(unsigned long)&brq, (unsigned long)&crq}; struct ocfs2_info info = { .ir_requests = reqs, .ir_count = 2, } ret = ioctl(fd, OCFS2_IOC_INFO, &info); * In kernel: Get the request pointers from *info*, then handle each request one bye one. Idea here is to make the spearated request small enough to guarantee a better backward&forward compatibility since a small piece of request would be less likely to be broken if filesys on raw disk get changed. Currently, following 8 ioctls get implemented per the requirement from userspace tool o2info, and I believe it will grow over time:-) OCFS2_INFO_CLUSTERSIZE OCFS2_INFO_BLOCKSIZE OCFS2_INFO_SLOTNUM OCFS2_INFO_LABEL OCFS2_INFO_UUID OCFS2_INFO_FS_FEATURES OCFS2_INFO_FREEFRAG OCFS2_INFO_FREEINODE The ioctl is only specific to OCFS2. Signed-off-by: Tristan Ye <tristan.ye at oracle.com> --- fs/ocfs2/ioctl.c | 661 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 661 insertions(+), 0 deletions(-) diff --git a/fs/ocfs2/ioctl.c b/fs/ocfs2/ioctl.c index 31fbb06..4b756d4 100644 --- a/fs/ocfs2/ioctl.c +++ b/fs/ocfs2/ioctl.c @@ -20,8 +20,12 @@ #include "ocfs2_fs.h" #include "ioctl.h" +#include "ocfs2_ioctl.h" #include "resize.h" #include "refcounttree.h" +#include "sysfile.h" +#include "buffer_head_io.h" +#include "suballoc.h" #include <linux/ext2_fs.h> @@ -108,6 +112,656 @@ bail: return status; } +int ocfs2_info_handle_blocksize(struct inode *inode, + struct ocfs2_info_request __user *user_req) +{ + int status = 0; + struct ocfs2_info_blocksize req_bs; + + if (copy_from_user(&req_bs, user_req, + sizeof(struct ocfs2_info_blocksize))) { + status = -EFAULT; + goto bail; + } + + req_bs.ir_blocksize = inode->i_sb->s_blocksize; + req_bs.ir_request.ir_flags |= OCFS2_INFO_FL_FILLED; + + if (copy_to_user((struct ocfs2_info_blocksize __user *)user_req, + &req_bs, + sizeof(struct ocfs2_info_blocksize))) { + status = -EFAULT; + goto bail; + } + +bail: + mlog_exit(status); + return status; +} + +int ocfs2_info_handle_clustersize(struct inode *inode, + struct ocfs2_info_request __user *user_req) +{ + int status = 0; + struct ocfs2_info_clustersize req_cs; + struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); + + if (copy_from_user(&req_cs, user_req, + sizeof(struct ocfs2_info_clustersize))) { + status = -EFAULT; + goto bail; + } + + req_cs.ir_clustersize = osb->s_clustersize; + req_cs.ir_request.ir_flags |= OCFS2_INFO_FL_FILLED; + + if (copy_to_user((struct ocfs2_info_clustersize __user *)user_req, + &req_cs, + sizeof(struct ocfs2_info_clustersize))) { + status = -EFAULT; + goto bail; + } + +bail: + mlog_exit(status); + return status; +} + +int ocfs2_info_handle_slotnum(struct inode *inode, + struct ocfs2_info_request __user *user_req) +{ + int status = 0; + struct ocfs2_info_slotnum req_sn; + struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); + + if (copy_from_user(&req_sn, user_req, + sizeof(struct ocfs2_info_slotnum))) { + status = -EFAULT; + goto bail; + } + + req_sn.ir_slotnum = osb->max_slots; + req_sn.ir_request.ir_flags |= OCFS2_INFO_FL_FILLED; + + if (copy_to_user((struct ocfs2_info_slotnum __user *)user_req, + &req_sn, + sizeof(struct ocfs2_info_slotnum))) { + status = -EFAULT; + goto bail; + } + +bail: + mlog_exit(status); + return status; +} + +int ocfs2_info_handle_label(struct inode *inode, + struct ocfs2_info_request __user *user_req) +{ + int status = 0; + struct ocfs2_info_label req_lb; + struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); + + if (copy_from_user(&req_lb, user_req, + sizeof(struct ocfs2_info_label))) { + status = -EFAULT; + goto bail; + } + + memcpy(req_lb.ir_label, osb->vol_label, OCFS2_MAX_VOL_LABEL_LEN); + req_lb.ir_request.ir_flags |= OCFS2_INFO_FL_FILLED; + + if (copy_to_user((struct ocfs2_info_label __user *)user_req, + &req_lb, + sizeof(struct ocfs2_info_label))) { + status = -EFAULT; + goto bail; + } + +bail: + mlog_exit(status); + return status; +} + +int ocfs2_info_handle_uuid(struct inode *inode, + struct ocfs2_info_request __user *user_req) +{ + int status = 0; + struct ocfs2_info_uuid req_uuid; + struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); + + if (copy_from_user(&req_uuid, user_req, + sizeof(struct ocfs2_info_uuid))) { + status = -EFAULT; + goto bail; + } + + memcpy(req_uuid.ir_uuid_str, osb->uuid_str, OCFS2_INFO_VOL_UUIDSTR_LEN); + req_uuid.ir_request.ir_flags |= OCFS2_INFO_FL_FILLED; + + if (copy_to_user((struct ocfs2_info_uuid __user *)user_req, + &req_uuid, + sizeof(struct ocfs2_info_uuid))) { + status = -EFAULT; + goto bail; + } + +bail: + mlog_exit(status); + return status; +} + +int ocfs2_info_handle_fs_features(struct inode *inode, + struct ocfs2_info_request __user *user_req) +{ + int status = 0; + struct ocfs2_info_fs_features req_fs; + struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); + + if (copy_from_user(&req_fs, user_req, + sizeof(struct ocfs2_info_fs_features))) { + status = -EFAULT; + goto bail; + } + + req_fs.ir_compat_features = osb->s_feature_compat; + req_fs.ir_incompat_features = osb->s_feature_incompat; + req_fs.ir_ro_compat_features = osb->s_feature_ro_compat; + req_fs.ir_request.ir_flags |= OCFS2_INFO_FL_FILLED; + + if (copy_to_user((struct ocfs2_info_fs_features __user *)user_req, + &req_fs, + sizeof(struct ocfs2_info_fs_features))) { + status = -EFAULT; + goto bail; + } + +bail: + mlog_exit(status); + return status; +} + +void ocfs2_info_update_ffg(struct ocfs2_info_freefrag *ffg, + unsigned int chunksize) +{ + int index; + + index = __ilog2_u32(chunksize); + if (index >= OCFS2_INFO_MAX_HIST) + index = OCFS2_INFO_MAX_HIST - 1; + + ffg->ir_ffg.ir_fc_hist.ir_fc_chunks[index]++; + ffg->ir_ffg.ir_fc_hist.ir_fc_clusters[index] += chunksize; + + if (chunksize > ffg->ir_ffg.ir_max) + ffg->ir_ffg.ir_max = chunksize; + + if (chunksize < ffg->ir_ffg.ir_min) + ffg->ir_ffg.ir_min = chunksize; + + ffg->ir_ffg.ir_avg += chunksize; + ffg->ir_ffg.ir_free_chunks_real++; +} + +int ocfs2_info_scan_chain(struct inode *gb_inode, + struct ocfs2_dinode *gb_dinode, + struct ocfs2_info_freefrag *ffg, + struct ocfs2_chain_rec *rec, + unsigned int chunks_in_group) +{ + int status = 0, used; + u64 blkno; + + struct buffer_head *bh = NULL; + struct ocfs2_group_desc *bg = NULL; + + unsigned int max_bits, num_clusters; + unsigned int offset = 0, cluster, chunk; + unsigned int chunk_free, last_chunksize = 0; + + if (!le32_to_cpu(rec->c_free)) + goto bail; + + do { + if (!bg) + blkno = le64_to_cpu(rec->c_blkno); + else + blkno = le64_to_cpu(bg->bg_next_group); + + if (bh) { + brelse(bh); + bh = NULL; + } + + status = ocfs2_read_group_descriptor(gb_inode, gb_dinode, + blkno, &bh); + if (status < 0) { + mlog(ML_ERROR, "Can't read the group descriptor # " + "%llu from device.", (unsigned long long)blkno); + status = -EIO; + goto bail; + } + + bg = (struct ocfs2_group_desc *)bh->b_data; + + if (!le16_to_cpu(bg->bg_free_bits_count)) + continue; + + max_bits = le16_to_cpu(bg->bg_bits); + offset = 0; + + for (chunk = 0; chunk < chunks_in_group; chunk++) { + + /* Last chunk may be not a entire one */ + if ((offset + ffg->ir_chunksize) > max_bits) + num_clusters = max_bits - offset; + else + num_clusters = ffg->ir_chunksize; + + chunk_free = 0; + for (cluster = 0; cluster < num_clusters; cluster++) { + used = ocfs2_test_bit(offset, + (unsigned long *)bg->bg_bitmap); + if (!used) { + last_chunksize++; + chunk_free++; + } + + if (used && (last_chunksize)) { + ocfs2_info_update_ffg(ffg, + last_chunksize); + last_chunksize = 0; + } + + offset++; + } + + if (chunk_free == ffg->ir_chunksize) + ffg->ir_ffg.ir_free_chunks++; + } + + /* we need to update the info of last free chunk */ + if (last_chunksize) + ocfs2_info_update_ffg(ffg, last_chunksize); + + } while (le64_to_cpu(bg->bg_next_group)); + +bail: + brelse(bh); + + mlog_exit(status); + return status; +} + +int ocfs2_info_scan_bitmap(struct inode *gb_inode, + struct ocfs2_dinode *gb_dinode, + struct ocfs2_info_freefrag *ffg, + struct ocfs2_chain_list *cl) +{ + int status = 0, i; + unsigned int chunks_in_group; + struct ocfs2_chain_rec *rec = NULL; + + chunks_in_group = le16_to_cpu(cl->cl_cpg) / ffg->ir_chunksize + 1; + + for (i = 0; i < le16_to_cpu(cl->cl_next_free_rec); i++) { + + rec = &(cl->cl_recs[i]); + status = ocfs2_info_scan_chain(gb_inode, gb_dinode, + ffg, rec, chunks_in_group); + if (status) + goto bail; + } + +bail: + mlog_exit(status); + return status; +} + +int ocfs2_info_handle_freefrag(struct inode *inode, + struct ocfs2_info_request __user *user_req) +{ + int status = 0, unlock = 0; + + struct ocfs2_info_freefrag req_ffg; + struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); + struct buffer_head *bh = NULL; + struct inode *gb_inode = NULL; + struct ocfs2_dinode *gb_dinode = NULL; + struct ocfs2_chain_list *cl = NULL; + + if (copy_from_user(&req_ffg, user_req, + sizeof(struct ocfs2_info_freefrag))) { + status = -EFAULT; + goto bail; + } + + /* + * chunksize from userspace should be power of 2, + */ + if ((req_ffg.ir_chunksize & (req_ffg.ir_chunksize - 1)) || + (!req_ffg.ir_chunksize)) { + status = -EINVAL; + goto bail; + } + + memset(&req_ffg.ir_ffg, 0, sizeof(struct ocfs2_info_freefrag_stats)); + req_ffg.ir_ffg.ir_min = ~0U; + + gb_inode = ocfs2_get_system_file_inode(osb, + GLOBAL_BITMAP_SYSTEM_INODE, + OCFS2_INVALID_SLOT); + if (!gb_inode) { + mlog(ML_ERROR, "failed to get bitmap inode\n"); + status = -EIO; + goto bail; + } + + mutex_lock(&gb_inode->i_mutex); + + if (!(req_ffg.ir_request.ir_flags & OCFS2_INFO_FL_NON_COHERENT)) { + status = ocfs2_inode_lock(gb_inode, &bh, 0); + if (status < 0) { + mlog_errno(status); + goto bail_mutex_unlock; + } + unlock = 1; + + } else { + status = ocfs2_read_inode_block(gb_inode, &bh); + if (status < 0) { + mlog_errno(status); + goto bail; + } + } + + gb_dinode = (struct ocfs2_dinode *)bh->b_data; + + req_ffg.ir_ffg.ir_clusters + le32_to_cpu(gb_dinode->id1.bitmap1.i_total); + req_ffg.ir_ffg.ir_free_clusters = req_ffg.ir_ffg.ir_clusters - + le32_to_cpu(gb_dinode->id1.bitmap1.i_used); + + cl = &(gb_dinode->id2.i_chain); + + /* Chunksize from userspace should be less than clusters in a group */ + if (req_ffg.ir_chunksize > le16_to_cpu(cl->cl_cpg)) { + status = -EINVAL; + goto bail; + } + + status = ocfs2_info_scan_bitmap(gb_inode, gb_dinode, &req_ffg, cl); + if (status) + goto bail; + + if (req_ffg.ir_ffg.ir_free_chunks_real) + req_ffg.ir_ffg.ir_avg = (req_ffg.ir_ffg.ir_avg / + req_ffg.ir_ffg.ir_free_chunks_real); + + req_ffg.ir_request.ir_flags |= OCFS2_INFO_FL_FILLED; + + if (copy_to_user((struct ocfs2_info_freefrag __user *)user_req, + &req_ffg, + sizeof(struct ocfs2_info_freefrag))) { + status = -EFAULT; + goto bail; + } + +bail: + if (unlock) + ocfs2_inode_unlock(gb_inode, 0); + +bail_mutex_unlock: + if (gb_inode) + mutex_unlock(&gb_inode->i_mutex); + + iput(gb_inode); + brelse(bh); + + mlog_exit(status); + return status; +} + +int ocfs2_info_scan_inode_alloc(struct inode *inode_alloc, + struct ocfs2_info_freeinode *fi, + __u32 slotnum, + int flags) +{ + int status = 0, unlock = 0; + + struct buffer_head *bh = NULL; + struct ocfs2_dinode *dinode_alloc = NULL; + + mutex_lock(&inode_alloc->i_mutex); + + if (!(flags & OCFS2_INFO_FL_NON_COHERENT)) { + status = ocfs2_inode_lock(inode_alloc, &bh, 0); + if (status < 0) { + mlog_errno(status); + goto bail_mutex_unlock; + } + unlock = 1; + + } else { + + status = ocfs2_read_inode_block(inode_alloc, &bh); + if (status < 0) { + mlog_errno(status); + goto bail; + } + } + + dinode_alloc = (struct ocfs2_dinode *)bh->b_data; + + fi->ir_fi_stat[slotnum].ir_total + le32_to_cpu(dinode_alloc->id1.bitmap1.i_total); + fi->ir_fi_stat[slotnum].ir_free + le32_to_cpu(dinode_alloc->id1.bitmap1.i_total) - + le32_to_cpu(dinode_alloc->id1.bitmap1.i_used); +bail: + if (unlock) + ocfs2_inode_unlock(inode_alloc, 0); + +bail_mutex_unlock: + mutex_unlock(&inode_alloc->i_mutex); + + iput(inode_alloc); + brelse(bh); + + mlog_exit(status); + return status; +} + +int ocfs2_info_handle_freeinode(struct inode *inode, + struct ocfs2_info_request __user *user_req) +{ + int status = 0, i; + + struct ocfs2_info_freeinode req_fi; + struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); + struct inode *inode_alloc = NULL; + + + if (copy_from_user(&req_fi, user_req, + sizeof(struct ocfs2_info_freeinode))) { + status = -EFAULT; + goto bail; + } + + req_fi.ir_slotnum = osb->max_slots; + + for (i = 0; i < req_fi.ir_slotnum; i++) { + inode_alloc + ocfs2_get_system_file_inode(osb, + INODE_ALLOC_SYSTEM_INODE, + i); + if (!inode_alloc) { + mlog(ML_ERROR, "unable to get alloc inode in slot %u\n", + (u32)i); + status = -EIO; + goto bail; + } + + status = ocfs2_info_scan_inode_alloc(inode_alloc, &req_fi, i, + req_fi.ir_request.ir_flags); + if (status < 0) + goto bail; + } + + req_fi.ir_request.ir_flags |= OCFS2_INFO_FL_FILLED; + + if (copy_to_user((struct ocfs2_info_freeinode __user *)user_req, + &req_fi, + sizeof(struct ocfs2_info_freeinode))) { + status = -EFAULT; + } + +bail: + + mlog_exit(status); + return status; +} + +int ocfs2_info_handle_unknown(struct inode *inode, + struct ocfs2_info_request __user *user_req) +{ + int status = 0; + struct ocfs2_info_request req; + + if (copy_from_user(&req, user_req, sizeof(struct ocfs2_info_request))) { + status = -EFAULT; + goto bail; + } + + req.ir_flags &= ~OCFS2_INFO_FL_FILLED; + + if (copy_to_user(user_req, &req, + sizeof(struct ocfs2_info_request))) { + status = -EFAULT; + goto bail; + } + +bail: + mlog_exit(status); + return status; +} + +int ocfs2_info_handle_request(struct inode *inode, + struct ocfs2_info_request __user *user_req) +{ + int status = 0; + struct ocfs2_info_request req; + + if (copy_from_user(&req, user_req, sizeof(struct ocfs2_info_request))) { + status = -EFAULT; + goto bail; + } + + if (req.ir_magic != OCFS2_INFO_MAGIC) { + status = -EINVAL; + goto bail; + } + + switch (req.ir_code) { + case OCFS2_INFO_BLOCKSIZE: + if (req.ir_size != sizeof(struct ocfs2_info_blocksize)) { + status = -EINVAL; + break; + } + status = ocfs2_info_handle_blocksize(inode, user_req); + break; + case OCFS2_INFO_CLUSTERSIZE: + if (req.ir_size != sizeof(struct ocfs2_info_clustersize)) { + status = -EINVAL; + break; + } + status = ocfs2_info_handle_clustersize(inode, user_req); + break; + case OCFS2_INFO_SLOTNUM: + if (req.ir_size != sizeof(struct ocfs2_info_slotnum)) { + status = -EINVAL; + break; + } + status = ocfs2_info_handle_slotnum(inode, user_req); + break; + case OCFS2_INFO_LABEL: + if (req.ir_size != sizeof(struct ocfs2_info_label)) { + status = -EINVAL; + break; + } + status = ocfs2_info_handle_label(inode, user_req); + break; + case OCFS2_INFO_UUID: + if (req.ir_size != sizeof(struct ocfs2_info_uuid)) { + status = -EINVAL; + break; + } + status = ocfs2_info_handle_uuid(inode, user_req); + break; + case OCFS2_INFO_FS_FEATURES: + if (req.ir_size != sizeof(struct ocfs2_info_fs_features)) { + status = -EINVAL; + break; + } + status = ocfs2_info_handle_fs_features(inode, user_req); + break; + case OCFS2_INFO_FREEFRAG: + if (req.ir_size != sizeof(struct ocfs2_info_freefrag)) { + status = -EINVAL; + break; + } + status = ocfs2_info_handle_freefrag(inode, user_req); + break; + case OCFS2_INFO_FREEINODE: + if (req.ir_size != sizeof(struct ocfs2_info_freeinode)) { + status = -EINVAL; + break; + } + status = ocfs2_info_handle_freeinode(inode, user_req); + break; + default: + status = ocfs2_info_handle_unknown(inode, user_req); + break; + } + +bail: + mlog_exit(status); + return status; +} + +int ocfs2_info_handle(struct inode *inode, struct ocfs2_info *info) +{ + int i, status = 0; + u64 req_addr; + struct ocfs2_info_request __user *reqp; + + if ((info->info_count > OCFS2_INFO_MAX_REQUEST) || + (!info->info_requests)) { + status = -EINVAL; + goto bail; + } + + for (i = 0; i < info->info_count; i++) { + status = -EFAULT; + if (get_user(req_addr, (u64 __user *)(info->info_requests) + i)) + goto bail; + + reqp = (struct ocfs2_info_request *)req_addr; + if (!reqp) { + status = -EINVAL; + goto bail; + } + + status = ocfs2_info_handle_request(inode, reqp); + if (status) + goto bail; + } + +bail: + mlog_exit(status); + return status; +} + long ocfs2_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) { struct inode *inode = filp->f_path.dentry->d_inode; @@ -117,6 +771,7 @@ long ocfs2_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) struct ocfs2_space_resv sr; struct ocfs2_new_group_input input; struct reflink_arguments args; + struct ocfs2_info info; const char *old_path, *new_path; bool preserve; @@ -173,6 +828,12 @@ long ocfs2_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) preserve = (args.preserve != 0); return ocfs2_reflink_ioctl(inode, old_path, new_path, preserve); + case OCFS2_IOC_INFO: + if (copy_from_user(&info, (struct ocfs2_info __user *)arg, + sizeof(struct ocfs2_info))) + return -EFAULT; + + return ocfs2_info_handle(inode, &info); default: return -ENOTTY; } -- 1.5.5
Tristan Ye
2010-Feb-05 09:59 UTC
[Ocfs2-devel] [PATCH 1/2] Ocfs2: Move ocfs2 ioctl definitions from ocfs2_fs.h to new added ocfs2_ioctl.h.
Currently we were adding ioctl cmds/structures for ocfs2 into ocfs2_fs.h which was used for define ocfs2 on-disk layout. That sounds a little bit confusing, and it may be quickly polluted espcially when growing the ocfs2_info_request ioctls afterwards(it will grow i bet). As a result, such OCFS2 IOCs do need to be placed somewhere other than ocfs2_fs.h, a separated ocfs2_ioctl.h will be added to store such ioctl structures and definitions which could also be used from userspace to invoke the ioctls. What's more, the patch also introduces new structures and definitions for the new OCFS2_IOC_INFO. Signed-off-by: Tristan Ye <tristan.ye at oracle.com> --- fs/ocfs2/file.h | 2 + fs/ocfs2/ioctl.h | 6 +- fs/ocfs2/ocfs2_fs.h | 57 -------------- fs/ocfs2/ocfs2_ioctl.h | 195 ++++++++++++++++++++++++++++++++++++++++++++++++ fs/ocfs2/resize.c | 1 + 5 files changed, 201 insertions(+), 60 deletions(-) create mode 100644 fs/ocfs2/ocfs2_ioctl.h diff --git a/fs/ocfs2/file.h b/fs/ocfs2/file.h index d66cf4f..eb891db 100644 --- a/fs/ocfs2/file.h +++ b/fs/ocfs2/file.h @@ -26,6 +26,8 @@ #ifndef OCFS2_FILE_H #define OCFS2_FILE_H +#include "ocfs2_ioctl.h" + extern const struct file_operations ocfs2_fops; extern const struct file_operations ocfs2_dops; extern const struct file_operations ocfs2_fops_no_plocks; diff --git a/fs/ocfs2/ioctl.h b/fs/ocfs2/ioctl.h index cf9a5ee..0cd5323 100644 --- a/fs/ocfs2/ioctl.h +++ b/fs/ocfs2/ioctl.h @@ -7,10 +7,10 @@ * */ -#ifndef OCFS2_IOCTL_H -#define OCFS2_IOCTL_H +#ifndef OCFS2_IOCTL_PROTO_H +#define OCFS2_IOCTL_PROTO_H long ocfs2_ioctl(struct file *filp, unsigned int cmd, unsigned long arg); long ocfs2_compat_ioctl(struct file *file, unsigned cmd, unsigned long arg); -#endif /* OCFS2_IOCTL_H */ +#endif /* OCFS2_IOCTL_PROTO_H */ diff --git a/fs/ocfs2/ocfs2_fs.h b/fs/ocfs2/ocfs2_fs.h index e9431e4..54e1de0 100644 --- a/fs/ocfs2/ocfs2_fs.h +++ b/fs/ocfs2/ocfs2_fs.h @@ -254,63 +254,6 @@ * refcount tree */ /* - * ioctl commands - */ -#define OCFS2_IOC_GETFLAGS _IOR('f', 1, long) -#define OCFS2_IOC_SETFLAGS _IOW('f', 2, long) -#define OCFS2_IOC32_GETFLAGS _IOR('f', 1, int) -#define OCFS2_IOC32_SETFLAGS _IOW('f', 2, int) - -/* - * Space reservation / allocation / free ioctls and argument structure - * are designed to be compatible with XFS. - * - * ALLOCSP* and FREESP* are not and will never be supported, but are - * included here for completeness. - */ -struct ocfs2_space_resv { - __s16 l_type; - __s16 l_whence; - __s64 l_start; - __s64 l_len; /* len == 0 means until end of file */ - __s32 l_sysid; - __u32 l_pid; - __s32 l_pad[4]; /* reserve area */ -}; - -#define OCFS2_IOC_ALLOCSP _IOW ('X', 10, struct ocfs2_space_resv) -#define OCFS2_IOC_FREESP _IOW ('X', 11, struct ocfs2_space_resv) -#define OCFS2_IOC_RESVSP _IOW ('X', 40, struct ocfs2_space_resv) -#define OCFS2_IOC_UNRESVSP _IOW ('X', 41, struct ocfs2_space_resv) -#define OCFS2_IOC_ALLOCSP64 _IOW ('X', 36, struct ocfs2_space_resv) -#define OCFS2_IOC_FREESP64 _IOW ('X', 37, 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) - -/* Used to pass group descriptor data when online resize is done */ -struct ocfs2_new_group_input { - __u64 group; /* Group descriptor's blkno. */ - __u32 clusters; /* Total number of clusters in this group */ - __u32 frees; /* Total free clusters in this group */ - __u16 chain; /* Chain for this group */ - __u16 reserved1; - __u32 reserved2; -}; - -#define OCFS2_IOC_GROUP_EXTEND _IOW('o', 1, int) -#define OCFS2_IOC_GROUP_ADD _IOW('o', 2,struct ocfs2_new_group_input) -#define OCFS2_IOC_GROUP_ADD64 _IOW('o', 3,struct ocfs2_new_group_input) - -/* Used to pass 2 file names to reflink. */ -struct reflink_arguments { - __u64 old_path; - __u64 new_path; - __u64 preserve; -}; -#define OCFS2_IOC_REFLINK _IOW('o', 4, struct reflink_arguments) - - -/* * Journal Flags (ocfs2_dinode.id1.journal1.i_flags) */ #define OCFS2_JOURNAL_DIRTY_FL (0x00000001) /* Journal needs recovery */ diff --git a/fs/ocfs2/ocfs2_ioctl.h b/fs/ocfs2/ocfs2_ioctl.h new file mode 100644 index 0000000..e15c84d --- /dev/null +++ b/fs/ocfs2/ocfs2_ioctl.h @@ -0,0 +1,195 @@ +/* -*- mode: c; c-basic-offset: 8; -*- + * vim: noexpandtab sw=8 ts=8 sts=0: + * + * ocfs2_ioctl.h + * + * Defines OCFS2 ioctls. + * + * Copyright (C) 2009 Oracle. 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, version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will 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. + */ + +#ifndef OCFS2_IOCTL_H +#define OCFS2_IOCTL_H + +/* + * ioctl commands + */ +#define OCFS2_IOC_GETFLAGS _IOR('f', 1, long) +#define OCFS2_IOC_SETFLAGS _IOW('f', 2, long) +#define OCFS2_IOC32_GETFLAGS _IOR('f', 1, int) +#define OCFS2_IOC32_SETFLAGS _IOW('f', 2, int) + +/* + * Space reservation / allocation / free ioctls and argument structure + * are designed to be compatible with XFS. + * + * ALLOCSP* and FREESP* are not and will never be supported, but are + * included here for completeness. + */ +struct ocfs2_space_resv { + __s16 l_type; + __s16 l_whence; + __s64 l_start; + __s64 l_len; /* len == 0 means until end of file */ + __s32 l_sysid; + __u32 l_pid; + __s32 l_pad[4]; /* reserve area */ +}; + +#define OCFS2_IOC_ALLOCSP _IOW ('X', 10, struct ocfs2_space_resv) +#define OCFS2_IOC_FREESP _IOW ('X', 11, struct ocfs2_space_resv) +#define OCFS2_IOC_RESVSP _IOW ('X', 40, struct ocfs2_space_resv) +#define OCFS2_IOC_UNRESVSP _IOW ('X', 41, struct ocfs2_space_resv) +#define OCFS2_IOC_ALLOCSP64 _IOW ('X', 36, struct ocfs2_space_resv) +#define OCFS2_IOC_FREESP64 _IOW ('X', 37, 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) + +/* Used to pass group descriptor data when online resize is done */ +struct ocfs2_new_group_input { + __u64 group; /* Group descriptor's blkno. */ + __u32 clusters; /* Total number of clusters in this group */ + __u32 frees; /* Total free clusters in this group */ + __u16 chain; /* Chain for this group */ + __u16 reserved1; + __u32 reserved2; +}; + +#define OCFS2_IOC_GROUP_EXTEND _IOW('o', 1, int) +#define OCFS2_IOC_GROUP_ADD _IOW('o', 2,struct ocfs2_new_group_input) +#define OCFS2_IOC_GROUP_ADD64 _IOW('o', 3,struct ocfs2_new_group_input) + +/* Used to pass 2 file names to reflink. */ +struct reflink_arguments { + __u64 old_path; + __u64 new_path; + __u64 preserve; +}; +#define OCFS2_IOC_REFLINK _IOW('o', 4, struct reflink_arguments) + + +/* Following definitions dedicated for ocfs2_info_request ioctls. */ + +#define OCFS2_INFO_VOL_UUID_LEN (16) +#define OCFS2_INFO_MAX_VOL_LABEL_LEN (64) +#define OCFS2_INFO_VOL_UUIDSTR_LEN (OCFS2_INFO_VOL_UUID_LEN * 2 + 1) +#define OCFS2_INFO_MAX_SLOTS (255) +#define OCFS2_INFO_MAX_HIST (32) + +#define OCFS2_INFO_MAX_REQUEST (50) + +/* Magic number of all requests */ +#define OCFS2_INFO_MAGIC (0x4F32494E) + +/* + * Always try to separate info request into small pieces to + * guarantee the backward&forward compatibility. + */ + +struct ocfs2_info { + __u64 info_requests; /* Array of __u64 pointers to requests */ + __u32 info_count; /* Number of requests in info_requests */ +}; + +struct ocfs2_info_request { +/*00*/ __u32 ir_magic; /* Magic number */ + __u32 ir_code; /* Info request code */ + __u32 ir_size; /* Size of request */ + __u32 ir_flags; /* Request flags */ +/*10*/ /* Request specific fields */ +}; + +struct ocfs2_info_clustersize { + struct ocfs2_info_request ir_request; + __u32 ir_clustersize; +}; + +struct ocfs2_info_blocksize { + struct ocfs2_info_request ir_request; + __u32 ir_blocksize; +}; + +struct ocfs2_info_slotnum { + struct ocfs2_info_request ir_request; + __u16 ir_slotnum; +}; + +struct ocfs2_info_label { + struct ocfs2_info_request ir_request; + __u8 ir_label[OCFS2_INFO_MAX_VOL_LABEL_LEN]; +}; + +struct ocfs2_info_uuid { + struct ocfs2_info_request ir_request; + __u8 ir_uuid_str[OCFS2_INFO_VOL_UUIDSTR_LEN]; +}; + +struct ocfs2_info_fs_features { + struct ocfs2_info_request ir_request; + __u32 ir_compat_features; + __u32 ir_incompat_features; + __u32 ir_ro_compat_features; +}; + +struct ocfs2_info_freefrag { + struct ocfs2_info_request ir_request; + __u32 ir_chunksize; /* chunksize in clusters(in) */ + struct ocfs2_info_freefrag_stats { /* (out) */ + __u32 ir_clusters; + __u32 ir_free_clusters; + __u32 ir_free_chunks; + __u32 ir_free_chunks_real; + __u32 ir_min; /* Minimum free chunksize in clusters */ + __u32 ir_max; + __u32 ir_avg; + struct ocfs2_info_free_chunk_list { + __u32 ir_fc_chunks[OCFS2_INFO_MAX_HIST]; + __u32 ir_fc_clusters[OCFS2_INFO_MAX_HIST]; + } ir_fc_hist; + } ir_ffg; +}; + +struct ocfs2_info_freeinode { + struct ocfs2_info_request ir_request; + __u32 ir_slotnum; /* out */ + struct ocfs2_info_local_fi { + __u64 ir_total; + __u64 ir_free; + } ir_fi_stat[OCFS2_INFO_MAX_SLOTS]; +}; + +/* Codes for ocfs2_info_request */ + +#define OCFS2_INFO_CLUSTERSIZE (0x00000001) +#define OCFS2_INFO_BLOCKSIZE (0x00000002) +#define OCFS2_INFO_SLOTNUM (0x00000004) +#define OCFS2_INFO_LABEL (0x00000008) +#define OCFS2_INFO_UUID (0x00000010) +#define OCFS2_INFO_FS_FEATURES (0x00000020) +#define OCFS2_INFO_FREEFRAG (0x00000040) +#define OCFS2_INFO_FREEINODE (0x00000080) + +/* Flags for struct ocfs2_info_request */ +/* Filled by the caller */ +#define OCFS2_INFO_FL_NON_COHERENT (0x00000001) /* Cluster coherency not + required. This is a hint. + It is up to ocfs2 whether + the request can be fulfilled + without locking. */ +/* Filled by ocfs2 */ +#define OCFS2_INFO_FL_FILLED (0x80000000) /* Filesystem understood + this request and + filled in the answer */ + +#define OCFS2_IOC_INFO _IOR('o', 5, struct ocfs2_info) + +#endif /* OCFS2_IOCTL_H */ diff --git a/fs/ocfs2/resize.c b/fs/ocfs2/resize.c index 3c3d673..9cf5da3 100644 --- a/fs/ocfs2/resize.c +++ b/fs/ocfs2/resize.c @@ -42,6 +42,7 @@ #include "buffer_head_io.h" #include "suballoc.h" +#include "ocfs2_ioctl.h" #include "resize.h" /* -- 1.5.5
Joel Becker
2010-Feb-05 23:09 UTC
[Ocfs2-devel] [PATCH 1/2] Ocfs2: Move ocfs2 ioctl definitions from ocfs2_fs.h to new added ocfs2_ioctl.h.
On Fri, Jan 08, 2010 at 04:51:56PM +0800, Tristan Ye wrote:> Currently we were adding ioctl cmds/structures for ocfs2 into ocfs2_fs.h > which was used for define ocfs2 on-disk layout. That sounds a little bit > confusing, and it may be quickly polluted espcially when growing the > ocfs2_info_request ioctls afterwards(it will grow i bet). > > As a result, such OCFS2 IOCs do need to be placed somewhere other than ocfs2_fs.h, > a separated ocfs2_ioctl.h will be added to store such ioctl structures and definitions > which could also be used from userspace to invoke the ioctls. > > What's more, the patch also introduces new structures and definitions for the new > OCFS2_IOC_INFO.Can I get a version of this patch that does not inlude OCFS2_IOC_INFO? Separate out adding the INFO definitions. They can go in the second patch, as they match the operations. That way I can apply this patch even before INFO is ready. Joel -- "Always give your best, never get discouraged, never be petty; always remember, others may hate you. Those who hate you don't win unless you hate them. And then you destroy yourself." - Richard M. Nixon Joel Becker Principal Software Developer Oracle E-mail: joel.becker at oracle.com Phone: (650) 506-8127