Fedora kernel-2.6.17-1.2142_FC4 patched with stable patch-2.6.17.4-vs2.0.2-rc26.diff
[linux-2.6.git] / fs / smbfs / inode.c
index 1001a64..fdeabc0 100644 (file)
@@ -80,7 +80,8 @@ static int init_inodecache(void)
 {
        smb_inode_cachep = kmem_cache_create("smb_inode_cache",
                                             sizeof(struct smb_inode_info),
-                                            0, SLAB_RECLAIM_ACCOUNT,
+                                            0, (SLAB_RECLAIM_ACCOUNT|
+                                               SLAB_MEM_SPREAD),
                                             init_once, NULL);
        if (smb_inode_cachep == NULL)
                return -ENOMEM;
@@ -216,7 +217,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 +332,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 +370,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 +384,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 +434,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 +445,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);
@@ -481,14 +488,14 @@ smb_put_super(struct super_block *sb)
        if (server->conn_pid)
                kill_proc(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);
+       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 +518,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;
@@ -535,8 +542,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 +573,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 +603,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 +611,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 +621,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);
@@ -684,8 +697,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,12 +782,6 @@ 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)
 {
@@ -795,12 +801,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 +825,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)