Loading fs/cifs/cifsfs.c +1 −1 Original line number Diff line number Diff line Loading @@ -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, Loading fs/cifs/cifsfs.h +1 −1 Original line number Diff line number Diff line Loading @@ -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; Loading fs/cifs/readdir.c +80 −98 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; Loading Loading @@ -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; Loading @@ -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 Loading @@ -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; Loading @@ -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, ¤t_entry, rc = find_cifs_entry(xid, tcon, ctx->pos, file, ¤t_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; Loading @@ -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", Loading @@ -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 Loading @@ -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); Loading Loading
fs/cifs/cifsfs.c +1 −1 Original line number Diff line number Diff line Loading @@ -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, Loading
fs/cifs/cifsfs.h +1 −1 Original line number Diff line number Diff line Loading @@ -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; Loading
fs/cifs/readdir.c +80 −98 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; Loading Loading @@ -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; Loading @@ -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 Loading @@ -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; Loading @@ -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, ¤t_entry, rc = find_cifs_entry(xid, tcon, ctx->pos, file, ¤t_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; Loading @@ -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", Loading @@ -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 Loading @@ -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); Loading