diff options
Diffstat (limited to 'fs/ncpfs/inode.c')
| -rw-r--r-- | fs/ncpfs/inode.c | 103 | 
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,  }; | 
