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 <linux/namei.h>
21 #include <asm/uaccess.h>
22 #include <asm/byteorder.h>
26 static void ncp_read_volume_list(struct file
*, struct dir_context
*,
27 struct ncp_cache_control
*);
28 static void ncp_do_readdir(struct file
*, struct dir_context
*,
29 struct ncp_cache_control
*);
31 static int ncp_readdir(struct file
*, struct dir_context
*);
33 static int ncp_create(struct inode
*, struct dentry
*, umode_t
, bool);
34 static struct dentry
*ncp_lookup(struct inode
*, struct dentry
*, unsigned int);
35 static int ncp_unlink(struct inode
*, struct dentry
*);
36 static int ncp_mkdir(struct inode
*, struct dentry
*, umode_t
);
37 static int ncp_rmdir(struct inode
*, struct dentry
*);
38 static int ncp_rename(struct inode
*, struct dentry
*,
39 struct inode
*, struct dentry
*);
40 static 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)
43 extern int ncp_symlink(struct inode
*, struct dentry
*, const char *);
45 #define ncp_symlink NULL
48 const struct file_operations ncp_dir_operations
=
50 .llseek
= generic_file_llseek
,
51 .read
= generic_read_dir
,
52 .iterate
= ncp_readdir
,
53 .unlocked_ioctl
= ncp_ioctl
,
55 .compat_ioctl
= ncp_compat_ioctl
,
59 const struct inode_operations ncp_dir_inode_operations
=
64 .symlink
= ncp_symlink
,
69 .setattr
= ncp_notify_change
,
73 * Dentry operations routines
75 static int ncp_lookup_validate(struct dentry
*, unsigned int);
76 static int ncp_hash_dentry(const struct dentry
*, struct qstr
*);
77 static int ncp_compare_dentry(const struct dentry
*, const struct dentry
*,
78 unsigned int, const char *, const struct qstr
*);
79 static int ncp_delete_dentry(const struct dentry
*);
81 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 #define ncp_namespace(i) (NCP_SERVER(i)->name_space[NCP_FINFO(i)->volNumber])
91 static inline int ncp_preserve_entry_case(struct inode
*i
, __u32 nscreator
)
93 #ifdef CONFIG_NCPFS_SMALLDOS
94 int ns
= ncp_namespace(i
);
97 #ifdef CONFIG_NCPFS_OS2_NS
98 || ((ns
== NW_NS_OS2
) && (nscreator
== NW_NS_DOS
))
99 #endif /* CONFIG_NCPFS_OS2_NS */
102 #endif /* CONFIG_NCPFS_SMALLDOS */
106 #define ncp_preserve_case(i) (ncp_namespace(i) != NW_NS_DOS)
108 static inline int ncp_case_sensitive(const struct inode
*i
)
110 #ifdef CONFIG_NCPFS_NFS_NS
111 return ncp_namespace(i
) == NW_NS_NFS
;
114 #endif /* CONFIG_NCPFS_NFS_NS */
118 * Note: leave the hash unchanged if the directory
121 * Accessing the parent inode can be racy under RCU pathwalking.
122 * Use ACCESS_ONCE() to make sure we use _one_ particular inode,
123 * the callers will handle races.
126 ncp_hash_dentry(const struct dentry
*dentry
, struct qstr
*this)
128 struct inode
*inode
= ACCESS_ONCE(dentry
->d_inode
);
133 if (!ncp_case_sensitive(inode
)) {
134 struct super_block
*sb
= dentry
->d_sb
;
139 t
= NCP_IO_TABLE(sb
);
140 hash
= init_name_hash();
141 for (i
=0; i
<this->len
; i
++)
142 hash
= partial_name_hash(ncp_tolower(t
, this->name
[i
]),
144 this->hash
= end_name_hash(hash
);
150 * Accessing the parent inode can be racy under RCU pathwalking.
151 * Use ACCESS_ONCE() to make sure we use _one_ particular inode,
152 * the callers will handle races.
155 ncp_compare_dentry(const struct dentry
*parent
, const struct dentry
*dentry
,
156 unsigned int len
, const char *str
, const struct qstr
*name
)
158 struct inode
*pinode
;
160 if (len
!= name
->len
)
163 pinode
= ACCESS_ONCE(parent
->d_inode
);
167 if (ncp_case_sensitive(pinode
))
168 return strncmp(str
, name
->name
, len
);
170 return ncp_strnicmp(NCP_IO_TABLE(pinode
->i_sb
), str
, name
->name
, len
);
174 * This is the callback from dput() when d_count is going to 0.
175 * We use this to unhash dentries with bad inodes.
176 * Closing files can be safely postponed until iput() - it's done there anyway.
179 ncp_delete_dentry(const struct dentry
* dentry
)
181 struct inode
*inode
= dentry
->d_inode
;
184 if (is_bad_inode(inode
))
188 /* N.B. Unhash negative dentries? */
194 ncp_single_volume(struct ncp_server
*server
)
196 return (server
->m
.mounted_vol
[0] != '\0');
199 static inline int ncp_is_server_root(struct inode
*inode
)
201 return (!ncp_single_volume(NCP_SERVER(inode
)) &&
202 inode
== inode
->i_sb
->s_root
->d_inode
);
207 * This is the callback when the dcache has a lookup hit.
211 #ifdef CONFIG_NCPFS_STRONG
212 /* try to delete a readonly file (NW R bit set) */
215 ncp_force_unlink(struct inode
*dir
, struct dentry
* dentry
)
218 struct nw_modify_dos_info info
;
222 memset(&info
, 0, sizeof(info
));
224 /* remove the Read-Only flag on the NW server */
225 inode
= dentry
->d_inode
;
227 old_nwattr
= NCP_FINFO(inode
)->nwattr
;
228 info
.attributes
= old_nwattr
& ~(aRONLY
|aDELETEINHIBIT
|aRENAMEINHIBIT
);
229 res2
= ncp_modify_file_or_subdir_dos_info_path(NCP_SERVER(inode
), inode
, NULL
, DM_ATTRIBUTES
, &info
);
233 /* now try again the delete operation */
234 res
= ncp_del_file_or_subdir2(NCP_SERVER(dir
), dentry
);
236 if (res
) /* delete failed, set R bit again */
238 info
.attributes
= old_nwattr
;
239 res2
= ncp_modify_file_or_subdir_dos_info_path(NCP_SERVER(inode
), inode
, NULL
, DM_ATTRIBUTES
, &info
);
246 #endif /* CONFIG_NCPFS_STRONG */
248 #ifdef CONFIG_NCPFS_STRONG
250 ncp_force_rename(struct inode
*old_dir
, struct dentry
* old_dentry
, char *_old_name
,
251 struct inode
*new_dir
, struct dentry
* new_dentry
, char *_new_name
)
253 struct nw_modify_dos_info info
;
255 struct inode
*old_inode
= old_dentry
->d_inode
;
256 __le32 old_nwattr
= NCP_FINFO(old_inode
)->nwattr
;
257 __le32 new_nwattr
= 0; /* shut compiler warning */
258 int old_nwattr_changed
= 0;
259 int new_nwattr_changed
= 0;
261 memset(&info
, 0, sizeof(info
));
263 /* remove the Read-Only flag on the NW server */
265 info
.attributes
= old_nwattr
& ~(aRONLY
|aRENAMEINHIBIT
|aDELETEINHIBIT
);
266 res2
= ncp_modify_file_or_subdir_dos_info_path(NCP_SERVER(old_inode
), old_inode
, NULL
, DM_ATTRIBUTES
, &info
);
268 old_nwattr_changed
= 1;
269 if (new_dentry
&& new_dentry
->d_inode
) {
270 new_nwattr
= NCP_FINFO(new_dentry
->d_inode
)->nwattr
;
271 info
.attributes
= new_nwattr
& ~(aRONLY
|aRENAMEINHIBIT
|aDELETEINHIBIT
);
272 res2
= ncp_modify_file_or_subdir_dos_info_path(NCP_SERVER(new_dir
), new_dir
, _new_name
, DM_ATTRIBUTES
, &info
);
274 new_nwattr_changed
= 1;
276 /* now try again the rename operation */
277 /* but only if something really happened */
278 if (new_nwattr_changed
|| old_nwattr_changed
) {
279 res
= ncp_ren_or_mov_file_or_subdir(NCP_SERVER(old_dir
),
285 /* file was successfully renamed, so:
286 do not set attributes on old file - it no longer exists
287 copy attributes from old file to new */
288 new_nwattr_changed
= old_nwattr_changed
;
289 new_nwattr
= old_nwattr
;
290 old_nwattr_changed
= 0;
293 if (old_nwattr_changed
) {
294 info
.attributes
= old_nwattr
;
295 res2
= ncp_modify_file_or_subdir_dos_info_path(NCP_SERVER(old_inode
), old_inode
, NULL
, DM_ATTRIBUTES
, &info
);
298 if (new_nwattr_changed
) {
299 info
.attributes
= new_nwattr
;
300 res2
= ncp_modify_file_or_subdir_dos_info_path(NCP_SERVER(new_dir
), new_dir
, _new_name
, DM_ATTRIBUTES
, &info
);
305 #endif /* CONFIG_NCPFS_STRONG */
309 ncp_lookup_validate(struct dentry
*dentry
, unsigned int flags
)
311 struct ncp_server
*server
;
312 struct dentry
*parent
;
314 struct ncp_entry_info finfo
;
315 int res
, val
= 0, len
;
316 __u8 __name
[NCP_MAXPATHLEN
+ 1];
318 if (dentry
== dentry
->d_sb
->s_root
)
321 if (flags
& LOOKUP_RCU
)
324 parent
= dget_parent(dentry
);
325 dir
= parent
->d_inode
;
327 if (!dentry
->d_inode
)
330 server
= NCP_SERVER(dir
);
334 * The default validation is based on dentry age:
335 * We set the max age at mount time. (But each
336 * successful server lookup renews the timestamp.)
338 val
= NCP_TEST_AGE(server
, dentry
);
342 ncp_dbg(2, "%pd2 not valid, age=%ld, server lookup\n",
343 dentry
, NCP_GET_AGE(dentry
));
345 len
= sizeof(__name
);
346 if (ncp_is_server_root(dir
)) {
347 res
= ncp_io2vol(server
, __name
, &len
, dentry
->d_name
.name
,
348 dentry
->d_name
.len
, 1);
350 res
= ncp_lookup_volume(server
, __name
, &(finfo
.i
));
352 ncp_update_known_namespace(server
, finfo
.i
.volNumber
, NULL
);
355 res
= ncp_io2vol(server
, __name
, &len
, dentry
->d_name
.name
,
356 dentry
->d_name
.len
, !ncp_preserve_case(dir
));
358 res
= ncp_obtain_info(server
, dir
, __name
, &(finfo
.i
));
360 finfo
.volume
= finfo
.i
.volNumber
;
361 ncp_dbg(2, "looked for %pd/%s, res=%d\n",
362 dentry
->d_parent
, __name
, res
);
364 * If we didn't find it, or if it has a different dirEntNum to
365 * what we remember, it's not valid any more.
368 struct inode
*inode
= dentry
->d_inode
;
370 mutex_lock(&inode
->i_mutex
);
371 if (finfo
.i
.dirEntNum
== NCP_FINFO(inode
)->dirEntNum
) {
372 ncp_new_dentry(dentry
);
375 ncp_dbg(2, "found, but dirEntNum changed\n");
377 ncp_update_inode2(inode
, &finfo
);
378 mutex_unlock(&inode
->i_mutex
);
382 ncp_dbg(2, "result=%d\n", val
);
387 static struct dentry
*
388 ncp_dget_fpos(struct dentry
*dentry
, struct dentry
*parent
, unsigned long fpos
)
390 struct dentry
*dent
= dentry
;
391 struct list_head
*next
;
393 if (d_validate(dent
, parent
)) {
394 if (dent
->d_name
.len
<= NCP_MAXPATHLEN
&&
395 (unsigned long)dent
->d_fsdata
== fpos
) {
396 if (!dent
->d_inode
) {
405 /* If a pointer is invalid, we search the dentry. */
406 spin_lock(&parent
->d_lock
);
407 next
= parent
->d_subdirs
.next
;
408 while (next
!= &parent
->d_subdirs
) {
409 dent
= list_entry(next
, struct dentry
, d_u
.d_child
);
410 if ((unsigned long)dent
->d_fsdata
== fpos
) {
415 spin_unlock(&parent
->d_lock
);
420 spin_unlock(&parent
->d_lock
);
427 static time_t ncp_obtain_mtime(struct dentry
*dentry
)
429 struct inode
*inode
= dentry
->d_inode
;
430 struct ncp_server
*server
= NCP_SERVER(inode
);
431 struct nw_info_struct i
;
433 if (!ncp_conn_valid(server
) || ncp_is_server_root(inode
))
436 if (ncp_obtain_info(server
, inode
, NULL
, &i
))
439 return ncp_date_dos2unix(i
.modifyTime
, i
.modifyDate
);
442 static int ncp_readdir(struct file
*file
, struct dir_context
*ctx
)
444 struct dentry
*dentry
= file
->f_path
.dentry
;
445 struct inode
*inode
= dentry
->d_inode
;
446 struct page
*page
= NULL
;
447 struct ncp_server
*server
= NCP_SERVER(inode
);
448 union ncp_dir_cache
*cache
= NULL
;
449 struct ncp_cache_control ctl
;
450 int result
, mtime_valid
= 0;
456 ncp_dbg(2, "reading %pD2, pos=%d\n", file
, (int)ctx
->pos
);
459 /* Do not generate '.' and '..' when server is dead. */
460 if (!ncp_conn_valid(server
))
464 if (!dir_emit_dots(file
, ctx
))
467 page
= grab_cache_page(&inode
->i_data
, 0);
471 ctl
.cache
= cache
= kmap(page
);
472 ctl
.head
= cache
->head
;
474 if (!PageUptodate(page
) || !ctl
.head
.eof
)
478 if (jiffies
- ctl
.head
.time
>= NCP_MAX_AGE(server
))
481 mtime
= ncp_obtain_mtime(dentry
);
483 if ((!mtime
) || (mtime
!= ctl
.head
.mtime
))
487 if (ctx
->pos
> ctl
.head
.end
)
490 ctl
.fpos
= ctx
->pos
+ (NCP_DIRCACHE_START
- 2);
491 ctl
.ofs
= ctl
.fpos
/ NCP_DIRCACHE_SIZE
;
492 ctl
.idx
= ctl
.fpos
% NCP_DIRCACHE_SIZE
;
496 ctl
.page
= find_lock_page(&inode
->i_data
, ctl
.ofs
);
499 ctl
.cache
= kmap(ctl
.page
);
500 if (!PageUptodate(ctl
.page
))
503 while (ctl
.idx
< NCP_DIRCACHE_SIZE
) {
507 dent
= ncp_dget_fpos(ctl
.cache
->dentry
[ctl
.idx
],
511 over
= !dir_emit(ctx
, dent
->d_name
.name
,
513 dent
->d_inode
->i_ino
, DT_UNKNOWN
);
519 if (ctx
->pos
> ctl
.head
.end
)
524 SetPageUptodate(ctl
.page
);
525 unlock_page(ctl
.page
);
526 page_cache_release(ctl
.page
);
535 unlock_page(ctl
.page
);
536 page_cache_release(ctl
.page
);
541 ncp_invalidate_dircache_entries(dentry
);
543 mtime
= ncp_obtain_mtime(dentry
);
546 ctl
.head
.mtime
= mtime
;
547 ctl
.head
.time
= jiffies
;
551 ctl
.idx
= NCP_DIRCACHE_START
;
555 if (ncp_is_server_root(inode
)) {
556 ncp_read_volume_list(file
, ctx
, &ctl
);
558 ncp_do_readdir(file
, ctx
, &ctl
);
560 ctl
.head
.end
= ctl
.fpos
- 1;
561 ctl
.head
.eof
= ctl
.valid
;
565 SetPageUptodate(ctl
.page
);
566 unlock_page(ctl
.page
);
567 page_cache_release(ctl
.page
);
570 cache
->head
= ctl
.head
;
572 SetPageUptodate(page
);
574 page_cache_release(page
);
581 ncp_fill_cache(struct file
*file
, struct dir_context
*ctx
,
582 struct ncp_cache_control
*ctrl
, struct ncp_entry_info
*entry
,
585 struct dentry
*newdent
, *dentry
= file
->f_path
.dentry
;
586 struct inode
*dir
= dentry
->d_inode
;
587 struct ncp_cache_control ctl
= *ctrl
;
592 __u8 __name
[NCP_MAXPATHLEN
+ 1];
594 qname
.len
= sizeof(__name
);
595 if (ncp_vol2io(NCP_SERVER(dir
), __name
, &qname
.len
,
596 entry
->i
.entryName
, entry
->i
.nameLen
,
597 !ncp_preserve_entry_case(dir
, entry
->i
.NSCreator
)))
598 return 1; /* I'm not sure */
602 newdent
= d_hash_and_lookup(dentry
, &qname
);
603 if (unlikely(IS_ERR(newdent
)))
606 newdent
= d_alloc(dentry
, &qname
);
612 /* If case sensitivity changed for this volume, all entries below this one
613 should be thrown away. This entry itself is not affected, as its case
614 sensitivity is controlled by its own parent. */
616 shrink_dcache_parent(newdent
);
619 * NetWare's OS2 namespace is case preserving yet case
620 * insensitive. So we update dentry's name as received from
621 * server. Parent dir's i_mutex is locked because we're in
624 dentry_update_name_case(newdent
, &qname
);
627 if (!newdent
->d_inode
) {
631 entry
->ino
= iunique(dir
->i_sb
, 2);
632 inode
= ncp_iget(dir
->i_sb
, entry
);
634 d_instantiate(newdent
, inode
);
639 struct inode
*inode
= newdent
->d_inode
;
641 mutex_lock_nested(&inode
->i_mutex
, I_MUTEX_CHILD
);
642 ncp_update_inode2(inode
, entry
);
643 mutex_unlock(&inode
->i_mutex
);
646 if (newdent
->d_inode
) {
647 ino
= newdent
->d_inode
->i_ino
;
648 newdent
->d_fsdata
= (void *) ctl
.fpos
;
649 ncp_new_dentry(newdent
);
652 if (ctl
.idx
>= NCP_DIRCACHE_SIZE
) {
655 SetPageUptodate(ctl
.page
);
656 unlock_page(ctl
.page
);
657 page_cache_release(ctl
.page
);
660 ctl
.idx
-= NCP_DIRCACHE_SIZE
;
662 ctl
.page
= grab_cache_page(&dir
->i_data
, ctl
.ofs
);
664 ctl
.cache
= kmap(ctl
.page
);
667 ctl
.cache
->dentry
[ctl
.idx
] = newdent
;
674 if (!ctl
.filled
&& (ctl
.fpos
== ctx
->pos
)) {
676 ino
= iunique(dir
->i_sb
, 2);
677 ctl
.filled
= !dir_emit(ctx
, qname
.name
, qname
.len
,
685 return (ctl
.valid
|| !ctl
.filled
);
689 ncp_read_volume_list(struct file
*file
, struct dir_context
*ctx
,
690 struct ncp_cache_control
*ctl
)
692 struct dentry
*dentry
= file
->f_path
.dentry
;
693 struct inode
*inode
= dentry
->d_inode
;
694 struct ncp_server
*server
= NCP_SERVER(inode
);
695 struct ncp_volume_info info
;
696 struct ncp_entry_info entry
;
699 ncp_dbg(1, "pos=%ld\n", (unsigned long)ctx
->pos
);
701 for (i
= 0; i
< NCP_NUMBER_OF_VOLUMES
; i
++) {
704 if (ncp_get_volume_info_with_number(server
, i
, &info
) != 0)
706 if (!strlen(info
.volume_name
))
709 ncp_dbg(1, "found vol: %s\n", info
.volume_name
);
711 if (ncp_lookup_volume(server
, info
.volume_name
,
713 ncp_dbg(1, "could not lookup vol %s\n",
717 inval_dentry
= ncp_update_known_namespace(server
, entry
.i
.volNumber
, NULL
);
718 entry
.volume
= entry
.i
.volNumber
;
719 if (!ncp_fill_cache(file
, ctx
, ctl
, &entry
, inval_dentry
))
725 ncp_do_readdir(struct file
*file
, struct dir_context
*ctx
,
726 struct ncp_cache_control
*ctl
)
728 struct dentry
*dentry
= file
->f_path
.dentry
;
729 struct inode
*dir
= dentry
->d_inode
;
730 struct ncp_server
*server
= NCP_SERVER(dir
);
731 struct nw_search_sequence seq
;
732 struct ncp_entry_info entry
;
738 ncp_dbg(1, "%pD2, fpos=%ld\n", file
, (unsigned long)ctx
->pos
);
739 ncp_vdbg("init %pD, volnum=%d, dirent=%u\n",
740 file
, NCP_FINFO(dir
)->volNumber
, NCP_FINFO(dir
)->dirEntNum
);
742 err
= ncp_initialize_search(server
, dir
, &seq
);
744 ncp_dbg(1, "init failed, err=%d\n", err
);
747 /* We MUST NOT use server->buffer_size handshaked with server if we are
748 using UDP, as for UDP server uses max. buffer size determined by
749 MTU, and for TCP server uses hardwired value 65KB (== 66560 bytes).
750 So we use 128KB, just to be sure, as there is no way how to know
751 this value in advance. */
753 buf
= vmalloc(bufsize
);
761 err
= ncp_search_for_fileset(server
, &seq
, &more
, &cnt
, buf
, bufsize
, &rpl
, &rpls
);
764 if (!cnt
) /* prevent endless loop */
769 if (rpls
< offsetof(struct nw_info_struct
, entryName
))
770 break; /* short packet */
771 ncp_extract_file_info(rpl
, &entry
.i
);
772 onerpl
= offsetof(struct nw_info_struct
, entryName
) + entry
.i
.nameLen
;
774 break; /* short packet */
775 (void)ncp_obtain_nfs_info(server
, &entry
.i
);
778 entry
.volume
= entry
.i
.volNumber
;
779 if (!ncp_fill_cache(file
, ctx
, ctl
, &entry
, 0))
787 int ncp_conn_logged_in(struct super_block
*sb
)
789 struct ncp_server
* server
= NCP_SBP(sb
);
792 if (ncp_single_volume(server
)) {
798 __u8 __name
[NCP_MAXPATHLEN
+ 1];
800 len
= sizeof(__name
);
801 result
= ncp_io2vol(server
, __name
, &len
, server
->m
.mounted_vol
,
802 strlen(server
->m
.mounted_vol
), 1);
806 if (ncp_get_volume_root(server
, __name
, &volNumber
, &dirEntNum
, &DosDirNum
)) {
807 ncp_vdbg("%s not found\n", server
->m
.mounted_vol
);
812 struct inode
* ino
= dent
->d_inode
;
814 ncp_update_known_namespace(server
, volNumber
, NULL
);
815 NCP_FINFO(ino
)->volNumber
= volNumber
;
816 NCP_FINFO(ino
)->dirEntNum
= dirEntNum
;
817 NCP_FINFO(ino
)->DosDirNum
= DosDirNum
;
820 ncp_dbg(1, "sb->s_root->d_inode == NULL!\n");
823 ncp_dbg(1, "sb->s_root == NULL!\n");
832 static struct dentry
*ncp_lookup(struct inode
*dir
, struct dentry
*dentry
, unsigned int flags
)
834 struct ncp_server
*server
= NCP_SERVER(dir
);
835 struct inode
*inode
= NULL
;
836 struct ncp_entry_info finfo
;
838 __u8 __name
[NCP_MAXPATHLEN
+ 1];
841 if (!ncp_conn_valid(server
))
844 ncp_vdbg("server lookup for %pd2\n", dentry
);
846 len
= sizeof(__name
);
847 if (ncp_is_server_root(dir
)) {
848 res
= ncp_io2vol(server
, __name
, &len
, dentry
->d_name
.name
,
849 dentry
->d_name
.len
, 1);
851 res
= ncp_lookup_volume(server
, __name
, &(finfo
.i
));
853 ncp_update_known_namespace(server
, finfo
.i
.volNumber
, NULL
);
855 res
= ncp_io2vol(server
, __name
, &len
, dentry
->d_name
.name
,
856 dentry
->d_name
.len
, !ncp_preserve_case(dir
));
858 res
= ncp_obtain_info(server
, dir
, __name
, &(finfo
.i
));
860 ncp_vdbg("looked for %pd2, res=%d\n", dentry
, res
);
862 * If we didn't find an entry, make a negative dentry.
868 * Create an inode for the entry.
871 finfo
.ino
= iunique(dir
->i_sb
, 2);
872 finfo
.volume
= finfo
.i
.volNumber
;
874 inode
= ncp_iget(dir
->i_sb
, &finfo
);
877 ncp_new_dentry(dentry
);
879 d_add(dentry
, inode
);
884 ncp_vdbg("result=%d\n", error
);
885 return ERR_PTR(error
);
889 * This code is common to create, mkdir, and mknod.
891 static int ncp_instantiate(struct inode
*dir
, struct dentry
*dentry
,
892 struct ncp_entry_info
*finfo
)
897 finfo
->ino
= iunique(dir
->i_sb
, 2);
898 inode
= ncp_iget(dir
->i_sb
, finfo
);
901 d_instantiate(dentry
,inode
);
907 ncp_vdbg("%pd2 failed, closing file\n", dentry
);
908 ncp_close_file(NCP_SERVER(dir
), finfo
->file_handle
);
912 int ncp_create_new(struct inode
*dir
, struct dentry
*dentry
, umode_t mode
,
913 dev_t rdev
, __le32 attributes
)
915 struct ncp_server
*server
= NCP_SERVER(dir
);
916 struct ncp_entry_info finfo
;
917 int error
, result
, len
;
919 __u8 __name
[NCP_MAXPATHLEN
+ 1];
921 ncp_vdbg("creating %pd2, mode=%hx\n", dentry
, mode
);
923 ncp_age_dentry(server
, dentry
);
924 len
= sizeof(__name
);
925 error
= ncp_io2vol(server
, __name
, &len
, dentry
->d_name
.name
,
926 dentry
->d_name
.len
, !ncp_preserve_case(dir
));
933 (server
->m
.flags
& NCP_MOUNT_EXTRAS
) &&
935 attributes
|= aSYSTEM
| aSHARED
;
937 result
= ncp_open_create_file_or_subdir(server
, dir
, __name
,
938 OC_MODE_CREATE
| OC_MODE_OPEN
| OC_MODE_REPLACE
,
939 attributes
, AR_READ
| AR_WRITE
, &finfo
);
942 result
= ncp_open_create_file_or_subdir(server
, dir
, __name
,
943 OC_MODE_CREATE
| OC_MODE_OPEN
| OC_MODE_REPLACE
,
944 attributes
, AR_WRITE
, &finfo
);
947 error
= -ENAMETOOLONG
;
950 ncp_dbg(1, "%pd2 failed\n", dentry
);
955 finfo
.access
= opmode
;
956 if (ncp_is_nfs_extras(server
, finfo
.volume
)) {
957 finfo
.i
.nfs
.mode
= mode
;
958 finfo
.i
.nfs
.rdev
= new_encode_dev(rdev
);
959 if (ncp_modify_nfs_info(server
, finfo
.volume
,
961 mode
, new_encode_dev(rdev
)) != 0)
965 error
= ncp_instantiate(dir
, dentry
, &finfo
);
970 static int ncp_create(struct inode
*dir
, struct dentry
*dentry
, umode_t mode
,
973 return ncp_create_new(dir
, dentry
, mode
, 0, 0);
976 static int ncp_mkdir(struct inode
*dir
, struct dentry
*dentry
, umode_t mode
)
978 struct ncp_entry_info finfo
;
979 struct ncp_server
*server
= NCP_SERVER(dir
);
981 __u8 __name
[NCP_MAXPATHLEN
+ 1];
983 ncp_dbg(1, "making %pd2\n", dentry
);
985 ncp_age_dentry(server
, dentry
);
986 len
= sizeof(__name
);
987 error
= ncp_io2vol(server
, __name
, &len
, dentry
->d_name
.name
,
988 dentry
->d_name
.len
, !ncp_preserve_case(dir
));
992 error
= ncp_open_create_file_or_subdir(server
, dir
, __name
,
993 OC_MODE_CREATE
, aDIR
,
997 if (ncp_is_nfs_extras(server
, finfo
.volume
)) {
999 finfo
.i
.nfs
.mode
= mode
;
1000 if (ncp_modify_nfs_info(server
,
1006 error
= ncp_instantiate(dir
, dentry
, &finfo
);
1007 } else if (error
> 0) {
1014 static int ncp_rmdir(struct inode
*dir
, struct dentry
*dentry
)
1016 struct ncp_server
*server
= NCP_SERVER(dir
);
1017 int error
, result
, len
;
1018 __u8 __name
[NCP_MAXPATHLEN
+ 1];
1020 ncp_dbg(1, "removing %pd2\n", dentry
);
1022 len
= sizeof(__name
);
1023 error
= ncp_io2vol(server
, __name
, &len
, dentry
->d_name
.name
,
1024 dentry
->d_name
.len
, !ncp_preserve_case(dir
));
1028 result
= ncp_del_file_or_subdir(server
, dir
, __name
);
1033 case 0x85: /* unauthorized to delete file */
1034 case 0x8A: /* unauthorized to delete file */
1038 case 0x90: /* read only */
1041 case 0x9F: /* in use by another client */
1044 case 0xA0: /* directory not empty */
1047 case 0xFF: /* someone deleted file */
1051 error
= result
< 0 ? result
: -EACCES
;
1058 static int ncp_unlink(struct inode
*dir
, struct dentry
*dentry
)
1060 struct inode
*inode
= dentry
->d_inode
;
1061 struct ncp_server
*server
;
1064 server
= NCP_SERVER(dir
);
1065 ncp_dbg(1, "unlinking %pd2\n", dentry
);
1068 * Check whether to close the file ...
1071 ncp_vdbg("closing file\n");
1072 ncp_make_closed(inode
);
1075 error
= ncp_del_file_or_subdir2(server
, dentry
);
1076 #ifdef CONFIG_NCPFS_STRONG
1077 /* 9C is Invalid path.. It should be 8F, 90 - read only, but
1079 if ((error
== 0x9C || error
== 0x90) && server
->m
.flags
& NCP_MOUNT_STRONG
) { /* R/O */
1080 error
= ncp_force_unlink(dir
, dentry
);
1085 ncp_dbg(1, "removed %pd2\n", dentry
);
1091 case 0x8D: /* some files in use */
1092 case 0x8E: /* all files in use */
1095 case 0x8F: /* some read only */
1096 case 0x90: /* all read only */
1097 case 0x9C: /* !!! returned when in-use or read-only by NW4 */
1104 error
= error
< 0 ? error
: -EACCES
;
1110 static int ncp_rename(struct inode
*old_dir
, struct dentry
*old_dentry
,
1111 struct inode
*new_dir
, struct dentry
*new_dentry
)
1113 struct ncp_server
*server
= NCP_SERVER(old_dir
);
1115 int old_len
, new_len
;
1116 __u8 __old_name
[NCP_MAXPATHLEN
+ 1], __new_name
[NCP_MAXPATHLEN
+ 1];
1118 ncp_dbg(1, "%pd2 to %pd2\n", old_dentry
, new_dentry
);
1120 ncp_age_dentry(server
, old_dentry
);
1121 ncp_age_dentry(server
, new_dentry
);
1123 old_len
= sizeof(__old_name
);
1124 error
= ncp_io2vol(server
, __old_name
, &old_len
,
1125 old_dentry
->d_name
.name
, old_dentry
->d_name
.len
,
1126 !ncp_preserve_case(old_dir
));
1130 new_len
= sizeof(__new_name
);
1131 error
= ncp_io2vol(server
, __new_name
, &new_len
,
1132 new_dentry
->d_name
.name
, new_dentry
->d_name
.len
,
1133 !ncp_preserve_case(new_dir
));
1137 error
= ncp_ren_or_mov_file_or_subdir(server
, old_dir
, __old_name
,
1138 new_dir
, __new_name
);
1139 #ifdef CONFIG_NCPFS_STRONG
1140 if ((error
== 0x90 || error
== 0x8B || error
== -EACCES
) &&
1141 server
->m
.flags
& NCP_MOUNT_STRONG
) { /* RO */
1142 error
= ncp_force_rename(old_dir
, old_dentry
, __old_name
,
1143 new_dir
, new_dentry
, __new_name
);
1148 ncp_dbg(1, "renamed %pd -> %pd\n",
1149 old_dentry
, new_dentry
);
1152 error
= -ENAMETOOLONG
;
1158 error
= error
< 0 ? error
: -EACCES
;
1165 static int ncp_mknod(struct inode
* dir
, struct dentry
*dentry
,
1166 umode_t mode
, dev_t rdev
)
1168 if (!new_valid_dev(rdev
))
1170 if (ncp_is_nfs_extras(NCP_SERVER(dir
), NCP_FINFO(dir
)->volNumber
)) {
1171 ncp_dbg(1, "mode = 0%ho\n", mode
);
1172 return ncp_create_new(dir
, dentry
, mode
, rdev
, 0);
1174 return -EPERM
; /* Strange, but true */
1177 /* The following routines are taken directly from msdos-fs */
1179 /* Linear day numbers of the respective 1sts in non-leap years. */
1181 static int day_n
[] =
1182 {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 0, 0, 0, 0};
1183 /* Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec */
1186 extern struct timezone sys_tz
;
1188 static int utc2local(int time
)
1190 return time
- sys_tz
.tz_minuteswest
* 60;
1193 static int local2utc(int time
)
1195 return time
+ sys_tz
.tz_minuteswest
* 60;
1198 /* Convert a MS-DOS time/date pair to a UNIX date (seconds since 1 1 70). */
1200 ncp_date_dos2unix(__le16 t
, __le16 d
)
1202 unsigned short time
= le16_to_cpu(t
), date
= le16_to_cpu(d
);
1203 int month
, year
, secs
;
1205 /* first subtract and mask after that... Otherwise, if
1206 date == 0, bad things happen */
1207 month
= ((date
>> 5) - 1) & 15;
1209 secs
= (time
& 31) * 2 + 60 * ((time
>> 5) & 63) + (time
>> 11) * 3600 +
1210 86400 * ((date
& 31) - 1 + day_n
[month
] + (year
/ 4) +
1211 year
* 365 - ((year
& 3) == 0 && month
< 2 ? 1 : 0) + 3653);
1212 /* days since 1.1.70 plus 80's leap day */
1213 return local2utc(secs
);
1217 /* Convert linear UNIX date to a MS-DOS time/date pair. */
1219 ncp_date_unix2dos(int unix_date
, __le16
*time
, __le16
*date
)
1221 int day
, year
, nl_day
, month
;
1223 unix_date
= utc2local(unix_date
);
1224 *time
= cpu_to_le16(
1225 (unix_date
% 60) / 2 + (((unix_date
/ 60) % 60) << 5) +
1226 (((unix_date
/ 3600) % 24) << 11));
1227 day
= unix_date
/ 86400 - 3652;
1229 if ((year
+ 3) / 4 + 365 * year
> day
)
1231 day
-= (year
+ 3) / 4 + 365 * year
;
1232 if (day
== 59 && !(year
& 3)) {
1236 nl_day
= (year
& 3) || day
<= 59 ? day
: day
- 1;
1237 for (month
= 1; month
< 12; month
++)
1238 if (day_n
[month
] > nl_day
)
1241 *date
= cpu_to_le16(nl_day
- day_n
[month
- 1] + 1 + (month
<< 5) + (year
<< 9));