mirror of
https://git.openafs.org/openafs.git
synced 2025-01-22 08:50:17 +00:00
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:
parent
35d5b6c4e1
commit
ec352e0bfd
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user