Login
[x]
Log in using an account from:
Fedora Account System
Red Hat Associate
Red Hat Customer
Or login using a Red Hat Bugzilla account
Forgot Password
Login:
Hide Forgot
Create an Account
Red Hat Bugzilla – Attachment 146972 Details for
Bug 190475
error when two nodes rename two files to same new name
[?]
New
Simple Search
Advanced Search
My Links
Browse
Requests
Reports
Current State
Search
Tabular reports
Graphical reports
Duplicates
Other Reports
User Changes
Plotly Reports
Bug Status
Bug Severity
Non-Defaults
|
Product Dashboard
Help
Page Help!
Bug Writing Guidelines
What's new
Browser Support Policy
5.0.4.rh83 Release notes
FAQ
Guides index
User guide
Web Services
Contact
Legal
This site requires JavaScript to be enabled to function correctly, please enable it.
gfs_rename_core.patch
gfs_rename_core.patch (text/plain), 5.91 KB, created by
Wendy Cheng
on 2007-01-30 22:38:47 UTC
(
hide
)
Description:
gfs_rename_core.patch
Filename:
MIME Type:
Creator:
Wendy Cheng
Created:
2007-01-30 22:38:47 UTC
Size:
5.91 KB
patch
obsolete
>--- gfs-rename2/src/gfs/inode.h 2007-01-18 16:33:37.000000000 -0500 >+++ gfs-kernel/src/gfs/inode.h 2007-01-18 16:39:11.000000000 -0500 >@@ -37,7 +37,7 @@ int gfs_createi(struct gfs_holder *d_gh, > int gfs_unlinki(struct gfs_inode *dip, struct qstr *name, struct gfs_inode *ip); > int gfs_rmdiri(struct gfs_inode *dip, struct qstr *name, struct gfs_inode *ip); > int gfs_unlink_ok(struct gfs_inode *dip, struct qstr *name, >- struct gfs_inode *ip); >+ struct gfs_inode *ip, struct gfs_inum *inum); > int gfs_ok_to_move(struct gfs_inode *this, struct gfs_inode *to); > int gfs_readlinki(struct gfs_inode *ip, char **buf, unsigned int *len); > >--- gfs-rename2/src/gfs/inode.c 2007-01-18 16:36:38.000000000 -0500 >+++ gfs-kernel/src/gfs/inode.c 2007-01-18 21:41:26.000000000 -0500 >@@ -1566,7 +1566,8 @@ gfs_rmdiri(struct gfs_inode *dip, struct > */ > > int >-gfs_unlink_ok(struct gfs_inode *dip, struct qstr *name, struct gfs_inode *ip) >+gfs_unlink_ok(struct gfs_inode *dip, struct qstr *name, >+ struct gfs_inode *ip, struct gfs_inum *inump) > { > struct gfs_inum inum; > unsigned int type; >@@ -1589,11 +1590,21 @@ gfs_unlink_ok(struct gfs_inode *dip, str > return error; > > error = gfs_dir_search(dip, name, &inum, &type); >- if (error) >+ if (error) > return error; > >- if (inum.no_formal_ino != ip->i_num.no_formal_ino) >+ if (inum.no_formal_ino != ip->i_num.no_formal_ino) { >+ >+ /* >+ * Add for rename - bugzilla 190475 >+ * return new inum such that gfs_rename can >+ * do its silly rename. >+ */ >+ if (unlikely(inump)) >+ *inump = inum; >+ > return -ENOENT; >+ } > > if (ip->i_di.di_type != type) { > gfs_consist_inode(dip); >--- gfs-rename2/src/gfs/ops_inode.c 2007-01-18 15:02:24.000000000 -0500 >+++ gfs-kernel/src/gfs/ops_inode.c 2007-01-18 21:40:04.000000000 -0500 >@@ -537,7 +537,7 @@ gfs_unlink(struct inode *dir, struct den > if (error) > goto fail; > >- error = gfs_unlink_ok(dip, &dentry->d_name, ip); >+ error = gfs_unlink_ok(dip, &dentry->d_name, ip, NULL); > if (error) > goto fail_gunlock; > >@@ -772,7 +772,7 @@ gfs_rmdir(struct inode *dir, struct dent > if (error) > goto fail; > >- error = gfs_unlink_ok(dip, &dentry->d_name, ip); >+ error = gfs_unlink_ok(dip, &dentry->d_name, ip, NULL); > if (error) > goto fail_gunlock; > >@@ -914,6 +914,55 @@ gfs_mknod(struct inode *dir, struct dent > return 0; > } > >+/* >+ * Obtain a clone dentry with correct inode: >+ * >+ * This is to work around the window between lock_rename() >+ * and gfs_rename() where another node may have renamed the >+ * target file (bugzilla 190475). The bug most likely occurs >+ * in a mail server environment. >+ * >+ * Return true if the dentry has been successfully updated. >+ */ >+static int >+gfs_refresh_dentry(struct gfs_sbd *sdp, struct dentry **f_dentry, >+ struct gfs_inum *inump) >+{ >+ struct inode *inode; >+ struct dentry *dentry, *sdentry=*f_dentry; >+ >+ dentry = d_alloc(sdentry->d_parent, &sdentry->d_name); >+ if (!dentry) >+ return 0; >+ >+ /* Get the fully updated inode */ >+ inode = NULL; >+ if (inump->no_formal_ino) { >+ inode = gfs_refresh_iobj(sdp, inump, NULL); >+ if (IS_ERR(inode)) { >+ dput(dentry); >+ return 0; >+ } >+ } >+ >+ /* >+ * Remove the old dentry from cache to avoid >+ * another lookup. >+ */ >+ if (!d_unhashed(sdentry)) { >+ d_drop(sdentry); >+ } >+ >+ /* Instantiate the new dentry */ >+ dentry->d_op = &gfs_dops; >+ >+ d_splice_alias(inode, dentry); >+ >+ /* Return with success */ >+ *f_dentry = dentry; >+ return 1; >+} >+ > /** > * gfs_rename - Rename a file > * @odir: Parent directory of old file name >@@ -935,17 +984,21 @@ gfs_rename(struct inode *odir, struct de > struct gfs_sbd *sdp = odip->i_sbd; > struct qstr name; > struct gfs_alloc *al; >- struct gfs_holder ghs[4], r_gh; >+ struct gfs_holder ghs[5], r_gh; > unsigned int num_gh; > int dir_rename = FALSE; > int alloc_required; > unsigned int x; > int error; >+ int loop_cnt=0, has_ndentry=0; >+ struct gfs_inum new_inum; > > atomic_inc(&sdp->sd_ops_inode); > > gfs_unlinked_limit(sdp); > >+ odir->i_sb->s_type->fs_flags &= ~FS_ODD_RENAME; >+ > if (ndentry->d_inode) { > nip = vn2ip(ndentry->d_inode); > if (ip == nip) >@@ -988,16 +1041,47 @@ gfs_rename(struct inode *odir, struct de > > /* Check out the old directory */ > >- error = gfs_unlink_ok(odip, &odentry->d_name, ip); >+ error = gfs_unlink_ok(odip, &odentry->d_name, ip, NULL); > if (error) > goto fail_gunlock; > > /* Check out the new directory */ > >+gfs_rename_restart: > if (nip) { >- error = gfs_unlink_ok(ndip, &ndentry->d_name, nip); >- if (error) >+ /* Zero out this field so gfs_unlink_ok could fill in the correct >+ * ino. why ? >+ */ >+ new_inum.no_formal_ino = 0; >+ error = gfs_unlink_ok(ndip, &ndentry->d_name, nip, &new_inum); >+ if (unlikely(error)) { >+ /* >+ * Bugzilla 190475: >+ * >+ * Handle a rare race condition that the new file >+ * could have been renamed by another node - the >+ * correct inode number is passed into new_inum. >+ * We can only go thru this logic once. >+ */ >+ if ((error == -ENOENT) && (!loop_cnt) >+ && (new_inum.no_formal_ino)) >+ { >+ loop_cnt++; >+ if (gfs_refresh_dentry(sdp,&ndentry,&new_inum)) >+ { >+ odir->i_sb->s_type->fs_flags >+ |= FS_ODD_RENAME; >+ has_ndentry = 1; >+ nip = vn2ip(ndentry->d_inode); >+ if (nip) >+ gfs_glock_nq_init(nip->i_gl, >+ LM_ST_EXCLUSIVE, 0, >+ &ghs[num_gh++]); >+ goto gfs_rename_restart; >+ } >+ } > goto fail_gunlock; >+ } > > if (nip->i_di.di_type == GFS_FILE_DIR) { > if (nip->i_di.di_entries < 2) { >@@ -1150,6 +1234,14 @@ gfs_rename(struct inode *odir, struct de > if (dir_rename) > gfs_glock_dq_uninit(&r_gh); > >+ >+ /* dput new dentry as vfs layer still uses old entry */ >+ if (unlikely(has_ndentry)) { >+ d_move(odentry, ndentry); >+ dput(ndentry); >+ dput(ndentry); >+ } >+ > return 0; > > fail_end_trans: >@@ -1178,6 +1270,12 @@ gfs_rename(struct inode *odir, struct de > if (dir_rename) > gfs_glock_dq_uninit(&r_gh); > >+ if (unlikely(has_ndentry)) { >+ d_move(odentry, ndentry); >+ dput(ndentry); >+ dput(ndentry); >+ } >+ > return error; > } >
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Raw
Actions:
View
Attachments on
bug 190475
:
128507
|
128513
|
135183
|
135213
|
135292
| 146972