aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ncpfs/inode.c
diff options
context:
space:
mode:
authorPetr Vandrovec <petr@vandrovec.name>2010-09-26 19:47:33 -0400
committerArnd Bergmann <arnd@arndb.de>2010-10-04 15:10:52 -0400
commit2e54eb96e2c801f33d95b5dade15212ac4d6c4a5 (patch)
treec2996f29aa49881e93c7a37fad41e4961f6b8578 /fs/ncpfs/inode.c
parent60056794127a25d641465b706e8828186f7a2e1f (diff)
BKL: Remove BKL from ncpfs
Dozen of changes in ncpfs to provide some locking other than BKL. In readdir cache unlock and mark complete first page as last operation, so it can be used for synchronization, as code intended. When updating dentry name on case insensitive filesystems do at least some basic locking... Hold i_mutex when updating inode fields. Push some ncp_conn_is_valid down to ncp_request. Connection can become invalid at any moment, and fewer error code paths to test the better. Use i_size_{read,write} to modify file size. Set inode's backing_dev_info as ncpfs has its own special bdi. In ioctl unbreak ioctls invoked on filesystem mounted 'ro' - tests are for inode writeable or owner match, but were turned to filesystem writeable and inode writeable or owner match. Also collect all permission checks in single place. Add some locking, and remove comments saying that it would be cool to add some locks to the code. Constify some pointers. Signed-off-by: Petr Vandrovec <petr@vandrovec.name> Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Diffstat (limited to 'fs/ncpfs/inode.c')
-rw-r--r--fs/ncpfs/inode.c41
1 files changed, 24 insertions, 17 deletions
diff --git a/fs/ncpfs/inode.c b/fs/ncpfs/inode.c
index b4de38cf49f5..5f4e58d93fdd 100644
--- a/fs/ncpfs/inode.c
+++ b/fs/ncpfs/inode.c
@@ -139,7 +139,7 @@ static void ncp_update_dates(struct inode *inode, struct nw_info_struct *nwi)
139 inode->i_mode = nwi->nfs.mode; 139 inode->i_mode = nwi->nfs.mode;
140 } 140 }
141 141
142 inode->i_blocks = (inode->i_size + NCP_BLOCK_SIZE - 1) >> NCP_BLOCK_SHIFT; 142 inode->i_blocks = (i_size_read(inode) + NCP_BLOCK_SIZE - 1) >> NCP_BLOCK_SHIFT;
143 143
144 inode->i_mtime.tv_sec = ncp_date_dos2unix(nwi->modifyTime, nwi->modifyDate); 144 inode->i_mtime.tv_sec = ncp_date_dos2unix(nwi->modifyTime, nwi->modifyDate);
145 inode->i_ctime.tv_sec = ncp_date_dos2unix(nwi->creationTime, nwi->creationDate); 145 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)
158 inode->i_mode = server->m.dir_mode; 158 inode->i_mode = server->m.dir_mode;
159 /* for directories dataStreamSize seems to be some 159 /* for directories dataStreamSize seems to be some
160 Object ID ??? */ 160 Object ID ??? */
161 inode->i_size = NCP_BLOCK_SIZE; 161 i_size_write(inode, NCP_BLOCK_SIZE);
162 } else { 162 } else {
163 u32 size;
164
163 inode->i_mode = server->m.file_mode; 165 inode->i_mode = server->m.file_mode;
164 inode->i_size = le32_to_cpu(nwi->dataStreamSize); 166 size = le32_to_cpu(nwi->dataStreamSize);
167 i_size_write(inode, size);
165#ifdef CONFIG_NCPFS_EXTRAS 168#ifdef CONFIG_NCPFS_EXTRAS
166 if ((server->m.flags & (NCP_MOUNT_EXTRAS|NCP_MOUNT_SYMLINKS)) 169 if ((server->m.flags & (NCP_MOUNT_EXTRAS|NCP_MOUNT_SYMLINKS))
167 && (nwi->attributes & aSHARED)) { 170 && (nwi->attributes & aSHARED)) {
168 switch (nwi->attributes & (aHIDDEN|aSYSTEM)) { 171 switch (nwi->attributes & (aHIDDEN|aSYSTEM)) {
169 case aHIDDEN: 172 case aHIDDEN:
170 if (server->m.flags & NCP_MOUNT_SYMLINKS) { 173 if (server->m.flags & NCP_MOUNT_SYMLINKS) {
171 if (/* (inode->i_size >= NCP_MIN_SYMLINK_SIZE) 174 if (/* (size >= NCP_MIN_SYMLINK_SIZE)
172 && */ (inode->i_size <= NCP_MAX_SYMLINK_SIZE)) { 175 && */ (size <= NCP_MAX_SYMLINK_SIZE)) {
173 inode->i_mode = (inode->i_mode & ~S_IFMT) | S_IFLNK; 176 inode->i_mode = (inode->i_mode & ~S_IFMT) | S_IFLNK;
174 NCP_FINFO(inode)->flags |= NCPI_KLUDGE_SYMLINK; 177 NCP_FINFO(inode)->flags |= NCPI_KLUDGE_SYMLINK;
175 break; 178 break;
@@ -208,7 +211,7 @@ void ncp_update_inode2(struct inode* inode, struct ncp_entry_info *nwinfo)
208} 211}
209 212
210/* 213/*
211 * Fill in the inode based on the ncp_entry_info structure. 214 * Fill in the inode based on the ncp_entry_info structure. Used only for brand new inodes.
212 */ 215 */
213static void ncp_set_attr(struct inode *inode, struct ncp_entry_info *nwinfo) 216static void ncp_set_attr(struct inode *inode, struct ncp_entry_info *nwinfo)
214{ 217{
@@ -254,6 +257,7 @@ ncp_iget(struct super_block *sb, struct ncp_entry_info *info)
254 if (inode) { 257 if (inode) {
255 atomic_set(&NCP_FINFO(inode)->opened, info->opened); 258 atomic_set(&NCP_FINFO(inode)->opened, info->opened);
256 259
260 inode->i_mapping->backing_dev_info = sb->s_bdi;
257 inode->i_ino = info->ino; 261 inode->i_ino = info->ino;
258 ncp_set_attr(inode, info); 262 ncp_set_attr(inode, info);
259 if (S_ISREG(inode->i_mode)) { 263 if (S_ISREG(inode->i_mode)) {
@@ -565,10 +569,12 @@ static int ncp_fill_super(struct super_block *sb, void *raw_data, int silent)
565/* server->conn_status = 0; */ 569/* server->conn_status = 0; */
566/* server->root_dentry = NULL; */ 570/* server->root_dentry = NULL; */
567/* server->root_setuped = 0; */ 571/* server->root_setuped = 0; */
572 mutex_init(&server->root_setup_lock);
568#ifdef CONFIG_NCPFS_PACKET_SIGNING 573#ifdef CONFIG_NCPFS_PACKET_SIGNING
569/* server->sign_wanted = 0; */ 574/* server->sign_wanted = 0; */
570/* server->sign_active = 0; */ 575/* server->sign_active = 0; */
571#endif 576#endif
577 init_rwsem(&server->auth_rwsem);
572 server->auth.auth_type = NCP_AUTH_NONE; 578 server->auth.auth_type = NCP_AUTH_NONE;
573/* server->auth.object_name_len = 0; */ 579/* server->auth.object_name_len = 0; */
574/* server->auth.object_name = NULL; */ 580/* server->auth.object_name = NULL; */
@@ -593,7 +599,7 @@ static int ncp_fill_super(struct super_block *sb, void *raw_data, int silent)
593 server->nls_io = load_nls_default(); 599 server->nls_io = load_nls_default();
594#endif /* CONFIG_NCPFS_NLS */ 600#endif /* CONFIG_NCPFS_NLS */
595 601
596 server->dentry_ttl = 0; /* no caching */ 602 atomic_set(&server->dentry_ttl, 0); /* no caching */
597 603
598 INIT_LIST_HEAD(&server->tx.requests); 604 INIT_LIST_HEAD(&server->tx.requests);
599 mutex_init(&server->rcv.creq_mutex); 605 mutex_init(&server->rcv.creq_mutex);
@@ -658,8 +664,10 @@ static int ncp_fill_super(struct super_block *sb, void *raw_data, int silent)
658 goto out_disconnect; 664 goto out_disconnect;
659 } 665 }
660 } 666 }
667 ncp_lock_server(server);
661 if (options & 2) 668 if (options & 2)
662 server->sign_wanted = 1; 669 server->sign_wanted = 1;
670 ncp_unlock_server(server);
663 } 671 }
664 else 672 else
665#endif /* CONFIG_NCPFS_PACKET_SIGNING */ 673#endif /* CONFIG_NCPFS_PACKET_SIGNING */
@@ -720,6 +728,9 @@ out_nls:
720 unload_nls(server->nls_io); 728 unload_nls(server->nls_io);
721 unload_nls(server->nls_vol); 729 unload_nls(server->nls_vol);
722#endif 730#endif
731 mutex_destroy(&server->rcv.creq_mutex);
732 mutex_destroy(&server->root_setup_lock);
733 mutex_destroy(&server->mutex);
723out_fput2: 734out_fput2:
724 if (server->info_filp) 735 if (server->info_filp)
725 fput(server->info_filp); 736 fput(server->info_filp);
@@ -743,8 +754,6 @@ static void ncp_put_super(struct super_block *sb)
743{ 754{
744 struct ncp_server *server = NCP_SBP(sb); 755 struct ncp_server *server = NCP_SBP(sb);
745 756
746 lock_kernel();
747
748 ncp_lock_server(server); 757 ncp_lock_server(server);
749 ncp_disconnect(server); 758 ncp_disconnect(server);
750 ncp_unlock_server(server); 759 ncp_unlock_server(server);
@@ -756,6 +765,9 @@ static void ncp_put_super(struct super_block *sb)
756 unload_nls(server->nls_vol); 765 unload_nls(server->nls_vol);
757 unload_nls(server->nls_io); 766 unload_nls(server->nls_io);
758#endif /* CONFIG_NCPFS_NLS */ 767#endif /* CONFIG_NCPFS_NLS */
768 mutex_destroy(&server->rcv.creq_mutex);
769 mutex_destroy(&server->root_setup_lock);
770 mutex_destroy(&server->mutex);
759 771
760 if (server->info_filp) 772 if (server->info_filp)
761 fput(server->info_filp); 773 fput(server->info_filp);
@@ -771,8 +783,6 @@ static void ncp_put_super(struct super_block *sb)
771 vfree(server->packet); 783 vfree(server->packet);
772 sb->s_fs_info = NULL; 784 sb->s_fs_info = NULL;
773 kfree(server); 785 kfree(server);
774
775 unlock_kernel();
776} 786}
777 787
778static int ncp_statfs(struct dentry *dentry, struct kstatfs *buf) 788static int ncp_statfs(struct dentry *dentry, struct kstatfs *buf)
@@ -851,10 +861,8 @@ int ncp_notify_change(struct dentry *dentry, struct iattr *attr)
851 861
852 result = -EIO; 862 result = -EIO;
853 863
854 lock_kernel();
855
856 server = NCP_SERVER(inode); 864 server = NCP_SERVER(inode);
857 if ((!server) || !ncp_conn_valid(server)) 865 if (!server) /* How this could happen? */
858 goto out; 866 goto out;
859 867
860 /* ageing the dentry to force validation */ 868 /* ageing the dentry to force validation */
@@ -981,8 +989,6 @@ int ncp_notify_change(struct dentry *dentry, struct iattr *attr)
981 result = ncp_modify_file_or_subdir_dos_info(NCP_SERVER(inode), 989 result = ncp_modify_file_or_subdir_dos_info(NCP_SERVER(inode),
982 inode, info_mask, &info); 990 inode, info_mask, &info);
983 if (result != 0) { 991 if (result != 0) {
984 result = -EACCES;
985
986 if (info_mask == (DM_CREATE_TIME | DM_CREATE_DATE)) { 992 if (info_mask == (DM_CREATE_TIME | DM_CREATE_DATE)) {
987 /* NetWare seems not to allow this. I 993 /* NetWare seems not to allow this. I
988 do not know why. So, just tell the 994 do not know why. So, just tell the
@@ -1005,7 +1011,8 @@ int ncp_notify_change(struct dentry *dentry, struct iattr *attr)
1005 mark_inode_dirty(inode); 1011 mark_inode_dirty(inode);
1006 1012
1007out: 1013out:
1008 unlock_kernel(); 1014 if (result > 0)
1015 result = -EACCES;
1009 return result; 1016 return result;
1010} 1017}
1011 1018