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