diff options
author | Ralf Baechle <ralf@linux-mips.org> | 2000-01-29 01:41:54 +0000 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2000-01-29 01:41:54 +0000 |
commit | f969d69ba9f952e5bdd38278e25e26a3e4a61a70 (patch) | |
tree | b3530d803df59d726afaabebc6626987dee1ca05 /fs/ncpfs | |
parent | a10ce7ef2066b455d69187643ddf2073bfc4db24 (diff) |
Merge with 2.3.27.
Diffstat (limited to 'fs/ncpfs')
-rw-r--r-- | fs/ncpfs/dir.c | 692 | ||||
-rw-r--r-- | fs/ncpfs/file.c | 26 | ||||
-rw-r--r-- | fs/ncpfs/inode.c | 48 | ||||
-rw-r--r-- | fs/ncpfs/ioctl.c | 12 | ||||
-rw-r--r-- | fs/ncpfs/mmap.c | 23 | ||||
-rw-r--r-- | fs/ncpfs/ncplib_kernel.c | 32 | ||||
-rw-r--r-- | fs/ncpfs/ncplib_kernel.h | 73 | ||||
-rw-r--r-- | fs/ncpfs/sock.c | 28 | ||||
-rw-r--r-- | fs/ncpfs/symlink.c | 6 |
9 files changed, 519 insertions, 421 deletions
diff --git a/fs/ncpfs/dir.c b/fs/ncpfs/dir.c index d3af541dd..4ed7a9abe 100644 --- a/fs/ncpfs/dir.c +++ b/fs/ncpfs/dir.c @@ -26,8 +26,10 @@ #include "ncplib_kernel.h" -static int ncp_read_volume_list(struct file *, void *, filldir_t); -static int ncp_do_readdir(struct file *, void *, filldir_t); +static void ncp_read_volume_list(struct file *, void *, filldir_t, + struct ncp_cache_control *); +static void ncp_do_readdir(struct file *, void *, filldir_t, + struct ncp_cache_control *); static ssize_t ncp_dir_read(struct file *, char *, size_t, loff_t *); static int ncp_readdir(struct file *, void *, filldir_t); @@ -171,10 +173,8 @@ ncp_delete_dentry(struct dentry * dentry) * (Somebody might have used it again ...) */ if (dentry->d_count == 1 && NCP_FINFO(inode)->opened) { -#ifdef NCPFS_PARANOIA -printk(KERN_DEBUG "ncp_delete_dentry: closing file %s/%s\n", -dentry->d_parent->d_name.name, dentry->d_name.name); -#endif + PPRINTK("ncp_delete_dentry: closing file %s/%s\n", + dentry->d_parent->d_name.name, dentry->d_name.name); ncp_make_closed(inode); } } else @@ -310,7 +310,7 @@ ncp_lookup_validate(struct dentry * dentry, int flags) if (!dentry->d_inode || !dir) goto finished; - + server = NCP_SERVER(dir); if (!ncp_conn_valid(server)) @@ -325,19 +325,18 @@ ncp_lookup_validate(struct dentry * dentry, int flags) val = NCP_TEST_AGE(server, dentry); if (val) goto finished; -#ifdef NCPFS_PARANOIA - printk(KERN_DEBUG "ncp_lookup_validate: %s/%s not valid, age=%ld\n", + + PPRINTK("ncp_lookup_validate: %s/%s not valid, age=%ld\n", dentry->d_parent->d_name.name, dentry->d_name.name, NCP_GET_AGE(dentry)); -#endif memcpy(__name, dentry->d_name.name, len); __name[len] = '\0'; -#ifdef NCPFS_PARANOIA -printk(KERN_DEBUG "ncp_lookup_validate: %s, len %d\n", __name, len); -printk(KERN_DEBUG "ncp_lookup_validate: server lookup for %s/%s\n", -dentry->d_parent->d_name.name, __name); -#endif + + PPRINTK("ncp_lookup_validate: %s, len %d\n", __name, len); + PPRINTK("ncp_lookup_validate: server lookup for %s/%s\n", + dentry->d_parent->d_name.name, __name); + if (ncp_is_server_root(dir)) { io2vol(server, __name, 1); res = ncp_lookup_volume(server, __name, &(finfo.i)); @@ -345,10 +344,8 @@ dentry->d_parent->d_name.name, __name); io2vol(server, __name, !ncp_preserve_case(dir)); res = ncp_obtain_info(server, dir, __name, &(finfo.i)); } -#ifdef NCPFS_PARANOIA -printk(KERN_DEBUG "ncp_lookup_validate: looked for %s/%s, res=%d\n", -dentry->d_parent->d_name.name, __name, res); -#endif + PPRINTK("ncp_lookup_validate: looked for %s/%s, res=%d\n", + dentry->d_parent->d_name.name, __name, res); /* * If we didn't find it, or if it has a different dirEntNum to * what we remember, it's not valid any more. @@ -356,359 +353,435 @@ dentry->d_parent->d_name.name, __name, res); if (!res) { if (finfo.i.dirEntNum == NCP_FINFO(dentry->d_inode)->dirEntNum) val=1; -#ifdef NCPFS_PARANOIA else - printk(KERN_DEBUG "ncp_lookup_validate: found, but dirEntNum changed\n"); -#endif + PPRINTK("ncp_lookup_validate: found, but dirEntNum changed\n"); + vol2io(server, finfo.i.entryName, !ncp_preserve_entry_case(dir, finfo.i.NSCreator)); ncp_update_inode2(dentry->d_inode, &finfo); - ncp_new_dentry(dentry); + if (val) + ncp_new_dentry(dentry); } finished: -#ifdef NCPFS_PARANOIA -printk(KERN_DEBUG "ncp_lookup_validate: result=%d\n", val); -#endif - + PPRINTK("ncp_lookup_validate: result=%d\n", val); return val; } +static struct page * +ncp_get_cache_page(struct inode *inode, unsigned long offset, int used) +{ + struct address_space *i_data = &inode->i_data; + struct page *new_page, *page, **hash; + + hash = page_hash(i_data, offset); + + page = __find_lock_page(i_data, offset, hash); + if (used || page) + return page; + + new_page = page_cache_alloc(); + if (!new_page) + return NULL; + + for (;;) { + page = new_page; + if (!add_to_page_cache_unique(page, i_data, offset, hash)) + break; + page_cache_release(page); + page = __find_lock_page(i_data, offset, hash); + if (page) { + page_cache_free(new_page); + break; + } + } + + return page; +} + +/* most parts from nfsd_d_validate() */ +static int +ncp_d_validate(struct dentry *dentry) +{ + unsigned long dent_addr = (unsigned long) dentry; + unsigned long min_addr = PAGE_OFFSET; + unsigned long align_mask = 0x0F; + unsigned int len; + int valid = 0; + + if (dent_addr < min_addr) + goto bad_addr; + if (dent_addr > (unsigned long)high_memory - sizeof(struct dentry)) + goto bad_addr; + if ((dent_addr & ~align_mask) != dent_addr) + goto bad_align; + if (!kern_addr_valid(dent_addr)) + goto bad_addr; + /* + * Looks safe enough to dereference ... + */ + len = dentry->d_name.len; + if (len > NCP_MAXPATHLEN) + goto out; + /* + * Note: d_validate doesn't dereference the parent pointer ... + * just combines it with the name hash to find the hash chain. + */ + valid = d_validate(dentry, dentry->d_parent, dentry->d_name.hash, len); +out: + return valid; + +bad_addr: + PRINTK("ncp_d_validate: invalid address %lx\n", dent_addr); + goto out; +bad_align: + PRINTK("ncp_d_validate: unaligned address %lx\n", dent_addr); + goto out; +} + +static struct dentry * +ncp_dget_fpos(struct dentry *dentry, struct dentry *parent, unsigned long fpos) +{ + struct dentry *dent = dentry; + struct list_head *next; + + if (ncp_d_validate(dent)) + if ((dent->d_parent == parent) && + ((unsigned long)dent->d_fsdata == fpos)) + goto out; + + /* If a pointer is invalid, we search the dentry. */ + next = parent->d_subdirs.next; + while (next != &parent->d_subdirs) { + dent = list_entry(next, struct dentry, d_child); + if ((unsigned long)dent->d_fsdata == fpos) + goto out; + next = next->next; + } + dent = NULL; +out: + if (dent) + if (dent->d_inode) + return dget(dent); + return NULL; +} + +static time_t ncp_obtain_mtime(struct dentry *dentry) +{ + struct inode *inode = dentry->d_inode; + struct ncp_server *server = NCP_SERVER(inode); + struct nw_info_struct i; + + if (!ncp_conn_valid(server) || + ncp_is_server_root(inode)) + return 0; + + if (ncp_obtain_info(server, inode, NULL, &i)) + return 0; + + return ncp_date_dos2unix(le16_to_cpu(i.modifyTime), + le16_to_cpu(i.modifyDate)); +} static int ncp_readdir(struct file *filp, void *dirent, filldir_t filldir) { struct dentry *dentry = filp->f_dentry; struct inode *inode = dentry->d_inode; + struct page *page = NULL; struct ncp_server *server = NCP_SERVER(inode); - int entries, result; + union ncp_dir_cache *cache = NULL; + struct ncp_cache_control ctl; + int result, mtime_valid = 0; + time_t mtime = 0; - DDPRINTK(KERN_DEBUG "ncp_readdir: reading %s/%s, pos=%d\n", + ctl.page = NULL; + ctl.cache = NULL; + + DDPRINTK("ncp_readdir: reading %s/%s, pos=%d\n", dentry->d_parent->d_name.name, dentry->d_name.name, (int) filp->f_pos); result = -EIO; if (!ncp_conn_valid(server)) - goto finished; + goto out; result = 0; if (filp->f_pos == 0) { if (filldir(dirent, ".", 1, 0, inode->i_ino)) - goto finished; + goto out; filp->f_pos = 1; } if (filp->f_pos == 1) { if (filldir(dirent, "..", 2, 1, dentry->d_parent->d_inode->i_ino)) - goto finished; + goto out; filp->f_pos = 2; } - if (ncp_is_server_root(inode)) { - entries = ncp_read_volume_list(filp, dirent, filldir); - DPRINTK(KERN_DEBUG "ncp_read_volume_list returned %d\n", entries); - } else { - entries = ncp_do_readdir(filp, dirent, filldir); - DPRINTK(KERN_DEBUG "ncp_readdir: returned %d\n", entries); + page = ncp_get_cache_page(inode, 0, 0); + if (!page) + goto read_really; + + ctl.cache = cache = (union ncp_dir_cache *) page_address(page); + ctl.head = cache->head; + + if (!Page_Uptodate(page) || !ctl.head.eof) + goto init_cache; + + if (filp->f_pos == 2) { + if (jiffies - ctl.head.time >= NCP_MAX_AGE(server)) + goto init_cache; + + mtime = ncp_obtain_mtime(dentry); + mtime_valid = 1; + if ((!mtime) || (mtime != ctl.head.mtime)) + goto init_cache; } - if (entries < 0) - result = entries; + if (filp->f_pos > ctl.head.end) + goto finished; + + ctl.fpos = filp->f_pos + (NCP_DIRCACHE_START - 2); + ctl.ofs = ctl.fpos / NCP_DIRCACHE_SIZE; + ctl.idx = ctl.fpos % NCP_DIRCACHE_SIZE; + for (;;) { + if (ctl.ofs != 0) { + ctl.page = ncp_get_cache_page(inode, ctl.ofs, 1); + if (!ctl.page) + goto invalid_cache; + if (!Page_Uptodate(ctl.page)) + goto invalid_cache; + ctl.cache = (union ncp_dir_cache *) + page_address(ctl.page); + } + while (ctl.idx < NCP_DIRCACHE_SIZE) { + struct dentry *dent; + int res; + + dent = ncp_dget_fpos(ctl.cache->dentry[ctl.idx], + dentry, filp->f_pos); + if (!dent) + goto invalid_cache; + res = filldir(dirent, dent->d_name.name, + dent->d_name.len, filp->f_pos, + dent->d_inode->i_ino); + dput(dent); + if (res) + goto finished; + filp->f_pos += 1; + ctl.idx += 1; + if (filp->f_pos > ctl.head.end) + goto finished; + } + if (ctl.page) { + SetPageUptodate(ctl.page); + UnlockPage(ctl.page); + page_cache_release(ctl.page); + ctl.page = NULL; + } + ctl.idx = 0; + ctl.ofs += 1; + } +invalid_cache: + if (ctl.page) { + UnlockPage(ctl.page); + page_cache_release(ctl.page); + ctl.page = NULL; + } + ctl.cache = cache; +init_cache: + ncp_invalidate_dircache_entries(dentry); + if (!mtime_valid) { + mtime = ncp_obtain_mtime(dentry); + mtime_valid = 1; + } + ctl.head.mtime = mtime; + ctl.head.time = jiffies; + ctl.head.eof = 0; + ctl.fpos = 2; + ctl.ofs = 0; + ctl.idx = NCP_DIRCACHE_START; + ctl.filled = 0; + ctl.valid = 1; +read_really: + if (ncp_is_server_root(inode)) { + ncp_read_volume_list(filp, dirent, filldir, &ctl); + } else { + ncp_do_readdir(filp, dirent, filldir, &ctl); + } + ctl.head.end = ctl.fpos - 1; + ctl.head.eof = ctl.valid; finished: + if (page) { + cache->head = ctl.head; + SetPageUptodate(page); + UnlockPage(page); + page_cache_release(page); + } + if (ctl.page) { + SetPageUptodate(ctl.page); + UnlockPage(ctl.page); + page_cache_release(ctl.page); + } +out: return result; } static int -ncp_do_simple_filldir(struct file *filp, char* name, int len, - void* dirent, filldir_t filldir) +ncp_fill_cache(struct file *filp, void *dirent, filldir_t filldir, + struct ncp_cache_control *ctrl, struct ncp_entry_info *entry) { - struct dentry *dentry = filp->f_dentry; + struct dentry *newdent, *dentry = filp->f_dentry; + struct inode *newino, *inode = dentry->d_inode; + struct ncp_server *server = NCP_SERVER(inode); + struct ncp_cache_control ctl = *ctrl; struct qstr qname; ino_t ino = 0; - int result; - - qname.name = name; - qname.len = len; - - ino = find_inode_number(dentry, &qname); + int valid = 0; - if (!ino) - ino = iunique(dentry->d_inode->i_sb, 2); + vol2io(server, entry->i.entryName, + !ncp_preserve_entry_case(inode, entry->i.NSCreator)); - result = filldir(dirent, name, len, filp->f_pos, ino); - if (!result) - filp->f_pos += 1; - - return result; -} - -static int -ncp_do_filldir(struct file *filp, struct ncp_entry_info *entry, void *dirent, - filldir_t filldir) -{ - struct dentry *dentry = filp->f_dentry; - struct inode *inode = dentry->d_inode; - struct qstr qname; - ino_t ino = 0; - int result; - - /* For getwd() we have to return the correct inode in d_ino if the - * inode is currently in use. Otherwise the inode number does not - * matter. (You can argue a lot about this..) - */ qname.name = entry->i.entryName; qname.len = entry->i.nameLen; + qname.hash = full_name_hash(qname.name, qname.len); - { - struct dentry *newdent; - struct inode *newino; - - qname.hash = full_name_hash(qname.name, qname.len); - if (dentry->d_op && dentry->d_op->d_hash) - if (dentry->d_op->d_hash(dentry, &qname) != 0) - goto end_advance; - - newdent = d_lookup(dentry, &qname); + if (dentry->d_op && dentry->d_op->d_hash) + if (dentry->d_op->d_hash(dentry, &qname) != 0) + goto end_advance; - if (!newdent) { - newdent = d_alloc(dentry, &qname); - if (!newdent) - goto end_advance; - } + newdent = d_lookup(dentry, &qname); - if (!newdent->d_inode) { - entry->opened = 0; - entry->ino = iunique(inode->i_sb, 2); - newino = ncp_iget(inode->i_sb, entry); - if (newino) { - newdent->d_op = &ncp_dentry_operations; - d_add(newdent, newino); - ncp_new_dentry(newdent); - } - } else { - ncp_update_inode2(newdent->d_inode, entry); - ncp_new_dentry(newdent); + if (!newdent) { + newdent = d_alloc(dentry, &qname); + if (!newdent) + goto end_advance; + } else + memcpy((char *) newdent->d_name.name, qname.name, + newdent->d_name.len); + + if (!newdent->d_inode) { + entry->opened = 0; + entry->ino = iunique(inode->i_sb, 2); + newino = ncp_iget(inode->i_sb, entry); + if (newino) { + newdent->d_op = &ncp_dentry_operations; + d_add(newdent, newino); } + } else + ncp_update_inode2(newdent->d_inode, entry); - if (newdent->d_inode) - ino = newdent->d_inode->i_ino; - - dput(newdent); + if (newdent->d_inode) { + ino = newdent->d_inode->i_ino; + newdent->d_fsdata = (void *) ctl.fpos; + ncp_new_dentry(newdent); + } + if (ctl.idx >= NCP_DIRCACHE_SIZE) { + if (ctl.page) { + SetPageUptodate(ctl.page); + UnlockPage(ctl.page); + page_cache_release(ctl.page); + } + ctl.cache = NULL; + ctl.idx -= NCP_DIRCACHE_SIZE; + ctl.ofs += 1; + ctl.page = ncp_get_cache_page(inode, ctl.ofs, 0); + if (ctl.page) + ctl.cache = (union ncp_dir_cache *) + page_address(ctl.page); + } + if (ctl.cache) { + ctl.cache->dentry[ctl.idx] = newdent; + valid = 1; + } + dput(newdent); end_advance: + if (!valid) + ctl.valid = 0; + if (!ctl.filled && (ctl.fpos == filp->f_pos)) { + if (!ino) + ino = find_inode_number(dentry, &qname); + if (!ino) + ino = iunique(inode->i_sb, 2); + ctl.filled = filldir(dirent, entry->i.entryName, + entry->i.nameLen, filp->f_pos, ino); + if (!ctl.filled) + filp->f_pos += 1; } - if (!ino) - ino = find_inode_number(dentry, &qname); - - if (!ino) - ino = iunique(inode->i_sb, 2); - - result = filldir(dirent, entry->i.entryName, entry->i.nameLen, - filp->f_pos, ino); - if (!result) - filp->f_pos += 1; - - return result; + ctl.fpos += 1; + ctl.idx += 1; + *ctrl = ctl; + return (ctl.valid || !ctl.filled); } -static int -ncp_read_volume_list(struct file *filp, void *dirent, filldir_t filldir) +static void +ncp_read_volume_list(struct file *filp, void *dirent, filldir_t filldir, + struct ncp_cache_control *ctl) { struct dentry *dentry = filp->f_dentry; struct inode *inode = dentry->d_inode; struct ncp_server *server = NCP_SERVER(inode); struct ncp_volume_info info; struct ncp_entry_info entry; - unsigned long total_count = 2, fpos = filp->f_pos; int i; - DPRINTK(KERN_DEBUG "ncp_read_volume_list: pos=%ld\n", fpos); + DPRINTK("ncp_read_volume_list: pos=%ld\n", + (unsigned long) filp->f_pos); for (i = 0; i < NCP_NUMBER_OF_VOLUMES; i++) { if (ncp_get_volume_info_with_number(server, i, &info) != 0) - break; + return; if (!strlen(info.volume_name)) continue; - if (total_count < fpos) { - DPRINTK(KERN_DEBUG "ncp_read_volume_list: skipped vol: %s\n", - info.volume_name); - } else { - DPRINTK(KERN_DEBUG "ncp_read_volume_list: found vol: %s\n", - info.volume_name); + DPRINTK("ncp_read_volume_list: found vol: %s\n", + info.volume_name); - if (ncp_lookup_volume(server, info.volume_name, - &entry.i)) { - DPRINTK(KERN_DEBUG "ncpfs: could not lookup vol %s\n", - info.volume_name); - continue; - } - vol2io(server, entry.i.entryName, - !ncp_preserve_entry_case(inode, entry.i.NSCreator)); - if (ncp_do_filldir(filp, &entry, dirent, filldir)) - break; + if (ncp_lookup_volume(server, info.volume_name, + &entry.i)) { + DPRINTK("ncpfs: could not lookup vol %s\n", + info.volume_name); + continue; } - total_count += 1; + if (!ncp_fill_cache(filp, dirent, filldir, ctl, &entry)) + return; } - - return (total_count - fpos); } -static int ncp_do_readdir(struct file *filp, void *dirent, filldir_t filldir) +static void ncp_do_readdir(struct file *filp, void *dirent, filldir_t filldir, + struct ncp_cache_control *ctl) { struct dentry *dentry = filp->f_dentry; struct inode *dir = dentry->d_inode; struct ncp_server *server = NCP_SERVER(dir); - struct ncp_seq_cache *cache = NULL; - struct ncp_cache_control ctl; + struct nw_search_sequence seq; struct ncp_entry_info entry; - struct page *page, **hash; - unsigned long total_count = 0, fpos = filp->f_pos; int err; - DPRINTK(KERN_DEBUG "ncp_do_readdir: %s/%s, fpos=%ld\n", - dentry->d_parent->d_name.name, dentry->d_name.name, fpos); - -#ifdef NCPFS_DEBUG_VERBOSE -printk("ncp_do_readdir: finding cache for %s/%s\n", - dentry->d_parent->d_name.name, dentry->d_name.name); -#endif - - /* cache using inspired by smbfs and nfs */ - hash = page_hash(&dir->i_data, 0); - - page = __find_lock_page(&dir->i_data, 0, hash); - - if (!page) { - unsigned long page_cache; - - page_cache = page_cache_alloc(); - if (page_cache) { - page = page_cache_entry(page_cache); - if (add_to_page_cache_unique(page, &dir->i_data, 0, hash)) { - page_cache_release(page); - page = NULL; - page_cache_free(page_cache); - } - } - } - - if (!page) - goto start_search; - - cache = (struct ncp_seq_cache *) page_address(page); - ctl = cache->ctl; - - if (!Page_Uptodate(page)) - ctl.currentpos = NCP_FPOS_EMPTY; - - if ((fpos == 2) || (fpos < ctl.firstcache)) - ctl.currentpos = NCP_FPOS_EMPTY; - - if (ctl.currentpos == NCP_FPOS_EMPTY) - goto start_search; - - { - int fetchpos = ctl.cachehead; - int readpos = ctl.firstcache; - - while (readpos < fpos) { - fetchpos += cache->cache[fetchpos] + 1; - readpos++; - } - while (fpos < ctl.currentpos) { - err = ncp_do_simple_filldir(filp, - (char*)(cache->cache+fetchpos+1), - cache->cache[fetchpos], - dirent, filldir); - if (err) - goto out; - fetchpos += cache->cache[fetchpos] + 1; - fpos++; - total_count++; - } + DPRINTK("ncp_do_readdir: %s/%s, fpos=%ld\n", + dentry->d_parent->d_name.name, dentry->d_name.name, + (unsigned long) filp->f_pos); + PPRINTK("ncp_do_readdir: init %s, volnum=%d, dirent=%u\n", + dentry->d_name.name, NCP_FINFO(dir)->volNumber, + NCP_FINFO(dir)->dirEntNum); + + err = ncp_initialize_search(server, dir, &seq); + if (err) { + DPRINTK("ncp_do_readdir: init failed, err=%d\n", err); + return; } - -start_search: - - DDPRINTK(KERN_DEBUG "ncp_do_readdir: %s: f_pos=%ld,total_count=%ld\n", - dentry->d_name.name, fpos, total_count); - - if (ctl.currentpos == NCP_FPOS_EMPTY) { -#ifdef NCPFS_PARANOIA -printk(KERN_DEBUG "ncp_do_readdir: init %s, volnum=%d, dirent=%u\n", -dentry->d_name.name, NCP_FINFO(dir)->volNumber, NCP_FINFO(dir)->dirEntNum); -#endif - err = ncp_initialize_search(server, dir, &ctl.seq); - if (err) { - DPRINTK(KERN_DEBUG "ncp_do_readdir: init failed, err=%d\n", err); - goto out; - } - ctl.eof = 0; - ctl.cachehead = ctl.cachetail = 0; - ctl.firstcache = ctl.currentpos = 2; - } else - DDPRINTK(KERN_DEBUG "ncp_do_readdir: reused seq for %s, fpos=%li\n", - dentry->d_name.name, total_count); - for (;;) { - err = ncp_search_for_file_or_subdir(server, &ctl.seq, - &entry.i); + err = ncp_search_for_file_or_subdir(server, &seq, &entry.i); if (err) { - DPRINTK(KERN_DEBUG "ncp_do_readdir: search failed, err=%d\n", err); - ctl.eof = 1; - break; + DPRINTK("ncp_do_readdir: search failed, err=%d\n", err); + return; } - - ctl.currentpos++; - - vol2io(server, entry.i.entryName, - !ncp_preserve_entry_case(dir, entry.i.NSCreator)); - - if (page) { - int tlen = ctl.cachetail + entry.i.nameLen + 1; - - if (tlen > NCP_DIRCACHE_SIZE) { - int ofs = ctl.cachehead; - - while (tlen - ofs > NCP_DIRCACHE_SIZE) { - ofs += cache->cache[ofs] + 1; - ctl.firstcache++; - } - ctl.cachetail -= ofs; - memmove(cache->cache+0, - cache->cache+ofs, - ctl.cachetail); - } - cache->cache[ctl.cachetail++] = entry.i.nameLen; - memcpy(cache->cache+ctl.cachetail, - entry.i.entryName, entry.i.nameLen); - ctl.cachetail += entry.i.nameLen; - } - if (ctl.currentpos < fpos) { - DPRINTK(KERN_DEBUG "ncp_do_readdir: skipped file: %s/%s\n", - dentry->d_name.name, entry.i.entryName); - } else { - DDPRINTK(KERN_DEBUG "ncp_do_r: file: %s, f_pos=%ld,total_count=%ld", - entry.i.entryName, fpos, total_count); - if (ncp_do_filldir(filp, &entry, dirent, filldir)) - break; - } - total_count++; - fpos++; + if (!ncp_fill_cache(filp, dirent, filldir, ctl, &entry)) + return; } -out: - if (page) { - cache->ctl = ctl; - SetPageUptodate(page); - UnlockPage(page); - page_cache_release(page); - } - - DDPRINTK(KERN_DEBUG "ncp_do_readdir: %s: return=%ld\n", - dentry->d_name.name, total_count); - return total_count; } int ncp_conn_logged_in(struct super_block *sb) @@ -723,9 +796,8 @@ int ncp_conn_logged_in(struct super_block *sb) result = -ENOENT; io2vol(server, server->m.mounted_vol, 1); if (ncp_lookup_volume(server, server->m.mounted_vol, &i)) { -#ifdef NCPFS_PARANOIA -printk(KERN_DEBUG "ncp_conn_logged_in: %s not found\n", server->m.mounted_vol); -#endif + PPRINTK("ncp_conn_logged_in: %s not found\n", + server->m.mounted_vol); goto out; } vol2io(server, i.entryName, 1); @@ -737,10 +809,10 @@ printk(KERN_DEBUG "ncp_conn_logged_in: %s not found\n", server->m.mounted_vol); NCP_FINFO(ino)->dirEntNum = i.dirEntNum; NCP_FINFO(ino)->DosDirNum = i.DosDirNum; } else { - DPRINTK(KERN_DEBUG "ncpfs: sb->s_root->d_inode == NULL!\n"); + DPRINTK("ncpfs: sb->s_root->d_inode == NULL!\n"); } } else { - DPRINTK(KERN_DEBUG "ncpfs: sb->s_root == NULL!\n"); + DPRINTK("ncpfs: sb->s_root == NULL!\n"); } } result = 0; @@ -765,11 +837,9 @@ static struct dentry *ncp_lookup(struct inode *dir, struct dentry *dentry) memcpy(__name, dentry->d_name.name, len); __name[len] = '\0'; -#ifdef NCPFS_PARANOIA -printk(KERN_DEBUG "ncp_lookup: %s, len %d\n", __name, len); -printk(KERN_DEBUG "ncp_lookup: server lookup for %s/%s\n", -dentry->d_parent->d_name.name, __name); -#endif + PPRINTK("ncp_lookup: %s, len %d\n", __name, len); + PPRINTK("ncp_lookup: server lookup for %s/%s\n", + dentry->d_parent->d_name.name, __name); if (ncp_is_server_root(dir)) { io2vol(server, __name, 1); res = ncp_lookup_volume(server, __name, &(finfo.i)); @@ -777,10 +847,8 @@ dentry->d_parent->d_name.name, __name); io2vol(server, __name, !ncp_preserve_case(dir)); res = ncp_obtain_info(server, dir, __name, &(finfo.i)); } -#ifdef NCPFS_PARANOIA -printk(KERN_DEBUG "ncp_lookup: looked for %s/%s, res=%d\n", -dentry->d_parent->d_name.name, __name, res); -#endif + PPRINTK("ncp_lookup: looked for %s/%s, res=%d\n", + dentry->d_parent->d_name.name, __name, res); /* * If we didn't find an entry, make a negative dentry. */ @@ -807,9 +875,7 @@ add_entry: } finished: -#ifdef NCPFS_PARANOIA -printk(KERN_DEBUG "ncp_lookup: result=%d\n", error); -#endif + PPRINTK("ncp_lookup: result=%d\n", error); return ERR_PTR(error); } @@ -832,10 +898,8 @@ out: return error; out_close: -#ifdef NCPFS_PARANOIA -printk(KERN_DEBUG "ncp_instantiate: %s/%s failed, closing file\n", -dentry->d_parent->d_name.name, dentry->d_name.name); -#endif + PPRINTK("ncp_instantiate: %s/%s failed, closing file\n", + dentry->d_parent->d_name.name, dentry->d_name.name); ncp_close_file(NCP_SERVER(dir), finfo->file_handle); goto out; } @@ -848,10 +912,8 @@ int ncp_create_new(struct inode *dir, struct dentry *dentry, int mode, struct ncp_server *server = NCP_SERVER(dir); __u8 _name[dentry->d_name.len + 1]; -#ifdef NCPFS_PARANOIA -printk(KERN_DEBUG "ncp_create_new: creating %s/%s, mode=%x\n", -dentry->d_parent->d_name.name, dentry->d_name.name, mode); -#endif + PPRINTK("ncp_create_new: creating %s/%s, mode=%x\n", + dentry->d_parent->d_name.name, dentry->d_name.name, mode); error = -EIO; if (!ncp_conn_valid(server)) goto out; @@ -872,7 +934,7 @@ dentry->d_parent->d_name.name, dentry->d_name.name, mode); error = ncp_instantiate(dir, dentry, &finfo); } else { if (result == 0x87) error = -ENAMETOOLONG; - DPRINTK(KERN_DEBUG "ncp_create: %s/%s failed\n", + DPRINTK("ncp_create: %s/%s failed\n", dentry->d_parent->d_name.name, dentry->d_name.name); } @@ -892,7 +954,7 @@ static int ncp_mkdir(struct inode *dir, struct dentry *dentry, int mode) struct ncp_server *server = NCP_SERVER(dir); __u8 _name[dentry->d_name.len + 1]; - DPRINTK(KERN_DEBUG "ncp_mkdir: making %s/%s\n", + DPRINTK("ncp_mkdir: making %s/%s\n", dentry->d_parent->d_name.name, dentry->d_name.name); error = -EIO; if (!ncp_conn_valid(server)) @@ -921,7 +983,7 @@ static int ncp_rmdir(struct inode *dir, struct dentry *dentry) struct ncp_server *server = NCP_SERVER(dir); __u8 _name[dentry->d_name.len + 1]; - DPRINTK(KERN_DEBUG "ncp_rmdir: removing %s/%s\n", + DPRINTK("ncp_rmdir: removing %s/%s\n", dentry->d_parent->d_name.name, dentry->d_name.name); error = -EIO; @@ -972,7 +1034,7 @@ static int ncp_unlink(struct inode *dir, struct dentry *dentry) struct ncp_server *server = NCP_SERVER(dir); int error; - DPRINTK(KERN_DEBUG "ncp_unlink: unlinking %s/%s\n", + DPRINTK("ncp_unlink: unlinking %s/%s\n", dentry->d_parent->d_name.name, dentry->d_name.name); error = -EIO; @@ -983,9 +1045,7 @@ static int ncp_unlink(struct inode *dir, struct dentry *dentry) * Check whether to close the file ... */ if (inode && NCP_FINFO(inode)->opened) { -#ifdef NCPFS_PARANOIA -printk(KERN_DEBUG "ncp_unlink: closing file\n"); -#endif + PPRINTK("ncp_unlink: closing file\n"); ncp_make_closed(inode); } @@ -999,7 +1059,7 @@ printk(KERN_DEBUG "ncp_unlink: closing file\n"); #endif switch (error) { case 0x00: - DPRINTK(KERN_DEBUG "ncp: removed %s/%s\n", + DPRINTK("ncp: removed %s/%s\n", dentry->d_parent->d_name.name, dentry->d_name.name); d_delete(dentry); break; @@ -1037,7 +1097,7 @@ static int ncp_rename(struct inode *old_dir, struct dentry *old_dentry, char _old_name[old_dentry->d_name.len + 1]; char _new_name[new_dentry->d_name.len + 1]; - DPRINTK(KERN_DEBUG "ncp_rename: %s/%s to %s/%s\n", + DPRINTK("ncp_rename: %s/%s to %s/%s\n", old_dentry->d_parent->d_name.name, old_dentry->d_name.name, new_dentry->d_parent->d_name.name, new_dentry->d_name.name); @@ -1067,7 +1127,7 @@ static int ncp_rename(struct inode *old_dir, struct dentry *old_dentry, #endif switch (error) { case 0x00: - DPRINTK(KERN_DEBUG "ncp renamed %s -> %s.\n", + DPRINTK("ncp renamed %s -> %s.\n", old_dentry->d_name.name,new_dentry->d_name.name); /* d_move(old_dentry, new_dentry); */ break; diff --git a/fs/ncpfs/file.c b/fs/ncpfs/file.c index e39578d75..4a907a9b1 100644 --- a/fs/ncpfs/file.c +++ b/fs/ncpfs/file.c @@ -46,7 +46,7 @@ int ncp_make_open(struct inode *inode, int right) goto out; } - DPRINTK(KERN_DEBUG "ncp_make_open: opened=%d, volume # %u, dir entry # %u\n", + DPRINTK("ncp_make_open: opened=%d, volume # %u, dir entry # %u\n", NCP_FINFO(inode)->opened, NCP_FINFO(inode)->volNumber, NCP_FINFO(inode)->dirEntNum); @@ -67,9 +67,7 @@ int ncp_make_open(struct inode *inode, int right) NULL, NULL, OC_MODE_OPEN, 0, AR_READ, &finfo); if (result) { -#ifdef NCPFS_PARANOIA -printk(KERN_DEBUG "ncp_make_open: failed, result=%d\n", result); -#endif + PPRINTK("ncp_make_open: failed, result=%d\n", result); goto out_unlock; } /* @@ -80,9 +78,7 @@ printk(KERN_DEBUG "ncp_make_open: failed, result=%d\n", result); } access = NCP_FINFO(inode)->access; -#ifdef NCPFS_PARANOIA -printk(KERN_DEBUG "ncp_make_open: file open, access=%x\n", access); -#endif + PPRINTK("ncp_make_open: file open, access=%x\n", access); if (access == right || access == O_RDWR) error = 0; @@ -104,12 +100,12 @@ ncp_file_read(struct file *file, char *buf, size_t count, loff_t *ppos) void* freepage; size_t freelen; - DPRINTK(KERN_DEBUG "ncp_file_read: enter %s/%s\n", + DPRINTK("ncp_file_read: enter %s/%s\n", dentry->d_parent->d_name.name, dentry->d_name.name); error = -EINVAL; if (inode == NULL) { - DPRINTK(KERN_DEBUG "ncp_file_read: inode = NULL\n"); + DPRINTK("ncp_file_read: inode = NULL\n"); goto out; } error = -EIO; @@ -117,7 +113,7 @@ ncp_file_read(struct file *file, char *buf, size_t count, loff_t *ppos) goto out; error = -EINVAL; if (!S_ISREG(inode->i_mode)) { - DPRINTK(KERN_DEBUG "ncp_file_read: read from non-file, mode %07o\n", + DPRINTK("ncp_file_read: read from non-file, mode %07o\n", inode->i_mode); goto out; } @@ -177,7 +173,7 @@ ncp_file_read(struct file *file, char *buf, size_t count, loff_t *ppos) inode->i_atime = CURRENT_TIME; } - DPRINTK(KERN_DEBUG "ncp_file_read: exit %s/%s\n", + DPRINTK("ncp_file_read: exit %s/%s\n", dentry->d_parent->d_name.name, dentry->d_name.name); out: return already_read ? already_read : error; @@ -194,17 +190,17 @@ ncp_file_write(struct file *file, const char *buf, size_t count, loff_t *ppos) int errno; void* bouncebuffer; - DPRINTK(KERN_DEBUG "ncp_file_write: enter %s/%s\n", + DPRINTK("ncp_file_write: enter %s/%s\n", dentry->d_parent->d_name.name, dentry->d_name.name); if (inode == NULL) { - DPRINTK(KERN_DEBUG "ncp_file_write: inode = NULL\n"); + DPRINTK("ncp_file_write: inode = NULL\n"); return -EINVAL; } errno = -EIO; if (!ncp_conn_valid(NCP_SERVER(inode))) goto out; if (!S_ISREG(inode->i_mode)) { - DPRINTK(KERN_DEBUG "ncp_file_write: write to non-file, mode %07o\n", + DPRINTK("ncp_file_write: write to non-file, mode %07o\n", inode->i_mode); return -EINVAL; } @@ -260,7 +256,7 @@ ncp_file_write(struct file *file, const char *buf, size_t count, loff_t *ppos) if (pos > inode->i_size) { inode->i_size = pos; } - DPRINTK(KERN_DEBUG "ncp_file_write: exit %s/%s\n", + DPRINTK("ncp_file_write: exit %s/%s\n", dentry->d_parent->d_name.name, dentry->d_name.name); out: return already_written ? already_written : errno; diff --git a/fs/ncpfs/inode.c b/fs/ncpfs/inode.c index e2d8a8a0f..ec2c1a4e4 100644 --- a/fs/ncpfs/inode.c +++ b/fs/ncpfs/inode.c @@ -72,10 +72,9 @@ void ncp_update_inode(struct inode *inode, struct ncp_entry_info *nwinfo) NCP_FINFO(inode)->server_file_handle = nwinfo->server_file_handle; memcpy(NCP_FINFO(inode)->file_handle, nwinfo->file_handle, sizeof(nwinfo->file_handle)); -#ifdef NCPFS_DEBUG_VERBOSE -printk(KERN_DEBUG "ncp_update_inode: updated %s, volnum=%d, dirent=%u\n", -nwinfo->i.entryName, NCP_FINFO(inode)->volNumber, NCP_FINFO(inode)->dirEntNum); -#endif + DPRINTK("ncp_update_inode: updated %s, volnum=%d, dirent=%u\n", + nwinfo->i.entryName, NCP_FINFO(inode)->volNumber, + NCP_FINFO(inode)->dirEntNum); } void ncp_update_inode2(struct inode* inode, struct ncp_entry_info *nwinfo) @@ -123,12 +122,8 @@ void ncp_update_inode2(struct inode* inode, struct ncp_entry_info *nwinfo) } if (nwi->attributes & aRONLY) inode->i_mode &= ~0222; } - inode->i_blocks = 0; - if ((inode->i_size)&&(inode->i_blksize)) { - inode->i_blocks = (inode->i_size-1)/(inode->i_blksize)+1; - } + inode->i_blocks = (inode->i_size + NCP_BLOCK_SIZE - 1) >> NCP_BLOCK_SHIFT; - /* TODO: times? I'm not sure... */ inode->i_mtime = ncp_date_dos2unix(le16_to_cpu(nwinfo->i.modifyTime), le16_to_cpu(nwinfo->i.modifyDate)); inode->i_ctime = ncp_date_dos2unix(le16_to_cpu(nwinfo->i.creationTime), @@ -163,8 +158,8 @@ static void ncp_set_attr(struct inode *inode, struct ncp_entry_info *nwinfo) switch (nwi->attributes & (aHIDDEN|aSYSTEM)) { case aHIDDEN: if (server->m.flags & NCP_MOUNT_SYMLINKS) { - if ((inode->i_size >= NCP_MIN_SYMLINK_SIZE) - && (inode->i_size <= NCP_MAX_SYMLINK_SIZE)) { + if (/* (inode->i_size >= NCP_MIN_SYMLINK_SIZE) + && */ (inode->i_size <= NCP_MAX_SYMLINK_SIZE)) { inode->i_mode = (inode->i_mode & ~S_IFMT) | S_IFLNK; break; } @@ -188,19 +183,15 @@ static void ncp_set_attr(struct inode *inode, struct ncp_entry_info *nwinfo) } if (nwi->attributes & aRONLY) inode->i_mode &= ~0222; - DDPRINTK(KERN_DEBUG "ncp_read_inode: inode->i_mode = %u\n", inode->i_mode); + DDPRINTK("ncp_read_inode: inode->i_mode = %u\n", inode->i_mode); inode->i_nlink = 1; inode->i_uid = server->m.uid; inode->i_gid = server->m.gid; - inode->i_blksize = NCP_BLOCK_SIZE; inode->i_rdev = 0; + inode->i_blksize = NCP_BLOCK_SIZE; - inode->i_blocks = 0; - if ((inode->i_blksize != 0) && (inode->i_size != 0)) { - inode->i_blocks = - (inode->i_size - 1) / inode->i_blksize + 1; - } + inode->i_blocks = (inode->i_size + NCP_BLOCK_SIZE - 1) >> NCP_BLOCK_SHIFT; inode->i_mtime = ncp_date_dos2unix(le16_to_cpu(nwi->modifyTime), le16_to_cpu(nwi->modifyDate)); @@ -255,7 +246,7 @@ static void ncp_delete_inode(struct inode *inode) { if (S_ISDIR(inode->i_mode)) { - DDPRINTK(KERN_DEBUG "ncp_delete_inode: put directory %ld\n", inode->i_ino); + DDPRINTK("ncp_delete_inode: put directory %ld\n", inode->i_ino); } if (NCP_FINFO(inode)->opened && ncp_make_closed(inode) != 0) { @@ -323,10 +314,11 @@ ncp_read_super(struct super_block *sb, void *raw_data, int silent) server->m = *data; /* Althought anything producing this is buggy, it happens now because of PATH_MAX changes.. */ - if (server->m.time_out < 10) { + if (server->m.time_out < 1) { server->m.time_out = 10; printk(KERN_INFO "You need to recompile your ncpfs utils..\n"); } + server->m.time_out = server->m.time_out * HZ / 100; server->m.file_mode = (server->m.file_mode & (S_IRWXU | S_IRWXG | S_IRWXO)) | S_IFREG; server->m.dir_mode = (server->m.dir_mode & @@ -350,7 +342,7 @@ ncp_read_super(struct super_block *sb, void *raw_data, int silent) ncp_unlock_server(server); if (error < 0) goto out_no_connect; - DPRINTK(KERN_DEBUG "ncp_read_super: NCP_SBP(sb) = %x\n", (int) NCP_SBP(sb)); + DPRINTK("ncp_read_super: NCP_SBP(sb) = %x\n", (int) NCP_SBP(sb)); #ifdef CONFIG_NCPFS_PACKET_SIGNING if (ncp_negotiate_size_and_options(server, NCP_DEFAULT_BUFSIZE, @@ -375,7 +367,7 @@ ncp_read_super(struct super_block *sb, void *raw_data, int silent) if (ncp_negotiate_buffersize(server, NCP_DEFAULT_BUFSIZE, &(server->buffer_size)) != 0) goto out_no_bufsize; - DPRINTK(KERN_DEBUG "ncpfs: bufsize = %d\n", server->buffer_size); + DPRINTK("ncpfs: bufsize = %d\n", server->buffer_size); memset(&finfo, 0, sizeof(finfo)); finfo.i.attributes = aDIR; @@ -402,7 +394,7 @@ ncp_read_super(struct super_block *sb, void *raw_data, int silent) root_inode = ncp_iget(sb, &finfo); if (!root_inode) goto out_no_root; - DPRINTK(KERN_DEBUG "ncp_read_super: root vol=%d\n", NCP_FINFO(root_inode)->volNumber); + DPRINTK("ncp_read_super: root vol=%d\n", NCP_FINFO(root_inode)->volNumber); sb->s_root = d_alloc_root(root_inode); if (!sb->s_root) goto out_no_root; @@ -650,7 +642,7 @@ int ncp_notify_change(struct dentry *dentry, struct iattr *attr) if ((attr->ia_valid & ATTR_SIZE) != 0) { int written; - DPRINTK(KERN_DEBUG "ncpfs: trying to change size to %ld\n", + DPRINTK("ncpfs: trying to change size to %ld\n", attr->ia_size); if ((result = ncp_make_open(inode, O_RDWR)) < 0) { @@ -689,7 +681,7 @@ EXPORT_NO_SYMBOLS; int init_module(void) { - DPRINTK(KERN_DEBUG "ncpfs: init_module called\n"); + DPRINTK("ncpfs: init_module called\n"); #ifdef DEBUG_NCP_MALLOC ncp_malloced = 0; @@ -700,11 +692,11 @@ int init_module(void) void cleanup_module(void) { - DPRINTK(KERN_DEBUG "ncpfs: cleanup_module called\n"); + DPRINTK("ncpfs: cleanup_module called\n"); unregister_filesystem(&ncp_fs_type); #ifdef DEBUG_NCP_MALLOC - printk(KERN_DEBUG "ncp_malloced: %d\n", ncp_malloced); - printk(KERN_DEBUG "ncp_current_malloced: %d\n", ncp_current_malloced); + PRINTK("ncp_malloced: %d\n", ncp_malloced); + PRINTK("ncp_current_malloced: %d\n", ncp_current_malloced); #endif } diff --git a/fs/ncpfs/ioctl.c b/fs/ncpfs/ioctl.c index ca2b534eb..05def9d6c 100644 --- a/fs/ncpfs/ioctl.c +++ b/fs/ncpfs/ioctl.c @@ -93,7 +93,7 @@ int ncp_ioctl(struct inode *inode, struct file *filp, else result = server->reply_size; ncp_unlock_server(server); - DPRINTK(KERN_DEBUG "ncp_ioctl: copy %d bytes\n", + DPRINTK("ncp_ioctl: copy %d bytes\n", result); if (result >= 0) if (copy_to_user(request.data, bouncebuffer, result)) @@ -124,7 +124,7 @@ int ncp_ioctl(struct inode *inode, struct file *filp, copy_from_user(&info, (struct ncp_fs_info *) arg, sizeof(info)); if (info.version != NCP_GET_FS_INFO_VERSION) { - DPRINTK(KERN_DEBUG "info.version invalid: %d\n", info.version); + DPRINTK("info.version invalid: %d\n", info.version); return -EINVAL; } /* TODO: info.addr = server->m.serv_addr; */ @@ -171,9 +171,9 @@ int ncp_ioctl(struct inode *inode, struct file *filp, sr.dirEntNum = NCP_FINFO(inode)->dirEntNum; sr.namespace = server->name_space[sr.volNumber]; } else - DPRINTK(KERN_DEBUG "ncpfs: s_root->d_inode==NULL\n"); + DPRINTK("ncpfs: s_root->d_inode==NULL\n"); } else - DPRINTK(KERN_DEBUG "ncpfs: s_root==NULL\n"); + DPRINTK("ncpfs: s_root==NULL\n"); } else { sr.volNumber = -1; sr.namespace = 0; @@ -221,9 +221,9 @@ int ncp_ioctl(struct inode *inode, struct file *filp, NCP_FINFO(inode)->dirEntNum = i.dirEntNum; NCP_FINFO(inode)->DosDirNum = i.DosDirNum; } else - DPRINTK(KERN_DEBUG "ncpfs: s_root->d_inode==NULL\n"); + DPRINTK("ncpfs: s_root->d_inode==NULL\n"); } else - DPRINTK(KERN_DEBUG "ncpfs: s_root==NULL\n"); + DPRINTK("ncpfs: s_root==NULL\n"); return 0; } diff --git a/fs/ncpfs/mmap.c b/fs/ncpfs/mmap.c index 776e9366b..036e92e93 100644 --- a/fs/ncpfs/mmap.c +++ b/fs/ncpfs/mmap.c @@ -30,23 +30,25 @@ static inline int min(int a, int b) /* * Fill in the supplied page for mmap */ -static unsigned long ncp_file_mmap_nopage(struct vm_area_struct *area, - unsigned long address, int no_share) +static struct page* ncp_file_mmap_nopage(struct vm_area_struct *area, + unsigned long address, int write_access) { struct file *file = area->vm_file; struct dentry *dentry = file->f_dentry; struct inode *inode = dentry->d_inode; - unsigned long page; + struct page* page; + unsigned long pg_addr; unsigned int already_read; unsigned int count; int bufsize; int pos; - page = __get_free_page(GFP_KERNEL); + page = alloc_page(GFP_KERNEL); if (!page) return page; + pg_addr = page_address(page); address &= PAGE_MASK; - pos = address - area->vm_start + area->vm_offset; + pos = address - area->vm_start + (area->vm_pgoff << PAGE_SHIFT); count = PAGE_SIZE; if (address + PAGE_SIZE > area->vm_end) { @@ -68,7 +70,7 @@ static unsigned long ncp_file_mmap_nopage(struct vm_area_struct *area, if (ncp_read_kernel(NCP_SERVER(inode), NCP_FINFO(inode)->file_handle, pos, to_read, - (char *) (page + already_read), + (char *) (pg_addr + already_read), &read_this_time) != 0) { read_this_time = 0; } @@ -83,7 +85,7 @@ static unsigned long ncp_file_mmap_nopage(struct vm_area_struct *area, } if (already_read < PAGE_SIZE) - memset((char*)(page + already_read), 0, + memset((char*)(pg_addr + already_read), 0, PAGE_SIZE - already_read); return page; } @@ -107,7 +109,7 @@ int ncp_mmap(struct file *file, struct vm_area_struct *vma) { struct inode *inode = file->f_dentry->d_inode; - DPRINTK(KERN_DEBUG "ncp_mmap: called\n"); + DPRINTK("ncp_mmap: called\n"); if (!ncp_conn_valid(NCP_SERVER(inode))) { return -EIO; @@ -117,6 +119,11 @@ int ncp_mmap(struct file *file, struct vm_area_struct *vma) return -EINVAL; if (!inode->i_sb || !S_ISREG(inode->i_mode)) return -EACCES; + /* we do not support files bigger than 4GB... We eventually + supports just 4GB... */ + if (((vma->vm_end - vma->vm_start) >> PAGE_SHIFT) + vma->vm_pgoff + > (1U << (32 - PAGE_SHIFT))) + return -EFBIG; if (!IS_RDONLY(inode)) { inode->i_atime = CURRENT_TIME; } diff --git a/fs/ncpfs/ncplib_kernel.c b/fs/ncpfs/ncplib_kernel.c index 2881c74fa..5dbd0c55a 100644 --- a/fs/ncpfs/ncplib_kernel.c +++ b/fs/ncpfs/ncplib_kernel.c @@ -17,10 +17,10 @@ static inline int min(int a, int b) return a < b ? a : b; } -static void assert_server_locked(struct ncp_server *server) +static inline void assert_server_locked(struct ncp_server *server) { if (server->lock == 0) { - DPRINTK(KERN_DEBUG "ncpfs: server not locked!\n"); + DPRINTK("ncpfs: server not locked!\n"); } } @@ -69,7 +69,7 @@ static void ncp_add_pstring(struct ncp_server *server, const char *s) int len = strlen(s); assert_server_locked(server); if (len > 255) { - DPRINTK(KERN_DEBUG "ncpfs: string too long: %s\n", s); + DPRINTK("ncpfs: string too long: %s\n", s); len = 255; } ncp_add_byte(server, len); @@ -77,7 +77,7 @@ static void ncp_add_pstring(struct ncp_server *server, const char *s) return; } -static void ncp_init_request(struct ncp_server *server) +static inline void ncp_init_request(struct ncp_server *server) { ncp_lock_server(server); @@ -95,7 +95,7 @@ static void ncp_init_request_s(struct ncp_server *server, int subfunction) server->has_subfunction = 1; } -static char * +static inline char * ncp_reply_data(struct ncp_server *server, int offset) { return &(server->packet[sizeof(struct ncp_reply_header) + offset]); @@ -196,7 +196,7 @@ ncp_get_volume_info_with_number(struct ncp_server *server, int n, result = -EIO; len = ncp_reply_byte(server, 29); if (len > NCP_VOLNAME_LEN) { - DPRINTK(KERN_DEBUG "ncpfs: volume name too long: %d\n", len); + DPRINTK("ncpfs: volume name too long: %d\n", len); goto out; } memcpy(&(target->volume_name), ncp_reply_data(server, 30), len); @@ -229,11 +229,11 @@ ncp_make_closed(struct inode *inode) int err; NCP_FINFO(inode)->opened = 0; err = ncp_close_file(NCP_SERVER(inode), NCP_FINFO(inode)->file_handle); -#ifdef NCPFS_PARANOIA -if (!err) -printk(KERN_DEBUG "ncp_make_closed: volnum=%d, dirent=%u, error=%d\n", -NCP_FINFO(inode)->volNumber, NCP_FINFO(inode)->dirEntNum, err); -#endif + + if (!err) + PPRINTK("ncp_make_closed: volnum=%d, dirent=%u, error=%d\n", + NCP_FINFO(inode)->volNumber, + NCP_FINFO(inode)->dirEntNum, err); return err; } @@ -350,7 +350,7 @@ ncp_get_known_namespace(struct ncp_server *server, __u8 volume) namespace = ncp_reply_data(server, 2); while (no_namespaces > 0) { - DPRINTK(KERN_DEBUG "get_namespaces: found %d on %d\n", *namespace, volume); + DPRINTK("get_namespaces: found %d on %d\n", *namespace, volume); #ifdef CONFIG_NCPFS_NFS_NS if ((*namespace == NW_NS_NFS) && !(server->m.flags&NCP_MOUNT_NO_NFS)) @@ -387,7 +387,7 @@ ncp_ObtainSpecificDirBase(struct ncp_server *server, ncp_add_byte(server, 6); /* subfunction */ ncp_add_byte(server, nsSrc); ncp_add_byte(server, nsDst); - ncp_add_word(server, 0x8006); /* get all */ + ncp_add_word(server, htons(0x0680)); /* get all */ ncp_add_dword(server, RIM_ALL); ncp_add_handle_path(server, vol_num, dir_base, 1, path); @@ -436,7 +436,7 @@ ncp_lookup_volume(struct ncp_server *server, char *volname, int result; int volnum; - DPRINTK(KERN_DEBUG "ncp_lookup_volume: looking up vol %s\n", volname); + DPRINTK("ncp_lookup_volume: looking up vol %s\n", volname); ncp_init_request(server); ncp_add_byte(server, 22); /* Subfunction: Generate dir handle */ @@ -462,7 +462,7 @@ ncp_lookup_volume(struct ncp_server *server, char *volname, server->name_space[volnum] = ncp_get_known_namespace(server, volnum); - DPRINTK(KERN_DEBUG "lookup_vol: namespace[%d] = %d\n", + DPRINTK("lookup_vol: namespace[%d] = %d\n", volnum, server->name_space[volnum]); target->nameLen = strlen(volname); @@ -537,7 +537,7 @@ ncp_del_file_or_subdir2(struct ncp_server *server, if (!inode) { #if CONFIG_NCPFS_DEBUGDENTRY - printk(KERN_DEBUG "ncpfs: ncpdel2: dentry->d_inode == NULL\n"); + PRINTK("ncpfs: ncpdel2: dentry->d_inode == NULL\n"); #endif return 0xFF; /* Any error */ } diff --git a/fs/ncpfs/ncplib_kernel.h b/fs/ncpfs/ncplib_kernel.h index f4cc6425b..92309db26 100644 --- a/fs/ncpfs/ncplib_kernel.h +++ b/fs/ncpfs/ncplib_kernel.h @@ -36,7 +36,8 @@ #define NCP_MIN_SYMLINK_SIZE 8 #define NCP_MAX_SYMLINK_SIZE 512 -#define NCP_BLOCK_SIZE 512 +#define NCP_BLOCK_SHIFT 9 +#define NCP_BLOCK_SIZE (1 << (NCP_BLOCK_SHIFT)) int ncp_negotiate_buffersize(struct ncp_server *, int, int *); int ncp_negotiate_size_and_options(struct ncp_server *server, int size, @@ -173,8 +174,8 @@ vol2io(struct ncp_server *server, char *name, int case_trans) #endif /* CONFIG_NCPFS_NLS */ #define NCP_GET_AGE(dentry) (jiffies - (dentry)->d_time) -#define NCP_MAX_AGE (server->dentry_ttl) -#define NCP_TEST_AGE(server,dentry) (NCP_GET_AGE(dentry) < NCP_MAX_AGE) +#define NCP_MAX_AGE(server) ((server)->dentry_ttl) +#define NCP_TEST_AGE(server,dentry) (NCP_GET_AGE(dentry) < NCP_MAX_AGE(server)) static inline void ncp_age_dentry(struct ncp_server* server, struct dentry* dentry) @@ -188,21 +189,65 @@ ncp_new_dentry(struct dentry* dentry) dentry->d_time = jiffies; } -#define NCP_FPOS_EMPTY 0 /* init value for fpos variables. */ +static inline void +ncp_renew_dentries(struct dentry *parent) +{ + struct ncp_server *server = NCP_SERVER(parent->d_inode); + struct list_head *next = parent->d_subdirs.next; + struct dentry *dentry; -struct ncp_cache_control { - struct nw_search_sequence seq; - int firstcache; - int currentpos; - int cachehead; - int cachetail; + while (next != &parent->d_subdirs) { + dentry = list_entry(next, struct dentry, d_child); + + if (dentry->d_fsdata == NULL) + ncp_age_dentry(server, dentry); + else + ncp_new_dentry(dentry); + + next = next->next; + } +} + +static inline void +ncp_invalidate_dircache_entries(struct dentry *parent) +{ + struct ncp_server *server = NCP_SERVER(parent->d_inode); + struct list_head *next = parent->d_subdirs.next; + struct dentry *dentry; + + while (next != &parent->d_subdirs) { + dentry = list_entry(next, struct dentry, d_child); + dentry->d_fsdata = NULL; + ncp_age_dentry(server, dentry); + next = next->next; + } +} + +struct ncp_cache_head { + time_t mtime; + unsigned long time; /* cache age */ + unsigned long end; /* last valid fpos in cache */ int eof; }; -#define NCP_DIRCACHE_SIZE (PAGE_CACHE_SIZE-sizeof(struct ncp_cache_control)) -struct ncp_seq_cache { - struct ncp_cache_control ctl; - unsigned char cache[NCP_DIRCACHE_SIZE]; +#define NCP_DIRCACHE_SIZE ((int)(PAGE_CACHE_SIZE/sizeof(struct dentry *))) +union ncp_dir_cache { + struct ncp_cache_head head; + struct dentry *dentry[NCP_DIRCACHE_SIZE]; +}; + +#define NCP_FIRSTCACHE_SIZE ((int)((NCP_DIRCACHE_SIZE * \ + sizeof(struct dentry *) - sizeof(struct ncp_cache_head)) / \ + sizeof(struct dentry *))) + +#define NCP_DIRCACHE_START (NCP_DIRCACHE_SIZE - NCP_FIRSTCACHE_SIZE) + +struct ncp_cache_control { + struct ncp_cache_head head; + struct page *page; + union ncp_dir_cache *cache; + unsigned long fpos, ofs; + int filled, valid, idx; }; #endif /* _NCPLIB_H */ diff --git a/fs/ncpfs/sock.c b/fs/ncpfs/sock.c index 2d43ec9ad..33a4293c4 100644 --- a/fs/ncpfs/sock.c +++ b/fs/ncpfs/sock.c @@ -144,7 +144,7 @@ static int do_ncp_rpc_call(struct ncp_server *server, int size, set_fs(get_ds()); for (n = 0, timeout = init_timeout;; n++, timeout <<= 1) { /* - DDPRINTK(KERN_DEBUG "ncpfs: %08lX:%02X%02X%02X%02X%02X%02X:%04X\n", + DDPRINTK("ncpfs: %08lX:%02X%02X%02X%02X%02X%02X:%04X\n", htonl(server->m.serv_addr.sipx_network), server->m.serv_addr.sipx_node[0], server->m.serv_addr.sipx_node[1], @@ -154,12 +154,12 @@ static int do_ncp_rpc_call(struct ncp_server *server, int size, server->m.serv_addr.sipx_node[5], ntohs(server->m.serv_addr.sipx_port)); */ - DDPRINTK(KERN_DEBUG "ncpfs: req.typ: %04X, con: %d, " + DDPRINTK("ncpfs: req.typ: %04X, con: %d, " "seq: %d", request.type, (request.conn_high << 8) + request.conn_low, request.sequence); - DDPRINTK(KERN_DEBUG " func: %d\n", + DDPRINTK(" func: %d\n", request.function); result = _send(sock, (void *) start, size); @@ -223,11 +223,11 @@ static int do_ncp_rpc_call(struct ncp_server *server, int size, MSG_PEEK | MSG_DONTWAIT); if (result < 0) { if (result == -EAGAIN) { - DDPRINTK(KERN_DEBUG "ncp_rpc_call: bad select ready\n"); + DDPRINTK("ncp_rpc_call: bad select ready\n"); goto re_select; } if (result == -ECONNREFUSED) { - DPRINTK(KERN_WARNING "ncp_rpc_call: server playing coy\n"); + DPRINTK("ncp_rpc_call: server playing coy\n"); goto re_select; } if (result != -ERESTARTSYS) { @@ -239,7 +239,7 @@ static int do_ncp_rpc_call(struct ncp_server *server, int size, if ((result == sizeof(reply)) && (reply.type == NCP_POSITIVE_ACK)) { /* Throw away the packet */ - DPRINTK(KERN_DEBUG "ncp_rpc_call: got positive acknowledge\n"); + DPRINTK("ncp_rpc_call: got positive acknowledge\n"); _recv(sock, (void *) &reply, sizeof(reply), MSG_DONTWAIT); n = 0; @@ -247,7 +247,7 @@ static int do_ncp_rpc_call(struct ncp_server *server, int size, acknowledge_seen = 1; goto re_select; } - DDPRINTK(KERN_DEBUG "ncpfs: rep.typ: %04X, con: %d, tsk: %d," + DDPRINTK("ncpfs: rep.typ: %04X, con: %d, tsk: %d," "seq: %d\n", reply.type, (reply.conn_high << 8) + reply.conn_low, @@ -271,7 +271,7 @@ static int do_ncp_rpc_call(struct ncp_server *server, int size, * a null buffer yet. */ _recv(sock, (void *) &reply, sizeof(reply), MSG_DONTWAIT); - DPRINTK(KERN_WARNING "ncp_rpc_call: reply mismatch\n"); + DPRINTK("ncp_rpc_call: reply mismatch\n"); goto re_select; } /* @@ -321,7 +321,7 @@ static int ncp_do_request(struct ncp_server *server, int size, #endif /* CONFIG_NCPFS_PACKET_SIGNING */ result = do_ncp_rpc_call(server, size, reply, max_reply_size); - DDPRINTK(KERN_DEBUG "do_ncp_rpc_call returned %d\n", result); + DDPRINTK("do_ncp_rpc_call returned %d\n", result); if (result < 0) { /* There was a problem with I/O, so the connections is @@ -363,7 +363,7 @@ int ncp_request2(struct ncp_server *server, int function, result = ncp_do_request(server, request_size + sizeof(*h), reply, size); if (result < 0) { - DPRINTK(KERN_WARNING "ncp_request_error: %d\n", result); + DPRINTK("ncp_request_error: %d\n", result); goto out; } server->completion = reply->completion_code; @@ -373,10 +373,8 @@ int ncp_request2(struct ncp_server *server, int function, result = reply->completion_code; -#ifdef NCPFS_PARANOIA -if (result != 0) -printk(KERN_DEBUG "ncp_request: completion code=%x\n", result); -#endif + if (result != 0) + PPRINTK("ncp_request: completion code=%x\n", result); out: return result; } @@ -428,7 +426,7 @@ void ncp_lock_server(struct ncp_server *server) #if 0 /* For testing, only 1 process */ if (server->lock != 0) { - DPRINTK(KERN_WARNING "ncpfs: server locked!!!\n"); + DPRINTK("ncpfs: server locked!!!\n"); } #endif down(&server->sem); diff --git a/fs/ncpfs/symlink.c b/fs/ncpfs/symlink.c index 578b2b985..81151959a 100644 --- a/fs/ncpfs/symlink.c +++ b/fs/ncpfs/symlink.c @@ -80,7 +80,7 @@ static struct dentry *ncp_follow_link(struct dentry *dentry, char *link; #ifdef DEBUG - printk("ncp_follow_link(dentry=%p,base=%p,follow=%u)\n",dentry,base,follow); + PRINTK("ncp_follow_link(dentry=%p,base=%p,follow=%u)\n",dentry,base,follow); #endif if(!S_ISLNK(inode->i_mode)) { @@ -131,7 +131,7 @@ static int ncp_readlink(struct dentry * dentry, char * buffer, int buflen) int length,error; #ifdef DEBUG - printk("ncp_readlink(dentry=%p,buffer=%p,buflen=%d)\n",dentry,buffer,buflen); + PRINTK("ncp_readlink(dentry=%p,buffer=%p,buflen=%d)\n",dentry,buffer,buflen); #endif if(!S_ISLNK(inode->i_mode)) @@ -173,7 +173,7 @@ int ncp_symlink(struct inode *dir, struct dentry *dentry, const char *symname) { char *link; #ifdef DEBUG - printk("ncp_symlink(dir=%p,dentry=%p,symname=%s)\n",dir,dentry,symname); + PRINTK("ncp_symlink(dir=%p,dentry=%p,symname=%s)\n",dir,dentry,symname); #endif if (!(NCP_SERVER(dir)->m.flags & NCP_MOUNT_SYMLINKS)) |