From 2b3a22fea0509681d9e86d5131a0008165bbf6ba Mon Sep 17 00:00:00 2001 From: Miklos Szeredi Date: Tue, 19 Jun 2007 09:23:02 +0000 Subject: [PATCH] kernel: sync with mainline (2.6.22) --- ChangeLog | 9 +++++++++ kernel/configure.ac | 9 ++++++++- kernel/file.c | 5 ++++- kernel/fuse_i.h | 9 +++++++++ kernel/inode.c | 40 ++++++++++++++++++++++++++++++++++++++-- 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 + + * kernel: sync with mainline (2.6.22) + +2007-06-18 Miklos Szeredi + + * Send debug output to stderr instead of stdout. Patch by Jan + Engelhardt + 2007-06-03 Miklos Szeredi * 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 #include #include +#include #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 #include #include +#include MODULE_AUTHOR("Miklos Szeredi "); 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 +#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; -- 2.30.2