4 * Copyright (C) 1995, 1996 by Volker Lendecke 5 * Modified for big endian by J.F. Chadima and David S. Miller 6 * Modified 1997 Peter Waltenberg, Bill Hawes, David Woodhouse for 2.1 dcache 10 #include <linux/config.h> 11 #include <linux/module.h> 13 #include <asm/system.h> 14 #include <asm/uaccess.h> 15 #include <asm/byteorder.h> 17 #include <linux/sched.h> 18 #include <linux/kernel.h> 20 #include <linux/string.h> 21 #include <linux/stat.h> 22 #include <linux/errno.h> 23 #include <linux/locks.h> 24 #include <linux/file.h> 25 #include <linux/fcntl.h> 26 #include <linux/malloc.h> 27 #include <linux/init.h> 29 #include <linux/kerneld.h> 32 #include <linux/ncp_fs.h> 33 #include"ncplib_kernel.h" 35 static voidncp_read_inode(struct inode
*); 36 static voidncp_put_inode(struct inode
*); 37 static voidncp_delete_inode(struct inode
*); 38 static voidncp_put_super(struct super_block
*); 39 static intncp_statfs(struct super_block
*,struct statfs
*,int); 41 static struct super_operations ncp_sops
= 43 ncp_read_inode
,/* read inode */ 44 NULL
,/* write inode */ 45 ncp_put_inode
,/* put inode */ 46 ncp_delete_inode
,/* delete inode */ 47 ncp_notify_change
,/* notify change */ 48 ncp_put_super
,/* put superblock */ 49 NULL
,/* write superblock */ 50 ncp_statfs
,/* stat filesystem */ 54 externstruct dentry_operations ncp_dentry_operations
; 56 static struct nw_file_info
*read_nwinfo
= NULL
; 57 static struct semaphore read_sem
= MUTEX
; 60 * Fill in the ncpfs-specific information in the inode. 62 voidncp_update_inode(struct inode
*inode
,struct nw_file_info
*nwinfo
) 64 NCP_FINFO(inode
)->DosDirNum
= nwinfo
->i
.DosDirNum
; 65 NCP_FINFO(inode
)->dirEntNum
= nwinfo
->i
.dirEntNum
; 66 NCP_FINFO(inode
)->volNumber
= nwinfo
->i
.volNumber
; 68 NCP_FINFO(inode
)->opened
= nwinfo
->opened
; 69 NCP_FINFO(inode
)->access
= nwinfo
->access
; 70 NCP_FINFO(inode
)->server_file_handle
= nwinfo
->server_file_handle
; 71 memcpy(NCP_FINFO(inode
)->file_handle
, nwinfo
->file_handle
, 72 sizeof(nwinfo
->file_handle
)); 73 #ifdef NCPFS_DEBUG_VERBOSE 74 printk(KERN_DEBUG
"ncp_update_inode: updated %s, volnum=%d, dirent=%u\n", 75 nwinfo
->i
.entryName
,NCP_FINFO(inode
)->volNumber
,NCP_FINFO(inode
)->dirEntNum
); 79 voidncp_update_inode2(struct inode
* inode
,struct nw_file_info
*nwinfo
) 81 struct nw_info_struct
*nwi
= &nwinfo
->i
; 82 struct ncp_server
*server
=NCP_SERVER(inode
); 84 if(!NCP_FINFO(inode
)->opened
) { 85 if(nwi
->attributes
& aDIR
) { 86 inode
->i_mode
= server
->m
.dir_mode
; 89 inode
->i_mode
= server
->m
.file_mode
; 90 inode
->i_size
=le32_to_cpu(nwi
->dataStreamSize
); 92 if(nwi
->attributes
& aRONLY
) inode
->i_mode
&= ~0222; 95 if((inode
->i_size
)&&(inode
->i_blksize
)) { 96 inode
->i_blocks
= (inode
->i_size
-1)/(inode
->i_blksize
)+1; 98 /* TODO: times? I'm not sure... */ 99 NCP_FINFO(inode
)->DosDirNum
= nwinfo
->i
.DosDirNum
; 100 NCP_FINFO(inode
)->dirEntNum
= nwinfo
->i
.dirEntNum
; 101 NCP_FINFO(inode
)->volNumber
= nwinfo
->i
.volNumber
; 105 * Fill in the inode based on the nw_file_info structure. 107 static voidncp_set_attr(struct inode
*inode
,struct nw_file_info
*nwinfo
) 109 struct nw_info_struct
*nwi
= &nwinfo
->i
; 110 struct ncp_server
*server
=NCP_SERVER(inode
); 112 if(nwi
->attributes
& aDIR
) { 113 inode
->i_mode
= server
->m
.dir_mode
; 114 /* for directories dataStreamSize seems to be some 118 inode
->i_mode
= server
->m
.file_mode
; 119 inode
->i_size
=le32_to_cpu(nwi
->dataStreamSize
); 121 if(nwi
->attributes
& aRONLY
) inode
->i_mode
&= ~0222; 123 DDPRINTK(KERN_DEBUG
"ncp_read_inode: inode->i_mode = %u\n", inode
->i_mode
); 126 inode
->i_uid
= server
->m
.uid
; 127 inode
->i_gid
= server
->m
.gid
; 128 inode
->i_blksize
=512; 132 if((inode
->i_blksize
!=0) && (inode
->i_size
!=0)) { 134 (inode
->i_size
-1) / inode
->i_blksize
+1; 137 inode
->i_mtime
=ncp_date_dos2unix(le16_to_cpu(nwi
->modifyTime
), 138 le16_to_cpu(nwi
->modifyDate
)); 139 inode
->i_ctime
=ncp_date_dos2unix(le16_to_cpu(nwi
->creationTime
), 140 le16_to_cpu(nwi
->creationDate
)); 141 inode
->i_atime
=ncp_date_dos2unix(0, 142 le16_to_cpu(nwi
->lastAccessDate
)); 143 ncp_update_inode(inode
, nwinfo
); 147 * This is called from iget() with the read semaphore held. 148 * The global ncpfs_file_info structure has been set up by ncp_iget. 150 static voidncp_read_inode(struct inode
*inode
) 152 if(read_nwinfo
== NULL
) { 153 printk(KERN_ERR
"ncp_read_inode: invalid call\n"); 157 ncp_set_attr(inode
, read_nwinfo
); 159 if(S_ISREG(inode
->i_mode
)) { 160 inode
->i_op
= &ncp_file_inode_operations
; 161 }else if(S_ISDIR(inode
->i_mode
)) { 162 inode
->i_op
= &ncp_dir_inode_operations
; 169 * Set up the ncpfs_inode_info pointer and get a new inode. 172 ncp_iget(struct super_block
*sb
,struct ncpfs_inode_info
*info
) 177 printk(KERN_ERR
"ncp_iget: info is NULL\n"); 182 read_nwinfo
= &info
->nw_info
; 183 inode
=iget(sb
, info
->ino
); 187 printk(KERN_ERR
"ncp_iget: iget failed!\n"); 191 static voidncp_put_inode(struct inode
*inode
) 193 if(inode
->i_count
==1) 198 ncp_delete_inode(struct inode
*inode
) 200 if(S_ISDIR(inode
->i_mode
)) { 201 DDPRINTK(KERN_DEBUG
"ncp_delete_inode: put directory %ld\n", inode
->i_ino
); 202 ncp_invalid_dir_cache(inode
); 205 if(NCP_FINFO(inode
)->opened
&&ncp_make_closed(inode
) !=0) { 206 /* We can't do anything but complain. */ 207 printk(KERN_ERR
"ncp_delete_inode: could not close\n"); 212 static voidncp_init_root(struct ncp_server
*server
, 213 struct ncpfs_inode_info
*info
) 215 struct ncp_inode_info
*root
= &(server
->root
); 216 struct nw_info_struct
*i
= &(root
->finfo
.i
); 217 unsigned short dummy
; 219 DPRINTK(KERN_DEBUG
"ncp_init_root: i = %x\n", (int) i
); 221 i
->attributes
= aDIR
; 222 i
->dataStreamSize
=1024; 225 i
->volNumber
= NCP_NUMBER_OF_VOLUMES
+1;/* illegal volnum */ 226 ncp_date_unix2dos(0, &(i
->creationTime
), &(i
->creationDate
)); 227 ncp_date_unix2dos(0, &(i
->modifyTime
), &(i
->modifyDate
)); 228 ncp_date_unix2dos(0, &(dummy
), &(i
->lastAccessDate
)); 229 i
->creationTime
=le16_to_cpu(i
->creationTime
); 230 i
->creationDate
=le16_to_cpu(i
->creationDate
); 231 i
->modifyTime
=le16_to_cpu(i
->modifyTime
); 232 i
->modifyDate
=le16_to_cpu(i
->modifyDate
); 233 i
->lastAccessDate
=le16_to_cpu(i
->lastAccessDate
); 235 i
->entryName
[0] ='\0'; 237 root
->finfo
.opened
=0; 238 info
->ino
=2;/* tradition */ 239 info
->nw_info
= root
->finfo
; 244 ncp_read_super(struct super_block
*sb
,void*raw_data
,int silent
) 246 struct ncp_mount_data
*data
= (struct ncp_mount_data
*) raw_data
; 247 struct ncp_server
*server
; 248 struct file
*ncp_filp
; 249 struct inode
*root_inode
; 250 kdev_t dev
= sb
->s_dev
; 252 #ifdef CONFIG_NCPFS_PACKET_SIGNING 255 struct ncpfs_inode_info finfo
; 260 if(data
->version
!= NCP_MOUNT_VERSION
) 262 ncp_filp
=fget(data
->ncp_fd
); 265 if(!S_ISSOCK(ncp_filp
->f_dentry
->d_inode
->i_mode
)) 270 sb
->s_blocksize
=1024;/* Eh... Is this correct? */ 271 sb
->s_blocksize_bits
=10; 272 sb
->s_magic
= NCP_SUPER_MAGIC
; 274 sb
->s_op
= &ncp_sops
; 276 /* We must malloc our own super-block info */ 277 server
= (struct ncp_server
*)ncp_kmalloc(sizeof(struct ncp_server
), 281 NCP_SBP(sb
) = server
; 283 server
->ncp_filp
= ncp_filp
; 286 server
->packet
= NULL
; 287 server
->buffer_size
=0; 288 server
->conn_status
=0; 289 server
->root_dentry
= NULL
; 290 #ifdef CONFIG_NCPFS_PACKET_SIGNING 291 server
->sign_wanted
=0; 292 server
->sign_active
=0; 294 server
->auth
.auth_type
= NCP_AUTH_NONE
; 295 server
->auth
.object_name_len
=0; 296 server
->auth
.object_name
= NULL
; 297 server
->auth
.object_type
=0; 299 server
->priv
.data
= NULL
; 302 /* Althought anything producing this is buggy, it happens 303 now because of PATH_MAX changes.. */ 304 if(server
->m
.time_out
<10) { 305 server
->m
.time_out
=10; 306 printk(KERN_INFO
"You need to recompile your ncpfs utils..\n"); 308 server
->m
.file_mode
= (server
->m
.file_mode
& 309 (S_IRWXU
| S_IRWXG
| S_IRWXO
)) | S_IFREG
; 310 server
->m
.dir_mode
= (server
->m
.dir_mode
& 311 (S_IRWXU
| S_IRWXG
| S_IRWXO
)) | S_IFDIR
; 313 server
->packet_size
= NCP_PACKET_SIZE
; 314 server
->packet
=ncp_kmalloc(NCP_PACKET_SIZE
, GFP_KERNEL
); 315 if(server
->packet
== NULL
) 318 ncp_lock_server(server
); 319 error
=ncp_connect(server
); 320 ncp_unlock_server(server
); 323 DPRINTK(KERN_DEBUG
"ncp_read_super: NCP_SBP(sb) = %x\n", (int)NCP_SBP(sb
)); 325 #ifdef CONFIG_NCPFS_PACKET_SIGNING 326 if(ncp_negotiate_size_and_options(server
, NCP_DEFAULT_BUFSIZE
, 327 NCP_DEFAULT_OPTIONS
, &(server
->buffer_size
), &options
) ==0) 329 if(options
!= NCP_DEFAULT_OPTIONS
) 331 if(ncp_negotiate_size_and_options(server
, 334 &(server
->buffer_size
), &options
) !=0) 341 server
->sign_wanted
=1; 344 #endif/* CONFIG_NCPFS_PACKET_SIGNING */ 345 if(ncp_negotiate_buffersize(server
, NCP_DEFAULT_BUFSIZE
, 346 &(server
->buffer_size
)) !=0) 348 DPRINTK(KERN_DEBUG
"ncpfs: bufsize = %d\n", server
->buffer_size
); 350 ncp_init_root(server
, &finfo
); 351 server
->name_space
[finfo
.nw_info
.i
.volNumber
] = NW_NS_DOS
; 352 root_inode
=ncp_iget(sb
, &finfo
); 355 DPRINTK(KERN_DEBUG
"ncp_read_super: root vol=%d\n",NCP_FINFO(root_inode
)->volNumber
); 356 server
->root_dentry
= sb
->s_root
=d_alloc_root(root_inode
, NULL
); 359 server
->root_dentry
->d_op
= &ncp_dentry_operations
; 364 printk(KERN_ERR
"ncp_read_super: get root inode failed\n"); 368 printk(KERN_ERR
"ncp_read_super: could not get bufsize\n"); 370 ncp_lock_server(server
); 371 ncp_disconnect(server
); 372 ncp_unlock_server(server
); 373 goto out_free_packet
; 375 printk(KERN_ERR
"ncp_read_super: Failed connection, error=%d\n", error
); 377 ncp_kfree_s(server
->packet
, server
->packet_size
); 378 goto out_free_server
; 380 printk(KERN_ERR
"ncp_read_super: could not alloc packet\n"); 382 ncp_kfree_s(NCP_SBP(sb
),sizeof(struct ncp_server
)); 385 printk(KERN_ERR
"ncp_read_super: could not alloc ncp_server\n"); 394 printk(KERN_ERR
"ncp_read_super: invalid ncp socket\n"); 397 printk(KERN_INFO
"ncp_read_super: kernel requires mount version %d\n", 401 printk(KERN_ERR
"ncp_read_super: missing data argument\n"); 408 static voidncp_put_super(struct super_block
*sb
) 410 struct ncp_server
*server
=NCP_SBP(sb
); 414 ncp_lock_server(server
); 415 ncp_disconnect(server
); 416 ncp_unlock_server(server
); 418 fput(server
->ncp_filp
); 419 kill_proc(server
->m
.wdog_pid
, SIGTERM
,1); 421 if(server
->priv
.data
) 422 ncp_kfree_s(server
->priv
.data
, server
->priv
.len
); 423 if(server
->auth
.object_name
) 424 ncp_kfree_s(server
->auth
.object_name
, server
->auth
.object_name_len
); 425 ncp_kfree_s(server
->packet
, server
->packet_size
); 427 ncp_kfree_s(NCP_SBP(sb
),sizeof(struct ncp_server
)); 435 static intncp_statfs(struct super_block
*sb
,struct statfs
*buf
,int bufsiz
) 439 /* We cannot say how much disk space is left on a mounted 440 NetWare Server, because free space is distributed over 441 volumes, and the current user might have disk quotas. So 442 free space is not that simple to determine. Our decision 443 here is to err conservatively. */ 445 tmp
.f_type
= NCP_SUPER_MAGIC
; 453 returncopy_to_user(buf
, &tmp
, bufsiz
) ? -EFAULT
:0; 456 intncp_notify_change(struct dentry
*dentry
,struct iattr
*attr
) 458 struct inode
*inode
= dentry
->d_inode
; 461 struct nw_modify_dos_info info
; 464 if(!ncp_conn_valid(NCP_SERVER(inode
))) 467 result
=inode_change_ok(inode
, attr
); 472 if(((attr
->ia_valid
& ATTR_UID
) && 473 (attr
->ia_uid
!=NCP_SERVER(inode
)->m
.uid
))) 476 if(((attr
->ia_valid
& ATTR_GID
) && 477 (attr
->ia_uid
!=NCP_SERVER(inode
)->m
.gid
))) 480 if(((attr
->ia_valid
& ATTR_MODE
) && 482 ~(S_IFREG
| S_IFDIR
| S_IRWXU
| S_IRWXG
| S_IRWXO
)))) 486 memset(&info
,0,sizeof(info
)); 489 if((attr
->ia_valid
& ATTR_MODE
) !=0) 491 if(!S_ISREG(inode
->i_mode
)) 499 info_mask
|= DM_ATTRIBUTES
; 500 newmode
=attr
->ia_mode
; 501 newmode
&=NCP_SERVER(inode
)->m
.file_mode
; 503 if(newmode
&0222)/* any write bit set */ 505 info
.attributes
&= ~0x60001; 509 info
.attributes
|=0x60001; 515 if((attr
->ia_valid
& ATTR_CTIME
) !=0) { 516 info_mask
|= (DM_CREATE_TIME
| DM_CREATE_DATE
); 517 ncp_date_unix2dos(attr
->ia_ctime
, 518 &(info
.creationTime
), &(info
.creationDate
)); 519 info
.creationTime
=le16_to_cpu(info
.creationTime
); 520 info
.creationDate
=le16_to_cpu(info
.creationDate
); 522 if((attr
->ia_valid
& ATTR_MTIME
) !=0) { 523 info_mask
|= (DM_MODIFY_TIME
| DM_MODIFY_DATE
); 524 ncp_date_unix2dos(attr
->ia_mtime
, 525 &(info
.modifyTime
), &(info
.modifyDate
)); 526 info
.modifyTime
=le16_to_cpu(info
.modifyTime
); 527 info
.modifyDate
=le16_to_cpu(info
.modifyDate
); 529 if((attr
->ia_valid
& ATTR_ATIME
) !=0) { 531 info_mask
|= (DM_LAST_ACCESS_DATE
); 532 ncp_date_unix2dos(attr
->ia_ctime
, 533 &(dummy
), &(info
.lastAccessDate
)); 534 info
.lastAccessDate
=le16_to_cpu(info
.lastAccessDate
); 537 result
=ncp_modify_file_or_subdir_dos_info(NCP_SERVER(inode
), 538 inode
, info_mask
, &info
); 542 if(info_mask
== (DM_CREATE_TIME
| DM_CREATE_DATE
)) { 543 /* NetWare seems not to allow this. I 544 do not know why. So, just tell the 545 user everything went fine. This is 546 a terrible hack, but I do not know 547 how to do this correctly. */ 552 if((attr
->ia_valid
& ATTR_SIZE
) !=0) { 555 DPRINTK(KERN_DEBUG
"ncpfs: trying to change size to %ld\n", 558 if((result
=ncp_make_open(inode
, O_RDWR
)) <0) { 561 ncp_write(NCP_SERVER(inode
),NCP_FINFO(inode
)->file_handle
, 562 attr
->ia_size
,0,"", &written
); 564 /* According to ndir, the changes only take effect after 566 result
=ncp_make_closed(inode
); 568 ncp_invalid_dir_cache(dentry
->d_parent
->d_inode
); 573 #ifdef DEBUG_NCP_MALLOC 575 int ncp_current_malloced
; 578 static struct file_system_type ncp_fs_type
= { 580 0/* FS_NO_DCACHE doesn't work correctly */, 585 __initfunc(intinit_ncp_fs(void)) 587 returnregister_filesystem(&ncp_fs_type
); 595 DPRINTK(KERN_DEBUG
"ncpfs: init_module called\n"); 600 #ifdef DEBUG_NCP_MALLOC 602 ncp_current_malloced
=0; 604 ncp_init_dir_cache(); 609 voidcleanup_module(void) 611 DPRINTK(KERN_DEBUG
"ncpfs: cleanup_module called\n"); 612 ncp_free_dir_cache(); 613 unregister_filesystem(&ncp_fs_type
); 614 #ifdef DEBUG_NCP_MALLOC 615 printk(KERN_DEBUG
"ncp_malloced: %d\n", ncp_malloced
); 616 printk(KERN_DEBUG
"ncp_current_malloced: %d\n", ncp_current_malloced
);