current->state = TASK_INTERRUPTIBLE; schedule_timeout(HZ/5); 
schedule_timeout_interruptible(msecs_to_jiffies(200)); 
smb_proc_readdir_long(struct file *filp, void *dirent, filldir_t filldir,		      struct smb_cache_control *ctl){	struct dentry *dir = filp->f_dentry;	struct smb_sb_info *server = server_from_dentry(dir);	struct qstr qname;	struct smb_fattr fattr;	unsigned char *p, *lastname;	char *mask, *param;	__u16 command;	int first, entries_seen;	/* Both NT and OS/2 accept info level 1 (but see note below). */	int info_level = 260;	const int max_matches = 512;	unsigned int ff_searchcount = 0;	unsigned int ff_eos = 0;	unsigned int ff_lastname = 0;	unsigned int ff_dir_handle = 0;	unsigned int loop_count = 0;	unsigned int mask_len, i;	int result;	struct smb_request *req;	unsigned char *name_buf;	static struct qstr star = {		.name	= "*",		.len	= 1,	};	lock_kernel();	/*	 * We always prefer unix style. Use info level 1 for older	 * servers that don't do 260.	 */	if (server->opt.capabilities & SMB_CAP_UNIX)		info_level = SMB_FIND_FILE_UNIX;	else if (server->opt.protocol < SMB_PROTOCOL_NT1)		info_level = 1;	result = -ENOMEM;	if (! (name_buf = kmalloc(SMB_MAXNAMELEN+2, GFP_KERNEL)))		goto out;	if (! (req = smb_alloc_request(server, server->opt.max_xmit)))		goto out_name;	param = req->rq_buffer;	/*	 * Encode the initial path	 */	mask = param + 12;	result = smb_encode_path(server, mask, SMB_MAXPATHLEN+1, dir, &star);	if (result <= 0)		goto out_free;	mask_len = result - 1;	/* mask_len is strlen, not #bytes */	result = 0;	first = 1;	VERBOSE("starting mask_len=%d, mask=%s\n", mask_len, mask);	entries_seen = 2;	ff_eos = 0;	while (ff_eos == 0) {		loop_count += 1;		if (loop_count > 10) {			printk(KERN_WARNING "smb_proc_readdir_long: "			       "Looping in FIND_NEXT??\n");			result = -EIO;			break;		}		if (first != 0) {			command = TRANSACT2_FINDFIRST;			WSET(param, 0, aSYSTEM | aHIDDEN | aDIR);			WSET(param, 2, max_matches);	/* max count */			WSET(param, 4, SMB_CLOSE_IF_END);			WSET(param, 6, info_level);			DSET(param, 8, 0);		} else {			command = TRANSACT2_FINDNEXT;			VERBOSE("handle=0x%X, lastname=%d, mask=%.*s\n",				ff_dir_handle, ff_lastname, mask_len, mask);			WSET(param, 0, ff_dir_handle);	/* search handle */			WSET(param, 2, max_matches);	/* max count */			WSET(param, 4, info_level);			DSET(param, 6, 0);			WSET(param, 10, SMB_CONTINUE_BIT|SMB_CLOSE_IF_END);		}		req->rq_trans2_command = command;		req->rq_ldata = 0;		req->rq_data  = NULL;		req->rq_lparm = 12 + mask_len + 1;		req->rq_parm  = param;		req->rq_flags = 0;		result = smb_add_request(req);		if (result < 0) {			PARANOIA("error=%d, breaking\n", result);			break;		}		if (req->rq_rcls == ERRSRV && req->rq_err == ERRerror) {			/* a damn Win95 bug - sometimes it clags if you 			   ask it too fast */			current->state = TASK_INTERRUPTIBLE;			schedule_timeout(HZ/5);			continue;                }		if (req->rq_rcls != 0) {			result = smb_errno(req);			PARANOIA("name=%s, result=%d, rcls=%d, err=%d\n",				 mask, result, req->rq_rcls, req->rq_err);			break;		}		/* parse out some important return info */		if (first != 0) {			ff_dir_handle = WVAL(req->rq_parm, 0);			ff_searchcount = WVAL(req->rq_parm, 2);			ff_eos = WVAL(req->rq_parm, 4);			ff_lastname = WVAL(req->rq_parm, 8);		} else {			ff_searchcount = WVAL(req->rq_parm, 0);			ff_eos = WVAL(req->rq_parm, 2);			ff_lastname = WVAL(req->rq_parm, 6);		}		if (ff_searchcount == 0)			break;		/* Now we are ready to parse smb directory entries. */		/* point to the data bytes */		p = req->rq_data;		for (i = 0; i < ff_searchcount; i++) {			/* make sure we stay within the buffer */			if (p >= req->rq_data + req->rq_ldata) {				printk(KERN_ERR "smb_proc_readdir_long: "				       "dirent pointer outside buffer! "				       "%p  %d@%p\n",				       p, req->rq_ldata, req->rq_data);				result = -EIO; /* always a comm. error? */				goto out_free;			}			p = smb_decode_long_dirent(server, p, info_level,						   &qname, &fattr, name_buf);			/* ignore . and .. from the server */			if (entries_seen == 2 && qname.name[0] == '.') {				if (qname.len == 1)					continue;				if (qname.name[1] == '.' && qname.len == 2)					continue;			}			if (!smb_fill_cache(filp, dirent, filldir, ctl, 					    &qname, &fattr))				;	/* stop reading? */			entries_seen++;		}		VERBOSE("received %d entries, eos=%d\n", ff_searchcount,ff_eos);		/*		 * We might need the lastname for continuations.		 *		 * Note that some servers (win95?) point to the filename and		 * others (NT4, Samba using NT1) to the dir entry. We assume		 * here that those who do not point to a filename do not need		 * this info to continue the listing.		 *		 * OS/2 needs this and talks infolevel 1.		 * NetApps want lastname with infolevel 260.		 * win2k want lastname with infolevel 260, and points to		 *       the record not to the name.		 * Samba+CifsUnixExt doesn't need lastname.		 *		 * Both are happy if we return the data they point to. So we do.		 * (FIXME: above is not true with win2k)		 */		mask_len = 0;		if (info_level != SMB_FIND_FILE_UNIX &&		    ff_lastname > 0 && ff_lastname < req->rq_ldata) {			lastname = req->rq_data + ff_lastname;			switch (info_level) {			case 260:				mask_len = req->rq_ldata - ff_lastname;				break;			case 1:				/* lastname points to a length byte */				mask_len = *lastname++;				if (ff_lastname + 1 + mask_len > req->rq_ldata)					mask_len = req->rq_ldata - ff_lastname - 1;				break;			}			/*			 * Update the mask string for the next message.			 */			if (mask_len > 255)				mask_len = 255;			if (mask_len)				strncpy(mask, lastname, mask_len);		}		mask_len = strnlen(mask, mask_len);		VERBOSE("new mask, len=%d@%d of %d, mask=%.*s\n",			mask_len, ff_lastname, req->rq_ldata, mask_len, mask);		first = 0;		loop_count = 0;	}out_free:	smb_rput(req);out_name:	kfree(name_buf);out:	unlock_kernel();	return result;}
10457	/local/tlutelli/issta_data/temp/c/2005_temp/2005/10457/041e0e3b1970c508dc9a95b7dd9dc86271a7d7ac/proc.c/clean/fs/smbfs/proc.c