svn commit: r216785 - in projects/ofed/head/sys/ofed:
drivers/infiniband/core drivers/infiniband/hw/mlx4 include/linux
Jeff Roberson
jeff at FreeBSD.org
Wed Dec 29 02:24:43 UTC 2010
Author: jeff
Date: Wed Dec 29 02:24:43 2010
New Revision: 216785
URL: http://svn.freebsd.org/changeset/base/216785
Log:
- Eliminate file descriptor ifdefs related to get_unused_fd() and
alloc_file() by providing compatible wrappers for these functions.
- Add support for SIGIO based async file IO and the fasync()
file operation entry.
- Document a few cases that are missing compatibility shims and still
require work.
- Also document those ifdefs which do not require compatibility shims for
various reasons.
Sponsored by: Isilon Systems, iX Systems, and Panasas.
Modified:
projects/ofed/head/sys/ofed/drivers/infiniband/core/addr.c
projects/ofed/head/sys/ofed/drivers/infiniband/core/cma.c
projects/ofed/head/sys/ofed/drivers/infiniband/core/sysfs.c
projects/ofed/head/sys/ofed/drivers/infiniband/core/ucma.c
projects/ofed/head/sys/ofed/drivers/infiniband/core/umem.c
projects/ofed/head/sys/ofed/drivers/infiniband/core/uverbs_main.c
projects/ofed/head/sys/ofed/drivers/infiniband/hw/mlx4/main.c
projects/ofed/head/sys/ofed/include/linux/file.h
projects/ofed/head/sys/ofed/include/linux/fs.h
projects/ofed/head/sys/ofed/include/linux/linux_compat.c
Modified: projects/ofed/head/sys/ofed/drivers/infiniband/core/addr.c
==============================================================================
--- projects/ofed/head/sys/ofed/drivers/infiniband/core/addr.c Tue Dec 28 23:50:13 2010 (r216784)
+++ projects/ofed/head/sys/ofed/drivers/infiniband/core/addr.c Wed Dec 29 02:24:43 2010 (r216785)
@@ -585,6 +585,7 @@ void rdma_addr_cancel(struct rdma_dev_ad
EXPORT_SYMBOL(rdma_addr_cancel);
#ifdef __linux__
+/* XXX Need this callback to reduce timeout time. */
static int netevent_callback(struct notifier_block *self, unsigned long event,
void *ctx)
{
Modified: projects/ofed/head/sys/ofed/drivers/infiniband/core/cma.c
==============================================================================
--- projects/ofed/head/sys/ofed/drivers/infiniband/core/cma.c Tue Dec 28 23:50:13 2010 (r216784)
+++ projects/ofed/head/sys/ofed/drivers/infiniband/core/cma.c Wed Dec 29 02:24:43 2010 (r216785)
@@ -1682,6 +1682,7 @@ out:
}
#ifdef __linux__
+/* XXX I need to add an EVENTHANDLER based system for handling these events. */
static void cma_ndev_work_handler(struct work_struct *_work)
{
struct cma_ndev_work *work = container_of(_work, struct cma_ndev_work, work);
Modified: projects/ofed/head/sys/ofed/drivers/infiniband/core/sysfs.c
==============================================================================
--- projects/ofed/head/sys/ofed/drivers/infiniband/core/sysfs.c Tue Dec 28 23:50:13 2010 (r216784)
+++ projects/ofed/head/sys/ofed/drivers/infiniband/core/sysfs.c Wed Dec 29 02:24:43 2010 (r216785)
@@ -444,6 +444,7 @@ static void ib_device_release(struct dev
}
#ifdef __linux__
+/* BSD supports this through devfs(5) and devd(8). */
static int ib_device_uevent(struct device *device,
struct kobj_uevent_env *env)
{
Modified: projects/ofed/head/sys/ofed/drivers/infiniband/core/ucma.c
==============================================================================
--- projects/ofed/head/sys/ofed/drivers/infiniband/core/ucma.c Tue Dec 28 23:50:13 2010 (r216784)
+++ projects/ofed/head/sys/ofed/drivers/infiniband/core/ucma.c Wed Dec 29 02:24:43 2010 (r216785)
@@ -596,6 +596,7 @@ static void ucma_copy_iboe_route(struct
switch (route->num_paths) {
case 0:
dev_addr = &route->addr.dev_addr;
+ /* XXX Vlan missing. */
#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
dev = dev_get_by_index(&init_net, dev_addr->bound_dev_if);
if (dev) {
Modified: projects/ofed/head/sys/ofed/drivers/infiniband/core/umem.c
==============================================================================
--- projects/ofed/head/sys/ofed/drivers/infiniband/core/umem.c Tue Dec 28 23:50:13 2010 (r216784)
+++ projects/ofed/head/sys/ofed/drivers/infiniband/core/umem.c Wed Dec 29 02:24:43 2010 (r216785)
@@ -120,6 +120,7 @@ static void __ib_umem_release(struct ib_
chunk->nents, DMA_BIDIRECTIONAL, &chunk->attrs);
for (i = 0; i < chunk->nents; ++i) {
#ifdef __linux__
+ /* XXX I need to set the proper page flags here too. */
struct page *page = sg_page(&chunk->page_list[i]);
if (umem->writable && dirty)
set_page_dirty_lock(page);
Modified: projects/ofed/head/sys/ofed/drivers/infiniband/core/uverbs_main.c
==============================================================================
--- projects/ofed/head/sys/ofed/drivers/infiniband/core/uverbs_main.c Tue Dec 28 23:50:13 2010 (r216784)
+++ projects/ofed/head/sys/ofed/drivers/infiniband/core/uverbs_main.c Wed Dec 29 02:24:43 2010 (r216785)
@@ -121,6 +121,7 @@ static ssize_t (*uverbs_cmd_table[])(str
};
#ifdef __linux__
+/* BSD Does not require a fake mountpoint for all files. */
static struct vfsmount *uverbs_event_mnt;
#endif
@@ -372,14 +373,12 @@ static unsigned int ib_uverbs_event_poll
return pollflags;
}
-#ifdef __linux__
static int ib_uverbs_event_fasync(int fd, struct file *filp, int on)
{
struct ib_uverbs_event_file *file = filp->private_data;
return fasync_helper(fd, filp, on, &file->async_queue);
}
-#endif
static int ib_uverbs_event_close(struct inode *inode, struct file *filp)
{
@@ -409,9 +408,7 @@ static const struct file_operations uver
.read = ib_uverbs_event_read,
.poll = ib_uverbs_event_poll,
.release = ib_uverbs_event_close,
-#ifdef __linux__
.fasync = ib_uverbs_event_fasync
-#endif
};
void ib_uverbs_comp_handler(struct ib_cq *cq, void *cq_context)
@@ -448,10 +445,7 @@ void ib_uverbs_comp_handler(struct ib_cq
wake_up_interruptible(&file->poll_wait);
if (file->filp)
selwakeup(&file->filp->f_selinfo);
-#ifdef __linux__
- /* funsetown ? */
kill_fasync(&file->async_queue, SIGIO, POLL_IN);
-#endif
}
static void ib_uverbs_async_handler(struct ib_uverbs_file *file,
@@ -486,10 +480,7 @@ static void ib_uverbs_async_handler(stru
wake_up_interruptible(&file->async_file->poll_wait);
if (file->async_file->filp)
selwakeup(&file->async_file->filp->f_selinfo);
-#ifdef __linux__
- /* funsetown? */
kill_fasync(&file->async_file->async_queue, SIGIO, POLL_IN);
-#endif
}
void ib_uverbs_cq_event_handler(struct ib_event *event, void *context_ptr)
@@ -563,7 +554,6 @@ struct file *ib_uverbs_alloc_event_file(
ev_file->is_async = is_async;
ev_file->is_closed = 0;
-#ifdef __linux__
*fd = get_unused_fd();
if (*fd < 0) {
ret = *fd;
@@ -582,28 +572,12 @@ struct file *ib_uverbs_alloc_event_file(
goto err_fd;
}
-#else
- filp = kzalloc(sizeof(*filp), GFP_KERNEL);
- if (filp == NULL) {
- ret = -ENOMEM;
- goto err;
- }
- filp->f_op = &uverbs_event_fops;
- ret = falloc(curthread, &filp->_file, fd);
- if (ret) {
- ret = -ret;
- goto err;
- }
- finit(filp->_file, FREAD, DTYPE_DEV, filp, &badfileops);
-#endif
filp->private_data = ev_file;
return filp;
-#ifdef __linux__
err_fd:
put_unused_fd(*fd);
-#endif
err:
kfree(ev_file);
Modified: projects/ofed/head/sys/ofed/drivers/infiniband/hw/mlx4/main.c
==============================================================================
--- projects/ofed/head/sys/ofed/drivers/infiniband/hw/mlx4/main.c Tue Dec 28 23:50:13 2010 (r216784)
+++ projects/ofed/head/sys/ofed/drivers/infiniband/hw/mlx4/main.c Wed Dec 29 02:24:43 2010 (r216785)
@@ -1135,6 +1135,7 @@ static int update_ipv6_gids(struct mlx4_
goto out;
}
+ /* XXX vlan */
read_lock(&dev_base_lock);
for_each_netdev(&init_net, tmp) {
if (ndev && (tmp == ndev
@@ -1195,7 +1196,6 @@ static int update_ipv6_gids(struct mlx4_
out:
kfree(work);
return ret;
- return 0;
}
static void handle_en_event(struct mlx4_ib_dev *dev, int port, unsigned long event)
@@ -1221,6 +1221,7 @@ static void netdev_removed(struct mlx4_i
update_ipv6_gids(dev, port, 1);
}
+/* XXX netdev event needed. */
static int mlx4_ib_netdev_event(struct notifier_block *this, unsigned long event,
void *ptr)
{
Modified: projects/ofed/head/sys/ofed/include/linux/file.h
==============================================================================
--- projects/ofed/head/sys/ofed/include/linux/file.h Tue Dec 28 23:50:13 2010 (r216784)
+++ projects/ofed/head/sys/ofed/include/linux/file.h Wed Dec 29 02:24:43 2010 (r216785)
@@ -54,6 +54,10 @@ linux_fget(unsigned int fd)
static inline void
fput(struct linux_file *filp)
{
+ if (filp->_file == NULL) {
+ kfree(filp);
+ return;
+ }
if (refcount_release(&filp->_file->f_count)) {
_fdrop(filp->_file, curthread);
kfree(filp);
@@ -63,21 +67,53 @@ fput(struct linux_file *filp)
static inline void
put_unused_fd(unsigned int fd)
{
- struct linux_file *file;
+ struct file *file;
- file = linux_fget(fd);
+ file = fget_unlocked(curthread->td_proc->p_fd, fd);
if (file == NULL)
return;
- if (file->_file)
- fdclose(curthread->td_proc->p_fd, file->_file, fd, curthread);
+ fdclose(curthread->td_proc->p_fd, file, fd, curthread);
}
static inline void
fd_install(unsigned int fd, struct linux_file *filp)
{
- filp->_file->f_ops = &linuxfileops;
+ struct file *file;
+
+ file = fget_unlocked(curthread->td_proc->p_fd, fd);
+ filp->_file = file;
+ finit(file, filp->f_mode, DTYPE_DEV, filp, &linuxfileops);
+}
+
+static inline int
+get_unused_fd(void)
+{
+ struct file *file;
+ int error;
+ int fd;
+
+ error = falloc(curthread, &file, &fd);
+ if (error)
+ return -error;
+ return fd;
}
+static inline struct linux_file *
+_alloc_file(int mode, const struct file_operations *fops)
+{
+ struct linux_file *filp;
+
+ filp = kzalloc(sizeof(*filp), GFP_KERNEL);
+ if (filp == NULL)
+ return (NULL);
+ filp->f_op = fops;
+ filp->f_mode = mode;
+
+ return filp;
+}
+
+#define alloc_file(mnt, root, mode, fops) _alloc_file((mode), (fops))
+
#define file linux_file
#define fget linux_fget
Modified: projects/ofed/head/sys/ofed/include/linux/fs.h
==============================================================================
--- projects/ofed/head/sys/ofed/include/linux/fs.h Tue Dec 28 23:50:13 2010 (r216784)
+++ projects/ofed/head/sys/ofed/include/linux/fs.h Wed Dec 29 02:24:43 2010 (r216785)
@@ -68,12 +68,30 @@ struct linux_file {
const struct file_operations *f_op;
void *private_data;
int f_flags;
+ int f_mode; /* Just starting mode. */
struct dentry *f_dentry;
struct dentry f_dentry_store;
struct selinfo f_selinfo;
+ struct sigio *f_sigio;
};
-#define file linux_file
+#define file linux_file
+#define fasync_struct sigio *
+
+#define fasync_helper(fd, filp, on, queue) \
+({ \
+ if ((on)) \
+ *(queue) = &(filp)->f_sigio; \
+ else \
+ *(queue) = NULL; \
+ 0; \
+})
+
+#define kill_fasync(queue, sig, pollstat) \
+do { \
+ if (*(queue) != NULL) \
+ pgsigio(*(queue), (sig), 0); \
+} while (0)
typedef int (*filldir_t)(void *, const char *, int, loff_t, u64, unsigned);
@@ -86,6 +104,7 @@ struct file_operations {
int (*mmap)(struct file *, struct vm_area_struct *);
int (*open)(struct inode *, struct file *);
int (*release)(struct inode *, struct file *);
+ int (*fasync)(int, struct file *, int);
#if 0
/* We do not support these methods. Don't permit them to compile. */
loff_t (*llseek)(struct file *, loff_t, int);
@@ -100,7 +119,6 @@ struct file_operations {
int (*flush)(struct file *, fl_owner_t id);
int (*fsync)(struct file *, struct dentry *, int datasync);
int (*aio_fsync)(struct kiocb *, int datasync);
- int (*fasync)(int, struct file *, int);
int (*lock)(struct file *, int, struct file_lock *);
ssize_t (*sendpage)(struct file *, struct page *, int, size_t,
loff_t *, int);
@@ -115,6 +133,11 @@ struct file_operations {
int (*setlease)(struct file *, long, struct file_lock **);
#endif
};
+#define fops_get(fops) (fops)
+
+#define FMODE_READ FREAD
+#define FMODE_WRITE FWRITE
+#define FMODE_EXEC FEXEC
static inline int
register_chrdev_region(dev_t dev, unsigned range, const char *name)
Modified: projects/ofed/head/sys/ofed/include/linux/linux_compat.c
==============================================================================
--- projects/ofed/head/sys/ofed/include/linux/linux_compat.c Tue Dec 28 23:50:13 2010 (r216784)
+++ projects/ofed/head/sys/ofed/include/linux/linux_compat.c Wed Dec 29 02:24:43 2010 (r216785)
@@ -34,6 +34,9 @@
#include <sys/lock.h>
#include <sys/mutex.h>
#include <sys/bus.h>
+#include <sys/fcntl.h>
+#include <sys/file.h>
+#include <sys/filio.h>
#include <vm/vm.h>
#include <vm/pmap.h>
@@ -440,8 +443,6 @@ linux_dev_mmap_single(struct cdev *dev,
return (error);
}
-
-
struct cdevsw linuxcdevsw = {
.d_version = D_VERSION,
.d_flags = D_TRACKCLOSE,
@@ -510,15 +511,52 @@ linux_file_close(struct file *file, stru
filp = (struct linux_file *)file->f_data;
filp->f_flags = file->f_flag;
error = -filp->f_op->release(NULL, filp);
+ funsetown(&filp->f_sigio);
kfree(filp);
return (error);
}
+static int
+linux_file_ioctl(struct file *fp, u_long cmd, void *data, struct ucred *cred,
+ struct thread *td)
+{
+ struct linux_file *filp;
+ int error;
+
+ filp = (struct linux_file *)fp->f_data;
+ filp->f_flags = fp->f_flag;
+ error = 0;
+
+ switch (cmd) {
+ case FIONBIO:
+ break;
+ case FIOASYNC:
+ if (filp->f_op->fasync == NULL)
+ break;
+ error = filp->f_op->fasync(0, filp, fp->f_flag & FASYNC);
+ break;
+ case FIOSETOWN:
+ error = fsetown(*(int *)data, &filp->f_sigio);
+ if (error == 0)
+ error = filp->f_op->fasync(0, filp,
+ fp->f_flag & FASYNC);
+ break;
+ case FIOGETOWN:
+ *(int *)data = fgetown(&filp->f_sigio);
+ break;
+ default:
+ error = ENOTTY;
+ break;
+ }
+ return (error);
+}
+
struct fileops linuxfileops = {
.fo_read = linux_file_read,
.fo_poll = linux_file_poll,
- .fo_close = linux_file_close
+ .fo_close = linux_file_close,
+ .fo_ioctl = linux_file_ioctl
};
/*
More information about the svn-src-projects
mailing list