aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/unlink.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/nfs/unlink.c')
-rw-r--r--fs/nfs/unlink.c38
1 files changed, 28 insertions, 10 deletions
diff --git a/fs/nfs/unlink.c b/fs/nfs/unlink.c
index 60395ad3a2e4..bb939edd4c99 100644
--- a/fs/nfs/unlink.c
+++ b/fs/nfs/unlink.c
@@ -20,6 +20,8 @@
20#include "iostat.h" 20#include "iostat.h"
21#include "delegation.h" 21#include "delegation.h"
22 22
23#include "nfstrace.h"
24
23/** 25/**
24 * nfs_free_unlinkdata - release data from a sillydelete operation. 26 * nfs_free_unlinkdata - release data from a sillydelete operation.
25 * @data: pointer to unlink structure. 27 * @data: pointer to unlink structure.
@@ -77,6 +79,7 @@ static void nfs_async_unlink_done(struct rpc_task *task, void *calldata)
77 struct nfs_unlinkdata *data = calldata; 79 struct nfs_unlinkdata *data = calldata;
78 struct inode *dir = data->dir; 80 struct inode *dir = data->dir;
79 81
82 trace_nfs_sillyrename_unlink(data, task->tk_status);
80 if (!NFS_PROTO(dir)->unlink_done(task, dir)) 83 if (!NFS_PROTO(dir)->unlink_done(task, dir))
81 rpc_restart_call_prepare(task); 84 rpc_restart_call_prepare(task);
82} 85}
@@ -204,6 +207,13 @@ out_free:
204 return ret; 207 return ret;
205} 208}
206 209
210void nfs_wait_on_sillyrename(struct dentry *dentry)
211{
212 struct nfs_inode *nfsi = NFS_I(dentry->d_inode);
213
214 wait_event(nfsi->waitqueue, atomic_read(&nfsi->silly_count) <= 1);
215}
216
207void nfs_block_sillyrename(struct dentry *dentry) 217void nfs_block_sillyrename(struct dentry *dentry)
208{ 218{
209 struct nfs_inode *nfsi = NFS_I(dentry->d_inode); 219 struct nfs_inode *nfsi = NFS_I(dentry->d_inode);
@@ -336,6 +346,8 @@ static void nfs_async_rename_done(struct rpc_task *task, void *calldata)
336 struct inode *new_dir = data->new_dir; 346 struct inode *new_dir = data->new_dir;
337 struct dentry *old_dentry = data->old_dentry; 347 struct dentry *old_dentry = data->old_dentry;
338 348
349 trace_nfs_sillyrename_rename(old_dir, old_dentry,
350 new_dir, data->new_dentry, task->tk_status);
339 if (!NFS_PROTO(old_dir)->rename_done(task, old_dir, new_dir)) { 351 if (!NFS_PROTO(old_dir)->rename_done(task, old_dir, new_dir)) {
340 rpc_restart_call_prepare(task); 352 rpc_restart_call_prepare(task);
341 return; 353 return;
@@ -444,6 +456,14 @@ nfs_async_rename(struct inode *old_dir, struct inode *new_dir,
444 return rpc_run_task(&task_setup_data); 456 return rpc_run_task(&task_setup_data);
445} 457}
446 458
459#define SILLYNAME_PREFIX ".nfs"
460#define SILLYNAME_PREFIX_LEN ((unsigned)sizeof(SILLYNAME_PREFIX) - 1)
461#define SILLYNAME_FILEID_LEN ((unsigned)sizeof(u64) << 1)
462#define SILLYNAME_COUNTER_LEN ((unsigned)sizeof(unsigned int) << 1)
463#define SILLYNAME_LEN (SILLYNAME_PREFIX_LEN + \
464 SILLYNAME_FILEID_LEN + \
465 SILLYNAME_COUNTER_LEN)
466
447/** 467/**
448 * nfs_sillyrename - Perform a silly-rename of a dentry 468 * nfs_sillyrename - Perform a silly-rename of a dentry
449 * @dir: inode of directory that contains dentry 469 * @dir: inode of directory that contains dentry
@@ -469,10 +489,8 @@ int
469nfs_sillyrename(struct inode *dir, struct dentry *dentry) 489nfs_sillyrename(struct inode *dir, struct dentry *dentry)
470{ 490{
471 static unsigned int sillycounter; 491 static unsigned int sillycounter;
472 const int fileidsize = sizeof(NFS_FILEID(dentry->d_inode))*2; 492 unsigned char silly[SILLYNAME_LEN + 1];
473 const int countersize = sizeof(sillycounter)*2; 493 unsigned long long fileid;
474 const int slen = sizeof(".nfs")+fileidsize+countersize-1;
475 char silly[slen+1];
476 struct dentry *sdentry; 494 struct dentry *sdentry;
477 struct rpc_task *task; 495 struct rpc_task *task;
478 int error = -EIO; 496 int error = -EIO;
@@ -489,20 +507,20 @@ nfs_sillyrename(struct inode *dir, struct dentry *dentry)
489 if (dentry->d_flags & DCACHE_NFSFS_RENAMED) 507 if (dentry->d_flags & DCACHE_NFSFS_RENAMED)
490 goto out; 508 goto out;
491 509
492 sprintf(silly, ".nfs%*.*Lx", 510 fileid = NFS_FILEID(dentry->d_inode);
493 fileidsize, fileidsize,
494 (unsigned long long)NFS_FILEID(dentry->d_inode));
495 511
496 /* Return delegation in anticipation of the rename */ 512 /* Return delegation in anticipation of the rename */
497 NFS_PROTO(dentry->d_inode)->return_delegation(dentry->d_inode); 513 NFS_PROTO(dentry->d_inode)->return_delegation(dentry->d_inode);
498 514
499 sdentry = NULL; 515 sdentry = NULL;
500 do { 516 do {
501 char *suffix = silly + slen - countersize; 517 int slen;
502
503 dput(sdentry); 518 dput(sdentry);
504 sillycounter++; 519 sillycounter++;
505 sprintf(suffix, "%*.*x", countersize, countersize, sillycounter); 520 slen = scnprintf(silly, sizeof(silly),
521 SILLYNAME_PREFIX "%0*llx%0*x",
522 SILLYNAME_FILEID_LEN, fileid,
523 SILLYNAME_COUNTER_LEN, sillycounter);
506 524
507 dfprintk(VFS, "NFS: trying to rename %s to %s\n", 525 dfprintk(VFS, "NFS: trying to rename %s to %s\n",
508 dentry->d_name.name, silly); 526 dentry->d_name.name, silly);