2.1.x NCP Patches

Peter T. Waltenberg (p.waltenberg@irl.cri.nz)
Fri, 17 Oct 1997 08:26:28 +1300 (NZDT)


This message is in MIME format
--_=XFMail.1.2.p0.Linux:971017082628:188=_
Content-Type: text/plain; charset=us-ascii

The attached patch should get read access back for ncp, and it seems as stable
as the 2.0. version. It's been in use here for several weeks now and hasn't
caused any noticeable problems.

There are still bugs with things like ls -R on very large ncp mounted
dirs, but these existed in the original code.
ipx_interface delall generally allows these to be cleared without rebooting.

Getting it fully functional still requires quite a bit of work. If anyone feels
inspired, the now working smbfs code is a good model for the changes required.
I'll continue working on it when I get time, so if there are bug reports, feel
free to send me a copy, but this isn't a high priority item for me.

Peter Waltenberg
----------------------------------
E-Mail: P.Waltenberg@irl.cri.nz
Date: 17-Oct-97
Time: 08:14:00
----------------------------------

--_=XFMail.1.2.p0.Linux:971017082628:188=_
Content-Disposition: attachment; filename="ncp_pat"
Content-Transfer-Encoding: none
Content-Description: ncp_pat
Content-Type: application/octet-stream; name=ncp_pat; SizeOnDisk=20797

--- linux/fs/ncpfs/dir.c.orig Mon Sep 8 09:00:24 1997
+++ linux/fs/ncpfs/dir.c Fri Oct 17 08:09:21 1997
@@ -1,8 +1,10 @@
+/* #define DEBUG_NCP 2 */
/*
* dir.c
*
* Copyright (C) 1995, 1996 by Volker Lendecke
* Modified for big endian by J.F. Chadima and David S. Miller
+ * Patches for late 2.1 (dcache) kernels P.T.Waltenberg
*
*/

@@ -28,7 +30,8 @@
};

static long
- ncp_dir_read(struct inode *inode, struct file *filp, char *buf, unsigned long
count);
+ ncp_dir_read(struct inode *inode, struct file *filp,
+ char *buf, unsigned long count);

static int
ncp_readdir(struct file *filp,
@@ -49,25 +52,23 @@
ncp_find_dir_inode(struct inode *dir, const char *name);

static int
- ncp_lookup(struct inode *dir, const char *__name,
- int len, struct inode **result);
+ ncp_lookup(struct inode *dir, struct dentry *dentry);

static int
- ncp_create(struct inode *dir, const char *name, int len, int mode,
- struct inode **result);
+ ncp_create(struct inode *dir, struct dentry *dentry, int mode);

static int
- ncp_mkdir(struct inode *dir, const char *name, int len, int mode);
+ ncp_mkdir(struct inode *dir, struct dentry *dentry,int mode);

static int
- ncp_rmdir(struct inode *dir, const char *name, int len);
+ ncp_rmdir(struct inode *dir, struct dentry *dentry);

static int
- ncp_unlink(struct inode *dir, const char *name, int len);
+ ncp_unlink(struct inode *dir, struct dentry *dentry);

static int
- ncp_rename(struct inode *old_dir, const char *old_name, int old_len,
- struct inode *new_dir, const char *new_name, int new_len);
+ ncp_rename(struct inode *old_dir, struct dentry *old_dentry,
+ struct inode *new_dir, struct dentry *new_dentry);

static inline void str_upper(char *name)
{
@@ -128,10 +129,15 @@
NULL, /* mknod */
ncp_rename, /* rename */
NULL, /* readlink */
+ NULL, /* follow link */
+ NULL, /* readpage */
+ NULL, /* writepage */
NULL, /* bmap */
NULL, /* truncate */
NULL, /* permission */
- NULL /* smap */
+ NULL, /* smap */
+ NULL, /* updatepage */
+ NULL, /* revalidate */
};


@@ -216,7 +222,7 @@
int result = 0;
int i = 0;
int index = 0;
- struct inode *inode = file->f_dentry->d_inode;
+ struct inode *inode = filp->f_dentry->d_inode;
struct ncp_dirent *entry = NULL;
struct ncp_server *server = NCP_SERVER(inode);
struct ncp_inode_info *dir = NCP_INOP(inode);
@@ -405,7 +411,8 @@
return (total_count - fpos);
}

-static int ncp_do_readdir(struct ncp_server *server, struct inode *dir, int fpo
s,
+static int ncp_do_readdir(struct ncp_server *server,
+ struct inode *dir, int fpos,
int cache_size, struct ncp_dirent *entry)
{
static struct nw_search_sequence seq;
@@ -421,37 +428,37 @@
DPRINTK("ncp_do_readdir: fpos = %d\n", fpos);

if (fpos == 2) {
- last_dir = NULL;
- total_count = 2;
+ last_dir = NULL;
+ total_count = 2;
}
if ((fpos != total_count) || (dir != last_dir)) {
- total_count = 2;
- last_dir = dir;
-
- DPRINTK("ncp_do_readdir: re-used seq for %s\n",
- NCP_ISTRUCT(dir)->entryName);
-
- if (ncp_initialize_search(server, NCP_ISTRUCT(dir), &seq) != 0) {
- DPRINTK("ncp_init_search failed\n");
- return total_count - fpos;
- }
+ total_count = 2;
+ last_dir = dir;
+
+ DPRINTK("ncp_do_readdir: re-used seq for %s\n",
+ NCP_ISTRUCT(dir)->entryName);
+
+ if (ncp_initialize_search(server, NCP_ISTRUCT(dir), &seq) != 0) {
+ DPRINTK("ncp_init_search failed\n");
+ return total_count - fpos;
+ }
}
while (total_count < fpos + cache_size) {
- if (ncp_search_for_file_or_subdir(server, &seq,
- &(entry->i)) != 0) {
- return total_count - fpos;
- }
- if (total_count < fpos) {
- DPRINTK("ncp_do_readdir: skipped file: %s\n",
- entry->i.entryName);
- } else {
- DDPRINTK("ncp_do_r: file: %s, f_pos=%d,total_count=%d",
- entry->i.entryName, fpos, total_count);
- entry->s = seq;
- entry->f_pos = total_count;
- entry += 1;
- }
- total_count += 1;
+ if (ncp_search_for_file_or_subdir(server, &seq,
+ &(entry->i)) != 0) {
+ return total_count - fpos;
+ }
+ if (total_count < fpos) {
+ DPRINTK("ncp_do_readdir: skipped file: %s\n",
+ entry->i.entryName);
+ } else {
+ DDPRINTK("ncp_do_r: file: %s, f_pos=%d,total_count=%d",
+ entry->i.entryName, fpos, total_count);
+ entry->s = seq;
+ entry->f_pos = total_count;
+ entry += 1;
+ }
+ total_count += 1;
}
return (total_count - fpos);
}
@@ -486,8 +493,7 @@
}


-static struct inode *
- ncp_iget(struct inode *dir, struct nw_file_info *finfo)
+static struct inode * ncp_iget(struct inode *dir, struct nw_file_info *finfo)
{
struct inode *inode;
struct ncp_inode_info *new_inode_info;
@@ -661,72 +667,87 @@

return NULL;
}
-
-static int ncp_lookup(struct inode *dir, const char *__name, int len,
- struct inode **result)
+static int ncp_lookup(struct inode *dir, struct dentry *dentry)
{
struct nw_file_info finfo;
struct ncp_server *server;
struct ncp_inode_info *result_info;
+ struct inode *inode = NULL;
int found_in_cache;
int down_case = 0;
- char name[len + 1];
-
- *result = NULL;
-
+ int error = 0;
+ __u8 __name[dentry->d_name.len + 1];
+ int len = dentry->d_name.len;
+
if (!dir || !S_ISDIR(dir->i_mode)) {
printk("ncp_lookup: inode is NULL or not a directory.\n");
- iput(dir);
- return -ENOENT;
+
+ error = -ENOENT;
+ goto finished;
}
server = NCP_SERVER(dir);

if (!ncp_conn_valid(server)) {
- iput(dir);
- return -EIO;
+
+ error = -EIO;
+ goto finished;
}
- DPRINTK("ncp_lookup: %s, len %d\n", __name, len);
+ strncpy(__name,dentry->d_name.name,dentry->d_name.len);
+ __name[len] = '\0';
+ DPRINTK("ncp_lookup: %s, len %d ",__name,len);

/* Fast cheat for . */
if (len == 0 || (len == 1 && __name[0] == '.')) {
- *result = dir;
- return 0;
+ inode = dir;
+ error = 0;
+ goto finished;;
}
/* ..and for .. */
- if (len == 2 && __name[0] == '.' && __name[1] == '.') {
- struct ncp_inode_info *parent = NCP_INOP(dir)->dir;
-
- if (parent->state == NCP_INODE_CACHED) {
- parent->state = NCP_INODE_LOOKED_UP;
- }
- *result = iget(dir->i_sb, ncp_info_ino(server, parent));
- iput(dir);
- if (*result == 0) {
- return -EACCES;
- } else {
- return 0;
- }
+ if (len == 2 && __name[0] == '.' && __name[1] == '.')
+ {
+ struct ncp_inode_info *parent = NCP_INOP(dir)->dir;
+
+ if (parent->state == NCP_INODE_CACHED)
+ {
+ parent->state = NCP_INODE_LOOKED_UP;
+ }
+ inode = iget(dir->i_sb, ncp_info_ino(server, parent));
+
+ if (inode == 0)
+ {
+ error = -EACCES;
+ goto finished;
+ }
+ else
+ {
+ d_add(dentry,inode);
+ error = 0;
+ goto finished;;
+ }
}
- memcpy(name, __name, len);
- name[len] = 0;
- lock_super(dir->i_sb);
- result_info = ncp_find_dir_inode(dir, name);
-
- if (result_info != 0) {
- if (result_info->state == NCP_INODE_CACHED) {
- result_info->state = NCP_INODE_LOOKED_UP;
- }
- /* Here we convert the inode_info address into an
- inode number */
-
- *result = iget(dir->i_sb, ncp_info_ino(server, result_info));
- unlock_super(dir->i_sb);
- iput(dir);

- if (*result == NULL) {
- return -EACCES;
- }
- return 0;
+ lock_super(dir->i_sb);
+ result_info = ncp_find_dir_inode(dir,__name);
+
+ if (result_info != 0)
+ {
+ if (result_info->state == NCP_INODE_CACHED)
+ {
+ result_info->state = NCP_INODE_LOOKED_UP;
+ }
+ /* Here we convert the inode_info address into an
+ inode number */
+
+ inode = iget(dir->i_sb, ncp_info_ino(server, result_info));
+ unlock_super(dir->i_sb);
+ if (inode == NULL)
+ {
+ error = -EACCES;
+ goto finished;
+ }
+ d_add(dentry,inode);
+ error = 0;
+ goto finished;
}
/* If the file is in the dir cache, we do not have to ask the
server. */
@@ -734,87 +755,95 @@
found_in_cache = 0;
ncp_lock_dircache();

- if ((dir->i_dev == c_dev) && (dir->i_ino == c_ino)) {
- int first = c_last_returned_index;
- int i;
-
- i = first;
- do {
- DDPRINTK("ncp_lookup: trying index: %d, name: %s\n",
- i, c_entry[i].i.entryName);
-
- if (strcmp(c_entry[i].i.entryName, name) == 0) {
- DPRINTK("ncp_lookup: found in cache!\n");
- finfo.i = c_entry[i].i;
- found_in_cache = 1;
- break;
- }
- i = (i + 1) % c_size;
- }
- while (i != first);
+ if ((dir->i_dev == c_dev) && (dir->i_ino == c_ino))
+ {
+ int first = c_last_returned_index;
+ int i;
+
+ i = first;
+ do {
+ DDPRINTK("ncp_lookup: trying index: %d, name: %s\n",
+ i, c_entry[i].i.entryName);
+
+ if (strcmp(c_entry[i].i.entryName, __name) == 0) {
+ DPRINTK("ncp_lookup: found in cache!\n");
+ finfo.i = c_entry[i].i;
+ found_in_cache = 1;
+ break;
+ }
+ i = (i + 1) % c_size;
+ }
+ while (i != first);
}
ncp_unlock_dircache();

if (found_in_cache == 0) {
- int res;
-
- DDPRINTK("ncp_lookup: do_lookup on %s/%s\n",
- NCP_ISTRUCT(dir)->entryName, name);
-
- if (ncp_is_server_root(dir)) {
- str_upper(name);
- down_case = 1;
- res = ncp_lookup_volume(server, name, &(finfo.i));
- } else {
- if (!ncp_preserve_case(dir)) {
- str_upper(name);
- down_case = 1;
- }
- res = ncp_obtain_info(server,
- NCP_ISTRUCT(dir)->volNumber,
- NCP_ISTRUCT(dir)->dirEntNum,
- name, &(finfo.i));
- }
- if (res != 0) {
- unlock_super(dir->i_sb);
- iput(dir);
- return -ENOENT;
- }
+ int res;
+
+ DDPRINTK("ncp_lookup: do_lookup on %s/%s\n",
+ NCP_ISTRUCT(dir)->entryName, __name);
+
+ if (ncp_is_server_root(dir))
+ {
+ str_upper(__name);
+ down_case = 1;
+ res = ncp_lookup_volume(server, __name, &(finfo.i));
+ }
+ else
+ {
+ if (!ncp_preserve_case(dir))
+ {
+ str_upper(__name);
+ down_case = 1;
+ }
+ res = ncp_obtain_info(server,
+ NCP_ISTRUCT(dir)->volNumber,
+ NCP_ISTRUCT(dir)->dirEntNum,
+ __name, &(finfo.i));
+ }
+ if (res != 0) {
+ unlock_super(dir->i_sb);
+ error = -ENOENT;
+ goto finished;
+ }
}
finfo.opened = 0;
-
+
if (down_case != 0) {
- str_lower(finfo.i.entryName);
+ str_lower(finfo.i.entryName);
}
- if (!(*result = ncp_iget(dir, &finfo))) {
- unlock_super(dir->i_sb);
- iput(dir);
- return -EACCES;
+ if (!(inode = ncp_iget(dir, &finfo)))
+ {
+ unlock_super(dir->i_sb);
+ error = -EACCES;
+ goto finished;
}
unlock_super(dir->i_sb);
- iput(dir);
- return 0;
+ d_add(dentry,inode);
+ error = 0;
+ finished:
+ DPRINTK(" result %d\n",error);
+ return error;
}
-
-static int ncp_create(struct inode *dir, const char *name, int len, int mode,
- struct inode **result)
+static int ncp_create(struct inode *dir, struct dentry *dentry, int mode)
{
struct nw_file_info finfo;
- __u8 _name[len + 1];
+ struct inode *inode;

- *result = NULL;
+ __u8 _name[dentry->d_name.len + 1];

+
+ DPRINTK("ncp_create: ");
if (!dir || !S_ISDIR(dir->i_mode)) {
printk("ncp_create: inode is NULL or not a directory\n");
- iput(dir);
return -ENOENT;
}
if (!ncp_conn_valid(NCP_SERVER(dir))) {
- iput(dir);
+
return -EIO;
}
- strncpy(_name, name, len);
- _name[len] = '\0';
+ strncpy(_name, dentry->d_name.name, dentry->d_name.len);
+ _name[dentry->d_name.len] = '\0';

if (!ncp_preserve_case(dir)) {
str_upper(_name);
@@ -827,7 +856,7 @@
0, AR_READ | AR_WRITE,
&finfo) != 0) {
unlock_super(dir->i_sb);
- iput(dir);
+ DPRINTK("ncp: could not create file or sub-dir (NCP)\n");
return -EACCES;
}
ncp_invalid_dir_cache(dir);
@@ -837,185 +866,194 @@
}
finfo.access = O_RDWR;

- if (!(*result = ncp_iget(dir, &finfo)) < 0) {
+ if (!(inode = ncp_iget(dir, &finfo)))
+ {
ncp_close_file(NCP_SERVER(dir), finfo.file_handle);
unlock_super(dir->i_sb);
- iput(dir);
+ DPRINTK("ncp: ncp_create new inode lookup fails\n");
return -EINVAL;
}
+ DPRINTK("ncp: ncp_create it SHOULD have worked\n");
unlock_super(dir->i_sb);
- iput(dir);
+ d_instantiate(dentry,inode);
return 0;
}

-static int ncp_mkdir(struct inode *dir, const char *name, int len, int mode)
+static int ncp_mkdir(struct inode *dir, struct dentry *dentry, int mode)
{
- int error;
struct nw_file_info new_dir;
- __u8 _name[len + 1];
+ struct inode * inode;
+ __u8 _name[dentry->d_name.len + 1];

- if ((name[0] == '.')
- && ((len == 1)
- || ((len == 2)
- && (name[1] == '.')))) {
- iput(dir);
+ DPRINTK("ncp_mkdir: ");
+ if ((dentry->d_name.name[0] == '.')
+ && ((dentry->d_name.len == 1)
+ || ((dentry->d_name.len == 2)
+ && (dentry->d_name.name[1] == '.')))) {
+
return -EEXIST;
}
- strncpy(_name, name, len);
- _name[len] = '\0';
+ strncpy(_name, dentry->d_name.name, dentry->d_name.len);
+ _name[dentry->d_name.len] = '\0';

if (!ncp_preserve_case(dir)) {
str_upper(_name);
}
if (!dir || !S_ISDIR(dir->i_mode)) {
printk("ncp_mkdir: inode is NULL or not a directory\n");
- iput(dir);
+
return -ENOENT;
}
if (!ncp_conn_valid(NCP_SERVER(dir))) {
- iput(dir);
+
return -EIO;
}
if (ncp_open_create_file_or_subdir(NCP_SERVER(dir),
NCP_ISTRUCT(dir), _name,
OC_MODE_CREATE, aDIR, 0xffff,
- &new_dir) != 0) {
- error = -EACCES;
- } else {
- error = 0;
+ &new_dir) == 0)
+ {
+ ncp_invalid_dir_cache(dir);
+ inode = ncp_iget(dir,&new_dir);
+ d_instantiate(dentry,inode);
+ return 0;
+ }
+ return -EACCES;
+}
+
+static int ncp_rmdir(struct inode *dir, struct dentry *dentry)
+{
+ __u8 _name[dentry->d_name.len + 1];
+
+ DPRINTK("npc_rmdir: ");
+
+ if (!dir || !S_ISDIR(dir->i_mode))
+ {
+ printk("ncp_rmdir: inode is NULL or not a directory\n");
+ return -ENOENT;
+ }
+ if (!ncp_conn_valid(NCP_SERVER(dir)))
+ {
+ return -EIO;
+ }
+ if (ncp_find_dir_inode(dir, dentry->d_name.name) != NULL)
+ {
+ return -EBUSY;
+ }
+ else
+ {
+ strncpy(_name, dentry->d_name.name, dentry->d_name.len);
+ _name[dentry->d_name.len] = '\0';
+
+ if (!ncp_preserve_case(dir))
+ {
+ str_upper(_name);
+ }
+ if ( ncp_del_file_or_subdir(NCP_SERVER(dir),
+ NCP_ISTRUCT(dir),
+ _name) == 0)
+ {
ncp_invalid_dir_cache(dir);
+ d_delete(dentry);
+ return 0;
+ }
}
-
- iput(dir);
- return error;
-}
-
-static int ncp_rmdir(struct inode *dir, const char *name, int len)
-{
- int error;
- __u8 _name[len + 1];
-
- if (!dir || !S_ISDIR(dir->i_mode)) {
- printk("ncp_rmdir: inode is NULL or not a directory\n");
- iput(dir);
- return -ENOENT;
- }
- if (!ncp_conn_valid(NCP_SERVER(dir))) {
- iput(dir);
- return -EIO;
- }
- if (ncp_find_dir_inode(dir, name) != NULL) {
- iput(dir);
- error = -EBUSY;
- } else {
-
- strncpy(_name, name, len);
- _name[len] = '\0';
-
- if (!ncp_preserve_case(dir)) {
- str_upper(_name);
- }
- if ((error = ncp_del_file_or_subdir(NCP_SERVER(dir),
- NCP_ISTRUCT(dir),
- _name)) == 0) {
- ncp_invalid_dir_cache(dir);
- } else {
- error = -EACCES;
- }
- }
- iput(dir);
- return error;
+ return -EACCES;
}

-static int ncp_unlink(struct inode *dir, const char *name, int len)
+static int ncp_unlink(struct inode *dir, struct dentry *dentry)
{
- int error;
- __u8 _name[len + 1];
+ __u8 _name[dentry->d_name.len + 1];

+ DPRINTK("ncp_unlink: ");
+
if (!dir || !S_ISDIR(dir->i_mode)) {
printk("ncp_unlink: inode is NULL or not a directory\n");
- iput(dir);
+
return -ENOENT;
}
- if (!ncp_conn_valid(NCP_SERVER(dir))) {
- iput(dir);
+ if (!ncp_conn_valid(NCP_SERVER(dir)))
+ {
+
return -EIO;
}
- if (ncp_find_dir_inode(dir, name) != NULL) {
- iput(dir);
- error = -EBUSY;
- } else {
- strncpy(_name, name, len);
- _name[len] = '\0';
-
- if (!ncp_preserve_case(dir)) {
- str_upper(_name);
- }
- if ((error = ncp_del_file_or_subdir(NCP_SERVER(dir),
- NCP_ISTRUCT(dir),
- _name)) == 0) {
- ncp_invalid_dir_cache(dir);
- } else {
- error = -EACCES;
- }
+ /* don't remove a directory */
+ if (ncp_find_dir_inode(dir, dentry->d_name.name) != NULL)
+ {
+ DPRINTK("ncp: ncp_unlink, ncp thinks you tried to rm a dir or something no
nexistant.\n");
+ return -EBUSY;
+ }
+ else
+ {
+ strncpy(_name, dentry->d_name.name, dentry->d_name.len);
+ _name[dentry->d_name.len] = '\0';
+ if (!ncp_preserve_case(dir))
+ {
+ str_upper(_name);
+ }
+ if (ncp_del_file_or_subdir(NCP_SERVER(dir),
+ NCP_ISTRUCT(dir),
+ _name) == 0) {
+ DPRINTK("ncp: removing %s.\n",dentry->d_name.name);
+ ncp_invalid_dir_cache(dir);
+ d_delete(dentry);
+ return 0;
+ }
}
- iput(dir);
- return error;
+ return -EACCES;
}

-static int ncp_rename(struct inode *old_dir, const char *old_name, int old_len,
- struct inode *new_dir, const char *new_name, int new_len)
+static int ncp_rename(struct inode *old_dir, struct dentry *old_dentry,
+ struct inode *new_dir, struct dentry *new_dentry)
{
- int res;
- char _old_name[old_len + 1];
- char _new_name[new_len + 1];
+ char _old_name[old_dentry->d_name.len + 1];
+ char _new_name[new_dentry->d_name.len + 1];
+ int old_len = old_dentry->d_name.len;
+ int new_len = new_dentry->d_name.len;

+ DPRINTK("ncp_rename: ");
if (!old_dir || !S_ISDIR(old_dir->i_mode)) {
printk("ncp_rename: old inode is NULL or not a directory\n");
- res = -ENOENT;
- goto finished;
+ return -ENOENT;
}
if (!ncp_conn_valid(NCP_SERVER(old_dir))) {
- res = -EIO;
- goto finished;
+ return -EIO;
}
if (!new_dir || !S_ISDIR(new_dir->i_mode)) {
printk("ncp_rename: new inode is NULL or not a directory\n");
- res = -ENOENT;
- goto finished;
+ return -ENOENT;
}
- if ((ncp_find_dir_inode(old_dir, old_name) != NULL)
- || (ncp_find_dir_inode(new_dir, new_name) != NULL)) {
- res = -EBUSY;
- goto finished;
+ if ((ncp_find_dir_inode(old_dir, old_dentry->d_name.name) != NULL)
+ || (ncp_find_dir_inode(new_dir, new_dentry->d_name.name) != NULL))
+ {
+ DPRINTK("ncp_rename:attempt to rename a directory\n");
+ return -EBUSY;
}
- strncpy(_old_name, old_name, old_len);
+ strncpy(_old_name, old_dentry->d_name.name, old_len);
_old_name[old_len] = '\0';

if (!ncp_preserve_case(old_dir)) {
str_upper(_old_name);
}
- strncpy(_new_name, new_name, new_len);
+ strncpy(_new_name, new_dentry->d_name.name, new_len);
_new_name[new_len] = '\0';

if (!ncp_preserve_case(new_dir)) {
str_upper(_new_name);
}
- res = ncp_ren_or_mov_file_or_subdir(NCP_SERVER(old_dir),
- NCP_ISTRUCT(old_dir), _old_name,
- NCP_ISTRUCT(new_dir), _new_name);
-
- if (res == 0) {
- ncp_invalid_dir_cache(old_dir);
- ncp_invalid_dir_cache(new_dir);
- } else {
- res = -EACCES;
+ if( ncp_ren_or_mov_file_or_subdir(NCP_SERVER(old_dir),
+ NCP_ISTRUCT(old_dir), _old_name,
+ NCP_ISTRUCT(new_dir), _new_name)
+ == 0)
+ {
+ DPRINTK("ncp renamed %s -> %s.\n",
+ old_dentry->d_name.name,new_dentry->d_name.name);
+ ncp_invalid_dir_cache(old_dir);
+ ncp_invalid_dir_cache(new_dir);
+ d_move(old_dentry,new_dentry);
+ return 0;
}
-
- finished:
- iput(old_dir);
- iput(new_dir);
- return res;
+ return -EACCES;
}

/* The following routines are taken directly from msdos-fs */
--- linux/fs/ncpfs/inode.c.orig Sat Aug 16 07:51:03 1997
+++ linux/fs/ncpfs/inode.c Fri Oct 17 08:09:27 1997
@@ -35,19 +35,20 @@
static void ncp_put_inode(struct inode *);
static void ncp_read_inode(struct inode *);
static void ncp_put_super(struct super_block *);
-static void ncp_statfs(struct super_block *sb, struct statfs *buf, int bufsiz);
+static int ncp_statfs(struct super_block *sb, struct statfs *buf, int bufsiz);
static int ncp_notify_change(struct inode *inode, struct iattr *attr);

static struct super_operations ncp_sops =
{
ncp_read_inode, /* read inode */
- ncp_notify_change, /* notify change */
NULL, /* write inode */
ncp_put_inode, /* put inode */
+ NULL, /* delete inode */
+ ncp_notify_change, /* notify change */
ncp_put_super, /* put superblock */
NULL, /* write superblock */
ncp_statfs, /* stat filesystem */
- NULL
+ NULL /* remount */
};

/* ncp_read_inode: Called from iget, it only traverses the allocated
@@ -288,7 +289,7 @@
MOD_DEC_USE_COUNT;
}

-static void ncp_statfs(struct super_block *sb, struct statfs *buf, int bufsiz)
+static int ncp_statfs(struct super_block *sb, struct statfs *buf, int bufsiz)
{
struct statfs tmp;

@@ -306,7 +307,7 @@
tmp.f_files = -1;
tmp.f_ffree = -1;
tmp.f_namelen = 12;
- copy_to_user(buf, &tmp, bufsiz);
+ return copy_to_user(buf, &tmp, bufsiz) ? -EFAULT : 0;
}

static int ncp_notify_change(struct inode *inode, struct iattr *attr)

--_=XFMail.1.2.p0.Linux:971017082628:188=_--
End of MIME message