[Linux-cluster] problem exporting GFS2 filesystem with NFS
Benoit DUFFAU
benoit.duffau at devoteam.com
Thu Jan 25 16:55:02 UTC 2007
Le jeudi 25 janvier 2007 à 10:30 +0000, Steven Whitehouse a écrit :
> Hi,
> >
> > Hope it helps
> >
> Yes, that was just the thing, thanks for sending that. Please see if the
> follow patch (it assumes that you have already applied the original fix
> I pointed you at) does the trick,
>
It works just GREAT !!!
Actually, doing some more test i figured out that the problem was only
by mounting the export with the hard option !
If one mounts the NFS export with the soft option using the first patch
you provided before already did the trick !
Now, with this patch it works using either hard or soft mount option for
NFS client !
Thank you so much !!
Benoit
> Steve.
>
>
> diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c
> index f7c8d31..88fcfb4 100644
> --- a/fs/gfs2/inode.c
> +++ b/fs/gfs2/inode.c
> @@ -395,8 +395,10 @@ struct inode *gfs2_lookup_simple(struct
> * @is_root: If 1, ignore the caller's permissions
> * @i_gh: An uninitialized holder for the new inode glock
> *
> - * There will always be a vnode (Linux VFS inode) for the d_gh inode unless
> - * @is_root is true.
> + * This can be called via the VFS filldir function when NFS is doing
> + * a readdirplus and the inode which its intending to stat isn't
> + * already in cache. In this case we must not take the directory glock
> + * again, since the readdir call will have already taken that lock.
> *
> * Returns: errno
> */
> @@ -409,8 +411,9 @@ struct inode *gfs2_lookupi(struct inode
> struct gfs2_holder d_gh;
> struct gfs2_inum_host inum;
> unsigned int type;
> - int error = 0;
> + int error;
> struct inode *inode = NULL;
> + int unlock = 0;
>
> if (!name->len || name->len > GFS2_FNAMESIZE)
> return ERR_PTR(-ENAMETOOLONG);
> @@ -422,9 +425,12 @@ struct inode *gfs2_lookupi(struct inode
> return dir;
> }
>
> - error = gfs2_glock_nq_init(dip->i_gl, LM_ST_SHARED, 0, &d_gh);
> - if (error)
> - return ERR_PTR(error);
> + if (gfs2_glock_is_locked_by_me(dip->i_gl) == 0) {
> + error = gfs2_glock_nq_init(dip->i_gl, LM_ST_SHARED, 0, &d_gh);
> + if (error)
> + return ERR_PTR(error);
> + unlock = 1;
> + }
>
> if (!is_root) {
> error = permission(dir, MAY_EXEC, NULL);
> @@ -439,10 +445,11 @@ struct inode *gfs2_lookupi(struct inode
> inode = gfs2_inode_lookup(sb, &inum, type);
>
> out:
> - gfs2_glock_dq_uninit(&d_gh);
> + if (unlock)
> + gfs2_glock_dq_uninit(&d_gh);
> if (error == -ENOENT)
> return NULL;
> - return inode;
> + return inode ? inode : ERR_PTR(error);
> }
>
> static int pick_formal_ino_1(struct gfs2_sbd *sdp, u64 *formal_ino)
> diff --git a/fs/gfs2/lops.c b/fs/gfs2/lops.c
> index 4d7f94d..16bb4b4 100644
> --- a/fs/gfs2/lops.c
> +++ b/fs/gfs2/lops.c
> @@ -69,13 +69,16 @@ static void buf_lo_add(struct gfs2_sbd *
> struct gfs2_bufdata *bd = container_of(le, struct gfs2_bufdata, bd_le);
> struct gfs2_trans *tr;
>
> - if (!list_empty(&bd->bd_list_tr))
> + gfs2_log_lock(sdp);
> + if (!list_empty(&bd->bd_list_tr)) {
> + gfs2_log_unlock(sdp);
> return;
> -
> + }
> tr = current->journal_info;
> tr->tr_touched = 1;
> tr->tr_num_buf++;
> list_add(&bd->bd_list_tr, &tr->tr_list_buf);
> + gfs2_log_unlock(sdp);
>
> if (!list_empty(&le->le_list))
> return;
> @@ -84,7 +87,6 @@ static void buf_lo_add(struct gfs2_sbd *
>
> gfs2_meta_check(sdp, bd->bd_bh);
> gfs2_pin(sdp, bd->bd_bh);
> -
> gfs2_log_lock(sdp);
> sdp->sd_log_num_buf++;
> list_add(&le->le_list, &sdp->sd_log_le_buf);
> @@ -98,11 +100,13 @@ static void buf_lo_incore_commit(struct
> struct list_head *head = &tr->tr_list_buf;
> struct gfs2_bufdata *bd;
>
> + gfs2_log_lock(sdp);
> while (!list_empty(head)) {
> bd = list_entry(head->next, struct gfs2_bufdata, bd_list_tr);
> list_del_init(&bd->bd_list_tr);
> tr->tr_num_buf--;
> }
> + gfs2_log_unlock(sdp);
> gfs2_assert_warn(sdp, !tr->tr_num_buf);
> }
>
> @@ -462,13 +466,17 @@ static void databuf_lo_add(struct gfs2_s
> struct address_space *mapping = bd->bd_bh->b_page->mapping;
> struct gfs2_inode *ip = GFS2_I(mapping->host);
>
> + gfs2_log_lock(sdp);
> tr->tr_touched = 1;
> if (list_empty(&bd->bd_list_tr) &&
> (ip->i_di.di_flags & GFS2_DIF_JDATA)) {
> tr->tr_num_buf++;
> list_add(&bd->bd_list_tr, &tr->tr_list_buf);
> + gfs2_log_unlock(sdp);
> gfs2_pin(sdp, bd->bd_bh);
> tr->tr_num_buf_new++;
> + } else {
> + gfs2_log_unlock(sdp);
> }
> gfs2_trans_add_gl(bd->bd_gl);
> gfs2_log_lock(sdp);
> diff --git a/fs/gfs2/ops_inode.c b/fs/gfs2/ops_inode.c
> index 747c731..5591f89 100644
> --- a/fs/gfs2/ops_inode.c
> +++ b/fs/gfs2/ops_inode.c
> @@ -1018,7 +1018,7 @@ static int gfs2_getattr(struct vfsmount
> }
>
> generic_fillattr(inode, stat);
> - if (unlock);
> + if (unlock)
> gfs2_glock_dq_uninit(&gh);
>
> return 0;
>
+---------------------------------------------------------------------+
Combining consulting and technology solutions offers enables Devoteam
to provide its customers with independent advice and effective solutions
that meet their strategic objectives (IT performance and optimisation)
in complementary areas: networks, systems infrastructure, security
and e-business applications.
Created in 1995, Devoteam achieved in 2005 a turnover of 199 million euros
and an operating margin of 7%. The group counts 2,400 employees through
sixteen countries in Europe, the Middle East and North Africa.
Listed on Euronext (Eurolist B compartment) since October 28, 1999.
Part of the Nexteconomy, CAC SMALL 90, IT CAC 50, SBF 250 index of
Euronext Paris
ISIN: FR 000007379 3, Reuters: DVTM.LM, Bloomberg: DEVO FP
+---------------------------------------------------------------------+
More information about the Linux-cluster
mailing list