Re: path_lookup() alternative

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 2012-01-24, at 6:03, <dmitry.krivenok@xxxxxxx> wrote:
> Hi Al, thanks for quick reply.
> 
> The module I'm working on is intended to work on wide range of kernels, so
> we have lots of #ifdefs. For example, out internal hash lookup routine looks like:
> 
> static struct dentry * int_lookup_hash(struct nameidata *nd)
> {
> #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,15))
>    return lookup_hash(&nd->last, NDP_TO_DENTRY(nd));
> #elif (LINUX_VERSION_CODE  >= KERNEL_VERSION(2,6,16))
>    return lookup_one_len(nd->last.name, NDP_TO_DENTRY(nd), nd->last.len);
> #else
>    return lookup_hash(nd);
> #endif
> }

On a side note, from my experience the kernel version checks are nearly useless when you start trying to build against distro kernels. These kernels will backport API changes from newer upstream kernels, so you need to have autoconf checks for the specific API and symbol exports that you are concerned with.

> Where NDP_TO_DENTRY is defined as follows:
> 
> #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,25))
> #define NDP_TO_DENTRY(_ndp) (_ndp)->path.dentry
> #else
> #define NDP_TO_DENTRY(_ndp) (_ndp)->dentry
> #endif
> 
> As you can see, lookup_hash() wasn't static is previous kernel versions.
> 
> Yes, lookup_one_len() doesn't take whole nameidata, but it may be called 
> as follows (code from drivers/base/devtmpfs.c):
> 
> kern_path_parent(name, &nd);
> ...
> dentry = lookup_one_len(nd.last.name, nd.path.dentry, nd.last.len);
> 
> That's how we call lookup_one_len() in our module and we need a way to fill 
> nameidata structure and then pass some of its fields to this function.
> path_lookup() was responsible for filling nameidata so it could then be passed
> to other kernel functions, but path_lookup() was removed.
> 
> Our module has functions which implement file/directory operations in kernel-space.
> The function below is a bit simplified version of "int_file_delete" function which
> deletes a file (some comments related to nameidata were added).
> 
> int int_file_delete(const char* file_path)
> {
>    int os_status;
>    struct dentry *dentry;
>    struct nameidata nd;
>    struct inode *inode = NULL;
>    os_status = path_lookup(file_path, LOOKUP_PARENT, &nd); /* HERE WE FILL nameidata */
>    if (os_status != 0) {
>        return os_status;
>    }
>    if (nd.last_type != LAST_NORM) { /* HERE WE EXAMINE nameidata content */
>        os_status = -EISDIR;
>        goto exit;
>    }
>    INODE_LOCK(ND_TO_DENTRY(nd)->d_inode);
>    dentry = int_lookup_hash(&nd); /* HERE WE PASS nd TO int_lookup_hash MENTIONED ABOVE */
>    os_status = PTR_ERR(dentry);
>    if (!IS_ERR(dentry)) {
>        if (nd.last.name[nd.last.len]) { /* HERE WE EXAMINE nameidata content */
>            os_status = (dentry->d_inode == NULL) ? -ENOENT : S_ISDIR(dentry->d_inode->i_mode) ? -EISDIR : -ENOTDIR;
>        } else {
>            inode = dentry->d_inode;
>            if (inode != NULL) {
>                atomic_inc(&inode->i_count);
>            }
>            os_status = vfs_unlink(ND_TO_DENTRY(nd)->d_inode, dentry);
>        }
>        dput(dentry);
>    }
>    INODE_UNLOCK(ND_TO_DENTRY(nd)->d_inode);
>    if (inode != NULL) {
>        iput(inode);
>    }
>  exit:
>    path_release(&nd);
>    if (os_status != 0) {
>        return os_status;
>    }
>    return 0;
> }
> 
> Other functions use path_lookup(), int_lookup_hash() and nameidata in a similar way.
> 
> Thanks,
> Dmitry
> 
> -----Original Message-----
> From: Al Viro [mailto:viro@xxxxxxxxxxxxxxxx] On Behalf Of Al Viro
> Sent: Tuesday, January 24, 2012 1:24 AM
> To: Krivenok, Dmitry
> Cc: linux-fsdevel@xxxxxxxxxxxxxxx
> Subject: Re: path_lookup() alternative
> 
> On Mon, Jan 23, 2012 at 05:19:24AM -0500, dmitry.krivenok@xxxxxxx wrote:
>> Hello,
>> I sent this question to Al Viro first, but didn't get any feedback, so reposting here and hope that someone can help me.
>> 
>> I'm trying to build existing system consisting of several kernel modules and user-space tools on the latest vanilla kernel.
>> Previously, we used path_lookup() function to perform lookup with arbitrary flags (e.g. we passed LOOKUP_PARENT in
>> some cases) and save results in nameidata structure. Then, this structure was passed to other kernel functions (e.g. 
>> lookup_hash and then lookup_one_len) or was used directly in the module code.
> 
> lookup_one_len() does not take nameidata at all.
> lookup_hash() is not only not exported, it's _static_.
> 
> what are you talking about?
> 
>> The problem is that path_lookup() was removed in c9c6cac0c2bdbda42e7b804838648d0bc60ddb13 and kern_path_parent
>> was added instead (and, of course, it didn't allow user to pass arbitrary flags).
>> Then, in e3c3d9c838d48c0341c40ea45ee087e3d8c8ea39, kern_path_parent() was unexported and thus became unavailable for us.
>> 
>> I spent several hours learning path lookup code in the kernel tree, but didn't find a function/method which allows to get properly filled 
>> nameidata having only path and flags.
>> Is there an alternative to removed path_lookup() function or any other way of {path, flags}->{nameidata} translation?
> 
> Depends on what do you want to do with it.  IMO nameidata should be internal to
> fs/namei.c; we still have it exposed more than I'd like it to be and if nothing
> else, that exposure is going to shrink.
> 
> Details of your use case, please (ideally - along with the reference to your
> code).
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in
> the body of a message to majordomo@xxxxxxxxxxxxxxx
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
--
To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Ext4 Filesystem]     [Union Filesystem]     [Filesystem Testing]     [Ceph Users]     [Ecryptfs]     [AutoFS]     [Kernel Newbies]     [Share Photos]     [Security]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux Cachefs]     [Reiser Filesystem]     [Linux RAID]     [Samba]     [Device Mapper]     [CEPH Development]
  Powered by Linux