提交 cadc723c 编写于 作者: T Trond Myklebust

Merge branch 'bkl-removal' into next

...@@ -224,7 +224,9 @@ void nlm_release_call(struct nlm_rqst *call) ...@@ -224,7 +224,9 @@ void nlm_release_call(struct nlm_rqst *call)
static void nlmclnt_rpc_release(void *data) static void nlmclnt_rpc_release(void *data)
{ {
lock_kernel();
nlm_release_call(data); nlm_release_call(data);
unlock_kernel();
} }
static int nlm_wait_on_grace(wait_queue_head_t *queue) static int nlm_wait_on_grace(wait_queue_head_t *queue)
...@@ -710,7 +712,9 @@ static void nlmclnt_unlock_callback(struct rpc_task *task, void *data) ...@@ -710,7 +712,9 @@ static void nlmclnt_unlock_callback(struct rpc_task *task, void *data)
die: die:
return; return;
retry_rebind: retry_rebind:
lock_kernel();
nlm_rebind_host(req->a_host); nlm_rebind_host(req->a_host);
unlock_kernel();
retry_unlock: retry_unlock:
rpc_restart_call(task); rpc_restart_call(task);
} }
...@@ -788,7 +792,9 @@ static void nlmclnt_cancel_callback(struct rpc_task *task, void *data) ...@@ -788,7 +792,9 @@ static void nlmclnt_cancel_callback(struct rpc_task *task, void *data)
/* Don't ever retry more than 3 times */ /* Don't ever retry more than 3 times */
if (req->a_retries++ >= NLMCLNT_MAX_RETRIES) if (req->a_retries++ >= NLMCLNT_MAX_RETRIES)
goto die; goto die;
lock_kernel();
nlm_rebind_host(req->a_host); nlm_rebind_host(req->a_host);
unlock_kernel();
rpc_restart_call(task); rpc_restart_call(task);
rpc_delay(task, 30 * HZ); rpc_delay(task, 30 * HZ);
} }
......
...@@ -248,7 +248,9 @@ static void nlm4svc_callback_exit(struct rpc_task *task, void *data) ...@@ -248,7 +248,9 @@ static void nlm4svc_callback_exit(struct rpc_task *task, void *data)
static void nlm4svc_callback_release(void *data) static void nlm4svc_callback_release(void *data)
{ {
lock_kernel();
nlm_release_call(data); nlm_release_call(data);
unlock_kernel();
} }
static const struct rpc_call_ops nlm4svc_callback_ops = { static const struct rpc_call_ops nlm4svc_callback_ops = {
......
...@@ -795,6 +795,7 @@ static void nlmsvc_grant_callback(struct rpc_task *task, void *data) ...@@ -795,6 +795,7 @@ static void nlmsvc_grant_callback(struct rpc_task *task, void *data)
dprintk("lockd: GRANT_MSG RPC callback\n"); dprintk("lockd: GRANT_MSG RPC callback\n");
lock_kernel();
/* if the block is not on a list at this point then it has /* if the block is not on a list at this point then it has
* been invalidated. Don't try to requeue it. * been invalidated. Don't try to requeue it.
* *
...@@ -804,7 +805,7 @@ static void nlmsvc_grant_callback(struct rpc_task *task, void *data) ...@@ -804,7 +805,7 @@ static void nlmsvc_grant_callback(struct rpc_task *task, void *data)
* for nlm_blocked? * for nlm_blocked?
*/ */
if (list_empty(&block->b_list)) if (list_empty(&block->b_list))
return; goto out;
/* Technically, we should down the file semaphore here. Since we /* Technically, we should down the file semaphore here. Since we
* move the block towards the head of the queue only, no harm * move the block towards the head of the queue only, no harm
...@@ -818,13 +819,17 @@ static void nlmsvc_grant_callback(struct rpc_task *task, void *data) ...@@ -818,13 +819,17 @@ static void nlmsvc_grant_callback(struct rpc_task *task, void *data)
} }
nlmsvc_insert_block(block, timeout); nlmsvc_insert_block(block, timeout);
svc_wake_up(block->b_daemon); svc_wake_up(block->b_daemon);
out:
unlock_kernel();
} }
static void nlmsvc_grant_release(void *data) static void nlmsvc_grant_release(void *data)
{ {
struct nlm_rqst *call = data; struct nlm_rqst *call = data;
lock_kernel();
nlmsvc_release_block(call->a_block); nlmsvc_release_block(call->a_block);
unlock_kernel();
} }
static const struct rpc_call_ops nlmsvc_grant_ops = { static const struct rpc_call_ops nlmsvc_grant_ops = {
......
...@@ -278,7 +278,9 @@ static void nlmsvc_callback_exit(struct rpc_task *task, void *data) ...@@ -278,7 +278,9 @@ static void nlmsvc_callback_exit(struct rpc_task *task, void *data)
static void nlmsvc_callback_release(void *data) static void nlmsvc_callback_release(void *data)
{ {
lock_kernel();
nlm_release_call(data); nlm_release_call(data);
unlock_kernel();
} }
static const struct rpc_call_ops nlmsvc_callback_ops = { static const struct rpc_call_ops nlmsvc_callback_ops = {
......
...@@ -139,10 +139,8 @@ nfs_opendir(struct inode *inode, struct file *filp) ...@@ -139,10 +139,8 @@ nfs_opendir(struct inode *inode, struct file *filp)
nfs_inc_stats(inode, NFSIOS_VFSOPEN); nfs_inc_stats(inode, NFSIOS_VFSOPEN);
lock_kernel();
/* Call generic open code in order to cache credentials */ /* Call generic open code in order to cache credentials */
res = nfs_open(inode, filp); res = nfs_open(inode, filp);
unlock_kernel();
return res; return res;
} }
...@@ -536,8 +534,6 @@ static int nfs_readdir(struct file *filp, void *dirent, filldir_t filldir) ...@@ -536,8 +534,6 @@ static int nfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
(long long)filp->f_pos); (long long)filp->f_pos);
nfs_inc_stats(inode, NFSIOS_VFSGETDENTS); nfs_inc_stats(inode, NFSIOS_VFSGETDENTS);
lock_kernel();
/* /*
* filp->f_pos points to the dirent entry number. * filp->f_pos points to the dirent entry number.
* *desc->dir_cookie has the cookie for the next entry. We have * *desc->dir_cookie has the cookie for the next entry. We have
...@@ -595,7 +591,6 @@ static int nfs_readdir(struct file *filp, void *dirent, filldir_t filldir) ...@@ -595,7 +591,6 @@ static int nfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
} }
out: out:
nfs_unblock_sillyrename(dentry); nfs_unblock_sillyrename(dentry);
unlock_kernel();
if (res > 0) if (res > 0)
res = 0; res = 0;
dfprintk(FILE, "NFS: readdir(%s/%s) returns %ld\n", dfprintk(FILE, "NFS: readdir(%s/%s) returns %ld\n",
...@@ -779,7 +774,6 @@ static int nfs_lookup_revalidate(struct dentry * dentry, struct nameidata *nd) ...@@ -779,7 +774,6 @@ static int nfs_lookup_revalidate(struct dentry * dentry, struct nameidata *nd)
struct nfs_fattr fattr; struct nfs_fattr fattr;
parent = dget_parent(dentry); parent = dget_parent(dentry);
lock_kernel();
dir = parent->d_inode; dir = parent->d_inode;
nfs_inc_stats(dir, NFSIOS_DENTRYREVALIDATE); nfs_inc_stats(dir, NFSIOS_DENTRYREVALIDATE);
inode = dentry->d_inode; inode = dentry->d_inode;
...@@ -817,7 +811,6 @@ static int nfs_lookup_revalidate(struct dentry * dentry, struct nameidata *nd) ...@@ -817,7 +811,6 @@ static int nfs_lookup_revalidate(struct dentry * dentry, struct nameidata *nd)
nfs_set_verifier(dentry, nfs_save_change_attribute(dir)); nfs_set_verifier(dentry, nfs_save_change_attribute(dir));
out_valid: out_valid:
unlock_kernel();
dput(parent); dput(parent);
dfprintk(LOOKUPCACHE, "NFS: %s(%s/%s) is valid\n", dfprintk(LOOKUPCACHE, "NFS: %s(%s/%s) is valid\n",
__func__, dentry->d_parent->d_name.name, __func__, dentry->d_parent->d_name.name,
...@@ -836,7 +829,6 @@ static int nfs_lookup_revalidate(struct dentry * dentry, struct nameidata *nd) ...@@ -836,7 +829,6 @@ static int nfs_lookup_revalidate(struct dentry * dentry, struct nameidata *nd)
shrink_dcache_parent(dentry); shrink_dcache_parent(dentry);
} }
d_drop(dentry); d_drop(dentry);
unlock_kernel();
dput(parent); dput(parent);
dfprintk(LOOKUPCACHE, "NFS: %s(%s/%s) is invalid\n", dfprintk(LOOKUPCACHE, "NFS: %s(%s/%s) is invalid\n",
__func__, dentry->d_parent->d_name.name, __func__, dentry->d_parent->d_name.name,
...@@ -870,6 +862,14 @@ static int nfs_dentry_delete(struct dentry *dentry) ...@@ -870,6 +862,14 @@ static int nfs_dentry_delete(struct dentry *dentry)
} }
static void nfs_drop_nlink(struct inode *inode)
{
spin_lock(&inode->i_lock);
if (inode->i_nlink > 0)
drop_nlink(inode);
spin_unlock(&inode->i_lock);
}
/* /*
* Called when the dentry loses inode. * Called when the dentry loses inode.
* We use it to clean up silly-renamed files. * We use it to clean up silly-renamed files.
...@@ -881,10 +881,8 @@ static void nfs_dentry_iput(struct dentry *dentry, struct inode *inode) ...@@ -881,10 +881,8 @@ static void nfs_dentry_iput(struct dentry *dentry, struct inode *inode)
NFS_I(inode)->cache_validity |= NFS_INO_INVALID_DATA; NFS_I(inode)->cache_validity |= NFS_INO_INVALID_DATA;
if (dentry->d_flags & DCACHE_NFSFS_RENAMED) { if (dentry->d_flags & DCACHE_NFSFS_RENAMED) {
lock_kernel();
drop_nlink(inode); drop_nlink(inode);
nfs_complete_unlink(dentry, inode); nfs_complete_unlink(dentry, inode);
unlock_kernel();
} }
iput(inode); iput(inode);
} }
...@@ -915,8 +913,6 @@ static struct dentry *nfs_lookup(struct inode *dir, struct dentry * dentry, stru ...@@ -915,8 +913,6 @@ static struct dentry *nfs_lookup(struct inode *dir, struct dentry * dentry, stru
res = ERR_PTR(-ENOMEM); res = ERR_PTR(-ENOMEM);
dentry->d_op = NFS_PROTO(dir)->dentry_ops; dentry->d_op = NFS_PROTO(dir)->dentry_ops;
lock_kernel();
/* /*
* If we're doing an exclusive create, optimize away the lookup * If we're doing an exclusive create, optimize away the lookup
* but don't hash the dentry. * but don't hash the dentry.
...@@ -924,7 +920,7 @@ static struct dentry *nfs_lookup(struct inode *dir, struct dentry * dentry, stru ...@@ -924,7 +920,7 @@ static struct dentry *nfs_lookup(struct inode *dir, struct dentry * dentry, stru
if (nfs_is_exclusive_create(dir, nd)) { if (nfs_is_exclusive_create(dir, nd)) {
d_instantiate(dentry, NULL); d_instantiate(dentry, NULL);
res = NULL; res = NULL;
goto out_unlock; goto out;
} }
parent = dentry->d_parent; parent = dentry->d_parent;
...@@ -952,8 +948,6 @@ static struct dentry *nfs_lookup(struct inode *dir, struct dentry * dentry, stru ...@@ -952,8 +948,6 @@ static struct dentry *nfs_lookup(struct inode *dir, struct dentry * dentry, stru
nfs_set_verifier(dentry, nfs_save_change_attribute(dir)); nfs_set_verifier(dentry, nfs_save_change_attribute(dir));
out_unblock_sillyrename: out_unblock_sillyrename:
nfs_unblock_sillyrename(parent); nfs_unblock_sillyrename(parent);
out_unlock:
unlock_kernel();
out: out:
return res; return res;
} }
...@@ -1011,9 +1005,7 @@ static struct dentry *nfs_atomic_lookup(struct inode *dir, struct dentry *dentry ...@@ -1011,9 +1005,7 @@ static struct dentry *nfs_atomic_lookup(struct inode *dir, struct dentry *dentry
} }
/* Open the file on the server */ /* Open the file on the server */
lock_kernel();
res = nfs4_atomic_open(dir, dentry, nd); res = nfs4_atomic_open(dir, dentry, nd);
unlock_kernel();
if (IS_ERR(res)) { if (IS_ERR(res)) {
error = PTR_ERR(res); error = PTR_ERR(res);
switch (error) { switch (error) {
...@@ -1075,9 +1067,7 @@ static int nfs_open_revalidate(struct dentry *dentry, struct nameidata *nd) ...@@ -1075,9 +1067,7 @@ static int nfs_open_revalidate(struct dentry *dentry, struct nameidata *nd)
* operations that change the directory. We therefore save the * operations that change the directory. We therefore save the
* change attribute *before* we do the RPC call. * change attribute *before* we do the RPC call.
*/ */
lock_kernel();
ret = nfs4_open_revalidate(dir, dentry, openflags, nd); ret = nfs4_open_revalidate(dir, dentry, openflags, nd);
unlock_kernel();
out: out:
dput(parent); dput(parent);
if (!ret) if (!ret)
...@@ -1230,14 +1220,11 @@ static int nfs_create(struct inode *dir, struct dentry *dentry, int mode, ...@@ -1230,14 +1220,11 @@ static int nfs_create(struct inode *dir, struct dentry *dentry, int mode,
if ((nd->flags & LOOKUP_CREATE) != 0) if ((nd->flags & LOOKUP_CREATE) != 0)
open_flags = nd->intent.open.flags; open_flags = nd->intent.open.flags;
lock_kernel();
error = NFS_PROTO(dir)->create(dir, dentry, &attr, open_flags, nd); error = NFS_PROTO(dir)->create(dir, dentry, &attr, open_flags, nd);
if (error != 0) if (error != 0)
goto out_err; goto out_err;
unlock_kernel();
return 0; return 0;
out_err: out_err:
unlock_kernel();
d_drop(dentry); d_drop(dentry);
return error; return error;
} }
...@@ -1260,14 +1247,11 @@ nfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t rdev) ...@@ -1260,14 +1247,11 @@ nfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t rdev)
attr.ia_mode = mode; attr.ia_mode = mode;
attr.ia_valid = ATTR_MODE; attr.ia_valid = ATTR_MODE;
lock_kernel();
status = NFS_PROTO(dir)->mknod(dir, dentry, &attr, rdev); status = NFS_PROTO(dir)->mknod(dir, dentry, &attr, rdev);
if (status != 0) if (status != 0)
goto out_err; goto out_err;
unlock_kernel();
return 0; return 0;
out_err: out_err:
unlock_kernel();
d_drop(dentry); d_drop(dentry);
return status; return status;
} }
...@@ -1286,15 +1270,12 @@ static int nfs_mkdir(struct inode *dir, struct dentry *dentry, int mode) ...@@ -1286,15 +1270,12 @@ static int nfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
attr.ia_valid = ATTR_MODE; attr.ia_valid = ATTR_MODE;
attr.ia_mode = mode | S_IFDIR; attr.ia_mode = mode | S_IFDIR;
lock_kernel();
error = NFS_PROTO(dir)->mkdir(dir, dentry, &attr); error = NFS_PROTO(dir)->mkdir(dir, dentry, &attr);
if (error != 0) if (error != 0)
goto out_err; goto out_err;
unlock_kernel();
return 0; return 0;
out_err: out_err:
d_drop(dentry); d_drop(dentry);
unlock_kernel();
return error; return error;
} }
...@@ -1311,14 +1292,12 @@ static int nfs_rmdir(struct inode *dir, struct dentry *dentry) ...@@ -1311,14 +1292,12 @@ static int nfs_rmdir(struct inode *dir, struct dentry *dentry)
dfprintk(VFS, "NFS: rmdir(%s/%ld), %s\n", dfprintk(VFS, "NFS: rmdir(%s/%ld), %s\n",
dir->i_sb->s_id, dir->i_ino, dentry->d_name.name); dir->i_sb->s_id, dir->i_ino, dentry->d_name.name);
lock_kernel();
error = NFS_PROTO(dir)->rmdir(dir, &dentry->d_name); error = NFS_PROTO(dir)->rmdir(dir, &dentry->d_name);
/* Ensure the VFS deletes this inode */ /* Ensure the VFS deletes this inode */
if (error == 0 && dentry->d_inode != NULL) if (error == 0 && dentry->d_inode != NULL)
clear_nlink(dentry->d_inode); clear_nlink(dentry->d_inode);
else if (error == -ENOENT) else if (error == -ENOENT)
nfs_dentry_handle_enoent(dentry); nfs_dentry_handle_enoent(dentry);
unlock_kernel();
return error; return error;
} }
...@@ -1420,7 +1399,7 @@ static int nfs_safe_remove(struct dentry *dentry) ...@@ -1420,7 +1399,7 @@ static int nfs_safe_remove(struct dentry *dentry)
error = NFS_PROTO(dir)->remove(dir, &dentry->d_name); error = NFS_PROTO(dir)->remove(dir, &dentry->d_name);
/* The VFS may want to delete this inode */ /* The VFS may want to delete this inode */
if (error == 0) if (error == 0)
drop_nlink(inode); nfs_drop_nlink(inode);
nfs_mark_for_revalidate(inode); nfs_mark_for_revalidate(inode);
} else } else
error = NFS_PROTO(dir)->remove(dir, &dentry->d_name); error = NFS_PROTO(dir)->remove(dir, &dentry->d_name);
...@@ -1443,7 +1422,6 @@ static int nfs_unlink(struct inode *dir, struct dentry *dentry) ...@@ -1443,7 +1422,6 @@ static int nfs_unlink(struct inode *dir, struct dentry *dentry)
dfprintk(VFS, "NFS: unlink(%s/%ld, %s)\n", dir->i_sb->s_id, dfprintk(VFS, "NFS: unlink(%s/%ld, %s)\n", dir->i_sb->s_id,
dir->i_ino, dentry->d_name.name); dir->i_ino, dentry->d_name.name);
lock_kernel();
spin_lock(&dcache_lock); spin_lock(&dcache_lock);
spin_lock(&dentry->d_lock); spin_lock(&dentry->d_lock);
if (atomic_read(&dentry->d_count) > 1) { if (atomic_read(&dentry->d_count) > 1) {
...@@ -1452,7 +1430,6 @@ static int nfs_unlink(struct inode *dir, struct dentry *dentry) ...@@ -1452,7 +1430,6 @@ static int nfs_unlink(struct inode *dir, struct dentry *dentry)
/* Start asynchronous writeout of the inode */ /* Start asynchronous writeout of the inode */
write_inode_now(dentry->d_inode, 0); write_inode_now(dentry->d_inode, 0);
error = nfs_sillyrename(dir, dentry); error = nfs_sillyrename(dir, dentry);
unlock_kernel();
return error; return error;
} }
if (!d_unhashed(dentry)) { if (!d_unhashed(dentry)) {
...@@ -1466,7 +1443,6 @@ static int nfs_unlink(struct inode *dir, struct dentry *dentry) ...@@ -1466,7 +1443,6 @@ static int nfs_unlink(struct inode *dir, struct dentry *dentry)
nfs_set_verifier(dentry, nfs_save_change_attribute(dir)); nfs_set_verifier(dentry, nfs_save_change_attribute(dir));
} else if (need_rehash) } else if (need_rehash)
d_rehash(dentry); d_rehash(dentry);
unlock_kernel();
return error; return error;
} }
...@@ -1503,13 +1479,9 @@ static int nfs_symlink(struct inode *dir, struct dentry *dentry, const char *sym ...@@ -1503,13 +1479,9 @@ static int nfs_symlink(struct inode *dir, struct dentry *dentry, const char *sym
attr.ia_mode = S_IFLNK | S_IRWXUGO; attr.ia_mode = S_IFLNK | S_IRWXUGO;
attr.ia_valid = ATTR_MODE; attr.ia_valid = ATTR_MODE;
lock_kernel();
page = alloc_page(GFP_HIGHUSER); page = alloc_page(GFP_HIGHUSER);
if (!page) { if (!page)
unlock_kernel();
return -ENOMEM; return -ENOMEM;
}
kaddr = kmap_atomic(page, KM_USER0); kaddr = kmap_atomic(page, KM_USER0);
memcpy(kaddr, symname, pathlen); memcpy(kaddr, symname, pathlen);
...@@ -1524,7 +1496,6 @@ static int nfs_symlink(struct inode *dir, struct dentry *dentry, const char *sym ...@@ -1524,7 +1496,6 @@ static int nfs_symlink(struct inode *dir, struct dentry *dentry, const char *sym
dentry->d_name.name, symname, error); dentry->d_name.name, symname, error);
d_drop(dentry); d_drop(dentry);
__free_page(page); __free_page(page);
unlock_kernel();
return error; return error;
} }
...@@ -1542,7 +1513,6 @@ static int nfs_symlink(struct inode *dir, struct dentry *dentry, const char *sym ...@@ -1542,7 +1513,6 @@ static int nfs_symlink(struct inode *dir, struct dentry *dentry, const char *sym
} else } else
__free_page(page); __free_page(page);
unlock_kernel();
return 0; return 0;
} }
...@@ -1556,14 +1526,12 @@ nfs_link(struct dentry *old_dentry, struct inode *dir, struct dentry *dentry) ...@@ -1556,14 +1526,12 @@ nfs_link(struct dentry *old_dentry, struct inode *dir, struct dentry *dentry)
old_dentry->d_parent->d_name.name, old_dentry->d_name.name, old_dentry->d_parent->d_name.name, old_dentry->d_name.name,
dentry->d_parent->d_name.name, dentry->d_name.name); dentry->d_parent->d_name.name, dentry->d_name.name);
lock_kernel();
d_drop(dentry); d_drop(dentry);
error = NFS_PROTO(dir)->link(inode, dir, &dentry->d_name); error = NFS_PROTO(dir)->link(inode, dir, &dentry->d_name);
if (error == 0) { if (error == 0) {
atomic_inc(&inode->i_count); atomic_inc(&inode->i_count);
d_add(dentry, inode); d_add(dentry, inode);
} }
unlock_kernel();
return error; return error;
} }
...@@ -1603,7 +1571,6 @@ static int nfs_rename(struct inode *old_dir, struct dentry *old_dentry, ...@@ -1603,7 +1571,6 @@ static int nfs_rename(struct inode *old_dir, struct dentry *old_dentry,
* To prevent any new references to the target during the rename, * To prevent any new references to the target during the rename,
* we unhash the dentry and free the inode in advance. * we unhash the dentry and free the inode in advance.
*/ */
lock_kernel();
if (!d_unhashed(new_dentry)) { if (!d_unhashed(new_dentry)) {
d_drop(new_dentry); d_drop(new_dentry);
rehash = new_dentry; rehash = new_dentry;
...@@ -1647,7 +1614,7 @@ static int nfs_rename(struct inode *old_dir, struct dentry *old_dentry, ...@@ -1647,7 +1614,7 @@ static int nfs_rename(struct inode *old_dir, struct dentry *old_dentry,
/* dentry still busy? */ /* dentry still busy? */
goto out; goto out;
} else } else
drop_nlink(new_inode); nfs_drop_nlink(new_inode);
go_ahead: go_ahead:
/* /*
...@@ -1681,7 +1648,6 @@ static int nfs_rename(struct inode *old_dir, struct dentry *old_dentry, ...@@ -1681,7 +1648,6 @@ static int nfs_rename(struct inode *old_dir, struct dentry *old_dentry,
/* new dentry created? */ /* new dentry created? */
if (dentry) if (dentry)
dput(dentry); dput(dentry);
unlock_kernel();
return error; return error;
} }
...@@ -1974,8 +1940,6 @@ int nfs_permission(struct inode *inode, int mask, struct nameidata *nd) ...@@ -1974,8 +1940,6 @@ int nfs_permission(struct inode *inode, int mask, struct nameidata *nd)
} }
force_lookup: force_lookup:
lock_kernel();
if (!NFS_PROTO(inode)->access) if (!NFS_PROTO(inode)->access)
goto out_notsup; goto out_notsup;
...@@ -1985,7 +1949,6 @@ int nfs_permission(struct inode *inode, int mask, struct nameidata *nd) ...@@ -1985,7 +1949,6 @@ int nfs_permission(struct inode *inode, int mask, struct nameidata *nd)
put_rpccred(cred); put_rpccred(cred);
} else } else
res = PTR_ERR(cred); res = PTR_ERR(cred);
unlock_kernel();
out: out:
dfprintk(VFS, "NFS: permission(%s/%ld), mask=0x%x, res=%d\n", dfprintk(VFS, "NFS: permission(%s/%ld), mask=0x%x, res=%d\n",
inode->i_sb->s_id, inode->i_ino, mask, res); inode->i_sb->s_id, inode->i_ino, mask, res);
...@@ -1994,7 +1957,6 @@ int nfs_permission(struct inode *inode, int mask, struct nameidata *nd) ...@@ -1994,7 +1957,6 @@ int nfs_permission(struct inode *inode, int mask, struct nameidata *nd)
res = nfs_revalidate_inode(NFS_SERVER(inode), inode); res = nfs_revalidate_inode(NFS_SERVER(inode), inode);
if (res == 0) if (res == 0)
res = generic_permission(inode, mask, NULL); res = generic_permission(inode, mask, NULL);
unlock_kernel();
goto out; goto out;
} }
......
...@@ -128,9 +128,7 @@ nfs_file_open(struct inode *inode, struct file *filp) ...@@ -128,9 +128,7 @@ nfs_file_open(struct inode *inode, struct file *filp)
return res; return res;
nfs_inc_stats(inode, NFSIOS_VFSOPEN); nfs_inc_stats(inode, NFSIOS_VFSOPEN);
lock_kernel();
res = nfs_open(inode, filp); res = nfs_open(inode, filp);
unlock_kernel();
return res; return res;
} }
...@@ -398,9 +396,7 @@ static int nfs_write_end(struct file *file, struct address_space *mapping, ...@@ -398,9 +396,7 @@ static int nfs_write_end(struct file *file, struct address_space *mapping,
zero_user_segment(page, pglen, PAGE_CACHE_SIZE); zero_user_segment(page, pglen, PAGE_CACHE_SIZE);
} }
lock_kernel();
status = nfs_updatepage(file, page, offset, copied); status = nfs_updatepage(file, page, offset, copied);
unlock_kernel();
unlock_page(page); unlock_page(page);
page_cache_release(page); page_cache_release(page);
......
...@@ -370,7 +370,6 @@ nfs_setattr(struct dentry *dentry, struct iattr *attr) ...@@ -370,7 +370,6 @@ nfs_setattr(struct dentry *dentry, struct iattr *attr)
if ((attr->ia_valid & ~ATTR_FILE) == 0) if ((attr->ia_valid & ~ATTR_FILE) == 0)
return 0; return 0;
lock_kernel();
/* Write all dirty data */ /* Write all dirty data */
if (S_ISREG(inode->i_mode)) { if (S_ISREG(inode->i_mode)) {
filemap_write_and_wait(inode->i_mapping); filemap_write_and_wait(inode->i_mapping);
...@@ -384,10 +383,65 @@ nfs_setattr(struct dentry *dentry, struct iattr *attr) ...@@ -384,10 +383,65 @@ nfs_setattr(struct dentry *dentry, struct iattr *attr)
error = NFS_PROTO(inode)->setattr(dentry, &fattr, attr); error = NFS_PROTO(inode)->setattr(dentry, &fattr, attr);
if (error == 0) if (error == 0)
nfs_refresh_inode(inode, &fattr); nfs_refresh_inode(inode, &fattr);
unlock_kernel();
return error; return error;
} }
/**
* nfs_vmtruncate - unmap mappings "freed" by truncate() syscall
* @inode: inode of the file used
* @offset: file offset to start truncating
*
* This is a copy of the common vmtruncate, but with the locking
* corrected to take into account the fact that NFS requires
* inode->i_size to be updated under the inode->i_lock.
*/
static int nfs_vmtruncate(struct inode * inode, loff_t offset)
{
if (i_size_read(inode) < offset) {
unsigned long limit;
limit = current->signal->rlim[RLIMIT_FSIZE].rlim_cur;
if (limit != RLIM_INFINITY && offset > limit)
goto out_sig;
if (offset > inode->i_sb->s_maxbytes)
goto out_big;
spin_lock(&inode->i_lock);
i_size_write(inode, offset);
spin_unlock(&inode->i_lock);
} else {
struct address_space *mapping = inode->i_mapping;
/*
* truncation of in-use swapfiles is disallowed - it would
* cause subsequent swapout to scribble on the now-freed
* blocks.
*/
if (IS_SWAPFILE(inode))
return -ETXTBSY;
spin_lock(&inode->i_lock);
i_size_write(inode, offset);
spin_unlock(&inode->i_lock);
/*
* unmap_mapping_range is called twice, first simply for
* efficiency so that truncate_inode_pages does fewer
* single-page unmaps. However after this first call, and
* before truncate_inode_pages finishes, it is possible for
* private pages to be COWed, which remain after
* truncate_inode_pages finishes, hence the second
* unmap_mapping_range call must be made for correctness.
*/
unmap_mapping_range(mapping, offset + PAGE_SIZE - 1, 0, 1);
truncate_inode_pages(mapping, offset);
unmap_mapping_range(mapping, offset + PAGE_SIZE - 1, 0, 1);
}
return 0;
out_sig:
send_sig(SIGXFSZ, current, 0);
out_big:
return -EFBIG;
}
/** /**
* nfs_setattr_update_inode - Update inode metadata after a setattr call. * nfs_setattr_update_inode - Update inode metadata after a setattr call.
* @inode: pointer to struct inode * @inode: pointer to struct inode
...@@ -414,8 +468,7 @@ void nfs_setattr_update_inode(struct inode *inode, struct iattr *attr) ...@@ -414,8 +468,7 @@ void nfs_setattr_update_inode(struct inode *inode, struct iattr *attr)
} }
if ((attr->ia_valid & ATTR_SIZE) != 0) { if ((attr->ia_valid & ATTR_SIZE) != 0) {
nfs_inc_stats(inode, NFSIOS_SETATTRTRUNC); nfs_inc_stats(inode, NFSIOS_SETATTRTRUNC);
inode->i_size = attr->ia_size; nfs_vmtruncate(inode, attr->ia_size);
vmtruncate(inode, attr->ia_size);
} }
} }
...@@ -645,7 +698,6 @@ __nfs_revalidate_inode(struct nfs_server *server, struct inode *inode) ...@@ -645,7 +698,6 @@ __nfs_revalidate_inode(struct nfs_server *server, struct inode *inode)
inode->i_sb->s_id, (long long)NFS_FILEID(inode)); inode->i_sb->s_id, (long long)NFS_FILEID(inode));
nfs_inc_stats(inode, NFSIOS_INODEREVALIDATE); nfs_inc_stats(inode, NFSIOS_INODEREVALIDATE);
lock_kernel();
if (is_bad_inode(inode)) if (is_bad_inode(inode))
goto out_nowait; goto out_nowait;
if (NFS_STALE(inode)) if (NFS_STALE(inode))
...@@ -694,7 +746,6 @@ __nfs_revalidate_inode(struct nfs_server *server, struct inode *inode) ...@@ -694,7 +746,6 @@ __nfs_revalidate_inode(struct nfs_server *server, struct inode *inode)
nfs_wake_up_inode(inode); nfs_wake_up_inode(inode);
out_nowait: out_nowait:
unlock_kernel();
return status; return status;
} }
...@@ -829,9 +880,9 @@ static void nfs_wcc_update_inode(struct inode *inode, struct nfs_fattr *fattr) ...@@ -829,9 +880,9 @@ static void nfs_wcc_update_inode(struct inode *inode, struct nfs_fattr *fattr)
if (S_ISDIR(inode->i_mode)) if (S_ISDIR(inode->i_mode))
nfsi->cache_validity |= NFS_INO_INVALID_DATA; nfsi->cache_validity |= NFS_INO_INVALID_DATA;
} }
if (inode->i_size == nfs_size_to_loff_t(fattr->pre_size) && if (i_size_read(inode) == nfs_size_to_loff_t(fattr->pre_size) &&
nfsi->npages == 0) nfsi->npages == 0)
inode->i_size = nfs_size_to_loff_t(fattr->size); i_size_write(inode, nfs_size_to_loff_t(fattr->size));
} }
} }
...@@ -972,7 +1023,7 @@ int nfs_post_op_update_inode_force_wcc(struct inode *inode, struct nfs_fattr *fa ...@@ -972,7 +1023,7 @@ int nfs_post_op_update_inode_force_wcc(struct inode *inode, struct nfs_fattr *fa
(fattr->valid & NFS_ATTR_WCC) == 0) { (fattr->valid & NFS_ATTR_WCC) == 0) {
memcpy(&fattr->pre_ctime, &inode->i_ctime, sizeof(fattr->pre_ctime)); memcpy(&fattr->pre_ctime, &inode->i_ctime, sizeof(fattr->pre_ctime));
memcpy(&fattr->pre_mtime, &inode->i_mtime, sizeof(fattr->pre_mtime)); memcpy(&fattr->pre_mtime, &inode->i_mtime, sizeof(fattr->pre_mtime));
fattr->pre_size = inode->i_size; fattr->pre_size = i_size_read(inode);
fattr->valid |= NFS_ATTR_WCC; fattr->valid |= NFS_ATTR_WCC;
} }
return nfs_post_op_update_inode(inode, fattr); return nfs_post_op_update_inode(inode, fattr);
...@@ -1057,7 +1108,7 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr) ...@@ -1057,7 +1108,7 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr)
/* Do we perhaps have any outstanding writes, or has /* Do we perhaps have any outstanding writes, or has
* the file grown beyond our last write? */ * the file grown beyond our last write? */
if (nfsi->npages == 0 || new_isize > cur_isize) { if (nfsi->npages == 0 || new_isize > cur_isize) {
inode->i_size = new_isize; i_size_write(inode, new_isize);
invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA; invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA;
} }
dprintk("NFS: isize change on server for file %s/%ld\n", dprintk("NFS: isize change on server for file %s/%ld\n",
......
...@@ -451,9 +451,7 @@ static struct nfs4_state *nfs4_try_open_cached(struct nfs4_opendata *opendata) ...@@ -451,9 +451,7 @@ static struct nfs4_state *nfs4_try_open_cached(struct nfs4_opendata *opendata)
/* Save the delegation */ /* Save the delegation */
memcpy(stateid.data, delegation->stateid.data, sizeof(stateid.data)); memcpy(stateid.data, delegation->stateid.data, sizeof(stateid.data));
rcu_read_unlock(); rcu_read_unlock();
lock_kernel();
ret = nfs_may_open(state->inode, state->owner->so_cred, open_mode); ret = nfs_may_open(state->inode, state->owner->so_cred, open_mode);
unlock_kernel();
if (ret != 0) if (ret != 0)
goto out; goto out;
ret = -EAGAIN; ret = -EAGAIN;
......
...@@ -940,7 +940,6 @@ static int reclaimer(void *ptr) ...@@ -940,7 +940,6 @@ static int reclaimer(void *ptr)
allow_signal(SIGKILL); allow_signal(SIGKILL);
/* Ensure exclusive access to NFSv4 state */ /* Ensure exclusive access to NFSv4 state */
lock_kernel();
down_write(&clp->cl_sem); down_write(&clp->cl_sem);
/* Are there any NFS mounts out there? */ /* Are there any NFS mounts out there? */
if (list_empty(&clp->cl_superblocks)) if (list_empty(&clp->cl_superblocks))
...@@ -1000,7 +999,6 @@ static int reclaimer(void *ptr) ...@@ -1000,7 +999,6 @@ static int reclaimer(void *ptr)
nfs_delegation_reap_unclaimed(clp); nfs_delegation_reap_unclaimed(clp);
out: out:
up_write(&clp->cl_sem); up_write(&clp->cl_sem);
unlock_kernel();
if (status == -NFS4ERR_CB_PATH_DOWN) if (status == -NFS4ERR_CB_PATH_DOWN)
nfs_handle_cb_pathdown(clp); nfs_handle_cb_pathdown(clp);
nfs4_clear_recover_bit(clp); nfs4_clear_recover_bit(clp);
......
...@@ -374,8 +374,6 @@ static int nfs_statfs(struct dentry *dentry, struct kstatfs *buf) ...@@ -374,8 +374,6 @@ static int nfs_statfs(struct dentry *dentry, struct kstatfs *buf)
}; };
int error; int error;
lock_kernel();
error = server->nfs_client->rpc_ops->statfs(server, fh, &res); error = server->nfs_client->rpc_ops->statfs(server, fh, &res);
if (error < 0) if (error < 0)
goto out_err; goto out_err;
...@@ -407,12 +405,10 @@ static int nfs_statfs(struct dentry *dentry, struct kstatfs *buf) ...@@ -407,12 +405,10 @@ static int nfs_statfs(struct dentry *dentry, struct kstatfs *buf)
buf->f_namelen = server->namelen; buf->f_namelen = server->namelen;
unlock_kernel();
return 0; return 0;
out_err: out_err:
dprintk("%s: statfs error = %d\n", __func__, -error); dprintk("%s: statfs error = %d\n", __func__, -error);
unlock_kernel();
return error; return error;
} }
......
...@@ -133,16 +133,21 @@ static struct nfs_page *nfs_page_find_request(struct page *page) ...@@ -133,16 +133,21 @@ static struct nfs_page *nfs_page_find_request(struct page *page)
static void nfs_grow_file(struct page *page, unsigned int offset, unsigned int count) static void nfs_grow_file(struct page *page, unsigned int offset, unsigned int count)
{ {
struct inode *inode = page->mapping->host; struct inode *inode = page->mapping->host;
loff_t end, i_size = i_size_read(inode); loff_t end, i_size;
pgoff_t end_index = (i_size - 1) >> PAGE_CACHE_SHIFT; pgoff_t end_index;
spin_lock(&inode->i_lock);
i_size = i_size_read(inode);
end_index = (i_size - 1) >> PAGE_CACHE_SHIFT;
if (i_size > 0 && page->index < end_index) if (i_size > 0 && page->index < end_index)
return; goto out;
end = ((loff_t)page->index << PAGE_CACHE_SHIFT) + ((loff_t)offset+count); end = ((loff_t)page->index << PAGE_CACHE_SHIFT) + ((loff_t)offset+count);
if (i_size >= end) if (i_size >= end)
return; goto out;
nfs_inc_stats(inode, NFSIOS_EXTENDWRITE);
i_size_write(inode, end); i_size_write(inode, end);
nfs_inc_stats(inode, NFSIOS_EXTENDWRITE);
out:
spin_unlock(&inode->i_lock);
} }
/* A writeback failed: mark the page as bad, and invalidate the page cache */ /* A writeback failed: mark the page as bad, and invalidate the page cache */
......
...@@ -576,9 +576,7 @@ EXPORT_SYMBOL_GPL(rpc_delay); ...@@ -576,9 +576,7 @@ EXPORT_SYMBOL_GPL(rpc_delay);
*/ */
static void rpc_prepare_task(struct rpc_task *task) static void rpc_prepare_task(struct rpc_task *task)
{ {
lock_kernel();
task->tk_ops->rpc_call_prepare(task, task->tk_calldata); task->tk_ops->rpc_call_prepare(task, task->tk_calldata);
unlock_kernel();
} }
/* /*
...@@ -588,9 +586,7 @@ void rpc_exit_task(struct rpc_task *task) ...@@ -588,9 +586,7 @@ void rpc_exit_task(struct rpc_task *task)
{ {
task->tk_action = NULL; task->tk_action = NULL;
if (task->tk_ops->rpc_call_done != NULL) { if (task->tk_ops->rpc_call_done != NULL) {
lock_kernel();
task->tk_ops->rpc_call_done(task, task->tk_calldata); task->tk_ops->rpc_call_done(task, task->tk_calldata);
unlock_kernel();
if (task->tk_action != NULL) { if (task->tk_action != NULL) {
WARN_ON(RPC_ASSASSINATED(task)); WARN_ON(RPC_ASSASSINATED(task));
/* Always release the RPC slot and buffer memory */ /* Always release the RPC slot and buffer memory */
...@@ -602,11 +598,8 @@ EXPORT_SYMBOL_GPL(rpc_exit_task); ...@@ -602,11 +598,8 @@ EXPORT_SYMBOL_GPL(rpc_exit_task);
void rpc_release_calldata(const struct rpc_call_ops *ops, void *calldata) void rpc_release_calldata(const struct rpc_call_ops *ops, void *calldata)
{ {
if (ops->rpc_release != NULL) { if (ops->rpc_release != NULL)
lock_kernel();
ops->rpc_release(calldata); ops->rpc_release(calldata);
unlock_kernel();
}
} }
/* /*
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册