summaryrefslogtreecommitdiffstats
path: root/fs/ncpfs
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>2000-01-29 01:41:54 +0000
committerRalf Baechle <ralf@linux-mips.org>2000-01-29 01:41:54 +0000
commitf969d69ba9f952e5bdd38278e25e26a3e4a61a70 (patch)
treeb3530d803df59d726afaabebc6626987dee1ca05 /fs/ncpfs
parenta10ce7ef2066b455d69187643ddf2073bfc4db24 (diff)
Merge with 2.3.27.
Diffstat (limited to 'fs/ncpfs')
-rw-r--r--fs/ncpfs/dir.c692
-rw-r--r--fs/ncpfs/file.c26
-rw-r--r--fs/ncpfs/inode.c48
-rw-r--r--fs/ncpfs/ioctl.c12
-rw-r--r--fs/ncpfs/mmap.c23
-rw-r--r--fs/ncpfs/ncplib_kernel.c32
-rw-r--r--fs/ncpfs/ncplib_kernel.h73
-rw-r--r--fs/ncpfs/sock.c28
-rw-r--r--fs/ncpfs/symlink.c6
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))