Commit c506da41 authored by Urban Widmark's avatar Urban Widmark Committed by Linus Torvalds

[PATCH] smbfs module unload and highuid

I haven't been doing much smbfs work recently, but here are some bugfixes:

- Fix module unload (Angus Sawyer).
- Fix the smbfs error handling if kernel_thread() should fail.
- Allow high uids/gids to be used as the fake uid smbfs sets as file owner.
parent 851cbb5f
......@@ -32,6 +32,8 @@ proto:
@echo >> proto2.h " */"
@echo >> proto2.h ""
@echo >> proto2.h "struct smb_request;"
@echo >> proto2.h "struct sock;"
@echo >> proto2.h "struct statfs;"
@echo >> proto2.h ""
cproto -E "gcc -E" -e -v -I $(TOPDIR)/include -DMAKING_PROTO -D__KERNEL__ $(SRC) >> proto2.h
mv proto2.h proto.h
......@@ -25,6 +25,7 @@
#include <linux/mount.h>
#include <linux/net.h>
#include <linux/vfs.h>
#include <linux/highuid.h>
#include <linux/smb_fs.h>
#include <linux/smbno.h>
#include <linux/smb_mount.h>
......@@ -446,6 +447,19 @@ smb_show_options(struct seq_file *s, struct vfsmount *m)
return 0;
}
static void
smb_unload_nls(struct smb_sb_info *server)
{
if (server->remote_nls) {
unload_nls(server->remote_nls);
server->remote_nls = NULL;
}
if (server->local_nls) {
unload_nls(server->local_nls);
server->local_nls = NULL;
}
}
static void
smb_put_super(struct super_block *sb)
{
......@@ -461,15 +475,7 @@ smb_put_super(struct super_block *sb)
kill_proc(server->conn_pid, SIGTERM, 1);
smb_kfree(server->ops);
if (server->remote_nls) {
unload_nls(server->remote_nls);
server->remote_nls = NULL;
}
if (server->local_nls) {
unload_nls(server->local_nls);
server->local_nls = NULL;
}
smb_unload_nls(server);
sb->s_fs_info = NULL;
smb_unlock_server(server);
smb_kfree(server);
......@@ -545,10 +551,8 @@ int smb_fill_super(struct super_block *sb, void *raw_data, int silent)
if (ver == SMB_MOUNT_OLDVERSION) {
mnt->version = oldmnt->version;
/* FIXME: is this enough to convert uid/gid's ? */
mnt->mounted_uid = oldmnt->mounted_uid;
mnt->uid = oldmnt->uid;
mnt->gid = oldmnt->gid;
mnt->uid = low2highuid(oldmnt->uid);
mnt->gid = low2highuid(oldmnt->gid);
mnt->file_mode = (oldmnt->file_mode & S_IRWXUGO) | S_IFREG;
mnt->dir_mode = (oldmnt->dir_mode & S_IRWXUGO) | S_IFDIR;
......@@ -557,9 +561,8 @@ int smb_fill_super(struct super_block *sb, void *raw_data, int silent)
} else {
if (parse_options(mnt, raw_data))
goto out_bad_option;
mnt->mounted_uid = current->uid;
}
mnt->mounted_uid = current->uid;
smb_setcodepage(server, &mnt->codepage);
/*
......@@ -571,6 +574,11 @@ int smb_fill_super(struct super_block *sb, void *raw_data, int silent)
else if (mnt->flags & SMB_MOUNT_DIRATTR)
printk("SMBFS: Using dir ff getattr\n");
if (smbiod_register_server(server) < 0) {
printk(KERN_ERR "smbfs: failed to start smbiod\n");
goto out_no_smbiod;
}
/*
* Keep the super block locked while we get the root inode.
*/
......@@ -584,12 +592,12 @@ int smb_fill_super(struct super_block *sb, void *raw_data, int silent)
goto out_no_root;
smb_new_dentry(sb->s_root);
smbiod_register_server(server);
return 0;
out_no_root:
iput(root_inode);
out_no_smbiod:
smb_unload_nls(server);
out_bad_option:
smb_kfree(mem);
out_no_mem:
......
/*
* Autogenerated with cproto on: Sun Sep 29 21:48:59 CEST 2002
* Autogenerated with cproto on: Sat Sep 13 17:18:51 CEST 2003
*/
struct smb_request;
......@@ -34,6 +34,7 @@ extern int smb_proc_read_link(struct smb_sb_info *server, struct dentry *d, char
extern int smb_proc_symlink(struct smb_sb_info *server, struct dentry *d, const char *oldpath);
extern int smb_proc_link(struct smb_sb_info *server, struct dentry *dentry, struct dentry *new_dentry);
extern int smb_proc_query_cifsunix(struct smb_sb_info *server);
extern void smb_install_null_ops(struct smb_ops *ops);
/* dir.c */
extern struct file_operations smb_dir_operations;
extern struct inode_operations smb_dir_inode_operations;
......@@ -71,7 +72,7 @@ extern struct inode_operations smb_file_inode_operations;
extern int smb_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg);
/* smbiod.c */
extern void smbiod_wake_up(void);
extern void smbiod_register_server(struct smb_sb_info *server);
extern int smbiod_register_server(struct smb_sb_info *server);
extern void smbiod_unregister_server(struct smb_sb_info *server);
extern void smbiod_flush(struct smb_sb_info *server);
extern int smbiod_retry(struct smb_sb_info *server);
......
......@@ -49,7 +49,7 @@ static spinlock_t servers_lock = SPIN_LOCK_UNLOCKED;
static long smbiod_flags;
static int smbiod(void *);
static void smbiod_start(void);
static int smbiod_start(void);
/*
* called when there's work for us to do
......@@ -65,30 +65,36 @@ void smbiod_wake_up()
/*
* start smbiod if none is running
*/
static void smbiod_start()
static int smbiod_start()
{
pid_t pid;
if (smbiod_state != SMBIOD_DEAD)
return;
return 0;
smbiod_state = SMBIOD_STARTING;
__module_get(THIS_MODULE);
spin_unlock(&servers_lock);
pid = kernel_thread(smbiod, NULL, 0);
if (pid < 0)
module_put(THIS_MODULE);
spin_lock(&servers_lock);
smbiod_state = SMBIOD_RUNNING;
smbiod_state = pid < 0 ? SMBIOD_DEAD : SMBIOD_RUNNING;
smbiod_pid = pid;
return pid;
}
/*
* register a server & start smbiod if necessary
*/
void smbiod_register_server(struct smb_sb_info *server)
int smbiod_register_server(struct smb_sb_info *server)
{
int ret;
spin_lock(&servers_lock);
list_add(&server->entry, &smb_servers);
VERBOSE("%p\n", server);
smbiod_start();
ret = smbiod_start();
spin_unlock(&servers_lock);
return ret;
}
/*
......@@ -282,7 +288,6 @@ static void smbiod_doio(struct smb_sb_info *server)
*/
static int smbiod(void *unused)
{
MOD_INC_USE_COUNT;
daemonize("smbiod");
allow_signal(SIGKILL);
......@@ -330,6 +335,5 @@ static int smbiod(void *unused)
}
VERBOSE("SMB Kernel thread exiting (%d) ...\n", current->pid);
MOD_DEC_USE_COUNT;
return 0;
module_put_and_exit(0);
}
......@@ -43,11 +43,11 @@ struct smb_mount_data {
struct smb_mount_data_kernel {
int version;
__kernel_uid_t mounted_uid; /* Who may umount() this filesystem? */
__kernel_uid_t uid;
__kernel_gid_t gid;
__kernel_mode_t file_mode;
__kernel_mode_t dir_mode;
uid_t mounted_uid; /* Who may umount() this filesystem? */
uid_t uid;
gid_t gid;
mode_t file_mode;
mode_t dir_mode;
u32 flags;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment