cocalele / ViveNAS

5 stars 4 forks source link

segfault in write file #4

Closed cocalele closed 2 years ago

cocalele commented 2 years ago

Segfault encountered in file mem_write2 because the ViveFile* was NULL in the object handle asked to write.

We have the following structure for ViveNAS open:

struct vn_fd {
    struct state_t state;
    /** The open and share mode etc. This MUST be first in every
     *  file descriptor structure.
     */
    fsal_openflags_t openflags;
    struct ViveFile* vf;    //segfault caused by this NULL
};

struct mem_fsal_obj_handle {
        struct {
            struct fsal_share share;
            struct vn_fd fd;  //HOPE: vf in fd should be valid after open. 
        } mh_file;
};

In open2 function, the logic is as following :

fsal_status_t mem_open2(struct fsal_obj_handle *obj_hdl,
            struct state_t *state,
            fsal_openflags_t openflags,
            enum fsal_create_mode createmode,
            const char *name,
            struct fsal_attrlist *attrs_set,
            fsal_verifier_t verifier,
            struct fsal_obj_handle **new_obj,
            struct fsal_attrlist *attrs_out,
            bool *caller_perm_check)
{
    if (state != NULL) {
        my_fd = container_of(state, struct vn_fd, state);
    }

    if (name == NULL) {
        if (state != NULL) {
                          // NOT CHANGE TO my_fd, use state as fd
        } else {
            my_fd = &myself->mh_file.fd;  //use fd take from handle
        }
    }
    mem_open_my_fd(myself, my_fd, openflags);

}

The open2 function was called with

open file name:(null) myslef:0x7f38c821ea90 myself_name:f2 state:0x7f38c811d4f0

That's to say the state was used as fd and opened, and we not touch the fd in input param obj_handle was not touched.

cocalele commented 2 years ago

Though not totally understand ganesha mechanism on using state in open, I guess a state should be valid for an unique object_handle. There may be something wrong make ganesha treat the handle different as an existing one.

At last I found the function package_mem_handle, it use field in object_handle to form a unique identifier. Then obj_handle.fileid was found initialized wrong.

static struct mem_fsal_obj_handle * _mem_alloc_handle()
{
    struct mem_fsal_obj_handle *hdl;
    size_t isize;

     hdl->obj_handle.fileid = atomic_postinc_uint64_t(&mem_inode_number);  //that's the legacy code inherited from fsal_mem
    hdl->obj_handle.fileid = inode->i_no;  //for ViveNAS should use correct inode number
}
cocalele commented 2 years ago

after correcting the error in alloc_handle, this bug disappears.

a new state object is allocated on each time the file is opened.