fedora core 6 1.2949 + vserver 2.2.0
[linux-2.6.git] / fs / smbfs / inode.c
index c8ca98a..84dfe3f 100644 (file)
@@ -7,7 +7,6 @@
  *  Please add a note about your changes to smbfs in the ChangeLog file.
  */
 
-#include <linux/config.h>
 #include <linux/module.h>
 #include <linux/time.h>
 #include <linux/kernel.h>
 
 static void smb_delete_inode(struct inode *);
 static void smb_put_super(struct super_block *);
-static int  smb_statfs(struct super_block *, struct kstatfs *);
+static int  smb_statfs(struct dentry *, struct kstatfs *);
 static int  smb_show_options(struct seq_file *, struct vfsmount *);
 
-static kmem_cache_t *smb_inode_cachep;
+static struct kmem_cache *smb_inode_cachep;
 
 static struct inode *smb_alloc_inode(struct super_block *sb)
 {
        struct smb_inode_info *ei;
-       ei = (struct smb_inode_info *)kmem_cache_alloc(smb_inode_cachep, SLAB_KERNEL);
+       ei = (struct smb_inode_info *)kmem_cache_alloc(smb_inode_cachep, GFP_KERNEL);
        if (!ei)
                return NULL;
        return &ei->vfs_inode;
@@ -67,7 +66,7 @@ static void smb_destroy_inode(struct inode *inode)
        kmem_cache_free(smb_inode_cachep, SMB_I(inode));
 }
 
-static void init_once(void * foo, kmem_cache_t * cachep, unsigned long flags)
+static void init_once(void * foo, struct kmem_cache * cachep, unsigned long flags)
 {
        struct smb_inode_info *ei = (struct smb_inode_info *) foo;
        unsigned long flagmask = SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR;
@@ -80,7 +79,8 @@ static int init_inodecache(void)
 {
        smb_inode_cachep = kmem_cache_create("smb_inode_cache",
                                             sizeof(struct smb_inode_info),
-                                            0, SLAB_HWCACHE_ALIGN|SLAB_RECLAIM_ACCOUNT,
+                                            0, (SLAB_RECLAIM_ACCOUNT|
+                                               SLAB_MEM_SPREAD),
                                             init_once, NULL);
        if (smb_inode_cachep == NULL)
                return -ENOMEM;
@@ -89,8 +89,7 @@ static int init_inodecache(void)
 
 static void destroy_inodecache(void)
 {
-       if (kmem_cache_destroy(smb_inode_cachep))
-               printk(KERN_INFO "smb_inode_cache: not all structures were freed\n");
+       kmem_cache_destroy(smb_inode_cachep);
 }
 
 static int smb_remount(struct super_block *sb, int *flags, char *data)
@@ -167,7 +166,6 @@ smb_get_inode_attr(struct inode *inode, struct smb_fattr *fattr)
        fattr->f_mtime  = inode->i_mtime;
        fattr->f_ctime  = inode->i_ctime;
        fattr->f_atime  = inode->i_atime;
-       fattr->f_blksize= inode->i_blksize;
        fattr->f_blocks = inode->i_blocks;
 
        fattr->attr     = SMB_I(inode)->attr;
@@ -201,7 +199,6 @@ smb_set_inode_attr(struct inode *inode, struct smb_fattr *fattr)
        inode->i_uid    = fattr->f_uid;
        inode->i_gid    = fattr->f_gid;
        inode->i_ctime  = fattr->f_ctime;
-       inode->i_blksize= fattr->f_blksize;
        inode->i_blocks = fattr->f_blocks;
        inode->i_size   = fattr->f_size;
        inode->i_mtime  = fattr->f_mtime;
@@ -216,7 +213,7 @@ smb_set_inode_attr(struct inode *inode, struct smb_fattr *fattr)
        if (inode->i_mtime.tv_sec != last_time || inode->i_size != last_sz) {
                VERBOSE("%ld changed, old=%ld, new=%ld, oz=%ld, nz=%ld\n",
                        inode->i_ino,
-                       (long) last_time, (long) inode->i_mtime,
+                       (long) last_time, (long) inode->i_mtime.tv_sec,
                        (long) last_sz, (long) inode->i_size);
 
                if (!S_ISDIR(inode->i_mode))
@@ -331,6 +328,7 @@ static void
 smb_delete_inode(struct inode *ino)
 {
        DEBUG1("ino=%ld\n", ino->i_ino);
+       truncate_inode_pages(&ino->i_data, 0);
        lock_kernel();
        if (smb_close(ino))
                PARANOIA("could not close inode %ld\n", ino->i_ino);
@@ -368,7 +366,6 @@ parse_options(struct smb_mount_data_kernel *mnt, char *options)
                                &optopt, &optarg, &flags, &value)) > 0) {
 
                VERBOSE("'%s' -> '%s'\n", optopt, optarg ? optarg : "<none>");
-
                switch (c) {
                case 1:
                        /* got a "flag" option */
@@ -383,15 +380,19 @@ parse_options(struct smb_mount_data_kernel *mnt, char *options)
                        break;
                case 'u':
                        mnt->uid = value;
+                       flags |= SMB_MOUNT_UID;
                        break;
                case 'g':
                        mnt->gid = value;
+                       flags |= SMB_MOUNT_GID;
                        break;
                case 'f':
                        mnt->file_mode = (value & S_IRWXUGO) | S_IFREG;
+                       flags |= SMB_MOUNT_FMODE;
                        break;
                case 'd':
                        mnt->dir_mode = (value & S_IRWXUGO) | S_IFDIR;
+                       flags |= SMB_MOUNT_DMODE;
                        break;
                case 'i':
                        strlcpy(mnt->codepage.local_name, optarg, 
@@ -429,9 +430,9 @@ smb_show_options(struct seq_file *s, struct vfsmount *m)
                if (mnt->flags & opts[i].flag)
                        seq_printf(s, ",%s", opts[i].name);
 
-       if (mnt->uid != 0)
+       if (mnt->flags & SMB_MOUNT_UID)
                seq_printf(s, ",uid=%d", mnt->uid);
-       if (mnt->gid != 0)
+       if (mnt->flags & SMB_MOUNT_GID)
                seq_printf(s, ",gid=%d", mnt->gid);
        if (mnt->mounted_uid != 0)
                seq_printf(s, ",mounted_uid=%d", mnt->mounted_uid);
@@ -440,8 +441,10 @@ smb_show_options(struct seq_file *s, struct vfsmount *m)
         * Defaults for file_mode and dir_mode are unknown to us; they
         * depend on the current umask of the user doing the mount.
         */
-       seq_printf(s, ",file_mode=%04o", mnt->file_mode & S_IRWXUGO);
-       seq_printf(s, ",dir_mode=%04o", mnt->dir_mode & S_IRWXUGO);
+       if (mnt->flags & SMB_MOUNT_FMODE)
+               seq_printf(s, ",file_mode=%04o", mnt->file_mode & S_IRWXUGO);
+       if (mnt->flags & SMB_MOUNT_DMODE)
+               seq_printf(s, ",dir_mode=%04o", mnt->dir_mode & S_IRWXUGO);
 
        if (strcmp(mnt->codepage.local_name, CONFIG_NLS_DEFAULT))
                seq_printf(s, ",iocharset=%s", mnt->codepage.local_name);
@@ -479,16 +482,17 @@ smb_put_super(struct super_block *sb)
        smb_close_socket(server);
 
        if (server->conn_pid)
-               kill_proc(server->conn_pid, SIGTERM, 1);
+               kill_pid(server->conn_pid, SIGTERM, 1);
 
-       smb_kfree(server->ops);
+       kfree(server->ops);
        smb_unload_nls(server);
        sb->s_fs_info = NULL;
        smb_unlock_server(server);
-       smb_kfree(server);
+       put_pid(server->conn_pid);
+       kfree(server);
 }
 
-int smb_fill_super(struct super_block *sb, void *raw_data, int silent)
+static int smb_fill_super(struct super_block *sb, void *raw_data, int silent)
 {
        struct smb_sb_info *server;
        struct smb_mount_data_kernel *mnt;
@@ -511,12 +515,12 @@ int smb_fill_super(struct super_block *sb, void *raw_data, int silent)
        sb->s_blocksize_bits = 10;
        sb->s_magic = SMB_SUPER_MAGIC;
        sb->s_op = &smb_sops;
+       sb->s_time_gran = 100;
 
-       server = smb_kmalloc(sizeof(struct smb_sb_info), GFP_KERNEL);
+       server = kzalloc(sizeof(struct smb_sb_info), GFP_KERNEL);
        if (!server)
                goto out_no_server;
        sb->s_fs_info = server;
-       memset(server, 0, sizeof(struct smb_sb_info));
 
        server->super_block = sb;
        server->mnt = NULL;
@@ -527,7 +531,7 @@ int smb_fill_super(struct super_block *sb, void *raw_data, int silent)
        INIT_LIST_HEAD(&server->xmitq);
        INIT_LIST_HEAD(&server->recvq);
        server->conn_error = 0;
-       server->conn_pid = 0;
+       server->conn_pid = NULL;
        server->state = CONN_INVALID; /* no connection yet */
        server->generation = 0;
 
@@ -535,8 +539,8 @@ int smb_fill_super(struct super_block *sb, void *raw_data, int silent)
        /* FIXME: move these to the smb_sb_info struct */
        VERBOSE("alloc chunk = %d\n", sizeof(struct smb_ops) +
                sizeof(struct smb_mount_data_kernel));
-       mem = smb_kmalloc(sizeof(struct smb_ops) +
-                         sizeof(struct smb_mount_data_kernel), GFP_KERNEL);
+       mem = kmalloc(sizeof(struct smb_ops) +
+                     sizeof(struct smb_mount_data_kernel), GFP_KERNEL);
        if (!mem)
                goto out_no_mem;
 
@@ -566,8 +570,13 @@ int smb_fill_super(struct super_block *sb, void *raw_data, int silent)
                mnt->file_mode = (oldmnt->file_mode & S_IRWXUGO) | S_IFREG;
                mnt->dir_mode = (oldmnt->dir_mode & S_IRWXUGO) | S_IFDIR;
 
-               mnt->flags = (oldmnt->file_mode >> 9);
+               mnt->flags = (oldmnt->file_mode >> 9) | SMB_MOUNT_UID |
+                       SMB_MOUNT_GID | SMB_MOUNT_FMODE | SMB_MOUNT_DMODE;
        } else {
+               mnt->file_mode = S_IRWXU | S_IRGRP | S_IXGRP |
+                               S_IROTH | S_IXOTH | S_IFREG;
+               mnt->dir_mode = S_IRWXU | S_IRGRP | S_IXGRP |
+                               S_IROTH | S_IXOTH | S_IFDIR;
                if (parse_options(mnt, raw_data))
                        goto out_bad_option;
        }
@@ -591,7 +600,7 @@ int smb_fill_super(struct super_block *sb, void *raw_data, int silent)
        /*
         * Keep the super block locked while we get the root inode.
         */
-       smb_init_root_dirent(server, &root);
+       smb_init_root_dirent(server, &root, sb);
        root_inode = smb_iget(sb, &root);
        if (!root_inode)
                goto out_no_root;
@@ -599,6 +608,7 @@ int smb_fill_super(struct super_block *sb, void *raw_data, int silent)
        sb->s_root = d_alloc_root(root_inode);
        if (!sb->s_root)
                goto out_no_root;
+
        smb_new_dentry(sb->s_root);
 
        return 0;
@@ -608,12 +618,12 @@ out_no_root:
 out_no_smbiod:
        smb_unload_nls(server);
 out_bad_option:
-       smb_kfree(mem);
+       kfree(mem);
 out_no_mem:
        if (!server->mnt)
                printk(KERN_ERR "smb_fill_super: allocation failure\n");
        sb->s_fs_info = NULL;
-       smb_kfree(server);
+       kfree(server);
        goto out_fail;
 out_wrong_data:
        printk(KERN_ERR "smbfs: mount_data version %d is not supported\n", ver);
@@ -628,13 +638,13 @@ out_no_server:
 }
 
 static int
-smb_statfs(struct super_block *sb, struct kstatfs *buf)
+smb_statfs(struct dentry *dentry, struct kstatfs *buf)
 {
        int result;
        
        lock_kernel();
 
-       result = smb_proc_dskattr(sb, buf);
+       result = smb_proc_dskattr(dentry, buf);
 
        unlock_kernel();
 
@@ -684,8 +694,7 @@ smb_notify_change(struct dentry *dentry, struct iattr *attr)
                        DENTRY_PATH(dentry),
                        (long) inode->i_size, (long) attr->ia_size);
 
-               filemap_fdatawrite(inode->i_mapping);
-               filemap_fdatawait(inode->i_mapping);
+               filemap_write_and_wait(inode->i_mapping);
 
                error = smb_open(dentry, O_WRONLY);
                if (error)
@@ -770,16 +779,10 @@ out:
        return error;
 }
 
-#ifdef DEBUG_SMB_MALLOC
-int smb_malloced;
-int smb_current_kmalloced;
-int smb_current_vmalloced;
-#endif
-
-static struct super_block *smb_get_sb(struct file_system_type *fs_type,
-       int flags, const char *dev_name, void *data)
+static int smb_get_sb(struct file_system_type *fs_type,
+       int flags, const char *dev_name, void *data, struct vfsmount *mnt)
 {
-       return get_sb_nodev(fs_type, flags, data, smb_fill_super);
+       return get_sb_nodev(fs_type, flags, data, smb_fill_super, mnt);
 }
 
 static struct file_system_type smb_fs_type = {
@@ -795,12 +798,6 @@ static int __init init_smb_fs(void)
        int err;
        DEBUG1("registering ...\n");
 
-#ifdef DEBUG_SMB_MALLOC
-       smb_malloced = 0;
-       smb_current_kmalloced = 0;
-       smb_current_vmalloced = 0;
-#endif
-
        err = init_inodecache();
        if (err)
                goto out_inode;
@@ -825,11 +822,6 @@ static void __exit exit_smb_fs(void)
        unregister_filesystem(&smb_fs_type);
        smb_destroy_request_cache();
        destroy_inodecache();
-#ifdef DEBUG_SMB_MALLOC
-       printk(KERN_DEBUG "smb_malloced: %d\n", smb_malloced);
-       printk(KERN_DEBUG "smb_current_kmalloced: %d\n",smb_current_kmalloced);
-       printk(KERN_DEBUG "smb_current_vmalloced: %d\n",smb_current_vmalloced);
-#endif
 }
 
 module_init(init_smb_fs)