From: rpeterso@sourceware.org <rpeterso@sourceware.org>
To: cluster-devel.redhat.com
Subject: [Cluster-devel] cluster/gfs-kernel/src/gfs gfs_ioctl.h ioctl.c ...
Date: 24 Jan 2008 20:54:32 -0000 [thread overview]
Message-ID: <20080124205432.7457.qmail@sourceware.org> (raw)
CVSROOT: /cvs/cluster
Module name: cluster
Changes by: rpeterso at sourceware.org 2008-01-24 20:54:31
Modified files:
gfs-kernel/src/gfs: gfs_ioctl.h ioctl.c ioctl.h ops_file.c
Log message:
Resolves: bz 429633: gfs_tool doesn't recognize GFS file sytem
Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/gfs-kernel/src/gfs/gfs_ioctl.h.diff?cvsroot=cluster&r1=1.11&r2=1.12
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/gfs-kernel/src/gfs/ioctl.c.diff?cvsroot=cluster&r1=1.17&r2=1.18
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/gfs-kernel/src/gfs/ioctl.h.diff?cvsroot=cluster&r1=1.3&r2=1.4
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/gfs-kernel/src/gfs/ops_file.c.diff?cvsroot=cluster&r1=1.36&r2=1.37
--- cluster/gfs-kernel/src/gfs/gfs_ioctl.h 2006/07/10 23:22:34 1.11
+++ cluster/gfs-kernel/src/gfs/gfs_ioctl.h 2008/01/24 20:54:31 1.12
@@ -22,12 +22,23 @@
#define GFS_IOCTL_SUPER _GFSC_(45)
struct gfs_ioctl {
- unsigned int gi_argc;
- char **gi_argv;
+ unsigned int gi_argc;
+ char **gi_argv;
char __user *gi_data;
+ unsigned int gi_size;
+ uint64_t gi_offset;
+};
+
+#ifdef CONFIG_COMPAT
+struct gfs_ioctl_compat {
+ unsigned int gi_argc;
+ uint32_t gi_argv;
+
+ uint32_t gi_data;
unsigned int gi_size;
uint64_t gi_offset;
};
+#endif
#endif /* ___GFS_IOCTL_DOT_H__ */
--- cluster/gfs-kernel/src/gfs/ioctl.c 2007/06/19 21:26:11 1.17
+++ cluster/gfs-kernel/src/gfs/ioctl.c 2008/01/24 20:54:31 1.18
@@ -19,6 +19,7 @@
#include <linux/completion.h>
#include <linux/buffer_head.h>
#include <asm/uaccess.h>
+#include <linux/compat.h>
#include "gfs_ioctl.h"
#include "gfs.h"
@@ -509,7 +510,7 @@
*/
static int
-gi_set_tune(struct gfs_sbd *sdp, struct gfs_ioctl *gi)
+gi_set_tune(struct gfs_sbd *sdp, struct gfs_ioctl *gi, int from_user)
{
struct gfs_tune *gt = &sdp->sd_tune;
char param[ARG_SIZE], value[ARG_SIZE];
@@ -521,12 +522,21 @@
if (gi->gi_argc != 3)
return -EINVAL;
- if (strncpy_from_user(param, gi->gi_argv[1], ARG_SIZE) < 0)
- return -EFAULT;
+ if (from_user) {
+ if (strncpy_from_user(param, gi->gi_argv[1], ARG_SIZE) < 0)
+ return -EFAULT;
+ } else {
+ strncpy(param, gi->gi_argv[1], ARG_SIZE);
+ }
param[ARG_SIZE - 1] = 0;
- if (strncpy_from_user(value, gi->gi_argv[2], ARG_SIZE) < 0)
- return -EFAULT;
+ if (from_user) {
+ if (strncpy_from_user(value, gi->gi_argv[2], ARG_SIZE) < 0)
+ return -EFAULT;
+ } else {
+ strncpy(value, gi->gi_argv[2], ARG_SIZE);
+ }
+
value[ARG_SIZE - 1] = 0;
if (strcmp(param, "ilimit1") == 0) {
@@ -884,7 +894,7 @@
*/
static int
-gi_set_file_flag(struct gfs_inode *ip, struct gfs_ioctl *gi)
+gi_set_file_flag(struct gfs_inode *ip, struct gfs_ioctl *gi, int from_user)
{
char buf[ARG_SIZE];
int set;
@@ -896,8 +906,12 @@
if (gi->gi_argc != 3)
return -EINVAL;
- if (strncpy_from_user(buf, gi->gi_argv[1], ARG_SIZE) < 0)
- return -EFAULT;
+ if (from_user) {
+ if (strncpy_from_user(buf, gi->gi_argv[1], ARG_SIZE) < 0)
+ return -EFAULT;
+ } else {
+ strncpy(buf, gi->gi_argv[1], ARG_SIZE);
+ }
buf[ARG_SIZE - 1] = 0;
if (strcmp(buf, "set") == 0)
@@ -907,8 +921,12 @@
else
return -EINVAL;
- if (strncpy_from_user(buf, gi->gi_argv[2], ARG_SIZE) < 0)
- return -EFAULT;
+ if (from_user) {
+ if (strncpy_from_user(buf, gi->gi_argv[2], ARG_SIZE) < 0)
+ return -EFAULT;
+ } else {
+ strncpy(buf, gi->gi_argv[2], ARG_SIZE);
+ }
buf[ARG_SIZE - 1] = 0;
error = gfs_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &i_gh);
@@ -1065,15 +1083,19 @@
*/
static struct gfs_inode *
-gi2hip(struct gfs_sbd *sdp, struct gfs_ioctl *gi)
+gi2hip(struct gfs_sbd *sdp, struct gfs_ioctl *gi, int from_user)
{
char buf[ARG_SIZE];
if (gi->gi_argc != 2)
return ERR_PTR(-EINVAL);
- if (strncpy_from_user(buf, gi->gi_argv[1], ARG_SIZE) < 0)
- return ERR_PTR(-EFAULT);
+ if (from_user) {
+ if (strncpy_from_user(buf, gi->gi_argv[1], ARG_SIZE) < 0)
+ return ERR_PTR(-EFAULT);
+ } else {
+ strncpy(buf, gi->gi_argv[1], ARG_SIZE);
+ }
buf[ARG_SIZE - 1] = 0;
if (strcmp(buf, "jindex") == 0)
@@ -1097,14 +1119,14 @@
*/
static int
-gi_get_hfile_stat(struct gfs_sbd *sdp, struct gfs_ioctl *gi)
+gi_get_hfile_stat(struct gfs_sbd *sdp, struct gfs_ioctl *gi, int from_user)
{
struct gfs_inode *ip;
struct gfs_dinode *di;
struct gfs_holder i_gh;
int error;
- ip = gi2hip(sdp, gi);
+ ip = gi2hip(sdp, gi, from_user);
if (IS_ERR(ip))
return PTR_ERR(ip);
@@ -1142,7 +1164,7 @@
*/
static int
-gi_do_hfile_read(struct gfs_sbd *sdp, struct gfs_ioctl *gi)
+gi_do_hfile_read(struct gfs_sbd *sdp, struct gfs_ioctl *gi, int from_user)
{
struct gfs_inode *ip;
struct gfs_holder i_gh;
@@ -1151,7 +1173,7 @@
if (!capable(CAP_SYS_ADMIN))
return -EACCES;
- ip = gi2hip(sdp, gi);
+ ip = gi2hip(sdp, gi, from_user);
if (IS_ERR(ip))
return PTR_ERR(ip);
@@ -1179,7 +1201,7 @@
*/
static int
-gi_do_hfile_write(struct gfs_sbd *sdp, struct gfs_ioctl *gi)
+gi_do_hfile_write(struct gfs_sbd *sdp, struct gfs_ioctl *gi, int from_user)
{
struct gfs_inode *ip;
struct gfs_alloc *al = NULL;
@@ -1191,7 +1213,7 @@
if (!capable(CAP_SYS_ADMIN))
return -EACCES;
- ip = gi2hip(sdp, gi);
+ ip = gi2hip(sdp, gi, from_user);
if (IS_ERR(ip))
return PTR_ERR(ip);
@@ -1248,8 +1270,12 @@
goto out_relse;
}
- error = gfs_writei(ip, gi->gi_data, gi->gi_offset, gi->gi_size,
- gfs_copy_from_user, NULL);
+ if (from_user)
+ error = gfs_writei(ip, gi->gi_data, gi->gi_offset, gi->gi_size,
+ gfs_copy_from_user, NULL);
+ else
+ error = gfs_writei(ip, gi->gi_data, gi->gi_offset, gi->gi_size,
+ gfs_copy_from_mem, NULL);
gfs_trans_end(sdp);
@@ -1283,7 +1309,7 @@
*/
static int
-gi_do_hfile_trunc(struct gfs_sbd *sdp, struct gfs_ioctl *gi)
+gi_do_hfile_trunc(struct gfs_sbd *sdp, struct gfs_ioctl *gi, int from_user)
{
struct gfs_inode *ip;
struct gfs_holder i_gh;
@@ -1292,7 +1318,7 @@
if (!capable(CAP_SYS_ADMIN))
return -EACCES;
- ip = gi2hip(sdp, gi);
+ ip = gi2hip(sdp, gi, from_user);
if (IS_ERR(ip))
return PTR_ERR(ip);
@@ -1335,7 +1361,7 @@
*/
static int
-gi_do_quota_refresh(struct gfs_sbd *sdp, struct gfs_ioctl *gi)
+gi_do_quota_refresh(struct gfs_sbd *sdp, struct gfs_ioctl *gi, int from_user)
{
char buf[ARG_SIZE];
int user;
@@ -1346,8 +1372,12 @@
if (gi->gi_argc != 2)
return -EINVAL;
- if (strncpy_from_user(buf, gi->gi_argv[1], ARG_SIZE) < 0)
- return -EFAULT;
+ if (from_user) {
+ if (strncpy_from_user(buf, gi->gi_argv[1], ARG_SIZE) < 0)
+ return -EFAULT;
+ } else {
+ strncpy(buf, gi->gi_argv[1], ARG_SIZE);
+ }
buf[ARG_SIZE - 1] = 0;
switch (buf[0]) {
@@ -1379,7 +1409,7 @@
*/
static int
-gi_do_quota_read(struct gfs_sbd *sdp, struct gfs_ioctl *gi)
+gi_do_quota_read(struct gfs_sbd *sdp, struct gfs_ioctl *gi, int from_user)
{
char buf[ARG_SIZE];
int user;
@@ -1392,8 +1422,12 @@
if (gi->gi_size != sizeof(struct gfs_quota))
return -EINVAL;
- if (strncpy_from_user(buf, gi->gi_argv[1], ARG_SIZE) < 0)
- return -EFAULT;
+ if (from_user) {
+ if (strncpy_from_user(buf, gi->gi_argv[1], ARG_SIZE) < 0)
+ return -EFAULT;
+ } else {
+ strncpy(buf, gi->gi_argv[1], ARG_SIZE);
+ }
buf[ARG_SIZE - 1] = 0;
switch (buf[0]) {
@@ -1423,8 +1457,64 @@
return 0;
}
+int
+gfs_ioctl_i_local(struct gfs_inode *ip, struct gfs_ioctl *gi, const char *arg0,
+ int from_user)
+{
+ int error = -EFAULT;
+
+ if (strcmp(arg0, "get_cookie") == 0)
+ error = gi_skeleton(ip, gi, gi_get_cookie);
+ else if (strcmp(arg0, "get_super") == 0)
+ error = gi_get_super(ip->i_sbd, gi);
+ else if (strcmp(arg0, "get_args") == 0)
+ error = gi_skeleton(ip, gi, gi_get_args);
+ else if (strcmp(arg0, "get_lockstruct") == 0)
+ error = gi_skeleton(ip, gi, gi_get_lockstruct);
+ else if (strcmp(arg0, "get_stat_gfs") == 0)
+ error = gi_skeleton(ip, gi, gi_get_stat_gfs);
+ else if (strcmp(arg0, "get_counters") == 0)
+ error = gi_skeleton(ip, gi, gi_get_counters);
+ else if (strcmp(arg0, "get_tune") == 0)
+ error = gi_skeleton(ip, gi, gi_get_tune);
+ else if (strcmp(arg0, "set_tune") == 0)
+ error = gi_set_tune(ip->i_sbd, gi, from_user);
+ else if (strcmp(arg0, "do_reclaim") == 0)
+ error = gi_skeleton(ip, gi, gi_do_reclaim);
+ else if (strcmp(arg0, "do_shrink") == 0)
+ error = gi_do_shrink(ip->i_sbd, gi);
+ else if (strcmp(arg0, "get_file_stat") == 0)
+ error = gi_get_file_stat(ip, gi);
+ else if (strcmp(arg0, "set_file_flag") == 0)
+ error = gi_set_file_flag(ip, gi, from_user);
+ else if (strcmp(arg0, "get_file_meta") == 0)
+ error = gi_get_file_meta(ip, gi);
+ else if (strcmp(arg0, "get_file_meta_quota") == 0)
+ error = gi_get_file_meta(ip->i_sbd->sd_qinode, &gi);
+ else if (strcmp(arg0, "do_file_flush") == 0)
+ error = gi_do_file_flush(ip, gi);
+ else if (strcmp(arg0, "get_hfile_stat") == 0)
+ error = gi_get_hfile_stat(ip->i_sbd, gi, from_user);
+ else if (strcmp(arg0, "do_hfile_read") == 0)
+ error = gi_do_hfile_read(ip->i_sbd, gi, from_user);
+ else if (strcmp(arg0, "do_hfile_write") == 0)
+ error = gi_do_hfile_write(ip->i_sbd, gi, from_user);
+ else if (strcmp(arg0, "do_hfile_trunc") == 0)
+ error = gi_do_hfile_trunc(ip->i_sbd, gi, from_user);
+ else if (strcmp(arg0, "do_quota_sync") == 0)
+ error = gi_do_quota_sync(ip->i_sbd, gi);
+ else if (strcmp(arg0, "do_quota_refresh") == 0)
+ error = gi_do_quota_refresh(ip->i_sbd, gi, from_user);
+ else if (strcmp(arg0, "do_quota_read") == 0)
+ error = gi_do_quota_read(ip->i_sbd, gi, from_user);
+ else
+ error = -ENOTTY;
+
+ return error;
+}
+
/**
- * gfs_ioctl_i -
+ * gfs_ioctl_i - Normal ioctls
* @ip:
* @arg:
*
@@ -1455,58 +1545,73 @@
if (strncpy_from_user(arg0, argv[0], ARG_SIZE) < 0)
goto out;
arg0[ARG_SIZE - 1] = 0;
-
- if (strcmp(arg0, "get_cookie") == 0)
- error = gi_skeleton(ip, &gi, gi_get_cookie);
- else if (strcmp(arg0, "get_super") == 0)
- error = gi_get_super(ip->i_sbd, &gi);
- else if (strcmp(arg0, "get_args") == 0)
- error = gi_skeleton(ip, &gi, gi_get_args);
- else if (strcmp(arg0, "get_lockstruct") == 0)
- error = gi_skeleton(ip, &gi, gi_get_lockstruct);
- else if (strcmp(arg0, "get_stat_gfs") == 0)
- error = gi_skeleton(ip, &gi, gi_get_stat_gfs);
- else if (strcmp(arg0, "get_counters") == 0)
- error = gi_skeleton(ip, &gi, gi_get_counters);
- else if (strcmp(arg0, "get_tune") == 0)
- error = gi_skeleton(ip, &gi, gi_get_tune);
- else if (strcmp(arg0, "set_tune") == 0)
- error = gi_set_tune(ip->i_sbd, &gi);
- else if (strcmp(arg0, "do_reclaim") == 0)
- error = gi_skeleton(ip, &gi, gi_do_reclaim);
- else if (strcmp(arg0, "do_shrink") == 0)
- error = gi_do_shrink(ip->i_sbd, &gi);
- else if (strcmp(arg0, "get_file_stat") == 0)
- error = gi_get_file_stat(ip, &gi);
- else if (strcmp(arg0, "set_file_flag") == 0)
- error = gi_set_file_flag(ip, &gi);
- else if (strcmp(arg0, "get_file_meta") == 0)
- error = gi_get_file_meta(ip, &gi);
- else if (strcmp(arg0, "get_file_meta_quota") == 0)
- error = gi_get_file_meta(ip->i_sbd->sd_qinode, &gi);
- else if (strcmp(arg0, "do_file_flush") == 0)
- error = gi_do_file_flush(ip, &gi);
- else if (strcmp(arg0, "get_hfile_stat") == 0)
- error = gi_get_hfile_stat(ip->i_sbd, &gi);
- else if (strcmp(arg0, "do_hfile_read") == 0)
- error = gi_do_hfile_read(ip->i_sbd, &gi);
- else if (strcmp(arg0, "do_hfile_write") == 0)
- error = gi_do_hfile_write(ip->i_sbd, &gi);
- else if (strcmp(arg0, "do_hfile_trunc") == 0)
- error = gi_do_hfile_trunc(ip->i_sbd, &gi);
- else if (strcmp(arg0, "do_quota_sync") == 0)
- error = gi_do_quota_sync(ip->i_sbd, &gi);
- else if (strcmp(arg0, "do_quota_refresh") == 0)
- error = gi_do_quota_refresh(ip->i_sbd, &gi);
- else if (strcmp(arg0, "do_quota_read") == 0)
- error = gi_do_quota_read(ip->i_sbd, &gi);
- else
- error = -ENOTTY;
-
+ error = gfs_ioctl_i_local(ip, &gi, arg0, 1);
out:
kfree(argv);
return error;
}
+#ifdef CONFIG_COMPAT
+/**
+ * gfs_ioctl_i_compat - compatibility ioctls
+ * These ioctls are used to provide ioctls for situations
+ * where userland and kernel arch is different.
+ * For example, userland may be 32-bit ppc whereas the
+ * kernel may be ppc64. In this case, we need to do
+ * extra translation between the addresses.
+ * @ip:
+ * @arg:
+ *
+ * Returns: -errno or positive byte count
+ */
+
+int
+gfs_ioctl_i_compat(struct gfs_inode *ip, unsigned long arg)
+{
+ struct gfs_ioctl_compat *src;
+ struct gfs_ioctl dst;
+ char **argv, *argptr;
+ uint32_t *ptr;
+ char arg0[ARG_SIZE];
+ char *tmparg;
+ int i;
+ int error = -EFAULT;
+
+ src = (struct gfs_ioctl_compat *)compat_ptr(arg);
+
+ memset(&dst, 0, sizeof(dst));
+ dst.gi_argc = src->gi_argc;
+ dst.gi_size = src->gi_size;
+ dst.gi_offset = src->gi_offset;
+
+ argv = kmalloc(dst.gi_argc * sizeof(char *), GFP_KERNEL);
+ if (!argv)
+ return -ENOMEM;
+
+ memset(argv, 0, dst.gi_argc * sizeof(char *));
+ ptr = (uint32_t *)compat_ptr(src->gi_argv);
+
+ for (i = 0; i < dst.gi_argc; i++) { /* for each parm */
+ tmparg = kmalloc(ARG_SIZE * sizeof(char *), GFP_KERNEL);
+ if (!tmparg)
+ goto out;
+ argptr = (char *)compat_ptr(*ptr);
+ if (strncpy_from_user(tmparg, argptr, ARG_SIZE) < 0)
+ goto out;
+ argv[i] = tmparg;
+ ptr++;
+ }
+ strncpy(arg0, argv[0], ARG_SIZE);
+ arg0[ARG_SIZE - 1] = 0;
+ dst.gi_argv = argv;
+ dst.gi_data = compat_ptr(src->gi_data);
+ error = gfs_ioctl_i_local(ip, &dst, arg0, 0);
+ out:
+ for (i = 0; i < dst.gi_argc; i++)
+ kfree(argv[i]);
+ kfree(argv);
+ return error;
+}
+#endif
--- cluster/gfs-kernel/src/gfs/ioctl.h 2006/07/10 23:22:34 1.3
+++ cluster/gfs-kernel/src/gfs/ioctl.h 2008/01/24 20:54:31 1.4
@@ -14,6 +14,9 @@
#ifndef __IOCTL_DOT_H__
#define __IOCTL_DOT_H__
+int gfs_ioctl_i_local(struct gfs_inode *ip, struct gfs_ioctl *gi,
+ const char *arg0, int from_user);
+int gfs_ioctl_i_compat(struct gfs_inode *ip, unsigned long arg);
int gfs_ioctl_i(struct gfs_inode *ip, void *arg);
#endif /* __IOCTL_DOT_H__ */
--- cluster/gfs-kernel/src/gfs/ops_file.c 2007/07/13 15:19:16 1.36
+++ cluster/gfs-kernel/src/gfs/ops_file.c 2008/01/24 20:54:31 1.37
@@ -26,6 +26,7 @@
#include <linux/aio.h>
#include <linux/writeback.h>
#include <asm/uaccess.h>
+#include <linux/compat.h>
#include "gfs_ioctl.h"
#include "gfs.h"
@@ -333,17 +334,17 @@
goto out_gunlock;
count = do_read_readi(file, buf, size & ~mask, offset, iocb);
- }
- else {
- if (!iocb)
- count = do_sync_read(file, buf, size, offset);
- else {
- struct iovec local_iov = { .iov_base = buf, .iov_len = size};
-
- count = generic_file_aio_read(iocb, &local_iov, 1, *offset);
- iocb->ki_pos = *offset;
- }
- }
+ }
+ else {
+ if (!iocb)
+ count = do_sync_read(file, buf, size, offset);
+ else {
+ struct iovec local_iov = { .iov_base = buf, .iov_len = size};
+
+ count = generic_file_aio_read(iocb, &local_iov, 1, *offset);
+ iocb->ki_pos = *offset;
+ }
+ }
error = 0;
@@ -387,17 +388,17 @@
if (gfs_is_jdata(ip) ||
(gfs_is_stuffed(ip) && !test_bit(GIF_PAGED, &ip->i_flags)))
- count = do_read_readi(file, buf, size, offset, iocb);
- else {
- if (!iocb) {
- count = do_sync_read(file, buf, size, offset);
- } else {
- struct iovec local_iov = { .iov_base = buf, .iov_len = size};
-
- count = generic_file_aio_read(iocb, &local_iov, 1, *offset);
- iocb->ki_pos = *offset;
- }
- }
+ count = do_read_readi(file, buf, size, offset, iocb);
+ else {
+ if (!iocb) {
+ count = do_sync_read(file, buf, size, offset);
+ } else {
+ struct iovec local_iov = { .iov_base = buf, .iov_len = size};
+
+ count = generic_file_aio_read(iocb, &local_iov, 1, *offset);
+ iocb->ki_pos = *offset;
+ }
+ }
gfs_glock_dq_m(num_gh + 1, ghs);
@@ -438,16 +439,16 @@
/*
* gfs_aio_read: match with vfs generic_file_aio_read as:
- * (struct kiocb *iocb, char __user *buf, size_t count, loff_t pos)
+ * (struct kiocb *iocb, char __user *buf, size_t count, loff_t pos)
*/
static ssize_t
gfs_aio_read(struct kiocb *iocb, const struct iovec *iov, unsigned long count,
- loff_t pos)
+ loff_t pos)
{
- struct file *filp = iocb->ki_filp;
+ struct file *filp = iocb->ki_filp;
- BUG_ON(iocb->ki_pos != pos);
- return(__gfs_read(filp, iov->iov_base, iov->iov_len, &iocb->ki_pos, iocb));
+ BUG_ON(iocb->ki_pos != pos);
+ return(__gfs_read(filp, iov->iov_base, iov->iov_len, &iocb->ki_pos, iocb));
}
/**
@@ -493,27 +494,27 @@
*/
static ssize_t
gfs_file_aio_write_nolock(struct file *file, char *buf, size_t size,
- loff_t *offset, struct kiocb *iocb)
+ loff_t *offset, struct kiocb *iocb)
{
- struct iovec local_iov = { .iov_base = buf, .iov_len = size };
- struct kiocb local_iocb, *kiocb = NULL;
- ssize_t count;
-
- if (!iocb) {
- init_sync_kiocb(&local_iocb, file);
- local_iocb.ki_nr_segs = 1;
- kiocb = &local_iocb;
- }
- else
- kiocb = iocb;
-
- kiocb->ki_pos = *offset;
- count = generic_file_aio_write_nolock(kiocb, &local_iov, kiocb->ki_nr_segs,
- kiocb->ki_pos);
- *offset = kiocb->ki_pos;
- if (kiocb == &local_iocb && count == -EIOCBQUEUED)
- count = wait_on_sync_kiocb(kiocb);
- return count;
+ struct iovec local_iov = { .iov_base = buf, .iov_len = size };
+ struct kiocb local_iocb, *kiocb = NULL;
+ ssize_t count;
+
+ if (!iocb) {
+ init_sync_kiocb(&local_iocb, file);
+ local_iocb.ki_nr_segs = 1;
+ kiocb = &local_iocb;
+ }
+ else
+ kiocb = iocb;
+
+ kiocb->ki_pos = *offset;
+ count = generic_file_aio_write_nolock(kiocb, &local_iov, kiocb->ki_nr_segs,
+ kiocb->ki_pos);
+ *offset = kiocb->ki_pos;
+ if (kiocb == &local_iocb && count == -EIOCBQUEUED)
+ count = wait_on_sync_kiocb(kiocb);
+ return count;
}
/**
@@ -533,12 +534,12 @@
struct kiocb *iocb)
{
struct inode *inode = file->f_mapping->host;
- struct gfs_inode *ip = get_v2ip(inode);
- struct gfs_sbd *sdp = ip->i_sbd;
- struct gfs_alloc *al = NULL;
- struct buffer_head *dibh;
- unsigned int data_blocks, ind_blocks;
- ssize_t count;
+ struct gfs_inode *ip = get_v2ip(inode);
+ struct gfs_sbd *sdp = ip->i_sbd;
+ struct gfs_alloc *al = NULL;
+ struct buffer_head *dibh;
+ unsigned int data_blocks, ind_blocks;
+ ssize_t count;
int error;
gfs_write_calc_reserv(ip, size, &data_blocks, &ind_blocks);
@@ -583,13 +584,13 @@
}
if (gfs_is_stuffed(ip)) { error = gfs_unstuff_dinode(ip, gfs_unstuffer_sync, NULL); if (error)
- goto fail_end_trans;
- }
+ goto fail_end_trans;
+ }
- count = gfs_file_aio_write_nolock(file, buf, size, offset, iocb);
- if (count < 0) {
- error = count;
- goto fail_end_trans;
+ count = gfs_file_aio_write_nolock(file, buf, size, offset, iocb);
+ if (count < 0) {
+ error = count;
+ goto fail_end_trans;
}
error = gfs_get_inode_buffer(ip, &dibh);
@@ -747,23 +748,23 @@
buf += error;
size -= error;
- count += error;
- }
- } else {
- struct gfs_holder t_gh;
+ count += error;
+ }
+ } else {
+ struct gfs_holder t_gh;
- clear_bit(GFF_DID_DIRECT_ALLOC, &fp->f_flags);
+ clear_bit(GFF_DID_DIRECT_ALLOC, &fp->f_flags);
error = gfs_glock_nq_init(sdp->sd_trans_gl, LM_ST_SHARED, 0, &t_gh);
if (error)
goto out_gunlock;
- /* Todo: It would be nice if init_sync_kiocb is exported.
- * .. wcheng
- */
- count = gfs_file_aio_write_nolock(file, buf, size, offset, iocb);
- gfs_glock_dq_uninit(&t_gh);
- }
+ /* Todo: It would be nice if init_sync_kiocb is exported.
+ * .. wcheng
+ */
+ count = gfs_file_aio_write_nolock(file, buf, size, offset, iocb);
+ gfs_glock_dq_uninit(&t_gh);
+ }
out_iocb_write:
error = 0;
@@ -881,13 +882,13 @@
ClearPageUptodate(page);
page_cache_release(page);
}
- }
- *offset += count;
- } else {
- count = gfs_file_aio_write_nolock(file, buf, size, offset, iocb);
- if (count < 0) {
- error = count;
- goto fail_end_trans;
+ }
+ *offset += count;
+ } else {
+ count = gfs_file_aio_write_nolock(file, buf, size, offset, iocb);
+ if (count < 0) {
+ error = count;
+ goto fail_end_trans;
}
error = gfs_get_inode_buffer(ip, &dibh);
@@ -1061,14 +1062,14 @@
static ssize_t
gfs_aio_write(struct kiocb *iocb, const struct iovec *iov, unsigned long segs,
- loff_t pos)
+ loff_t pos)
{
- struct file *file = iocb->ki_filp;
+ struct file *file = iocb->ki_filp;
- BUG_ON(iocb->ki_pos != pos);
+ BUG_ON(iocb->ki_pos != pos);
- return(__gfs_write(file, iov->iov_base, iov->iov_len, &iocb->ki_pos,
- iocb));
+ return(__gfs_write(file, iov->iov_base, iov->iov_len, &iocb->ki_pos,
+ iocb));
}
/**
@@ -1373,6 +1374,41 @@
}
}
+#ifdef CONFIG_COMPAT
+/**
+ * gfs_compat_ioctl - do an ioctl on a file - compatible between 32-64 bit
+ * @inode: the inode
+ * @file: the file pointer
+ * @cmd: the ioctl command
+ * @arg: the argument
+ *
+ * Returns: errno
+ */
+
+static long
+gfs_compat_ioctl(struct file *file, unsigned cmd, unsigned long arg)
+{
+ struct gfs_inode *ip = get_v2ip(file->f_mapping->host);
+
+ atomic_inc(&ip->i_sbd->sd_ops_file);
+
+ switch (cmd) {
+ case GFS_IOCTL_IDENTIFY: {
+ unsigned int x = GFS_MAGIC;
+ if (copy_to_user((unsigned int *)arg, &x, sizeof(unsigned int)))
+ return -EFAULT;
+ return 0;
+ }
+
+ case GFS_IOCTL_SUPER:
+ return gfs_ioctl_i_compat(ip, arg);
+
+ default:
+ return -ENOTTY;
+ }
+}
+#endif
+
/**
* gfs_mmap - We don't support shared writable mappings right now
* @file: The file to map
@@ -1577,24 +1613,24 @@
if (!(fl->fl_flags & FL_POSIX))
return -ENOLCK;
- if ((ip->i_di.di_mode & (S_ISGID | S_IXGRP)) == S_ISGID)
- return -ENOLCK;
+ if ((ip->i_di.di_mode & (S_ISGID | S_IXGRP)) == S_ISGID)
+ return -ENOLCK;
- if (sdp->sd_args.ar_localflocks) {
- if (IS_GETLK(cmd)) {
- posix_test_lock(file, fl);
- return 0;
- } else {
- return posix_lock_file_wait(file, fl);
- }
- }
+ if (sdp->sd_args.ar_localflocks) {
+ if (IS_GETLK(cmd)) {
+ posix_test_lock(file, fl);
+ return 0;
+ } else {
+ return posix_lock_file_wait(file, fl);
+ }
+ }
- if (IS_GETLK(cmd))
- return gfs_lm_plock_get(sdp, &name, file, fl);
- else if (fl->fl_type == F_UNLCK)
+ if (IS_GETLK(cmd))
+ return gfs_lm_plock_get(sdp, &name, file, fl);
+ else if (fl->fl_type == F_UNLCK)
return gfs_lm_punlock(sdp, &name, file, fl);
else
- return gfs_lm_plock(sdp, &name, file, cmd, fl);
+ return gfs_lm_plock(sdp, &name, file, cmd, fl);
}
#if 0
@@ -1635,7 +1671,7 @@
out:
gfs_holder_uninit(&gh);
- return retval;
+ return retval;
}
#endif
@@ -1731,22 +1767,22 @@
static int
gfs_flock(struct file *file, int cmd, struct file_lock *fl)
{
- struct gfs_inode *ip = get_v2ip(file->f_mapping->host);
- struct gfs_sbd *sdp = ip->i_sbd;
+ struct gfs_inode *ip = get_v2ip(file->f_mapping->host);
+ struct gfs_sbd *sdp = ip->i_sbd;
- atomic_inc(&ip->i_sbd->sd_ops_file);
+ atomic_inc(&ip->i_sbd->sd_ops_file);
if (!(fl->fl_flags & FL_FLOCK))
return -ENOLCK;
- if ((ip->i_di.di_mode & (S_ISGID | S_IXGRP)) == S_ISGID)
- return -ENOLCK;
+ if ((ip->i_di.di_mode & (S_ISGID | S_IXGRP)) == S_ISGID)
+ return -ENOLCK;
- if (sdp->sd_args.ar_localflocks)
- return flock_lock_file_wait(file, fl);
+ if (sdp->sd_args.ar_localflocks)
+ return flock_lock_file_wait(file, fl);
- if (fl->fl_type == F_UNLCK) {
- do_unflock(file, fl);
- return 0;
+ if (fl->fl_type == F_UNLCK) {
+ do_unflock(file, fl);
+ return 0;
} else
return do_flock(file, cmd, fl);
}
@@ -1758,21 +1794,27 @@
.aio_read = gfs_aio_read,
.aio_write = gfs_aio_write,
.ioctl = gfs_ioctl,
+#ifdef CONFIG_COMPAT
+ .compat_ioctl = gfs_compat_ioctl,
+#endif
.mmap = gfs_mmap,
.open = gfs_open,
- .release = gfs_close,
- .fsync = gfs_fsync,
- .lock = gfs_lock,
- /* .sendfile = gfs_sendfile, */
- .flock = gfs_flock,
+ .release = gfs_close,
+ .fsync = gfs_fsync,
+ .lock = gfs_lock,
+ /* .sendfile = gfs_sendfile, */
+ .flock = gfs_flock,
};
struct file_operations gfs_dir_fops = {
.readdir = gfs_readdir,
.ioctl = gfs_ioctl,
+#ifdef CONFIG_COMPAT
+ .compat_ioctl = gfs_compat_ioctl,
+#endif
.open = gfs_open,
.release = gfs_close,
.fsync = gfs_fsync,
- .lock = gfs_lock,
- .flock = gfs_flock,
+ .lock = gfs_lock,
+ .flock = gfs_flock,
};
next reply other threads:[~2008-01-24 20:54 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-01-24 20:54 rpeterso [this message]
-- strict thread matches above, loose matches on Subject: below --
2008-01-24 21:25 [Cluster-devel] cluster/gfs-kernel/src/gfs gfs_ioctl.h ioctl.c rpeterso
2008-01-24 20:51 rpeterso
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=20080124205432.7457.qmail@sourceware.org \
--to=rpeterso@sourceware.org \
/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.