~ubuntu-branches/ubuntu/quantal/linux-linaro-mx51/quantal

« back to all changes in this revision

Viewing changes to fs/nfs/dir.c

  • Committer: Package Import Robot
  • Author(s): John Rigby, John Rigby
  • Date: 2011-09-26 10:44:23 UTC
  • Revision ID: package-import@ubuntu.com-20110926104423-3o58a3c1bj7x00rs
Tags: 3.0.0-1007.9
[ John Rigby ]

Enable crypto modules and remove crypto-modules from
exclude-module files
LP: #826021

Show diffs side-by-side

added added

removed removed

Lines of Context:
134
134
 
135
135
#endif /* CONFIG_NFS_V4 */
136
136
 
137
 
static struct nfs_open_dir_context *alloc_nfs_open_dir_context(struct rpc_cred *cred)
 
137
static struct nfs_open_dir_context *alloc_nfs_open_dir_context(struct inode *dir, struct rpc_cred *cred)
138
138
{
139
139
        struct nfs_open_dir_context *ctx;
140
140
        ctx = kmalloc(sizeof(*ctx), GFP_KERNEL);
141
141
        if (ctx != NULL) {
142
142
                ctx->duped = 0;
 
143
                ctx->attr_gencount = NFS_I(dir)->attr_gencount;
143
144
                ctx->dir_cookie = 0;
144
145
                ctx->dup_cookie = 0;
145
146
                ctx->cred = get_rpccred(cred);
146
 
        } else
147
 
                ctx = ERR_PTR(-ENOMEM);
148
 
        return ctx;
 
147
                return ctx;
 
148
        }
 
149
        return  ERR_PTR(-ENOMEM);
149
150
}
150
151
 
151
152
static void put_nfs_open_dir_context(struct nfs_open_dir_context *ctx)
173
174
        cred = rpc_lookup_cred();
174
175
        if (IS_ERR(cred))
175
176
                return PTR_ERR(cred);
176
 
        ctx = alloc_nfs_open_dir_context(cred);
 
177
        ctx = alloc_nfs_open_dir_context(inode, cred);
177
178
        if (IS_ERR(ctx)) {
178
179
                res = PTR_ERR(ctx);
179
180
                goto out;
323
324
{
324
325
        loff_t diff = desc->file->f_pos - desc->current_index;
325
326
        unsigned int index;
326
 
        struct nfs_open_dir_context *ctx = desc->file->private_data;
327
327
 
328
328
        if (diff < 0)
329
329
                goto out_eof;
336
336
        index = (unsigned int)diff;
337
337
        *desc->dir_cookie = array->array[index].cookie;
338
338
        desc->cache_entry_index = index;
339
 
        ctx->duped = 0;
340
339
        return 0;
341
340
out_eof:
342
341
        desc->eof = 1;
349
348
        int i;
350
349
        loff_t new_pos;
351
350
        int status = -EAGAIN;
352
 
        struct nfs_open_dir_context *ctx = desc->file->private_data;
353
351
 
354
352
        for (i = 0; i < array->size; i++) {
355
353
                if (array->array[i].cookie == *desc->dir_cookie) {
 
354
                        struct nfs_inode *nfsi = NFS_I(desc->file->f_path.dentry->d_inode);
 
355
                        struct nfs_open_dir_context *ctx = desc->file->private_data;
 
356
 
356
357
                        new_pos = desc->current_index + i;
357
 
                        if (new_pos < desc->file->f_pos) {
 
358
                        if (ctx->attr_gencount != nfsi->attr_gencount
 
359
                            || (nfsi->cache_validity & (NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA))) {
 
360
                                ctx->duped = 0;
 
361
                                ctx->attr_gencount = nfsi->attr_gencount;
 
362
                        } else if (new_pos < desc->file->f_pos) {
 
363
                                if (ctx->duped > 0
 
364
                                    && ctx->dup_cookie == *desc->dir_cookie) {
 
365
                                        if (printk_ratelimit()) {
 
366
                                                pr_notice("NFS: directory %s/%s contains a readdir loop."
 
367
                                                                "Please contact your server vendor.  "
 
368
                                                                "Offending cookie: %llu\n",
 
369
                                                                desc->file->f_dentry->d_parent->d_name.name,
 
370
                                                                desc->file->f_dentry->d_name.name,
 
371
                                                                *desc->dir_cookie);
 
372
                                        }
 
373
                                        status = -ELOOP;
 
374
                                        goto out;
 
375
                                }
358
376
                                ctx->dup_cookie = *desc->dir_cookie;
359
 
                                ctx->duped = 1;
 
377
                                ctx->duped = -1;
360
378
                        }
361
379
                        desc->file->f_pos = new_pos;
362
380
                        desc->cache_entry_index = i;
368
386
                if (*desc->dir_cookie == array->last_cookie)
369
387
                        desc->eof = 1;
370
388
        }
 
389
out:
371
390
        return status;
372
391
}
373
392
 
512
531
                                struct page **xdr_pages, struct page *page, unsigned int buflen)
513
532
{
514
533
        struct xdr_stream stream;
515
 
        struct xdr_buf buf = {
516
 
                .pages = xdr_pages,
517
 
                .page_len = buflen,
518
 
                .buflen = buflen,
519
 
                .len = buflen,
520
 
        };
 
534
        struct xdr_buf buf;
521
535
        struct page *scratch;
522
536
        struct nfs_cache_array *array;
523
537
        unsigned int count = 0;
527
541
        if (scratch == NULL)
528
542
                return -ENOMEM;
529
543
 
530
 
        xdr_init_decode(&stream, &buf, NULL);
 
544
        xdr_init_decode_pages(&stream, &buf, xdr_pages, buflen);
531
545
        xdr_set_scratch_buffer(&stream, page_address(scratch), PAGE_SIZE);
532
546
 
533
547
        do {
745
759
        struct nfs_cache_array *array = NULL;
746
760
        struct nfs_open_dir_context *ctx = file->private_data;
747
761
 
748
 
        if (ctx->duped != 0 && ctx->dup_cookie == *desc->dir_cookie) {
749
 
                if (printk_ratelimit()) {
750
 
                        pr_notice("NFS: directory %s/%s contains a readdir loop.  "
751
 
                                "Please contact your server vendor.  "
752
 
                                "Offending cookie: %llu\n",
753
 
                                file->f_dentry->d_parent->d_name.name,
754
 
                                file->f_dentry->d_name.name,
755
 
                                *desc->dir_cookie);
756
 
                }
757
 
                res = -ELOOP;
758
 
                goto out;
759
 
        }
760
 
 
761
762
        array = nfs_readdir_get_array(desc->page);
762
763
        if (IS_ERR(array)) {
763
764
                res = PTR_ERR(array);
779
780
                        *desc->dir_cookie = array->array[i+1].cookie;
780
781
                else
781
782
                        *desc->dir_cookie = array->last_cookie;
 
783
                if (ctx->duped != 0)
 
784
                        ctx->duped = 1;
782
785
        }
783
786
        if (array->eof_index >= 0)
784
787
                desc->eof = 1;
810
813
        struct page     *page = NULL;
811
814
        int             status;
812
815
        struct inode *inode = desc->file->f_path.dentry->d_inode;
 
816
        struct nfs_open_dir_context *ctx = desc->file->private_data;
813
817
 
814
818
        dfprintk(DIRCACHE, "NFS: uncached_readdir() searching for cookie %Lu\n",
815
819
                        (unsigned long long)*desc->dir_cookie);
823
827
        desc->page_index = 0;
824
828
        desc->last_cookie = *desc->dir_cookie;
825
829
        desc->page = page;
 
830
        ctx->duped = 0;
826
831
 
827
832
        status = nfs_readdir_xdr_to_array(desc, page, inode);
828
833
        if (status < 0)
2042
2047
        }
2043
2048
}
2044
2049
 
2045
 
int nfs_access_cache_shrinker(struct shrinker *shrink, int nr_to_scan, gfp_t gfp_mask)
 
2050
int nfs_access_cache_shrinker(struct shrinker *shrink,
 
2051
                              struct shrink_control *sc)
2046
2052
{
2047
2053
        LIST_HEAD(head);
2048
2054
        struct nfs_inode *nfsi, *next;
2049
2055
        struct nfs_access_entry *cache;
 
2056
        int nr_to_scan = sc->nr_to_scan;
 
2057
        gfp_t gfp_mask = sc->gfp_mask;
2050
2058
 
2051
2059
        if ((gfp_mask & GFP_KERNEL) != GFP_KERNEL)
2052
2060
                return (nr_to_scan == 0) ? 0 : -1;