diff options
author | Ralf Baechle <ralf@linux-mips.org> | 1997-12-16 05:34:03 +0000 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 1997-12-16 05:34:03 +0000 |
commit | 967c65a99059fd459b956c1588ce0ba227912c4e (patch) | |
tree | 8224d013ff5d255420713d05610c7efebd204d2a /fs/lockd | |
parent | e20c1cc1656a66a2773bca4591a895cbc12696ff (diff) |
Merge with Linux 2.1.72, part 1.
Diffstat (limited to 'fs/lockd')
-rw-r--r-- | fs/lockd/clntproc.c | 34 | ||||
-rw-r--r-- | fs/lockd/svc.c | 24 | ||||
-rw-r--r-- | fs/lockd/svcsubs.c | 64 |
3 files changed, 78 insertions, 44 deletions
diff --git a/fs/lockd/clntproc.c b/fs/lockd/clntproc.c index c25a19c97..d0c70c276 100644 --- a/fs/lockd/clntproc.c +++ b/fs/lockd/clntproc.c @@ -90,7 +90,8 @@ nlmclnt_proc(struct inode *inode, int cmd, struct file_lock *fl) struct nfs_server *nfssrv = NFS_SERVER(inode); struct nlm_host *host; struct nlm_rqst reqst, *call = &reqst; - unsigned long oldmask; + sigset_t oldset; + unsigned long flags; int status; /* Always use NLM version 1 over UDP for now... */ @@ -114,16 +115,21 @@ nlmclnt_proc(struct inode *inode, int cmd, struct file_lock *fl) } /* Keep the old signal mask */ - oldmask = current->blocked; + spin_lock_irqsave(¤t->sigmask_lock, flags); + oldset = current->blocked; /* If we're cleaning up locks because the process is exiting, * perform the RPC call asynchronously. */ if (cmd == F_SETLK && fl->fl_type == F_UNLCK - && (current->flags & PF_EXITING)) { - current->blocked = ~0UL; /* Mask all signals */ + && (current->flags & PF_EXITING)) { + sigfillset(¤t->blocked); /* Mask all signals */ + recalc_sigpending(current); + spin_unlock_irqrestore(¤t->sigmask_lock, flags); + call = nlmclnt_alloc_call(); call->a_flags = RPC_TASK_ASYNC; } else { + spin_unlock_irqrestore(¤t->sigmask_lock, flags); call->a_flags = 0; } call->a_host = host; @@ -145,7 +151,10 @@ nlmclnt_proc(struct inode *inode, int cmd, struct file_lock *fl) if (status < 0 && (call->a_flags & RPC_TASK_ASYNC)) rpc_free(call); - current->blocked = oldmask; + spin_lock_irqsave(¤t->sigmask_lock, flags); + current->blocked = oldset; + recalc_sigpending(current); + spin_unlock_irqrestore(¤t->sigmask_lock, flags); done: dprintk("lockd: clnt proc returns %d\n", status); @@ -454,11 +463,16 @@ int nlmclnt_cancel(struct nlm_host *host, struct file_lock *fl) { struct nlm_rqst *req; - unsigned long oldmask = current->blocked; + unsigned long flags; + sigset_t oldset; int status; /* Block all signals while setting up call */ - current->blocked = ~0UL; + spin_lock_irqsave(¤t->sigmask_lock, flags); + oldset = current->blocked; + sigfillset(¤t->blocked); + recalc_sigpending(current); + spin_unlock_irqrestore(¤t->sigmask_lock, flags); do { req = (struct nlm_rqst *) rpc_allocate(RPC_TASK_ASYNC, @@ -474,7 +488,11 @@ nlmclnt_cancel(struct nlm_host *host, struct file_lock *fl) if (status < 0) rpc_free(req); - current->blocked = oldmask; + spin_lock_irqsave(¤t->sigmask_lock, flags); + current->blocked = oldset; + recalc_sigpending(current); + spin_unlock_irqrestore(¤t->sigmask_lock, flags); + return status; } diff --git a/fs/lockd/svc.c b/fs/lockd/svc.c index c5f77ef89..e649cf633 100644 --- a/fs/lockd/svc.c +++ b/fs/lockd/svc.c @@ -37,8 +37,7 @@ #define NLMDBG_FACILITY NLMDBG_SVC #define LOCKD_BUFSIZE (1024 + NLMSSVC_XDRSIZE) -#define BLOCKABLE_SIGS (~(_S(SIGKILL) | _S(SIGSTOP))) -#define _S(sig) (1 << ((sig) - 1)) +#define BLOCKABLE_SIGS (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) extern struct svc_program nlmsvc_program; struct nlmsvc_binding * nlmsvc_ops = NULL; @@ -65,7 +64,6 @@ static void lockd(struct svc_rqst *rqstp) { struct svc_serv *serv = rqstp->rq_server; - sigset_t oldsigmask; int err = 0; /* Lock module and set up kernel thread */ @@ -118,8 +116,11 @@ lockd(struct svc_rqst *rqstp) */ while ((nlmsvc_users || !signalled()) && nlmsvc_pid == current->pid) { - if (signalled()) - current->signal = 0; + if (signalled()) { + spin_lock_irq(¤t->sigmask_lock); + flush_signals(current); + spin_unlock_irq(¤t->sigmask_lock); + } /* * Retry any blocked locks that have been notified by @@ -162,10 +163,17 @@ lockd(struct svc_rqst *rqstp) } /* Process request with all signals blocked. */ - oldsigmask = current->blocked; - current->blocked = BLOCKABLE_SIGS; + spin_lock_irq(¤t->sigmask_lock); + siginitsetinv(¤t->blocked, ~BLOCKABLE_SIGS); + recalc_sigpending(current); + spin_unlock_irq(¤t->sigmask_lock); + svc_process(serv, rqstp); - current->blocked = oldsigmask; + + spin_lock_irq(¤t->sigmask_lock); + sigemptyset(¤t->blocked); + recalc_sigpending(current); + spin_unlock_irq(¤t->sigmask_lock); /* Unlock export hash tables */ if (nlmsvc_ops) diff --git a/fs/lockd/svcsubs.c b/fs/lockd/svcsubs.c index 0c2380de3..ce405d8d5 100644 --- a/fs/lockd/svcsubs.c +++ b/fs/lockd/svcsubs.c @@ -24,24 +24,25 @@ * Global file hash table */ #define FILE_NRHASH 32 -#define FILE_HASH(dhash) ((dhash) & FILE_NRHASH) +#define FILE_HASH_BITS 5 static struct nlm_file * nlm_files[FILE_NRHASH]; static struct semaphore nlm_file_sema = MUTEX; +static unsigned int file_hash(dev_t dev, ino_t ino) +{ + unsigned long tmp = (unsigned long) ino | (unsigned long) dev; + tmp = tmp + (tmp >> FILE_HASH_BITS) + (tmp >> FILE_HASH_BITS*2); + return tmp & (FILE_NRHASH - 1); +} + /* * Lookup file info. If it doesn't exist, create a file info struct * and open a (VFS) file for the given inode. * - * The NFS filehandle must have been validated prior to this call, - * as we assume that the dentry pointer is valid. - * * FIXME: * Note that we open the file O_RDONLY even when creating write locks. * This is not quite right, but for now, we assume the client performs * the proper R/W checking. - * - * The dentry in the FH may not be validated .. can we call this with - * the full svc_fh? */ u32 nlm_lookup_file(struct svc_rqst *rqstp, struct nlm_file **result, @@ -49,40 +50,38 @@ nlm_lookup_file(struct svc_rqst *rqstp, struct nlm_file **result, { struct nlm_file *file; struct knfs_fh *fh = (struct knfs_fh *) f; - struct dentry *dentry = fh->fh_dcookie; - unsigned int hash = FILE_HASH(dentry->d_name.hash); + unsigned int hash = file_hash(fh->fh_dev, fh->fh_ino); u32 nfserr; - dprintk("lockd: nlm_file_lookup(%s/%s)\n", - dentry->d_parent->d_name.name, dentry->d_name.name); + dprintk("lockd: nlm_file_lookup(%s/%ld)\n", + kdevname(fh->fh_dev), fh->fh_ino); /* Lock file table */ down(&nlm_file_sema); for (file = nlm_files[hash]; file; file = file->f_next) { - if (file->f_handle.fh_dcookie == dentry - && !memcmp(&file->f_handle, fh, sizeof(*fh))) + if (file->f_handle.fh_dcookie == fh->fh_dcookie && + !memcmp(&file->f_handle, fh, sizeof(*fh))) goto found; } - dprintk("lockd: creating file for %s/%s\n", - dentry->d_parent->d_name.name, dentry->d_name.name); - if (!(file = (struct nlm_file *) kmalloc(sizeof(*file), GFP_KERNEL))) { - up(&nlm_file_sema); - return nlm_lck_denied_nolocks; - } + dprintk("lockd: creating file for %s/%ld\n", + kdevname(fh->fh_dev), fh->fh_ino); + nfserr = nlm_lck_denied_nolocks; + file = (struct nlm_file *) kmalloc(sizeof(*file), GFP_KERNEL); + if (!file) + goto out_unlock; memset(file, 0, sizeof(*file)); file->f_handle = *fh; file->f_sema = MUTEX; /* Open the file. Note that this must not sleep for too long, else - * we would lock up lockd:-) So no NFS re-exports, folks. */ + * we would lock up lockd:-) So no NFS re-exports, folks. + */ if ((nfserr = nlmsvc_ops->fopen(rqstp, fh, &file->f_file)) != 0) { dprintk("lockd: open failed (nfserr %ld)\n", ntohl(nfserr)); - kfree(file); - up(&nlm_file_sema); - return nlm_lck_denied; + goto out_free; } file->f_next = nlm_files[hash]; @@ -91,9 +90,17 @@ nlm_lookup_file(struct svc_rqst *rqstp, struct nlm_file **result, found: dprintk("lockd: found file %p (count %d)\n", file, file->f_count); *result = file; - up(&nlm_file_sema); file->f_count++; - return 0; + nfserr = 0; + +out_unlock: + up(&nlm_file_sema); + return nfserr; + +out_free: + kfree(file); + nfserr = nlm_lck_denied; + goto out_unlock; } /* @@ -102,11 +109,12 @@ found: static inline void nlm_delete_file(struct nlm_file *file) { - struct dentry *dentry = file->f_file.f_dentry; + struct inode *inode = file->f_file.f_dentry->d_inode; struct nlm_file **fp, *f; - dprintk("lockd: closing file %p\n", dentry); - fp = nlm_files + FILE_HASH(dentry->d_name.hash); + dprintk("lockd: closing file %s/%ld\n", + kdevname(inode->i_dev), inode->i_ino); + fp = nlm_files + file_hash(inode->i_dev, inode->i_ino); while ((f = *fp) != NULL) { if (f == file) { *fp = file->f_next; |