Commit 2be7828c authored by Al Viro's avatar Al Viro

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: default avatarAl Viro <viro@zeniv.linux.org.uk>
parent a2bbe664
...@@ -87,6 +87,7 @@ struct autofs_wait_queue { ...@@ -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) ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment