Skip to contentSkip to conversation

Ocfs2: Add macro OCFS2_VOL_UUIDSTR_LEN in ocfs2_fs.h

PATCH New Tristan Ye 3 participants 13 messages Apr 20, 2010 – Apr 22, 2010 OCFS2

lore
Share & tools
lore

Tristan Ye

author
#0 lore raw

PATCH 1/2 Ocfs2: Add macro OCFS2_VOL_UUIDSTR_LEN in ocfs2_fs.h

Since we've been using uuid_str in most of ocfs2 codes, adding such a macro would be helpful.

---
 fs/ocfs2/ocfs2_fs.h |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)
fs/ocfs2/ocfs2_fs.h +1 -0
index bb37218..b313c83 100644
@@ -274,6 +274,7 @@
 
 #define OCFS2_VOL_UUID_LEN		16
 #define OCFS2_MAX_VOL_LABEL_LEN		64
+#define OCFS2_VOL_UUIDSTR_LEN		(OCFS2_VOL_UUID_LEN * 2 + 1)
 
 /* The alternate, userspace stack fields */
 #define OCFS2_STACK_LABEL_LEN		4
Signature · 1 line
1.5.5
author
#1 lore raw

PATCH 2/2 Ocfs2: Add new OCFS2_IOC_INFO ioctl for ocfs2 v7.

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 oib = {
        .ib_req = {
                .ir_magic = OCFS2_INFO_MAGIC,
                .ir_code = OCFS2_INFO_BLOCKSIZE,
                ...
        }
        ...
}
struct ocfs2_info_clustersize oic = {
        ...
}

uint64_t reqs[2] = {(unsigned long)&oib,

                    (unsigned long)&oic};

struct ocfs2_info info = {
.oi_requests = reqs,
.oi_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_MAXSLOTS
OCFS2_INFO_LABEL
OCFS2_INFO_UUID
OCFS2_INFO_FS_FEATURES

This ioctl is only specific to OCFS2.

---
 fs/ocfs2/ioctl.c       |  275 ++++++++++++++++++++++++++++++++++++++++++++++++
 fs/ocfs2/ocfs2_ioctl.h |   80 ++++++++++++++
 2 files changed, 355 insertions(+), 0 deletions(-)
fs/ocfs2/ioctl.c +275 -0
index 7d9d9c1..5e10340 100644
@@ -23,8 +23,18 @@
 #include "ioctl.h"
 #include "resize.h"
 #include "refcounttree.h"
+#include "sysfile.h"
+#include "buffer_head_io.h"
+#include "suballoc.h"
+
 
 #include <linux/ext2_fs.h>
+#include <linux/compat.h>
+
+#define o2info_from_user(a, b)	\
+		copy_from_user(&(a), (b), sizeof(a))
+#define o2info_to_user(a, b)	\
+		copy_to_user((typeof(a) __user *)b, &(a), sizeof(a))
 
 static int ocfs2_get_inode_attr(struct inode *inode, unsigned *flags)
 {
@@ -109,6 +119,257 @@ bail:
 	return status;
 }
 
+int ocfs2_info_handle_blocksize(struct inode *inode,
+				struct ocfs2_info_request __user *req)
+{
+	int status = -EFAULT;
+	struct ocfs2_info_blocksize oib;
+
+	if (o2info_from_user(oib, req))
+		goto bail;
+
+	oib.ib_blocksize = inode->i_sb->s_blocksize;
+	oib.ib_req.ir_flags |= OCFS2_INFO_FL_FILLED;
+
+	if (o2info_to_user(oib, req))
+		goto bail;
+
+	status = 0;
+bail:
+	return status;
+}
+
+int ocfs2_info_handle_clustersize(struct inode *inode,
+				  struct ocfs2_info_request __user *req)
+{
+	int status = -EFAULT;
+	struct ocfs2_info_clustersize oic;
+	struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
+
+	if (o2info_from_user(oic, req))
+		goto bail;
+
+	oic.ic_clustersize = osb->s_clustersize;
+	oic.ic_req.ir_flags |= OCFS2_INFO_FL_FILLED;
+
+	if (o2info_to_user(oic, req))
+		goto bail;
+
+	status = 0;
+bail:
+	return status;
+}
+
+int ocfs2_info_handle_maxslots(struct inode *inode,
+			       struct ocfs2_info_request __user *req)
+{
+	int status = -EFAULT;
+	struct ocfs2_info_maxslots oim;
+	struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
+
+	if (o2info_from_user(oim, req))
+		goto bail;
+
+	oim.im_max_slots = osb->max_slots;
+	oim.im_req.ir_flags |= OCFS2_INFO_FL_FILLED;
+
+	if (o2info_to_user(oim, req))
+		goto bail;
+
+	status = 0;
+bail:
+	return status;
+}
+
+int ocfs2_info_handle_label(struct inode *inode,
+			    struct ocfs2_info_request __user *req)
+{
+	int status = -EFAULT;
+	struct ocfs2_info_label oil;
+	struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
+
+	if (o2info_from_user(oil, req))
+		goto bail;
+
+	memcpy(oil.il_label, osb->vol_label, OCFS2_MAX_VOL_LABEL_LEN);
+	oil.il_req.ir_flags |= OCFS2_INFO_FL_FILLED;
+
+	if (o2info_to_user(oil, req))
+		goto bail;
+
+	status = 0;
+bail:
+	return status;
+}
+
+int ocfs2_info_handle_uuid(struct inode *inode,
+			   struct ocfs2_info_request __user *req)
+{
+	int status = -EFAULT;
+	struct ocfs2_info_uuid oiu;
+	struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
+
+	if (o2info_from_user(oiu, req))
+		goto bail;
+
+	memcpy(oiu.iu_uuid_str, osb->uuid_str, OCFS2_VOL_UUIDSTR_LEN);
+	oiu.iu_req.ir_flags |= OCFS2_INFO_FL_FILLED;
+
+	if (o2info_to_user(oiu, req))
+		goto bail;
+
+	status = 0;
+bail:
+	return status;
+}
+
+int ocfs2_info_handle_fs_features(struct inode *inode,
+				  struct ocfs2_info_request __user *req)
+{
+	int status = -EFAULT;
+	struct ocfs2_info_fs_features oif;
+	struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
+
+	if (o2info_from_user(oif, req))
+		goto bail;
+
+	oif.if_compat_features = osb->s_feature_compat;
+	oif.if_incompat_features = osb->s_feature_incompat;
+	oif.if_ro_compat_features = osb->s_feature_ro_compat;
+	oif.if_req.ir_flags |= OCFS2_INFO_FL_FILLED;
+
+	if (o2info_to_user(oif, req))
+		goto bail;
+
+	status = 0;
+bail:
+	return status;
+}
+
+int ocfs2_info_handle_unknown(struct inode *inode,
+			      struct ocfs2_info_request __user *req)
+{
+	int status = -EFAULT;
+	struct ocfs2_info_request oir;
+
+	if (o2info_from_user(oir, req))
+		goto bail;
+
+	oir.ir_flags &= ~OCFS2_INFO_FL_FILLED;
+
+	if (o2info_to_user(oir, req))
+		goto bail;
+
+	status = 0;
+bail:
+	return status;
+}
+
+/*
+ * Validate and distinguish OCFS2_IOC_INFO requests.
+ *
+ * - validate the magic number.
+ * - distinguish different requests.
+ * - validate size of different requests.
+ */
+int ocfs2_info_handle_request(struct inode *inode,
+			      struct ocfs2_info_request __user *req)
+{
+	int status = -EFAULT;
+	struct ocfs2_info_request oir;
+
+	if (o2info_from_user(oir, req))
+		goto bail;
+
+	status = -EINVAL;
+	if (oir.ir_magic != OCFS2_INFO_MAGIC)
+		goto bail;
+
+	switch (oir.ir_code) {
+	case OCFS2_INFO_BLOCKSIZE:
+		if (oir.ir_size == sizeof(struct ocfs2_info_blocksize))
+			status = ocfs2_info_handle_blocksize(inode, req);
+		break;
+	case OCFS2_INFO_CLUSTERSIZE:
+		if (oir.ir_size == sizeof(struct ocfs2_info_clustersize))
+			status = ocfs2_info_handle_clustersize(inode, req);
+		break;
+	case OCFS2_INFO_MAXSLOTS:
+		if (oir.ir_size == sizeof(struct ocfs2_info_maxslots))
+			status = ocfs2_info_handle_maxslots(inode, req);
+		break;
+	case OCFS2_INFO_LABEL:
+		if (oir.ir_size == sizeof(struct ocfs2_info_label))
+			status = ocfs2_info_handle_label(inode, req);
+		break;
+	case OCFS2_INFO_UUID:
+		if (oir.ir_size == sizeof(struct ocfs2_info_uuid))
+			status = ocfs2_info_handle_uuid(inode, req);
+		break;
+	case OCFS2_INFO_FS_FEATURES:
+		if (oir.ir_size == sizeof(struct ocfs2_info_fs_features))
+			status = ocfs2_info_handle_fs_features(inode, req);
+		break;
+	default:
+		status = ocfs2_info_handle_unknown(inode, req);
+		break;
+	}
+
+bail:
+	return status;
+}
+
+/*
+ * OCFS2_IOC_INFO handles an array of requests passed from userspace.
+ *
+ * ocfs2_info_handle() recevies a large info aggregation, grab and
+ * validate the request count from header, then break it into small
+ * pieces, later specific handlers can handle them one by one.
+ *
+ * Idea here is to make each separate request small enough to ensure
+ * a better backward&forward compatibility, since a small piece of
+ * request will be less likely to be broken if disk layout get changed.
+ */
+int ocfs2_info_handle(struct inode *inode, struct ocfs2_info *info,
+		      int compat_flag)
+{
+	int i, status = 0;
+	u64 req_addr;
+	struct ocfs2_info_request __user *reqp;
+
+	if ((info->oi_count > OCFS2_INFO_MAX_REQUEST) ||
+	    (!info->oi_requests)) {
+		status = -EINVAL;
+		goto bail;
+	}
+
+	for (i = 0; i < info->oi_count; i++) {
+		status = -EFAULT;
+		if (compat_flag) {
+			if (get_user(req_addr,
+			     (u64 __user *)compat_ptr(info->oi_requests) + i))
+				goto bail;
+		} else {
+			if (get_user(req_addr,
+				     (u64 __user *)(info->oi_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:
+	return status;
+}
+
 long ocfs2_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
 {
 	struct inode *inode = filp->f_path.dentry->d_inode;
@@ -120,6 +381,7 @@ long ocfs2_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
 	struct reflink_arguments args;
 	const char *old_path, *new_path;
 	bool preserve;
+	struct ocfs2_info info;
 
 	switch (cmd) {
 	case OCFS2_IOC_GETFLAGS:
@@ -174,6 +436,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, 0);
 	default:
 		return -ENOTTY;
 	}
@@ -185,6 +453,7 @@ long ocfs2_compat_ioctl(struct file *file, unsigned cmd, unsigned long arg)
 	bool preserve;
 	struct reflink_arguments args;
 	struct inode *inode = file->f_path.dentry->d_inode;
+	struct ocfs2_info info;
 
 	switch (cmd) {
 	case OCFS2_IOC32_GETFLAGS:
@@ -209,6 +478,12 @@ long ocfs2_compat_ioctl(struct file *file, unsigned cmd, unsigned long arg)
 
 		return ocfs2_reflink_ioctl(inode, compat_ptr(args.old_path),
 					   compat_ptr(args.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, 1);
 	default:
 		return -ENOIOCTLCMD;
 	}
fs/ocfs2/ocfs2_ioctl.h +80 -0

84 lines not on this page · raw message

Signature · 1 line
1.5.5
#2 lore raw

PATCH 2/2 Ocfs2: Add new OCFS2_IOC_INFO ioctl for ocfs2 v7.

Quoted 471 lines · Tristan Ye

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 oib = {
        .ib_req = {
                .ir_magic = OCFS2_INFO_MAGIC,
                .ir_code = OCFS2_INFO_BLOCKSIZE,
                ...
        }
        ...
}
struct ocfs2_info_clustersize oic = {
        ...
}

uint64_t reqs[2] = {(unsigned long)&oib,

                    (unsigned long)&oic};

struct ocfs2_info info = {
.oi_requests = reqs,
.oi_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_MAXSLOTS
OCFS2_INFO_LABEL
OCFS2_INFO_UUID
OCFS2_INFO_FS_FEATURES

This ioctl is only specific to OCFS2.

---
 fs/ocfs2/ioctl.c       |  275 ++++++++++++++++++++++++++++++++++++++++++++++++
 fs/ocfs2/ocfs2_ioctl.h |   80 ++++++++++++++
 2 files changed, 355 insertions(+), 0 deletions(-)
fs/ocfs2/ioctl.c +275 -0
index 7d9d9c1..5e10340 100644
@@ -23,8 +23,18 @@
 #include "ioctl.h"
 #include "resize.h"
 #include "refcounttree.h"
+#include "sysfile.h"
+#include "buffer_head_io.h"
+#include "suballoc.h"
+
 
 #include <linux/ext2_fs.h>
+#include <linux/compat.h>
+
+#define o2info_from_user(a, b)	\
+		copy_from_user(&(a), (b), sizeof(a))
+#define o2info_to_user(a, b)	\
+		copy_to_user((typeof(a) __user *)b, &(a), sizeof(a))
 
 static int ocfs2_get_inode_attr(struct inode *inode, unsigned *flags)
 {
@@ -109,6 +119,257 @@ bail:
 	return status;
 }
 
+int ocfs2_info_handle_blocksize(struct inode *inode,
+				struct ocfs2_info_request __user *req)
+{
+	int status = -EFAULT;
+	struct ocfs2_info_blocksize oib;
+
+	if (o2info_from_user(oib, req))
+		goto bail;
+
+	oib.ib_blocksize = inode->i_sb->s_blocksize;
+	oib.ib_req.ir_flags |= OCFS2_INFO_FL_FILLED;
+
+	if (o2info_to_user(oib, req))
+		goto bail;
+
+	status = 0;
+bail:
+	return status;
+}
+
+int ocfs2_info_handle_clustersize(struct inode *inode,
+				  struct ocfs2_info_request __user *req)
+{
+	int status = -EFAULT;
+	struct ocfs2_info_clustersize oic;
+	struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
+
+	if (o2info_from_user(oic, req))
+		goto bail;
+
+	oic.ic_clustersize = osb->s_clustersize;
+	oic.ic_req.ir_flags |= OCFS2_INFO_FL_FILLED;
+
+	if (o2info_to_user(oic, req))
+		goto bail;
+
+	status = 0;
+bail:
+	return status;
+}
+
+int ocfs2_info_handle_maxslots(struct inode *inode,
+			       struct ocfs2_info_request __user *req)
+{
+	int status = -EFAULT;
+	struct ocfs2_info_maxslots oim;
+	struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
+
+	if (o2info_from_user(oim, req))
+		goto bail;
+
+	oim.im_max_slots = osb->max_slots;
+	oim.im_req.ir_flags |= OCFS2_INFO_FL_FILLED;
+
+	if (o2info_to_user(oim, req))
+		goto bail;
+
+	status = 0;
+bail:
+	return status;
+}
+
+int ocfs2_info_handle_label(struct inode *inode,
+			    struct ocfs2_info_request __user *req)
+{
+	int status = -EFAULT;
+	struct ocfs2_info_label oil;
+	struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
+
+	if (o2info_from_user(oil, req))
+		goto bail;
+
+	memcpy(oil.il_label, osb->vol_label, OCFS2_MAX_VOL_LABEL_LEN);
+	oil.il_req.ir_flags |= OCFS2_INFO_FL_FILLED;
+
+	if (o2info_to_user(oil, req))
+		goto bail;
+
+	status = 0;
+bail:
+	return status;
+}
+
+int ocfs2_info_handle_uuid(struct inode *inode,
+			   struct ocfs2_info_request __user *req)
+{
+	int status = -EFAULT;
+	struct ocfs2_info_uuid oiu;
+	struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
+
+	if (o2info_from_user(oiu, req))
+		goto bail;
+
+	memcpy(oiu.iu_uuid_str, osb->uuid_str, OCFS2_VOL_UUIDSTR_LEN);
+	oiu.iu_req.ir_flags |= OCFS2_INFO_FL_FILLED;
+
+	if (o2info_to_user(oiu, req))
+		goto bail;
+
+	status = 0;
+bail:
+	return status;
+}
+
+int ocfs2_info_handle_fs_features(struct inode *inode,
+				  struct ocfs2_info_request __user *req)
+{
+	int status = -EFAULT;
+	struct ocfs2_info_fs_features oif;
+	struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
+
+	if (o2info_from_user(oif, req))
+		goto bail;
+
+	oif.if_compat_features = osb->s_feature_compat;
+	oif.if_incompat_features = osb->s_feature_incompat;
+	oif.if_ro_compat_features = osb->s_feature_ro_compat;
+	oif.if_req.ir_flags |= OCFS2_INFO_FL_FILLED;
+
+	if (o2info_to_user(oif, req))
+		goto bail;
+
+	status = 0;
+bail:
+	return status;
+}
+
+int ocfs2_info_handle_unknown(struct inode *inode,
+			      struct ocfs2_info_request __user *req)
+{
+	int status = -EFAULT;
+	struct ocfs2_info_request oir;
+
+	if (o2info_from_user(oir, req))
+		goto bail;
+
+	oir.ir_flags &= ~OCFS2_INFO_FL_FILLED;
+
+	if (o2info_to_user(oir, req))
+		goto bail;
+
+	status = 0;
+bail:
+	return status;
+}
+
+/*
+ * Validate and distinguish OCFS2_IOC_INFO requests.
+ *
+ * - validate the magic number.
+ * - distinguish different requests.
+ * - validate size of different requests.
+ */
+int ocfs2_info_handle_request(struct inode *inode,
+			      struct ocfs2_info_request __user *req)
+{
+	int status = -EFAULT;
+	struct ocfs2_info_request oir;
+
+	if (o2info_from_user(oir, req))
+		goto bail;
+
+	status = -EINVAL;
+	if (oir.ir_magic != OCFS2_INFO_MAGIC)
+		goto bail;
+
+	switch (oir.ir_code) {
+	case OCFS2_INFO_BLOCKSIZE:
+		if (oir.ir_size == sizeof(struct ocfs2_info_blocksize))
+			status = ocfs2_info_handle_blocksize(inode, req);
+		break;
+	case OCFS2_INFO_CLUSTERSIZE:
+		if (oir.ir_size == sizeof(struct ocfs2_info_clustersize))
+			status = ocfs2_info_handle_clustersize(inode, req);
+		break;
+	case OCFS2_INFO_MAXSLOTS:
+		if (oir.ir_size == sizeof(struct ocfs2_info_maxslots))
+			status = ocfs2_info_handle_maxslots(inode, req);
+		break;
+	case OCFS2_INFO_LABEL:
+		if (oir.ir_size == sizeof(struct ocfs2_info_label))
+			status = ocfs2_info_handle_label(inode, req);
+		break;
+	case OCFS2_INFO_UUID:
+		if (oir.ir_size == sizeof(struct ocfs2_info_uuid))
+			status = ocfs2_info_handle_uuid(inode, req);
+		break;
+	case OCFS2_INFO_FS_FEATURES:
+		if (oir.ir_size == sizeof(struct ocfs2_info_fs_features))
+			status = ocfs2_info_handle_fs_features(inode, req);
+		break;
+	default:
+		status = ocfs2_info_handle_unknown(inode, req);
+		break;
+	}
+
+bail:
+	return status;
+}
+
+/*
+ * OCFS2_IOC_INFO handles an array of requests passed from userspace.
+ *
+ * ocfs2_info_handle() recevies a large info aggregation, grab and
+ * validate the request count from header, then break it into small
+ * pieces, later specific handlers can handle them one by one.
+ *
+ * Idea here is to make each separate request small enough to ensure
+ * a better backward&forward compatibility, since a small piece of
+ * request will be less likely to be broken if disk layout get changed.
+ */
+int ocfs2_info_handle(struct inode *inode, struct ocfs2_info *info,
+		      int compat_flag)
+{
+	int i, status = 0;
+	u64 req_addr;
+	struct ocfs2_info_request __user *reqp;
+
+	if ((info->oi_count > OCFS2_INFO_MAX_REQUEST) ||
+	    (!info->oi_requests)) {
+		status = -EINVAL;
+		goto bail;
+	}
+
+	for (i = 0; i < info->oi_count; i++) {
+		status = -EFAULT;
+		if (compat_flag) {
+			if (get_user(req_addr,
+			     (u64 __user *)compat_ptr(info->oi_requests) + i))
+				goto bail;
+		} else {
+			if (get_user(req_addr,
+				     (u64 __user *)(info->oi_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:
+	return status;
+}
+
 long ocfs2_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
 {
 	struct inode *inode = filp->f_path.dentry->d_inode;
@@ -120,6 +381,7 @@ long ocfs2_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
 	struct reflink_arguments args;
 	const char *old_path, *new_path;
 	bool preserve;
+	struct ocfs2_info info;
 
 	switch (cmd) {
 	case OCFS2_IOC_GETFLAGS:
@@ -174,6 +436,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, 0);
 	default:
 		return -ENOTTY;
 	}
@@ -185,6 +453,7 @@ long ocfs2_compat_ioctl(struct file *file, unsigned cmd, unsigned long arg)
 	bool preserve;
 	struct reflink_arguments args;
 	struct inode *inode = file->f_path.dentry->d_inode;
+	struct ocfs2_info info;
 
 	switch (cmd) {
 	case OCFS2_IOC32_GETFLAGS:
@@ -209,6 +478,12 @@ long ocfs2_compat_ioctl(struct file *file, unsigned cmd, unsigned long arg)
 
 		return ocfs2_reflink_ioctl(inode, compat_ptr(args.old_path),
 					   compat_ptr(args.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, 1);
 	default:
 		return -ENOIOCTLCMD;
 	}
fs/ocfs2/ocfs2_ioctl.h +80 -0
index 2d3420a..12a5502 100644
@@ -76,4 +76,84 @@ struct reflink_arguments {
 };
 #define OCFS2_IOC_REFLINK	_IOW('o', 4, struct reflink_arguments)
 
+/* Following definitions dedicated for ocfs2_info_request ioctls. */
+#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 oi_requests;	/* Array of __u64 pointers to requests */
+	__u32 oi_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 ic_req;
+	__u32 ic_clustersize;
+};
+
+struct ocfs2_info_blocksize {
+	struct ocfs2_info_request ib_req;
+	__u32 ib_blocksize;
+};
+
+struct ocfs2_info_maxslots {
+	struct ocfs2_info_request im_req;
+	__u16 im_max_slots;
+};
+
+struct ocfs2_info_label {
+	struct ocfs2_info_request il_req;
+	__u8	il_label[OCFS2_MAX_VOL_LABEL_LEN];
+};
+
+struct ocfs2_info_uuid {
+	struct ocfs2_info_request iu_req;
+	__u8	iu_uuid_str[OCFS2_VOL_UUIDSTR_LEN];
+};
+
+struct ocfs2_info_fs_features {
+	struct ocfs2_info_request if_req;
+	__u32 if_compat_features;
+	__u32 if_incompat_features;
+	__u32 if_ro_compat_features;
+};
+
+/* Codes for ocfs2_info_request */
+enum ocfs2_info_type {
+	OCFS2_INFO_CLUSTERSIZE = 1,
+	OCFS2_INFO_BLOCKSIZE,
+	OCFS2_INFO_MAXSLOTS,
+	OCFS2_INFO_LABEL,
+	OCFS2_INFO_UUID,
+	OCFS2_INFO_FS_FEATURES,
+	OCFS2_INFO_NUM_TYPES
+};
+
+/* 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 */
#3 lore raw

PATCH 1/2 Ocfs2: Add macro OCFS2_VOL_UUIDSTR_LEN in ocfs2_fs.h

In reply to Tristan Ye
Quoted 21 lines · Tristan Ye

Since we've been using uuid_str in most of ocfs2 codes, adding such a macro would be helpful.

---
 fs/ocfs2/ocfs2_fs.h |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)
fs/ocfs2/ocfs2_fs.h +1 -0
index bb37218..b313c83 100644
@@ -274,6 +274,7 @@
 
 #define OCFS2_VOL_UUID_LEN		16
 #define OCFS2_MAX_VOL_LABEL_LEN		64
+#define OCFS2_VOL_UUIDSTR_LEN		(OCFS2_VOL_UUID_LEN * 2 + 1)
 
 /* The alternate, userspace stack fields */
 #define OCFS2_STACK_LABEL_LEN		4
#4 lore raw

PATCH 1/2 Ocfs2: Add macro OCFS2_VOL_UUIDSTR_LEN in ocfs2_fs.h

In reply to Tristan Ye
Quoted 13 lines · Tristan Ye

Since we've been using uuid_str in most of ocfs2 codes, adding such a macro would be helpful.

---
 fs/ocfs2/ocfs2_fs.h |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)
fs/ocfs2/ocfs2_fs.h +0 -0
index bb37218..b313c83 100644

fs/ocfs2/ocfs2_fs.h line 277

Quoted 4 lines
fs/ocfs2/ocfs2_fs.h +1 -0
@@ -274,6 +274,7 @@
 
 #define OCFS2_VOL_UUID_LEN		16
 #define OCFS2_MAX_VOL_LABEL_LEN		64
+#define OCFS2_VOL_UUIDSTR_LEN		(OCFS2_VOL_UUID_LEN * 2 + 1)

Do we want this _LEN macro to include the NUL?

Joel

Signature · 10 lines
"Sometimes I think the surest sign intelligent
 life exists elsewhere in the universe is that
 none of it has tried to contact us."
                                -Calvin & Hobbes

Joel Becker
Principal Software Developer
Oracle
E-mail: joel.becker at oracle.com
Phone: (650) 506-8127
#5 lore raw

PATCH 1/2 Ocfs2: Add macro OCFS2_VOL_UUIDSTR_LEN in ocfs2_fs.h

In reply to Tristan Ye
Quoted 13 lines · Tristan Ye

Since we've been using uuid_str in most of ocfs2 codes, adding such a macro would be helpful.

---
 fs/ocfs2/ocfs2_fs.h |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)
fs/ocfs2/ocfs2_fs.h +0 -0
index bb37218..b313c83 100644

fs/ocfs2/ocfs2_fs.h line 277

Quoted 4 lines
fs/ocfs2/ocfs2_fs.h +1 -0
@@ -274,6 +274,7 @@
 
 #define OCFS2_VOL_UUID_LEN		16
 #define OCFS2_MAX_VOL_LABEL_LEN		64
+#define OCFS2_VOL_UUIDSTR_LEN		(OCFS2_VOL_UUID_LEN * 2 + 1)

Also, why is this in ocfs2_fs.h? It's not a structural
feature.

Joel

Signature · 9 lines
"If you are ever in doubt as to whether or not to kiss a pretty girl, 
 give her the benefit of the doubt"
                                        -Thomas Carlyle

Joel Becker
Principal Software Developer
Oracle
E-mail: joel.becker at oracle.com
Phone: (650) 506-8127
#6 lore raw

PATCH 1/2 Ocfs2: Add macro OCFS2_VOL_UUIDSTR_LEN in ocfs2_fs.h

True. I had asked Tristan to put it in ocfs2.h

Quoted 27 lines · Joel Becker
Quoted 13 lines · Tristan Ye

Since we've been using uuid_str in most of ocfs2 codes, adding such a macro would be helpful.

---
 fs/ocfs2/ocfs2_fs.h |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)
fs/ocfs2/ocfs2_fs.h +0 -0
index bb37218..b313c83 100644

fs/ocfs2/ocfs2_fs.h line 278

Quoted 5 lines
fs/ocfs2/ocfs2_fs.h +1 -0
@@ -274,6 +274,7 @@
 
 #define OCFS2_VOL_UUID_LEN		16
 #define OCFS2_MAX_VOL_LABEL_LEN		64
+#define OCFS2_VOL_UUIDSTR_LEN		(OCFS2_VOL_UUID_LEN * 2 + 1)
 

Also, why is this in ocfs2_fs.h? It's not a structural
feature.

Joel

#7 lore raw

PATCH 1/2 Ocfs2: Add macro OCFS2_VOL_UUIDSTR_LEN in ocfs2_fs.h

ok. So how about we remove this #define totally and have the ioctl interface return the binary uuid. The o2info tool can convert do the conversion.

Quoted 40 lines · Sunil Mushran

True. I had asked Tristan to put it in ocfs2.h

Quoted 25 lines · Joel Becker
Quoted 13 lines · Tristan Ye

Since we've been using uuid_str in most of ocfs2 codes, adding such a macro would be helpful.

---
 fs/ocfs2/ocfs2_fs.h |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)
fs/ocfs2/ocfs2_fs.h +0 -0
index bb37218..b313c83 100644

fs/ocfs2/ocfs2_fs.h line 279

Quoted 6 lines
fs/ocfs2/ocfs2_fs.h +1 -0
@@ -274,6 +274,7 @@
 
 #define OCFS2_VOL_UUID_LEN		16
 #define OCFS2_MAX_VOL_LABEL_LEN		64
+#define OCFS2_VOL_UUIDSTR_LEN		(OCFS2_VOL_UUID_LEN * 2 + 1)
 
 

Also, why is this in ocfs2_fs.h? It's not a structural
feature.

Quoted 4 lines

Joel

_______________________________________________
Ocfs2-devel mailing list
Ocfs2-devel at oss.oracle.com
http://oss.oracle.com/mailman/listinfo/ocfs2-devel

author
#8 lore raw

PATCH 1/2 Ocfs2: Add macro OCFS2_VOL_UUIDSTR_LEN in ocfs2_fs.h

Quoted 3 lines · Sunil Mushran

ok. So how about we remove this #define totally and have the ioctl interface return the binary uuid. The o2info tool can convert do the conversion.

But... returning binary uuid from o2info was not that easy, ocfs2 in-memory super_block osb only successfully initialized the osb->uuid, while did nothing to uuid_str, I remembered we've been discussing on that issue:

http://oss.oracle.com/pipermail/ocfs2-devel/2009-November/005514.html

That patch was not adopted, and we're still using uuid_str in most places.

Tristan.

Quoted 35 lines
Quoted 32 lines · Sunil Mushran

True. I had asked Tristan to put it in ocfs2.h

Quoted 15 lines · Joel Becker
Quoted 14 lines · Tristan Ye

Since we've been using uuid_str in most of ocfs2 codes, adding such a macro would be helpful.

---
fs/ocfs2/ocfs2_fs.h | 1 +

1 files changed, 1 insertions(+), 0 deletions(-)
fs/ocfs2/ocfs2_fs.h +0 -0
index bb37218..b313c83 100644
@@ -274,6 +274,7 @@
 
Quoted 8 lines

fs/ocfs2/ocfs2_fs.h line 277

Quoted 3 lines
fs/ocfs2/ocfs2_fs.h +1 -0
 #define OCFS2_VOL_UUID_LEN 16
 #define OCFS2_MAX_VOL_LABEL_LEN 64
+#define OCFS2_VOL_UUIDSTR_LEN (OCFS2_VOL_UUID_LEN * 2 + 1)

Also, why is this in ocfs2_fs.h? It's not a structural feature.

Joel

_______________________________________________
Ocfs2-devel mailing list
Ocfs2-devel at oss.oracle.com
http://oss.oracle.com/mailman/listinfo/ocfs2-devel

author
#9 lore raw

PATCH 1/2 Ocfs2: Add macro OCFS2_VOL_UUIDSTR_LEN in ocfs2_fs.h

Quoted 9 lines · tristan
Quoted 3 lines · Sunil Mushran

ok. So how about we remove this #define totally and have the ioctl interface return the binary uuid. The o2info tool can convert do the conversion.

But... returning binary uuid from o2info was not that easy, ocfs2 in-memory super_block osb only successfully initialized the osb->uuid, while did nothing to uuid_str, I remembered we've been discussing on that issue:

Oh, sorry for the typo here , I meant it successfully initialized osb->uuid_str, while did nothing to osb->uuid.

Quoted 47 lines

http://oss.oracle.com/pipermail/ocfs2-devel/2009-November/005514.html

That patch was not adopted, and we're still using uuid_str in most places.

Tristan.

Quoted 25 lines
Quoted 24 lines · Sunil Mushran

True. I had asked Tristan to put it in ocfs2.h

Quoted 21 lines · Joel Becker
Quoted 13 lines · Tristan Ye

Since we've been using uuid_str in most of ocfs2 codes, adding such a macro would be helpful.

---
fs/ocfs2/ocfs2_fs.h | 1 +

1 files changed, 1 insertions(+), 0 deletions(-)
fs/ocfs2/ocfs2_fs.h +0 -0
index bb37218..b313c83 100644

fs/ocfs2/ocfs2_fs.h line 277

Quoted 4 lines
fs/ocfs2/ocfs2_fs.h +1 -0
@@ -274,6 +274,7 @@
 
 #define OCFS2_VOL_UUID_LEN 16
 #define OCFS2_MAX_VOL_LABEL_LEN 64
+#define OCFS2_VOL_UUIDSTR_LEN (OCFS2_VOL_UUID_LEN * 2 + 1)

Also, why is this in ocfs2_fs.h? It's not a structural feature.

Quoted 7 lines
Quoted 7 lines
Quoted 2 lines

Joel

_______________________________________________
Ocfs2-devel mailing list
Ocfs2-devel at oss.oracle.com
http://oss.oracle.com/mailman/listinfo/ocfs2-devel

_______________________________________________
Ocfs2-devel mailing list
Ocfs2-devel at oss.oracle.com
http://oss.oracle.com/mailman/listinfo/ocfs2-devel

#10 lore raw

PATCH 1/2 Ocfs2: Add macro OCFS2_VOL_UUIDSTR_LEN in ocfs2_fs.h

In reply to tristan
Quoted 10 lines · tristan
Quoted 3 lines · Sunil Mushran

ok. So how about we remove this #define totally and have the ioctl interface return the binary uuid. The o2info tool can convert do the conversion.

But... returning binary uuid from o2info was not that easy, ocfs2 in-memory super_block osb only successfully initialized the osb->uuid, while did nothing to uuid_str, I remembered we've been discussing on that issue:

Quoted 5 lines

http://oss.oracle.com/pipermail/ocfs2-devel/2009-November/005514.html

That patch was not adopted, and we're still using uuid_str in most places.

Ok. Thanks for reminding me.

It appears we already have OCFS2_TEXT_UUID_LEN in stack_user.c. That's a clean name. In the patch below, I have moved it to ocfs2.h so that we can use it elsewhere.

http://oss.oracle.com/~smushran/0001-ocfs2-Cleanup-uuid-strings.patch

I am waiting for Joel to comment. If he approves, then you can use the same #define in your ioctl.

#11 lore raw

PATCH 1/2 Ocfs2: Add macro OCFS2_VOL_UUIDSTR_LEN in ocfs2_fs.h

Quoted 19 lines · Sunil Mushran
Quoted 10 lines · tristan
Quoted 3 lines · Sunil Mushran

ok. So how about we remove this #define totally and have the ioctl interface return the binary uuid. The o2info tool can convert do the conversion.

But... returning binary uuid from o2info was not that easy, ocfs2 in-memory super_block osb only successfully initialized the osb->uuid, while did nothing to uuid_str, I remembered we've been discussing on that issue:

Quoted 5 lines

http://oss.oracle.com/pipermail/ocfs2-devel/2009-November/005514.html

That patch was not adopted, and we're still using uuid_str in most places.

Ok. Thanks for reminding me.

Quoted 8 lines

It appears we already have OCFS2_TEXT_UUID_LEN in stack_user.c. That's a clean name. In the patch below, I have moved it to ocfs2.h so that we can use it elsewhere.

http://oss.oracle.com/~smushran/0001-ocfs2-Cleanup-uuid-strings.patch

I am waiting for Joel to comment. If he approves, then you can use the same #define in your ioctl.

I'm glad you like the name, and I'm fine with you adding it to
ocfs2.h, but it should not be removing the define from stack_user.c. Note that stack_user.c does not include ocfs2.h.

Joel

Signature · 9 lines
"Any man who is under 30, and is not a liberal, has not heart;
 and any man who is over 30, and is not a conservative, has no brains."
         - Sir Winston Churchill 

Joel Becker
Principal Software Developer
Oracle
E-mail: joel.becker at oracle.com
Phone: (650) 506-8127
author
#12 lore raw

PATCH 1/2 Ocfs2: Add macro OCFS2_VOL_UUIDSTR_LEN in ocfs2_fs.h

In reply to Sunil Mushran
Quoted 24 lines · Sunil Mushran

True. I had asked Tristan to put it in ocfs2.h

Quoted 21 lines · Joel Becker
Quoted 13 lines · Tristan Ye

Since we've been using uuid_str in most of ocfs2 codes, adding such a macro would be helpful.

---
fs/ocfs2/ocfs2_fs.h | 1 +

1 files changed, 1 insertions(+), 0 deletions(-)
fs/ocfs2/ocfs2_fs.h +0 -0
index bb37218..b313c83 100644

fs/ocfs2/ocfs2_fs.h line 277

Quoted 4 lines
fs/ocfs2/ocfs2_fs.h +1 -0
@@ -274,6 +274,7 @@
 
 #define ' 16
 #define OCFS2_MAX_VOL_LABEL_LEN 64
+#define OCFS2_VOL_UUIDSTR_LEN (OCFS2_VOL_UUID_LEN * 2 + 1)

Also, why is this in ocfs2_fs.h? It's not a structural feature.

Yes I remembered sunil has asked me to add this in ocfs2.h, that's really my fault.

I thought it should be together with 'OCFS2_VOL_UUID_LEN', that's definitely wrong.

Quoted 4 lines
Quoted 3 lines

Joel