at v4.10 1071 lines 28 kB view raw
1/* 2 * inode.c 3 * 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 7 * Modified 1998 Wolfram Pienkoss for NLS 8 * Modified 2000 Ben Harris, University of Cambridge for NFS NS meta-info 9 * 10 */ 11 12#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 13 14#include <linux/module.h> 15 16#include <linux/uaccess.h> 17#include <asm/byteorder.h> 18 19#include <linux/time.h> 20#include <linux/kernel.h> 21#include <linux/mm.h> 22#include <linux/string.h> 23#include <linux/stat.h> 24#include <linux/errno.h> 25#include <linux/file.h> 26#include <linux/fcntl.h> 27#include <linux/slab.h> 28#include <linux/vmalloc.h> 29#include <linux/init.h> 30#include <linux/vfs.h> 31#include <linux/mount.h> 32#include <linux/seq_file.h> 33#include <linux/namei.h> 34 35#include <net/sock.h> 36 37#include "ncp_fs.h" 38#include "getopt.h" 39 40#define NCP_DEFAULT_FILE_MODE 0600 41#define NCP_DEFAULT_DIR_MODE 0700 42#define NCP_DEFAULT_TIME_OUT 10 43#define NCP_DEFAULT_RETRY_COUNT 20 44 45static void ncp_evict_inode(struct inode *); 46static void ncp_put_super(struct super_block *); 47static int ncp_statfs(struct dentry *, struct kstatfs *); 48static int ncp_show_options(struct seq_file *, struct dentry *); 49 50static struct kmem_cache * ncp_inode_cachep; 51 52static struct inode *ncp_alloc_inode(struct super_block *sb) 53{ 54 struct ncp_inode_info *ei; 55 ei = (struct ncp_inode_info *)kmem_cache_alloc(ncp_inode_cachep, GFP_KERNEL); 56 if (!ei) 57 return NULL; 58 return &ei->vfs_inode; 59} 60 61static void ncp_i_callback(struct rcu_head *head) 62{ 63 struct inode *inode = container_of(head, struct inode, i_rcu); 64 kmem_cache_free(ncp_inode_cachep, NCP_FINFO(inode)); 65} 66 67static void ncp_destroy_inode(struct inode *inode) 68{ 69 call_rcu(&inode->i_rcu, ncp_i_callback); 70} 71 72static void init_once(void *foo) 73{ 74 struct ncp_inode_info *ei = (struct ncp_inode_info *) foo; 75 76 mutex_init(&ei->open_mutex); 77 inode_init_once(&ei->vfs_inode); 78} 79 80static int init_inodecache(void) 81{ 82 ncp_inode_cachep = kmem_cache_create("ncp_inode_cache", 83 sizeof(struct ncp_inode_info), 84 0, (SLAB_RECLAIM_ACCOUNT| 85 SLAB_MEM_SPREAD|SLAB_ACCOUNT), 86 init_once); 87 if (ncp_inode_cachep == NULL) 88 return -ENOMEM; 89 return 0; 90} 91 92static void destroy_inodecache(void) 93{ 94 /* 95 * Make sure all delayed rcu free inodes are flushed before we 96 * destroy cache. 97 */ 98 rcu_barrier(); 99 kmem_cache_destroy(ncp_inode_cachep); 100} 101 102static int ncp_remount(struct super_block *sb, int *flags, char* data) 103{ 104 sync_filesystem(sb); 105 *flags |= MS_NODIRATIME; 106 return 0; 107} 108 109static const struct super_operations ncp_sops = 110{ 111 .alloc_inode = ncp_alloc_inode, 112 .destroy_inode = ncp_destroy_inode, 113 .drop_inode = generic_delete_inode, 114 .evict_inode = ncp_evict_inode, 115 .put_super = ncp_put_super, 116 .statfs = ncp_statfs, 117 .remount_fs = ncp_remount, 118 .show_options = ncp_show_options, 119}; 120 121/* 122 * Fill in the ncpfs-specific information in the inode. 123 */ 124static void ncp_update_dirent(struct inode *inode, struct ncp_entry_info *nwinfo) 125{ 126 NCP_FINFO(inode)->DosDirNum = nwinfo->i.DosDirNum; 127 NCP_FINFO(inode)->dirEntNum = nwinfo->i.dirEntNum; 128 NCP_FINFO(inode)->volNumber = nwinfo->volume; 129} 130 131void ncp_update_inode(struct inode *inode, struct ncp_entry_info *nwinfo) 132{ 133 ncp_update_dirent(inode, nwinfo); 134 NCP_FINFO(inode)->nwattr = nwinfo->i.attributes; 135 NCP_FINFO(inode)->access = nwinfo->access; 136 memcpy(NCP_FINFO(inode)->file_handle, nwinfo->file_handle, 137 sizeof(nwinfo->file_handle)); 138 ncp_dbg(1, "updated %s, volnum=%d, dirent=%u\n", 139 nwinfo->i.entryName, NCP_FINFO(inode)->volNumber, 140 NCP_FINFO(inode)->dirEntNum); 141} 142 143static void ncp_update_dates(struct inode *inode, struct nw_info_struct *nwi) 144{ 145 /* NFS namespace mode overrides others if it's set. */ 146 ncp_dbg(1, "(%s) nfs.mode=0%o\n", nwi->entryName, nwi->nfs.mode); 147 if (nwi->nfs.mode) { 148 /* XXX Security? */ 149 inode->i_mode = nwi->nfs.mode; 150 } 151 152 inode->i_blocks = (i_size_read(inode) + NCP_BLOCK_SIZE - 1) >> NCP_BLOCK_SHIFT; 153 154 inode->i_mtime.tv_sec = ncp_date_dos2unix(nwi->modifyTime, nwi->modifyDate); 155 inode->i_ctime.tv_sec = ncp_date_dos2unix(nwi->creationTime, nwi->creationDate); 156 inode->i_atime.tv_sec = ncp_date_dos2unix(0, nwi->lastAccessDate); 157 inode->i_atime.tv_nsec = 0; 158 inode->i_mtime.tv_nsec = 0; 159 inode->i_ctime.tv_nsec = 0; 160} 161 162static void ncp_update_attrs(struct inode *inode, struct ncp_entry_info *nwinfo) 163{ 164 struct nw_info_struct *nwi = &nwinfo->i; 165 struct ncp_server *server = NCP_SERVER(inode); 166 167 if (nwi->attributes & aDIR) { 168 inode->i_mode = server->m.dir_mode; 169 /* for directories dataStreamSize seems to be some 170 Object ID ??? */ 171 i_size_write(inode, NCP_BLOCK_SIZE); 172 } else { 173 u32 size; 174 175 inode->i_mode = server->m.file_mode; 176 size = le32_to_cpu(nwi->dataStreamSize); 177 i_size_write(inode, size); 178#ifdef CONFIG_NCPFS_EXTRAS 179 if ((server->m.flags & (NCP_MOUNT_EXTRAS|NCP_MOUNT_SYMLINKS)) 180 && (nwi->attributes & aSHARED)) { 181 switch (nwi->attributes & (aHIDDEN|aSYSTEM)) { 182 case aHIDDEN: 183 if (server->m.flags & NCP_MOUNT_SYMLINKS) { 184 if (/* (size >= NCP_MIN_SYMLINK_SIZE) 185 && */ (size <= NCP_MAX_SYMLINK_SIZE)) { 186 inode->i_mode = (inode->i_mode & ~S_IFMT) | S_IFLNK; 187 NCP_FINFO(inode)->flags |= NCPI_KLUDGE_SYMLINK; 188 break; 189 } 190 } 191 /* FALLTHROUGH */ 192 case 0: 193 if (server->m.flags & NCP_MOUNT_EXTRAS) 194 inode->i_mode |= S_IRUGO; 195 break; 196 case aSYSTEM: 197 if (server->m.flags & NCP_MOUNT_EXTRAS) 198 inode->i_mode |= (inode->i_mode >> 2) & S_IXUGO; 199 break; 200 /* case aSYSTEM|aHIDDEN: */ 201 default: 202 /* reserved combination */ 203 break; 204 } 205 } 206#endif 207 } 208 if (nwi->attributes & aRONLY) inode->i_mode &= ~S_IWUGO; 209} 210 211void ncp_update_inode2(struct inode* inode, struct ncp_entry_info *nwinfo) 212{ 213 NCP_FINFO(inode)->flags = 0; 214 if (!atomic_read(&NCP_FINFO(inode)->opened)) { 215 NCP_FINFO(inode)->nwattr = nwinfo->i.attributes; 216 ncp_update_attrs(inode, nwinfo); 217 } 218 219 ncp_update_dates(inode, &nwinfo->i); 220 ncp_update_dirent(inode, nwinfo); 221} 222 223/* 224 * Fill in the inode based on the ncp_entry_info structure. Used only for brand new inodes. 225 */ 226static void ncp_set_attr(struct inode *inode, struct ncp_entry_info *nwinfo) 227{ 228 struct ncp_server *server = NCP_SERVER(inode); 229 230 NCP_FINFO(inode)->flags = 0; 231 232 ncp_update_attrs(inode, nwinfo); 233 234 ncp_dbg(2, "inode->i_mode = %u\n", inode->i_mode); 235 236 set_nlink(inode, 1); 237 inode->i_uid = server->m.uid; 238 inode->i_gid = server->m.gid; 239 240 ncp_update_dates(inode, &nwinfo->i); 241 ncp_update_inode(inode, nwinfo); 242} 243 244#if defined(CONFIG_NCPFS_EXTRAS) || defined(CONFIG_NCPFS_NFS_NS) 245static const struct inode_operations ncp_symlink_inode_operations = { 246 .get_link = page_get_link, 247 .setattr = ncp_notify_change, 248}; 249#endif 250 251/* 252 * Get a new inode. 253 */ 254struct inode * 255ncp_iget(struct super_block *sb, struct ncp_entry_info *info) 256{ 257 struct inode *inode; 258 259 if (info == NULL) { 260 pr_err("%s: info is NULL\n", __func__); 261 return NULL; 262 } 263 264 inode = new_inode(sb); 265 if (inode) { 266 atomic_set(&NCP_FINFO(inode)->opened, info->opened); 267 268 inode->i_ino = info->ino; 269 ncp_set_attr(inode, info); 270 if (S_ISREG(inode->i_mode)) { 271 inode->i_op = &ncp_file_inode_operations; 272 inode->i_fop = &ncp_file_operations; 273 } else if (S_ISDIR(inode->i_mode)) { 274 inode->i_op = &ncp_dir_inode_operations; 275 inode->i_fop = &ncp_dir_operations; 276#ifdef CONFIG_NCPFS_NFS_NS 277 } else if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode) || S_ISFIFO(inode->i_mode) || S_ISSOCK(inode->i_mode)) { 278 init_special_inode(inode, inode->i_mode, 279 new_decode_dev(info->i.nfs.rdev)); 280#endif 281#if defined(CONFIG_NCPFS_EXTRAS) || defined(CONFIG_NCPFS_NFS_NS) 282 } else if (S_ISLNK(inode->i_mode)) { 283 inode->i_op = &ncp_symlink_inode_operations; 284 inode_nohighmem(inode); 285 inode->i_data.a_ops = &ncp_symlink_aops; 286#endif 287 } else { 288 make_bad_inode(inode); 289 } 290 insert_inode_hash(inode); 291 } else 292 pr_err("%s: iget failed!\n", __func__); 293 return inode; 294} 295 296static void 297ncp_evict_inode(struct inode *inode) 298{ 299 truncate_inode_pages_final(&inode->i_data); 300 clear_inode(inode); 301 302 if (S_ISDIR(inode->i_mode)) { 303 ncp_dbg(2, "put directory %ld\n", inode->i_ino); 304 } 305 306 if (ncp_make_closed(inode) != 0) { 307 /* We can't do anything but complain. */ 308 pr_err("%s: could not close\n", __func__); 309 } 310} 311 312static void ncp_stop_tasks(struct ncp_server *server) { 313 struct sock* sk = server->ncp_sock->sk; 314 315 lock_sock(sk); 316 sk->sk_error_report = server->error_report; 317 sk->sk_data_ready = server->data_ready; 318 sk->sk_write_space = server->write_space; 319 release_sock(sk); 320 del_timer_sync(&server->timeout_tm); 321 322 flush_work(&server->rcv.tq); 323 if (sk->sk_socket->type == SOCK_STREAM) 324 flush_work(&server->tx.tq); 325 else 326 flush_work(&server->timeout_tq); 327} 328 329static int ncp_show_options(struct seq_file *seq, struct dentry *root) 330{ 331 struct ncp_server *server = NCP_SBP(root->d_sb); 332 unsigned int tmp; 333 334 if (!uid_eq(server->m.uid, GLOBAL_ROOT_UID)) 335 seq_printf(seq, ",uid=%u", 336 from_kuid_munged(&init_user_ns, server->m.uid)); 337 if (!gid_eq(server->m.gid, GLOBAL_ROOT_GID)) 338 seq_printf(seq, ",gid=%u", 339 from_kgid_munged(&init_user_ns, server->m.gid)); 340 if (!uid_eq(server->m.mounted_uid, GLOBAL_ROOT_UID)) 341 seq_printf(seq, ",owner=%u", 342 from_kuid_munged(&init_user_ns, server->m.mounted_uid)); 343 tmp = server->m.file_mode & S_IALLUGO; 344 if (tmp != NCP_DEFAULT_FILE_MODE) 345 seq_printf(seq, ",mode=0%o", tmp); 346 tmp = server->m.dir_mode & S_IALLUGO; 347 if (tmp != NCP_DEFAULT_DIR_MODE) 348 seq_printf(seq, ",dirmode=0%o", tmp); 349 if (server->m.time_out != NCP_DEFAULT_TIME_OUT * HZ / 100) { 350 tmp = server->m.time_out * 100 / HZ; 351 seq_printf(seq, ",timeout=%u", tmp); 352 } 353 if (server->m.retry_count != NCP_DEFAULT_RETRY_COUNT) 354 seq_printf(seq, ",retry=%u", server->m.retry_count); 355 if (server->m.flags != 0) 356 seq_printf(seq, ",flags=%lu", server->m.flags); 357 if (server->m.wdog_pid != NULL) 358 seq_printf(seq, ",wdogpid=%u", pid_vnr(server->m.wdog_pid)); 359 360 return 0; 361} 362 363static const struct ncp_option ncp_opts[] = { 364 { "uid", OPT_INT, 'u' }, 365 { "gid", OPT_INT, 'g' }, 366 { "owner", OPT_INT, 'o' }, 367 { "mode", OPT_INT, 'm' }, 368 { "dirmode", OPT_INT, 'd' }, 369 { "timeout", OPT_INT, 't' }, 370 { "retry", OPT_INT, 'r' }, 371 { "flags", OPT_INT, 'f' }, 372 { "wdogpid", OPT_INT, 'w' }, 373 { "ncpfd", OPT_INT, 'n' }, 374 { "infofd", OPT_INT, 'i' }, /* v5 */ 375 { "version", OPT_INT, 'v' }, 376 { NULL, 0, 0 } }; 377 378static int ncp_parse_options(struct ncp_mount_data_kernel *data, char *options) { 379 int optval; 380 char *optarg; 381 unsigned long optint; 382 int version = 0; 383 int ret; 384 385 data->flags = 0; 386 data->int_flags = 0; 387 data->mounted_uid = GLOBAL_ROOT_UID; 388 data->wdog_pid = NULL; 389 data->ncp_fd = ~0; 390 data->time_out = NCP_DEFAULT_TIME_OUT; 391 data->retry_count = NCP_DEFAULT_RETRY_COUNT; 392 data->uid = GLOBAL_ROOT_UID; 393 data->gid = GLOBAL_ROOT_GID; 394 data->file_mode = NCP_DEFAULT_FILE_MODE; 395 data->dir_mode = NCP_DEFAULT_DIR_MODE; 396 data->info_fd = -1; 397 data->mounted_vol[0] = 0; 398 399 while ((optval = ncp_getopt("ncpfs", &options, ncp_opts, NULL, &optarg, &optint)) != 0) { 400 ret = optval; 401 if (ret < 0) 402 goto err; 403 switch (optval) { 404 case 'u': 405 data->uid = make_kuid(current_user_ns(), optint); 406 if (!uid_valid(data->uid)) { 407 ret = -EINVAL; 408 goto err; 409 } 410 break; 411 case 'g': 412 data->gid = make_kgid(current_user_ns(), optint); 413 if (!gid_valid(data->gid)) { 414 ret = -EINVAL; 415 goto err; 416 } 417 break; 418 case 'o': 419 data->mounted_uid = make_kuid(current_user_ns(), optint); 420 if (!uid_valid(data->mounted_uid)) { 421 ret = -EINVAL; 422 goto err; 423 } 424 break; 425 case 'm': 426 data->file_mode = optint; 427 break; 428 case 'd': 429 data->dir_mode = optint; 430 break; 431 case 't': 432 data->time_out = optint; 433 break; 434 case 'r': 435 data->retry_count = optint; 436 break; 437 case 'f': 438 data->flags = optint; 439 break; 440 case 'w': 441 data->wdog_pid = find_get_pid(optint); 442 break; 443 case 'n': 444 data->ncp_fd = optint; 445 break; 446 case 'i': 447 data->info_fd = optint; 448 break; 449 case 'v': 450 ret = -ECHRNG; 451 if (optint < NCP_MOUNT_VERSION_V4) 452 goto err; 453 if (optint > NCP_MOUNT_VERSION_V5) 454 goto err; 455 version = optint; 456 break; 457 458 } 459 } 460 return 0; 461err: 462 put_pid(data->wdog_pid); 463 data->wdog_pid = NULL; 464 return ret; 465} 466 467static int ncp_fill_super(struct super_block *sb, void *raw_data, int silent) 468{ 469 struct ncp_mount_data_kernel data; 470 struct ncp_server *server; 471 struct inode *root_inode; 472 struct socket *sock; 473 int error; 474 int default_bufsize; 475#ifdef CONFIG_NCPFS_PACKET_SIGNING 476 int options; 477#endif 478 struct ncp_entry_info finfo; 479 480 memset(&data, 0, sizeof(data)); 481 server = kzalloc(sizeof(struct ncp_server), GFP_KERNEL); 482 if (!server) 483 return -ENOMEM; 484 sb->s_fs_info = server; 485 486 error = -EFAULT; 487 if (raw_data == NULL) 488 goto out; 489 switch (*(int*)raw_data) { 490 case NCP_MOUNT_VERSION: 491 { 492 struct ncp_mount_data* md = (struct ncp_mount_data*)raw_data; 493 494 data.flags = md->flags; 495 data.int_flags = NCP_IMOUNT_LOGGEDIN_POSSIBLE; 496 data.mounted_uid = make_kuid(current_user_ns(), md->mounted_uid); 497 data.wdog_pid = find_get_pid(md->wdog_pid); 498 data.ncp_fd = md->ncp_fd; 499 data.time_out = md->time_out; 500 data.retry_count = md->retry_count; 501 data.uid = make_kuid(current_user_ns(), md->uid); 502 data.gid = make_kgid(current_user_ns(), md->gid); 503 data.file_mode = md->file_mode; 504 data.dir_mode = md->dir_mode; 505 data.info_fd = -1; 506 memcpy(data.mounted_vol, md->mounted_vol, 507 NCP_VOLNAME_LEN+1); 508 } 509 break; 510 case NCP_MOUNT_VERSION_V4: 511 { 512 struct ncp_mount_data_v4* md = (struct ncp_mount_data_v4*)raw_data; 513 514 data.flags = md->flags; 515 data.mounted_uid = make_kuid(current_user_ns(), md->mounted_uid); 516 data.wdog_pid = find_get_pid(md->wdog_pid); 517 data.ncp_fd = md->ncp_fd; 518 data.time_out = md->time_out; 519 data.retry_count = md->retry_count; 520 data.uid = make_kuid(current_user_ns(), md->uid); 521 data.gid = make_kgid(current_user_ns(), md->gid); 522 data.file_mode = md->file_mode; 523 data.dir_mode = md->dir_mode; 524 data.info_fd = -1; 525 } 526 break; 527 default: 528 error = -ECHRNG; 529 if (memcmp(raw_data, "vers", 4) == 0) { 530 error = ncp_parse_options(&data, raw_data); 531 } 532 if (error) 533 goto out; 534 break; 535 } 536 error = -EINVAL; 537 if (!uid_valid(data.mounted_uid) || !uid_valid(data.uid) || 538 !gid_valid(data.gid)) 539 goto out; 540 sock = sockfd_lookup(data.ncp_fd, &error); 541 if (!sock) 542 goto out; 543 544 if (sock->type == SOCK_STREAM) 545 default_bufsize = 0xF000; 546 else 547 default_bufsize = 1024; 548 549 sb->s_flags |= MS_NODIRATIME; /* probably even noatime */ 550 sb->s_maxbytes = 0xFFFFFFFFU; 551 sb->s_blocksize = 1024; /* Eh... Is this correct? */ 552 sb->s_blocksize_bits = 10; 553 sb->s_magic = NCP_SUPER_MAGIC; 554 sb->s_op = &ncp_sops; 555 sb->s_d_op = &ncp_dentry_operations; 556 sb->s_bdi = &server->bdi; 557 558 server = NCP_SBP(sb); 559 memset(server, 0, sizeof(*server)); 560 561 error = bdi_setup_and_register(&server->bdi, "ncpfs"); 562 if (error) 563 goto out_fput; 564 565 server->ncp_sock = sock; 566 567 if (data.info_fd != -1) { 568 struct socket *info_sock = sockfd_lookup(data.info_fd, &error); 569 if (!info_sock) 570 goto out_bdi; 571 server->info_sock = info_sock; 572 error = -EBADFD; 573 if (info_sock->type != SOCK_STREAM) 574 goto out_fput2; 575 } 576 577/* server->lock = 0; */ 578 mutex_init(&server->mutex); 579 server->packet = NULL; 580/* server->buffer_size = 0; */ 581/* server->conn_status = 0; */ 582/* server->root_dentry = NULL; */ 583/* server->root_setuped = 0; */ 584 mutex_init(&server->root_setup_lock); 585#ifdef CONFIG_NCPFS_PACKET_SIGNING 586/* server->sign_wanted = 0; */ 587/* server->sign_active = 0; */ 588#endif 589 init_rwsem(&server->auth_rwsem); 590 server->auth.auth_type = NCP_AUTH_NONE; 591/* server->auth.object_name_len = 0; */ 592/* server->auth.object_name = NULL; */ 593/* server->auth.object_type = 0; */ 594/* server->priv.len = 0; */ 595/* server->priv.data = NULL; */ 596 597 server->m = data; 598 /* Although anything producing this is buggy, it happens 599 now because of PATH_MAX changes.. */ 600 if (server->m.time_out < 1) { 601 server->m.time_out = 10; 602 pr_info("You need to recompile your ncpfs utils..\n"); 603 } 604 server->m.time_out = server->m.time_out * HZ / 100; 605 server->m.file_mode = (server->m.file_mode & S_IRWXUGO) | S_IFREG; 606 server->m.dir_mode = (server->m.dir_mode & S_IRWXUGO) | S_IFDIR; 607 608#ifdef CONFIG_NCPFS_NLS 609 /* load the default NLS charsets */ 610 server->nls_vol = load_nls_default(); 611 server->nls_io = load_nls_default(); 612#endif /* CONFIG_NCPFS_NLS */ 613 614 atomic_set(&server->dentry_ttl, 0); /* no caching */ 615 616 INIT_LIST_HEAD(&server->tx.requests); 617 mutex_init(&server->rcv.creq_mutex); 618 server->tx.creq = NULL; 619 server->rcv.creq = NULL; 620 621 init_timer(&server->timeout_tm); 622#undef NCP_PACKET_SIZE 623#define NCP_PACKET_SIZE 131072 624 error = -ENOMEM; 625 server->packet_size = NCP_PACKET_SIZE; 626 server->packet = vmalloc(NCP_PACKET_SIZE); 627 if (server->packet == NULL) 628 goto out_nls; 629 server->txbuf = vmalloc(NCP_PACKET_SIZE); 630 if (server->txbuf == NULL) 631 goto out_packet; 632 server->rxbuf = vmalloc(NCP_PACKET_SIZE); 633 if (server->rxbuf == NULL) 634 goto out_txbuf; 635 636 lock_sock(sock->sk); 637 server->data_ready = sock->sk->sk_data_ready; 638 server->write_space = sock->sk->sk_write_space; 639 server->error_report = sock->sk->sk_error_report; 640 sock->sk->sk_user_data = server; 641 sock->sk->sk_data_ready = ncp_tcp_data_ready; 642 sock->sk->sk_error_report = ncp_tcp_error_report; 643 if (sock->type == SOCK_STREAM) { 644 server->rcv.ptr = (unsigned char*)&server->rcv.buf; 645 server->rcv.len = 10; 646 server->rcv.state = 0; 647 INIT_WORK(&server->rcv.tq, ncp_tcp_rcv_proc); 648 INIT_WORK(&server->tx.tq, ncp_tcp_tx_proc); 649 sock->sk->sk_write_space = ncp_tcp_write_space; 650 } else { 651 INIT_WORK(&server->rcv.tq, ncpdgram_rcv_proc); 652 INIT_WORK(&server->timeout_tq, ncpdgram_timeout_proc); 653 server->timeout_tm.data = (unsigned long)server; 654 server->timeout_tm.function = ncpdgram_timeout_call; 655 } 656 release_sock(sock->sk); 657 658 ncp_lock_server(server); 659 error = ncp_connect(server); 660 ncp_unlock_server(server); 661 if (error < 0) 662 goto out_rxbuf; 663 ncp_dbg(1, "NCP_SBP(sb) = %p\n", NCP_SBP(sb)); 664 665 error = -EMSGSIZE; /* -EREMOTESIDEINCOMPATIBLE */ 666#ifdef CONFIG_NCPFS_PACKET_SIGNING 667 if (ncp_negotiate_size_and_options(server, default_bufsize, 668 NCP_DEFAULT_OPTIONS, &(server->buffer_size), &options) == 0) 669 { 670 if (options != NCP_DEFAULT_OPTIONS) 671 { 672 if (ncp_negotiate_size_and_options(server, 673 default_bufsize, 674 options & 2, 675 &(server->buffer_size), &options) != 0) 676 677 { 678 goto out_disconnect; 679 } 680 } 681 ncp_lock_server(server); 682 if (options & 2) 683 server->sign_wanted = 1; 684 ncp_unlock_server(server); 685 } 686 else 687#endif /* CONFIG_NCPFS_PACKET_SIGNING */ 688 if (ncp_negotiate_buffersize(server, default_bufsize, 689 &(server->buffer_size)) != 0) 690 goto out_disconnect; 691 ncp_dbg(1, "bufsize = %d\n", server->buffer_size); 692 693 memset(&finfo, 0, sizeof(finfo)); 694 finfo.i.attributes = aDIR; 695 finfo.i.dataStreamSize = 0; /* ignored */ 696 finfo.i.dirEntNum = 0; 697 finfo.i.DosDirNum = 0; 698#ifdef CONFIG_NCPFS_SMALLDOS 699 finfo.i.NSCreator = NW_NS_DOS; 700#endif 701 finfo.volume = NCP_NUMBER_OF_VOLUMES; 702 /* set dates of mountpoint to Jan 1, 1986; 00:00 */ 703 finfo.i.creationTime = finfo.i.modifyTime 704 = cpu_to_le16(0x0000); 705 finfo.i.creationDate = finfo.i.modifyDate 706 = finfo.i.lastAccessDate 707 = cpu_to_le16(0x0C21); 708 finfo.i.nameLen = 0; 709 finfo.i.entryName[0] = '\0'; 710 711 finfo.opened = 0; 712 finfo.ino = 2; /* tradition */ 713 714 server->name_space[finfo.volume] = NW_NS_DOS; 715 716 error = -ENOMEM; 717 root_inode = ncp_iget(sb, &finfo); 718 if (!root_inode) 719 goto out_disconnect; 720 ncp_dbg(1, "root vol=%d\n", NCP_FINFO(root_inode)->volNumber); 721 sb->s_root = d_make_root(root_inode); 722 if (!sb->s_root) 723 goto out_disconnect; 724 return 0; 725 726out_disconnect: 727 ncp_lock_server(server); 728 ncp_disconnect(server); 729 ncp_unlock_server(server); 730out_rxbuf: 731 ncp_stop_tasks(server); 732 vfree(server->rxbuf); 733out_txbuf: 734 vfree(server->txbuf); 735out_packet: 736 vfree(server->packet); 737out_nls: 738#ifdef CONFIG_NCPFS_NLS 739 unload_nls(server->nls_io); 740 unload_nls(server->nls_vol); 741#endif 742 mutex_destroy(&server->rcv.creq_mutex); 743 mutex_destroy(&server->root_setup_lock); 744 mutex_destroy(&server->mutex); 745out_fput2: 746 if (server->info_sock) 747 sockfd_put(server->info_sock); 748out_bdi: 749 bdi_destroy(&server->bdi); 750out_fput: 751 sockfd_put(sock); 752out: 753 put_pid(data.wdog_pid); 754 sb->s_fs_info = NULL; 755 kfree(server); 756 return error; 757} 758 759static void delayed_free(struct rcu_head *p) 760{ 761 struct ncp_server *server = container_of(p, struct ncp_server, rcu); 762#ifdef CONFIG_NCPFS_NLS 763 /* unload the NLS charsets */ 764 unload_nls(server->nls_vol); 765 unload_nls(server->nls_io); 766#endif /* CONFIG_NCPFS_NLS */ 767 kfree(server); 768} 769 770static void ncp_put_super(struct super_block *sb) 771{ 772 struct ncp_server *server = NCP_SBP(sb); 773 774 ncp_lock_server(server); 775 ncp_disconnect(server); 776 ncp_unlock_server(server); 777 778 ncp_stop_tasks(server); 779 780 mutex_destroy(&server->rcv.creq_mutex); 781 mutex_destroy(&server->root_setup_lock); 782 mutex_destroy(&server->mutex); 783 784 if (server->info_sock) 785 sockfd_put(server->info_sock); 786 sockfd_put(server->ncp_sock); 787 kill_pid(server->m.wdog_pid, SIGTERM, 1); 788 put_pid(server->m.wdog_pid); 789 790 bdi_destroy(&server->bdi); 791 kfree(server->priv.data); 792 kfree(server->auth.object_name); 793 vfree(server->rxbuf); 794 vfree(server->txbuf); 795 vfree(server->packet); 796 call_rcu(&server->rcu, delayed_free); 797} 798 799static int ncp_statfs(struct dentry *dentry, struct kstatfs *buf) 800{ 801 struct dentry* d; 802 struct inode* i; 803 struct ncp_inode_info* ni; 804 struct ncp_server* s; 805 struct ncp_volume_info vi; 806 struct super_block *sb = dentry->d_sb; 807 int err; 808 __u8 dh; 809 810 d = sb->s_root; 811 if (!d) { 812 goto dflt; 813 } 814 i = d_inode(d); 815 if (!i) { 816 goto dflt; 817 } 818 ni = NCP_FINFO(i); 819 if (!ni) { 820 goto dflt; 821 } 822 s = NCP_SBP(sb); 823 if (!s) { 824 goto dflt; 825 } 826 if (!s->m.mounted_vol[0]) { 827 goto dflt; 828 } 829 830 err = ncp_dirhandle_alloc(s, ni->volNumber, ni->DosDirNum, &dh); 831 if (err) { 832 goto dflt; 833 } 834 err = ncp_get_directory_info(s, dh, &vi); 835 ncp_dirhandle_free(s, dh); 836 if (err) { 837 goto dflt; 838 } 839 buf->f_type = NCP_SUPER_MAGIC; 840 buf->f_bsize = vi.sectors_per_block * 512; 841 buf->f_blocks = vi.total_blocks; 842 buf->f_bfree = vi.free_blocks; 843 buf->f_bavail = vi.free_blocks; 844 buf->f_files = vi.total_dir_entries; 845 buf->f_ffree = vi.available_dir_entries; 846 buf->f_namelen = 12; 847 return 0; 848 849 /* We cannot say how much disk space is left on a mounted 850 NetWare Server, because free space is distributed over 851 volumes, and the current user might have disk quotas. So 852 free space is not that simple to determine. Our decision 853 here is to err conservatively. */ 854 855dflt:; 856 buf->f_type = NCP_SUPER_MAGIC; 857 buf->f_bsize = NCP_BLOCK_SIZE; 858 buf->f_blocks = 0; 859 buf->f_bfree = 0; 860 buf->f_bavail = 0; 861 buf->f_namelen = 12; 862 return 0; 863} 864 865int ncp_notify_change(struct dentry *dentry, struct iattr *attr) 866{ 867 struct inode *inode = d_inode(dentry); 868 int result = 0; 869 __le32 info_mask; 870 struct nw_modify_dos_info info; 871 struct ncp_server *server; 872 873 result = -EIO; 874 875 server = NCP_SERVER(inode); 876 if (!server) /* How this could happen? */ 877 goto out; 878 879 result = -EPERM; 880 if (IS_DEADDIR(d_inode(dentry))) 881 goto out; 882 883 /* ageing the dentry to force validation */ 884 ncp_age_dentry(server, dentry); 885 886 result = setattr_prepare(dentry, attr); 887 if (result < 0) 888 goto out; 889 890 result = -EPERM; 891 if ((attr->ia_valid & ATTR_UID) && !uid_eq(attr->ia_uid, server->m.uid)) 892 goto out; 893 894 if ((attr->ia_valid & ATTR_GID) && !gid_eq(attr->ia_gid, server->m.gid)) 895 goto out; 896 897 if (((attr->ia_valid & ATTR_MODE) && 898 (attr->ia_mode & 899 ~(S_IFREG | S_IFDIR | S_IRWXUGO)))) 900 goto out; 901 902 info_mask = 0; 903 memset(&info, 0, sizeof(info)); 904 905#if 1 906 if ((attr->ia_valid & ATTR_MODE) != 0) 907 { 908 umode_t newmode = attr->ia_mode; 909 910 info_mask |= DM_ATTRIBUTES; 911 912 if (S_ISDIR(inode->i_mode)) { 913 newmode &= server->m.dir_mode; 914 } else { 915#ifdef CONFIG_NCPFS_EXTRAS 916 if (server->m.flags & NCP_MOUNT_EXTRAS) { 917 /* any non-default execute bit set */ 918 if (newmode & ~server->m.file_mode & S_IXUGO) 919 info.attributes |= aSHARED | aSYSTEM; 920 /* read for group/world and not in default file_mode */ 921 else if (newmode & ~server->m.file_mode & S_IRUGO) 922 info.attributes |= aSHARED; 923 } else 924#endif 925 newmode &= server->m.file_mode; 926 } 927 if (newmode & S_IWUGO) 928 info.attributes &= ~(aRONLY|aRENAMEINHIBIT|aDELETEINHIBIT); 929 else 930 info.attributes |= (aRONLY|aRENAMEINHIBIT|aDELETEINHIBIT); 931 932#ifdef CONFIG_NCPFS_NFS_NS 933 if (ncp_is_nfs_extras(server, NCP_FINFO(inode)->volNumber)) { 934 result = ncp_modify_nfs_info(server, 935 NCP_FINFO(inode)->volNumber, 936 NCP_FINFO(inode)->dirEntNum, 937 attr->ia_mode, 0); 938 if (result != 0) 939 goto out; 940 info.attributes &= ~(aSHARED | aSYSTEM); 941 { 942 /* mark partial success */ 943 struct iattr tmpattr; 944 945 tmpattr.ia_valid = ATTR_MODE; 946 tmpattr.ia_mode = attr->ia_mode; 947 948 setattr_copy(inode, &tmpattr); 949 mark_inode_dirty(inode); 950 } 951 } 952#endif 953 } 954#endif 955 956 /* Do SIZE before attributes, otherwise mtime together with size does not work... 957 */ 958 if ((attr->ia_valid & ATTR_SIZE) != 0) { 959 int written; 960 961 ncp_dbg(1, "trying to change size to %llu\n", attr->ia_size); 962 963 if ((result = ncp_make_open(inode, O_WRONLY)) < 0) { 964 result = -EACCES; 965 goto out; 966 } 967 ncp_write_kernel(NCP_SERVER(inode), NCP_FINFO(inode)->file_handle, 968 attr->ia_size, 0, "", &written); 969 970 /* According to ndir, the changes only take effect after 971 closing the file */ 972 ncp_inode_close(inode); 973 result = ncp_make_closed(inode); 974 if (result) 975 goto out; 976 977 if (attr->ia_size != i_size_read(inode)) { 978 truncate_setsize(inode, attr->ia_size); 979 mark_inode_dirty(inode); 980 } 981 } 982 if ((attr->ia_valid & ATTR_CTIME) != 0) { 983 info_mask |= (DM_CREATE_TIME | DM_CREATE_DATE); 984 ncp_date_unix2dos(attr->ia_ctime.tv_sec, 985 &info.creationTime, &info.creationDate); 986 } 987 if ((attr->ia_valid & ATTR_MTIME) != 0) { 988 info_mask |= (DM_MODIFY_TIME | DM_MODIFY_DATE); 989 ncp_date_unix2dos(attr->ia_mtime.tv_sec, 990 &info.modifyTime, &info.modifyDate); 991 } 992 if ((attr->ia_valid & ATTR_ATIME) != 0) { 993 __le16 dummy; 994 info_mask |= (DM_LAST_ACCESS_DATE); 995 ncp_date_unix2dos(attr->ia_atime.tv_sec, 996 &dummy, &info.lastAccessDate); 997 } 998 if (info_mask != 0) { 999 result = ncp_modify_file_or_subdir_dos_info(NCP_SERVER(inode), 1000 inode, info_mask, &info); 1001 if (result != 0) { 1002 if (info_mask == (DM_CREATE_TIME | DM_CREATE_DATE)) { 1003 /* NetWare seems not to allow this. I 1004 do not know why. So, just tell the 1005 user everything went fine. This is 1006 a terrible hack, but I do not know 1007 how to do this correctly. */ 1008 result = 0; 1009 } else 1010 goto out; 1011 } 1012#ifdef CONFIG_NCPFS_STRONG 1013 if ((!result) && (info_mask & DM_ATTRIBUTES)) 1014 NCP_FINFO(inode)->nwattr = info.attributes; 1015#endif 1016 } 1017 if (result) 1018 goto out; 1019 1020 setattr_copy(inode, attr); 1021 mark_inode_dirty(inode); 1022 1023out: 1024 if (result > 0) 1025 result = -EACCES; 1026 return result; 1027} 1028 1029static struct dentry *ncp_mount(struct file_system_type *fs_type, 1030 int flags, const char *dev_name, void *data) 1031{ 1032 return mount_nodev(fs_type, flags, data, ncp_fill_super); 1033} 1034 1035static struct file_system_type ncp_fs_type = { 1036 .owner = THIS_MODULE, 1037 .name = "ncpfs", 1038 .mount = ncp_mount, 1039 .kill_sb = kill_anon_super, 1040 .fs_flags = FS_BINARY_MOUNTDATA, 1041}; 1042MODULE_ALIAS_FS("ncpfs"); 1043 1044static int __init init_ncp_fs(void) 1045{ 1046 int err; 1047 ncp_dbg(1, "called\n"); 1048 1049 err = init_inodecache(); 1050 if (err) 1051 goto out1; 1052 err = register_filesystem(&ncp_fs_type); 1053 if (err) 1054 goto out; 1055 return 0; 1056out: 1057 destroy_inodecache(); 1058out1: 1059 return err; 1060} 1061 1062static void __exit exit_ncp_fs(void) 1063{ 1064 ncp_dbg(1, "called\n"); 1065 unregister_filesystem(&ncp_fs_type); 1066 destroy_inodecache(); 1067} 1068 1069module_init(init_ncp_fs) 1070module_exit(exit_ncp_fs) 1071MODULE_LICENSE("GPL");