summaryrefslogtreecommitdiffstats
path: root/fs/ncpfs
diff options
context:
space:
mode:
Diffstat (limited to 'fs/ncpfs')
-rw-r--r--fs/ncpfs/dir.c6
-rw-r--r--fs/ncpfs/file.c38
-rw-r--r--fs/ncpfs/inode.c10
-rw-r--r--fs/ncpfs/ioctl.c16
-rw-r--r--fs/ncpfs/mmap.c1
-rw-r--r--fs/ncpfs/ncplib_kernel.c24
-rw-r--r--fs/ncpfs/ncplib_kernel.h4
-rw-r--r--fs/ncpfs/symlink.c56
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