aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog9
-rw-r--r--kernel/configure.ac9
-rw-r--r--kernel/file.c5
-rw-r--r--kernel/fuse_i.h9
-rw-r--r--kernel/inode.c40
5 files changed, 68 insertions, 4 deletions
diff --git a/ChangeLog b/ChangeLog
index 9e8a830..59653aa 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2007-06-19 Miklos Szeredi <miklos@szeredi.hu>
+
+ * kernel: sync with mainline (2.6.22)
+
+2007-06-18 Miklos Szeredi <miklos@szeredi.hu>
+
+ * Send debug output to stderr instead of stdout. Patch by Jan
+ Engelhardt
+
2007-06-03 Miklos Szeredi <miklos@szeredi.hu>
* libulockmgr: Work around a kernel bug in recv(), causing it to
diff --git a/kernel/configure.ac b/kernel/configure.ac
index 0427afd..ef44a15 100644
--- a/kernel/configure.ac
+++ b/kernel/configure.ac
@@ -193,8 +193,15 @@ if test "$ENABLE_FUSE_MODULE" = y; then
else
AC_MSG_RESULT([no])
fi
+ AC_MSG_CHECKING([if kernel has exportfs.h ])
+ if test -f $kernelsrc/include/linux/exportfs.h; then
+ AC_DEFINE(HAVE_EXPORTFS_H, 1, [kernel has exportfs.h])
+ AC_MSG_RESULT([yes])
+ else
+ AC_MSG_RESULT([no])
+ fi
AC_MSG_CHECKING([if kernel has BLOCK option ])
- if test -f $kernelsrc/block/Kconfig && egrep -wq "config *BLOCK" $kernelsrc/block/Kconfig; then
+ if test -f $kernelsrc/block/Kconfig && egrep -q "config *BLOCK" $kernelsrc/block/Kconfig; then
AC_DEFINE(HAVE_CONFIG_BLOCK, 1, [kernel has BLOCK option])
AC_MSG_RESULT([yes])
else
diff --git a/kernel/file.c b/kernel/file.c
index fc03b1e..dd198d0 100644
--- a/kernel/file.c
+++ b/kernel/file.c
@@ -11,6 +11,7 @@
#include <linux/pagemap.h>
#include <linux/slab.h>
#include <linux/kernel.h>
+#include <linux/sched.h>
#ifndef KERNEL_2_6_11_PLUS
static inline loff_t page_offset(struct page *page)
@@ -787,7 +788,9 @@ static int fuse_file_lock(struct file *file, int cmd, struct file_lock *fl)
if (cmd == F_GETLK) {
if (fc->no_lock) {
-#ifdef KERNEL_2_6_17_PLUS
+#ifdef KERNEL_2_6_22_PLUS
+ posix_test_lock(file, fl);
+#elif defined(KERNEL_2_6_17_PLUS)
if (!posix_test_lock(file, fl, fl))
fl->fl_type = F_UNLCK;
#else
diff --git a/kernel/fuse_i.h b/kernel/fuse_i.h
index b80b2aa..d226164 100644
--- a/kernel/fuse_i.h
+++ b/kernel/fuse_i.h
@@ -42,6 +42,9 @@
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,21)
# define KERNEL_2_6_21_PLUS
#endif
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22)
+# define KERNEL_2_6_22_PLUS
+#endif
#if defined(__arm__) && LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
#define DCACHE_BUG
@@ -85,6 +88,12 @@
#ifndef HAVE_CONFIG_BLOCK
#define CONFIG_BLOCK
#endif
+#ifndef FS_HAS_SUBTYPE
+#define FS_HAS_SUBTYPE 0
+#endif
+#ifndef FS_SAFE
+#define FS_SAFE 0
+#endif
/** Max number of pages that can be used in a single read request */
#define FUSE_MAX_PAGES_PER_REQ 32
diff --git a/kernel/inode.c b/kernel/inode.c
index e529427..a072f95 100644
--- a/kernel/inode.c
+++ b/kernel/inode.c
@@ -17,6 +17,7 @@
#include <linux/parser.h>
#include <linux/statfs.h>
#include <linux/random.h>
+#include <linux/sched.h>
MODULE_AUTHOR("Miklos Szeredi <miklos@szeredi.hu>");
MODULE_DESCRIPTION("Filesystem in Userspace");
@@ -345,6 +346,19 @@ static int parse_fuse_opt(char *opt, struct fuse_mount_data *d, int is_bdev)
d->max_read = ~0;
d->blksize = 512;
+ /*
+ * For unprivileged mounts use current uid/gid. Still allow
+ * "user_id" and "group_id" options for compatibility, but
+ * only if they match these values.
+ */
+ if (!capable(CAP_SYS_ADMIN)) {
+ d->user_id = current->uid;
+ d->user_id_present = 1;
+ d->group_id = current->gid;
+ d->group_id_present = 1;
+
+ }
+
while ((p = strsep(&opt, ",")) != NULL) {
int token;
int value;
@@ -373,6 +387,8 @@ static int parse_fuse_opt(char *opt, struct fuse_mount_data *d, int is_bdev)
case OPT_USER_ID:
if (match_int(&args[0], &value))
return 0;
+ if (d->user_id_present && d->user_id != value)
+ return 0;
d->user_id = value;
d->user_id_present = 1;
break;
@@ -380,6 +396,8 @@ static int parse_fuse_opt(char *opt, struct fuse_mount_data *d, int is_bdev)
case OPT_GROUP_ID:
if (match_int(&args[0], &value))
return 0;
+ if (d->group_id_present && d->group_id != value)
+ return 0;
d->group_id = value;
d->group_id_present = 1;
break;
@@ -491,6 +509,9 @@ static struct inode *get_root_inode(struct super_block *sb, unsigned mode)
return fuse_iget(sb, 1, 0, &attr);
}
#ifndef FUSE_MAINLINE
+#ifdef HAVE_EXPORTFS_H
+#include <linux/exportfs.h>
+#endif
static struct dentry *fuse_get_dentry(struct super_block *sb, void *vobjp)
{
__u32 *objp = vobjp;
@@ -642,6 +663,10 @@ static int fuse_fill_super(struct super_block *sb, void *data, int silent)
if (!parse_fuse_opt((char *) data, &d, is_bdev))
return -EINVAL;
+ /* This is a privileged option */
+ if ((d.flags & FUSE_ALLOW_OTHER) && !capable(CAP_SYS_ADMIN))
+ return -EPERM;
+
if (is_bdev) {
#ifdef CONFIG_BLOCK
if (!sb_set_blocksize(sb, d.blksize))
@@ -756,6 +781,7 @@ static struct file_system_type fuse_fs_type = {
.name = "fuse",
.get_sb = fuse_get_sb,
.kill_sb = kill_anon_super,
+ .fs_flags = FS_HAS_SUBTYPE | FS_SAFE,
};
#ifdef CONFIG_BLOCK
@@ -782,7 +808,7 @@ static struct file_system_type fuseblk_fs_type = {
.name = "fuseblk",
.get_sb = fuse_get_sb_blk,
.kill_sb = kill_block_super,
- .fs_flags = FS_REQUIRES_DEV,
+ .fs_flags = FS_REQUIRES_DEV | FS_HAS_SUBTYPE,
};
static inline int register_fuseblk(void)
@@ -816,9 +842,11 @@ static void fuse_inode_init_once(void *foo, struct kmem_cache *cachep,
{
struct inode * inode = foo;
+#ifndef KERNEL_2_6_22_PLUS
if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) ==
SLAB_CTOR_CONSTRUCTOR)
- inode_init_once(inode);
+#endif
+ inode_init_once(inode);
}
static int __init fuse_fs_init(void)
@@ -867,12 +895,20 @@ static int fuse_sysfs_init(void)
if (err)
return err;
#endif
+#ifdef KERNEL_2_6_22_PLUS
+ kobj_set_kset_s(&fuse_subsys, fs_subsys);
+#else
kset_set_kset_s(&fuse_subsys, fs_subsys);
+#endif
err = subsystem_register(&fuse_subsys);
if (err)
goto out_err;
+#ifdef KERNEL_2_6_22_PLUS
+ kobj_set_kset_s(&connections_subsys, fuse_subsys);
+#else
kset_set_kset_s(&connections_subsys, fuse_subsys);
+#endif
err = subsystem_register(&connections_subsys);
if (err)
goto out_fuse_unregister;