diff options
author | Ralf Baechle <ralf@linux-mips.org> | 1998-03-17 22:05:47 +0000 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 1998-03-17 22:05:47 +0000 |
commit | 27cfca1ec98e91261b1a5355d10a8996464b63af (patch) | |
tree | 8e895a53e372fa682b4c0a585b9377d67ed70d0e /fs/ncpfs/inode.c | |
parent | 6a76fb7214c477ccf6582bd79c5b4ccc4f9c41b1 (diff) |
Look Ma' what I found on my harddisk ...
o New faster syscalls for 2.1.x, too
o Upgrade to 2.1.89.
Don't try to run this. It's flaky as hell. But feel free to debug ...
Diffstat (limited to 'fs/ncpfs/inode.c')
-rw-r--r-- | fs/ncpfs/inode.c | 155 |
1 files changed, 125 insertions, 30 deletions
diff --git a/fs/ncpfs/inode.c b/fs/ncpfs/inode.c index 61cdd0319..f11f4640c 100644 --- a/fs/ncpfs/inode.c +++ b/fs/ncpfs/inode.c @@ -32,12 +32,9 @@ #include <linux/ncp_fs.h> #include "ncplib_kernel.h" -extern int close_fp(struct file *filp); - static void ncp_read_inode(struct inode *); static void ncp_put_inode(struct inode *); static void ncp_delete_inode(struct inode *); -static int ncp_notify_change(struct inode *, struct iattr *); static void ncp_put_super(struct super_block *); static int ncp_statfs(struct super_block *, struct statfs *, int); @@ -54,6 +51,8 @@ static struct super_operations ncp_sops = NULL /* remount */ }; +extern struct dentry_operations ncp_dentry_operations; + static struct nw_file_info *read_nwinfo = NULL; static struct semaphore read_sem = MUTEX; @@ -77,6 +76,31 @@ nwinfo->i.entryName, NCP_FINFO(inode)->volNumber, NCP_FINFO(inode)->dirEntNum); #endif } +void ncp_update_inode2(struct inode* inode, struct nw_file_info *nwinfo) +{ + struct nw_info_struct *nwi = &nwinfo->i; + struct ncp_server *server = NCP_SERVER(inode); + + if (!NCP_FINFO(inode)->opened) { + if (nwi->attributes & aDIR) { + inode->i_mode = server->m.dir_mode; + inode->i_size = 512; + } else { + inode->i_mode = server->m.file_mode; + inode->i_size = le32_to_cpu(nwi->dataStreamSize); + } + if (nwi->attributes & aRONLY) inode->i_mode &= ~0222; + } + inode->i_blocks = 0; + if ((inode->i_size)&&(inode->i_blksize)) { + inode->i_blocks = (inode->i_size-1)/(inode->i_blksize)+1; + } + /* TODO: times? I'm not sure... */ + NCP_FINFO(inode)->DosDirNum = nwinfo->i.DosDirNum; + NCP_FINFO(inode)->dirEntNum = nwinfo->i.dirEntNum; + NCP_FINFO(inode)->volNumber = nwinfo->i.volNumber; +} + /* * Fill in the inode based on the nw_file_info structure. */ @@ -94,6 +118,7 @@ static void ncp_set_attr(struct inode *inode, struct nw_file_info *nwinfo) inode->i_mode = server->m.file_mode; inode->i_size = le32_to_cpu(nwi->dataStreamSize); } + if (nwi->attributes & aRONLY) inode->i_mode &= ~0222; DDPRINTK(KERN_DEBUG "ncp_read_inode: inode->i_mode = %u\n", inode->i_mode); @@ -210,8 +235,9 @@ static void ncp_init_root(struct ncp_server *server, i->entryName[0] = '\0'; root->finfo.opened= 0; - info->ino = 1; + info->ino = 2; /* tradition */ info->nw_info = root->finfo; + return; } struct super_block * @@ -223,6 +249,9 @@ ncp_read_super(struct super_block *sb, void *raw_data, int silent) struct inode *root_inode; kdev_t dev = sb->s_dev; int error; +#ifdef CONFIG_NCPFS_PACKET_SIGNING + int options; +#endif struct ncpfs_inode_info finfo; MOD_INC_USE_COUNT; @@ -230,13 +259,13 @@ ncp_read_super(struct super_block *sb, void *raw_data, int silent) goto out_no_data; if (data->version != NCP_MOUNT_VERSION) goto out_bad_mount; - if ((data->ncp_fd >= NR_OPEN) || - ((ncp_filp = current->files->fd[data->ncp_fd]) == NULL) || - !S_ISSOCK(ncp_filp->f_dentry->d_inode->i_mode)) + ncp_filp = fget(data->ncp_fd); + if (!ncp_filp) goto out_bad_file; + if (!S_ISSOCK(ncp_filp->f_dentry->d_inode->i_mode)) + goto out_bad_file2; lock_super(sb); - ncp_filp->f_count++; sb->s_blocksize = 1024; /* Eh... Is this correct? */ sb->s_blocksize_bits = 10; @@ -257,6 +286,17 @@ ncp_read_super(struct super_block *sb, void *raw_data, int silent) server->packet = NULL; server->buffer_size = 0; server->conn_status = 0; + server->root_dentry = NULL; +#ifdef CONFIG_NCPFS_PACKET_SIGNING + server->sign_wanted = 0; + server->sign_active = 0; +#endif + server->auth.auth_type = NCP_AUTH_NONE; + server->auth.object_name_len = 0; + server->auth.object_name = NULL; + server->auth.object_type = 0; + server->priv.len = 0; + server->priv.data = NULL; server->m = *data; /* Althought anything producing this is buggy, it happens @@ -282,21 +322,41 @@ ncp_read_super(struct super_block *sb, void *raw_data, int silent) goto out_no_connect; DPRINTK(KERN_DEBUG "ncp_read_super: NCP_SBP(sb) = %x\n", (int) NCP_SBP(sb)); - error = ncp_negotiate_buffersize(server, NCP_DEFAULT_BUFSIZE, - &(server->buffer_size)); - if (error) +#ifdef CONFIG_NCPFS_PACKET_SIGNING + if (ncp_negotiate_size_and_options(server, NCP_DEFAULT_BUFSIZE, + NCP_DEFAULT_OPTIONS, &(server->buffer_size), &options) == 0) + { + if (options != NCP_DEFAULT_OPTIONS) + { + if (ncp_negotiate_size_and_options(server, + NCP_DEFAULT_BUFSIZE, + options & 2, + &(server->buffer_size), &options) != 0) + + { + goto out_no_bufsize; + } + } + if (options & 2) + server->sign_wanted = 1; + } + else +#endif /* CONFIG_NCPFS_PACKET_SIGNING */ + if (ncp_negotiate_buffersize(server, NCP_DEFAULT_BUFSIZE, + &(server->buffer_size)) != 0) goto out_no_bufsize; DPRINTK(KERN_DEBUG "ncpfs: bufsize = %d\n", server->buffer_size); ncp_init_root(server, &finfo); + server->name_space[finfo.nw_info.i.volNumber] = NW_NS_DOS; root_inode = ncp_iget(sb, &finfo); if (!root_inode) goto out_no_root; DPRINTK(KERN_DEBUG "ncp_read_super: root vol=%d\n", NCP_FINFO(root_inode)->volNumber); - sb->s_root = d_alloc_root(root_inode, NULL); + server->root_dentry = sb->s_root = d_alloc_root(root_inode, NULL); if (!sb->s_root) goto out_no_root; - + server->root_dentry->d_op = &ncp_dentry_operations; unlock_super(sb); return sb; @@ -328,6 +388,8 @@ out_unlock: unlock_super(sb); goto out; +out_bad_file2: + fput(ncp_filp); out_bad_file: printk(KERN_ERR "ncp_read_super: invalid ncp socket\n"); goto out; @@ -353,9 +415,13 @@ static void ncp_put_super(struct super_block *sb) ncp_disconnect(server); ncp_unlock_server(server); - close_fp(server->ncp_filp); - kill_proc(server->m.wdog_pid, SIGTERM, 0); + fput(server->ncp_filp); + kill_proc(server->m.wdog_pid, SIGTERM, 1); + 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); ncp_kfree_s(server->packet, server->packet_size); ncp_kfree_s(NCP_SBP(sb), sizeof(struct ncp_server)); @@ -387,34 +453,65 @@ static int ncp_statfs(struct super_block *sb, struct statfs *buf, int bufsiz) return copy_to_user(buf, &tmp, bufsiz) ? -EFAULT : 0; } -static int ncp_notify_change(struct inode *inode, struct iattr *attr) +int ncp_notify_change(struct dentry *dentry, struct iattr *attr) { + struct inode *inode = dentry->d_inode; int result = 0; int info_mask; struct nw_modify_dos_info info; - if (!ncp_conn_valid(NCP_SERVER(inode))) { - return -EIO; - } - if ((result = inode_change_ok(inode, attr)) < 0) - return result; + result = -EIO; + if (!ncp_conn_valid(NCP_SERVER(inode))) + goto out; + + result = inode_change_ok(inode, attr); + if (result < 0) + goto out; + result = -EPERM; if (((attr->ia_valid & ATTR_UID) && (attr->ia_uid != NCP_SERVER(inode)->m.uid))) - return -EPERM; + goto out; if (((attr->ia_valid & ATTR_GID) && (attr->ia_uid != NCP_SERVER(inode)->m.gid))) - return -EPERM; + goto out; if (((attr->ia_valid & ATTR_MODE) && (attr->ia_mode & ~(S_IFREG | S_IFDIR | S_IRWXU | S_IRWXG | S_IRWXO)))) - return -EPERM; + goto out; info_mask = 0; memset(&info, 0, sizeof(info)); +#if 1 + if ((attr->ia_valid & ATTR_MODE) != 0) + { + if (!S_ISREG(inode->i_mode)) + { + return -EPERM; + } + else + { + umode_t newmode; + + info_mask |= DM_ATTRIBUTES; + newmode=attr->ia_mode; + newmode &= NCP_SERVER(inode)->m.file_mode; + + if (newmode & 0222) /* any write bit set */ + { + info.attributes &= ~0x60001; + } + else + { + info.attributes |= 0x60001; + } + } + } +#endif + if ((attr->ia_valid & ATTR_CTIME) != 0) { info_mask |= (DM_CREATE_TIME | DM_CREATE_DATE); ncp_date_unix2dos(attr->ia_ctime, @@ -455,7 +552,8 @@ static int ncp_notify_change(struct inode *inode, struct iattr *attr) if ((attr->ia_valid & ATTR_SIZE) != 0) { int written; - DPRINTK(KERN_DEBUG "ncpfs: trying to change size to %ld\n", attr->ia_size); + DPRINTK(KERN_DEBUG "ncpfs: trying to change size to %ld\n", + attr->ia_size); if ((result = ncp_make_open(inode, O_RDWR)) < 0) { return -EACCES; @@ -467,11 +565,8 @@ static int ncp_notify_change(struct inode *inode, struct iattr *attr) closing the file */ result = ncp_make_closed(inode); } - /* - * We need a dentry here ... - */ - /* ncp_invalid_dir_cache(NCP_INOP(inode)->dir->inode); */ - + ncp_invalid_dir_cache(dentry->d_parent->d_inode); +out: return result; } |