Commit be4ccdcc2575ae154426083765b8b8eb9253c925

Authored by Al Viro
1 parent 9b5d5a1707

[readdir] convert cifs

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>

Showing 3 changed files with 82 additions and 100 deletions Side-by-side Diff

... ... @@ -968,7 +968,7 @@
968 968 };
969 969  
970 970 const struct file_operations cifs_dir_ops = {
971   - .readdir = cifs_readdir,
  971 + .iterate = cifs_readdir,
972 972 .release = cifs_closedir,
973 973 .read = generic_read_dir,
974 974 .unlocked_ioctl = cifs_ioctl,
... ... @@ -101,7 +101,7 @@
101 101 extern int cifs_file_strict_mmap(struct file * , struct vm_area_struct *);
102 102 extern const struct file_operations cifs_dir_ops;
103 103 extern int cifs_dir_open(struct inode *inode, struct file *file);
104   -extern int cifs_readdir(struct file *file, void *direntry, filldir_t filldir);
  104 +extern int cifs_readdir(struct file *file, struct dir_context *ctx);
105 105  
106 106 /* Functions related to dir entries */
107 107 extern const struct dentry_operations cifs_dentry_ops;
... ... @@ -537,14 +537,14 @@
537 537 * every entry (do not increment for . or .. entry).
538 538 */
539 539 static int
540   -find_cifs_entry(const unsigned int xid, struct cifs_tcon *tcon,
  540 +find_cifs_entry(const unsigned int xid, struct cifs_tcon *tcon, loff_t pos,
541 541 struct file *file, char **current_entry, int *num_to_ret)
542 542 {
543 543 __u16 search_flags;
544 544 int rc = 0;
545 545 int pos_in_buf = 0;
546 546 loff_t first_entry_in_buffer;
547   - loff_t index_to_find = file->f_pos;
  547 + loff_t index_to_find = pos;
548 548 struct cifsFileInfo *cfile = file->private_data;
549 549 struct cifs_sb_info *cifs_sb = CIFS_SB(file->f_path.dentry->d_sb);
550 550 struct TCP_Server_Info *server = tcon->ses->server;
... ... @@ -659,8 +659,9 @@
659 659 return rc;
660 660 }
661 661  
662   -static int cifs_filldir(char *find_entry, struct file *file, filldir_t filldir,
663   - void *dirent, char *scratch_buf, unsigned int max_len)
  662 +static int cifs_filldir(char *find_entry, struct file *file,
  663 + struct dir_context *ctx,
  664 + char *scratch_buf, unsigned int max_len)
664 665 {
665 666 struct cifsFileInfo *file_info = file->private_data;
666 667 struct super_block *sb = file->f_path.dentry->d_sb;
667 668  
... ... @@ -740,13 +741,11 @@
740 741 cifs_prime_dcache(file->f_dentry, &name, &fattr);
741 742  
742 743 ino = cifs_uniqueid_to_ino_t(fattr.cf_uniqueid);
743   - rc = filldir(dirent, name.name, name.len, file->f_pos, ino,
744   - fattr.cf_dtype);
745   - return rc;
  744 + return !dir_emit(ctx, name.name, name.len, ino, fattr.cf_dtype);
746 745 }
747 746  
748 747  
749   -int cifs_readdir(struct file *file, void *direntry, filldir_t filldir)
  748 +int cifs_readdir(struct file *file, struct dir_context *ctx)
750 749 {
751 750 int rc = 0;
752 751 unsigned int xid;
753 752  
754 753  
755 754  
756 755  
757 756  
758 757  
759 758  
760 759  
... ... @@ -772,103 +771,86 @@
772 771 goto rddir2_exit;
773 772 }
774 773  
775   - switch ((int) file->f_pos) {
776   - case 0:
777   - if (filldir(direntry, ".", 1, file->f_pos,
778   - file_inode(file)->i_ino, DT_DIR) < 0) {
779   - cifs_dbg(VFS, "Filldir for current dir failed\n");
780   - rc = -ENOMEM;
781   - break;
782   - }
783   - file->f_pos++;
784   - case 1:
785   - if (filldir(direntry, "..", 2, file->f_pos,
786   - parent_ino(file->f_path.dentry), DT_DIR) < 0) {
787   - cifs_dbg(VFS, "Filldir for parent dir failed\n");
788   - rc = -ENOMEM;
789   - break;
790   - }
791   - file->f_pos++;
792   - default:
793   - /* 1) If search is active,
794   - is in current search buffer?
795   - if it before then restart search
796   - if after then keep searching till find it */
  774 + if (!dir_emit_dots(file, ctx))
  775 + goto rddir2_exit;
797 776  
798   - if (file->private_data == NULL) {
799   - rc = -EINVAL;
800   - free_xid(xid);
801   - return rc;
802   - }
803   - cifsFile = file->private_data;
804   - if (cifsFile->srch_inf.endOfSearch) {
805   - if (cifsFile->srch_inf.emptyDir) {
806   - cifs_dbg(FYI, "End of search, empty dir\n");
807   - rc = 0;
808   - break;
809   - }
810   - } /* else {
811   - cifsFile->invalidHandle = true;
812   - tcon->ses->server->close(xid, tcon, &cifsFile->fid);
813   - } */
  777 + /* 1) If search is active,
  778 + is in current search buffer?
  779 + if it before then restart search
  780 + if after then keep searching till find it */
814 781  
815   - tcon = tlink_tcon(cifsFile->tlink);
816   - rc = find_cifs_entry(xid, tcon, file, &current_entry,
817   - &num_to_fill);
818   - if (rc) {
819   - cifs_dbg(FYI, "fce error %d\n", rc);
  782 + if (file->private_data == NULL) {
  783 + rc = -EINVAL;
  784 + goto rddir2_exit;
  785 + }
  786 + cifsFile = file->private_data;
  787 + if (cifsFile->srch_inf.endOfSearch) {
  788 + if (cifsFile->srch_inf.emptyDir) {
  789 + cifs_dbg(FYI, "End of search, empty dir\n");
  790 + rc = 0;
820 791 goto rddir2_exit;
821   - } else if (current_entry != NULL) {
822   - cifs_dbg(FYI, "entry %lld found\n", file->f_pos);
823   - } else {
824   - cifs_dbg(FYI, "could not find entry\n");
825   - goto rddir2_exit;
826 792 }
827   - cifs_dbg(FYI, "loop through %d times filling dir for net buf %p\n",
828   - num_to_fill, cifsFile->srch_inf.ntwrk_buf_start);
829   - max_len = tcon->ses->server->ops->calc_smb_size(
830   - cifsFile->srch_inf.ntwrk_buf_start);
831   - end_of_smb = cifsFile->srch_inf.ntwrk_buf_start + max_len;
  793 + } /* else {
  794 + cifsFile->invalidHandle = true;
  795 + tcon->ses->server->close(xid, tcon, &cifsFile->fid);
  796 + } */
832 797  
833   - tmp_buf = kmalloc(UNICODE_NAME_MAX, GFP_KERNEL);
834   - if (tmp_buf == NULL) {
835   - rc = -ENOMEM;
  798 + tcon = tlink_tcon(cifsFile->tlink);
  799 + rc = find_cifs_entry(xid, tcon, ctx->pos, file, &current_entry,
  800 + &num_to_fill);
  801 + if (rc) {
  802 + cifs_dbg(FYI, "fce error %d\n", rc);
  803 + goto rddir2_exit;
  804 + } else if (current_entry != NULL) {
  805 + cifs_dbg(FYI, "entry %lld found\n", ctx->pos);
  806 + } else {
  807 + cifs_dbg(FYI, "could not find entry\n");
  808 + goto rddir2_exit;
  809 + }
  810 + cifs_dbg(FYI, "loop through %d times filling dir for net buf %p\n",
  811 + num_to_fill, cifsFile->srch_inf.ntwrk_buf_start);
  812 + max_len = tcon->ses->server->ops->calc_smb_size(
  813 + cifsFile->srch_inf.ntwrk_buf_start);
  814 + end_of_smb = cifsFile->srch_inf.ntwrk_buf_start + max_len;
  815 +
  816 + tmp_buf = kmalloc(UNICODE_NAME_MAX, GFP_KERNEL);
  817 + if (tmp_buf == NULL) {
  818 + rc = -ENOMEM;
  819 + goto rddir2_exit;
  820 + }
  821 +
  822 + for (i = 0; i < num_to_fill; i++) {
  823 + if (current_entry == NULL) {
  824 + /* evaluate whether this case is an error */
  825 + cifs_dbg(VFS, "past SMB end, num to fill %d i %d\n",
  826 + num_to_fill, i);
836 827 break;
837 828 }
838   -
839   - for (i = 0; (i < num_to_fill) && (rc == 0); i++) {
840   - if (current_entry == NULL) {
841   - /* evaluate whether this case is an error */
842   - cifs_dbg(VFS, "past SMB end, num to fill %d i %d\n",
843   - num_to_fill, i);
844   - break;
845   - }
846   - /*
847   - * if buggy server returns . and .. late do we want to
848   - * check for that here?
849   - */
850   - rc = cifs_filldir(current_entry, file, filldir,
851   - direntry, tmp_buf, max_len);
852   - if (rc == -EOVERFLOW) {
  829 + /*
  830 + * if buggy server returns . and .. late do we want to
  831 + * check for that here?
  832 + */
  833 + rc = cifs_filldir(current_entry, file, ctx,
  834 + tmp_buf, max_len);
  835 + if (rc) {
  836 + if (rc > 0)
853 837 rc = 0;
854   - break;
855   - }
856   -
857   - file->f_pos++;
858   - if (file->f_pos ==
859   - cifsFile->srch_inf.index_of_last_entry) {
860   - cifs_dbg(FYI, "last entry in buf at pos %lld %s\n",
861   - file->f_pos, tmp_buf);
862   - cifs_save_resume_key(current_entry, cifsFile);
863   - break;
864   - } else
865   - current_entry =
866   - nxt_dir_entry(current_entry, end_of_smb,
867   - cifsFile->srch_inf.info_level);
  838 + break;
868 839 }
869   - kfree(tmp_buf);
870   - break;
871   - } /* end switch */
  840 +
  841 + ctx->pos++;
  842 + if (ctx->pos ==
  843 + cifsFile->srch_inf.index_of_last_entry) {
  844 + cifs_dbg(FYI, "last entry in buf at pos %lld %s\n",
  845 + ctx->pos, tmp_buf);
  846 + cifs_save_resume_key(current_entry, cifsFile);
  847 + break;
  848 + } else
  849 + current_entry =
  850 + nxt_dir_entry(current_entry, end_of_smb,
  851 + cifsFile->srch_inf.info_level);
  852 + }
  853 + kfree(tmp_buf);
872 854  
873 855 rddir2_exit:
874 856 free_xid(xid);