patch-2.1.52 linux/fs/smbfs/proc.c
Next file: linux/fs/smbfs/sock.c
Previous file: linux/fs/smbfs/mmap.c
Back to the patch index
Back to the overall index
- Lines: 1860
- Date:
Fri Aug 22 10:04:33 1997
- Orig file:
v2.1.51/linux/fs/smbfs/proc.c
- Orig date:
Mon Dec 30 01:54:12 1996
diff -u --recursive --new-file v2.1.51/linux/fs/smbfs/proc.c linux/fs/smbfs/proc.c
@@ -2,6 +2,7 @@
* proc.c
*
* Copyright (C) 1995, 1996 by Paal-Kr. Engstad and Volker Lendecke
+ * Copyright (C) 1997 by Volker Lendecke
*
* 28/06/96 - Fixed long file name support (smb_proc_readdir_long) by Yuri Per
*/
@@ -20,15 +21,15 @@
#include <asm/string.h>
#define SMB_VWV(packet) ((packet) + SMB_HEADER_LEN)
-#define SMB_CMD(packet) (BVAL(packet,8))
-#define SMB_WCT(packet) (BVAL(packet, SMB_HEADER_LEN - 1))
+#define SMB_CMD(packet) (*(packet+8))
+#define SMB_WCT(packet) (*(packet+SMB_HEADER_LEN - 1))
#define SMB_BCC(packet) smb_bcc(packet)
#define SMB_BUF(packet) ((packet) + SMB_HEADER_LEN + SMB_WCT(packet) * 2 + 2)
#define SMB_DIRINFO_SIZE 43
#define SMB_STATUS_SIZE 21
-static int smb_request_ok(struct smb_server *s, int command, int wct, int bcc);
+static int smb_request_ok(struct smb_sb_info *s, int command, int wct, int bcc);
static inline int
min(int a, int b)
@@ -64,132 +65,57 @@
/* */
/*****************************************************************************/
-static inline byte *
-smb_decode_word(byte * p, word * data)
-{
- *data = WVAL(p, 0);
- return p + 2;
-}
-
-byte *
-smb_encode_smb_length(byte * p, dword len)
+__u8 *
+smb_encode_smb_length(__u8 * p, __u32 len)
{
- BSET(p, 0, 0);
- BSET(p, 1, 0);
- BSET(p, 2, (len & 0xFF00) >> 8);
- BSET(p, 3, (len & 0xFF));
+ *p = 0;
+ *(p+1) = 0;
+ *(p+2) = (len & 0xFF00) >> 8;
+ *(p+3) = (len & 0xFF);
if (len > 0xFFFF)
{
- BSET(p, 1, 1);
+ *(p+1) = 1;
}
return p + 4;
}
-static byte *
-smb_encode_ascii(byte * p, const byte * name, int len)
+static int smb_d_path(struct dentry * entry, char * buf)
{
- *p++ = 4;
- strcpy(p, name);
- return p + len + 1;
-}
-
-static byte *
-smb_encode_this_name(byte * p, const char *name, const int len)
-{
- *p++ = '\\';
- strncpy(p, name, len);
- return p + len;
-}
+ if (IS_ROOT(entry)) {
+ *buf = '\\';
+ return 1;
+ } else {
+ int len = smb_d_path(entry->d_parent, buf);
-/* I put smb_encode_parents into a separate function so that the
- recursion only takes 16 bytes on the stack per path component on a
- 386. */
-
-static byte *
-smb_encode_parents(byte * p, struct smb_inode_info *ino)
-{
- byte *q;
-
- if (ino->dir == NULL)
- {
- return p;
- }
- q = smb_encode_parents(p, ino->dir);
- if (q - p + 1 + ino->finfo.len > SMB_MAXPATHLEN)
- {
- return p;
+ buf += len;
+ if (len > 1) {
+ *buf++ = '\\';
+ len++;
+ }
+ memcpy(buf, entry->d_name.name, entry->d_name.len);
+ return len + entry->d_name.len;
}
- return smb_encode_this_name(q, ino->finfo.name, ino->finfo.len);
}
-static byte *
-smb_encode_path(struct smb_server *server,
- byte * p, struct smb_inode_info *dir,
- const char *name, const int len)
+static char *smb_encode_path(struct smb_sb_info *server, char *buf,
+ struct inode *dir, struct qstr *name)
{
- byte *start = p;
- if (dir != NULL)
- {
- p = smb_encode_parents(p, dir);
- }
- p = smb_encode_this_name(p, name, len);
- *p++ = 0;
- if (server->protocol <= PROTOCOL_COREPLUS)
- {
- str_upper(start);
- }
- return p;
-}
+ char *start = buf;
-static byte *
-smb_decode_data(byte * p, byte * data, word * data_len, int fs)
-{
- word len;
+ if (dir != NULL)
+ buf += smb_d_path(i_dentry(dir), buf);
- if (!(*p == 1 || *p == 5))
- {
- printk("smb_decode_data: Warning! Data block not starting "
- "with 1 or 5\n");
+ if (name != NULL) {
+ *buf++ = '\\';
+ memcpy(buf, name->name, name->len);
+ buf += name->len;
+ *buf++ = 0;
}
- len = WVAL(p, 1);
- p += 3;
-
- if (fs)
- copy_to_user(data, p, len);
- else
- memcpy(data, p, len);
-
- *data_len = len;
-
- return p + len;
-}
-
-static byte *
-smb_name_mangle(byte * p, const byte * name)
-{
- int len, pad = 0;
-
- len = strlen(name);
-
- if (len < 16)
- pad = 16 - len;
- *p++ = 2 * (len + pad);
-
- while (*name)
- {
- *p++ = (*name >> 4) + 'A';
- *p++ = (*name & 0x0F) + 'A';
- name++;
- }
- while (pad--)
- {
- *p++ = 'C';
- *p++ = 'A';
- }
- *p++ = '\0';
+ if (server->opt.protocol <= SMB_PROTOCOL_COREPLUS)
+ str_upper(start);
- return p;
+ return buf;
}
/* The following are taken directly from msdos-fs */
@@ -235,7 +161,7 @@
/* Convert linear UNIX date to a MS-DOS time/date pair. */
static void
-date_unix2dos(int unix_date, byte * date, byte * time)
+date_unix2dos(int unix_date, __u8 * date, __u8 * time)
{
int day, year, nl_day, month;
@@ -271,16 +197,16 @@
/* */
/*****************************************************************************/
-dword
-smb_len(byte * p)
+__u32
+smb_len(__u8 * p)
{
- return ((BVAL(p, 1) & 0x1) << 16L) | (BVAL(p, 2) << 8L) | (BVAL(p, 3));
+ return ((*(p+1) & 0x1) << 16L) | (*(p+2) << 8L) | *(p+3);
}
-static word
-smb_bcc(byte * packet)
+static __u16
+smb_bcc(__u8 * packet)
{
- int pos = SMB_HEADER_LEN + SMB_WCT(packet) * sizeof(word);
+ int pos = SMB_HEADER_LEN + SMB_WCT(packet) * sizeof(__u16);
return WVAL(packet, pos);
}
@@ -288,10 +214,8 @@
requirements of a smb packet */
static int
-smb_valid_packet(byte * packet)
+smb_valid_packet(__u8 * packet)
{
- DDPRINTK("len: %d, wct: %d, bcc: %d\n",
- smb_len(packet), SMB_WCT(packet), SMB_BCC(packet));
return (packet[4] == 0xff
&& packet[5] == 'S'
&& packet[6] == 'M'
@@ -304,7 +228,7 @@
got enough data. If bcc == -1, we don't care. */
static int
-smb_verify(byte * packet, int command, int wct, int bcc)
+smb_verify(__u8 * packet, int command, int wct, int bcc)
{
return (SMB_CMD(packet) == command &&
SMB_WCT(packet) >= wct &&
@@ -404,23 +328,16 @@
return 0;
}
-static void
-smb_lock_server(struct smb_server *server)
+static inline void
+smb_lock_server(struct smb_sb_info *server)
{
- while (server->lock)
- sleep_on(&server->wait);
- server->lock = 1;
+ down(&(server->sem));
}
-static void
-smb_unlock_server(struct smb_server *server)
+static inline void
+smb_unlock_server(struct smb_sb_info *server)
{
- if (server->lock != 1)
- {
- printk("smb_unlock_server: was not locked!\n");
- }
- server->lock = 0;
- wake_up(&server->wait);
+ up(&(server->sem));
}
/* smb_request_ok: We expect the server to be locked. Then we do the
@@ -429,7 +346,7 @@
the answer is <=0, the returned number is a valid unix errno. */
static int
-smb_request_ok(struct smb_server *s, int command, int wct, int bcc)
+smb_request_ok(struct smb_sb_info *s, int command, int wct, int bcc)
{
int result = 0;
s->rcls = 0;
@@ -437,18 +354,18 @@
if (smb_request(s) < 0)
{
- DPRINTK("smb_request failed\n");
+ pr_debug("smb_request failed\n");
result = -EIO;
} else if (smb_valid_packet(s->packet) != 0)
{
- DPRINTK("not a valid packet!\n");
+ pr_debug("not a valid packet!\n");
result = -EIO;
} else if (s->rcls != 0)
{
result = -smb_errno(s->rcls, s->err);
} else if (smb_verify(s->packet, command, wct, bcc) != 0)
{
- DPRINTK("smb_verify failed\n");
+ pr_debug("smb_verify failed\n");
result = -EIO;
}
return result;
@@ -461,69 +378,111 @@
of any use. */
static int
-smb_retry(struct smb_server *server)
+smb_retry(struct smb_sb_info *server)
{
if (server->state != CONN_INVALID)
{
return 0;
}
- if (smb_release(server) < 0)
+ if (server->sock_file != NULL)
{
- DPRINTK("smb_retry: smb_release failed\n");
- server->state = CONN_RETRIED;
- return 0;
+ close_fp(server->sock_file);
+ server->sock_file = NULL;
}
- if (smb_proc_reconnect(server) < 0)
+
+ if (server->conn_pid == 0)
{
- DPRINTK("smb_proc_reconnect failed\n");
server->state = CONN_RETRIED;
return 0;
}
- server->state = CONN_VALID;
- return 1;
+
+ kill_proc(server->conn_pid, SIGUSR1, 0);
+ server->conn_pid = 0;
+
+ smb_lock_server(server);
+
+ if (server->sock_file != NULL)
+ {
+ server->state = CONN_VALID;
+ return 1;
+ }
+ return 0;
}
-static int
-smb_request_ok_unlock(struct smb_server *s, int command, int wct, int bcc)
+int
+smb_offerconn(struct smb_sb_info *server)
{
- int result = smb_request_ok(s, command, wct, bcc);
+ if (!suser() && (current->uid != server->m.mounted_uid))
+ {
+ return -EACCES;
+ }
+ server->conn_pid = current->pid;
+ return 0;
+}
- smb_unlock_server(s);
+int
+smb_newconn(struct smb_sb_info *server, struct smb_conn_opt *opt)
+{
+ struct file *filp;
- return result;
+ if (opt->fd >= NR_OPEN || !(filp = current->files->fd[opt->fd]))
+ {
+ return -EBADF;
+ }
+ if (!S_ISSOCK(filp->f_dentry->d_inode->i_mode))
+ {
+ return -EBADF;
+ }
+ if (!suser() && (current->uid != server->m.mounted_uid))
+ {
+ return -EACCES;
+ }
+ if (server->sock_file != NULL)
+ {
+ close_fp(server->sock_file);
+ server->sock_file = NULL;
+ }
+ filp->f_count += 1;
+ server->sock_file = filp;
+ smb_catch_keepalive(server);
+ server->opt = *opt;
+ pr_debug("smb_newconn: protocol = %d\n", server->opt.protocol);
+ server->conn_pid = 0;
+ server->generation += 1;
+ smb_unlock_server(server);
+ return 0;
}
/* smb_setup_header: We completely set up the packet. You only have to
insert the command-specific fields */
__u8 *
-smb_setup_header(struct smb_server * server, byte command, word wct, word bcc)
+smb_setup_header(struct smb_sb_info * server, __u8 command, __u16 wct, __u16 bcc)
{
- dword xmit_len = SMB_HEADER_LEN + wct * sizeof(word) + bcc + 2;
- byte *p = server->packet;
- byte *buf = server->packet;
+ __u32 xmit_len = SMB_HEADER_LEN + wct * sizeof(__u16) + bcc + 2;
+ __u8 *p = server->packet;
+ __u8 *buf = server->packet;
p = smb_encode_smb_length(p, xmit_len - 4);
- BSET(p, 0, 0xff);
- BSET(p, 1, 'S');
- BSET(p, 2, 'M');
- BSET(p, 3, 'B');
- BSET(p, 4, command);
+ *p++ = 0xff;
+ *p++ = 'S';
+ *p++ = 'M';
+ *p++ = 'B';
+ *p++ = command;
- p += 5;
memset(p, '\0', 19);
p += 19;
p += 8;
- WSET(buf, smb_tid, server->tid);
- WSET(buf, smb_pid, server->pid);
- WSET(buf, smb_uid, server->server_uid);
- WSET(buf, smb_mid, server->mid);
+ WSET(buf, smb_tid, server->opt.tid);
+ WSET(buf, smb_pid, 1);
+ WSET(buf, smb_uid, server->opt.server_uid);
+ WSET(buf, smb_mid, 1);
- if (server->protocol > PROTOCOL_CORE)
+ if (server->opt.protocol > SMB_PROTOCOL_CORE)
{
- BSET(buf, smb_flg, 0x8);
+ *(buf+smb_flg) = 0x8;
WSET(buf, smb_flg2, 0x3);
}
*p++ = wct; /* wct */
@@ -532,20 +491,8 @@
return p + 2;
}
-/* smb_setup_header_exclusive waits on server->lock and locks the
- server, when it's free. You have to unlock it manually when you're
- finished with server->packet! */
-
-static byte *
-smb_setup_header_exclusive(struct smb_server *server,
- byte command, word wct, word bcc)
-{
- smb_lock_server(server);
- return smb_setup_header(server, command, wct, bcc);
-}
-
static void
-smb_setup_bcc(struct smb_server *server, byte * p)
+smb_setup_bcc(struct smb_sb_info *server, __u8 * p)
{
__u8 *packet = server->packet;
__u8 *pbcc = packet + SMB_HEADER_LEN + 2 * SMB_WCT(packet);
@@ -557,101 +504,118 @@
}
-/*****************************************************************************/
-/* */
-/* File operation section. */
-/* */
-/*****************************************************************************/
+/*
+ * We're called with the server locked, and we leave it that way. We
+ * try maximum permissions.
+ */
-int
-smb_proc_open(struct smb_server *server,
- struct smb_inode_info *dir, const char *name, int len,
- struct smb_dirent *entry)
+static int
+smb_proc_open(struct inode *ino)
{
+ struct smb_sb_info *server = SMB_SERVER(ino);
int error;
char *p;
- char *buf;
- const word o_attr = aSYSTEM | aHIDDEN | aDIR;
-
- DPRINTK("smb_proc_open: name=%s\n", name);
-
- smb_lock_server(server);
- if (entry->opened != 0)
- {
- /* Somebody else opened the file while we slept */
- smb_unlock_server(server);
- return 0;
- }
retry:
- buf = server->packet;
p = smb_setup_header(server, SMBopen, 2, 0);
- WSET(buf, smb_vwv0, 0x42); /* read/write */
- WSET(buf, smb_vwv1, o_attr);
+ WSET(server->packet, smb_vwv0, 0x42); /* read/write */
+ WSET(server->packet, smb_vwv1, aSYSTEM | aHIDDEN | aDIR);
*p++ = 4;
- p = smb_encode_path(server, p, dir, name, len);
+ p = smb_encode_path(server, p, ino, NULL);
smb_setup_bcc(server, p);
if ((error = smb_request_ok(server, SMBopen, 7, 0)) != 0)
{
-
if (smb_retry(server))
- {
goto retry;
- }
+
if ((error != -EACCES) && (error != -ETXTBSY)
&& (error != -EROFS))
- {
- smb_unlock_server(server);
return error;
- }
+
p = smb_setup_header(server, SMBopen, 2, 0);
- WSET(buf, smb_vwv0, 0x40); /* read only */
- WSET(buf, smb_vwv1, o_attr);
+ WSET(server->packet, smb_vwv0, 0x40); /* read only */
+ WSET(server->packet, smb_vwv1, aSYSTEM | aHIDDEN | aDIR);
*p++ = 4;
- p = smb_encode_path(server, p, dir, name, len);
+ p = smb_encode_path(server, p, ino, NULL);
smb_setup_bcc(server, p);
if ((error = smb_request_ok(server, SMBopen, 7, 0)) != 0)
{
if (smb_retry(server))
- {
goto retry;
- }
- smb_unlock_server(server);
+
return error;
}
}
/* We should now have data in vwv[0..6]. */
- entry->fileid = WVAL(buf, smb_vwv0);
- entry->attr = WVAL(buf, smb_vwv1);
- entry->f_ctime = entry->f_atime =
- entry->f_mtime = local2utc(DVAL(buf, smb_vwv2));
- entry->f_size = DVAL(buf, smb_vwv4);
- entry->access = WVAL(buf, smb_vwv6);
-
- entry->opened = 1;
- entry->access &= 3;
+ ino->u.smbfs_i.fileid = WVAL(server->packet, smb_vwv0);
+ ino->u.smbfs_i.attr = WVAL(server->packet, smb_vwv1);
+ ino->u.smbfs_i.access = WVAL(server->packet, smb_vwv6);
+ ino->u.smbfs_i.access &= 3;
- smb_unlock_server(server);
+ ino->u.smbfs_i.open = server->generation;
- DPRINTK("smb_proc_open: entry->access = %d\n", entry->access);
+ pr_debug("smb_proc_open: entry->access = %d\n", ino->u.smbfs_i.access);
return 0;
}
int
-smb_proc_close(struct smb_server *server,
- __u16 fileid, __u32 mtime)
+smb_open(struct inode *i, int wish)
{
- char *buf;
+ struct smb_sb_info *server = SMB_SERVER(i);
+ int result = -EACCES;
- smb_setup_header_exclusive(server, SMBclose, 3, 0);
- buf = server->packet;
- WSET(buf, smb_vwv0, fileid);
- DSET(buf, smb_vwv1, utc2local(mtime));
+ smb_lock_server(server);
+
+ if (!smb_is_open(i)) {
+ int error = smb_proc_open(i);
+ if (error) {
+ smb_unlock_server(server);
+ return error;
+ }
+ }
+
+ if (((wish == O_RDONLY) && ((i->u.smbfs_i.access == O_RDONLY)
+ || (i->u.smbfs_i.access == O_RDWR)))
+ || ((wish == O_WRONLY) && ((i->u.smbfs_i.access == O_WRONLY)
+ || (i->u.smbfs_i.access == O_RDWR)))
+ || ((wish == O_RDWR) && (i->u.smbfs_i.access == O_RDWR)))
+ result = 0;
- return smb_request_ok_unlock(server, SMBclose, 0, 0);
+ smb_unlock_server(server);
+ return result;
+}
+
+/* We're called with the server locked */
+
+static int smb_proc_close(struct smb_sb_info *server,
+ __u16 fileid, __u32 mtime)
+{
+ smb_setup_header(server, SMBclose, 3, 0);
+ WSET(server->packet, smb_vwv0, fileid);
+ DSET(server->packet, smb_vwv1, mtime);
+ return smb_request_ok(server, SMBclose, 0, 0);
+}
+
+
+int smb_close(struct inode *ino)
+{
+ struct smb_sb_info *server = SMB_SERVER(ino);
+ int result;
+
+ smb_lock_server(server);
+
+ if (!smb_is_open(ino)) {
+ smb_unlock_server(server);
+ return 0;
+ }
+
+ result = smb_proc_close(server, ino->u.smbfs_i.fileid, ino->i_mtime);
+ ino->u.smbfs_i.open = 0;
+ smb_unlock_server(server);
+ return result;
}
/* In smb_proc_read and smb_proc_write we do not retry, because the
@@ -661,17 +625,18 @@
copy_to_user. */
int
-smb_proc_read(struct smb_server *server, struct smb_dirent *finfo,
- off_t offset, long count, char *data, int fs)
+smb_proc_read(struct inode *ino, off_t offset, long count, char *data)
{
- word returned_count, data_len;
+ struct smb_sb_info *server = SMB_SERVER(ino);
+ __u16 returned_count, data_len;
char *buf;
int error;
- smb_setup_header_exclusive(server, SMBread, 5, 0);
+ smb_lock_server(server);
+ smb_setup_header(server, SMBread, 5, 0);
buf = server->packet;
- WSET(buf, smb_vwv0, finfo->fileid);
+ WSET(buf, smb_vwv0, ino->u.smbfs_i.fileid);
WSET(buf, smb_vwv1, count);
DSET(buf, smb_vwv2, offset);
WSET(buf, smb_vwv4, 0);
@@ -683,56 +648,56 @@
}
returned_count = WVAL(buf, smb_vwv0);
- smb_decode_data(SMB_BUF(server->packet), data, &data_len, fs);
+ buf = SMB_BUF(server->packet);
+ data_len = WVAL(buf, 1);
+
+ memcpy(data, buf+3, data_len);
smb_unlock_server(server);
if (returned_count != data_len)
{
- printk("smb_proc_read: Warning, returned_count != data_len\n");
- printk("smb_proc_read: ret_c=%d, data_len=%d\n",
+ printk(KERN_NOTICE "smb_proc_read: returned != data_len\n");
+ printk(KERN_NOTICE "smb_proc_read: ret_c=%d, data_len=%d\n",
returned_count, data_len);
}
return data_len;
}
int
-smb_proc_write(struct smb_server *server, struct smb_dirent *finfo,
- off_t offset, int count, const char *data)
+smb_proc_write(struct inode *ino, off_t offset, int count, const char *data)
{
+ struct smb_sb_info *server = SMB_SERVER(ino);
int res = 0;
- char *buf;
- byte *p;
+ __u8 *p;
- p = smb_setup_header_exclusive(server, SMBwrite, 5, count + 3);
- buf = server->packet;
- WSET(buf, smb_vwv0, finfo->fileid);
- WSET(buf, smb_vwv1, count);
- DSET(buf, smb_vwv2, offset);
- WSET(buf, smb_vwv4, 0);
+ smb_lock_server(server);
+ p = smb_setup_header(server, SMBwrite, 5, count + 3);
+ WSET(server->packet, smb_vwv0, ino->u.smbfs_i.fileid);
+ WSET(server->packet, smb_vwv1, count);
+ DSET(server->packet, smb_vwv2, offset);
+ WSET(server->packet, smb_vwv4, 0);
*p++ = 1;
WSET(p, 0, count);
- copy_from_user(p + 2, data, count);
+ memcpy(p+2, data, count);
if ((res = smb_request_ok(server, SMBwrite, 1, 0)) >= 0)
- {
- res = WVAL(buf, smb_vwv0);
- }
+ res = WVAL(server->packet, smb_vwv0);
+
smb_unlock_server(server);
return res;
}
int
-smb_proc_create(struct inode *dir, const char *name, int len,
- word attr, time_t ctime)
+smb_proc_create(struct inode *dir, struct qstr *name,
+ __u16 attr, time_t ctime)
{
int error;
char *p;
- struct smb_server *server = SMB_SERVER(dir);
+ struct smb_sb_info *server = SMB_SERVER(dir);
char *buf;
- __u16 fileid;
smb_lock_server(server);
retry:
@@ -741,7 +706,7 @@
WSET(buf, smb_vwv0, attr);
DSET(buf, smb_vwv1, utc2local(ctime));
*p++ = 4;
- p = smb_encode_path(server, p, SMB_INOP(dir), name, len);
+ p = smb_encode_path(server, p, dir, name);
smb_setup_bcc(server, p);
if ((error = smb_request_ok(server, SMBcreate, 1, 0)) < 0)
@@ -753,20 +718,18 @@
smb_unlock_server(server);
return error;
}
- fileid = WVAL(buf, smb_vwv0);
+ smb_proc_close(server, WVAL(buf, smb_vwv0), CURRENT_TIME);
smb_unlock_server(server);
- smb_proc_close(server, fileid, CURRENT_TIME);
-
return 0;
}
int
-smb_proc_mv(struct inode *odir, const char *oname, const int olen,
- struct inode *ndir, const char *nname, const int nlen)
+smb_proc_mv(struct inode *odir, struct qstr *oname,
+ struct inode *ndir, struct qstr *nname)
{
char *p;
- struct smb_server *server = SMB_SERVER(odir);
+ struct smb_sb_info *server = SMB_SERVER(odir);
int result;
smb_lock_server(server);
@@ -775,9 +738,9 @@
p = smb_setup_header(server, SMBmv, 1, 0);
WSET(server->packet, smb_vwv0, aSYSTEM | aHIDDEN);
*p++ = 4;
- p = smb_encode_path(server, p, SMB_INOP(odir), oname, olen);
+ p = smb_encode_path(server, p, odir, oname);
*p++ = 4;
- p = smb_encode_path(server, p, SMB_INOP(ndir), nname, nlen);
+ p = smb_encode_path(server, p, ndir, nname);
smb_setup_bcc(server, p);
if ((result = smb_request_ok(server, SMBmv, 0, 0)) < 0)
@@ -792,18 +755,18 @@
}
int
-smb_proc_mkdir(struct inode *dir, const char *name, const int len)
+smb_proc_mkdir(struct inode *dir, struct qstr *name)
{
char *p;
int result;
- struct smb_server *server = SMB_SERVER(dir);
+ struct smb_sb_info *server = SMB_SERVER(dir);
smb_lock_server(server);
retry:
p = smb_setup_header(server, SMBmkdir, 0, 0);
*p++ = 4;
- p = smb_encode_path(server, p, SMB_INOP(dir), name, len);
+ p = smb_encode_path(server, p, dir, name);
smb_setup_bcc(server, p);
if ((result = smb_request_ok(server, SMBmkdir, 0, 0)) < 0)
@@ -818,18 +781,18 @@
}
int
-smb_proc_rmdir(struct inode *dir, const char *name, const int len)
+smb_proc_rmdir(struct inode *dir, struct qstr *name)
{
char *p;
int result;
- struct smb_server *server = SMB_SERVER(dir);
+ struct smb_sb_info *server = SMB_SERVER(dir);
smb_lock_server(server);
retry:
p = smb_setup_header(server, SMBrmdir, 0, 0);
*p++ = 4;
- p = smb_encode_path(server, p, SMB_INOP(dir), name, len);
+ p = smb_encode_path(server, p, dir, name);
smb_setup_bcc(server, p);
if ((result = smb_request_ok(server, SMBrmdir, 0, 0)) < 0)
@@ -844,10 +807,10 @@
}
int
-smb_proc_unlink(struct inode *dir, const char *name, const int len)
+smb_proc_unlink(struct inode *dir, struct qstr *name)
{
char *p;
- struct smb_server *server = SMB_SERVER(dir);
+ struct smb_sb_info *server = SMB_SERVER(dir);
int result;
smb_lock_server(server);
@@ -856,7 +819,7 @@
p = smb_setup_header(server, SMBunlink, 1, 0);
WSET(server->packet, smb_vwv0, aSYSTEM | aHIDDEN);
*p++ = 4;
- p = smb_encode_path(server, p, SMB_INOP(dir), name, len);
+ p = smb_encode_path(server, p, dir, name);
smb_setup_bcc(server, p);
if ((result = smb_request_ok(server, SMBunlink, 0, 0)) < 0)
@@ -871,7 +834,7 @@
}
int
-smb_proc_trunc(struct smb_server *server, word fid, dword length)
+smb_proc_trunc(struct smb_sb_info *server, __u16 fid, __u32 length)
{
char *p;
char *buf;
@@ -886,7 +849,8 @@
WSET(buf, smb_vwv1, 0);
DSET(buf, smb_vwv2, length);
WSET(buf, smb_vwv4, 0);
- p = smb_encode_ascii(p, "", 0);
+ *p++ = 4;
+ *p++ = 0;
smb_setup_bcc(server, p);
if ((result = smb_request_ok(server, SMBwrite, 1, 0)) < 0)
@@ -901,59 +865,60 @@
}
static void
-smb_init_dirent(struct smb_server *server, struct smb_dirent *entry)
+smb_init_dirent(struct smb_sb_info *server, struct smb_fattr *fattr)
{
- memset(entry, 0, sizeof(struct smb_dirent));
+ memset(fattr, 0, sizeof(*fattr));
- entry->f_nlink = 1;
- entry->f_uid = server->m.uid;
- entry->f_gid = server->m.gid;
- entry->f_blksize = 512;
+ fattr->f_nlink = 1;
+ fattr->f_uid = server->m.uid;
+ fattr->f_gid = server->m.gid;
+ fattr->f_blksize = 512;
}
static void
-smb_finish_dirent(struct smb_server *server, struct smb_dirent *entry)
+smb_finish_dirent(struct smb_sb_info *server, struct smb_fattr *fattr)
{
- if ((entry->attr & aDIR) != 0)
+ if (fattr->attr & aDIR)
{
- entry->f_mode = server->m.dir_mode;
- entry->f_size = 512;
+ fattr->f_mode = server->m.dir_mode;
+ fattr->f_size = 512;
} else
{
- entry->f_mode = server->m.file_mode;
+ fattr->f_mode = server->m.file_mode;
}
- if ((entry->f_blksize != 0) && (entry->f_size != 0))
+ if ((fattr->f_blksize != 0) && (fattr->f_size != 0))
{
- entry->f_blocks =
- (entry->f_size - 1) / entry->f_blksize + 1;
+ fattr->f_blocks =
+ (fattr->f_size - 1) / fattr->f_blksize + 1;
} else
{
- entry->f_blocks = 0;
+ fattr->f_blocks = 0;
}
return;
}
void
-smb_init_root_dirent(struct smb_server *server, struct smb_dirent *entry)
+smb_init_root_dirent(struct smb_sb_info *server, struct smb_fattr *fattr)
{
- smb_init_dirent(server, entry);
- entry->attr = aDIR;
- entry->f_ino = 1;
- smb_finish_dirent(server, entry);
+ smb_init_dirent(server, fattr);
+ fattr->attr = aDIR;
+ fattr->f_ino = 1;
+ smb_finish_dirent(server, fattr);
}
-static char *
-smb_decode_dirent(struct smb_server *server, char *p, struct smb_dirent *entry)
+static __u8 *
+smb_decode_dirent(struct smb_sb_info *server, __u8 *p,
+ struct smb_dirent *entry)
{
- smb_init_dirent(server, entry);
+ smb_init_dirent(server, &(entry->attr));
p += SMB_STATUS_SIZE; /* reserved (search_status) */
- entry->attr = BVAL(p, 0);
- entry->f_mtime = entry->f_atime = entry->f_ctime =
+ entry->attr.attr = *p;
+ entry->attr.f_mtime = entry->attr.f_atime = entry->attr.f_ctime =
date_dos2unix(WVAL(p, 1), WVAL(p, 3));
- entry->f_size = DVAL(p, 5);
+ entry->attr.f_size = DVAL(p, 5);
entry->len = strlen(p + 9);
if (entry->len > 12)
{
@@ -970,28 +935,28 @@
entry->name[entry->len] = '\0';
}
}
- switch (server->case_handling)
+ switch (server->opt.case_handling)
{
- case CASE_UPPER:
+ case SMB_CASE_UPPER:
str_upper(entry->name);
break;
- case CASE_LOWER:
+ case SMB_CASE_LOWER:
str_lower(entry->name);
break;
default:
break;
}
- DPRINTK("smb_decode_dirent: name = %s\n", entry->name);
- smb_finish_dirent(server, entry);
+ pr_debug("smb_decode_dirent: name = %s\n", entry->name);
+ smb_finish_dirent(server, &(entry->attr));
return p + 22;
}
/* This routine is used to read in directory entries from the network.
Note that it is for short directory name seeks, i.e.: protocol <
- PROTOCOL_LANMAN2 */
+ SMB_PROTOCOL_LANMAN2 */
static int
-smb_proc_readdir_short(struct smb_server *server, struct inode *dir, int fpos,
+smb_proc_readdir_short(struct smb_sb_info *server, struct inode *dir, int fpos,
int cache_size, struct smb_dirent *entry)
{
char *p;
@@ -1001,12 +966,14 @@
int i;
int first, total_count;
struct smb_dirent *current_entry;
- word bcc;
- word count;
+ __u16 bcc;
+ __u16 count;
char status[SMB_STATUS_SIZE];
- int entries_asked = (server->max_xmit - 100) / SMB_DIRINFO_SIZE;
+ int entries_asked = (server->opt.max_xmit - 100) / SMB_DIRINFO_SIZE;
+
+ static struct qstr mask = { "*.*", 3, 0 };
- DPRINTK("SMB call readdir %d @ %d\n", cache_size, fpos);
+ pr_debug("SMB call readdir %d @ %d\n", cache_size, fpos);
smb_lock_server(server);
@@ -1024,7 +991,7 @@
WSET(buf, smb_vwv0, entries_asked);
WSET(buf, smb_vwv1, aDIR);
*p++ = 4;
- p = smb_encode_path(server, p, SMB_INOP(dir), "*.*", 3);
+ p = smb_encode_path(server, p, dir, &mask);
*p++ = 5;
WSET(p, 0, 0);
p += 2;
@@ -1033,7 +1000,8 @@
p = smb_setup_header(server, SMBsearch, 2, 0);
WSET(buf, smb_vwv0, entries_asked);
WSET(buf, smb_vwv1, aDIR);
- p = smb_encode_ascii(p, "", 0);
+ *p++ = 4;
+ *p++ = 0;
*p++ = 5;
WSET(p, 0, SMB_STATUS_SIZE);
p += 2;
@@ -1061,8 +1029,8 @@
}
}
p = SMB_VWV(server->packet);
- p = smb_decode_word(p, &count);
- p = smb_decode_word(p, &bcc);
+ count = WVAL(p, 0);
+ bcc = WVAL(p, 2);
first = 0;
@@ -1076,8 +1044,7 @@
result = -EIO;
goto unlock_return;
}
- p += 3; /* Skipping VBLOCK header
- (5, length lo, length hi). */
+ p += 7;
/* Read the last entry into the status field. */
memcpy(status,
@@ -1092,8 +1059,8 @@
if (total_count < fpos)
{
p += SMB_DIRINFO_SIZE;
- DDPRINTK("smb_proc_readdir: skipped entry.\n");
- DDPRINTK(" total_count = %d\n"
+ pr_debug("smb_proc_readdir: skipped entry.\n");
+ pr_debug(" total_count = %d\n"
" i = %d, fpos = %d\n",
total_count, i, fpos);
} else if (total_count >= fpos + cache_size)
@@ -1105,8 +1072,8 @@
p = smb_decode_dirent(server, p,
current_entry);
current_entry->f_pos = total_count;
- DDPRINTK("smb_proc_readdir: entry->f_pos = "
- "%lu\n", entry->f_pos);
+ pr_debug("smb_proc_readdir: entry->f_pos = "
+ "%u\n", entry->f_pos);
current_entry += 1;
}
total_count += 1;
@@ -1123,52 +1090,52 @@
is used by OS/2. */
static char *
-smb_decode_long_dirent(struct smb_server *server, char *p,
+smb_decode_long_dirent(struct smb_sb_info *server, char *p,
struct smb_dirent *entry, int level)
{
char *result;
- smb_init_dirent(server, entry);
+ smb_init_dirent(server, &(entry->attr));
switch (level)
{
/* We might add more levels later... */
case 1:
- entry->len = BVAL(p, 26);
+ entry->len = *(p+26);
strncpy(entry->name, p + 27, entry->len);
entry->name[entry->len] = '\0';
- entry->f_size = DVAL(p, 16);
- entry->attr = BVAL(p, 24);
+ entry->attr.f_size = DVAL(p, 16);
+ entry->attr.attr = *(p+24);
- entry->f_ctime = date_dos2unix(WVAL(p, 6), WVAL(p, 4));
- entry->f_atime = date_dos2unix(WVAL(p, 10), WVAL(p, 8));
- entry->f_mtime = date_dos2unix(WVAL(p, 14), WVAL(p, 12));
- result = p + 28 + BVAL(p, 26);
+ entry->attr.f_ctime = date_dos2unix(WVAL(p, 6), WVAL(p, 4));
+ entry->attr.f_atime = date_dos2unix(WVAL(p, 10), WVAL(p, 8));
+ entry->attr.f_mtime = date_dos2unix(WVAL(p, 14), WVAL(p, 12));
+ result = p + 28 + *(p+26);
break;
default:
- DPRINTK("Unknown long filename format %d\n", level);
+ pr_debug("Unknown long filename format %d\n", level);
result = p + WVAL(p, 0);
}
- switch (server->case_handling)
+ switch (server->opt.case_handling)
{
- case CASE_UPPER:
+ case SMB_CASE_UPPER:
str_upper(entry->name);
break;
- case CASE_LOWER:
+ case SMB_CASE_LOWER:
str_lower(entry->name);
break;
default:
break;
}
- smb_finish_dirent(server, entry);
+ smb_finish_dirent(server, &(entry->attr));
return result;
}
-int
-smb_proc_readdir_long(struct smb_server *server, struct inode *dir, int fpos,
+static int
+smb_proc_readdir_long(struct smb_sb_info *server, struct inode *dir, int fpos,
int cache_size, struct smb_dirent *cache)
{
/* NT uses 260, OS/2 uses 2. Both accept 1. */
@@ -1199,16 +1166,17 @@
char param[SMB_MAXPATHLEN + 2 + 12];
int mask_len;
- unsigned char *mask = &(param[12]);
+ char *mask = &(param[12]);
+
+ static struct qstr star = { "*", 1, 0 };
- mask_len = smb_encode_path(server, mask,
- SMB_INOP(dir), "*", 1) - mask;
+ mask_len = smb_encode_path(server, mask, dir, &star) - mask;
mask[mask_len] = 0;
mask[mask_len + 1] = 0;
- DPRINTK("smb_readdir_long cache=%d, fpos=%d, mask=%s\n",
- cache_size, fpos, mask);
+ pr_debug("smb_readdir_long cache=%d, fpos=%d, mask=%s\n",
+ cache_size, fpos, mask);
smb_lock_server(server);
@@ -1223,7 +1191,7 @@
loop_count += 1;
if (loop_count > 200)
{
- printk("smb_proc_readdir_long: "
+ printk(KERN_WARNING "smb_proc_readdir_long: "
"Looping in FIND_NEXT??\n");
break;
}
@@ -1240,8 +1208,9 @@
} else
{
command = TRANSACT2_FINDNEXT;
- DPRINTK("hand=0x%X resume=%d ff_lastname=%d mask=%s\n",
- ff_dir_handle, ff_resume_key, ff_lastname, mask);
+ pr_debug("hand=0x%X resume=%d ff_lastnm=%d mask=%s\n",
+ ff_dir_handle, ff_resume_key, ff_lastname,
+ mask);
WSET(param, 0, ff_dir_handle);
WSET(param, 2, max_matches); /* max count */
WSET(param, 4, info_level);
@@ -1270,8 +1239,8 @@
{
goto retry;
}
- DPRINTK("smb_proc_readdir_long: "
- "got error from trans2_request\n");
+ pr_debug("smb_proc_readdir_long: "
+ "got error from trans2_request\n");
break;
}
if (server->rcls != 0)
@@ -1314,7 +1283,7 @@
break;
case 1:
lastname = p + ff_lastname + 1;
- lastname_len = BVAL(p, ff_lastname);
+ lastname_len = *(p+ff_lastname);
ff_resume_key = 0;
break;
}
@@ -1332,7 +1301,7 @@
p = smb_decode_long_dirent(server, p,
entry, info_level);
- DDPRINTK("smb_readdir_long: got %s\n", entry->name);
+ pr_debug("smb_readdir_long: got %s\n", entry->name);
if ((entry->name[0] == '.')
&& ((entry->name[1] == '\0')
@@ -1354,8 +1323,8 @@
entries_seen += 1;
}
- DPRINTK("received %d entries (eos=%d resume=%d)\n",
- ff_searchcount, ff_eos, ff_resume_key);
+ pr_debug("received %d entries (eos=%d resume=%d)\n",
+ ff_searchcount, ff_eos, ff_resume_key);
first = 0;
}
@@ -1366,10 +1335,12 @@
}
int
-smb_proc_readdir(struct smb_server *server, struct inode *dir, int fpos,
+smb_proc_readdir(struct inode *dir, int fpos,
int cache_size, struct smb_dirent *entry)
{
- if (server->protocol >= PROTOCOL_LANMAN2)
+ struct smb_sb_info *server = SMB_SERVER(dir);
+
+ if (server->opt.protocol >= SMB_PROTOCOL_LANMAN2)
return smb_proc_readdir_long(server, dir, fpos, cache_size,
entry);
else
@@ -1378,23 +1349,21 @@
}
static int
-smb_proc_getattr_core(struct inode *dir, const char *name, int len,
- struct smb_dirent *entry)
+smb_proc_getattr_core(struct inode *dir, struct qstr *name,
+ struct smb_fattr *attr)
{
int result;
char *p;
- struct smb_server *server = SMB_SERVER(dir);
+ struct smb_sb_info *server = SMB_SERVER(dir);
char *buf;
smb_lock_server(server);
- DDPRINTK("smb_proc_getattr: %s\n", name);
-
retry:
buf = server->packet;
p = smb_setup_header(server, SMBgetatr, 0, 0);
*p++ = 4;
- p = smb_encode_path(server, p, SMB_INOP(dir), name, len);
+ p = smb_encode_path(server, p, dir, name);
smb_setup_bcc(server, p);
if ((result = smb_request_ok(server, SMBgetatr, 10, 0)) < 0)
@@ -1406,20 +1375,20 @@
smb_unlock_server(server);
return result;
}
- entry->attr = WVAL(buf, smb_vwv0);
- entry->f_ctime = entry->f_atime =
- entry->f_mtime = local2utc(DVAL(buf, smb_vwv1));
+ attr->attr = WVAL(buf, smb_vwv0);
+ attr->f_ctime = attr->f_atime =
+ attr->f_mtime = local2utc(DVAL(buf, smb_vwv1));
- entry->f_size = DVAL(buf, smb_vwv3);
+ attr->f_size = DVAL(buf, smb_vwv3);
smb_unlock_server(server);
return 0;
}
static int
-smb_proc_getattr_trans2(struct inode *dir, const char *name, int len,
- struct smb_dirent *entry)
+smb_proc_getattr_trans2(struct inode *dir, struct qstr *name,
+ struct smb_fattr *attr)
{
- struct smb_server *server = SMB_SERVER(dir);
+ struct smb_sb_info *server = SMB_SERVER(dir);
char param[SMB_MAXPATHLEN + 20];
char *p;
int result;
@@ -1431,7 +1400,7 @@
WSET(param, 0, 1); /* Info level SMB_INFO_STANDARD */
DSET(param, 2, 0);
- p = smb_encode_path(server, param + 6, SMB_INOP(dir), name, len);
+ p = smb_encode_path(server, param + 6, dir, name);
smb_lock_server(server);
retry:
@@ -1459,41 +1428,34 @@
smb_unlock_server(server);
return -ENOENT;
}
- entry->f_ctime = date_dos2unix(WVAL(resp_data, 2),
- WVAL(resp_data, 0));
- entry->f_atime = date_dos2unix(WVAL(resp_data, 6),
- WVAL(resp_data, 4));
- entry->f_mtime = date_dos2unix(WVAL(resp_data, 10),
- WVAL(resp_data, 8));
- entry->f_size = DVAL(resp_data, 12);
- entry->attr = WVAL(resp_data, 20);
+ attr->f_ctime = date_dos2unix(WVAL(resp_data, 2),
+ WVAL(resp_data, 0));
+ attr->f_atime = date_dos2unix(WVAL(resp_data, 6),
+ WVAL(resp_data, 4));
+ attr->f_mtime = date_dos2unix(WVAL(resp_data, 10),
+ WVAL(resp_data, 8));
+ attr->f_size = DVAL(resp_data, 12);
+ attr->attr = WVAL(resp_data, 20);
smb_unlock_server(server);
return 0;
}
-int
-smb_proc_getattr(struct inode *dir, const char *name, int len,
- struct smb_dirent *entry)
+int smb_proc_getattr(struct inode *dir, struct qstr *name,
+ struct smb_fattr *fattr)
{
- struct smb_server *server = SMB_SERVER(dir);
+ struct smb_sb_info *server = SMB_SERVER(dir);
int result = 0;
- smb_init_dirent(server, entry);
+ smb_init_dirent(server, fattr);
- if (server->protocol >= PROTOCOL_LANMAN2)
- {
- result = smb_proc_getattr_trans2(dir, name, len, entry);
- }
- if ((server->protocol < PROTOCOL_LANMAN2) || (result < 0))
- {
- result = smb_proc_getattr_core(dir, name, len, entry);
- }
- smb_finish_dirent(server, entry);
+ if (server->opt.protocol >= SMB_PROTOCOL_LANMAN2)
+ result = smb_proc_getattr_trans2(dir, name, fattr);
- entry->len = len;
- memcpy(entry->name, name, len);
- /* entry->name is null terminated from smb_init_dirent */
+ if ((server->opt.protocol < SMB_PROTOCOL_LANMAN2) || (result < 0))
+ result = smb_proc_getattr_core(dir, name, fattr);
+
+ smb_finish_dirent(server, fattr);
return result;
}
@@ -1502,8 +1464,8 @@
/* In core protocol, there is only 1 time to be set, we use
entry->f_mtime, to make touch work. */
static int
-smb_proc_setattr_core(struct smb_server *server,
- struct inode *i, struct smb_dirent *new_finfo)
+smb_proc_setattr_core(struct smb_sb_info *server,
+ struct inode *i, struct smb_fattr *fattr)
{
char *p;
char *buf;
@@ -1514,29 +1476,25 @@
retry:
buf = server->packet;
p = smb_setup_header(server, SMBsetatr, 8, 0);
- WSET(buf, smb_vwv0, new_finfo->attr);
- DSET(buf, smb_vwv1, utc2local(new_finfo->f_mtime));
+ WSET(buf, smb_vwv0, fattr->attr);
+ DSET(buf, smb_vwv1, utc2local(fattr->f_mtime));
+ *p++ = 4;
+ p = smb_encode_path(server, p, i, NULL);
*p++ = 4;
- p = smb_encode_path(server, p,
- SMB_INOP(i)->dir, SMB_INOP(i)->finfo.name,
- SMB_INOP(i)->finfo.len);
- p = smb_encode_ascii(p, "", 0);
+ *p++ = 0;
smb_setup_bcc(server, p);
if ((result = smb_request_ok(server, SMBsetatr, 0, 0)) < 0)
- {
if (smb_retry(server))
- {
goto retry;
- }
- }
+
smb_unlock_server(server);
return result;
}
static int
-smb_proc_setattr_trans2(struct smb_server *server,
- struct inode *i, struct smb_dirent *new_finfo)
+smb_proc_setattr_trans2(struct smb_sb_info *server,
+ struct inode *i, struct smb_fattr *fattr)
{
char param[SMB_MAXPATHLEN + 20];
char data[26];
@@ -1550,16 +1508,14 @@
WSET(param, 0, 1); /* Info level SMB_INFO_STANDARD */
DSET(param, 2, 0);
- p = smb_encode_path(server, param + 6,
- SMB_INOP(i)->dir, SMB_INOP(i)->finfo.name,
- SMB_INOP(i)->finfo.len);
-
- date_unix2dos(new_finfo->f_ctime, &(data[0]), &(data[2]));
- date_unix2dos(new_finfo->f_atime, &(data[4]), &(data[6]));
- date_unix2dos(new_finfo->f_mtime, &(data[8]), &(data[10]));
- DSET(data, 12, new_finfo->f_size);
- DSET(data, 16, new_finfo->f_blksize);
- WSET(data, 20, new_finfo->attr);
+ p = smb_encode_path(server, param + 6, i, NULL);
+
+ date_unix2dos(fattr->f_ctime, &(data[0]), &(data[2]));
+ date_unix2dos(fattr->f_atime, &(data[4]), &(data[6]));
+ date_unix2dos(fattr->f_mtime, &(data[8]), &(data[10]));
+ DSET(data, 12, fattr->f_size);
+ DSET(data, 16, fattr->f_blksize);
+ WSET(data, 20, fattr->attr);
WSET(data, 22, 0);
smb_lock_server(server);
@@ -1575,39 +1531,34 @@
return -smb_errno(server->rcls, server->err);
}
if (result < 0)
- {
if (smb_retry(server))
- {
goto retry;
- }
- }
+
smb_unlock_server(server);
return 0;
}
int
-smb_proc_setattr(struct smb_server *server, struct inode *inode,
- struct smb_dirent *new_finfo)
+smb_proc_setattr(struct smb_sb_info *server, struct inode *inode,
+ struct smb_fattr *fattr)
{
int result;
- if (server->protocol >= PROTOCOL_LANMAN2)
- {
- result = smb_proc_setattr_trans2(server, inode, new_finfo);
- }
- if ((server->protocol < PROTOCOL_LANMAN2) || (result < 0))
- {
- result = smb_proc_setattr_core(server, inode, new_finfo);
- }
+ if (server->opt.protocol >= SMB_PROTOCOL_LANMAN2)
+ result = smb_proc_setattr_trans2(server, inode, fattr);
+
+ if ((server->opt.protocol < SMB_PROTOCOL_LANMAN2) || (result < 0))
+ result = smb_proc_setattr_core(server, inode, fattr);
+
return result;
}
int
-smb_proc_dskattr(struct super_block *super, struct smb_dskattr *attr)
+smb_proc_dskattr(struct super_block *sb, struct statfs *attr)
{
int error;
char *p;
- struct smb_server *server = &(SMB_SBP(super)->s_server);
+ struct smb_sb_info *server = &(sb->u.smbfs_sb);
smb_lock_server(server);
@@ -1617,351 +1568,26 @@
if ((error = smb_request_ok(server, SMBdskattr, 5, 0)) < 0)
{
if (smb_retry(server))
- {
goto retry;
- }
+
smb_unlock_server(server);
return error;
}
p = SMB_VWV(server->packet);
- p = smb_decode_word(p, &attr->total);
- p = smb_decode_word(p, &attr->allocblocks);
- p = smb_decode_word(p, &attr->blocksize);
- p = smb_decode_word(p, &attr->free);
+ attr->f_bsize = WVAL(p, 2) * WVAL(p, 4);
+ attr->f_blocks = WVAL(p, 0);
+ attr->f_bavail = attr->f_bfree = WVAL(p, 6);
smb_unlock_server(server);
return 0;
}
-/*****************************************************************************/
-/* */
-/* Mount/umount operations. */
-/* */
-/*****************************************************************************/
-
-struct smb_prots
-{
- enum smb_protocol prot;
- const char *name;
-};
-
-/* smb_proc_reconnect: We expect the server to be locked, so that you
- can call the routine from within smb_retry. The socket must be
- created, like after a user-level socket()-call. It may not be
- connected. */
-
-int
-smb_proc_reconnect(struct smb_server *server)
-{
- struct smb_prots prots[] =
- {
- {PROTOCOL_CORE, "PC NETWORK PROGRAM 1.0"},
- {PROTOCOL_COREPLUS, "MICROSOFT NETWORKS 1.03"},
-#ifdef LANMAN1
- {PROTOCOL_LANMAN1, "MICROSOFT NETWORKS 3.0"},
- {PROTOCOL_LANMAN1, "LANMAN1.0"},
-#endif
-#ifdef LANMAN2
- {PROTOCOL_LANMAN2, "LM1.2X002"},
-#endif
-#ifdef NT1
- {PROTOCOL_NT1, "NT LM 0.12"},
- {PROTOCOL_NT1, "NT LANMAN 1.0"},
-#endif
- {-1, NULL}};
- char dev[] = "A:";
- int i, plength;
- int max_xmit = 1024; /* Space needed for first request. */
- int given_max_xmit = server->m.max_xmit;
- int result;
- byte *p;
-
- if ((result = smb_connect(server)) < 0)
- {
- DPRINTK("smb_proc_reconnect: could not smb_connect\n");
- goto fail;
- }
- /* Here we assume that the connection is valid */
- server->state = CONN_VALID;
-
- if (server->packet != NULL)
- {
- smb_vfree(server->packet);
- server->packet_size = 0;
- }
- server->packet = smb_vmalloc(max_xmit);
-
- if (server->packet == NULL)
- {
- printk("smb_proc_connect: No memory! Bailing out.\n");
- result = -ENOMEM;
- goto fail;
- }
- server->packet_size = server->max_xmit = max_xmit;
-
- /*
- * Start with an RFC1002 session request packet.
- */
- p = server->packet + 4;
-
- p = smb_name_mangle(p, server->m.server_name);
- p = smb_name_mangle(p, server->m.client_name);
-
- smb_encode_smb_length(server->packet,
- (void *) p - (void *) (server->packet));
-
- server->packet[0] = 0x81; /* SESSION REQUEST */
-
- if (smb_catch_keepalive(server) < 0)
- {
- printk("smb_proc_connect: could not catch_keepalives\n");
- }
- if ((result = smb_request(server)) < 0)
- {
- DPRINTK("smb_proc_connect: Failed to send SESSION REQUEST.\n");
- smb_dont_catch_keepalive(server);
- goto fail;
- }
- if (server->packet[0] != 0x82)
- {
- printk("smb_proc_connect: Did not receive positive response "
- "(err = %x)\n",
- server->packet[0]);
- smb_dont_catch_keepalive(server);
- result = -EIO;
- goto fail;
- }
- DPRINTK("smb_proc_connect: Passed SESSION REQUEST.\n");
-
- /* Now we are ready to send a SMB Negotiate Protocol packet. */
- memset(server->packet, 0, SMB_HEADER_LEN);
-
- plength = 0;
- for (i = 0; prots[i].name != NULL; i++)
- {
- plength += strlen(prots[i].name) + 2;
- }
-
- smb_setup_header(server, SMBnegprot, 0, plength);
-
- p = SMB_BUF(server->packet);
-
- for (i = 0; prots[i].name != NULL; i++)
- {
- *p++ = 2;
- strcpy(p, prots[i].name);
- p += strlen(prots[i].name) + 1;
- }
-
- if ((result = smb_request_ok(server, SMBnegprot, 1, -1)) < 0)
- {
- DPRINTK("smb_proc_connect: Failure requesting SMBnegprot\n");
- smb_dont_catch_keepalive(server);
- goto fail;
- } else
- {
- DDPRINTK("smb_proc_connect: Request SMBnegprot..");
- }
-
- DDPRINTK("Verified!\n");
-
- p = SMB_VWV(server->packet);
- p = smb_decode_word(p, (word *) & i);
- server->protocol = prots[i].prot;
-
- DPRINTK("smb_proc_connect: Server wants %s protocol.\n",
- prots[i].name);
-
- if (server->protocol >= PROTOCOL_LANMAN1)
- {
-
- word passlen = strlen(server->m.password);
- word userlen = strlen(server->m.username);
-
- DPRINTK("smb_proc_connect: password = %s\n",
- server->m.password);
- DPRINTK("smb_proc_connect: usernam = %s\n",
- server->m.username);
- DPRINTK("smb_proc_connect: blkmode = %d\n",
- WVAL(server->packet, smb_vwv5));
-
- if (server->protocol >= PROTOCOL_NT1)
- {
- server->max_xmit = DVAL(server->packet, smb_vwv3 + 1);
- server->maxmux = WVAL(server->packet, smb_vwv1 + 1);
- server->maxvcs = WVAL(server->packet, smb_vwv2 + 1);
- server->blkmode = DVAL(server->packet, smb_vwv9 + 1);
- server->sesskey = DVAL(server->packet, smb_vwv7 + 1);
- } else
- {
- server->max_xmit = WVAL(server->packet, smb_vwv2);
- server->maxmux = WVAL(server->packet, smb_vwv3);
- server->maxvcs = WVAL(server->packet, smb_vwv4);
- server->blkmode = WVAL(server->packet, smb_vwv5);
- server->sesskey = DVAL(server->packet, smb_vwv6);
- }
-
- if (server->max_xmit < given_max_xmit)
- {
- /* We do not distinguish between the client
- requests and the server response. */
- given_max_xmit = server->max_xmit;
- }
- if (server->protocol >= PROTOCOL_NT1)
- {
- char *workgroup = server->m.domain;
- char *OS_id = "Unix";
- char *client_id = "ksmbfs";
-
- smb_setup_header(server, SMBsesssetupX, 13,
- 5 + userlen + passlen +
- strlen(workgroup) + strlen(OS_id) +
- strlen(client_id));
-
- WSET(server->packet, smb_vwv0, 0x00ff);
- WSET(server->packet, smb_vwv1, 0);
- WSET(server->packet, smb_vwv2, given_max_xmit);
- WSET(server->packet, smb_vwv3, 2);
- WSET(server->packet, smb_vwv4, server->pid);
- DSET(server->packet, smb_vwv5, server->sesskey);
- WSET(server->packet, smb_vwv7, passlen + 1);
- WSET(server->packet, smb_vwv8, 0);
- WSET(server->packet, smb_vwv9, 0);
-
- p = SMB_BUF(server->packet);
- strcpy(p, server->m.password);
- p += passlen + 1;
- strcpy(p, server->m.username);
- p += userlen + 1;
- strcpy(p, workgroup);
- p += strlen(p) + 1;
- strcpy(p, OS_id);
- p += strlen(p) + 1;
- strcpy(p, client_id);
- } else
- {
- smb_setup_header(server, SMBsesssetupX, 10,
- 2 + userlen + passlen);
-
- WSET(server->packet, smb_vwv0, 0x00ff);
- WSET(server->packet, smb_vwv1, 0);
- WSET(server->packet, smb_vwv2, given_max_xmit);
- WSET(server->packet, smb_vwv3, 2);
- WSET(server->packet, smb_vwv4, server->pid);
- DSET(server->packet, smb_vwv5, server->sesskey);
- WSET(server->packet, smb_vwv7, passlen + 1);
- WSET(server->packet, smb_vwv8, 0);
- WSET(server->packet, smb_vwv9, 0);
-
- p = SMB_BUF(server->packet);
- strcpy(p, server->m.password);
- p += passlen + 1;
- strcpy(p, server->m.username);
- }
-
- if ((result = smb_request_ok(server, SMBsesssetupX, 3, 0)) < 0)
- {
- DPRINTK("smb_proc_connect: SMBsessetupX failed\n");
- smb_dont_catch_keepalive(server);
- goto fail;
- }
- smb_decode_word(server->packet + 32, &(server->server_uid));
- } else
- {
- server->max_xmit = 0;
- server->maxmux = 0;
- server->maxvcs = 0;
- server->blkmode = 0;
- server->sesskey = 0;
- }
-
- /* Fine! We have a connection, send a tcon message. */
-
- smb_setup_header(server, SMBtcon, 0,
- 6 + strlen(server->m.service) +
- strlen(server->m.password) + strlen(dev));
-
- p = SMB_BUF(server->packet);
- p = smb_encode_ascii(p, server->m.service, strlen(server->m.service));
- p = smb_encode_ascii(p, server->m.password, strlen(server->m.password));
- p = smb_encode_ascii(p, dev, strlen(dev));
-
- if ((result = smb_request_ok(server, SMBtcon, 2, 0)) < 0)
- {
- DPRINTK("smb_proc_connect: SMBtcon not verified.\n");
- smb_dont_catch_keepalive(server);
- goto fail;
- }
- DDPRINTK("OK! Managed to set up SMBtcon!\n");
-
- p = SMB_VWV(server->packet);
-
- if (server->protocol <= PROTOCOL_COREPLUS)
- {
- word max_xmit;
-
- p = smb_decode_word(p, &max_xmit);
- server->max_xmit = max_xmit;
-
- if (server->max_xmit > given_max_xmit)
- {
- server->max_xmit = given_max_xmit;
- }
- } else
- {
- p += 2;
- }
-
- p = smb_decode_word(p, &server->tid);
-
- /* Ok, everything is fine. max_xmit does not include */
- /* the TCP-SMB header of 4 bytes. */
- server->max_xmit += 4;
-
- DPRINTK("max_xmit = %d, tid = %d\n", server->max_xmit, server->tid);
-
- /* Now make a new packet with the correct size. */
- smb_vfree(server->packet);
-
- server->packet = smb_vmalloc(server->max_xmit);
- if (server->packet == NULL)
- {
- printk("smb_proc_connect: No memory left in end of "
- "connection phase :-(\n");
- smb_dont_catch_keepalive(server);
- goto fail;
- }
- server->packet_size = server->max_xmit;
-
- DPRINTK("smb_proc_connect: Normal exit\n");
- return 0;
-
- fail:
- server->state = CONN_INVALID;
- return result;
-}
-
-/* smb_proc_reconnect: server->packet is allocated with
- server->max_xmit bytes if and only if we return >= 0 */
int
-smb_proc_connect(struct smb_server *server)
+smb_proc_disconnect(struct smb_sb_info *server)
{
int result;
smb_lock_server(server);
-
- result = smb_proc_reconnect(server);
-
- if ((result < 0) && (server->packet != NULL))
- {
- smb_vfree(server->packet);
- server->packet = NULL;
- }
+ smb_setup_header(server, SMBtdis, 0, 0);
+ result = smb_request_ok(server, SMBtdis, 0, 0);
smb_unlock_server(server);
return result;
-}
-
-int
-smb_proc_disconnect(struct smb_server *server)
-{
- smb_setup_header_exclusive(server, SMBtdis, 0, 0);
- return smb_request_ok_unlock(server, SMBtdis, 0, 0);
}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov