1/*
2 *  dir.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, 1999 Wolfram Pienkoss for NLS
8 *  Modified 1999 Wolfram Pienkoss for directory caching
9 *  Modified 2000 Ben Harris, University of Cambridge for NFS NS meta-info
10 *
11 */
12
13
14#include <linux/time.h>
15#include <linux/errno.h>
16#include <linux/stat.h>
17#include <linux/kernel.h>
18#include <linux/vmalloc.h>
19#include <linux/mm.h>
20#include <linux/namei.h>
21#include <asm/uaccess.h>
22#include <asm/byteorder.h>
23
24#include "ncp_fs.h"
25
26static void ncp_read_volume_list(struct file *, struct dir_context *,
27				struct ncp_cache_control *);
28static void ncp_do_readdir(struct file *, struct dir_context *,
29				struct ncp_cache_control *);
30
31static int ncp_readdir(struct file *, struct dir_context *);
32
33static int ncp_create(struct inode *, struct dentry *, umode_t, bool);
34static struct dentry *ncp_lookup(struct inode *, struct dentry *, unsigned int);
35static int ncp_unlink(struct inode *, struct dentry *);
36static int ncp_mkdir(struct inode *, struct dentry *, umode_t);
37static int ncp_rmdir(struct inode *, struct dentry *);
38static int ncp_rename(struct inode *, struct dentry *,
39	  	      struct inode *, struct dentry *);
40static int ncp_mknod(struct inode * dir, struct dentry *dentry,
41		     umode_t mode, dev_t rdev);
42#if defined(CONFIG_NCPFS_EXTRAS) || defined(CONFIG_NCPFS_NFS_NS)
43extern int ncp_symlink(struct inode *, struct dentry *, const char *);
44#else
45#define ncp_symlink NULL
46#endif
47
48const struct file_operations ncp_dir_operations =
49{
50	.llseek		= generic_file_llseek,
51	.read		= generic_read_dir,
52	.iterate	= ncp_readdir,
53	.unlocked_ioctl	= ncp_ioctl,
54#ifdef CONFIG_COMPAT
55	.compat_ioctl	= ncp_compat_ioctl,
56#endif
57};
58
59const struct inode_operations ncp_dir_inode_operations =
60{
61	.create		= ncp_create,
62	.lookup		= ncp_lookup,
63	.unlink		= ncp_unlink,
64	.symlink	= ncp_symlink,
65	.mkdir		= ncp_mkdir,
66	.rmdir		= ncp_rmdir,
67	.mknod		= ncp_mknod,
68	.rename		= ncp_rename,
69	.setattr	= ncp_notify_change,
70};
71
72/*
73 * Dentry operations routines
74 */
75static int ncp_lookup_validate(struct dentry *, unsigned int);
76static int ncp_hash_dentry(const struct dentry *, struct qstr *);
77static int ncp_compare_dentry(const struct dentry *, const struct dentry *,
78		unsigned int, const char *, const struct qstr *);
79static int ncp_delete_dentry(const struct dentry *);
80static void ncp_d_prune(struct dentry *dentry);
81
82const struct dentry_operations ncp_dentry_operations =
83{
84	.d_revalidate	= ncp_lookup_validate,
85	.d_hash		= ncp_hash_dentry,
86	.d_compare	= ncp_compare_dentry,
87	.d_delete	= ncp_delete_dentry,
88	.d_prune	= ncp_d_prune,
89};
90
91#define ncp_namespace(i)	(NCP_SERVER(i)->name_space[NCP_FINFO(i)->volNumber])
92
93static inline int ncp_preserve_entry_case(struct inode *i, __u32 nscreator)
94{
95#ifdef CONFIG_NCPFS_SMALLDOS
96	int ns = ncp_namespace(i);
97
98	if ((ns == NW_NS_DOS)
99#ifdef CONFIG_NCPFS_OS2_NS
100		|| ((ns == NW_NS_OS2) && (nscreator == NW_NS_DOS))
101#endif /* CONFIG_NCPFS_OS2_NS */
102	   )
103		return 0;
104#endif /* CONFIG_NCPFS_SMALLDOS */
105	return 1;
106}
107
108#define ncp_preserve_case(i)	(ncp_namespace(i) != NW_NS_DOS)
109
110static inline int ncp_case_sensitive(const struct inode *i)
111{
112#ifdef CONFIG_NCPFS_NFS_NS
113	return ncp_namespace(i) == NW_NS_NFS;
114#else
115	return 0;
116#endif /* CONFIG_NCPFS_NFS_NS */
117}
118
119/*
120 * Note: leave the hash unchanged if the directory
121 * is case-sensitive.
122 *
123 * Accessing the parent inode can be racy under RCU pathwalking.
124 * Use ACCESS_ONCE() to make sure we use _one_ particular inode,
125 * the callers will handle races.
126 */
127static int
128ncp_hash_dentry(const struct dentry *dentry, struct qstr *this)
129{
130	struct inode *inode = d_inode_rcu(dentry);
131
132	if (!inode)
133		return 0;
134
135	if (!ncp_case_sensitive(inode)) {
136		struct super_block *sb = dentry->d_sb;
137		struct nls_table *t;
138		unsigned long hash;
139		int i;
140
141		t = NCP_IO_TABLE(sb);
142		hash = init_name_hash();
143		for (i=0; i<this->len ; i++)
144			hash = partial_name_hash(ncp_tolower(t, this->name[i]),
145									hash);
146		this->hash = end_name_hash(hash);
147	}
148	return 0;
149}
150
151/*
152 * Accessing the parent inode can be racy under RCU pathwalking.
153 * Use ACCESS_ONCE() to make sure we use _one_ particular inode,
154 * the callers will handle races.
155 */
156static int
157ncp_compare_dentry(const struct dentry *parent, const struct dentry *dentry,
158		unsigned int len, const char *str, const struct qstr *name)
159{
160	struct inode *pinode;
161
162	if (len != name->len)
163		return 1;
164
165	pinode = d_inode_rcu(parent);
166	if (!pinode)
167		return 1;
168
169	if (ncp_case_sensitive(pinode))
170		return strncmp(str, name->name, len);
171
172	return ncp_strnicmp(NCP_IO_TABLE(pinode->i_sb), str, name->name, len);
173}
174
175/*
176 * This is the callback from dput() when d_count is going to 0.
177 * We use this to unhash dentries with bad inodes.
178 * Closing files can be safely postponed until iput() - it's done there anyway.
179 */
180static int
181ncp_delete_dentry(const struct dentry * dentry)
182{
183	struct inode *inode = d_inode(dentry);
184
185	if (inode) {
186		if (is_bad_inode(inode))
187			return 1;
188	} else
189	{
190	/* N.B. Unhash negative dentries? */
191	}
192	return 0;
193}
194
195static inline int
196ncp_single_volume(struct ncp_server *server)
197{
198	return (server->m.mounted_vol[0] != '\0');
199}
200
201static inline int ncp_is_server_root(struct inode *inode)
202{
203	return !ncp_single_volume(NCP_SERVER(inode)) &&
204		is_root_inode(inode);
205}
206
207
208/*
209 * This is the callback when the dcache has a lookup hit.
210 */
211
212
213#ifdef CONFIG_NCPFS_STRONG
214/* try to delete a readonly file (NW R bit set) */
215
216static int
217ncp_force_unlink(struct inode *dir, struct dentry* dentry)
218{
219        int res=0x9c,res2;
220	struct nw_modify_dos_info info;
221	__le32 old_nwattr;
222	struct inode *inode;
223
224	memset(&info, 0, sizeof(info));
225
226        /* remove the Read-Only flag on the NW server */
227	inode = d_inode(dentry);
228
229	old_nwattr = NCP_FINFO(inode)->nwattr;
230	info.attributes = old_nwattr & ~(aRONLY|aDELETEINHIBIT|aRENAMEINHIBIT);
231	res2 = ncp_modify_file_or_subdir_dos_info_path(NCP_SERVER(inode), inode, NULL, DM_ATTRIBUTES, &info);
232	if (res2)
233		goto leave_me;
234
235        /* now try again the delete operation */
236        res = ncp_del_file_or_subdir2(NCP_SERVER(dir), dentry);
237
238        if (res)  /* delete failed, set R bit again */
239        {
240		info.attributes = old_nwattr;
241		res2 = ncp_modify_file_or_subdir_dos_info_path(NCP_SERVER(inode), inode, NULL, DM_ATTRIBUTES, &info);
242		if (res2)
243                        goto leave_me;
244        }
245leave_me:
246        return(res);
247}
248#endif	/* CONFIG_NCPFS_STRONG */
249
250#ifdef CONFIG_NCPFS_STRONG
251static int
252ncp_force_rename(struct inode *old_dir, struct dentry* old_dentry, char *_old_name,
253                 struct inode *new_dir, struct dentry* new_dentry, char *_new_name)
254{
255	struct nw_modify_dos_info info;
256        int res=0x90,res2;
257	struct inode *old_inode = d_inode(old_dentry);
258	__le32 old_nwattr = NCP_FINFO(old_inode)->nwattr;
259	__le32 new_nwattr = 0; /* shut compiler warning */
260	int old_nwattr_changed = 0;
261	int new_nwattr_changed = 0;
262
263	memset(&info, 0, sizeof(info));
264
265        /* remove the Read-Only flag on the NW server */
266
267	info.attributes = old_nwattr & ~(aRONLY|aRENAMEINHIBIT|aDELETEINHIBIT);
268	res2 = ncp_modify_file_or_subdir_dos_info_path(NCP_SERVER(old_inode), old_inode, NULL, DM_ATTRIBUTES, &info);
269	if (!res2)
270		old_nwattr_changed = 1;
271	if (new_dentry && d_really_is_positive(new_dentry)) {
272		new_nwattr = NCP_FINFO(d_inode(new_dentry))->nwattr;
273		info.attributes = new_nwattr & ~(aRONLY|aRENAMEINHIBIT|aDELETEINHIBIT);
274		res2 = ncp_modify_file_or_subdir_dos_info_path(NCP_SERVER(new_dir), new_dir, _new_name, DM_ATTRIBUTES, &info);
275		if (!res2)
276			new_nwattr_changed = 1;
277	}
278        /* now try again the rename operation */
279	/* but only if something really happened */
280	if (new_nwattr_changed || old_nwattr_changed) {
281	        res = ncp_ren_or_mov_file_or_subdir(NCP_SERVER(old_dir),
282        	                                    old_dir, _old_name,
283                	                            new_dir, _new_name);
284	}
285	if (res)
286		goto leave_me;
287	/* file was successfully renamed, so:
288	   do not set attributes on old file - it no longer exists
289	   copy attributes from old file to new */
290	new_nwattr_changed = old_nwattr_changed;
291	new_nwattr = old_nwattr;
292	old_nwattr_changed = 0;
293
294leave_me:;
295	if (old_nwattr_changed) {
296		info.attributes = old_nwattr;
297		res2 = ncp_modify_file_or_subdir_dos_info_path(NCP_SERVER(old_inode), old_inode, NULL, DM_ATTRIBUTES, &info);
298		/* ignore errors */
299	}
300	if (new_nwattr_changed)	{
301		info.attributes = new_nwattr;
302		res2 = ncp_modify_file_or_subdir_dos_info_path(NCP_SERVER(new_dir), new_dir, _new_name, DM_ATTRIBUTES, &info);
303		/* ignore errors */
304	}
305        return(res);
306}
307#endif	/* CONFIG_NCPFS_STRONG */
308
309
310static int
311ncp_lookup_validate(struct dentry *dentry, unsigned int flags)
312{
313	struct ncp_server *server;
314	struct dentry *parent;
315	struct inode *dir;
316	struct ncp_entry_info finfo;
317	int res, val = 0, len;
318	__u8 __name[NCP_MAXPATHLEN + 1];
319
320	if (dentry == dentry->d_sb->s_root)
321		return 1;
322
323	if (flags & LOOKUP_RCU)
324		return -ECHILD;
325
326	parent = dget_parent(dentry);
327	dir = d_inode(parent);
328
329	if (d_really_is_negative(dentry))
330		goto finished;
331
332	server = NCP_SERVER(dir);
333
334	/*
335	 * Inspired by smbfs:
336	 * The default validation is based on dentry age:
337	 * We set the max age at mount time.  (But each
338	 * successful server lookup renews the timestamp.)
339	 */
340	val = NCP_TEST_AGE(server, dentry);
341	if (val)
342		goto finished;
343
344	ncp_dbg(2, "%pd2 not valid, age=%ld, server lookup\n",
345		dentry, NCP_GET_AGE(dentry));
346
347	len = sizeof(__name);
348	if (ncp_is_server_root(dir)) {
349		res = ncp_io2vol(server, __name, &len, dentry->d_name.name,
350				 dentry->d_name.len, 1);
351		if (!res) {
352			res = ncp_lookup_volume(server, __name, &(finfo.i));
353			if (!res)
354				ncp_update_known_namespace(server, finfo.i.volNumber, NULL);
355		}
356	} else {
357		res = ncp_io2vol(server, __name, &len, dentry->d_name.name,
358				 dentry->d_name.len, !ncp_preserve_case(dir));
359		if (!res)
360			res = ncp_obtain_info(server, dir, __name, &(finfo.i));
361	}
362	finfo.volume = finfo.i.volNumber;
363	ncp_dbg(2, "looked for %pd/%s, res=%d\n",
364		dentry->d_parent, __name, res);
365	/*
366	 * If we didn't find it, or if it has a different dirEntNum to
367	 * what we remember, it's not valid any more.
368	 */
369	if (!res) {
370		struct inode *inode = d_inode(dentry);
371
372		mutex_lock(&inode->i_mutex);
373		if (finfo.i.dirEntNum == NCP_FINFO(inode)->dirEntNum) {
374			ncp_new_dentry(dentry);
375			val=1;
376		} else
377			ncp_dbg(2, "found, but dirEntNum changed\n");
378
379		ncp_update_inode2(inode, &finfo);
380		mutex_unlock(&inode->i_mutex);
381	}
382
383finished:
384	ncp_dbg(2, "result=%d\n", val);
385	dput(parent);
386	return val;
387}
388
389static time_t ncp_obtain_mtime(struct dentry *dentry)
390{
391	struct inode *inode = d_inode(dentry);
392	struct ncp_server *server = NCP_SERVER(inode);
393	struct nw_info_struct i;
394
395	if (!ncp_conn_valid(server) || ncp_is_server_root(inode))
396		return 0;
397
398	if (ncp_obtain_info(server, inode, NULL, &i))
399		return 0;
400
401	return ncp_date_dos2unix(i.modifyTime, i.modifyDate);
402}
403
404static inline void
405ncp_invalidate_dircache_entries(struct dentry *parent)
406{
407	struct ncp_server *server = NCP_SERVER(d_inode(parent));
408	struct dentry *dentry;
409
410	spin_lock(&parent->d_lock);
411	list_for_each_entry(dentry, &parent->d_subdirs, d_child) {
412		dentry->d_fsdata = NULL;
413		ncp_age_dentry(server, dentry);
414	}
415	spin_unlock(&parent->d_lock);
416}
417
418static int ncp_readdir(struct file *file, struct dir_context *ctx)
419{
420	struct dentry *dentry = file->f_path.dentry;
421	struct inode *inode = d_inode(dentry);
422	struct page *page = NULL;
423	struct ncp_server *server = NCP_SERVER(inode);
424	union  ncp_dir_cache *cache = NULL;
425	struct ncp_cache_control ctl;
426	int result, mtime_valid = 0;
427	time_t mtime = 0;
428
429	ctl.page  = NULL;
430	ctl.cache = NULL;
431
432	ncp_dbg(2, "reading %pD2, pos=%d\n", file, (int)ctx->pos);
433
434	result = -EIO;
435	/* Do not generate '.' and '..' when server is dead. */
436	if (!ncp_conn_valid(server))
437		goto out;
438
439	result = 0;
440	if (!dir_emit_dots(file, ctx))
441		goto out;
442
443	page = grab_cache_page(&inode->i_data, 0);
444	if (!page)
445		goto read_really;
446
447	ctl.cache = cache = kmap(page);
448	ctl.head  = cache->head;
449
450	if (!PageUptodate(page) || !ctl.head.eof)
451		goto init_cache;
452
453	if (ctx->pos == 2) {
454		if (jiffies - ctl.head.time >= NCP_MAX_AGE(server))
455			goto init_cache;
456
457		mtime = ncp_obtain_mtime(dentry);
458		mtime_valid = 1;
459		if ((!mtime) || (mtime != ctl.head.mtime))
460			goto init_cache;
461	}
462
463	if (ctx->pos > ctl.head.end)
464		goto finished;
465
466	ctl.fpos = ctx->pos + (NCP_DIRCACHE_START - 2);
467	ctl.ofs  = ctl.fpos / NCP_DIRCACHE_SIZE;
468	ctl.idx  = ctl.fpos % NCP_DIRCACHE_SIZE;
469
470	for (;;) {
471		if (ctl.ofs != 0) {
472			ctl.page = find_lock_page(&inode->i_data, ctl.ofs);
473			if (!ctl.page)
474				goto invalid_cache;
475			ctl.cache = kmap(ctl.page);
476			if (!PageUptodate(ctl.page))
477				goto invalid_cache;
478		}
479		while (ctl.idx < NCP_DIRCACHE_SIZE) {
480			struct dentry *dent;
481			bool over;
482
483			spin_lock(&dentry->d_lock);
484			if (!(NCP_FINFO(inode)->flags & NCPI_DIR_CACHE)) {
485				spin_unlock(&dentry->d_lock);
486				goto invalid_cache;
487			}
488			dent = ctl.cache->dentry[ctl.idx];
489			if (unlikely(!lockref_get_not_dead(&dent->d_lockref))) {
490				spin_unlock(&dentry->d_lock);
491				goto invalid_cache;
492			}
493			spin_unlock(&dentry->d_lock);
494			if (d_really_is_negative(dent)) {
495				dput(dent);
496				goto invalid_cache;
497			}
498			over = !dir_emit(ctx, dent->d_name.name,
499					dent->d_name.len,
500					d_inode(dent)->i_ino, DT_UNKNOWN);
501			dput(dent);
502			if (over)
503				goto finished;
504			ctx->pos += 1;
505			ctl.idx += 1;
506			if (ctx->pos > ctl.head.end)
507				goto finished;
508		}
509		if (ctl.page) {
510			kunmap(ctl.page);
511			SetPageUptodate(ctl.page);
512			unlock_page(ctl.page);
513			page_cache_release(ctl.page);
514			ctl.page = NULL;
515		}
516		ctl.idx  = 0;
517		ctl.ofs += 1;
518	}
519invalid_cache:
520	if (ctl.page) {
521		kunmap(ctl.page);
522		unlock_page(ctl.page);
523		page_cache_release(ctl.page);
524		ctl.page = NULL;
525	}
526	ctl.cache = cache;
527init_cache:
528	ncp_invalidate_dircache_entries(dentry);
529	if (!mtime_valid) {
530		mtime = ncp_obtain_mtime(dentry);
531		mtime_valid = 1;
532	}
533	ctl.head.mtime = mtime;
534	ctl.head.time = jiffies;
535	ctl.head.eof = 0;
536	ctl.fpos = 2;
537	ctl.ofs = 0;
538	ctl.idx = NCP_DIRCACHE_START;
539	ctl.filled = 0;
540	ctl.valid  = 1;
541read_really:
542	spin_lock(&dentry->d_lock);
543	NCP_FINFO(inode)->flags |= NCPI_DIR_CACHE;
544	spin_unlock(&dentry->d_lock);
545	if (ncp_is_server_root(inode)) {
546		ncp_read_volume_list(file, ctx, &ctl);
547	} else {
548		ncp_do_readdir(file, ctx, &ctl);
549	}
550	ctl.head.end = ctl.fpos - 1;
551	ctl.head.eof = ctl.valid;
552finished:
553	if (ctl.page) {
554		kunmap(ctl.page);
555		SetPageUptodate(ctl.page);
556		unlock_page(ctl.page);
557		page_cache_release(ctl.page);
558	}
559	if (page) {
560		cache->head = ctl.head;
561		kunmap(page);
562		SetPageUptodate(page);
563		unlock_page(page);
564		page_cache_release(page);
565	}
566out:
567	return result;
568}
569
570static void ncp_d_prune(struct dentry *dentry)
571{
572	if (!dentry->d_fsdata)	/* not referenced from page cache */
573		return;
574	NCP_FINFO(d_inode(dentry->d_parent))->flags &= ~NCPI_DIR_CACHE;
575}
576
577static int
578ncp_fill_cache(struct file *file, struct dir_context *ctx,
579		struct ncp_cache_control *ctrl, struct ncp_entry_info *entry,
580		int inval_childs)
581{
582	struct dentry *newdent, *dentry = file->f_path.dentry;
583	struct inode *dir = d_inode(dentry);
584	struct ncp_cache_control ctl = *ctrl;
585	struct qstr qname;
586	int valid = 0;
587	int hashed = 0;
588	ino_t ino = 0;
589	__u8 __name[NCP_MAXPATHLEN + 1];
590
591	qname.len = sizeof(__name);
592	if (ncp_vol2io(NCP_SERVER(dir), __name, &qname.len,
593			entry->i.entryName, entry->i.nameLen,
594			!ncp_preserve_entry_case(dir, entry->i.NSCreator)))
595		return 1; /* I'm not sure */
596
597	qname.name = __name;
598
599	newdent = d_hash_and_lookup(dentry, &qname);
600	if (IS_ERR(newdent))
601		goto end_advance;
602	if (!newdent) {
603		newdent = d_alloc(dentry, &qname);
604		if (!newdent)
605			goto end_advance;
606	} else {
607		hashed = 1;
608
609		/* If case sensitivity changed for this volume, all entries below this one
610		   should be thrown away.  This entry itself is not affected, as its case
611		   sensitivity is controlled by its own parent. */
612		if (inval_childs)
613			shrink_dcache_parent(newdent);
614
615		/*
616		 * NetWare's OS2 namespace is case preserving yet case
617		 * insensitive.  So we update dentry's name as received from
618		 * server. Parent dir's i_mutex is locked because we're in
619		 * readdir.
620		 */
621		dentry_update_name_case(newdent, &qname);
622	}
623
624	if (d_really_is_negative(newdent)) {
625		struct inode *inode;
626
627		entry->opened = 0;
628		entry->ino = iunique(dir->i_sb, 2);
629		inode = ncp_iget(dir->i_sb, entry);
630		if (inode) {
631			d_instantiate(newdent, inode);
632			if (!hashed)
633				d_rehash(newdent);
634		} else {
635			spin_lock(&dentry->d_lock);
636			NCP_FINFO(dir)->flags &= ~NCPI_DIR_CACHE;
637			spin_unlock(&dentry->d_lock);
638		}
639	} else {
640		struct inode *inode = d_inode(newdent);
641
642		mutex_lock_nested(&inode->i_mutex, I_MUTEX_CHILD);
643		ncp_update_inode2(inode, entry);
644		mutex_unlock(&inode->i_mutex);
645	}
646
647	if (ctl.idx >= NCP_DIRCACHE_SIZE) {
648		if (ctl.page) {
649			kunmap(ctl.page);
650			SetPageUptodate(ctl.page);
651			unlock_page(ctl.page);
652			page_cache_release(ctl.page);
653		}
654		ctl.cache = NULL;
655		ctl.idx  -= NCP_DIRCACHE_SIZE;
656		ctl.ofs  += 1;
657		ctl.page  = grab_cache_page(&dir->i_data, ctl.ofs);
658		if (ctl.page)
659			ctl.cache = kmap(ctl.page);
660	}
661	if (ctl.cache) {
662		if (d_really_is_positive(newdent)) {
663			newdent->d_fsdata = newdent;
664			ctl.cache->dentry[ctl.idx] = newdent;
665			ino = d_inode(newdent)->i_ino;
666			ncp_new_dentry(newdent);
667		}
668 		valid = 1;
669	}
670	dput(newdent);
671end_advance:
672	if (!valid)
673		ctl.valid = 0;
674	if (!ctl.filled && (ctl.fpos == ctx->pos)) {
675		if (!ino)
676			ino = iunique(dir->i_sb, 2);
677		ctl.filled = !dir_emit(ctx, qname.name, qname.len,
678				     ino, DT_UNKNOWN);
679		if (!ctl.filled)
680			ctx->pos += 1;
681	}
682	ctl.fpos += 1;
683	ctl.idx  += 1;
684	*ctrl = ctl;
685	return (ctl.valid || !ctl.filled);
686}
687
688static void
689ncp_read_volume_list(struct file *file, struct dir_context *ctx,
690			struct ncp_cache_control *ctl)
691{
692	struct inode *inode = file_inode(file);
693	struct ncp_server *server = NCP_SERVER(inode);
694	struct ncp_volume_info info;
695	struct ncp_entry_info entry;
696	int i;
697
698	ncp_dbg(1, "pos=%ld\n", (unsigned long)ctx->pos);
699
700	for (i = 0; i < NCP_NUMBER_OF_VOLUMES; i++) {
701		int inval_dentry;
702
703		if (ncp_get_volume_info_with_number(server, i, &info) != 0)
704			return;
705		if (!strlen(info.volume_name))
706			continue;
707
708		ncp_dbg(1, "found vol: %s\n", info.volume_name);
709
710		if (ncp_lookup_volume(server, info.volume_name,
711					&entry.i)) {
712			ncp_dbg(1, "could not lookup vol %s\n",
713				info.volume_name);
714			continue;
715		}
716		inval_dentry = ncp_update_known_namespace(server, entry.i.volNumber, NULL);
717		entry.volume = entry.i.volNumber;
718		if (!ncp_fill_cache(file, ctx, ctl, &entry, inval_dentry))
719			return;
720	}
721}
722
723static void
724ncp_do_readdir(struct file *file, struct dir_context *ctx,
725						struct ncp_cache_control *ctl)
726{
727	struct inode *dir = file_inode(file);
728	struct ncp_server *server = NCP_SERVER(dir);
729	struct nw_search_sequence seq;
730	struct ncp_entry_info entry;
731	int err;
732	void* buf;
733	int more;
734	size_t bufsize;
735
736	ncp_dbg(1, "%pD2, fpos=%ld\n", file, (unsigned long)ctx->pos);
737	ncp_vdbg("init %pD, volnum=%d, dirent=%u\n",
738		 file, NCP_FINFO(dir)->volNumber, NCP_FINFO(dir)->dirEntNum);
739
740	err = ncp_initialize_search(server, dir, &seq);
741	if (err) {
742		ncp_dbg(1, "init failed, err=%d\n", err);
743		return;
744	}
745	/* We MUST NOT use server->buffer_size handshaked with server if we are
746	   using UDP, as for UDP server uses max. buffer size determined by
747	   MTU, and for TCP server uses hardwired value 65KB (== 66560 bytes).
748	   So we use 128KB, just to be sure, as there is no way how to know
749	   this value in advance. */
750	bufsize = 131072;
751	buf = vmalloc(bufsize);
752	if (!buf)
753		return;
754	do {
755		int cnt;
756		char* rpl;
757		size_t rpls;
758
759		err = ncp_search_for_fileset(server, &seq, &more, &cnt, buf, bufsize, &rpl, &rpls);
760		if (err)		/* Error */
761			break;
762		if (!cnt)		/* prevent endless loop */
763			break;
764		while (cnt--) {
765			size_t onerpl;
766
767			if (rpls < offsetof(struct nw_info_struct, entryName))
768				break;	/* short packet */
769			ncp_extract_file_info(rpl, &entry.i);
770			onerpl = offsetof(struct nw_info_struct, entryName) + entry.i.nameLen;
771			if (rpls < onerpl)
772				break;	/* short packet */
773			(void)ncp_obtain_nfs_info(server, &entry.i);
774			rpl += onerpl;
775			rpls -= onerpl;
776			entry.volume = entry.i.volNumber;
777			if (!ncp_fill_cache(file, ctx, ctl, &entry, 0))
778				break;
779		}
780	} while (more);
781	vfree(buf);
782	return;
783}
784
785int ncp_conn_logged_in(struct super_block *sb)
786{
787	struct ncp_server* server = NCP_SBP(sb);
788	int result;
789
790	if (ncp_single_volume(server)) {
791		int len;
792		struct dentry* dent;
793		__u32 volNumber;
794		__le32 dirEntNum;
795		__le32 DosDirNum;
796		__u8 __name[NCP_MAXPATHLEN + 1];
797
798		len = sizeof(__name);
799		result = ncp_io2vol(server, __name, &len, server->m.mounted_vol,
800				    strlen(server->m.mounted_vol), 1);
801		if (result)
802			goto out;
803		result = -ENOENT;
804		if (ncp_get_volume_root(server, __name, &volNumber, &dirEntNum, &DosDirNum)) {
805			ncp_vdbg("%s not found\n", server->m.mounted_vol);
806			goto out;
807		}
808		dent = sb->s_root;
809		if (dent) {
810			struct inode* ino = d_inode(dent);
811			if (ino) {
812				ncp_update_known_namespace(server, volNumber, NULL);
813				NCP_FINFO(ino)->volNumber = volNumber;
814				NCP_FINFO(ino)->dirEntNum = dirEntNum;
815				NCP_FINFO(ino)->DosDirNum = DosDirNum;
816				result = 0;
817			} else {
818				ncp_dbg(1, "d_inode(sb->s_root) == NULL!\n");
819			}
820		} else {
821			ncp_dbg(1, "sb->s_root == NULL!\n");
822		}
823	} else
824		result = 0;
825
826out:
827	return result;
828}
829
830static struct dentry *ncp_lookup(struct inode *dir, struct dentry *dentry, unsigned int flags)
831{
832	struct ncp_server *server = NCP_SERVER(dir);
833	struct inode *inode = NULL;
834	struct ncp_entry_info finfo;
835	int error, res, len;
836	__u8 __name[NCP_MAXPATHLEN + 1];
837
838	error = -EIO;
839	if (!ncp_conn_valid(server))
840		goto finished;
841
842	ncp_vdbg("server lookup for %pd2\n", dentry);
843
844	len = sizeof(__name);
845	if (ncp_is_server_root(dir)) {
846		res = ncp_io2vol(server, __name, &len, dentry->d_name.name,
847				 dentry->d_name.len, 1);
848		if (!res)
849			res = ncp_lookup_volume(server, __name, &(finfo.i));
850		if (!res)
851			ncp_update_known_namespace(server, finfo.i.volNumber, NULL);
852	} else {
853		res = ncp_io2vol(server, __name, &len, dentry->d_name.name,
854				 dentry->d_name.len, !ncp_preserve_case(dir));
855		if (!res)
856			res = ncp_obtain_info(server, dir, __name, &(finfo.i));
857	}
858	ncp_vdbg("looked for %pd2, res=%d\n", dentry, res);
859	/*
860	 * If we didn't find an entry, make a negative dentry.
861	 */
862	if (res)
863		goto add_entry;
864
865	/*
866	 * Create an inode for the entry.
867	 */
868	finfo.opened = 0;
869	finfo.ino = iunique(dir->i_sb, 2);
870	finfo.volume = finfo.i.volNumber;
871	error = -EACCES;
872	inode = ncp_iget(dir->i_sb, &finfo);
873
874	if (inode) {
875		ncp_new_dentry(dentry);
876add_entry:
877		d_add(dentry, inode);
878		error = 0;
879	}
880
881finished:
882	ncp_vdbg("result=%d\n", error);
883	return ERR_PTR(error);
884}
885
886/*
887 * This code is common to create, mkdir, and mknod.
888 */
889static int ncp_instantiate(struct inode *dir, struct dentry *dentry,
890			struct ncp_entry_info *finfo)
891{
892	struct inode *inode;
893	int error = -EINVAL;
894
895	finfo->ino = iunique(dir->i_sb, 2);
896	inode = ncp_iget(dir->i_sb, finfo);
897	if (!inode)
898		goto out_close;
899	d_instantiate(dentry,inode);
900	error = 0;
901out:
902	return error;
903
904out_close:
905	ncp_vdbg("%pd2 failed, closing file\n", dentry);
906	ncp_close_file(NCP_SERVER(dir), finfo->file_handle);
907	goto out;
908}
909
910int ncp_create_new(struct inode *dir, struct dentry *dentry, umode_t mode,
911		   dev_t rdev, __le32 attributes)
912{
913	struct ncp_server *server = NCP_SERVER(dir);
914	struct ncp_entry_info finfo;
915	int error, result, len;
916	int opmode;
917	__u8 __name[NCP_MAXPATHLEN + 1];
918
919	ncp_vdbg("creating %pd2, mode=%hx\n", dentry, mode);
920
921	ncp_age_dentry(server, dentry);
922	len = sizeof(__name);
923	error = ncp_io2vol(server, __name, &len, dentry->d_name.name,
924			   dentry->d_name.len, !ncp_preserve_case(dir));
925	if (error)
926		goto out;
927
928	error = -EACCES;
929
930	if (S_ISREG(mode) &&
931	    (server->m.flags & NCP_MOUNT_EXTRAS) &&
932	    (mode & S_IXUGO))
933		attributes |= aSYSTEM | aSHARED;
934
935	result = ncp_open_create_file_or_subdir(server, dir, __name,
936				OC_MODE_CREATE | OC_MODE_OPEN | OC_MODE_REPLACE,
937				attributes, AR_READ | AR_WRITE, &finfo);
938	opmode = O_RDWR;
939	if (result) {
940		result = ncp_open_create_file_or_subdir(server, dir, __name,
941				OC_MODE_CREATE | OC_MODE_OPEN | OC_MODE_REPLACE,
942				attributes, AR_WRITE, &finfo);
943		if (result) {
944			if (result == 0x87)
945				error = -ENAMETOOLONG;
946			else if (result < 0)
947				error = result;
948			ncp_dbg(1, "%pd2 failed\n", dentry);
949			goto out;
950		}
951		opmode = O_WRONLY;
952	}
953	finfo.access = opmode;
954	if (ncp_is_nfs_extras(server, finfo.volume)) {
955		finfo.i.nfs.mode = mode;
956		finfo.i.nfs.rdev = new_encode_dev(rdev);
957		if (ncp_modify_nfs_info(server, finfo.volume,
958					finfo.i.dirEntNum,
959					mode, new_encode_dev(rdev)) != 0)
960			goto out;
961	}
962
963	error = ncp_instantiate(dir, dentry, &finfo);
964out:
965	return error;
966}
967
968static int ncp_create(struct inode *dir, struct dentry *dentry, umode_t mode,
969		bool excl)
970{
971	return ncp_create_new(dir, dentry, mode, 0, 0);
972}
973
974static int ncp_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
975{
976	struct ncp_entry_info finfo;
977	struct ncp_server *server = NCP_SERVER(dir);
978	int error, len;
979	__u8 __name[NCP_MAXPATHLEN + 1];
980
981	ncp_dbg(1, "making %pd2\n", dentry);
982
983	ncp_age_dentry(server, dentry);
984	len = sizeof(__name);
985	error = ncp_io2vol(server, __name, &len, dentry->d_name.name,
986			   dentry->d_name.len, !ncp_preserve_case(dir));
987	if (error)
988		goto out;
989
990	error = ncp_open_create_file_or_subdir(server, dir, __name,
991					   OC_MODE_CREATE, aDIR,
992					   cpu_to_le16(0xffff),
993					   &finfo);
994	if (error == 0) {
995		if (ncp_is_nfs_extras(server, finfo.volume)) {
996			mode |= S_IFDIR;
997			finfo.i.nfs.mode = mode;
998			if (ncp_modify_nfs_info(server,
999						finfo.volume,
1000						finfo.i.dirEntNum,
1001						mode, 0) != 0)
1002				goto out;
1003		}
1004		error = ncp_instantiate(dir, dentry, &finfo);
1005	} else if (error > 0) {
1006		error = -EACCES;
1007	}
1008out:
1009	return error;
1010}
1011
1012static int ncp_rmdir(struct inode *dir, struct dentry *dentry)
1013{
1014	struct ncp_server *server = NCP_SERVER(dir);
1015	int error, result, len;
1016	__u8 __name[NCP_MAXPATHLEN + 1];
1017
1018	ncp_dbg(1, "removing %pd2\n", dentry);
1019
1020	len = sizeof(__name);
1021	error = ncp_io2vol(server, __name, &len, dentry->d_name.name,
1022			   dentry->d_name.len, !ncp_preserve_case(dir));
1023	if (error)
1024		goto out;
1025
1026	result = ncp_del_file_or_subdir(server, dir, __name);
1027	switch (result) {
1028		case 0x00:
1029			error = 0;
1030			break;
1031		case 0x85:	/* unauthorized to delete file */
1032		case 0x8A:	/* unauthorized to delete file */
1033			error = -EACCES;
1034			break;
1035		case 0x8F:
1036		case 0x90:	/* read only */
1037			error = -EPERM;
1038			break;
1039		case 0x9F:	/* in use by another client */
1040			error = -EBUSY;
1041			break;
1042		case 0xA0:	/* directory not empty */
1043			error = -ENOTEMPTY;
1044			break;
1045		case 0xFF:	/* someone deleted file */
1046			error = -ENOENT;
1047			break;
1048		default:
1049			error = result < 0 ? result : -EACCES;
1050			break;
1051       	}
1052out:
1053	return error;
1054}
1055
1056static int ncp_unlink(struct inode *dir, struct dentry *dentry)
1057{
1058	struct inode *inode = d_inode(dentry);
1059	struct ncp_server *server;
1060	int error;
1061
1062	server = NCP_SERVER(dir);
1063	ncp_dbg(1, "unlinking %pd2\n", dentry);
1064
1065	/*
1066	 * Check whether to close the file ...
1067	 */
1068	if (inode) {
1069		ncp_vdbg("closing file\n");
1070		ncp_make_closed(inode);
1071	}
1072
1073	error = ncp_del_file_or_subdir2(server, dentry);
1074#ifdef CONFIG_NCPFS_STRONG
1075	/* 9C is Invalid path.. It should be 8F, 90 - read only, but
1076	   it is not :-( */
1077	if ((error == 0x9C || error == 0x90) && server->m.flags & NCP_MOUNT_STRONG) { /* R/O */
1078		error = ncp_force_unlink(dir, dentry);
1079	}
1080#endif
1081	switch (error) {
1082		case 0x00:
1083			ncp_dbg(1, "removed %pd2\n", dentry);
1084			break;
1085		case 0x85:
1086		case 0x8A:
1087			error = -EACCES;
1088			break;
1089		case 0x8D:	/* some files in use */
1090		case 0x8E:	/* all files in use */
1091			error = -EBUSY;
1092			break;
1093		case 0x8F:	/* some read only */
1094		case 0x90:	/* all read only */
1095		case 0x9C:	/* !!! returned when in-use or read-only by NW4 */
1096			error = -EPERM;
1097			break;
1098		case 0xFF:
1099			error = -ENOENT;
1100			break;
1101		default:
1102			error = error < 0 ? error : -EACCES;
1103			break;
1104	}
1105	return error;
1106}
1107
1108static int ncp_rename(struct inode *old_dir, struct dentry *old_dentry,
1109		      struct inode *new_dir, struct dentry *new_dentry)
1110{
1111	struct ncp_server *server = NCP_SERVER(old_dir);
1112	int error;
1113	int old_len, new_len;
1114	__u8 __old_name[NCP_MAXPATHLEN + 1], __new_name[NCP_MAXPATHLEN + 1];
1115
1116	ncp_dbg(1, "%pd2 to %pd2\n", old_dentry, new_dentry);
1117
1118	ncp_age_dentry(server, old_dentry);
1119	ncp_age_dentry(server, new_dentry);
1120
1121	old_len = sizeof(__old_name);
1122	error = ncp_io2vol(server, __old_name, &old_len,
1123			   old_dentry->d_name.name, old_dentry->d_name.len,
1124			   !ncp_preserve_case(old_dir));
1125	if (error)
1126		goto out;
1127
1128	new_len = sizeof(__new_name);
1129	error = ncp_io2vol(server, __new_name, &new_len,
1130			   new_dentry->d_name.name, new_dentry->d_name.len,
1131			   !ncp_preserve_case(new_dir));
1132	if (error)
1133		goto out;
1134
1135	error = ncp_ren_or_mov_file_or_subdir(server, old_dir, __old_name,
1136						      new_dir, __new_name);
1137#ifdef CONFIG_NCPFS_STRONG
1138	if ((error == 0x90 || error == 0x8B || error == -EACCES) &&
1139			server->m.flags & NCP_MOUNT_STRONG) {	/* RO */
1140		error = ncp_force_rename(old_dir, old_dentry, __old_name,
1141					 new_dir, new_dentry, __new_name);
1142	}
1143#endif
1144	switch (error) {
1145		case 0x00:
1146			ncp_dbg(1, "renamed %pd -> %pd\n",
1147				old_dentry, new_dentry);
1148			ncp_d_prune(old_dentry);
1149			ncp_d_prune(new_dentry);
1150			break;
1151		case 0x9E:
1152			error = -ENAMETOOLONG;
1153			break;
1154		case 0xFF:
1155			error = -ENOENT;
1156			break;
1157		default:
1158			error = error < 0 ? error : -EACCES;
1159			break;
1160	}
1161out:
1162	return error;
1163}
1164
1165static int ncp_mknod(struct inode * dir, struct dentry *dentry,
1166		     umode_t mode, dev_t rdev)
1167{
1168	if (ncp_is_nfs_extras(NCP_SERVER(dir), NCP_FINFO(dir)->volNumber)) {
1169		ncp_dbg(1, "mode = 0%ho\n", mode);
1170		return ncp_create_new(dir, dentry, mode, rdev, 0);
1171	}
1172	return -EPERM; /* Strange, but true */
1173}
1174
1175/* The following routines are taken directly from msdos-fs */
1176
1177/* Linear day numbers of the respective 1sts in non-leap years. */
1178
1179static int day_n[] =
1180{0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 0, 0, 0, 0};
1181/* Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec */
1182
1183static int utc2local(int time)
1184{
1185	return time - sys_tz.tz_minuteswest * 60;
1186}
1187
1188static int local2utc(int time)
1189{
1190	return time + sys_tz.tz_minuteswest * 60;
1191}
1192
1193/* Convert a MS-DOS time/date pair to a UNIX date (seconds since 1 1 70). */
1194int
1195ncp_date_dos2unix(__le16 t, __le16 d)
1196{
1197	unsigned short time = le16_to_cpu(t), date = le16_to_cpu(d);
1198	int month, year, secs;
1199
1200	/* first subtract and mask after that... Otherwise, if
1201	   date == 0, bad things happen */
1202	month = ((date >> 5) - 1) & 15;
1203	year = date >> 9;
1204	secs = (time & 31) * 2 + 60 * ((time >> 5) & 63) + (time >> 11) * 3600 +
1205		86400 * ((date & 31) - 1 + day_n[month] + (year / 4) +
1206		year * 365 - ((year & 3) == 0 && month < 2 ? 1 : 0) + 3653);
1207	/* days since 1.1.70 plus 80's leap day */
1208	return local2utc(secs);
1209}
1210
1211
1212/* Convert linear UNIX date to a MS-DOS time/date pair. */
1213void
1214ncp_date_unix2dos(int unix_date, __le16 *time, __le16 *date)
1215{
1216	int day, year, nl_day, month;
1217
1218	unix_date = utc2local(unix_date);
1219	*time = cpu_to_le16(
1220		(unix_date % 60) / 2 + (((unix_date / 60) % 60) << 5) +
1221		(((unix_date / 3600) % 24) << 11));
1222	day = unix_date / 86400 - 3652;
1223	year = day / 365;
1224	if ((year + 3) / 4 + 365 * year > day)
1225		year--;
1226	day -= (year + 3) / 4 + 365 * year;
1227	if (day == 59 && !(year & 3)) {
1228		nl_day = day;
1229		month = 2;
1230	} else {
1231		nl_day = (year & 3) || day <= 59 ? day : day - 1;
1232		for (month = 1; month < 12; month++)
1233			if (day_n[month] > nl_day)
1234				break;
1235	}
1236	*date = cpu_to_le16(nl_day - day_n[month - 1] + 1 + (month << 5) + (year << 9));
1237}
1238