I identified two more pointer in the xfs_ioctl.c open_by_handle function. If
you open a
file in write mode and their was already a cache entry for the file, running
fsr multiple
times would do this, some pointer variables would not have defined values
causing the
open_by_handle function to reference a null pointer.
I rearranged the code a bit and got rid of the null pointer problem and
discovered that
the linux inode i_fop did not point to the sgi xfs file system linux functions,
it pointed to
the default i_fop's. I add code to fix that problem and was finally able to
use the
open_by_handle funciotns with xfs_fsr.
Could you pass the following patch to Ted:
*** xfs_ioctl.c.orig Wed Jul 19 11:00:57 2000
--- xfs_ioctl.c Thu Jul 20 10:34:28 2000
***************
*** 354,360 ****
/*
* Make a unique name for dcache.
*/
! cpi = (char *)hanp;
cpo = sname;
for (i = 0; i < hlen && i < MAXFIDSZ; i++) {
--- 354,360 ----
/*
* Make a unique name for dcache.
*/
! cpi = (char *)handlep;
cpo = sname;
for (i = 0; i < hlen && i < MAXFIDSZ; i++) {
***************
*** 392,436 ****
up(&parinode->i_sem);
-
/*
* Handle 'negative' & 'new' dentries.
*/
inode = dentry->d_inode;
! if (inode == NULL) {
!
! /*
! * Get the XFS inode, building a vnode to go with it.
! */
! error = xfs_iget(mp, NULL, ino, XFS_ILOCK_SHARED, &ip, 0);
! if (error) {
! error = -error;
! goto cleanup_dentry;
! }
! if (ip == NULL) {
! error = -XFS_ERROR(EIO);
! goto cleanup_dentry;
! }
! if (ip->i_d.di_mode == 0 || ip->i_d.di_gen != igen) {
! xfs_iput(ip, XFS_ILOCK_SHARED);
! error = -XFS_ERROR(ENOENT);
! goto cleanup_dentry;
! }
! vp = XFS_ITOV(ip);
! xfs_iunlock(ip, XFS_ILOCK_SHARED);
inode = vp->v_inode;
if (! inode) {
--- 392,434 ----
up(&parinode->i_sem);
/*
* Handle 'negative' & 'new' dentries.
*/
inode = dentry->d_inode;
! /*
! * Get the XFS inode, building a vnode to go with it.
! */
! error = xfs_iget(mp, NULL, inode?inode->i_ino:ino, XFS_ILOCK_SHARED,
&ip, 0);
! if (error) {
! error = -error;
! goto cleanup_dentry;
! }
! if (ip == NULL) {
! error = -XFS_ERROR(EIO);
! goto cleanup_dentry;
! }
! if (ip->i_d.di_mode == 0 || ip->i_d.di_gen != igen) {
! xfs_iput(ip, XFS_ILOCK_SHARED);
! error = -XFS_ERROR(ENOENT);
! goto cleanup_dentry;
! }
! vp = XFS_ITOV(ip);
! xfs_iunlock(ip, XFS_ILOCK_SHARED);
+ if (inode == NULL) {
inode = vp->v_inode;
if (! inode) {
***************
*** 441,446 ****
--- 439,448 ----
goto cleanup_dentry;
}
+ /*
+ * Set xfs inode ops.
+ */
+ linvfs_set_inode_ops(inode);
d_add(dentry, inode);
}
***************
*** 524,529 ****
--- 526,533 ----
filp->f_reada = 0;
filp->f_op = inode->i_fop;
+
+
if (inode->i_sb)
file_move(filp, &inode->i_sb->s_files);
***************
*** 537,544 ****
filp->f_flags &= ~(O_CREAT | O_EXCL | O_NOCTTY | O_TRUNC);
- fd_install(newfd, filp);
return newfd;
--- 541,552 ----
filp->f_flags &= ~(O_CREAT | O_EXCL | O_NOCTTY | O_TRUNC);
+ if (klocked)
+ unlock_kernel();
+ klocked = 0;
+
+ fd_install(newfd, filp);
return newfd;
|