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
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>
20 #include <asm/uaccess.h>
21 #include <asm/byteorder.h>
23 #include <linux/ncp_fs.h>
25 #include "ncplib_kernel.h"
27 static void ncp_read_volume_list(struct file *, void *, filldir_t,
28 struct ncp_cache_control *);
29 static void ncp_do_readdir(struct file *, void *, filldir_t,
30 struct ncp_cache_control *);
32 static int ncp_readdir(struct file *, void *, filldir_t);
34 static int ncp_create(struct inode *, struct dentry *, int, struct nameidata *);
35 static struct dentry *ncp_lookup(struct inode *, struct dentry *, struct nameidata *);
36 static int ncp_unlink(struct inode *, struct dentry *);
37 static int ncp_mkdir(struct inode *, struct dentry *, int);
38 static int ncp_rmdir(struct inode *, struct dentry *);
39 static int ncp_rename(struct inode *, struct dentry *,
40 struct inode *, struct dentry *);
41 static int ncp_mknod(struct inode * dir, struct dentry *dentry,
42 int mode, dev_t rdev);
43 #if defined(CONFIG_NCPFS_EXTRAS) || defined(CONFIG_NCPFS_NFS_NS)
44 extern int ncp_symlink(struct inode *, struct dentry *, const char *);
46 #define ncp_symlink NULL
49 const struct file_operations ncp_dir_operations =
51 .llseek = generic_file_llseek,
52 .read = generic_read_dir,
53 .readdir = ncp_readdir,
54 .unlocked_ioctl = ncp_ioctl,
56 .compat_ioctl = ncp_compat_ioctl,
60 const struct inode_operations ncp_dir_inode_operations =
65 .symlink = ncp_symlink,
70 .setattr = ncp_notify_change,
74 * Dentry operations routines
76 static int ncp_lookup_validate(struct dentry *, struct nameidata *);
77 static int ncp_hash_dentry(struct dentry *, struct qstr *);
78 static int ncp_compare_dentry (struct dentry *, struct qstr *, struct qstr *);
79 static int ncp_delete_dentry(struct dentry *);
81 static const struct dentry_operations ncp_dentry_operations =
83 .d_revalidate = ncp_lookup_validate,
84 .d_hash = ncp_hash_dentry,
85 .d_compare = ncp_compare_dentry,
86 .d_delete = ncp_delete_dentry,
89 const struct dentry_operations ncp_root_dentry_operations =
91 .d_hash = ncp_hash_dentry,
92 .d_compare = ncp_compare_dentry,
93 .d_delete = ncp_delete_dentry,
97 #define ncp_namespace(i) (NCP_SERVER(i)->name_space[NCP_FINFO(i)->volNumber])
99 static inline int ncp_preserve_entry_case(struct inode *i, __u32 nscreator)
101 #ifdef CONFIG_NCPFS_SMALLDOS
102 int ns = ncp_namespace(i);
104 if ((ns == NW_NS_DOS)
105 #ifdef CONFIG_NCPFS_OS2_NS
106 || ((ns == NW_NS_OS2) && (nscreator == NW_NS_DOS))
107 #endif /* CONFIG_NCPFS_OS2_NS */
110 #endif /* CONFIG_NCPFS_SMALLDOS */
114 #define ncp_preserve_case(i) (ncp_namespace(i) != NW_NS_DOS)
116 static inline int ncp_case_sensitive(struct dentry *dentry)
118 #ifdef CONFIG_NCPFS_NFS_NS
119 return ncp_namespace(dentry->d_inode) == NW_NS_NFS;
122 #endif /* CONFIG_NCPFS_NFS_NS */
126 * Note: leave the hash unchanged if the directory
130 ncp_hash_dentry(struct dentry *dentry, struct qstr *this)
132 if (!ncp_case_sensitive(dentry)) {
137 t = NCP_IO_TABLE(dentry);
138 hash = init_name_hash();
139 for (i=0; i<this->len ; i++)
140 hash = partial_name_hash(ncp_tolower(t, this->name[i]),
142 this->hash = end_name_hash(hash);
148 ncp_compare_dentry(struct dentry *dentry, struct qstr *a, struct qstr *b)
150 if (a->len != b->len)
153 if (ncp_case_sensitive(dentry))
154 return strncmp(a->name, b->name, a->len);
156 return ncp_strnicmp(NCP_IO_TABLE(dentry), a->name, b->name, a->len);
160 * This is the callback from dput() when d_count is going to 0.
161 * We use this to unhash dentries with bad inodes.
162 * Closing files can be safely postponed until iput() - it's done there anyway.
165 ncp_delete_dentry(struct dentry * dentry)
167 struct inode *inode = dentry->d_inode;
170 if (is_bad_inode(inode))
174 /* N.B. Unhash negative dentries? */
180 ncp_single_volume(struct ncp_server *server)
182 return (server->m.mounted_vol[0] != '\0');
185 static inline int ncp_is_server_root(struct inode *inode)
187 return (!ncp_single_volume(NCP_SERVER(inode)) &&
188 inode == inode->i_sb->s_root->d_inode);
193 * This is the callback when the dcache has a lookup hit.
197 #ifdef CONFIG_NCPFS_STRONG
198 /* try to delete a readonly file (NW R bit set) */
201 ncp_force_unlink(struct inode *dir, struct dentry* dentry)
204 struct nw_modify_dos_info info;
208 memset(&info, 0, sizeof(info));
210 /* remove the Read-Only flag on the NW server */
211 inode = dentry->d_inode;
213 old_nwattr = NCP_FINFO(inode)->nwattr;
214 info.attributes = old_nwattr & ~(aRONLY|aDELETEINHIBIT|aRENAMEINHIBIT);
215 res2 = ncp_modify_file_or_subdir_dos_info_path(NCP_SERVER(inode), inode, NULL, DM_ATTRIBUTES, &info);
219 /* now try again the delete operation */
220 res = ncp_del_file_or_subdir2(NCP_SERVER(dir), dentry);
222 if (res) /* delete failed, set R bit again */
224 info.attributes = old_nwattr;
225 res2 = ncp_modify_file_or_subdir_dos_info_path(NCP_SERVER(inode), inode, NULL, DM_ATTRIBUTES, &info);
232 #endif /* CONFIG_NCPFS_STRONG */
234 #ifdef CONFIG_NCPFS_STRONG
236 ncp_force_rename(struct inode *old_dir, struct dentry* old_dentry, char *_old_name,
237 struct inode *new_dir, struct dentry* new_dentry, char *_new_name)
239 struct nw_modify_dos_info info;
241 struct inode *old_inode = old_dentry->d_inode;
242 __le32 old_nwattr = NCP_FINFO(old_inode)->nwattr;
243 __le32 new_nwattr = 0; /* shut compiler warning */
244 int old_nwattr_changed = 0;
245 int new_nwattr_changed = 0;
247 memset(&info, 0, sizeof(info));
249 /* remove the Read-Only flag on the NW server */
251 info.attributes = old_nwattr & ~(aRONLY|aRENAMEINHIBIT|aDELETEINHIBIT);
252 res2 = ncp_modify_file_or_subdir_dos_info_path(NCP_SERVER(old_inode), old_inode, NULL, DM_ATTRIBUTES, &info);
254 old_nwattr_changed = 1;
255 if (new_dentry && new_dentry->d_inode) {
256 new_nwattr = NCP_FINFO(new_dentry->d_inode)->nwattr;
257 info.attributes = new_nwattr & ~(aRONLY|aRENAMEINHIBIT|aDELETEINHIBIT);
258 res2 = ncp_modify_file_or_subdir_dos_info_path(NCP_SERVER(new_dir), new_dir, _new_name, DM_ATTRIBUTES, &info);
260 new_nwattr_changed = 1;
262 /* now try again the rename operation */
263 /* but only if something really happened */
264 if (new_nwattr_changed || old_nwattr_changed) {
265 res = ncp_ren_or_mov_file_or_subdir(NCP_SERVER(old_dir),
271 /* file was successfully renamed, so:
272 do not set attributes on old file - it no longer exists
273 copy attributes from old file to new */
274 new_nwattr_changed = old_nwattr_changed;
275 new_nwattr = old_nwattr;
276 old_nwattr_changed = 0;
279 if (old_nwattr_changed) {
280 info.attributes = old_nwattr;
281 res2 = ncp_modify_file_or_subdir_dos_info_path(NCP_SERVER(old_inode), old_inode, NULL, DM_ATTRIBUTES, &info);
284 if (new_nwattr_changed) {
285 info.attributes = new_nwattr;
286 res2 = ncp_modify_file_or_subdir_dos_info_path(NCP_SERVER(new_dir), new_dir, _new_name, DM_ATTRIBUTES, &info);
291 #endif /* CONFIG_NCPFS_STRONG */
295 ncp_lookup_validate(struct dentry *dentry, struct nameidata *nd)
297 struct ncp_server *server;
298 struct dentry *parent;
300 struct ncp_entry_info finfo;
301 int res, val = 0, len;
302 __u8 __name[NCP_MAXPATHLEN + 1];
304 parent = dget_parent(dentry);
305 dir = parent->d_inode;
307 if (!dentry->d_inode)
310 server = NCP_SERVER(dir);
314 * The default validation is based on dentry age:
315 * We set the max age at mount time. (But each
316 * successful server lookup renews the timestamp.)
318 val = NCP_TEST_AGE(server, dentry);
322 DDPRINTK("ncp_lookup_validate: %s/%s not valid, age=%ld, server lookup\n",
323 dentry->d_parent->d_name.name, dentry->d_name.name,
324 NCP_GET_AGE(dentry));
326 len = sizeof(__name);
327 if (ncp_is_server_root(dir)) {
328 res = ncp_io2vol(server, __name, &len, dentry->d_name.name,
329 dentry->d_name.len, 1);
331 res = ncp_lookup_volume(server, __name, &(finfo.i));
333 ncp_update_known_namespace(server, finfo.i.volNumber, NULL);
336 res = ncp_io2vol(server, __name, &len, dentry->d_name.name,
337 dentry->d_name.len, !ncp_preserve_case(dir));
339 res = ncp_obtain_info(server, dir, __name, &(finfo.i));
341 finfo.volume = finfo.i.volNumber;
342 DDPRINTK("ncp_lookup_validate: looked for %s/%s, res=%d\n",
343 dentry->d_parent->d_name.name, __name, res);
345 * If we didn't find it, or if it has a different dirEntNum to
346 * what we remember, it's not valid any more.
349 struct inode *inode = dentry->d_inode;
351 mutex_lock(&inode->i_mutex);
352 if (finfo.i.dirEntNum == NCP_FINFO(inode)->dirEntNum) {
353 ncp_new_dentry(dentry);
356 DDPRINTK("ncp_lookup_validate: found, but dirEntNum changed\n");
358 ncp_update_inode2(inode, &finfo);
359 mutex_unlock(&inode->i_mutex);
363 DDPRINTK("ncp_lookup_validate: result=%d\n", val);
368 static struct dentry *
369 ncp_dget_fpos(struct dentry *dentry, struct dentry *parent, unsigned long fpos)
371 struct dentry *dent = dentry;
372 struct list_head *next;
374 if (d_validate(dent, parent)) {
375 if (dent->d_name.len <= NCP_MAXPATHLEN &&
376 (unsigned long)dent->d_fsdata == fpos) {
377 if (!dent->d_inode) {
386 /* If a pointer is invalid, we search the dentry. */
387 spin_lock(&dcache_lock);
388 next = parent->d_subdirs.next;
389 while (next != &parent->d_subdirs) {
390 dent = list_entry(next, struct dentry, d_u.d_child);
391 if ((unsigned long)dent->d_fsdata == fpos) {
396 spin_unlock(&dcache_lock);
401 spin_unlock(&dcache_lock);
408 static time_t ncp_obtain_mtime(struct dentry *dentry)
410 struct inode *inode = dentry->d_inode;
411 struct ncp_server *server = NCP_SERVER(inode);
412 struct nw_info_struct i;
414 if (!ncp_conn_valid(server) || ncp_is_server_root(inode))
417 if (ncp_obtain_info(server, inode, NULL, &i))
420 return ncp_date_dos2unix(i.modifyTime, i.modifyDate);
423 static int ncp_readdir(struct file *filp, void *dirent, filldir_t filldir)
425 struct dentry *dentry = filp->f_path.dentry;
426 struct inode *inode = dentry->d_inode;
427 struct page *page = NULL;
428 struct ncp_server *server = NCP_SERVER(inode);
429 union ncp_dir_cache *cache = NULL;
430 struct ncp_cache_control ctl;
431 int result, mtime_valid = 0;
437 DDPRINTK("ncp_readdir: reading %s/%s, pos=%d\n",
438 dentry->d_parent->d_name.name, dentry->d_name.name,
442 /* Do not generate '.' and '..' when server is dead. */
443 if (!ncp_conn_valid(server))
447 if (filp->f_pos == 0) {
448 if (filldir(dirent, ".", 1, 0, inode->i_ino, DT_DIR))
452 if (filp->f_pos == 1) {
453 if (filldir(dirent, "..", 2, 1, parent_ino(dentry), DT_DIR))
458 page = grab_cache_page(&inode->i_data, 0);
462 ctl.cache = cache = kmap(page);
463 ctl.head = cache->head;
465 if (!PageUptodate(page) || !ctl.head.eof)
468 if (filp->f_pos == 2) {
469 if (jiffies - ctl.head.time >= NCP_MAX_AGE(server))
472 mtime = ncp_obtain_mtime(dentry);
474 if ((!mtime) || (mtime != ctl.head.mtime))
478 if (filp->f_pos > ctl.head.end)
481 ctl.fpos = filp->f_pos + (NCP_DIRCACHE_START - 2);
482 ctl.ofs = ctl.fpos / NCP_DIRCACHE_SIZE;
483 ctl.idx = ctl.fpos % NCP_DIRCACHE_SIZE;
487 ctl.page = find_lock_page(&inode->i_data, ctl.ofs);
490 ctl.cache = kmap(ctl.page);
491 if (!PageUptodate(ctl.page))
494 while (ctl.idx < NCP_DIRCACHE_SIZE) {
498 dent = ncp_dget_fpos(ctl.cache->dentry[ctl.idx],
499 dentry, filp->f_pos);
502 res = filldir(dirent, dent->d_name.name,
503 dent->d_name.len, filp->f_pos,
504 dent->d_inode->i_ino, DT_UNKNOWN);
510 if (filp->f_pos > ctl.head.end)
515 SetPageUptodate(ctl.page);
516 unlock_page(ctl.page);
517 page_cache_release(ctl.page);
526 unlock_page(ctl.page);
527 page_cache_release(ctl.page);
532 ncp_invalidate_dircache_entries(dentry);
534 mtime = ncp_obtain_mtime(dentry);
537 ctl.head.mtime = mtime;
538 ctl.head.time = jiffies;
542 ctl.idx = NCP_DIRCACHE_START;
546 if (ncp_is_server_root(inode)) {
547 ncp_read_volume_list(filp, dirent, filldir, &ctl);
549 ncp_do_readdir(filp, dirent, filldir, &ctl);
551 ctl.head.end = ctl.fpos - 1;
552 ctl.head.eof = ctl.valid;
556 SetPageUptodate(ctl.page);
557 unlock_page(ctl.page);
558 page_cache_release(ctl.page);
561 cache->head = ctl.head;
563 SetPageUptodate(page);
565 page_cache_release(page);
572 ncp_fill_cache(struct file *filp, void *dirent, filldir_t filldir,
573 struct ncp_cache_control *ctrl, struct ncp_entry_info *entry,
576 struct dentry *newdent, *dentry = filp->f_path.dentry;
577 struct inode *dir = dentry->d_inode;
578 struct ncp_cache_control ctl = *ctrl;
583 __u8 __name[NCP_MAXPATHLEN + 1];
585 qname.len = sizeof(__name);
586 if (ncp_vol2io(NCP_SERVER(dir), __name, &qname.len,
587 entry->i.entryName, entry->i.nameLen,
588 !ncp_preserve_entry_case(dir, entry->i.NSCreator)))
589 return 1; /* I'm not sure */
592 qname.hash = full_name_hash(qname.name, qname.len);
594 if (dentry->d_op && dentry->d_op->d_hash)
595 if (dentry->d_op->d_hash(dentry, &qname) != 0)
598 newdent = d_lookup(dentry, &qname);
601 newdent = d_alloc(dentry, &qname);
607 /* If case sensitivity changed for this volume, all entries below this one
608 should be thrown away. This entry itself is not affected, as its case
609 sensitivity is controlled by its own parent. */
611 shrink_dcache_parent(newdent);
614 * It is not as dangerous as it looks. NetWare's OS2 namespace is
615 * case preserving yet case insensitive. So we update dentry's name
616 * as received from server. We found dentry via d_lookup with our
617 * hash, so we know that hash does not change, and so replacing name
618 * should be reasonably safe.
620 if (qname.len == newdent->d_name.len &&
621 memcmp(newdent->d_name.name, qname.name, newdent->d_name.len)) {
622 struct inode *inode = newdent->d_inode;
625 * Inside ncpfs all uses of d_name are either for debugging,
626 * or on functions which acquire inode mutex (mknod, creat,
627 * lookup). So grab i_mutex here, to be sure. d_path
628 * uses dcache_lock when generating path, so we should too.
629 * And finally d_compare is protected by dentry's d_lock, so
633 mutex_lock(&inode->i_mutex);
634 spin_lock(&dcache_lock);
635 spin_lock(&newdent->d_lock);
636 memcpy((char *) newdent->d_name.name, qname.name,
637 newdent->d_name.len);
638 spin_unlock(&newdent->d_lock);
639 spin_unlock(&dcache_lock);
641 mutex_unlock(&inode->i_mutex);
645 if (!newdent->d_inode) {
649 entry->ino = iunique(dir->i_sb, 2);
650 inode = ncp_iget(dir->i_sb, entry);
652 newdent->d_op = &ncp_dentry_operations;
653 d_instantiate(newdent, inode);
658 struct inode *inode = newdent->d_inode;
660 mutex_lock(&inode->i_mutex);
661 ncp_update_inode2(inode, entry);
662 mutex_unlock(&inode->i_mutex);
665 if (newdent->d_inode) {
666 ino = newdent->d_inode->i_ino;
667 newdent->d_fsdata = (void *) ctl.fpos;
668 ncp_new_dentry(newdent);
671 if (ctl.idx >= NCP_DIRCACHE_SIZE) {
674 SetPageUptodate(ctl.page);
675 unlock_page(ctl.page);
676 page_cache_release(ctl.page);
679 ctl.idx -= NCP_DIRCACHE_SIZE;
681 ctl.page = grab_cache_page(&dir->i_data, ctl.ofs);
683 ctl.cache = kmap(ctl.page);
686 ctl.cache->dentry[ctl.idx] = newdent;
693 if (!ctl.filled && (ctl.fpos == filp->f_pos)) {
695 ino = find_inode_number(dentry, &qname);
697 ino = iunique(dir->i_sb, 2);
698 ctl.filled = filldir(dirent, qname.name, qname.len,
699 filp->f_pos, ino, DT_UNKNOWN);
706 return (ctl.valid || !ctl.filled);
710 ncp_read_volume_list(struct file *filp, void *dirent, filldir_t filldir,
711 struct ncp_cache_control *ctl)
713 struct dentry *dentry = filp->f_path.dentry;
714 struct inode *inode = dentry->d_inode;
715 struct ncp_server *server = NCP_SERVER(inode);
716 struct ncp_volume_info info;
717 struct ncp_entry_info entry;
720 DPRINTK("ncp_read_volume_list: pos=%ld\n",
721 (unsigned long) filp->f_pos);
723 for (i = 0; i < NCP_NUMBER_OF_VOLUMES; i++) {
726 if (ncp_get_volume_info_with_number(server, i, &info) != 0)
728 if (!strlen(info.volume_name))
731 DPRINTK("ncp_read_volume_list: found vol: %s\n",
734 if (ncp_lookup_volume(server, info.volume_name,
736 DPRINTK("ncpfs: could not lookup vol %s\n",
740 inval_dentry = ncp_update_known_namespace(server, entry.i.volNumber, NULL);
741 entry.volume = entry.i.volNumber;
742 if (!ncp_fill_cache(filp, dirent, filldir, ctl, &entry, inval_dentry))
748 ncp_do_readdir(struct file *filp, void *dirent, filldir_t filldir,
749 struct ncp_cache_control *ctl)
751 struct dentry *dentry = filp->f_path.dentry;
752 struct inode *dir = dentry->d_inode;
753 struct ncp_server *server = NCP_SERVER(dir);
754 struct nw_search_sequence seq;
755 struct ncp_entry_info entry;
761 DPRINTK("ncp_do_readdir: %s/%s, fpos=%ld\n",
762 dentry->d_parent->d_name.name, dentry->d_name.name,
763 (unsigned long) filp->f_pos);
764 PPRINTK("ncp_do_readdir: init %s, volnum=%d, dirent=%u\n",
765 dentry->d_name.name, NCP_FINFO(dir)->volNumber,
766 NCP_FINFO(dir)->dirEntNum);
768 err = ncp_initialize_search(server, dir, &seq);
770 DPRINTK("ncp_do_readdir: init failed, err=%d\n", err);
773 /* We MUST NOT use server->buffer_size handshaked with server if we are
774 using UDP, as for UDP server uses max. buffer size determined by
775 MTU, and for TCP server uses hardwired value 65KB (== 66560 bytes).
776 So we use 128KB, just to be sure, as there is no way how to know
777 this value in advance. */
779 buf = vmalloc(bufsize);
787 err = ncp_search_for_fileset(server, &seq, &more, &cnt, buf, bufsize, &rpl, &rpls);
790 if (!cnt) /* prevent endless loop */
795 if (rpls < offsetof(struct nw_info_struct, entryName))
796 break; /* short packet */
797 ncp_extract_file_info(rpl, &entry.i);
798 onerpl = offsetof(struct nw_info_struct, entryName) + entry.i.nameLen;
800 break; /* short packet */
801 (void)ncp_obtain_nfs_info(server, &entry.i);
804 entry.volume = entry.i.volNumber;
805 if (!ncp_fill_cache(filp, dirent, filldir, ctl, &entry, 0))
813 int ncp_conn_logged_in(struct super_block *sb)
815 struct ncp_server* server = NCP_SBP(sb);
818 if (ncp_single_volume(server)) {
824 __u8 __name[NCP_MAXPATHLEN + 1];
826 len = sizeof(__name);
827 result = ncp_io2vol(server, __name, &len, server->m.mounted_vol,
828 strlen(server->m.mounted_vol), 1);
832 if (ncp_get_volume_root(server, __name, &volNumber, &dirEntNum, &DosDirNum)) {
833 PPRINTK("ncp_conn_logged_in: %s not found\n",
834 server->m.mounted_vol);
839 struct inode* ino = dent->d_inode;
841 ncp_update_known_namespace(server, volNumber, NULL);
842 NCP_FINFO(ino)->volNumber = volNumber;
843 NCP_FINFO(ino)->dirEntNum = dirEntNum;
844 NCP_FINFO(ino)->DosDirNum = DosDirNum;
847 DPRINTK("ncpfs: sb->s_root->d_inode == NULL!\n");
850 DPRINTK("ncpfs: sb->s_root == NULL!\n");
859 static struct dentry *ncp_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd)
861 struct ncp_server *server = NCP_SERVER(dir);
862 struct inode *inode = NULL;
863 struct ncp_entry_info finfo;
865 __u8 __name[NCP_MAXPATHLEN + 1];
868 if (!ncp_conn_valid(server))
871 PPRINTK("ncp_lookup: server lookup for %s/%s\n",
872 dentry->d_parent->d_name.name, dentry->d_name.name);
874 len = sizeof(__name);
875 if (ncp_is_server_root(dir)) {
876 res = ncp_io2vol(server, __name, &len, dentry->d_name.name,
877 dentry->d_name.len, 1);
879 res = ncp_lookup_volume(server, __name, &(finfo.i));
881 ncp_update_known_namespace(server, finfo.i.volNumber, NULL);
883 res = ncp_io2vol(server, __name, &len, dentry->d_name.name,
884 dentry->d_name.len, !ncp_preserve_case(dir));
886 res = ncp_obtain_info(server, dir, __name, &(finfo.i));
888 PPRINTK("ncp_lookup: looked for %s/%s, res=%d\n",
889 dentry->d_parent->d_name.name, __name, res);
891 * If we didn't find an entry, make a negative dentry.
897 * Create an inode for the entry.
900 finfo.ino = iunique(dir->i_sb, 2);
901 finfo.volume = finfo.i.volNumber;
903 inode = ncp_iget(dir->i_sb, &finfo);
906 ncp_new_dentry(dentry);
908 dentry->d_op = &ncp_dentry_operations;
909 d_add(dentry, inode);
914 PPRINTK("ncp_lookup: result=%d\n", error);
915 return ERR_PTR(error);
919 * This code is common to create, mkdir, and mknod.
921 static int ncp_instantiate(struct inode *dir, struct dentry *dentry,
922 struct ncp_entry_info *finfo)
927 finfo->ino = iunique(dir->i_sb, 2);
928 inode = ncp_iget(dir->i_sb, finfo);
931 d_instantiate(dentry,inode);
937 PPRINTK("ncp_instantiate: %s/%s failed, closing file\n",
938 dentry->d_parent->d_name.name, dentry->d_name.name);
939 ncp_close_file(NCP_SERVER(dir), finfo->file_handle);
943 int ncp_create_new(struct inode *dir, struct dentry *dentry, int mode,
944 dev_t rdev, __le32 attributes)
946 struct ncp_server *server = NCP_SERVER(dir);
947 struct ncp_entry_info finfo;
948 int error, result, len;
950 __u8 __name[NCP_MAXPATHLEN + 1];
952 PPRINTK("ncp_create_new: creating %s/%s, mode=%x\n",
953 dentry->d_parent->d_name.name, dentry->d_name.name, mode);
955 ncp_age_dentry(server, dentry);
956 len = sizeof(__name);
957 error = ncp_io2vol(server, __name, &len, dentry->d_name.name,
958 dentry->d_name.len, !ncp_preserve_case(dir));
965 (server->m.flags & NCP_MOUNT_EXTRAS) &&
967 attributes |= aSYSTEM | aSHARED;
969 result = ncp_open_create_file_or_subdir(server, dir, __name,
970 OC_MODE_CREATE | OC_MODE_OPEN | OC_MODE_REPLACE,
971 attributes, AR_READ | AR_WRITE, &finfo);
974 result = ncp_open_create_file_or_subdir(server, dir, __name,
975 OC_MODE_CREATE | OC_MODE_OPEN | OC_MODE_REPLACE,
976 attributes, AR_WRITE, &finfo);
979 error = -ENAMETOOLONG;
982 DPRINTK("ncp_create: %s/%s failed\n",
983 dentry->d_parent->d_name.name, dentry->d_name.name);
988 finfo.access = opmode;
989 if (ncp_is_nfs_extras(server, finfo.volume)) {
990 finfo.i.nfs.mode = mode;
991 finfo.i.nfs.rdev = new_encode_dev(rdev);
992 if (ncp_modify_nfs_info(server, finfo.volume,
994 mode, new_encode_dev(rdev)) != 0)
998 error = ncp_instantiate(dir, dentry, &finfo);
1003 static int ncp_create(struct inode *dir, struct dentry *dentry, int mode,
1004 struct nameidata *nd)
1006 return ncp_create_new(dir, dentry, mode, 0, 0);
1009 static int ncp_mkdir(struct inode *dir, struct dentry *dentry, int mode)
1011 struct ncp_entry_info finfo;
1012 struct ncp_server *server = NCP_SERVER(dir);
1014 __u8 __name[NCP_MAXPATHLEN + 1];
1016 DPRINTK("ncp_mkdir: making %s/%s\n",
1017 dentry->d_parent->d_name.name, dentry->d_name.name);
1019 ncp_age_dentry(server, dentry);
1020 len = sizeof(__name);
1021 error = ncp_io2vol(server, __name, &len, dentry->d_name.name,
1022 dentry->d_name.len, !ncp_preserve_case(dir));
1026 error = ncp_open_create_file_or_subdir(server, dir, __name,
1027 OC_MODE_CREATE, aDIR,
1028 cpu_to_le16(0xffff),
1031 if (ncp_is_nfs_extras(server, finfo.volume)) {
1033 finfo.i.nfs.mode = mode;
1034 if (ncp_modify_nfs_info(server,
1040 error = ncp_instantiate(dir, dentry, &finfo);
1041 } else if (error > 0) {
1048 static int ncp_rmdir(struct inode *dir, struct dentry *dentry)
1050 struct ncp_server *server = NCP_SERVER(dir);
1051 int error, result, len;
1052 __u8 __name[NCP_MAXPATHLEN + 1];
1054 DPRINTK("ncp_rmdir: removing %s/%s\n",
1055 dentry->d_parent->d_name.name, dentry->d_name.name);
1058 if (!d_unhashed(dentry))
1061 len = sizeof(__name);
1062 error = ncp_io2vol(server, __name, &len, dentry->d_name.name,
1063 dentry->d_name.len, !ncp_preserve_case(dir));
1067 result = ncp_del_file_or_subdir(server, dir, __name);
1072 case 0x85: /* unauthorized to delete file */
1073 case 0x8A: /* unauthorized to delete file */
1077 case 0x90: /* read only */
1080 case 0x9F: /* in use by another client */
1083 case 0xA0: /* directory not empty */
1086 case 0xFF: /* someone deleted file */
1090 error = result < 0 ? result : -EACCES;
1097 static int ncp_unlink(struct inode *dir, struct dentry *dentry)
1099 struct inode *inode = dentry->d_inode;
1100 struct ncp_server *server;
1103 server = NCP_SERVER(dir);
1104 DPRINTK("ncp_unlink: unlinking %s/%s\n",
1105 dentry->d_parent->d_name.name, dentry->d_name.name);
1108 * Check whether to close the file ...
1111 PPRINTK("ncp_unlink: closing file\n");
1112 ncp_make_closed(inode);
1115 error = ncp_del_file_or_subdir2(server, dentry);
1116 #ifdef CONFIG_NCPFS_STRONG
1117 /* 9C is Invalid path.. It should be 8F, 90 - read only, but
1119 if ((error == 0x9C || error == 0x90) && server->m.flags & NCP_MOUNT_STRONG) { /* R/O */
1120 error = ncp_force_unlink(dir, dentry);
1125 DPRINTK("ncp: removed %s/%s\n",
1126 dentry->d_parent->d_name.name, dentry->d_name.name);
1132 case 0x8D: /* some files in use */
1133 case 0x8E: /* all files in use */
1136 case 0x8F: /* some read only */
1137 case 0x90: /* all read only */
1138 case 0x9C: /* !!! returned when in-use or read-only by NW4 */
1145 error = error < 0 ? error : -EACCES;
1151 static int ncp_rename(struct inode *old_dir, struct dentry *old_dentry,
1152 struct inode *new_dir, struct dentry *new_dentry)
1154 struct ncp_server *server = NCP_SERVER(old_dir);
1156 int old_len, new_len;
1157 __u8 __old_name[NCP_MAXPATHLEN + 1], __new_name[NCP_MAXPATHLEN + 1];
1159 DPRINTK("ncp_rename: %s/%s to %s/%s\n",
1160 old_dentry->d_parent->d_name.name, old_dentry->d_name.name,
1161 new_dentry->d_parent->d_name.name, new_dentry->d_name.name);
1163 ncp_age_dentry(server, old_dentry);
1164 ncp_age_dentry(server, new_dentry);
1166 old_len = sizeof(__old_name);
1167 error = ncp_io2vol(server, __old_name, &old_len,
1168 old_dentry->d_name.name, old_dentry->d_name.len,
1169 !ncp_preserve_case(old_dir));
1173 new_len = sizeof(__new_name);
1174 error = ncp_io2vol(server, __new_name, &new_len,
1175 new_dentry->d_name.name, new_dentry->d_name.len,
1176 !ncp_preserve_case(new_dir));
1180 error = ncp_ren_or_mov_file_or_subdir(server, old_dir, __old_name,
1181 new_dir, __new_name);
1182 #ifdef CONFIG_NCPFS_STRONG
1183 if ((error == 0x90 || error == 0x8B || error == -EACCES) &&
1184 server->m.flags & NCP_MOUNT_STRONG) { /* RO */
1185 error = ncp_force_rename(old_dir, old_dentry, __old_name,
1186 new_dir, new_dentry, __new_name);
1191 DPRINTK("ncp renamed %s -> %s.\n",
1192 old_dentry->d_name.name,new_dentry->d_name.name);
1195 error = -ENAMETOOLONG;
1201 error = error < 0 ? error : -EACCES;
1208 static int ncp_mknod(struct inode * dir, struct dentry *dentry,
1209 int mode, dev_t rdev)
1211 if (!new_valid_dev(rdev))
1213 if (ncp_is_nfs_extras(NCP_SERVER(dir), NCP_FINFO(dir)->volNumber)) {
1214 DPRINTK(KERN_DEBUG "ncp_mknod: mode = 0%o\n", mode);
1215 return ncp_create_new(dir, dentry, mode, rdev, 0);
1217 return -EPERM; /* Strange, but true */
1220 /* The following routines are taken directly from msdos-fs */
1222 /* Linear day numbers of the respective 1sts in non-leap years. */
1224 static int day_n[] =
1225 {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 0, 0, 0, 0};
1226 /* Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec */
1229 extern struct timezone sys_tz;
1231 static int utc2local(int time)
1233 return time - sys_tz.tz_minuteswest * 60;
1236 static int local2utc(int time)
1238 return time + sys_tz.tz_minuteswest * 60;
1241 /* Convert a MS-DOS time/date pair to a UNIX date (seconds since 1 1 70). */
1243 ncp_date_dos2unix(__le16 t, __le16 d)
1245 unsigned short time = le16_to_cpu(t), date = le16_to_cpu(d);
1246 int month, year, secs;
1248 /* first subtract and mask after that... Otherwise, if
1249 date == 0, bad things happen */
1250 month = ((date >> 5) - 1) & 15;
1252 secs = (time & 31) * 2 + 60 * ((time >> 5) & 63) + (time >> 11) * 3600 +
1253 86400 * ((date & 31) - 1 + day_n[month] + (year / 4) +
1254 year * 365 - ((year & 3) == 0 && month < 2 ? 1 : 0) + 3653);
1255 /* days since 1.1.70 plus 80's leap day */
1256 return local2utc(secs);
1260 /* Convert linear UNIX date to a MS-DOS time/date pair. */
1262 ncp_date_unix2dos(int unix_date, __le16 *time, __le16 *date)
1264 int day, year, nl_day, month;
1266 unix_date = utc2local(unix_date);
1267 *time = cpu_to_le16(
1268 (unix_date % 60) / 2 + (((unix_date / 60) % 60) << 5) +
1269 (((unix_date / 3600) % 24) << 11));
1270 day = unix_date / 86400 - 3652;
1272 if ((year + 3) / 4 + 365 * year > day)
1274 day -= (year + 3) / 4 + 365 * year;
1275 if (day == 59 && !(year & 3)) {
1279 nl_day = (year & 3) || day <= 59 ? day : day - 1;
1280 for (month = 1; month < 12; month++)
1281 if (day_n[month] > nl_day)
1284 *date = cpu_to_le16(nl_day - day_n[month - 1] + 1 + (month << 5) + (year << 9));