patch-2.1.81 linux/fs/smbfs/proc.c
Next file: linux/fs/super.c
Previous file: linux/fs/smbfs/inode.c
Back to the patch index
Back to the overall index
- Lines: 238
- Date:
Wed Jan 21 10:09:31 1998
- Orig file:
v2.1.80/linux/fs/smbfs/proc.c
- Orig date:
Fri Dec 19 10:53:29 1997
diff -u --recursive --new-file v2.1.80/linux/fs/smbfs/proc.c linux/fs/smbfs/proc.c
@@ -531,7 +531,8 @@
if (server->state == CONN_VALID)
{
#ifdef SMBFS_PARANOIA
-printk("smb_retry: new connection pid=%d\n", server->conn_pid);
+printk("smb_retry: new pid=%d, generation=%d\n",
+server->conn_pid, server->generation);
#endif
result = 1;
}
@@ -643,25 +644,17 @@
}
server->conn_pid = current->pid;
-#ifdef SMBFS_PARANOIA
-if (server->sock_file)
-printk("smb_newconn: old socket not closed!\n");
-#endif
-
filp->f_count += 1;
server->sock_file = filp;
smb_catch_keepalive(server);
server->opt = *opt;
-#ifdef SMBFS_DEBUG_VERBOSE
-printk("smb_newconn: protocol=%d, max_xmit=%d\n",
-server->opt.protocol, server->opt.max_xmit);
-#endif
server->generation += 1;
server->state = CONN_VALID;
-#ifdef SMBFS_PARANOIA
-printk("smb_newconn: state valid, pid=%d\n", server->conn_pid);
-#endif
error = 0;
+#ifdef SMBFS_DEBUG_VERBOSE
+printk("smb_newconn: protocol=%d, max_xmit=%d, pid=%d\n",
+server->opt.protocol, server->opt.max_xmit, server->conn_pid);
+#endif
out:
wake_up_interruptible(&server->wait);
@@ -987,9 +980,9 @@
file-id would not be valid after a reconnection. */
int
-smb_proc_read(struct inode *ino, off_t offset, int count, char *data)
+smb_proc_read(struct dentry *dentry, off_t offset, int count, char *data)
{
- struct smb_sb_info *server = SMB_SERVER(ino);
+ struct smb_sb_info *server = server_from_dentry(dentry);
__u16 returned_count, data_len;
char *buf;
int result;
@@ -997,7 +990,7 @@
smb_lock_server(server);
smb_setup_header(server, SMBread, 5, 0);
buf = server->packet;
- WSET(buf, smb_vwv0, ino->u.smbfs_i.fileid);
+ WSET(buf, smb_vwv0, dentry->d_inode->u.smbfs_i.fileid);
WSET(buf, smb_vwv1, count);
DSET(buf, smb_vwv2, offset);
WSET(buf, smb_vwv4, 0);
@@ -1022,29 +1015,27 @@
out:
#ifdef SMBFS_DEBUG_VERBOSE
printk("smb_proc_read: file %s/%s, count=%d, result=%d\n",
-((struct dentry *) ino->u.smbfs_i.dentry)->d_parent->d_name.name,
-((struct dentry *) ino->u.smbfs_i.dentry)->d_name.name, count, result);
+dentry->d_parent->d_name.name, dentry->d_name.name, count, result);
#endif
smb_unlock_server(server);
return result;
}
int
-smb_proc_write(struct inode *ino, off_t offset, int count, const char *data)
+smb_proc_write(struct dentry *dentry, off_t offset, int count, const char *data)
{
- struct smb_sb_info *server = SMB_SERVER(ino);
+ struct smb_sb_info *server = server_from_dentry(dentry);
int result;
__u8 *p;
- smb_lock_server(server);
#if SMBFS_DEBUG_VERBOSE
printk("smb_proc_write: file %s/%s, count=%d@%ld, packet_size=%d\n",
-((struct dentry *)ino->u.smbfs_i.dentry)->d_parent->d_name.name,
-((struct dentry *)ino->u.smbfs_i.dentry)->d_name.name,
+dentry->d_parent->d_name.name, dentry->d_name.name,
count, offset, server->packet_size);
#endif
+ 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_vwv0, dentry->d_inode->u.smbfs_i.fileid);
WSET(server->packet, smb_vwv1, count);
DSET(server->packet, smb_vwv2, offset);
WSET(server->packet, smb_vwv4, 0);
@@ -1544,9 +1535,10 @@
* Check whether to change the info level. There appears to be
* a bug in Win NT 4.0's handling of info level 1, whereby it
* truncates the directory scan for certain patterns of files.
- * Hence we use level 259 for NT. (And Win 95 as well ...)
+ * Hence we use level 259 for NT.
*/
- if (server->opt.protocol >= SMB_PROTOCOL_NT1)
+ if (server->opt.protocol >= SMB_PROTOCOL_NT1 &&
+ !(server->mnt->version & SMB_FIX_WIN95))
info_level = 259;
smb_lock_server(server);
@@ -1639,8 +1631,8 @@
if (server->rcls != 0)
{
#ifdef SMBFS_PARANOIA
-printk("smb_proc_readdir_long: rcls=%d, err=%d, breaking\n",
-server->rcls, server->err);
+printk("smb_proc_readdir_long: name=%s, entries=%d, rcls=%d, err=%d\n",
+mask, entries, server->rcls, server->err);
#endif
entries = -smb_errno(server);
break;
@@ -1750,6 +1742,94 @@
}
/*
+ * This version uses the trans2 TRANSACT2_FINDFIRST message
+ * to get the attribute data.
+ * Note: called with the server locked.
+ *
+ * Bugs Noted:
+ */
+static int
+smb_proc_getattr_ff(struct smb_sb_info *server, struct dentry *dentry,
+ struct smb_fattr *fattr)
+{
+ char *param = server->temp_buf, *mask = param + 12;
+ __u16 date, time;
+ unsigned char *resp_data = NULL;
+ unsigned char *resp_param = NULL;
+ int resp_data_len = 0;
+ int resp_param_len = 0;
+ int mask_len, result;
+
+retry:
+ mask_len = smb_encode_path(server, mask, dentry, NULL) - mask;
+#ifdef SMBFS_DEBUG_VERBOSE
+printk("smb_proc_getattr_ff: name=%s, len=%d\n", mask, mask_len);
+#endif
+ WSET(param, 0, aSYSTEM | aHIDDEN | aDIR);
+ WSET(param, 2, 1); /* max count */
+ WSET(param, 4, 1); /* close after this call */
+ WSET(param, 6, 1); /* info_level */
+ DSET(param, 8, 0);
+
+ result = smb_trans2_request(server, TRANSACT2_FINDFIRST,
+ 0, NULL, 12 + mask_len + 1, param,
+ &resp_data_len, &resp_data,
+ &resp_param_len, &resp_param);
+ if (result < 0)
+ {
+ if (smb_retry(server))
+ goto retry;
+ goto out;
+ }
+ if (server->rcls != 0)
+ {
+ result = -smb_errno(server);
+#ifdef SMBFS_PARANOIA
+if (result != -ENOENT)
+printk("smb_proc_getattr_ff: error for %s, rcls=%d, err=%d\n",
+mask, server->rcls, server->err);
+#endif
+ goto out;
+ }
+ /* Make sure we got enough data ... */
+ result = -EINVAL;
+ if (resp_data_len < 22 || WVAL(resp_param, 2) != 1)
+ {
+#ifdef SMBFS_PARANOIA
+printk("smb_proc_getattr_ff: bad result for %s, len=%d, count=%d\n",
+mask, resp_data_len, WVAL(resp_param, 2));
+#endif
+ goto out;
+ }
+
+ /*
+ * Decode the response into the fattr ...
+ */
+ date = WVAL(resp_data, 0);
+ time = WVAL(resp_data, 2);
+ fattr->f_ctime = date_dos2unix(date, time);
+
+ date = WVAL(resp_data, 4);
+ time = WVAL(resp_data, 6);
+ fattr->f_atime = date_dos2unix(date, time);
+
+ date = WVAL(resp_data, 8);
+ time = WVAL(resp_data, 10);
+ fattr->f_mtime = date_dos2unix(date, time);
+#ifdef SMBFS_DEBUG_VERBOSE
+printk("smb_proc_getattr_ff: name=%s, date=%x, time=%x, mtime=%ld\n",
+mask, date, time, fattr->f_mtime);
+#endif
+ fattr->f_size = DVAL(resp_data, 12);
+ /* ULONG allocation size */
+ fattr->attr = WVAL(resp_data, 20);
+ result = 0;
+
+out:
+ return result;
+}
+
+/*
* Note: called with the server locked.
*/
static int
@@ -1883,11 +1963,17 @@
* Win 95 is painfully slow at returning trans2 getattr info,
* so we provide the SMB_FIX_OLDATTR option switch.
*/
- if (server->opt.protocol >= SMB_PROTOCOL_LANMAN2 &&
- !(server->mnt->version & SMB_FIX_OLDATTR))
- result = smb_proc_getattr_trans2(server, dir, fattr);
- else
+ if (server->opt.protocol >= SMB_PROTOCOL_LANMAN2) {
+ if (server->mnt->version & SMB_FIX_OLDATTR)
+ goto core_attr;
+ if (server->mnt->version & SMB_FIX_DIRATTR)
+ result = smb_proc_getattr_ff(server, dir, fattr);
+ else
+ result = smb_proc_getattr_trans2(server, dir, fattr);
+ } else {
+ core_attr:
result = smb_proc_getattr_core(server, dir, fattr);
+ }
smb_finish_dirent(server, fattr);
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov