X-Git-Url: http://pilppa.org/gitweb/gitweb.cgi?a=blobdiff_plain;f=fs%2Fnfs%2Funlink.c;h=757415363422da022f2c7197779233d93b86e653;hb=8f859016ea49cd8d7c743533bd1ab3db9a813ffa;hp=233ad38161f924095e12e26ed4955337b16cdec6;hpb=43cd73658d8077ee6899b0b5029aad0cba1e9f92;p=linux-2.6-omap-h63xx.git diff --git a/fs/nfs/unlink.c b/fs/nfs/unlink.c index 233ad38161f..75741536342 100644 --- a/fs/nfs/unlink.c +++ b/fs/nfs/unlink.c @@ -14,6 +14,8 @@ #include #include +#include "internal.h" + struct nfs_unlinkdata { struct hlist_node list; struct nfs_removeargs args; @@ -68,24 +70,6 @@ static void nfs_dec_sillycount(struct inode *dir) wake_up(&nfsi->waitqueue); } -/** - * nfs_async_unlink_init - Initialize the RPC info - * task: rpc_task of the sillydelete - */ -static void nfs_async_unlink_init(struct rpc_task *task, void *calldata) -{ - struct nfs_unlinkdata *data = calldata; - struct inode *dir = data->dir; - struct rpc_message msg = { - .rpc_argp = &data->args, - .rpc_resp = &data->res, - .rpc_cred = data->cred, - }; - - NFS_PROTO(dir)->unlink_setup(&msg, dir); - rpc_call_setup(task, &msg, 0); -} - /** * nfs_async_unlink_done - Sillydelete post-processing * @task: rpc_task of the sillydelete @@ -113,32 +97,45 @@ static void nfs_async_unlink_release(void *calldata) struct nfs_unlinkdata *data = calldata; nfs_dec_sillycount(data->dir); + nfs_sb_deactive(NFS_SERVER(data->dir)); nfs_free_unlinkdata(data); } static const struct rpc_call_ops nfs_unlink_ops = { - .rpc_call_prepare = nfs_async_unlink_init, .rpc_call_done = nfs_async_unlink_done, .rpc_release = nfs_async_unlink_release, }; static int nfs_do_call_unlink(struct dentry *parent, struct inode *dir, struct nfs_unlinkdata *data) { + struct rpc_message msg = { + .rpc_argp = &data->args, + .rpc_resp = &data->res, + .rpc_cred = data->cred, + }; + struct rpc_task_setup task_setup_data = { + .rpc_message = &msg, + .callback_ops = &nfs_unlink_ops, + .callback_data = data, + .flags = RPC_TASK_ASYNC, + }; struct rpc_task *task; struct dentry *alias; alias = d_lookup(parent, &data->args.name); if (alias != NULL) { int ret = 0; + /* * Hey, we raced with lookup... See if we need to transfer * the sillyrename information to the aliased dentry. */ nfs_free_dname(data); spin_lock(&alias->d_lock); - if (!(alias->d_flags & DCACHE_NFSFS_RENAMED)) { + if (alias->d_inode != NULL && + !(alias->d_flags & DCACHE_NFSFS_RENAMED)) { alias->d_fsdata = data; - alias->d_flags ^= DCACHE_NFSFS_RENAMED; + alias->d_flags |= DCACHE_NFSFS_RENAMED; ret = 1; } spin_unlock(&alias->d_lock); @@ -151,10 +148,14 @@ static int nfs_do_call_unlink(struct dentry *parent, struct inode *dir, struct n nfs_dec_sillycount(dir); return 0; } + nfs_sb_active(NFS_SERVER(dir)); data->args.fh = NFS_FH(dir); nfs_fattr_init(&data->res.dir_attr); - task = rpc_run_task(NFS_CLIENT(dir), RPC_TASK_ASYNC, &nfs_unlink_ops, data); + NFS_PROTO(dir)->unlink_setup(&msg, dir); + + task_setup_data.rpc_client = NFS_CLIENT(dir); + task = rpc_run_task(&task_setup_data); if (!IS_ERR(task)) rpc_put_task(task); return 1;