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;
|
autofs_wqt_t wait_queue_token;
|
||||||
/* We use the following to see what we are waiting for */
|
/* We use the following to see what we are waiting for */
|
||||||
struct qstr name;
|
struct qstr name;
|
||||||
|
u32 offset;
|
||||||
u32 dev;
|
u32 dev;
|
||||||
u64 ino;
|
u64 ino;
|
||||||
kuid_t uid;
|
kuid_t uid;
|
||||||
|
@ -30,7 +30,7 @@ void autofs_catatonic_mode(struct autofs_sb_info *sbi)
|
|||||||
while (wq) {
|
while (wq) {
|
||||||
nwq = wq->next;
|
nwq = wq->next;
|
||||||
wq->status = -ENOENT; /* Magic is gone - report failure */
|
wq->status = -ENOENT; /* Magic is gone - report failure */
|
||||||
kfree(wq->name.name);
|
kfree(wq->name.name - wq->offset);
|
||||||
wq->name.name = NULL;
|
wq->name.name = NULL;
|
||||||
wq->wait_ctr--;
|
wq->wait_ctr--;
|
||||||
wake_up_interruptible(&wq->queue);
|
wake_up_interruptible(&wq->queue);
|
||||||
@ -175,51 +175,6 @@ static void autofs_notify_daemon(struct autofs_sb_info *sbi,
|
|||||||
fput(pipe);
|
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 *
|
static struct autofs_wait_queue *
|
||||||
autofs_find_wait(struct autofs_sb_info *sbi, const struct qstr *qstr)
|
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;
|
struct qstr qstr;
|
||||||
char *name;
|
char *name;
|
||||||
int status, ret, type;
|
int status, ret, type;
|
||||||
|
unsigned int offset = 0;
|
||||||
pid_t pid;
|
pid_t pid;
|
||||||
pid_t tgid;
|
pid_t tgid;
|
||||||
|
|
||||||
@ -389,20 +345,23 @@ int autofs_wait(struct autofs_sb_info *sbi,
|
|||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
/* If this is a direct mount request create a dummy name */
|
/* 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);
|
qstr.len = sprintf(name, "%p", dentry);
|
||||||
else {
|
} else {
|
||||||
qstr.len = autofs_getpath(sbi, dentry, name);
|
char *p = dentry_path_raw(dentry, name, NAME_MAX);
|
||||||
if (!qstr.len) {
|
if (IS_ERR(p)) {
|
||||||
kfree(name);
|
kfree(name);
|
||||||
return -ENOENT;
|
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);
|
qstr.hash = full_name_hash(dentry, name, qstr.len);
|
||||||
|
|
||||||
if (mutex_lock_interruptible(&sbi->wq_mutex)) {
|
if (mutex_lock_interruptible(&sbi->wq_mutex)) {
|
||||||
kfree(qstr.name);
|
kfree(name);
|
||||||
return -EINTR;
|
return -EINTR;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -410,7 +369,7 @@ int autofs_wait(struct autofs_sb_info *sbi,
|
|||||||
if (ret <= 0) {
|
if (ret <= 0) {
|
||||||
if (ret != -EINTR)
|
if (ret != -EINTR)
|
||||||
mutex_unlock(&sbi->wq_mutex);
|
mutex_unlock(&sbi->wq_mutex);
|
||||||
kfree(qstr.name);
|
kfree(name);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -418,7 +377,7 @@ int autofs_wait(struct autofs_sb_info *sbi,
|
|||||||
/* Create a new wait queue */
|
/* Create a new wait queue */
|
||||||
wq = kmalloc(sizeof(struct autofs_wait_queue), GFP_KERNEL);
|
wq = kmalloc(sizeof(struct autofs_wait_queue), GFP_KERNEL);
|
||||||
if (!wq) {
|
if (!wq) {
|
||||||
kfree(qstr.name);
|
kfree(name);
|
||||||
mutex_unlock(&sbi->wq_mutex);
|
mutex_unlock(&sbi->wq_mutex);
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
@ -430,6 +389,7 @@ int autofs_wait(struct autofs_sb_info *sbi,
|
|||||||
sbi->queues = wq;
|
sbi->queues = wq;
|
||||||
init_waitqueue_head(&wq->queue);
|
init_waitqueue_head(&wq->queue);
|
||||||
memcpy(&wq->name, &qstr, sizeof(struct qstr));
|
memcpy(&wq->name, &qstr, sizeof(struct qstr));
|
||||||
|
wq->offset = offset;
|
||||||
wq->dev = autofs_get_dev(sbi);
|
wq->dev = autofs_get_dev(sbi);
|
||||||
wq->ino = autofs_get_ino(sbi);
|
wq->ino = autofs_get_ino(sbi);
|
||||||
wq->uid = current_uid();
|
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,
|
(unsigned long) wq->wait_queue_token, wq->name.len,
|
||||||
wq->name.name, notify);
|
wq->name.name, notify);
|
||||||
mutex_unlock(&sbi->wq_mutex);
|
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 */
|
*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->name.name = NULL; /* Do not wait on this queue */
|
||||||
wq->status = status;
|
wq->status = status;
|
||||||
wake_up(&wq->queue);
|
wake_up(&wq->queue);
|
||||||
|
Loading…
Reference in New Issue
Block a user