summaryrefslogtreecommitdiffstats
path: root/fs/ncpfs/inode.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/ncpfs/inode.c')
-rw-r--r--fs/ncpfs/inode.c103
1 files changed, 57 insertions, 46 deletions
diff --git a/fs/ncpfs/inode.c b/fs/ncpfs/inode.c
index fa3385154023..d290545aa0c4 100644
--- a/fs/ncpfs/inode.c
+++ b/fs/ncpfs/inode.c
@@ -43,7 +43,7 @@
#define NCP_DEFAULT_TIME_OUT 10
#define NCP_DEFAULT_RETRY_COUNT 20
-static void ncp_delete_inode(struct inode *);
+static void ncp_evict_inode(struct inode *);
static void ncp_put_super(struct super_block *);
static int ncp_statfs(struct dentry *, struct kstatfs *);
static int ncp_show_options(struct seq_file *, struct vfsmount *);
@@ -100,7 +100,7 @@ static const struct super_operations ncp_sops =
.alloc_inode = ncp_alloc_inode,
.destroy_inode = ncp_destroy_inode,
.drop_inode = generic_delete_inode,
- .delete_inode = ncp_delete_inode,
+ .evict_inode = ncp_evict_inode,
.put_super = ncp_put_super,
.statfs = ncp_statfs,
.remount_fs = ncp_remount,
@@ -139,7 +139,7 @@ static void ncp_update_dates(struct inode *inode, struct nw_info_struct *nwi)
inode->i_mode = nwi->nfs.mode;
}
- inode->i_blocks = (inode->i_size + NCP_BLOCK_SIZE - 1) >> NCP_BLOCK_SHIFT;
+ inode->i_blocks = (i_size_read(inode) + NCP_BLOCK_SIZE - 1) >> NCP_BLOCK_SHIFT;
inode->i_mtime.tv_sec = ncp_date_dos2unix(nwi->modifyTime, nwi->modifyDate);
inode->i_ctime.tv_sec = ncp_date_dos2unix(nwi->creationTime, nwi->creationDate);
@@ -158,18 +158,21 @@ static void ncp_update_attrs(struct inode *inode, struct ncp_entry_info *nwinfo)
inode->i_mode = server->m.dir_mode;
/* for directories dataStreamSize seems to be some
Object ID ??? */
- inode->i_size = NCP_BLOCK_SIZE;
+ i_size_write(inode, NCP_BLOCK_SIZE);
} else {
+ u32 size;
+
inode->i_mode = server->m.file_mode;
- inode->i_size = le32_to_cpu(nwi->dataStreamSize);
+ size = le32_to_cpu(nwi->dataStreamSize);
+ i_size_write(inode, size);
#ifdef CONFIG_NCPFS_EXTRAS
if ((server->m.flags & (NCP_MOUNT_EXTRAS|NCP_MOUNT_SYMLINKS))
&& (nwi->attributes & aSHARED)) {
switch (nwi->attributes & (aHIDDEN|aSYSTEM)) {
case aHIDDEN:
if (server->m.flags & NCP_MOUNT_SYMLINKS) {
- if (/* (inode->i_size >= NCP_MIN_SYMLINK_SIZE)
- && */ (inode->i_size <= NCP_MAX_SYMLINK_SIZE)) {
+ if (/* (size >= NCP_MIN_SYMLINK_SIZE)
+ && */ (size <= NCP_MAX_SYMLINK_SIZE)) {
inode->i_mode = (inode->i_mode & ~S_IFMT) | S_IFLNK;
NCP_FINFO(inode)->flags |= NCPI_KLUDGE_SYMLINK;
break;
@@ -208,7 +211,7 @@ void ncp_update_inode2(struct inode* inode, struct ncp_entry_info *nwinfo)
}
/*
- * Fill in the inode based on the ncp_entry_info structure.
+ * Fill in the inode based on the ncp_entry_info structure. Used only for brand new inodes.
*/
static void ncp_set_attr(struct inode *inode, struct ncp_entry_info *nwinfo)
{
@@ -254,6 +257,7 @@ ncp_iget(struct super_block *sb, struct ncp_entry_info *info)
if (inode) {
atomic_set(&NCP_FINFO(inode)->opened, info->opened);
+ inode->i_mapping->backing_dev_info = sb->s_bdi;
inode->i_ino = info->ino;
ncp_set_attr(inode, info);
if (S_ISREG(inode->i_mode)) {
@@ -282,27 +286,29 @@ ncp_iget(struct super_block *sb, struct ncp_entry_info *info)
}
static void
-ncp_delete_inode(struct inode *inode)
+ncp_evict_inode(struct inode *inode)
{
truncate_inode_pages(&inode->i_data, 0);
+ end_writeback(inode);
if (S_ISDIR(inode->i_mode)) {
- DDPRINTK("ncp_delete_inode: put directory %ld\n", inode->i_ino);
+ DDPRINTK("ncp_evict_inode: put directory %ld\n", inode->i_ino);
}
if (ncp_make_closed(inode) != 0) {
/* We can't do anything but complain. */
- printk(KERN_ERR "ncp_delete_inode: could not close\n");
+ printk(KERN_ERR "ncp_evict_inode: could not close\n");
}
- clear_inode(inode);
}
static void ncp_stop_tasks(struct ncp_server *server) {
struct sock* sk = server->ncp_sock->sk;
-
+
+ lock_sock(sk);
sk->sk_error_report = server->error_report;
sk->sk_data_ready = server->data_ready;
sk->sk_write_space = server->write_space;
+ release_sock(sk);
del_timer_sync(&server->timeout_tm);
flush_scheduled_work();
}
@@ -565,10 +571,12 @@ static int ncp_fill_super(struct super_block *sb, void *raw_data, int silent)
/* server->conn_status = 0; */
/* server->root_dentry = NULL; */
/* server->root_setuped = 0; */
+ mutex_init(&server->root_setup_lock);
#ifdef CONFIG_NCPFS_PACKET_SIGNING
/* server->sign_wanted = 0; */
/* server->sign_active = 0; */
#endif
+ init_rwsem(&server->auth_rwsem);
server->auth.auth_type = NCP_AUTH_NONE;
/* server->auth.object_name_len = 0; */
/* server->auth.object_name = NULL; */
@@ -593,16 +601,12 @@ static int ncp_fill_super(struct super_block *sb, void *raw_data, int silent)
server->nls_io = load_nls_default();
#endif /* CONFIG_NCPFS_NLS */
- server->dentry_ttl = 0; /* no caching */
+ atomic_set(&server->dentry_ttl, 0); /* no caching */
INIT_LIST_HEAD(&server->tx.requests);
mutex_init(&server->rcv.creq_mutex);
server->tx.creq = NULL;
server->rcv.creq = NULL;
- server->data_ready = sock->sk->sk_data_ready;
- server->write_space = sock->sk->sk_write_space;
- server->error_report = sock->sk->sk_error_report;
- sock->sk->sk_user_data = server;
init_timer(&server->timeout_tm);
#undef NCP_PACKET_SIZE
@@ -619,6 +623,11 @@ static int ncp_fill_super(struct super_block *sb, void *raw_data, int silent)
if (server->rxbuf == NULL)
goto out_txbuf;
+ lock_sock(sock->sk);
+ server->data_ready = sock->sk->sk_data_ready;
+ server->write_space = sock->sk->sk_write_space;
+ server->error_report = sock->sk->sk_error_report;
+ sock->sk->sk_user_data = server;
sock->sk->sk_data_ready = ncp_tcp_data_ready;
sock->sk->sk_error_report = ncp_tcp_error_report;
if (sock->type == SOCK_STREAM) {
@@ -634,6 +643,7 @@ static int ncp_fill_super(struct super_block *sb, void *raw_data, int silent)
server->timeout_tm.data = (unsigned long)server;
server->timeout_tm.function = ncpdgram_timeout_call;
}
+ release_sock(sock->sk);
ncp_lock_server(server);
error = ncp_connect(server);
@@ -658,8 +668,10 @@ static int ncp_fill_super(struct super_block *sb, void *raw_data, int silent)
goto out_disconnect;
}
}
+ ncp_lock_server(server);
if (options & 2)
server->sign_wanted = 1;
+ ncp_unlock_server(server);
}
else
#endif /* CONFIG_NCPFS_PACKET_SIGNING */
@@ -720,6 +732,9 @@ out_nls:
unload_nls(server->nls_io);
unload_nls(server->nls_vol);
#endif
+ mutex_destroy(&server->rcv.creq_mutex);
+ mutex_destroy(&server->root_setup_lock);
+ mutex_destroy(&server->mutex);
out_fput2:
if (server->info_filp)
fput(server->info_filp);
@@ -728,8 +743,8 @@ out_fput:
out_bdi:
/* 23/12/1998 Marcin Dalecki <dalecki@cs.net.pl>:
*
- * The previously used put_filp(ncp_filp); was bogous, since
- * it doesn't proper unlocking.
+ * The previously used put_filp(ncp_filp); was bogus, since
+ * it doesn't perform proper unlocking.
*/
fput(ncp_filp);
out:
@@ -743,8 +758,6 @@ static void ncp_put_super(struct super_block *sb)
{
struct ncp_server *server = NCP_SBP(sb);
- lock_kernel();
-
ncp_lock_server(server);
ncp_disconnect(server);
ncp_unlock_server(server);
@@ -756,6 +769,9 @@ static void ncp_put_super(struct super_block *sb)
unload_nls(server->nls_vol);
unload_nls(server->nls_io);
#endif /* CONFIG_NCPFS_NLS */
+ mutex_destroy(&server->rcv.creq_mutex);
+ mutex_destroy(&server->root_setup_lock);
+ mutex_destroy(&server->mutex);
if (server->info_filp)
fput(server->info_filp);
@@ -771,8 +787,6 @@ static void ncp_put_super(struct super_block *sb)
vfree(server->packet);
sb->s_fs_info = NULL;
kfree(server);
-
- unlock_kernel();
}
static int ncp_statfs(struct dentry *dentry, struct kstatfs *buf)
@@ -851,10 +865,8 @@ int ncp_notify_change(struct dentry *dentry, struct iattr *attr)
result = -EIO;
- lock_kernel();
-
server = NCP_SERVER(inode);
- if ((!server) || !ncp_conn_valid(server))
+ if (!server) /* How this could happen? */
goto out;
/* ageing the dentry to force validation */
@@ -924,9 +936,8 @@ int ncp_notify_change(struct dentry *dentry, struct iattr *attr)
tmpattr.ia_valid = ATTR_MODE;
tmpattr.ia_mode = attr->ia_mode;
- result = inode_setattr(inode, &tmpattr);
- if (result)
- goto out;
+ setattr_copy(inode, &tmpattr);
+ mark_inode_dirty(inode);
}
}
#endif
@@ -954,15 +965,12 @@ int ncp_notify_change(struct dentry *dentry, struct iattr *attr)
result = ncp_make_closed(inode);
if (result)
goto out;
- {
- struct iattr tmpattr;
-
- tmpattr.ia_valid = ATTR_SIZE;
- tmpattr.ia_size = attr->ia_size;
-
- result = inode_setattr(inode, &tmpattr);
+
+ if (attr->ia_size != i_size_read(inode)) {
+ result = vmtruncate(inode, attr->ia_size);
if (result)
goto out;
+ mark_inode_dirty(inode);
}
}
if ((attr->ia_valid & ATTR_CTIME) != 0) {
@@ -985,8 +993,6 @@ int ncp_notify_change(struct dentry *dentry, struct iattr *attr)
result = ncp_modify_file_or_subdir_dos_info(NCP_SERVER(inode),
inode, info_mask, &info);
if (result != 0) {
- result = -EACCES;
-
if (info_mask == (DM_CREATE_TIME | DM_CREATE_DATE)) {
/* NetWare seems not to allow this. I
do not know why. So, just tell the
@@ -1002,23 +1008,28 @@ int ncp_notify_change(struct dentry *dentry, struct iattr *attr)
NCP_FINFO(inode)->nwattr = info.attributes;
#endif
}
- if (!result)
- result = inode_setattr(inode, attr);
+ if (result)
+ goto out;
+
+ setattr_copy(inode, attr);
+ mark_inode_dirty(inode);
+
out:
- unlock_kernel();
+ if (result > 0)
+ result = -EACCES;
return result;
}
-static int ncp_get_sb(struct file_system_type *fs_type,
- int flags, const char *dev_name, void *data, struct vfsmount *mnt)
+static struct dentry *ncp_mount(struct file_system_type *fs_type,
+ int flags, const char *dev_name, void *data)
{
- return get_sb_nodev(fs_type, flags, data, ncp_fill_super, mnt);
+ return mount_nodev(fs_type, flags, data, ncp_fill_super);
}
static struct file_system_type ncp_fs_type = {
.owner = THIS_MODULE,
.name = "ncpfs",
- .get_sb = ncp_get_sb,
+ .mount = ncp_mount,
.kill_sb = kill_anon_super,
.fs_flags = FS_BINARY_MOUNTDATA,
};