Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit be4ccdcc authored by Al Viro's avatar Al Viro
Browse files

[readdir] convert cifs



Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
parent 9b5d5a17
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -968,7 +968,7 @@ const struct file_operations cifs_file_direct_nobrl_ops = {
};

const struct file_operations cifs_dir_ops = {
	.readdir = cifs_readdir,
	.iterate = cifs_readdir,
	.release = cifs_closedir,
	.read    = generic_read_dir,
	.unlocked_ioctl  = cifs_ioctl,
+1 −1
Original line number Diff line number Diff line
@@ -101,7 +101,7 @@ extern int cifs_file_mmap(struct file * , struct vm_area_struct *);
extern int cifs_file_strict_mmap(struct file * , struct vm_area_struct *);
extern const struct file_operations cifs_dir_ops;
extern int cifs_dir_open(struct inode *inode, struct file *file);
extern int cifs_readdir(struct file *file, void *direntry, filldir_t filldir);
extern int cifs_readdir(struct file *file, struct dir_context *ctx);

/* Functions related to dir entries */
extern const struct dentry_operations cifs_dentry_ops;
+80 −98
Original line number Diff line number Diff line
@@ -537,14 +537,14 @@ static int cifs_save_resume_key(const char *current_entry,
 * every entry (do not increment for . or .. entry).
 */
static int
find_cifs_entry(const unsigned int xid, struct cifs_tcon *tcon,
find_cifs_entry(const unsigned int xid, struct cifs_tcon *tcon, loff_t pos,
		struct file *file, char **current_entry, int *num_to_ret)
{
	__u16 search_flags;
	int rc = 0;
	int pos_in_buf = 0;
	loff_t first_entry_in_buffer;
	loff_t index_to_find = file->f_pos;
	loff_t index_to_find = pos;
	struct cifsFileInfo *cfile = file->private_data;
	struct cifs_sb_info *cifs_sb = CIFS_SB(file->f_path.dentry->d_sb);
	struct TCP_Server_Info *server = tcon->ses->server;
@@ -659,8 +659,9 @@ find_cifs_entry(const unsigned int xid, struct cifs_tcon *tcon,
	return rc;
}

static int cifs_filldir(char *find_entry, struct file *file, filldir_t filldir,
		void *dirent, char *scratch_buf, unsigned int max_len)
static int cifs_filldir(char *find_entry, struct file *file,
		struct dir_context *ctx,
		char *scratch_buf, unsigned int max_len)
{
	struct cifsFileInfo *file_info = file->private_data;
	struct super_block *sb = file->f_path.dentry->d_sb;
@@ -740,13 +741,11 @@ static int cifs_filldir(char *find_entry, struct file *file, filldir_t filldir,
	cifs_prime_dcache(file->f_dentry, &name, &fattr);

	ino = cifs_uniqueid_to_ino_t(fattr.cf_uniqueid);
	rc = filldir(dirent, name.name, name.len, file->f_pos, ino,
		     fattr.cf_dtype);
	return rc;
	return !dir_emit(ctx, name.name, name.len, ino, fattr.cf_dtype);
}


int cifs_readdir(struct file *file, void *direntry, filldir_t filldir)
int cifs_readdir(struct file *file, struct dir_context *ctx)
{
	int rc = 0;
	unsigned int xid;
@@ -772,24 +771,9 @@ int cifs_readdir(struct file *file, void *direntry, filldir_t filldir)
			goto rddir2_exit;
	}

	switch ((int) file->f_pos) {
	case 0:
		if (filldir(direntry, ".", 1, file->f_pos,
		     file_inode(file)->i_ino, DT_DIR) < 0) {
			cifs_dbg(VFS, "Filldir for current dir failed\n");
			rc = -ENOMEM;
			break;
		}
		file->f_pos++;
	case 1:
		if (filldir(direntry, "..", 2, file->f_pos,
		     parent_ino(file->f_path.dentry), DT_DIR) < 0) {
			cifs_dbg(VFS, "Filldir for parent dir failed\n");
			rc = -ENOMEM;
			break;
		}
		file->f_pos++;
	default:
	if (!dir_emit_dots(file, ctx))
		goto rddir2_exit;

	/* 1) If search is active,
		is in current search buffer?
		if it before then restart search
@@ -797,15 +781,14 @@ int cifs_readdir(struct file *file, void *direntry, filldir_t filldir)

	if (file->private_data == NULL) {
		rc = -EINVAL;
			free_xid(xid);
			return rc;
		goto rddir2_exit;
	}
	cifsFile = file->private_data;
	if (cifsFile->srch_inf.endOfSearch) {
		if (cifsFile->srch_inf.emptyDir) {
			cifs_dbg(FYI, "End of search, empty dir\n");
			rc = 0;
				break;
			goto rddir2_exit;
		}
	} /* else {
		cifsFile->invalidHandle = true;
@@ -813,13 +796,13 @@ int cifs_readdir(struct file *file, void *direntry, filldir_t filldir)
	} */

	tcon = tlink_tcon(cifsFile->tlink);
		rc = find_cifs_entry(xid, tcon, file, &current_entry,
	rc = find_cifs_entry(xid, tcon, ctx->pos, file, &current_entry,
			     &num_to_fill);
	if (rc) {
		cifs_dbg(FYI, "fce error %d\n", rc);
		goto rddir2_exit;
	} else if (current_entry != NULL) {
			cifs_dbg(FYI, "entry %lld found\n", file->f_pos);
		cifs_dbg(FYI, "entry %lld found\n", ctx->pos);
	} else {
		cifs_dbg(FYI, "could not find entry\n");
		goto rddir2_exit;
@@ -833,10 +816,10 @@ int cifs_readdir(struct file *file, void *direntry, filldir_t filldir)
	tmp_buf = kmalloc(UNICODE_NAME_MAX, GFP_KERNEL);
	if (tmp_buf == NULL) {
		rc = -ENOMEM;
			break;
		goto rddir2_exit;
	}

		for (i = 0; (i < num_to_fill) && (rc == 0); i++) {
	for (i = 0; i < num_to_fill; i++) {
		if (current_entry == NULL) {
			/* evaluate whether this case is an error */
			cifs_dbg(VFS, "past SMB end,  num to fill %d i %d\n",
@@ -847,18 +830,19 @@ int cifs_readdir(struct file *file, void *direntry, filldir_t filldir)
		 * if buggy server returns . and .. late do we want to
		 * check for that here?
		 */
			rc = cifs_filldir(current_entry, file, filldir,
					  direntry, tmp_buf, max_len);
			if (rc == -EOVERFLOW) {
		rc = cifs_filldir(current_entry, file, ctx,
				  tmp_buf, max_len);
		if (rc) {
			if (rc > 0)
				rc = 0;
			break;
		}

			file->f_pos++;
			if (file->f_pos ==
		ctx->pos++;
		if (ctx->pos ==
			cifsFile->srch_inf.index_of_last_entry) {
			cifs_dbg(FYI, "last entry in buf at pos %lld %s\n",
					 file->f_pos, tmp_buf);
				 ctx->pos, tmp_buf);
			cifs_save_resume_key(current_entry, cifsFile);
			break;
		} else
@@ -867,8 +851,6 @@ int cifs_readdir(struct file *file, void *direntry, filldir_t filldir)
					cifsFile->srch_inf.info_level);
	}
	kfree(tmp_buf);
		break;
	} /* end switch */

rddir2_exit:
	free_xid(xid);