0
votes

I am following the open() system call to find out when the struct file_operations and struct file get connected during a creation of file.

The main path is as follows:

sys_open -> do_sys_open -> do_filp_open -> nameidata_to_filp -> __dentry_open

In __dentry_open

 static struct file *__dentry_open(struct dentry *dentry, struct vfsmount *mnt,
                                     int flags, struct file *f,
                                     int (*open)(struct inode *, struct file *),
                                     const struct cred *cred)
{
    struct inode *inode;
    int error;

    f->f_flags = flags;
    f->f_mode = ((flags+1) & O_ACCMODE) | FMODE_LSEEK |
                            FMODE_PREAD | FMODE_PWRITE;
    inode = dentry->d_inode;
    if (f->f_mode & FMODE_WRITE) {
            error = __get_file_write_access(inode, mnt);
            if (error)
                    goto cleanup_file;
            if (!special_file(inode->i_mode))
                    file_take_write(f);
    }

    f->f_mapping = inode->i_mapping;
    f->f_path.dentry = dentry;
    f->f_path.mnt = mnt;
    f->f_pos = 0;
    f->f_op = fops_get(inode->i_fop);//I think it is here that they get connected
    file_move(f, &inode->i_sb->s_files);

    error = security_dentry_open(f);

    ...

But when and in which function that the i_fop in inode gets initialized?

2

2 Answers

1
votes

Have you seen this and this:

The open(2) system call is implemented in fs/open.c:sys_open function and the real work is done by fs/open.c:filp_open() function, which is split into two parts:

open_namei(): fills in the nameidata structure containing the dentry and vfsmount structures. dentry_open(): given a dentry and vfsmount, this function allocates a new struct file and links them together; it also invokes the filesystem specific f_op->open() method which was set in inode->i_fop when inode was read in open_namei() (which provided inode via dentry->d_inode).

It is actually set at path_walk function (if file exists):

path_walk(const char *name, struct nameidata *nd) {
/* ... */
               /* if . or .. then special, otherwise: */
                dentry = cached_lookup(nd->dentry, &this);
/* ... */ 
                if (!dentry)
                 dentry = real_lookup(nd->dentry, &this);

dentry contains the inode information in its d_inode member. So the initialization inode is in open_namei function (or somewhere down there), before the dentry_open. Just track the dentry structure.

0
votes

File operations are assigned when a dentry object is being created for an existing file. This is done in the file system specific lookup function. Following is the call flow for that.

sys_open-->do_sys_open-->do_filp_open-->path_openat-->do_last-->walk_component-->do_lookup-->d_alloc_and_lookup-->filesystem specific lookup function()

File system specific lookup function for ext2 file system is ext2_lookup() and for ext3 it is ext3_lookup() and for ext4 it is ext4_lookup(). Inside the lookup function there will be a function call like ext2_iget() or ext3_iget() or ext4_iget(). This function fills the i_fop field of inode object.

This is on linux-3.0.