diff options
| author | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-03-04 21:30:44 -0800 |
|---|---|---|
| committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-03-04 21:30:44 -0800 |
| commit | 58a96a605ee4e5d573bec35c73bb6d015171cc16 (patch) | |
| tree | 52d49ddf2e58f38f457a1e50ffc7254cd8683783 /fs | |
| parent | 55d411d0e475235b36343c10216657d96e9da156 (diff) | |
| parent | 05e7304908ec281ce4ef29d1db58ec8d6fd73563 (diff) | |
Merge bk://gkernel.bkbits.net/libata-2.6
into ppc970.osdl.org:/home/torvalds/v2.6/linux
Diffstat (limited to 'fs')
| -rw-r--r-- | fs/binfmt_elf.c | 38 | ||||
| -rw-r--r-- | fs/buffer.c | 4 | ||||
| -rw-r--r-- | fs/direct-io.c | 7 | ||||
| -rw-r--r-- | fs/exec.c | 8 | ||||
| -rw-r--r-- | fs/exportfs/expfs.c | 4 | ||||
| -rw-r--r-- | fs/inode.c | 2 | ||||
| -rw-r--r-- | fs/lockd/svc.c | 33 | ||||
| -rw-r--r-- | fs/nfs/callback.c | 156 | ||||
| -rw-r--r-- | fs/nfsd/export.c | 22 | ||||
| -rw-r--r-- | fs/nfsd/lockd.c | 2 | ||||
| -rw-r--r-- | fs/nfsd/nfs3xdr.c | 5 | ||||
| -rw-r--r-- | fs/nfsd/nfscache.c | 133 | ||||
| -rw-r--r-- | fs/nfsd/nfsfh.c | 11 | ||||
| -rw-r--r-- | fs/nfsd/nfssvc.c | 4 | ||||
| -rw-r--r-- | fs/nfsd/vfs.c | 8 |
15 files changed, 158 insertions, 279 deletions
diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c index 3be133aa4a79..4c873236d06a 100644 --- a/fs/binfmt_elf.c +++ b/fs/binfmt_elf.c @@ -37,6 +37,7 @@ #include <linux/pagemap.h> #include <linux/security.h> #include <linux/syscalls.h> +#include <linux/random.h> #include <asm/uaccess.h> #include <asm/param.h> @@ -165,21 +166,14 @@ create_elf_tables(struct linux_binprm *bprm, struct elfhdr * exec, if (k_platform) { size_t len = strlen(k_platform) + 1; -#ifdef CONFIG_X86_HT /* * In some cases (e.g. Hyper-Threading), we want to avoid L1 * evictions by the processes running on the same package. One * thing we can do is to shuffle the initial stack for them. - * - * The conditionals here are unneeded, but kept in to make the - * code behaviour the same as pre change unless we have - * hyperthreaded processors. This should be cleaned up - * before 2.6 */ - if (smp_num_siblings > 1) - STACK_ALLOC(p, ((current->pid % 64) << 7)); -#endif + p = arch_align_stack(p); + u_platform = (elf_addr_t __user *)STACK_ALLOC(p, len); if (__copy_to_user(u_platform, k_platform, len)) return -EFAULT; @@ -501,6 +495,19 @@ out: #define INTERPRETER_ELF 2 +static unsigned long randomize_stack_top(unsigned long stack_top) +{ + unsigned int random_variable = 0; + + if (current->flags & PF_RANDOMIZE) + random_variable = get_random_int() % (8*1024*1024); +#ifdef CONFIG_STACK_GROWSUP + return PAGE_ALIGN(stack_top + random_variable); +#else + return PAGE_ALIGN(stack_top - random_variable); +#endif +} + static int load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs) { struct file *interpreter = NULL; /* to shut gcc up */ @@ -760,18 +767,29 @@ static int load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs) if (elf_read_implies_exec(loc->elf_ex, executable_stack)) current->personality |= READ_IMPLIES_EXEC; + if ( !(current->personality & ADDR_NO_RANDOMIZE) && randomize_va_space) + current->flags |= PF_RANDOMIZE; arch_pick_mmap_layout(current->mm); /* Do this so that we can load the interpreter, if need be. We will change some of these later */ current->mm->rss = 0; current->mm->free_area_cache = current->mm->mmap_base; - retval = setup_arg_pages(bprm, STACK_TOP, executable_stack); + retval = setup_arg_pages(bprm, randomize_stack_top(STACK_TOP), + executable_stack); if (retval < 0) { send_sig(SIGKILL, current, 0); goto out_free_dentry; } +#ifdef ARCH_HAS_SETUP_ADDITIONAL_PAGES + retval = arch_setup_additional_pages(bprm, executable_stack); + if (retval < 0) { + send_sig(SIGKILL, current, 0); + goto out_free_dentry; + } +#endif /* ARCH_HAS_SETUP_ADDITIONAL_PAGES */ + current->mm->start_stack = bprm->p; /* Now we do a little grungy work by mmaping the ELF image into diff --git a/fs/buffer.c b/fs/buffer.c index 3c40d6382925..ed6458f00d64 100644 --- a/fs/buffer.c +++ b/fs/buffer.c @@ -875,7 +875,7 @@ int __set_page_dirty_buffers(struct page *page) spin_unlock(&mapping->private_lock); if (!TestSetPageDirty(page)) { - spin_lock_irq(&mapping->tree_lock); + write_lock_irq(&mapping->tree_lock); if (page->mapping) { /* Race with truncate? */ if (!mapping->backing_dev_info->memory_backed) inc_page_state(nr_dirty); @@ -883,7 +883,7 @@ int __set_page_dirty_buffers(struct page *page) page_index(page), PAGECACHE_TAG_DIRTY); } - spin_unlock_irq(&mapping->tree_lock); + write_unlock_irq(&mapping->tree_lock); __mark_inode_dirty(mapping->host, I_DIRTY_PAGES); } diff --git a/fs/direct-io.c b/fs/direct-io.c index 283268396a15..5a674a0c7146 100644 --- a/fs/direct-io.c +++ b/fs/direct-io.c @@ -1206,7 +1206,8 @@ __blockdev_direct_IO(int rw, struct kiocb *iocb, struct inode *inode, */ dio->lock_type = dio_lock_type; if (dio_lock_type != DIO_NO_LOCKING) { - if (rw == READ) { + /* watch out for a 0 len io from a tricksy fs */ + if (rw == READ && end > offset) { struct address_space *mapping; mapping = iocb->ki_filp->f_mapping; @@ -1214,7 +1215,9 @@ __blockdev_direct_IO(int rw, struct kiocb *iocb, struct inode *inode, down(&inode->i_sem); reader_with_isem = 1; } - retval = filemap_write_and_wait(mapping); + + retval = filemap_write_and_wait_range(mapping, offset, + end - 1); if (retval) { kfree(dio); goto out; diff --git a/fs/exec.c b/fs/exec.c index ee58e91a9d7f..393605cdc101 100644 --- a/fs/exec.c +++ b/fs/exec.c @@ -400,7 +400,8 @@ int setup_arg_pages(struct linux_binprm *bprm, while (i < MAX_ARG_PAGES) bprm->page[i++] = NULL; #else - stack_base = stack_top - MAX_ARG_PAGES * PAGE_SIZE; + stack_base = arch_align_stack(stack_top - MAX_ARG_PAGES*PAGE_SIZE); + stack_base = PAGE_ALIGN(stack_base); bprm->p += stack_base; mm->arg_start = bprm->p; arg_size = stack_top - (PAGE_MASK & (unsigned long) mm->arg_start); @@ -877,6 +878,7 @@ int flush_old_exec(struct linux_binprm * bprm) tcomm[i] = '\0'; set_task_comm(current, tcomm); + current->flags &= ~PF_RANDOMIZE; flush_thread(); if (bprm->e_uid != current->euid || bprm->e_gid != current->egid || @@ -1191,8 +1193,8 @@ int do_execve(char * filename, /* execve success */ security_bprm_free(bprm); - acct_update_integrals(); - update_mem_hiwater(); + acct_update_integrals(current); + update_mem_hiwater(current); kfree(bprm); return retval; } diff --git a/fs/exportfs/expfs.c b/fs/exportfs/expfs.c index 0a6f7b06b8d7..c49d6254379a 100644 --- a/fs/exportfs/expfs.c +++ b/fs/exportfs/expfs.c @@ -55,7 +55,7 @@ find_exported_dentry(struct super_block *sb, void *obj, void *parent, struct list_head *le, *head; struct dentry *toput = NULL; int noprogress; - + char nbuf[NAME_MAX+1]; /* * Attempt to find the inode. @@ -176,7 +176,6 @@ find_exported_dentry(struct super_block *sb, void *obj, void *parent, */ struct dentry *ppd; struct dentry *npd; - char nbuf[NAME_MAX+1]; down(&pd->d_inode->i_sem); ppd = CALL(nops,get_parent)(pd); @@ -241,7 +240,6 @@ find_exported_dentry(struct super_block *sb, void *obj, void *parent, /* if we weren't after a directory, have one more step to go */ if (result != target_dir) { struct dentry *nresult; - char nbuf[NAME_MAX+1]; err = CALL(nops,get_name)(target_dir, nbuf, result); if (!err) { down(&target_dir->d_inode->i_sem); diff --git a/fs/inode.c b/fs/inode.c index d76a6e4b3ee1..ff654a268331 100644 --- a/fs/inode.c +++ b/fs/inode.c @@ -196,7 +196,7 @@ void inode_init_once(struct inode *inode) sema_init(&inode->i_sem, 1); init_rwsem(&inode->i_alloc_sem); INIT_RADIX_TREE(&inode->i_data.page_tree, GFP_ATOMIC); - spin_lock_init(&inode->i_data.tree_lock); + rwlock_init(&inode->i_data.tree_lock); spin_lock_init(&inode->i_data.i_mmap_lock); INIT_LIST_HEAD(&inode->i_data.private_list); spin_lock_init(&inode->i_data.private_lock); diff --git a/fs/lockd/svc.c b/fs/lockd/svc.c index d3ee09c5196e..b82e470912e8 100644 --- a/fs/lockd/svc.c +++ b/fs/lockd/svc.c @@ -403,6 +403,38 @@ static int param_set_##name(const char *val, struct kernel_param *kp) \ return 0; \ } +static inline int is_callback(u32 proc) +{ + return proc == NLMPROC_GRANTED + || proc == NLMPROC_GRANTED_MSG + || proc == NLMPROC_TEST_RES + || proc == NLMPROC_LOCK_RES + || proc == NLMPROC_CANCEL_RES + || proc == NLMPROC_UNLOCK_RES + || proc == NLMPROC_NSM_NOTIFY; +} + + +static int lockd_authenticate(struct svc_rqst *rqstp) +{ + rqstp->rq_client = NULL; + switch (rqstp->rq_authop->flavour) { + case RPC_AUTH_NULL: + case RPC_AUTH_UNIX: + if (rqstp->rq_proc == 0) + return SVC_OK; + if (is_callback(rqstp->rq_proc)) { + /* Leave it to individual procedures to + * call nlmsvc_lookup_host(rqstp) + */ + return SVC_OK; + } + return svc_set_client(rqstp); + } + return SVC_DENIED; +} + + param_set_min_max(port, int, simple_strtol, 0, 65535) param_set_min_max(grace_period, unsigned long, simple_strtoul, nlm_grace_period_min, nlm_grace_period_max) @@ -483,4 +515,5 @@ static struct svc_program nlmsvc_program = { .pg_name = "lockd", /* service name */ .pg_class = "nfsd", /* share authentication with nfsd */ .pg_stats = &nlmsvc_stats, /* stats table */ + .pg_authenticate = &lockd_authenticate /* export authentication */ }; diff --git a/fs/nfs/callback.c b/fs/nfs/callback.c index ad7677b4f21d..560d6175dd58 100644 --- a/fs/nfs/callback.c +++ b/fs/nfs/callback.c @@ -139,133 +139,10 @@ out: return ret; } -/* - * AUTH_NULL authentication - */ -static int nfs_callback_null_accept(struct svc_rqst *rqstp, u32 *authp) -{ - struct kvec *argv = &rqstp->rq_arg.head[0]; - struct kvec *resv = &rqstp->rq_res.head[0]; - - if (argv->iov_len < 3*4) - return SVC_GARBAGE; - - if (svc_getu32(argv) != 0) { - dprintk("svc: bad null cred\n"); - *authp = rpc_autherr_badcred; - return SVC_DENIED; - } - if (svc_getu32(argv) != RPC_AUTH_NULL || svc_getu32(argv) != 0) { - dprintk("svc: bad null verf\n"); - *authp = rpc_autherr_badverf; - return SVC_DENIED; - } - - /* Signal that mapping to nobody uid/gid is required */ - rqstp->rq_cred.cr_uid = (uid_t) -1; - rqstp->rq_cred.cr_gid = (gid_t) -1; - rqstp->rq_cred.cr_group_info = groups_alloc(0); - if (rqstp->rq_cred.cr_group_info == NULL) - return SVC_DROP; /* kmalloc failure - client must retry */ - - /* Put NULL verifier */ - svc_putu32(resv, RPC_AUTH_NULL); - svc_putu32(resv, 0); - dprintk("%s: success, returning %d!\n", __FUNCTION__, SVC_OK); - return SVC_OK; -} - -static int nfs_callback_null_release(struct svc_rqst *rqstp) -{ - if (rqstp->rq_cred.cr_group_info) - put_group_info(rqstp->rq_cred.cr_group_info); - rqstp->rq_cred.cr_group_info = NULL; - return 0; /* don't drop */ -} - -static struct auth_ops nfs_callback_auth_null = { - .name = "null", - .flavour = RPC_AUTH_NULL, - .accept = nfs_callback_null_accept, - .release = nfs_callback_null_release, -}; - -/* - * AUTH_SYS authentication - */ -static int nfs_callback_unix_accept(struct svc_rqst *rqstp, u32 *authp) -{ - struct kvec *argv = &rqstp->rq_arg.head[0]; - struct kvec *resv = &rqstp->rq_res.head[0]; - struct svc_cred *cred = &rqstp->rq_cred; - u32 slen, i; - int len = argv->iov_len; - - dprintk("%s: start\n", __FUNCTION__); - cred->cr_group_info = NULL; - rqstp->rq_client = NULL; - if ((len -= 3*4) < 0) - return SVC_GARBAGE; - - /* Get length, time stamp and machine name */ - svc_getu32(argv); - svc_getu32(argv); - slen = XDR_QUADLEN(ntohl(svc_getu32(argv))); - if (slen > 64 || (len -= (slen + 3)*4) < 0) - goto badcred; - argv->iov_base = (void*)((u32*)argv->iov_base + slen); - argv->iov_len -= slen*4; - - cred->cr_uid = ntohl(svc_getu32(argv)); - cred->cr_gid = ntohl(svc_getu32(argv)); - slen = ntohl(svc_getu32(argv)); - if (slen > 16 || (len -= (slen + 2)*4) < 0) - goto badcred; - cred->cr_group_info = groups_alloc(slen); - if (cred->cr_group_info == NULL) - return SVC_DROP; - for (i = 0; i < slen; i++) - GROUP_AT(cred->cr_group_info, i) = ntohl(svc_getu32(argv)); - - if (svc_getu32(argv) != RPC_AUTH_NULL || svc_getu32(argv) != 0) { - *authp = rpc_autherr_badverf; - return SVC_DENIED; - } - /* Put NULL verifier */ - svc_putu32(resv, RPC_AUTH_NULL); - svc_putu32(resv, 0); - dprintk("%s: success, returning %d!\n", __FUNCTION__, SVC_OK); - return SVC_OK; -badcred: - *authp = rpc_autherr_badcred; - return SVC_DENIED; -} - -static int nfs_callback_unix_release(struct svc_rqst *rqstp) -{ - if (rqstp->rq_cred.cr_group_info) - put_group_info(rqstp->rq_cred.cr_group_info); - rqstp->rq_cred.cr_group_info = NULL; - return 0; -} - -static struct auth_ops nfs_callback_auth_unix = { - .name = "unix", - .flavour = RPC_AUTH_UNIX, - .accept = nfs_callback_unix_accept, - .release = nfs_callback_unix_release, -}; - -/* - * Hook the authentication protocol - */ -static int nfs_callback_auth(struct svc_rqst *rqstp, u32 *authp) +static int nfs_callback_authenticate(struct svc_rqst *rqstp) { struct in_addr *addr = &rqstp->rq_addr.sin_addr; struct nfs4_client *clp; - struct kvec *argv = &rqstp->rq_arg.head[0]; - int flavour; - int retval; /* Don't talk to strangers */ clp = nfs4_find_client(addr); @@ -273,34 +150,19 @@ static int nfs_callback_auth(struct svc_rqst *rqstp, u32 *authp) return SVC_DROP; dprintk("%s: %u.%u.%u.%u NFSv4 callback!\n", __FUNCTION__, NIPQUAD(addr)); nfs4_put_client(clp); - flavour = ntohl(svc_getu32(argv)); - switch(flavour) { + switch (rqstp->rq_authop->flavour) { case RPC_AUTH_NULL: - if (rqstp->rq_proc != CB_NULL) { - *authp = rpc_autherr_tooweak; - retval = SVC_DENIED; - break; - } - rqstp->rq_authop = &nfs_callback_auth_null; - retval = nfs_callback_null_accept(rqstp, authp); + if (rqstp->rq_proc != CB_NULL) + return SVC_DENIED; break; case RPC_AUTH_UNIX: - /* Eat the authentication flavour */ - rqstp->rq_authop = &nfs_callback_auth_unix; - retval = nfs_callback_unix_accept(rqstp, authp); break; + case RPC_AUTH_GSS: + /* FIXME: RPCSEC_GSS handling? */ default: - /* FIXME: need to add RPCSEC_GSS upcalls */ -#if 0 - svc_ungetu32(argv); - retval = svc_authenticate(rqstp, authp); -#else - *authp = rpc_autherr_rejectedcred; - retval = SVC_DENIED; -#endif + return SVC_DENIED; } - dprintk("%s: flavour %d returning error %d\n", __FUNCTION__, flavour, retval); - return retval; + return SVC_OK; } /* @@ -321,5 +183,5 @@ static struct svc_program nfs4_callback_program = { .pg_name = "NFSv4 callback", /* service name */ .pg_class = "nfs", /* authentication class */ .pg_stats = &nfs4_callback_stats, - .pg_authenticate = nfs_callback_auth, + .pg_authenticate = nfs_callback_authenticate, }; diff --git a/fs/nfsd/export.c b/fs/nfsd/export.c index 96c0ea8f60ce..9a11aa39e2e4 100644 --- a/fs/nfsd/export.c +++ b/fs/nfsd/export.c @@ -79,9 +79,9 @@ void expkey_put(struct cache_head *item, struct cache_detail *cd) } } -void expkey_request(struct cache_detail *cd, - struct cache_head *h, - char **bpp, int *blen) +static void expkey_request(struct cache_detail *cd, + struct cache_head *h, + char **bpp, int *blen) { /* client fsidtype \xfsid */ struct svc_expkey *ek = container_of(h, struct svc_expkey, h); @@ -95,7 +95,7 @@ void expkey_request(struct cache_detail *cd, } static struct svc_expkey *svc_expkey_lookup(struct svc_expkey *, int); -int expkey_parse(struct cache_detail *cd, char *mesg, int mlen) +static int expkey_parse(struct cache_detail *cd, char *mesg, int mlen) { /* client fsidtype fsid [path] */ char *buf; @@ -284,9 +284,9 @@ void svc_export_put(struct cache_head *item, struct cache_detail *cd) } } -void svc_export_request(struct cache_detail *cd, - struct cache_head *h, - char **bpp, int *blen) +static void svc_export_request(struct cache_detail *cd, + struct cache_head *h, + char **bpp, int *blen) { /* client path */ struct svc_export *exp = container_of(h, struct svc_export, h); @@ -340,7 +340,7 @@ static int check_export(struct inode *inode, int flags) } -int svc_export_parse(struct cache_detail *cd, char *mesg, int mlen) +static int svc_export_parse(struct cache_detail *cd, char *mesg, int mlen) { /* client path expiry [flags anonuid anongid fsid] */ char *buf; @@ -510,8 +510,8 @@ exp_find_key(svc_client *clp, int fsid_type, u32 *fsidv, struct cache_req *reqp) return ek; } -int exp_set_key(svc_client *clp, int fsid_type, u32 *fsidv, - struct svc_export *exp) +static int exp_set_key(svc_client *clp, int fsid_type, u32 *fsidv, + struct svc_export *exp) { struct svc_expkey key, *ek; @@ -999,7 +999,7 @@ static void e_stop(struct seq_file *m, void *p) exp_readunlock(); } -struct flags { +static struct flags { int flag; char *name[2]; } expflags[] = { diff --git a/fs/nfsd/lockd.c b/fs/nfsd/lockd.c index 3397bec47085..7b889ff15ae6 100644 --- a/fs/nfsd/lockd.c +++ b/fs/nfsd/lockd.c @@ -60,7 +60,7 @@ nlm_fclose(struct file *filp) fput(filp); } -struct nlmsvc_binding nfsd_nlm_ops = { +static struct nlmsvc_binding nfsd_nlm_ops = { .fopen = nlm_fopen, /* open file for locking */ .fclose = nlm_fclose, /* close file */ }; diff --git a/fs/nfsd/nfs3xdr.c b/fs/nfsd/nfs3xdr.c index 941881de48a1..11f806835c5a 100644 --- a/fs/nfsd/nfs3xdr.c +++ b/fs/nfsd/nfs3xdr.c @@ -801,6 +801,11 @@ compose_entry_fh(struct nfsd3_readdirres *cd, struct svc_fh *fhp, if (isdotent(name, namlen)) { if (namlen == 2) { dchild = dget_parent(dparent); + if (dchild == dparent) { + /* filesystem root - cannot return filehandle for ".." */ + dput(dchild); + return 1; + } } else dchild = dget(dparent); } else diff --git a/fs/nfsd/nfscache.c b/fs/nfsd/nfscache.c index a3236dfedf98..119e4d4495b8 100644 --- a/fs/nfsd/nfscache.c +++ b/fs/nfsd/nfscache.c @@ -15,6 +15,7 @@ #include <linux/slab.h> #include <linux/string.h> #include <linux/spinlock.h> +#include <linux/list.h> #include <linux/sunrpc/svc.h> #include <linux/nfsd/nfsd.h> @@ -30,15 +31,8 @@ #define HASHSIZE 64 #define REQHASH(xid) ((((xid) >> 24) ^ (xid)) & (HASHSIZE-1)) -struct nfscache_head { - struct svc_cacherep * next; - struct svc_cacherep * prev; -}; - -static struct nfscache_head * hash_list; -static struct svc_cacherep * lru_head; -static struct svc_cacherep * lru_tail; -static struct svc_cacherep * nfscache; +static struct hlist_head * hash_list; +static struct list_head lru_head; static int cache_disabled = 1; static int nfsd_cache_append(struct svc_rqst *rqstp, struct kvec *vec); @@ -54,46 +48,32 @@ void nfsd_cache_init(void) { struct svc_cacherep *rp; - struct nfscache_head *rh; - size_t i; - unsigned long order; - - - i = CACHESIZE * sizeof (struct svc_cacherep); - for (order = 0; (PAGE_SIZE << order) < i; order++) - ; - nfscache = (struct svc_cacherep *) - __get_free_pages(GFP_KERNEL, order); - if (!nfscache) { - printk (KERN_ERR "nfsd: cannot allocate %Zd bytes for reply cache\n", i); - return; + int i; + + INIT_LIST_HEAD(&lru_head); + i = CACHESIZE; + while(i) { + rp = kmalloc(sizeof(*rp), GFP_KERNEL); + if (!rp) break; + list_add(&rp->c_lru, &lru_head); + rp->c_state = RC_UNUSED; + rp->c_type = RC_NOCACHE; + INIT_HLIST_NODE(&rp->c_hash); + i--; } - memset(nfscache, 0, i); - i = HASHSIZE * sizeof (struct nfscache_head); - hash_list = kmalloc (i, GFP_KERNEL); + if (i) + printk (KERN_ERR "nfsd: cannot allocate all %d cache entries, only got %d\n", + CACHESIZE, CACHESIZE-i); + + hash_list = kmalloc (HASHSIZE * sizeof(struct hlist_head), GFP_KERNEL); if (!hash_list) { - free_pages ((unsigned long)nfscache, order); - nfscache = NULL; - printk (KERN_ERR "nfsd: cannot allocate %Zd bytes for hash list\n", i); + nfsd_cache_shutdown(); + printk (KERN_ERR "nfsd: cannot allocate %Zd bytes for hash list\n", + HASHSIZE * sizeof(struct hlist_head)); return; } - - for (i = 0, rh = hash_list; i < HASHSIZE; i++, rh++) - rh->next = rh->prev = (struct svc_cacherep *) rh; - - for (i = 0, rp = nfscache; i < CACHESIZE; i++, rp++) { - rp->c_state = RC_UNUSED; - rp->c_type = RC_NOCACHE; - rp->c_hash_next = - rp->c_hash_prev = rp; - rp->c_lru_next = rp + 1; - rp->c_lru_prev = rp - 1; - } - lru_head = nfscache; - lru_tail = nfscache + CACHESIZE - 1; - lru_head->c_lru_prev = NULL; - lru_tail->c_lru_next = NULL; + memset(hash_list, 0, HASHSIZE * sizeof(struct hlist_head)); cache_disabled = 0; } @@ -102,48 +82,30 @@ void nfsd_cache_shutdown(void) { struct svc_cacherep *rp; - size_t i; - unsigned long order; - for (rp = lru_head; rp; rp = rp->c_lru_next) { + while (!list_empty(&lru_head)) { + rp = list_entry(lru_head.next, struct svc_cacherep, c_lru); if (rp->c_state == RC_DONE && rp->c_type == RC_REPLBUFF) kfree(rp->c_replvec.iov_base); + list_del(&rp->c_lru); + kfree(rp); } cache_disabled = 1; - i = CACHESIZE * sizeof (struct svc_cacherep); - for (order = 0; (PAGE_SIZE << order) < i; order++) - ; - free_pages ((unsigned long)nfscache, order); - nfscache = NULL; - kfree (hash_list); + if (hash_list) + kfree (hash_list); hash_list = NULL; } /* - * Move cache entry to front of LRU list + * Move cache entry to end of LRU list */ static void -lru_put_front(struct svc_cacherep *rp) +lru_put_end(struct svc_cacherep *rp) { - struct svc_cacherep *prev = rp->c_lru_prev, - *next = rp->c_lru_next; - - if (prev) - prev->c_lru_next = next; - else - lru_head = next; - if (next) - next->c_lru_prev = prev; - else - lru_tail = prev; - - rp->c_lru_next = lru_head; - rp->c_lru_prev = NULL; - if (lru_head) - lru_head->c_lru_prev = rp; - lru_head = rp; + list_del(&rp->c_lru); + list_add_tail(&rp->c_lru, &lru_head); } /* @@ -152,17 +114,8 @@ lru_put_front(struct svc_cacherep *rp) static void hash_refile(struct svc_cacherep *rp) { - struct svc_cacherep *prev = rp->c_hash_prev, - *next = rp->c_hash_next; - struct nfscache_head *head = hash_list + REQHASH(rp->c_xid); - - prev->c_hash_next = next; - next->c_hash_prev = prev; - - rp->c_hash_next = head->next; - rp->c_hash_prev = (struct svc_cacherep *) head; - head->next->c_hash_prev = rp; - head->next = rp; + hlist_del_init(&rp->c_hash); + hlist_add_head(&rp->c_hash, hash_list + REQHASH(rp->c_xid)); } /* @@ -173,7 +126,9 @@ hash_refile(struct svc_cacherep *rp) int nfsd_cache_lookup(struct svc_rqst *rqstp, int type) { - struct svc_cacherep *rh, *rp; + struct hlist_node *hn; + struct hlist_head *rh; + struct svc_cacherep *rp; u32 xid = rqstp->rq_xid, proto = rqstp->rq_prot, vers = rqstp->rq_vers, @@ -190,8 +145,8 @@ nfsd_cache_lookup(struct svc_rqst *rqstp, int type) spin_lock(&cache_lock); rtn = RC_DOIT; - rp = rh = (struct svc_cacherep *) &hash_list[REQHASH(xid)]; - while ((rp = rp->c_hash_next) != rh) { + rh = &hash_list[REQHASH(xid)]; + hlist_for_each_entry(rp, hn, rh, c_hash) { if (rp->c_state != RC_UNUSED && xid == rp->c_xid && proc == rp->c_proc && proto == rp->c_prot && vers == rp->c_vers && @@ -206,7 +161,7 @@ nfsd_cache_lookup(struct svc_rqst *rqstp, int type) /* This loop shouldn't take more than a few iterations normally */ { int safe = 0; - for (rp = lru_tail; rp; rp = rp->c_lru_prev) { + list_for_each_entry(rp, &lru_head, c_lru) { if (rp->c_state != RC_INPROG) break; if (safe++ > CACHESIZE) { @@ -254,7 +209,7 @@ found_entry: /* We found a matching entry which is either in progress or done. */ age = jiffies - rp->c_timestamp; rp->c_timestamp = jiffies; - lru_put_front(rp); + lru_put_end(rp); rtn = RC_DROPIT; /* Request being processed or excessive rexmits */ @@ -343,7 +298,7 @@ nfsd_cache_update(struct svc_rqst *rqstp, int cachetype, u32 *statp) break; } spin_lock(&cache_lock); - lru_put_front(rp); + lru_put_end(rp); rp->c_secure = rqstp->rq_secure; rp->c_type = cachetype; rp->c_state = RC_DONE; diff --git a/fs/nfsd/nfsfh.c b/fs/nfsd/nfsfh.c index 0cf106106674..7a3e397b4ed3 100644 --- a/fs/nfsd/nfsfh.c +++ b/fs/nfsd/nfsfh.c @@ -41,7 +41,7 @@ extern struct export_operations export_op_default; * if not, require that we can walk up to exp->ex_dentry * doing some checks on the 'x' bits */ -int nfsd_acceptable(void *expv, struct dentry *dentry) +static int nfsd_acceptable(void *expv, struct dentry *dentry) { struct svc_export *exp = expv; int rv; @@ -280,8 +280,8 @@ out: * an inode. In this case a call to fh_update should be made * before the fh goes out on the wire ... */ -inline int _fh_update(struct dentry *dentry, struct svc_export *exp, - __u32 *datap, int *maxsize) +static inline int _fh_update(struct dentry *dentry, struct svc_export *exp, + __u32 *datap, int *maxsize) { struct export_operations *nop = exp->ex_mnt->mnt_sb->s_export_op; @@ -297,8 +297,9 @@ inline int _fh_update(struct dentry *dentry, struct svc_export *exp, /* * for composing old style file handles */ -inline void _fh_update_old(struct dentry *dentry, struct svc_export *exp, - struct knfsd_fh *fh) +static inline void _fh_update_old(struct dentry *dentry, + struct svc_export *exp, + struct knfsd_fh *fh) { fh->ofh_ino = ino_t_to_u32(dentry->d_inode->i_ino); fh->ofh_generation = dentry->d_inode->i_generation; diff --git a/fs/nfsd/nfssvc.c b/fs/nfsd/nfssvc.c index 291dd8cd3214..f7e41965b043 100644 --- a/fs/nfsd/nfssvc.c +++ b/fs/nfsd/nfssvc.c @@ -60,7 +60,7 @@ struct nfsd_list { struct list_head list; struct task_struct *task; }; -struct list_head nfsd_list = LIST_HEAD_INIT(nfsd_list); +static struct list_head nfsd_list = LIST_HEAD_INIT(nfsd_list); /* * Maximum number of nfsd processes @@ -378,4 +378,6 @@ struct svc_program nfsd_program = { .pg_name = "nfsd", /* program name */ .pg_class = "nfsd", /* authentication class */ .pg_stats = &nfsd_svcstats, /* version table */ + .pg_authenticate = &svc_set_client, /* export authentication */ + }; diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c index a5a58a1dba0a..e86ee9ac6654 100644 --- a/fs/nfsd/vfs.c +++ b/fs/nfsd/vfs.c @@ -707,8 +707,8 @@ nfsd_close(struct file *filp) * As this calls fsync (not fdatasync) there is no need for a write_inode * after it. */ -inline void nfsd_dosync(struct file *filp, struct dentry *dp, - struct file_operations *fop) +static inline void nfsd_dosync(struct file *filp, struct dentry *dp, + struct file_operations *fop) { struct inode *inode = dp->d_inode; int (*fsync) (struct file *, struct dentry *, int); @@ -720,7 +720,7 @@ inline void nfsd_dosync(struct file *filp, struct dentry *dp, } -void +static void nfsd_sync(struct file *filp) { struct inode *inode = filp->f_dentry->d_inode; @@ -730,7 +730,7 @@ nfsd_sync(struct file *filp) up(&inode->i_sem); } -void +static void nfsd_sync_dir(struct dentry *dp) { nfsd_dosync(NULL, dp, dp->d_inode->i_fop); |
