forked from Minki/linux
get rid of autofs_getpath()
allow wq->name.name to point not at the beginning of the object containing the string, with wq->offset telling how far into it we are. Then we can bloody well just use dentry_path_raw() instead of autofs_getpath() - the only real difference is that dentry_path_raw() puts the result into the end of buffer and returns where it starts. Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
This commit is contained in:
parent
a2bbe66493
commit
2be7828c9f
@ -87,6 +87,7 @@ struct autofs_wait_queue {
|
||||
autofs_wqt_t wait_queue_token;
|
||||
/* We use the following to see what we are waiting for */
|
||||
struct qstr name;
|
||||
u32 offset;
|
||||
u32 dev;
|
||||
u64 ino;
|
||||
kuid_t uid;
|
||||
|
@ -30,7 +30,7 @@ void autofs_catatonic_mode(struct autofs_sb_info *sbi)
|
||||
while (wq) {
|
||||
nwq = wq->next;
|
||||
wq->status = -ENOENT; /* Magic is gone - report failure */
|
||||
kfree(wq->name.name);
|
||||
kfree(wq->name.name - wq->offset);
|
||||
wq->name.name = NULL;
|
||||
wq->wait_ctr--;
|
||||
wake_up_interruptible(&wq->queue);
|
||||
@ -175,51 +175,6 @@ static void autofs_notify_daemon(struct autofs_sb_info *sbi,
|
||||
fput(pipe);
|
||||
}
|
||||
|
||||
static int autofs_getpath(struct autofs_sb_info *sbi,
|
||||
struct dentry *dentry, char *name)
|
||||
{
|
||||
struct dentry *root = sbi->sb->s_root;
|
||||
struct dentry *tmp;
|
||||
char *buf;
|
||||
char *p;
|
||||
int len;
|
||||
unsigned seq;
|
||||
|
||||
rename_retry:
|
||||
buf = name;
|
||||
len = 0;
|
||||
|
||||
seq = read_seqbegin(&rename_lock);
|
||||
rcu_read_lock();
|
||||
spin_lock(&sbi->fs_lock);
|
||||
for (tmp = dentry ; tmp != root ; tmp = tmp->d_parent)
|
||||
len += tmp->d_name.len + 1;
|
||||
|
||||
if (!len || --len > NAME_MAX) {
|
||||
spin_unlock(&sbi->fs_lock);
|
||||
rcu_read_unlock();
|
||||
if (read_seqretry(&rename_lock, seq))
|
||||
goto rename_retry;
|
||||
return 0;
|
||||
}
|
||||
|
||||
*(buf + len) = '\0';
|
||||
p = buf + len - dentry->d_name.len;
|
||||
strncpy(p, dentry->d_name.name, dentry->d_name.len);
|
||||
|
||||
for (tmp = dentry->d_parent; tmp != root ; tmp = tmp->d_parent) {
|
||||
*(--p) = '/';
|
||||
p -= tmp->d_name.len;
|
||||
strncpy(p, tmp->d_name.name, tmp->d_name.len);
|
||||
}
|
||||
spin_unlock(&sbi->fs_lock);
|
||||
rcu_read_unlock();
|
||||
if (read_seqretry(&rename_lock, seq))
|
||||
goto rename_retry;
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
static struct autofs_wait_queue *
|
||||
autofs_find_wait(struct autofs_sb_info *sbi, const struct qstr *qstr)
|
||||
{
|
||||
@ -352,6 +307,7 @@ int autofs_wait(struct autofs_sb_info *sbi,
|
||||
struct qstr qstr;
|
||||
char *name;
|
||||
int status, ret, type;
|
||||
unsigned int offset = 0;
|
||||
pid_t pid;
|
||||
pid_t tgid;
|
||||
|
||||
@ -389,20 +345,23 @@ int autofs_wait(struct autofs_sb_info *sbi,
|
||||
return -ENOMEM;
|
||||
|
||||
/* If this is a direct mount request create a dummy name */
|
||||
if (IS_ROOT(dentry) && autofs_type_trigger(sbi->type))
|
||||
if (IS_ROOT(dentry) && autofs_type_trigger(sbi->type)) {
|
||||
qstr.name = name;
|
||||
qstr.len = sprintf(name, "%p", dentry);
|
||||
else {
|
||||
qstr.len = autofs_getpath(sbi, dentry, name);
|
||||
if (!qstr.len) {
|
||||
} else {
|
||||
char *p = dentry_path_raw(dentry, name, NAME_MAX);
|
||||
if (IS_ERR(p)) {
|
||||
kfree(name);
|
||||
return -ENOENT;
|
||||
}
|
||||
qstr.name = ++p; // skip the leading slash
|
||||
qstr.len = strlen(p);
|
||||
offset = p - name;
|
||||
}
|
||||
qstr.name = name;
|
||||
qstr.hash = full_name_hash(dentry, name, qstr.len);
|
||||
|
||||
if (mutex_lock_interruptible(&sbi->wq_mutex)) {
|
||||
kfree(qstr.name);
|
||||
kfree(name);
|
||||
return -EINTR;
|
||||
}
|
||||
|
||||
@ -410,7 +369,7 @@ int autofs_wait(struct autofs_sb_info *sbi,
|
||||
if (ret <= 0) {
|
||||
if (ret != -EINTR)
|
||||
mutex_unlock(&sbi->wq_mutex);
|
||||
kfree(qstr.name);
|
||||
kfree(name);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -418,7 +377,7 @@ int autofs_wait(struct autofs_sb_info *sbi,
|
||||
/* Create a new wait queue */
|
||||
wq = kmalloc(sizeof(struct autofs_wait_queue), GFP_KERNEL);
|
||||
if (!wq) {
|
||||
kfree(qstr.name);
|
||||
kfree(name);
|
||||
mutex_unlock(&sbi->wq_mutex);
|
||||
return -ENOMEM;
|
||||
}
|
||||
@ -430,6 +389,7 @@ int autofs_wait(struct autofs_sb_info *sbi,
|
||||
sbi->queues = wq;
|
||||
init_waitqueue_head(&wq->queue);
|
||||
memcpy(&wq->name, &qstr, sizeof(struct qstr));
|
||||
wq->offset = offset;
|
||||
wq->dev = autofs_get_dev(sbi);
|
||||
wq->ino = autofs_get_ino(sbi);
|
||||
wq->uid = current_uid();
|
||||
@ -469,7 +429,7 @@ int autofs_wait(struct autofs_sb_info *sbi,
|
||||
(unsigned long) wq->wait_queue_token, wq->name.len,
|
||||
wq->name.name, notify);
|
||||
mutex_unlock(&sbi->wq_mutex);
|
||||
kfree(qstr.name);
|
||||
kfree(name);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -540,7 +500,7 @@ int autofs_wait_release(struct autofs_sb_info *sbi,
|
||||
}
|
||||
|
||||
*wql = wq->next; /* Unlink from chain */
|
||||
kfree(wq->name.name);
|
||||
kfree(wq->name.name - wq->offset);
|
||||
wq->name.name = NULL; /* Do not wait on this queue */
|
||||
wq->status = status;
|
||||
wake_up(&wq->queue);
|
||||
|
Loading…
Reference in New Issue
Block a user