X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=fs%2Fnfs%2Ffile.c;h=57ccbd277fcecc529d15bb5ca42d6fa64f24d93b;hb=6a77f38946aaee1cd85eeec6cf4229b204c15071;hp=21071ddd466277f0bb585f375ad6010d513109eb;hpb=87fc8d1bb10cd459024a742c6a10961fefcef18f;p=linux-2.6.git diff --git a/fs/nfs/file.c b/fs/nfs/file.c index 21071ddd4..57ccbd277 100644 --- a/fs/nfs/file.c +++ b/fs/nfs/file.c @@ -295,10 +295,19 @@ out_swapfile: static int do_getlk(struct file *filp, int cmd, struct file_lock *fl) { struct inode *inode = filp->f_mapping->host; - int status; + int status = 0; lock_kernel(); - status = NFS_PROTO(inode)->lock(filp, cmd, fl); + /* Use local locking if mounted with "-onolock" */ + if (!(NFS_SERVER(inode)->flags & NFS_MOUNT_NONLM)) + status = NFS_PROTO(inode)->lock(filp, cmd, fl); + else { + struct file_lock *cfl = posix_test_lock(filp, fl); + + fl->fl_type = F_UNLCK; + if (cfl != NULL) + memcpy(fl, cfl, sizeof(*fl)); + } unlock_kernel(); return status; } @@ -325,7 +334,12 @@ static int do_unlk(struct file *filp, int cmd, struct file_lock *fl) * still need to complete the unlock. */ lock_kernel(); - status = NFS_PROTO(inode)->lock(filp, cmd, fl); + /* Use local locking if mounted with "-onolock" */ + if (!(NFS_SERVER(inode)->flags & NFS_MOUNT_NONLM)) + status = NFS_PROTO(inode)->lock(filp, cmd, fl); + else + status = posix_lock_file_wait(filp, fl); + unlock_kernel(); rpc_clnt_sigunmask(NFS_CLIENT(inode), &oldset); return status; } @@ -333,8 +347,10 @@ static int do_unlk(struct file *filp, int cmd, struct file_lock *fl) static int do_setlk(struct file *filp, int cmd, struct file_lock *fl) { struct inode *inode = filp->f_mapping->host; + sigset_t oldset; int status; + rpc_clnt_sigmask(NFS_CLIENT(inode), &oldset); /* * Flush all pending writes before doing anything * with locks.. @@ -348,21 +364,25 @@ static int do_setlk(struct file *filp, int cmd, struct file_lock *fl) status = filemap_fdatawait(filp->f_mapping); } if (status < 0) - return status; + goto out; lock_kernel(); - status = NFS_PROTO(inode)->lock(filp, cmd, fl); - /* If we were signalled we still need to ensure that - * we clean up any state on the server. We therefore - * record the lock call as having succeeded in order to - * ensure that locks_remove_posix() cleans it out when - * the process exits. - */ - if (status == -EINTR || status == -ERESTARTSYS) - posix_lock_file(filp, fl); + /* Use local locking if mounted with "-onolock" */ + if (!(NFS_SERVER(inode)->flags & NFS_MOUNT_NONLM)) { + status = NFS_PROTO(inode)->lock(filp, cmd, fl); + /* If we were signalled we still need to ensure that + * we clean up any state on the server. We therefore + * record the lock call as having succeeded in order to + * ensure that locks_remove_posix() cleans it out when + * the process exits. + */ + if (status == -EINTR || status == -ERESTARTSYS) + posix_lock_file_wait(filp, fl); + } else + status = posix_lock_file_wait(filp, fl); unlock_kernel(); if (status < 0) - return status; + goto out; /* * Make sure we clear the cache whenever we try to get the lock. * This makes locking act as a cache coherency point. @@ -373,7 +393,9 @@ static int do_setlk(struct file *filp, int cmd, struct file_lock *fl) up(&inode->i_sem); filemap_fdatawait(filp->f_mapping); nfs_zap_caches(inode); - return 0; +out: + rpc_clnt_sigunmask(NFS_CLIENT(inode), &oldset); + return status; } /* @@ -396,15 +418,6 @@ nfs_lock(struct file *filp, int cmd, struct file_lock *fl) if ((inode->i_mode & (S_ISGID | S_IXGRP)) == S_ISGID) return -ENOLCK; - if (NFS_PROTO(inode)->version != 4) { - /* Fake OK code if mounted without NLM support */ - if (NFS_SERVER(inode)->flags & NFS_MOUNT_NONLM) { - if (IS_GETLK(cmd)) - return LOCK_USE_CLNT; - return 0; - } - } - /* * No BSD flocks over NFS allowed. * Note: we could try to fake a POSIX lock request here by