diff options
Diffstat (limited to 'fs/ncpfs')
-rw-r--r-- | fs/ncpfs/dir.c | 6 | ||||
-rw-r--r-- | fs/ncpfs/file.c | 38 | ||||
-rw-r--r-- | fs/ncpfs/inode.c | 10 | ||||
-rw-r--r-- | fs/ncpfs/ioctl.c | 16 | ||||
-rw-r--r-- | fs/ncpfs/mmap.c | 1 | ||||
-rw-r--r-- | fs/ncpfs/ncplib_kernel.c | 24 | ||||
-rw-r--r-- | fs/ncpfs/ncplib_kernel.h | 4 | ||||
-rw-r--r-- | fs/ncpfs/symlink.c | 56 |
8 files changed, 66 insertions, 89 deletions
diff --git a/fs/ncpfs/dir.c b/fs/ncpfs/dir.c index 11694e79b..55daea198 100644 --- a/fs/ncpfs/dir.c +++ b/fs/ncpfs/dir.c @@ -973,7 +973,7 @@ static int ncp_unlink(struct inode *dir, struct dentry *dentry) /* * Check whether to close the file ... */ - if (inode) { + if (inode && NCP_FINFO(inode)->opened) { PPRINTK("ncp_unlink: closing file\n"); ncp_make_closed(inode); } @@ -982,7 +982,7 @@ static int ncp_unlink(struct inode *dir, struct dentry *dentry) #ifdef CONFIG_NCPFS_STRONG /* 9C is Invalid path.. It should be 8F, 90 - read only, but it is not :-( */ - if ((error == 0x9C || error == 0x90) && server->m.flags & NCP_MOUNT_STRONG) { /* R/O */ + if (error == 0x9C && server->m.flags & NCP_MOUNT_STRONG) { /* R/O */ error = ncp_force_unlink(dir, dentry); } #endif @@ -1051,7 +1051,7 @@ static int ncp_rename(struct inode *old_dir, struct dentry *old_dentry, error = ncp_ren_or_mov_file_or_subdir(server, old_dir, __old_name, new_dir, __new_name); #ifdef CONFIG_NCPFS_STRONG - if ((error == 0x90 || error == 0x8B || error == -EACCES) && + if ((error == 0x90 || error == -EACCES) && server->m.flags & NCP_MOUNT_STRONG) { /* RO */ error = ncp_force_rename(old_dir, old_dentry, __old_name, new_dir, new_dentry, __new_name); diff --git a/fs/ncpfs/file.c b/fs/ncpfs/file.c index 3442c3f9f..6f8fd2d63 100644 --- a/fs/ncpfs/file.c +++ b/fs/ncpfs/file.c @@ -26,7 +26,7 @@ static inline unsigned int min(unsigned int a, unsigned int b) return a < b ? a : b; } -static int ncp_fsync(struct file *file, struct dentry *dentry, int datasync) +static int ncp_fsync(struct file *file, struct dentry *dentry) { return 0; } @@ -46,12 +46,12 @@ int ncp_make_open(struct inode *inode, int right) } DPRINTK("ncp_make_open: opened=%d, volume # %u, dir entry # %u\n", - atomic_read(&NCP_FINFO(inode)->opened), + NCP_FINFO(inode)->opened, NCP_FINFO(inode)->volNumber, NCP_FINFO(inode)->dirEntNum); error = -EACCES; - down(&NCP_FINFO(inode)->open_sem); - if (!atomic_read(&NCP_FINFO(inode)->opened)) { + lock_super(inode->i_sb); + if (!NCP_FINFO(inode)->opened) { struct ncp_entry_info finfo; int result; @@ -88,18 +88,15 @@ int ncp_make_open(struct inode *inode, int right) */ update: ncp_update_inode(inode, &finfo); - atomic_set(&NCP_FINFO(inode)->opened, 1); } access = NCP_FINFO(inode)->access; PPRINTK("ncp_make_open: file open, access=%x\n", access); - if (access == right || access == O_RDWR) { - atomic_inc(&NCP_FINFO(inode)->opened); + if (access == right || access == O_RDWR) error = 0; - } out_unlock: - up(&NCP_FINFO(inode)->open_sem); + unlock_super(inode->i_sb); out: return error; } @@ -156,7 +153,7 @@ ncp_file_read(struct file *file, char *buf, size_t count, loff_t *ppos) freelen = ncp_read_bounce_size(bufsize); freepage = kmalloc(freelen, GFP_NFS); if (!freepage) - goto outrel; + goto out; error = 0; /* First read in as much as possible for each bufsize. */ while (already_read < count) { @@ -169,8 +166,9 @@ ncp_file_read(struct file *file, char *buf, size_t count, loff_t *ppos) pos, to_read, buf, &read_this_time, freepage, freelen); if (error) { - error = -EIO; /* NW errno -> Linux errno */ - break; + kfree(freepage); + error = -EIO; /* This is not exact, i know.. */ + goto out; } pos += read_this_time; buf += read_this_time; @@ -190,8 +188,6 @@ ncp_file_read(struct file *file, char *buf, size_t count, loff_t *ppos) DPRINTK("ncp_file_read: exit %s/%s\n", dentry->d_parent->d_name.name, dentry->d_name.name); -outrel: - ncp_inode_close(inode); out: return already_read ? already_read : error; } @@ -240,10 +236,8 @@ ncp_file_write(struct file *file, const char *buf, size_t count, loff_t *ppos) already_written = 0; bouncebuffer = kmalloc(bufsize, GFP_NFS); - if (!bouncebuffer) { - errno = -EIO; /* -ENOMEM */ - goto outrel; - } + if (!bouncebuffer) + return -EIO; /* -ENOMEM */ while (already_written < count) { int written_this_time; size_t to_write = min(bufsize - (pos % bufsize), @@ -277,15 +271,15 @@ ncp_file_write(struct file *file, const char *buf, size_t count, loff_t *ppos) } DPRINTK("ncp_file_write: exit %s/%s\n", dentry->d_parent->d_name.name, dentry->d_name.name); -outrel: - ncp_inode_close(inode); out: return already_written ? already_written : errno; } static int ncp_release(struct inode *inode, struct file *file) { - if (ncp_make_closed(inode)) { - DPRINTK("ncp_release: failed to close\n"); + if (NCP_FINFO(inode)->opened) { + if (ncp_make_closed(inode)) { + DPRINTK("ncp_release: failed to close\n"); + } } return 0; } diff --git a/fs/ncpfs/inode.c b/fs/ncpfs/inode.c index cff9649f5..e885aed47 100644 --- a/fs/ncpfs/inode.c +++ b/fs/ncpfs/inode.c @@ -61,6 +61,7 @@ void ncp_update_inode(struct inode *inode, struct ncp_entry_info *nwinfo) #ifdef CONFIG_NCPFS_STRONG NCP_FINFO(inode)->nwattr = nwinfo->i.attributes; #endif + NCP_FINFO(inode)->opened = nwinfo->opened; NCP_FINFO(inode)->access = nwinfo->access; NCP_FINFO(inode)->server_file_handle = nwinfo->server_file_handle; memcpy(NCP_FINFO(inode)->file_handle, nwinfo->file_handle, @@ -75,7 +76,7 @@ void ncp_update_inode2(struct inode* inode, struct ncp_entry_info *nwinfo) struct nw_info_struct *nwi = &nwinfo->i; struct ncp_server *server = NCP_SERVER(inode); - if (!atomic_read(&NCP_FINFO(inode)->opened)) { + if (!NCP_FINFO(inode)->opened) { #ifdef CONFIG_NCPFS_STRONG NCP_FINFO(inode)->nwattr = nwi->attributes; #endif @@ -215,9 +216,6 @@ ncp_iget(struct super_block *sb, struct ncp_entry_info *info) inode = get_empty_inode(); if (inode) { - init_MUTEX(&NCP_FINFO(inode)->open_sem); - atomic_set(&NCP_FINFO(inode)->opened, info->opened); - inode->i_sb = sb; inode->i_dev = sb->s_dev; inode->i_ino = info->ino; @@ -247,7 +245,7 @@ ncp_delete_inode(struct inode *inode) DDPRINTK("ncp_delete_inode: put directory %ld\n", inode->i_ino); } - if (ncp_make_closed(inode) != 0) { + if (NCP_FINFO(inode)->opened && ncp_make_closed(inode) != 0) { /* We can't do anything but complain. */ printk(KERN_ERR "ncp_delete_inode: could not close\n"); } @@ -320,6 +318,7 @@ ncp_read_super(struct super_block *sb, void *raw_data, int silent) sb->s_blocksize = 1024; /* Eh... Is this correct? */ sb->s_blocksize_bits = 10; sb->s_magic = NCP_SUPER_MAGIC; + sb->s_dev = dev; sb->s_op = &ncp_sops; server = NCP_SBP(sb); @@ -677,7 +676,6 @@ int ncp_notify_change(struct dentry *dentry, struct iattr *attr) /* According to ndir, the changes only take effect after closing the file */ - ncp_inode_close(inode); result = ncp_make_closed(inode); if (!result) vmtruncate(inode, attr->ia_size); diff --git a/fs/ncpfs/ioctl.c b/fs/ncpfs/ioctl.c index 24e616396..26c95fc8f 100644 --- a/fs/ncpfs/ioctl.c +++ b/fs/ncpfs/ioctl.c @@ -335,12 +335,18 @@ int ncp_ioctl(struct inode *inode, struct file *filp, { return result; } - result = -EIO; if (!ncp_conn_valid(server)) - goto outrel; - result = -EISDIR; + { + return -EIO; + } if (!S_ISREG(inode->i_mode)) - goto outrel; + { + return -EISDIR; + } + if (!NCP_FINFO(inode)->opened) + { + return -EBADFD; + } if (rqdata.cmd == NCP_LOCK_CLEAR) { result = ncp_ClearPhysicalRecord(NCP_SERVER(inode), @@ -367,8 +373,6 @@ int ncp_ioctl(struct inode *inode, struct file *filp, rqdata.timeout); if (result > 0) result = -EAGAIN; } -outrel: - ncp_inode_close(inode); return result; } #endif /* CONFIG_NCPFS_IOCTL_LOCKING */ diff --git a/fs/ncpfs/mmap.c b/fs/ncpfs/mmap.c index 08d28d895..752ae1e1e 100644 --- a/fs/ncpfs/mmap.c +++ b/fs/ncpfs/mmap.c @@ -82,7 +82,6 @@ static struct page* ncp_file_mmap_nopage(struct vm_area_struct *area, break; } } - ncp_inode_close(inode); } diff --git a/fs/ncpfs/ncplib_kernel.c b/fs/ncpfs/ncplib_kernel.c index 0353882b9..73afd107a 100644 --- a/fs/ncpfs/ncplib_kernel.c +++ b/fs/ncpfs/ncplib_kernel.c @@ -221,23 +221,20 @@ ncp_close_file(struct ncp_server *server, const char *file_id) return result; } +/* + * Called with the superblock locked. + */ int ncp_make_closed(struct inode *inode) { int err; + NCP_FINFO(inode)->opened = 0; + err = ncp_close_file(NCP_SERVER(inode), NCP_FINFO(inode)->file_handle); - err = 0; - down(&NCP_FINFO(inode)->open_sem); - if (atomic_read(&NCP_FINFO(inode)->opened) == 1) { - atomic_set(&NCP_FINFO(inode)->opened, 0); - err = ncp_close_file(NCP_SERVER(inode), NCP_FINFO(inode)->file_handle); - - if (!err) - PPRINTK("ncp_make_closed: volnum=%d, dirent=%u, error=%d\n", - NCP_FINFO(inode)->volNumber, - NCP_FINFO(inode)->dirEntNum, err); - } - up(&NCP_FINFO(inode)->open_sem); + if (!err) + PPRINTK("ncp_make_closed: volnum=%d, dirent=%u, error=%d\n", + NCP_FINFO(inode)->volNumber, + NCP_FINFO(inode)->dirEntNum, err); return err; } @@ -616,8 +613,7 @@ int ncp_open_create_file_or_subdir(struct ncp_server *server, if ((result = ncp_request(server, 87)) != 0) goto out; - if (!(create_attributes & aDIR)) - target->opened = 1; + target->opened = 1; target->server_file_handle = ncp_reply_dword(server, 0); target->open_create_action = ncp_reply_byte(server, 4); diff --git a/fs/ncpfs/ncplib_kernel.h b/fs/ncpfs/ncplib_kernel.h index 31797a3c3..8b33a5c2e 100644 --- a/fs/ncpfs/ncplib_kernel.h +++ b/fs/ncpfs/ncplib_kernel.h @@ -57,10 +57,6 @@ int ncp_read_kernel(struct ncp_server *, const char *, __u32, __u16, int ncp_write_kernel(struct ncp_server *, const char *, __u32, __u16, const char *, int *); -static inline void ncp_inode_close(struct inode *inode) { - atomic_dec(&NCP_FINFO(inode)->opened); -} - int ncp_obtain_info(struct ncp_server *server, struct inode *, char *, struct nw_info_struct *target); int ncp_lookup_volume(struct ncp_server *, char *, struct nw_info_struct *); diff --git a/fs/ncpfs/symlink.c b/fs/ncpfs/symlink.c index 0962593da..46925eb6d 100644 --- a/fs/ncpfs/symlink.c +++ b/fs/ncpfs/symlink.c @@ -50,6 +50,10 @@ static int ncp_symlink_readpage(struct file *file, struct page *page) char *link; char *buf = (char*)kmap(page); + error = -EIO; + if (ncp_make_open(inode,O_RDONLY)) + goto fail; + error = -ENOMEM; for (cnt = 0; (link=(char *)kmalloc(NCP_MAX_SYMLINK_SIZE, GFP_NFS))==NULL; cnt++) { if (cnt > 10) @@ -57,22 +61,20 @@ static int ncp_symlink_readpage(struct file *file, struct page *page) schedule(); } - if (ncp_make_open(inode,O_RDONLY)) - goto failEIO; - error=ncp_read_kernel(NCP_SERVER(inode),NCP_FINFO(inode)->file_handle, 0,NCP_MAX_SYMLINK_SIZE,link,&length); - ncp_inode_close(inode); - /* Close file handle if no other users... */ - ncp_make_closed(inode); - if (error) - goto failEIO; - + if (error) { + kfree(link); + goto fail; + } if (length<NCP_MIN_SYMLINK_SIZE || ((__u32 *)link)[0]!=NCP_SYMLINK_MAGIC0 || - ((__u32 *)link)[1]!=NCP_SYMLINK_MAGIC1) - goto failEIO; + ((__u32 *)link)[1]!=NCP_SYMLINK_MAGIC1) { + error = -EIO; + kfree(link); + goto fail; + } len = NCP_MAX_SYMLINK_SIZE; error = ncp_vol2io(NCP_SERVER(inode), buf, &len, link+8, length-8, 0); @@ -84,9 +86,6 @@ static int ncp_symlink_readpage(struct file *file, struct page *page) UnlockPage(page); return 0; -failEIO: - error = -EIO; - kfree(link); fail: SetPageError(page); kunmap(page); @@ -121,15 +120,13 @@ int ncp_symlink(struct inode *dir, struct dentry *dentry, const char *symname) { if ((link=(char *)kmalloc(length+9,GFP_NFS))==NULL) return -ENOMEM; - err = -EIO; - if (ncp_create_new(dir,dentry,0,aSHARED|aHIDDEN)) - goto failfree; + if (ncp_create_new(dir,dentry,0,aSHARED|aHIDDEN)) { + kfree(link); + return -EIO; + } inode=dentry->d_inode; - if (ncp_make_open(inode, O_WRONLY)) - goto failfree; - ((__u32 *)link)[0]=NCP_SYMLINK_MAGIC0; ((__u32 *)link)[1]=NCP_SYMLINK_MAGIC1; @@ -137,26 +134,19 @@ int ncp_symlink(struct inode *dir, struct dentry *dentry, const char *symname) { symlink can point out of ncp filesystem */ length += 1; err = ncp_io2vol(NCP_SERVER(inode),link+8,&length,symname,length-1,0); - if (err) - goto fail; + if (err) { + kfree(link); + return err; + } if(ncp_write_kernel(NCP_SERVER(inode), NCP_FINFO(inode)->file_handle, 0, length+8, link, &i) || i!=length+8) { - err = -EIO; - goto fail; + kfree(link); + return -EIO; } - ncp_inode_close(inode); - ncp_make_closed(inode); kfree(link); return 0; - -fail: - ncp_inode_close(inode); - ncp_make_closed(inode); -failfree: - kfree(link); - return err; } #endif |