Keep read and write fds with each nlm_file
We shouldn't really be using a read-only file descriptor to take a write lock. Most filesystems will put up with it. But NFS, for example, won't. Signed-off-by: J. Bruce Fields <bfields@redhat.com> Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
This commit is contained in:
parent
b661601a9f
commit
7f024fcd5c
7 changed files with 111 additions and 44 deletions
|
@ -40,13 +40,15 @@ nlm4svc_retrieve_args(struct svc_rqst *rqstp, struct nlm_args *argp,
|
||||||
|
|
||||||
/* Obtain file pointer. Not used by FREE_ALL call. */
|
/* Obtain file pointer. Not used by FREE_ALL call. */
|
||||||
if (filp != NULL) {
|
if (filp != NULL) {
|
||||||
|
int mode = lock_to_openmode(&lock->fl);
|
||||||
|
|
||||||
error = nlm_lookup_file(rqstp, &file, lock);
|
error = nlm_lookup_file(rqstp, &file, lock);
|
||||||
if (error)
|
if (error)
|
||||||
goto no_locks;
|
goto no_locks;
|
||||||
*filp = file;
|
*filp = file;
|
||||||
|
|
||||||
/* Set up the missing parts of the file_lock structure */
|
/* Set up the missing parts of the file_lock structure */
|
||||||
lock->fl.fl_file = file->f_file;
|
lock->fl.fl_file = file->f_file[mode];
|
||||||
lock->fl.fl_pid = current->tgid;
|
lock->fl.fl_pid = current->tgid;
|
||||||
lock->fl.fl_lmops = &nlmsvc_lock_operations;
|
lock->fl.fl_lmops = &nlmsvc_lock_operations;
|
||||||
nlmsvc_locks_init_private(&lock->fl, host, (pid_t)lock->svid);
|
nlmsvc_locks_init_private(&lock->fl, host, (pid_t)lock->svid);
|
||||||
|
|
|
@ -471,6 +471,7 @@ nlmsvc_lock(struct svc_rqst *rqstp, struct nlm_file *file,
|
||||||
{
|
{
|
||||||
struct nlm_block *block = NULL;
|
struct nlm_block *block = NULL;
|
||||||
int error;
|
int error;
|
||||||
|
int mode;
|
||||||
__be32 ret;
|
__be32 ret;
|
||||||
|
|
||||||
dprintk("lockd: nlmsvc_lock(%s/%ld, ty=%d, pi=%d, %Ld-%Ld, bl=%d)\n",
|
dprintk("lockd: nlmsvc_lock(%s/%ld, ty=%d, pi=%d, %Ld-%Ld, bl=%d)\n",
|
||||||
|
@ -524,7 +525,8 @@ nlmsvc_lock(struct svc_rqst *rqstp, struct nlm_file *file,
|
||||||
|
|
||||||
if (!wait)
|
if (!wait)
|
||||||
lock->fl.fl_flags &= ~FL_SLEEP;
|
lock->fl.fl_flags &= ~FL_SLEEP;
|
||||||
error = vfs_lock_file(file->f_file, F_SETLK, &lock->fl, NULL);
|
mode = lock_to_openmode(&lock->fl);
|
||||||
|
error = vfs_lock_file(file->f_file[mode], F_SETLK, &lock->fl, NULL);
|
||||||
lock->fl.fl_flags &= ~FL_SLEEP;
|
lock->fl.fl_flags &= ~FL_SLEEP;
|
||||||
|
|
||||||
dprintk("lockd: vfs_lock_file returned %d\n", error);
|
dprintk("lockd: vfs_lock_file returned %d\n", error);
|
||||||
|
@ -577,6 +579,7 @@ nlmsvc_testlock(struct svc_rqst *rqstp, struct nlm_file *file,
|
||||||
struct nlm_lock *conflock, struct nlm_cookie *cookie)
|
struct nlm_lock *conflock, struct nlm_cookie *cookie)
|
||||||
{
|
{
|
||||||
int error;
|
int error;
|
||||||
|
int mode;
|
||||||
__be32 ret;
|
__be32 ret;
|
||||||
struct nlm_lockowner *test_owner;
|
struct nlm_lockowner *test_owner;
|
||||||
|
|
||||||
|
@ -595,7 +598,8 @@ nlmsvc_testlock(struct svc_rqst *rqstp, struct nlm_file *file,
|
||||||
/* If there's a conflicting lock, remember to clean up the test lock */
|
/* If there's a conflicting lock, remember to clean up the test lock */
|
||||||
test_owner = (struct nlm_lockowner *)lock->fl.fl_owner;
|
test_owner = (struct nlm_lockowner *)lock->fl.fl_owner;
|
||||||
|
|
||||||
error = vfs_test_lock(file->f_file, &lock->fl);
|
mode = lock_to_openmode(&lock->fl);
|
||||||
|
error = vfs_test_lock(file->f_file[mode], &lock->fl);
|
||||||
if (error) {
|
if (error) {
|
||||||
/* We can't currently deal with deferred test requests */
|
/* We can't currently deal with deferred test requests */
|
||||||
if (error == FILE_LOCK_DEFERRED)
|
if (error == FILE_LOCK_DEFERRED)
|
||||||
|
@ -641,7 +645,7 @@ out:
|
||||||
__be32
|
__be32
|
||||||
nlmsvc_unlock(struct net *net, struct nlm_file *file, struct nlm_lock *lock)
|
nlmsvc_unlock(struct net *net, struct nlm_file *file, struct nlm_lock *lock)
|
||||||
{
|
{
|
||||||
int error;
|
int error = 0;
|
||||||
|
|
||||||
dprintk("lockd: nlmsvc_unlock(%s/%ld, pi=%d, %Ld-%Ld)\n",
|
dprintk("lockd: nlmsvc_unlock(%s/%ld, pi=%d, %Ld-%Ld)\n",
|
||||||
nlmsvc_file_inode(file)->i_sb->s_id,
|
nlmsvc_file_inode(file)->i_sb->s_id,
|
||||||
|
@ -654,7 +658,12 @@ nlmsvc_unlock(struct net *net, struct nlm_file *file, struct nlm_lock *lock)
|
||||||
nlmsvc_cancel_blocked(net, file, lock);
|
nlmsvc_cancel_blocked(net, file, lock);
|
||||||
|
|
||||||
lock->fl.fl_type = F_UNLCK;
|
lock->fl.fl_type = F_UNLCK;
|
||||||
error = vfs_lock_file(file->f_file, F_SETLK, &lock->fl, NULL);
|
if (file->f_file[O_RDONLY])
|
||||||
|
error = vfs_lock_file(file->f_file[O_RDONLY], F_SETLK,
|
||||||
|
&lock->fl, NULL);
|
||||||
|
if (file->f_file[O_WRONLY])
|
||||||
|
error = vfs_lock_file(file->f_file[O_WRONLY], F_SETLK,
|
||||||
|
&lock->fl, NULL);
|
||||||
|
|
||||||
return (error < 0)? nlm_lck_denied_nolocks : nlm_granted;
|
return (error < 0)? nlm_lck_denied_nolocks : nlm_granted;
|
||||||
}
|
}
|
||||||
|
@ -671,6 +680,7 @@ nlmsvc_cancel_blocked(struct net *net, struct nlm_file *file, struct nlm_lock *l
|
||||||
{
|
{
|
||||||
struct nlm_block *block;
|
struct nlm_block *block;
|
||||||
int status = 0;
|
int status = 0;
|
||||||
|
int mode;
|
||||||
|
|
||||||
dprintk("lockd: nlmsvc_cancel(%s/%ld, pi=%d, %Ld-%Ld)\n",
|
dprintk("lockd: nlmsvc_cancel(%s/%ld, pi=%d, %Ld-%Ld)\n",
|
||||||
nlmsvc_file_inode(file)->i_sb->s_id,
|
nlmsvc_file_inode(file)->i_sb->s_id,
|
||||||
|
@ -686,7 +696,8 @@ nlmsvc_cancel_blocked(struct net *net, struct nlm_file *file, struct nlm_lock *l
|
||||||
block = nlmsvc_lookup_block(file, lock);
|
block = nlmsvc_lookup_block(file, lock);
|
||||||
mutex_unlock(&file->f_mutex);
|
mutex_unlock(&file->f_mutex);
|
||||||
if (block != NULL) {
|
if (block != NULL) {
|
||||||
vfs_cancel_lock(block->b_file->f_file,
|
mode = lock_to_openmode(&lock->fl);
|
||||||
|
vfs_cancel_lock(block->b_file->f_file[mode],
|
||||||
&block->b_call->a_args.lock.fl);
|
&block->b_call->a_args.lock.fl);
|
||||||
status = nlmsvc_unlink_block(block);
|
status = nlmsvc_unlink_block(block);
|
||||||
nlmsvc_release_block(block);
|
nlmsvc_release_block(block);
|
||||||
|
@ -803,6 +814,7 @@ nlmsvc_grant_blocked(struct nlm_block *block)
|
||||||
{
|
{
|
||||||
struct nlm_file *file = block->b_file;
|
struct nlm_file *file = block->b_file;
|
||||||
struct nlm_lock *lock = &block->b_call->a_args.lock;
|
struct nlm_lock *lock = &block->b_call->a_args.lock;
|
||||||
|
int mode;
|
||||||
int error;
|
int error;
|
||||||
loff_t fl_start, fl_end;
|
loff_t fl_start, fl_end;
|
||||||
|
|
||||||
|
@ -828,7 +840,8 @@ nlmsvc_grant_blocked(struct nlm_block *block)
|
||||||
lock->fl.fl_flags |= FL_SLEEP;
|
lock->fl.fl_flags |= FL_SLEEP;
|
||||||
fl_start = lock->fl.fl_start;
|
fl_start = lock->fl.fl_start;
|
||||||
fl_end = lock->fl.fl_end;
|
fl_end = lock->fl.fl_end;
|
||||||
error = vfs_lock_file(file->f_file, F_SETLK, &lock->fl, NULL);
|
mode = lock_to_openmode(&lock->fl);
|
||||||
|
error = vfs_lock_file(file->f_file[mode], F_SETLK, &lock->fl, NULL);
|
||||||
lock->fl.fl_flags &= ~FL_SLEEP;
|
lock->fl.fl_flags &= ~FL_SLEEP;
|
||||||
lock->fl.fl_start = fl_start;
|
lock->fl.fl_start = fl_start;
|
||||||
lock->fl.fl_end = fl_end;
|
lock->fl.fl_end = fl_end;
|
||||||
|
|
|
@ -55,6 +55,7 @@ nlmsvc_retrieve_args(struct svc_rqst *rqstp, struct nlm_args *argp,
|
||||||
struct nlm_host *host = NULL;
|
struct nlm_host *host = NULL;
|
||||||
struct nlm_file *file = NULL;
|
struct nlm_file *file = NULL;
|
||||||
struct nlm_lock *lock = &argp->lock;
|
struct nlm_lock *lock = &argp->lock;
|
||||||
|
int mode;
|
||||||
__be32 error = 0;
|
__be32 error = 0;
|
||||||
|
|
||||||
/* nfsd callbacks must have been installed for this procedure */
|
/* nfsd callbacks must have been installed for this procedure */
|
||||||
|
@ -75,7 +76,8 @@ nlmsvc_retrieve_args(struct svc_rqst *rqstp, struct nlm_args *argp,
|
||||||
*filp = file;
|
*filp = file;
|
||||||
|
|
||||||
/* Set up the missing parts of the file_lock structure */
|
/* Set up the missing parts of the file_lock structure */
|
||||||
lock->fl.fl_file = file->f_file;
|
mode = lock_to_openmode(&lock->fl);
|
||||||
|
lock->fl.fl_file = file->f_file[mode];
|
||||||
lock->fl.fl_pid = current->tgid;
|
lock->fl.fl_pid = current->tgid;
|
||||||
lock->fl.fl_lmops = &nlmsvc_lock_operations;
|
lock->fl.fl_lmops = &nlmsvc_lock_operations;
|
||||||
nlmsvc_locks_init_private(&lock->fl, host, (pid_t)lock->svid);
|
nlmsvc_locks_init_private(&lock->fl, host, (pid_t)lock->svid);
|
||||||
|
|
|
@ -71,14 +71,35 @@ static inline unsigned int file_hash(struct nfs_fh *f)
|
||||||
return tmp & (FILE_NRHASH - 1);
|
return tmp & (FILE_NRHASH - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int lock_to_openmode(struct file_lock *lock)
|
||||||
|
{
|
||||||
|
return (lock->fl_type == F_WRLCK) ? O_WRONLY : O_RDONLY;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Open the file. Note that if we're reexporting, for example,
|
||||||
|
* this could block the lockd thread for a while.
|
||||||
|
*
|
||||||
|
* We have to make sure we have the right credential to open
|
||||||
|
* the file.
|
||||||
|
*/
|
||||||
|
static __be32 nlm_do_fopen(struct svc_rqst *rqstp,
|
||||||
|
struct nlm_file *file, int mode)
|
||||||
|
{
|
||||||
|
struct file **fp = &file->f_file[mode];
|
||||||
|
__be32 nfserr;
|
||||||
|
|
||||||
|
if (*fp)
|
||||||
|
return 0;
|
||||||
|
nfserr = nlmsvc_ops->fopen(rqstp, &file->f_handle, fp, mode);
|
||||||
|
if (nfserr)
|
||||||
|
dprintk("lockd: open failed (error %d)\n", nfserr);
|
||||||
|
return nfserr;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Lookup file info. If it doesn't exist, create a file info struct
|
* Lookup file info. If it doesn't exist, create a file info struct
|
||||||
* and open a (VFS) file for the given inode.
|
* and open a (VFS) file for the given inode.
|
||||||
*
|
|
||||||
* 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.
|
|
||||||
*/
|
*/
|
||||||
__be32
|
__be32
|
||||||
nlm_lookup_file(struct svc_rqst *rqstp, struct nlm_file **result,
|
nlm_lookup_file(struct svc_rqst *rqstp, struct nlm_file **result,
|
||||||
|
@ -87,42 +108,38 @@ nlm_lookup_file(struct svc_rqst *rqstp, struct nlm_file **result,
|
||||||
struct nlm_file *file;
|
struct nlm_file *file;
|
||||||
unsigned int hash;
|
unsigned int hash;
|
||||||
__be32 nfserr;
|
__be32 nfserr;
|
||||||
|
int mode;
|
||||||
|
|
||||||
nlm_debug_print_fh("nlm_lookup_file", &lock->fh);
|
nlm_debug_print_fh("nlm_lookup_file", &lock->fh);
|
||||||
|
|
||||||
hash = file_hash(&lock->fh);
|
hash = file_hash(&lock->fh);
|
||||||
|
mode = lock_to_openmode(&lock->fl);
|
||||||
|
|
||||||
/* Lock file table */
|
/* Lock file table */
|
||||||
mutex_lock(&nlm_file_mutex);
|
mutex_lock(&nlm_file_mutex);
|
||||||
|
|
||||||
hlist_for_each_entry(file, &nlm_files[hash], f_list)
|
hlist_for_each_entry(file, &nlm_files[hash], f_list)
|
||||||
if (!nfs_compare_fh(&file->f_handle, &lock->fh))
|
if (!nfs_compare_fh(&file->f_handle, &lock->fh)) {
|
||||||
|
mutex_lock(&file->f_mutex);
|
||||||
|
nfserr = nlm_do_fopen(rqstp, file, mode);
|
||||||
|
mutex_unlock(&file->f_mutex);
|
||||||
goto found;
|
goto found;
|
||||||
|
}
|
||||||
nlm_debug_print_fh("creating file for", &lock->fh);
|
nlm_debug_print_fh("creating file for", &lock->fh);
|
||||||
|
|
||||||
nfserr = nlm_lck_denied_nolocks;
|
nfserr = nlm_lck_denied_nolocks;
|
||||||
file = kzalloc(sizeof(*file), GFP_KERNEL);
|
file = kzalloc(sizeof(*file), GFP_KERNEL);
|
||||||
if (!file)
|
if (!file)
|
||||||
goto out_unlock;
|
goto out_free;
|
||||||
|
|
||||||
memcpy(&file->f_handle, &lock->fh, sizeof(struct nfs_fh));
|
memcpy(&file->f_handle, &lock->fh, sizeof(struct nfs_fh));
|
||||||
mutex_init(&file->f_mutex);
|
mutex_init(&file->f_mutex);
|
||||||
INIT_HLIST_NODE(&file->f_list);
|
INIT_HLIST_NODE(&file->f_list);
|
||||||
INIT_LIST_HEAD(&file->f_blocks);
|
INIT_LIST_HEAD(&file->f_blocks);
|
||||||
|
|
||||||
/*
|
nfserr = nlm_do_fopen(rqstp, file, mode);
|
||||||
* Open the file. Note that if we're reexporting, for example,
|
if (nfserr)
|
||||||
* this could block the lockd thread for a while.
|
goto out_unlock;
|
||||||
*
|
|
||||||
* We have to make sure we have the right credential to open
|
|
||||||
* the file.
|
|
||||||
*/
|
|
||||||
nfserr = nlmsvc_ops->fopen(rqstp, &lock->fh, &file->f_file);
|
|
||||||
if (nfserr) {
|
|
||||||
dprintk("lockd: open failed (error %d)\n", nfserr);
|
|
||||||
goto out_free;
|
|
||||||
}
|
|
||||||
|
|
||||||
hlist_add_head(&file->f_list, &nlm_files[hash]);
|
hlist_add_head(&file->f_list, &nlm_files[hash]);
|
||||||
|
|
||||||
|
@ -130,7 +147,6 @@ found:
|
||||||
dprintk("lockd: found file %p (count %d)\n", file, file->f_count);
|
dprintk("lockd: found file %p (count %d)\n", file, file->f_count);
|
||||||
*result = file;
|
*result = file;
|
||||||
file->f_count++;
|
file->f_count++;
|
||||||
nfserr = 0;
|
|
||||||
|
|
||||||
out_unlock:
|
out_unlock:
|
||||||
mutex_unlock(&nlm_file_mutex);
|
mutex_unlock(&nlm_file_mutex);
|
||||||
|
@ -150,13 +166,34 @@ nlm_delete_file(struct nlm_file *file)
|
||||||
nlm_debug_print_file("closing file", file);
|
nlm_debug_print_file("closing file", file);
|
||||||
if (!hlist_unhashed(&file->f_list)) {
|
if (!hlist_unhashed(&file->f_list)) {
|
||||||
hlist_del(&file->f_list);
|
hlist_del(&file->f_list);
|
||||||
nlmsvc_ops->fclose(file->f_file);
|
if (file->f_file[O_RDONLY])
|
||||||
|
nlmsvc_ops->fclose(file->f_file[O_RDONLY]);
|
||||||
|
if (file->f_file[O_WRONLY])
|
||||||
|
nlmsvc_ops->fclose(file->f_file[O_WRONLY]);
|
||||||
kfree(file);
|
kfree(file);
|
||||||
} else {
|
} else {
|
||||||
printk(KERN_WARNING "lockd: attempt to release unknown file!\n");
|
printk(KERN_WARNING "lockd: attempt to release unknown file!\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int nlm_unlock_files(struct nlm_file *file)
|
||||||
|
{
|
||||||
|
struct file_lock lock;
|
||||||
|
struct file *f;
|
||||||
|
|
||||||
|
lock.fl_type = F_UNLCK;
|
||||||
|
lock.fl_start = 0;
|
||||||
|
lock.fl_end = OFFSET_MAX;
|
||||||
|
for (f = file->f_file[0]; f <= file->f_file[1]; f++) {
|
||||||
|
if (f && vfs_lock_file(f, F_SETLK, &lock, NULL) < 0) {
|
||||||
|
pr_warn("lockd: unlock failure in %s:%d\n",
|
||||||
|
__FILE__, __LINE__);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Loop over all locks on the given file and perform the specified
|
* Loop over all locks on the given file and perform the specified
|
||||||
* action.
|
* action.
|
||||||
|
@ -184,17 +221,10 @@ again:
|
||||||
|
|
||||||
lockhost = ((struct nlm_lockowner *)fl->fl_owner)->host;
|
lockhost = ((struct nlm_lockowner *)fl->fl_owner)->host;
|
||||||
if (match(lockhost, host)) {
|
if (match(lockhost, host)) {
|
||||||
struct file_lock lock = *fl;
|
|
||||||
|
|
||||||
spin_unlock(&flctx->flc_lock);
|
spin_unlock(&flctx->flc_lock);
|
||||||
lock.fl_type = F_UNLCK;
|
if (nlm_unlock_files(file))
|
||||||
lock.fl_start = 0;
|
|
||||||
lock.fl_end = OFFSET_MAX;
|
|
||||||
if (vfs_lock_file(file->f_file, F_SETLK, &lock, NULL) < 0) {
|
|
||||||
printk("lockd: unlock failure in %s:%d\n",
|
|
||||||
__FILE__, __LINE__);
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
|
||||||
goto again;
|
goto again;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -248,6 +278,15 @@ nlm_file_inuse(struct nlm_file *file)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void nlm_close_files(struct nlm_file *file)
|
||||||
|
{
|
||||||
|
struct file *f;
|
||||||
|
|
||||||
|
for (f = file->f_file[0]; f <= file->f_file[1]; f++)
|
||||||
|
if (f)
|
||||||
|
nlmsvc_ops->fclose(f);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Loop over all files in the file table.
|
* Loop over all files in the file table.
|
||||||
*/
|
*/
|
||||||
|
@ -278,7 +317,7 @@ nlm_traverse_files(void *data, nlm_host_match_fn_t match,
|
||||||
if (list_empty(&file->f_blocks) && !file->f_locks
|
if (list_empty(&file->f_blocks) && !file->f_locks
|
||||||
&& !file->f_shares && !file->f_count) {
|
&& !file->f_shares && !file->f_count) {
|
||||||
hlist_del(&file->f_list);
|
hlist_del(&file->f_list);
|
||||||
nlmsvc_ops->fclose(file->f_file);
|
nlm_close_files(file);
|
||||||
kfree(file);
|
kfree(file);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -412,6 +451,7 @@ nlmsvc_invalidate_all(void)
|
||||||
nlm_traverse_files(NULL, nlmsvc_is_client, NULL);
|
nlm_traverse_files(NULL, nlmsvc_is_client, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
nlmsvc_match_sb(void *datap, struct nlm_file *file)
|
nlmsvc_match_sb(void *datap, struct nlm_file *file)
|
||||||
{
|
{
|
||||||
|
|
|
@ -25,9 +25,11 @@
|
||||||
* Note: we hold the dentry use count while the file is open.
|
* Note: we hold the dentry use count while the file is open.
|
||||||
*/
|
*/
|
||||||
static __be32
|
static __be32
|
||||||
nlm_fopen(struct svc_rqst *rqstp, struct nfs_fh *f, struct file **filp)
|
nlm_fopen(struct svc_rqst *rqstp, struct nfs_fh *f, struct file **filp,
|
||||||
|
int mode)
|
||||||
{
|
{
|
||||||
__be32 nfserr;
|
__be32 nfserr;
|
||||||
|
int access;
|
||||||
struct svc_fh fh;
|
struct svc_fh fh;
|
||||||
|
|
||||||
/* must initialize before using! but maxsize doesn't matter */
|
/* must initialize before using! but maxsize doesn't matter */
|
||||||
|
@ -36,7 +38,9 @@ nlm_fopen(struct svc_rqst *rqstp, struct nfs_fh *f, struct file **filp)
|
||||||
memcpy((char*)&fh.fh_handle.fh_base, f->data, f->size);
|
memcpy((char*)&fh.fh_handle.fh_base, f->data, f->size);
|
||||||
fh.fh_export = NULL;
|
fh.fh_export = NULL;
|
||||||
|
|
||||||
nfserr = nfsd_open(rqstp, &fh, S_IFREG, NFSD_MAY_LOCK, filp);
|
access = (mode == O_WRONLY) ? NFSD_MAY_WRITE : NFSD_MAY_READ;
|
||||||
|
access |= NFSD_MAY_LOCK;
|
||||||
|
nfserr = nfsd_open(rqstp, &fh, S_IFREG, access, filp);
|
||||||
fh_put(&fh);
|
fh_put(&fh);
|
||||||
/* We return nlm error codes as nlm doesn't know
|
/* We return nlm error codes as nlm doesn't know
|
||||||
* about nfsd, but nfsd does know about nlm..
|
* about nfsd, but nfsd does know about nlm..
|
||||||
|
|
|
@ -27,7 +27,8 @@ struct rpc_task;
|
||||||
struct nlmsvc_binding {
|
struct nlmsvc_binding {
|
||||||
__be32 (*fopen)(struct svc_rqst *,
|
__be32 (*fopen)(struct svc_rqst *,
|
||||||
struct nfs_fh *,
|
struct nfs_fh *,
|
||||||
struct file **);
|
struct file **,
|
||||||
|
int mode);
|
||||||
void (*fclose)(struct file *);
|
void (*fclose)(struct file *);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,8 @@
|
||||||
#ifndef LINUX_LOCKD_LOCKD_H
|
#ifndef LINUX_LOCKD_LOCKD_H
|
||||||
#define LINUX_LOCKD_LOCKD_H
|
#define LINUX_LOCKD_LOCKD_H
|
||||||
|
|
||||||
|
/* XXX: a lot of this should really be under fs/lockd. */
|
||||||
|
|
||||||
#include <linux/in.h>
|
#include <linux/in.h>
|
||||||
#include <linux/in6.h>
|
#include <linux/in6.h>
|
||||||
#include <net/ipv6.h>
|
#include <net/ipv6.h>
|
||||||
|
@ -154,7 +156,8 @@ struct nlm_rqst {
|
||||||
struct nlm_file {
|
struct nlm_file {
|
||||||
struct hlist_node f_list; /* linked list */
|
struct hlist_node f_list; /* linked list */
|
||||||
struct nfs_fh f_handle; /* NFS file handle */
|
struct nfs_fh f_handle; /* NFS file handle */
|
||||||
struct file * f_file; /* VFS file pointer */
|
struct file * f_file[2]; /* VFS file pointers,
|
||||||
|
indexed by O_ flags */
|
||||||
struct nlm_share * f_shares; /* DOS shares */
|
struct nlm_share * f_shares; /* DOS shares */
|
||||||
struct list_head f_blocks; /* blocked locks */
|
struct list_head f_blocks; /* blocked locks */
|
||||||
unsigned int f_locks; /* guesstimate # of locks */
|
unsigned int f_locks; /* guesstimate # of locks */
|
||||||
|
@ -267,6 +270,7 @@ typedef int (*nlm_host_match_fn_t)(void *cur, struct nlm_host *ref);
|
||||||
/*
|
/*
|
||||||
* Server-side lock handling
|
* Server-side lock handling
|
||||||
*/
|
*/
|
||||||
|
int lock_to_openmode(struct file_lock *);
|
||||||
__be32 nlmsvc_lock(struct svc_rqst *, struct nlm_file *,
|
__be32 nlmsvc_lock(struct svc_rqst *, struct nlm_file *,
|
||||||
struct nlm_host *, struct nlm_lock *, int,
|
struct nlm_host *, struct nlm_lock *, int,
|
||||||
struct nlm_cookie *, int);
|
struct nlm_cookie *, int);
|
||||||
|
@ -301,7 +305,8 @@ int nlmsvc_unlock_all_by_ip(struct sockaddr *server_addr);
|
||||||
|
|
||||||
static inline struct inode *nlmsvc_file_inode(struct nlm_file *file)
|
static inline struct inode *nlmsvc_file_inode(struct nlm_file *file)
|
||||||
{
|
{
|
||||||
return locks_inode(file->f_file);
|
return locks_inode(file->f_file[O_RDONLY] ?
|
||||||
|
file->f_file[O_RDONLY] : file->f_file[O_WRONLY]);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int __nlm_privileged_request4(const struct sockaddr *sap)
|
static inline int __nlm_privileged_request4(const struct sockaddr *sap)
|
||||||
|
|
Loading…
Add table
Reference in a new issue