Abstract out Linux sillyrename function

In order to keep the dcache happy, the Linux client has its own
sillyrename function. Abstract this out from afs_linux_unlink into a
function of its own (afs_linux_sillyrename) so we can make use of it
from other vnodeops.

Change-Id: I298251c400dfc22efb3bacaa72612b28a5409112
Reviewed-on: http://gerrit.openafs.org/1034
Reviewed-by: Derrick Brashear <shadow@dementia.org>
Tested-by: Derrick Brashear <shadow@dementia.org>
This commit is contained in:
Simon Wilkinson 2009-12-27 11:06:01 +00:00 committed by Derrick Brashear
parent 35d5b6c4e1
commit ec352e0bfd

View File

@ -1115,22 +1115,21 @@ afs_linux_link(struct dentry *olddp, struct inode *dip, struct dentry *newdp)
return afs_convert_code(code);
}
/* We have to have a Linux specific sillyrename function, because we
* also have to keep the dcache up to date when we're doing a silly
* rename - so we don't want the generic vnodeops doing this behind our
* back.
*/
static int
afs_linux_unlink(struct inode *dip, struct dentry *dp)
afs_linux_sillyrename(struct inode *dir, struct dentry *dentry,
cred_t *credp)
{
int code = EBUSY;
cred_t *credp = crref();
const char *name = dp->d_name.name;
struct vcache *tvc = VTOAFS(dp->d_inode);
struct vcache *tvc = VTOAFS(dentry->d_inode);
struct dentry *__dp = NULL;
char *__name = NULL;
int code;
afs_maybe_lock_kernel();
if (VREFCOUNT(tvc) > 1 && tvc->opens > 0
&& !(tvc->f.states & CUnlinked)) {
struct dentry *__dp;
char *__name;
__dp = NULL;
__name = NULL;
do {
dput(__dp);
@ -1140,14 +1139,18 @@ afs_linux_unlink(struct inode *dip, struct dentry *dp)
__name = afs_newname();
AFS_GUNLOCK();
__dp = lookup_one_len(__name, dp->d_parent, strlen(__name));
__dp = lookup_one_len(__name, dentry->d_parent, strlen(__name));
if (IS_ERR(__dp))
goto out;
if (IS_ERR(__dp)) {
osi_FreeSmallSpace(__name);
return EBUSY;
}
} while (__dp->d_inode != NULL);
AFS_GLOCK();
code = afs_rename(VTOAFS(dip), (char *)dp->d_name.name, VTOAFS(dip), (char *)__dp->d_name.name, credp);
code = afs_rename(VTOAFS(dir), (char *)dentry->d_name.name,
VTOAFS(dir), (char *)__dp->d_name.name,
credp);
if (!code) {
tvc->mvid = (void *) __name;
crhold(credp);
@ -1156,27 +1159,44 @@ afs_linux_unlink(struct inode *dip, struct dentry *dp)
}
tvc->uncred = credp;
tvc->f.states |= CUnlinked;
afs_linux_set_nfsfs_renamed(dp);
afs_linux_set_nfsfs_renamed(dentry);
} else {
osi_FreeSmallSpace(__name);
}
AFS_GUNLOCK();
if (!code) {
__dp->d_time = hgetlo(VTOAFS(dip)->f.m.DataVersion);
d_move(dp, __dp);
__dp->d_time = hgetlo(VTOAFS(dir)->f.m.DataVersion);
d_move(dentry, __dp);
}
dput(__dp);
goto out;
return code;
}
static int
afs_linux_unlink(struct inode *dip, struct dentry *dp)
{
int code = EBUSY;
cred_t *credp = crref();
const char *name = dp->d_name.name;
struct vcache *tvc = VTOAFS(dp->d_inode);
afs_maybe_lock_kernel();
if (VREFCOUNT(tvc) > 1 && tvc->opens > 0
&& !(tvc->f.states & CUnlinked)) {
code = afs_linux_sillyrename(dip, dp, credp);
} else {
AFS_GLOCK();
code = afs_remove(VTOAFS(dip), (char *)name, credp);
AFS_GUNLOCK();
if (!code)
d_drop(dp);
out:
}
afs_maybe_unlock_kernel();
crfree(credp);
return afs_convert_code(code);