fedora core 6 1.2949 + vserver 2.2.0
[linux-2.6.git] / fs / ncpfs / inode.c
index cda1ffd..67a90bf 100644 (file)
@@ -9,7 +9,6 @@
  *
  */
 
-#include <linux/config.h>
 #include <linux/module.h>
 
 #include <asm/system.h>
 
 static void ncp_delete_inode(struct inode *);
 static void ncp_put_super(struct super_block *);
-static int  ncp_statfs(struct super_block *, struct kstatfs *);
+static int  ncp_statfs(struct dentry *, struct kstatfs *);
 
-static kmem_cache_t * ncp_inode_cachep;
+static struct kmem_cache * ncp_inode_cachep;
 
 static struct inode *ncp_alloc_inode(struct super_block *sb)
 {
        struct ncp_inode_info *ei;
-       ei = (struct ncp_inode_info *)kmem_cache_alloc(ncp_inode_cachep, SLAB_KERNEL);
+       ei = (struct ncp_inode_info *)kmem_cache_alloc(ncp_inode_cachep, GFP_KERNEL);
        if (!ei)
                return NULL;
        return &ei->vfs_inode;
@@ -57,13 +56,13 @@ static void ncp_destroy_inode(struct inode *inode)
        kmem_cache_free(ncp_inode_cachep, NCP_FINFO(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 ncp_inode_info *ei = (struct ncp_inode_info *) foo;
 
        if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) ==
            SLAB_CTOR_CONSTRUCTOR) {
-               init_MUTEX(&ei->open_sem);
+               mutex_init(&ei->open_mutex);
                inode_init_once(&ei->vfs_inode);
        }
 }
@@ -72,7 +71,8 @@ static int init_inodecache(void)
 {
        ncp_inode_cachep = kmem_cache_create("ncp_inode_cache",
                                             sizeof(struct ncp_inode_info),
-                                            0, SLAB_HWCACHE_ALIGN|SLAB_RECLAIM_ACCOUNT,
+                                            0, (SLAB_RECLAIM_ACCOUNT|
+                                               SLAB_MEM_SPREAD),
                                             init_once, NULL);
        if (ncp_inode_cachep == NULL)
                return -ENOMEM;
@@ -81,8 +81,7 @@ static int init_inodecache(void)
 
 static void destroy_inodecache(void)
 {
-       if (kmem_cache_destroy(ncp_inode_cachep))
-               printk(KERN_INFO "ncp_inode_cache: not all structures were freed\n");
+       kmem_cache_destroy(ncp_inode_cachep);
 }
 
 static int ncp_remount(struct super_block *sb, int *flags, char* data)
@@ -104,7 +103,7 @@ static struct super_operations ncp_sops =
 
 extern struct dentry_operations ncp_root_dentry_operations;
 #if defined(CONFIG_NCPFS_EXTRAS) || defined(CONFIG_NCPFS_NFS_NS)
-extern struct address_space_operations ncp_symlink_aops;
+extern const struct address_space_operations ncp_symlink_aops;
 extern int ncp_symlink(struct inode*, struct dentry*, const char*);
 #endif
 
@@ -142,12 +141,9 @@ static void ncp_update_dates(struct inode *inode, struct nw_info_struct *nwi)
 
        inode->i_blocks = (inode->i_size + NCP_BLOCK_SIZE - 1) >> NCP_BLOCK_SHIFT;
 
-       inode->i_mtime.tv_sec = ncp_date_dos2unix(le16_to_cpu(nwi->modifyTime),
-                                          le16_to_cpu(nwi->modifyDate));
-       inode->i_ctime.tv_sec = ncp_date_dos2unix(le16_to_cpu(nwi->creationTime),
-                                          le16_to_cpu(nwi->creationDate));
-       inode->i_atime.tv_sec = ncp_date_dos2unix(0,
-                                          le16_to_cpu(nwi->lastAccessDate));
+       inode->i_mtime.tv_sec = ncp_date_dos2unix(nwi->modifyTime, nwi->modifyDate);
+       inode->i_ctime.tv_sec = ncp_date_dos2unix(nwi->creationTime, nwi->creationDate);
+       inode->i_atime.tv_sec = ncp_date_dos2unix(0, nwi->lastAccessDate);
        inode->i_atime.tv_nsec = 0;
        inode->i_mtime.tv_nsec = 0;
        inode->i_ctime.tv_nsec = 0;
@@ -227,7 +223,6 @@ static void ncp_set_attr(struct inode *inode, struct ncp_entry_info *nwinfo)
        inode->i_nlink = 1;
        inode->i_uid = server->m.uid;
        inode->i_gid = server->m.gid;
-       inode->i_blksize = NCP_BLOCK_SIZE;
 
        ncp_update_dates(inode, &nwinfo->i);
        ncp_update_inode(inode, nwinfo);
@@ -235,8 +230,9 @@ static void ncp_set_attr(struct inode *inode, struct ncp_entry_info *nwinfo)
 
 #if defined(CONFIG_NCPFS_EXTRAS) || defined(CONFIG_NCPFS_NFS_NS)
 static struct inode_operations ncp_symlink_inode_operations = {
-       .readlink       = page_readlink,
-       .follow_link    = page_follow_link,
+       .readlink       = generic_readlink,
+       .follow_link    = page_follow_link_light,
+       .put_link       = page_put_link,
        .setattr        = ncp_notify_change,
 };
 #endif
@@ -288,6 +284,8 @@ ncp_iget(struct super_block *sb, struct ncp_entry_info *info)
 static void
 ncp_delete_inode(struct inode *inode)
 {
+       truncate_inode_pages(&inode->i_data, 0);
+
        if (S_ISDIR(inode->i_mode)) {
                DDPRINTK("ncp_delete_inode: put directory %ld\n", inode->i_ino);
        }
@@ -329,11 +327,12 @@ static int ncp_parse_options(struct ncp_mount_data_kernel *data, char *options)
        char *optarg;
        unsigned long optint;
        int version = 0;
+       int ret;
 
        data->flags = 0;
        data->int_flags = 0;
        data->mounted_uid = 0;
-       data->wdog_pid = -1;
+       data->wdog_pid = NULL;
        data->ncp_fd = ~0;
        data->time_out = 10;
        data->retry_count = 20;
@@ -345,8 +344,9 @@ static int ncp_parse_options(struct ncp_mount_data_kernel *data, char *options)
        data->mounted_vol[0] = 0;
        
        while ((optval = ncp_getopt("ncpfs", &options, ncp_opts, NULL, &optarg, &optint)) != 0) {
-               if (optval < 0)
-                       return optval;
+               ret = optval;
+               if (ret < 0)
+                       goto err;
                switch (optval) {
                        case 'u':
                                data->uid = optint;
@@ -373,7 +373,7 @@ static int ncp_parse_options(struct ncp_mount_data_kernel *data, char *options)
                                data->flags = optint;
                                break;
                        case 'w':
-                               data->wdog_pid = optint;
+                               data->wdog_pid = find_get_pid(optint);
                                break;
                        case 'n':
                                data->ncp_fd = optint;
@@ -382,18 +382,21 @@ static int ncp_parse_options(struct ncp_mount_data_kernel *data, char *options)
                                data->info_fd = optint;
                                break;
                        case 'v':
-                               if (optint < NCP_MOUNT_VERSION_V4) {
-                                       return -ECHRNG;
-                               }
-                               if (optint > NCP_MOUNT_VERSION_V5) {
-                                       return -ECHRNG;
-                               }
+                               ret = -ECHRNG;
+                               if (optint < NCP_MOUNT_VERSION_V4)
+                                       goto err;
+                               if (optint > NCP_MOUNT_VERSION_V5)
+                                       goto err;
                                version = optint;
                                break;
                        
                }
        }
        return 0;
+err:
+       put_pid(data->wdog_pid);
+       data->wdog_pid = NULL;
+       return ret;
 }
 
 static int ncp_fill_super(struct super_block *sb, void *raw_data, int silent)
@@ -411,11 +414,11 @@ static int ncp_fill_super(struct super_block *sb, void *raw_data, int silent)
 #endif
        struct ncp_entry_info finfo;
 
-       server = kmalloc(sizeof(struct ncp_server), GFP_KERNEL);
+       data.wdog_pid = NULL;
+       server = kzalloc(sizeof(struct ncp_server), GFP_KERNEL);
        if (!server)
                return -ENOMEM;
        sb->s_fs_info = server;
-       memset(server, 0, sizeof(struct ncp_server));
 
        error = -EFAULT;
        if (raw_data == NULL)
@@ -428,7 +431,7 @@ static int ncp_fill_super(struct super_block *sb, void *raw_data, int silent)
                                data.flags = md->flags;
                                data.int_flags = NCP_IMOUNT_LOGGEDIN_POSSIBLE;
                                data.mounted_uid = md->mounted_uid;
-                               data.wdog_pid = md->wdog_pid;
+                               data.wdog_pid = find_get_pid(md->wdog_pid);
                                data.ncp_fd = md->ncp_fd;
                                data.time_out = md->time_out;
                                data.retry_count = md->retry_count;
@@ -448,7 +451,7 @@ static int ncp_fill_super(struct super_block *sb, void *raw_data, int silent)
                                data.flags = md->flags;
                                data.int_flags = 0;
                                data.mounted_uid = md->mounted_uid;
-                               data.wdog_pid = md->wdog_pid;
+                               data.wdog_pid = find_get_pid(md->wdog_pid);
                                data.ncp_fd = md->ncp_fd;
                                data.time_out = md->time_out;
                                data.retry_count = md->retry_count;
@@ -462,7 +465,7 @@ static int ncp_fill_super(struct super_block *sb, void *raw_data, int silent)
                        break;
                default:
                        error = -ECHRNG;
-                       if (*(__u32*)raw_data == cpu_to_be32(0x76657273)) {
+                       if (memcmp(raw_data, "vers", 4) == 0) {
                                error = ncp_parse_options(&data, raw_data);
                        }
                        if (error)
@@ -474,7 +477,7 @@ static int ncp_fill_super(struct super_block *sb, void *raw_data, int silent)
        if (!ncp_filp)
                goto out;
        error = -ENOTSOCK;
-       sock_inode = ncp_filp->f_dentry->d_inode;
+       sock_inode = ncp_filp->f_path.dentry->d_inode;
        if (!S_ISSOCK(sock_inode->i_mode))
                goto out_fput;
        sock = SOCKET_I(sock_inode);
@@ -507,7 +510,7 @@ static int ncp_fill_super(struct super_block *sb, void *raw_data, int silent)
                if (!server->info_filp)
                        goto out_fput;
                error = -ENOTSOCK;
-               sock_inode = server->info_filp->f_dentry->d_inode;
+               sock_inode = server->info_filp->f_path.dentry->d_inode;
                if (!S_ISSOCK(sock_inode->i_mode))
                        goto out_fput2;
                info_sock = SOCKET_I(sock_inode);
@@ -520,7 +523,7 @@ static int ncp_fill_super(struct super_block *sb, void *raw_data, int silent)
        }
 
 /*     server->lock = 0;       */
-       init_MUTEX(&server->sem);
+       mutex_init(&server->mutex);
        server->packet = NULL;
 /*     server->buffer_size = 0;        */
 /*     server->conn_status = 0;        */
@@ -557,7 +560,7 @@ static int ncp_fill_super(struct super_block *sb, void *raw_data, int silent)
        server->dentry_ttl = 0; /* no caching */
 
        INIT_LIST_HEAD(&server->tx.requests);
-       init_MUTEX(&server->rcv.creq_sem);
+       mutex_init(&server->rcv.creq_mutex);
        server->tx.creq         = NULL;
        server->rcv.creq        = NULL;
        server->data_ready      = sock->sk->sk_data_ready;
@@ -580,12 +583,12 @@ static int ncp_fill_super(struct super_block *sb, void *raw_data, int silent)
                server->rcv.ptr = (unsigned char*)&server->rcv.buf;
                server->rcv.len = 10;
                server->rcv.state = 0;
-               INIT_WORK(&server->rcv.tq, ncp_tcp_rcv_proc, server);
-               INIT_WORK(&server->tx.tq, ncp_tcp_tx_proc, server);
+               INIT_WORK(&server->rcv.tq, ncp_tcp_rcv_proc);
+               INIT_WORK(&server->tx.tq, ncp_tcp_tx_proc);
                sock->sk->sk_write_space = ncp_tcp_write_space;
        } else {
-               INIT_WORK(&server->rcv.tq, ncpdgram_rcv_proc, server);
-               INIT_WORK(&server->timeout_tq, ncpdgram_timeout_proc, server);
+               INIT_WORK(&server->rcv.tq, ncpdgram_rcv_proc);
+               INIT_WORK(&server->timeout_tq, ncpdgram_timeout_proc);
                server->timeout_tm.data = (unsigned long)server;
                server->timeout_tm.function = ncpdgram_timeout_call;
        }
@@ -625,7 +628,7 @@ static int ncp_fill_super(struct super_block *sb, void *raw_data, int silent)
 
        memset(&finfo, 0, sizeof(finfo));
        finfo.i.attributes      = aDIR;
-       finfo.i.dataStreamSize  = NCP_BLOCK_SIZE;
+       finfo.i.dataStreamSize  = 0;    /* ignored */
        finfo.i.dirEntNum       = 0;
        finfo.i.DosDirNum       = 0;
 #ifdef CONFIG_NCPFS_SMALLDOS
@@ -682,6 +685,7 @@ out_fput:
         */
        fput(ncp_filp);
 out:
+       put_pid(data.wdog_pid);
        sb->s_fs_info = NULL;
        kfree(server);
        return error;
@@ -714,24 +718,24 @@ static void ncp_put_super(struct super_block *sb)
        if (server->info_filp)
                fput(server->info_filp);
        fput(server->ncp_filp);
-       kill_proc(server->m.wdog_pid, SIGTERM, 1);
+       kill_pid(server->m.wdog_pid, SIGTERM, 1);
+       put_pid(server->m.wdog_pid);
 
-       if (server->priv.data) 
-               ncp_kfree_s(server->priv.data, server->priv.len);
-       if (server->auth.object_name)
-               ncp_kfree_s(server->auth.object_name, server->auth.object_name_len);
+       kfree(server->priv.data);
+       kfree(server->auth.object_name);
        vfree(server->packet);
        sb->s_fs_info = NULL;
        kfree(server);
 }
 
-static int ncp_statfs(struct super_block *sb, struct kstatfs *buf)
+static int ncp_statfs(struct dentry *dentry, struct kstatfs *buf)
 {
        struct dentry* d;
        struct inode* i;
        struct ncp_inode_info* ni;
        struct ncp_server* s;
        struct ncp_volume_info vi;
+       struct super_block *sb = dentry->d_sb;
        int err;
        __u8 dh;
        
@@ -794,7 +798,7 @@ int ncp_notify_change(struct dentry *dentry, struct iattr *attr)
 {
        struct inode *inode = dentry->d_inode;
        int result = 0;
-       int info_mask;
+       __le32 info_mask;
        struct nw_modify_dos_info info;
        struct ncp_server *server;
 
@@ -873,7 +877,9 @@ int ncp_notify_change(struct dentry *dentry, struct iattr *attr)
                                tmpattr.ia_valid = ATTR_MODE;
                                tmpattr.ia_mode = attr->ia_mode;
 
-                               inode_setattr(inode, &tmpattr);
+                               result = inode_setattr(inode, &tmpattr);
+                               if (result)
+                                       goto out;
                        }
                }
 #endif
@@ -899,35 +905,34 @@ int ncp_notify_change(struct dentry *dentry, struct iattr *attr)
                   closing the file */
                ncp_inode_close(inode);
                result = ncp_make_closed(inode);
+               if (result)
+                       goto out;
                {
                        struct iattr tmpattr;
                        
                        tmpattr.ia_valid = ATTR_SIZE;
                        tmpattr.ia_size = attr->ia_size;
                        
-                       inode_setattr(inode, &tmpattr);
+                       result = inode_setattr(inode, &tmpattr);
+                       if (result)
+                               goto out;
                }
        }
        if ((attr->ia_valid & ATTR_CTIME) != 0) {
                info_mask |= (DM_CREATE_TIME | DM_CREATE_DATE);
                ncp_date_unix2dos(attr->ia_ctime.tv_sec,
-                            &(info.creationTime), &(info.creationDate));
-               info.creationTime = le16_to_cpu(info.creationTime);
-               info.creationDate = le16_to_cpu(info.creationDate);
+                            &info.creationTime, &info.creationDate);
        }
        if ((attr->ia_valid & ATTR_MTIME) != 0) {
                info_mask |= (DM_MODIFY_TIME | DM_MODIFY_DATE);
                ncp_date_unix2dos(attr->ia_mtime.tv_sec,
-                                 &(info.modifyTime), &(info.modifyDate));
-               info.modifyTime = le16_to_cpu(info.modifyTime);
-               info.modifyDate = le16_to_cpu(info.modifyDate);
+                                 &info.modifyTime, &info.modifyDate);
        }
        if ((attr->ia_valid & ATTR_ATIME) != 0) {
-               __u16 dummy;
+               __le16 dummy;
                info_mask |= (DM_LAST_ACCESS_DATE);
                ncp_date_unix2dos(attr->ia_atime.tv_sec,
-                                 &(dummy), &(info.lastAccessDate));
-               info.lastAccessDate = le16_to_cpu(info.lastAccessDate);
+                                 &dummy, &info.lastAccessDate);
        }
        if (info_mask != 0) {
                result = ncp_modify_file_or_subdir_dos_info(NCP_SERVER(inode),
@@ -951,21 +956,16 @@ int ncp_notify_change(struct dentry *dentry, struct iattr *attr)
 #endif
        }
        if (!result)
-               inode_setattr(inode, attr);
+               result = inode_setattr(inode, attr);
 out:
        unlock_kernel();
        return result;
 }
 
-#ifdef DEBUG_NCP_MALLOC
-int ncp_malloced;
-int ncp_current_malloced;
-#endif
-
-static struct super_block *ncp_get_sb(struct file_system_type *fs_type,
-       int flags, const char *dev_name, void *data)
+static int ncp_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, ncp_fill_super);
+       return get_sb_nodev(fs_type, flags, data, ncp_fill_super, mnt);
 }
 
 static struct file_system_type ncp_fs_type = {
@@ -980,10 +980,6 @@ static int __init init_ncp_fs(void)
        int err;
        DPRINTK("ncpfs: init_module called\n");
 
-#ifdef DEBUG_NCP_MALLOC
-       ncp_malloced = 0;
-       ncp_current_malloced = 0;
-#endif
        err = init_inodecache();
        if (err)
                goto out1;
@@ -1002,10 +998,6 @@ static void __exit exit_ncp_fs(void)
        DPRINTK("ncpfs: cleanup_module called\n");
        unregister_filesystem(&ncp_fs_type);
        destroy_inodecache();
-#ifdef DEBUG_NCP_MALLOC
-       PRINTK("ncp_malloced: %d\n", ncp_malloced);
-       PRINTK("ncp_current_malloced: %d\n", ncp_current_malloced);
-#endif
 }
 
 module_init(init_ncp_fs)