aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2013-07-02 12:28:37 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2013-07-02 12:28:37 -0400
commit63580e51bb3e7ec459501165884e5f815a7a9322 (patch)
tree2130de984dda95996bc7922734feb465a13fca70 /fs/nfs
parent7747bd4bceb3079572695d3942294a6c7b265557 (diff)
parentac6614b76478e68173ccf7ad4e9e98035cc9c21d (diff)
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
Pull VFS patches (part 1) from Al Viro: "The major change in this pile is ->readdir() replacement with ->iterate(), dealing with ->f_pos races in ->readdir() instances for good. There's a lot more, but I'd prefer to split the pull request into several stages and this is the first obvious cutoff point." * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs: (67 commits) [readdir] constify ->actor [readdir] ->readdir() is gone [readdir] convert ecryptfs [readdir] convert coda [readdir] convert ocfs2 [readdir] convert fatfs [readdir] convert xfs [readdir] convert btrfs [readdir] convert hostfs [readdir] convert afs [readdir] convert ncpfs [readdir] convert hfsplus [readdir] convert hfs [readdir] convert befs [readdir] convert cifs [readdir] convert freevxfs [readdir] convert fuse [readdir] convert hpfs reiserfs: switch reiserfs_readdir_dentry to inode reiserfs: is_privroot_deh() needs only directory inode, actually ...
Diffstat (limited to 'fs/nfs')
-rw-r--r--fs/nfs/dir.c51
1 files changed, 25 insertions, 26 deletions
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c
index e093e73178b7..5d051419527b 100644
--- a/fs/nfs/dir.c
+++ b/fs/nfs/dir.c
@@ -46,7 +46,7 @@
46 46
47static int nfs_opendir(struct inode *, struct file *); 47static int nfs_opendir(struct inode *, struct file *);
48static int nfs_closedir(struct inode *, struct file *); 48static int nfs_closedir(struct inode *, struct file *);
49static int nfs_readdir(struct file *, void *, filldir_t); 49static int nfs_readdir(struct file *, struct dir_context *);
50static int nfs_fsync_dir(struct file *, loff_t, loff_t, int); 50static int nfs_fsync_dir(struct file *, loff_t, loff_t, int);
51static loff_t nfs_llseek_dir(struct file *, loff_t, int); 51static loff_t nfs_llseek_dir(struct file *, loff_t, int);
52static void nfs_readdir_clear_array(struct page*); 52static void nfs_readdir_clear_array(struct page*);
@@ -54,7 +54,7 @@ static void nfs_readdir_clear_array(struct page*);
54const struct file_operations nfs_dir_operations = { 54const struct file_operations nfs_dir_operations = {
55 .llseek = nfs_llseek_dir, 55 .llseek = nfs_llseek_dir,
56 .read = generic_read_dir, 56 .read = generic_read_dir,
57 .readdir = nfs_readdir, 57 .iterate = nfs_readdir,
58 .open = nfs_opendir, 58 .open = nfs_opendir,
59 .release = nfs_closedir, 59 .release = nfs_closedir,
60 .fsync = nfs_fsync_dir, 60 .fsync = nfs_fsync_dir,
@@ -147,6 +147,7 @@ typedef int (*decode_dirent_t)(struct xdr_stream *, struct nfs_entry *, int);
147typedef struct { 147typedef struct {
148 struct file *file; 148 struct file *file;
149 struct page *page; 149 struct page *page;
150 struct dir_context *ctx;
150 unsigned long page_index; 151 unsigned long page_index;
151 u64 *dir_cookie; 152 u64 *dir_cookie;
152 u64 last_cookie; 153 u64 last_cookie;
@@ -252,7 +253,7 @@ out:
252static 253static
253int nfs_readdir_search_for_pos(struct nfs_cache_array *array, nfs_readdir_descriptor_t *desc) 254int nfs_readdir_search_for_pos(struct nfs_cache_array *array, nfs_readdir_descriptor_t *desc)
254{ 255{
255 loff_t diff = desc->file->f_pos - desc->current_index; 256 loff_t diff = desc->ctx->pos - desc->current_index;
256 unsigned int index; 257 unsigned int index;
257 258
258 if (diff < 0) 259 if (diff < 0)
@@ -289,7 +290,7 @@ int nfs_readdir_search_for_cookie(struct nfs_cache_array *array, nfs_readdir_des
289 || (nfsi->cache_validity & (NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA))) { 290 || (nfsi->cache_validity & (NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA))) {
290 ctx->duped = 0; 291 ctx->duped = 0;
291 ctx->attr_gencount = nfsi->attr_gencount; 292 ctx->attr_gencount = nfsi->attr_gencount;
292 } else if (new_pos < desc->file->f_pos) { 293 } else if (new_pos < desc->ctx->pos) {
293 if (ctx->duped > 0 294 if (ctx->duped > 0
294 && ctx->dup_cookie == *desc->dir_cookie) { 295 && ctx->dup_cookie == *desc->dir_cookie) {
295 if (printk_ratelimit()) { 296 if (printk_ratelimit()) {
@@ -307,7 +308,7 @@ int nfs_readdir_search_for_cookie(struct nfs_cache_array *array, nfs_readdir_des
307 ctx->dup_cookie = *desc->dir_cookie; 308 ctx->dup_cookie = *desc->dir_cookie;
308 ctx->duped = -1; 309 ctx->duped = -1;
309 } 310 }
310 desc->file->f_pos = new_pos; 311 desc->ctx->pos = new_pos;
311 desc->cache_entry_index = i; 312 desc->cache_entry_index = i;
312 return 0; 313 return 0;
313 } 314 }
@@ -405,13 +406,13 @@ different:
405} 406}
406 407
407static 408static
408bool nfs_use_readdirplus(struct inode *dir, struct file *filp) 409bool nfs_use_readdirplus(struct inode *dir, struct dir_context *ctx)
409{ 410{
410 if (!nfs_server_capable(dir, NFS_CAP_READDIRPLUS)) 411 if (!nfs_server_capable(dir, NFS_CAP_READDIRPLUS))
411 return false; 412 return false;
412 if (test_and_clear_bit(NFS_INO_ADVISE_RDPLUS, &NFS_I(dir)->flags)) 413 if (test_and_clear_bit(NFS_INO_ADVISE_RDPLUS, &NFS_I(dir)->flags))
413 return true; 414 return true;
414 if (filp->f_pos == 0) 415 if (ctx->pos == 0)
415 return true; 416 return true;
416 return false; 417 return false;
417} 418}
@@ -702,8 +703,7 @@ int readdir_search_pagecache(nfs_readdir_descriptor_t *desc)
702 * Once we've found the start of the dirent within a page: fill 'er up... 703 * Once we've found the start of the dirent within a page: fill 'er up...
703 */ 704 */
704static 705static
705int nfs_do_filldir(nfs_readdir_descriptor_t *desc, void *dirent, 706int nfs_do_filldir(nfs_readdir_descriptor_t *desc)
706 filldir_t filldir)
707{ 707{
708 struct file *file = desc->file; 708 struct file *file = desc->file;
709 int i = 0; 709 int i = 0;
@@ -721,13 +721,12 @@ int nfs_do_filldir(nfs_readdir_descriptor_t *desc, void *dirent,
721 struct nfs_cache_array_entry *ent; 721 struct nfs_cache_array_entry *ent;
722 722
723 ent = &array->array[i]; 723 ent = &array->array[i];
724 if (filldir(dirent, ent->string.name, ent->string.len, 724 if (!dir_emit(desc->ctx, ent->string.name, ent->string.len,
725 file->f_pos, nfs_compat_user_ino64(ent->ino), 725 nfs_compat_user_ino64(ent->ino), ent->d_type)) {
726 ent->d_type) < 0) {
727 desc->eof = 1; 726 desc->eof = 1;
728 break; 727 break;
729 } 728 }
730 file->f_pos++; 729 desc->ctx->pos++;
731 if (i < (array->size-1)) 730 if (i < (array->size-1))
732 *desc->dir_cookie = array->array[i+1].cookie; 731 *desc->dir_cookie = array->array[i+1].cookie;
733 else 732 else
@@ -759,8 +758,7 @@ out:
759 * directory in the page cache by the time we get here. 758 * directory in the page cache by the time we get here.
760 */ 759 */
761static inline 760static inline
762int uncached_readdir(nfs_readdir_descriptor_t *desc, void *dirent, 761int uncached_readdir(nfs_readdir_descriptor_t *desc)
763 filldir_t filldir)
764{ 762{
765 struct page *page = NULL; 763 struct page *page = NULL;
766 int status; 764 int status;
@@ -785,7 +783,7 @@ int uncached_readdir(nfs_readdir_descriptor_t *desc, void *dirent,
785 if (status < 0) 783 if (status < 0)
786 goto out_release; 784 goto out_release;
787 785
788 status = nfs_do_filldir(desc, dirent, filldir); 786 status = nfs_do_filldir(desc);
789 787
790 out: 788 out:
791 dfprintk(DIRCACHE, "NFS: %s: returns %d\n", 789 dfprintk(DIRCACHE, "NFS: %s: returns %d\n",
@@ -800,35 +798,36 @@ int uncached_readdir(nfs_readdir_descriptor_t *desc, void *dirent,
800 last cookie cache takes care of the common case of reading the 798 last cookie cache takes care of the common case of reading the
801 whole directory. 799 whole directory.
802 */ 800 */
803static int nfs_readdir(struct file *filp, void *dirent, filldir_t filldir) 801static int nfs_readdir(struct file *file, struct dir_context *ctx)
804{ 802{
805 struct dentry *dentry = filp->f_path.dentry; 803 struct dentry *dentry = file->f_path.dentry;
806 struct inode *inode = dentry->d_inode; 804 struct inode *inode = dentry->d_inode;
807 nfs_readdir_descriptor_t my_desc, 805 nfs_readdir_descriptor_t my_desc,
808 *desc = &my_desc; 806 *desc = &my_desc;
809 struct nfs_open_dir_context *dir_ctx = filp->private_data; 807 struct nfs_open_dir_context *dir_ctx = file->private_data;
810 int res; 808 int res;
811 809
812 dfprintk(FILE, "NFS: readdir(%s/%s) starting at cookie %llu\n", 810 dfprintk(FILE, "NFS: readdir(%s/%s) starting at cookie %llu\n",
813 dentry->d_parent->d_name.name, dentry->d_name.name, 811 dentry->d_parent->d_name.name, dentry->d_name.name,
814 (long long)filp->f_pos); 812 (long long)ctx->pos);
815 nfs_inc_stats(inode, NFSIOS_VFSGETDENTS); 813 nfs_inc_stats(inode, NFSIOS_VFSGETDENTS);
816 814
817 /* 815 /*
818 * filp->f_pos points to the dirent entry number. 816 * ctx->pos points to the dirent entry number.
819 * *desc->dir_cookie has the cookie for the next entry. We have 817 * *desc->dir_cookie has the cookie for the next entry. We have
820 * to either find the entry with the appropriate number or 818 * to either find the entry with the appropriate number or
821 * revalidate the cookie. 819 * revalidate the cookie.
822 */ 820 */
823 memset(desc, 0, sizeof(*desc)); 821 memset(desc, 0, sizeof(*desc));
824 822
825 desc->file = filp; 823 desc->file = file;
824 desc->ctx = ctx;
826 desc->dir_cookie = &dir_ctx->dir_cookie; 825 desc->dir_cookie = &dir_ctx->dir_cookie;
827 desc->decode = NFS_PROTO(inode)->decode_dirent; 826 desc->decode = NFS_PROTO(inode)->decode_dirent;
828 desc->plus = nfs_use_readdirplus(inode, filp) ? 1 : 0; 827 desc->plus = nfs_use_readdirplus(inode, ctx) ? 1 : 0;
829 828
830 nfs_block_sillyrename(dentry); 829 nfs_block_sillyrename(dentry);
831 res = nfs_revalidate_mapping(inode, filp->f_mapping); 830 res = nfs_revalidate_mapping(inode, file->f_mapping);
832 if (res < 0) 831 if (res < 0)
833 goto out; 832 goto out;
834 833
@@ -840,7 +839,7 @@ static int nfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
840 /* This means either end of directory */ 839 /* This means either end of directory */
841 if (*desc->dir_cookie && desc->eof == 0) { 840 if (*desc->dir_cookie && desc->eof == 0) {
842 /* Or that the server has 'lost' a cookie */ 841 /* Or that the server has 'lost' a cookie */
843 res = uncached_readdir(desc, dirent, filldir); 842 res = uncached_readdir(desc);
844 if (res == 0) 843 if (res == 0)
845 continue; 844 continue;
846 } 845 }
@@ -857,7 +856,7 @@ static int nfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
857 if (res < 0) 856 if (res < 0)
858 break; 857 break;
859 858
860 res = nfs_do_filldir(desc, dirent, filldir); 859 res = nfs_do_filldir(desc);
861 if (res < 0) 860 if (res < 0)
862 break; 861 break;
863 } while (!desc->eof); 862 } while (!desc->eof);