aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ncpfs/ncplib_kernel.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/ncplib_kernel.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/ncplib_kernel.c')
-rw-r--r--fs/ncpfs/ncplib_kernel.c101
1 files changed, 56 insertions, 45 deletions
diff --git a/fs/ncpfs/ncplib_kernel.c b/fs/ncpfs/ncplib_kernel.c
index 0ec6237a5970..a95615a0b6ac 100644
--- a/fs/ncpfs/ncplib_kernel.c
+++ b/fs/ncpfs/ncplib_kernel.c
@@ -107,17 +107,17 @@ ncp_reply_data(struct ncp_server *server, int offset)
107 return &(server->packet[sizeof(struct ncp_reply_header) + offset]); 107 return &(server->packet[sizeof(struct ncp_reply_header) + offset]);
108} 108}
109 109
110static inline u8 BVAL(void *data) 110static inline u8 BVAL(const void *data)
111{ 111{
112 return *(u8 *)data; 112 return *(const u8 *)data;
113} 113}
114 114
115static u8 ncp_reply_byte(struct ncp_server *server, int offset) 115static u8 ncp_reply_byte(struct ncp_server *server, int offset)
116{ 116{
117 return *(u8 *)ncp_reply_data(server, offset); 117 return *(const u8 *)ncp_reply_data(server, offset);
118} 118}
119 119
120static inline u16 WVAL_LH(void *data) 120static inline u16 WVAL_LH(const void *data)
121{ 121{
122 return get_unaligned_le16(data); 122 return get_unaligned_le16(data);
123} 123}
@@ -134,7 +134,7 @@ ncp_reply_be16(struct ncp_server *server, int offset)
134 return get_unaligned_be16(ncp_reply_data(server, offset)); 134 return get_unaligned_be16(ncp_reply_data(server, offset));
135} 135}
136 136
137static inline u32 DVAL_LH(void *data) 137static inline u32 DVAL_LH(const void *data)
138{ 138{
139 return get_unaligned_le32(data); 139 return get_unaligned_le32(data);
140} 140}
@@ -349,9 +349,9 @@ int ncp_dirhandle_free(struct ncp_server* server, __u8 dirhandle) {
349 return result; 349 return result;
350} 350}
351 351
352void ncp_extract_file_info(void *structure, struct nw_info_struct *target) 352void ncp_extract_file_info(const void *structure, struct nw_info_struct *target)
353{ 353{
354 __u8 *name_len; 354 const __u8 *name_len;
355 const int info_struct_size = offsetof(struct nw_info_struct, nameLen); 355 const int info_struct_size = offsetof(struct nw_info_struct, nameLen);
356 356
357 memcpy(target, structure, info_struct_size); 357 memcpy(target, structure, info_struct_size);
@@ -364,7 +364,7 @@ void ncp_extract_file_info(void *structure, struct nw_info_struct *target)
364} 364}
365 365
366#ifdef CONFIG_NCPFS_NFS_NS 366#ifdef CONFIG_NCPFS_NFS_NS
367static inline void ncp_extract_nfs_info(unsigned char *structure, 367static inline void ncp_extract_nfs_info(const unsigned char *structure,
368 struct nw_nfs_info *target) 368 struct nw_nfs_info *target)
369{ 369{
370 target->mode = DVAL_LH(structure); 370 target->mode = DVAL_LH(structure);
@@ -417,7 +417,7 @@ int ncp_obtain_nfs_info(struct ncp_server *server,
417 * Returns information for a (one-component) name relative to 417 * Returns information for a (one-component) name relative to
418 * the specified directory. 418 * the specified directory.
419 */ 419 */
420int ncp_obtain_info(struct ncp_server *server, struct inode *dir, char *path, 420int ncp_obtain_info(struct ncp_server *server, struct inode *dir, const char *path,
421 struct nw_info_struct *target) 421 struct nw_info_struct *target)
422{ 422{
423 __u8 volnum = NCP_FINFO(dir)->volNumber; 423 __u8 volnum = NCP_FINFO(dir)->volNumber;
@@ -452,16 +452,16 @@ out:
452#ifdef CONFIG_NCPFS_NFS_NS 452#ifdef CONFIG_NCPFS_NFS_NS
453static int 453static int
454ncp_obtain_DOS_dir_base(struct ncp_server *server, 454ncp_obtain_DOS_dir_base(struct ncp_server *server,
455 __u8 volnum, __le32 dirent, 455 __u8 ns, __u8 volnum, __le32 dirent,
456 char *path, /* At most 1 component */ 456 const char *path, /* At most 1 component */
457 __le32 *DOS_dir_base) 457 __le32 *DOS_dir_base)
458{ 458{
459 int result; 459 int result;
460 460
461 ncp_init_request(server); 461 ncp_init_request(server);
462 ncp_add_byte(server, 6); /* subfunction */ 462 ncp_add_byte(server, 6); /* subfunction */
463 ncp_add_byte(server, server->name_space[volnum]); 463 ncp_add_byte(server, ns);
464 ncp_add_byte(server, server->name_space[volnum]); 464 ncp_add_byte(server, ns);
465 ncp_add_word(server, cpu_to_le16(0x8006)); /* get all */ 465 ncp_add_word(server, cpu_to_le16(0x8006)); /* get all */
466 ncp_add_dword(server, RIM_DIRECTORY); 466 ncp_add_dword(server, RIM_DIRECTORY);
467 ncp_add_handle_path(server, volnum, dirent, 1, path); 467 ncp_add_handle_path(server, volnum, dirent, 1, path);
@@ -523,10 +523,27 @@ ncp_get_known_namespace(struct ncp_server *server, __u8 volume)
523#endif /* defined(CONFIG_NCPFS_OS2_NS) || defined(CONFIG_NCPFS_NFS_NS) */ 523#endif /* defined(CONFIG_NCPFS_OS2_NS) || defined(CONFIG_NCPFS_NFS_NS) */
524} 524}
525 525
526int
527ncp_update_known_namespace(struct ncp_server *server, __u8 volume, int *ret_ns)
528{
529 int ns = ncp_get_known_namespace(server, volume);
530
531 if (ret_ns)
532 *ret_ns = ns;
533
534 DPRINTK("lookup_vol: namespace[%d] = %d\n",
535 volume, server->name_space[volume]);
536
537 if (server->name_space[volume] == ns)
538 return 0;
539 server->name_space[volume] = ns;
540 return 1;
541}
542
526static int 543static int
527ncp_ObtainSpecificDirBase(struct ncp_server *server, 544ncp_ObtainSpecificDirBase(struct ncp_server *server,
528 __u8 nsSrc, __u8 nsDst, __u8 vol_num, __le32 dir_base, 545 __u8 nsSrc, __u8 nsDst, __u8 vol_num, __le32 dir_base,
529 char *path, /* At most 1 component */ 546 const char *path, /* At most 1 component */
530 __le32 *dirEntNum, __le32 *DosDirNum) 547 __le32 *dirEntNum, __le32 *DosDirNum)
531{ 548{
532 int result; 549 int result;
@@ -560,14 +577,13 @@ ncp_mount_subdir(struct ncp_server *server,
560{ 577{
561 int dstNS; 578 int dstNS;
562 int result; 579 int result;
563 580
564 dstNS = ncp_get_known_namespace(server, volNumber); 581 ncp_update_known_namespace(server, volNumber, &dstNS);
565 if ((result = ncp_ObtainSpecificDirBase(server, srcNS, dstNS, volNumber, 582 if ((result = ncp_ObtainSpecificDirBase(server, srcNS, dstNS, volNumber,
566 dirEntNum, NULL, newDirEnt, newDosEnt)) != 0) 583 dirEntNum, NULL, newDirEnt, newDosEnt)) != 0)
567 { 584 {
568 return result; 585 return result;
569 } 586 }
570 server->name_space[volNumber] = dstNS;
571 *volume = volNumber; 587 *volume = volNumber;
572 server->m.mounted_vol[1] = 0; 588 server->m.mounted_vol[1] = 0;
573 server->m.mounted_vol[0] = 'X'; 589 server->m.mounted_vol[0] = 'X';
@@ -575,11 +591,10 @@ ncp_mount_subdir(struct ncp_server *server,
575} 591}
576 592
577int 593int
578ncp_get_volume_root(struct ncp_server *server, const char *volname, 594ncp_get_volume_root(struct ncp_server *server,
579 __u32* volume, __le32* dirent, __le32* dosdirent) 595 const char *volname, __u32* volume, __le32* dirent, __le32* dosdirent)
580{ 596{
581 int result; 597 int result;
582 __u8 volnum;
583 598
584 DPRINTK("ncp_get_volume_root: looking up vol %s\n", volname); 599 DPRINTK("ncp_get_volume_root: looking up vol %s\n", volname);
585 600
@@ -601,21 +616,14 @@ ncp_get_volume_root(struct ncp_server *server, const char *volname,
601 return result; 616 return result;
602 } 617 }
603 *dirent = *dosdirent = ncp_reply_dword(server, 4); 618 *dirent = *dosdirent = ncp_reply_dword(server, 4);
604 volnum = ncp_reply_byte(server, 8); 619 *volume = ncp_reply_byte(server, 8);
605 ncp_unlock_server(server); 620 ncp_unlock_server(server);
606 *volume = volnum;
607
608 server->name_space[volnum] = ncp_get_known_namespace(server, volnum);
609
610 DPRINTK("lookup_vol: namespace[%d] = %d\n",
611 volnum, server->name_space[volnum]);
612
613 return 0; 621 return 0;
614} 622}
615 623
616int 624int
617ncp_lookup_volume(struct ncp_server *server, const char *volname, 625ncp_lookup_volume(struct ncp_server *server,
618 struct nw_info_struct *target) 626 const char *volname, struct nw_info_struct *target)
619{ 627{
620 int result; 628 int result;
621 629
@@ -625,6 +633,7 @@ ncp_lookup_volume(struct ncp_server *server, const char *volname,
625 if (result) { 633 if (result) {
626 return result; 634 return result;
627 } 635 }
636 ncp_update_known_namespace(server, target->volNumber, NULL);
628 target->nameLen = strlen(volname); 637 target->nameLen = strlen(volname);
629 memcpy(target->entryName, volname, target->nameLen+1); 638 memcpy(target->entryName, volname, target->nameLen+1);
630 target->attributes = aDIR; 639 target->attributes = aDIR;
@@ -676,8 +685,8 @@ int ncp_modify_nfs_info(struct ncp_server *server, __u8 volnum, __le32 dirent,
676{ 685{
677 int result = 0; 686 int result = 0;
678 687
688 ncp_init_request(server);
679 if (server->name_space[volnum] == NW_NS_NFS) { 689 if (server->name_space[volnum] == NW_NS_NFS) {
680 ncp_init_request(server);
681 ncp_add_byte(server, 25); /* subfunction */ 690 ncp_add_byte(server, 25); /* subfunction */
682 ncp_add_byte(server, server->name_space[volnum]); 691 ncp_add_byte(server, server->name_space[volnum]);
683 ncp_add_byte(server, NW_NS_NFS); 692 ncp_add_byte(server, NW_NS_NFS);
@@ -690,8 +699,8 @@ int ncp_modify_nfs_info(struct ncp_server *server, __u8 volnum, __le32 dirent,
690 ncp_add_dword_lh(server, 1); /* nlinks */ 699 ncp_add_dword_lh(server, 1); /* nlinks */
691 ncp_add_dword_lh(server, rdev); 700 ncp_add_dword_lh(server, rdev);
692 result = ncp_request(server, 87); 701 result = ncp_request(server, 87);
693 ncp_unlock_server(server);
694 } 702 }
703 ncp_unlock_server(server);
695 return result; 704 return result;
696} 705}
697#endif 706#endif
@@ -700,7 +709,7 @@ int ncp_modify_nfs_info(struct ncp_server *server, __u8 volnum, __le32 dirent,
700static int 709static int
701ncp_DeleteNSEntry(struct ncp_server *server, 710ncp_DeleteNSEntry(struct ncp_server *server,
702 __u8 have_dir_base, __u8 volnum, __le32 dirent, 711 __u8 have_dir_base, __u8 volnum, __le32 dirent,
703 char* name, __u8 ns, __le16 attr) 712 const char* name, __u8 ns, __le16 attr)
704{ 713{
705 int result; 714 int result;
706 715
@@ -734,23 +743,25 @@ ncp_del_file_or_subdir2(struct ncp_server *server,
734 743
735int 744int
736ncp_del_file_or_subdir(struct ncp_server *server, 745ncp_del_file_or_subdir(struct ncp_server *server,
737 struct inode *dir, char *name) 746 struct inode *dir, const char *name)
738{ 747{
739 __u8 volnum = NCP_FINFO(dir)->volNumber; 748 __u8 volnum = NCP_FINFO(dir)->volNumber;
740 __le32 dirent = NCP_FINFO(dir)->dirEntNum; 749 __le32 dirent = NCP_FINFO(dir)->dirEntNum;
750 int name_space;
741 751
752 name_space = server->name_space[volnum];
742#ifdef CONFIG_NCPFS_NFS_NS 753#ifdef CONFIG_NCPFS_NFS_NS
743 if (server->name_space[volnum]==NW_NS_NFS) 754 if (name_space == NW_NS_NFS)
744 { 755 {
745 int result; 756 int result;
746 757
747 result=ncp_obtain_DOS_dir_base(server, volnum, dirent, name, &dirent); 758 result=ncp_obtain_DOS_dir_base(server, name_space, volnum, dirent, name, &dirent);
748 if (result) return result; 759 if (result) return result;
749 return ncp_DeleteNSEntry(server, 1, volnum, dirent, NULL, NW_NS_DOS, cpu_to_le16(0x8006)); 760 name = NULL;
761 name_space = NW_NS_DOS;
750 } 762 }
751 else
752#endif /* CONFIG_NCPFS_NFS_NS */ 763#endif /* CONFIG_NCPFS_NFS_NS */
753 return ncp_DeleteNSEntry(server, 1, volnum, dirent, name, server->name_space[volnum], cpu_to_le16(0x8006)); 764 return ncp_DeleteNSEntry(server, 1, volnum, dirent, name, name_space, cpu_to_le16(0x8006));
754} 765}
755 766
756static inline void ConvertToNWfromDWORD(__u16 v0, __u16 v1, __u8 ret[6]) 767static inline void ConvertToNWfromDWORD(__u16 v0, __u16 v1, __u8 ret[6])
@@ -765,7 +776,7 @@ static inline void ConvertToNWfromDWORD(__u16 v0, __u16 v1, __u8 ret[6])
765/* If both dir and name are NULL, then in target there's already a 776/* If both dir and name are NULL, then in target there's already a
766 looked-up entry that wants to be opened. */ 777 looked-up entry that wants to be opened. */
767int ncp_open_create_file_or_subdir(struct ncp_server *server, 778int ncp_open_create_file_or_subdir(struct ncp_server *server,
768 struct inode *dir, char *name, 779 struct inode *dir, const char *name,
769 int open_create_mode, 780 int open_create_mode,
770 __le32 create_attributes, 781 __le32 create_attributes,
771 __le16 desired_acc_rights, 782 __le16 desired_acc_rights,
@@ -890,8 +901,8 @@ int ncp_search_for_fileset(struct ncp_server *server,
890 901
891static int 902static int
892ncp_RenameNSEntry(struct ncp_server *server, 903ncp_RenameNSEntry(struct ncp_server *server,
893 struct inode *old_dir, char *old_name, __le16 old_type, 904 struct inode *old_dir, const char *old_name, __le16 old_type,
894 struct inode *new_dir, char *new_name) 905 struct inode *new_dir, const char *new_name)
895{ 906{
896 int result = -EINVAL; 907 int result = -EINVAL;
897 908
@@ -929,8 +940,8 @@ out:
929} 940}
930 941
931int ncp_ren_or_mov_file_or_subdir(struct ncp_server *server, 942int ncp_ren_or_mov_file_or_subdir(struct ncp_server *server,
932 struct inode *old_dir, char *old_name, 943 struct inode *old_dir, const char *old_name,
933 struct inode *new_dir, char *new_name) 944 struct inode *new_dir, const char *new_name)
934{ 945{
935 int result; 946 int result;
936 __le16 old_type = cpu_to_le16(0x06); 947 __le16 old_type = cpu_to_le16(0x06);
@@ -958,7 +969,7 @@ int
958ncp_read_kernel(struct ncp_server *server, const char *file_id, 969ncp_read_kernel(struct ncp_server *server, const char *file_id,
959 __u32 offset, __u16 to_read, char *target, int *bytes_read) 970 __u32 offset, __u16 to_read, char *target, int *bytes_read)
960{ 971{
961 char *source; 972 const char *source;
962 int result; 973 int result;
963 974
964 ncp_init_request(server); 975 ncp_init_request(server);