]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - fs/exportfs/expfs.c
EXPORTFS: handle NULL returns from fh_to_dentry()/fh_to_parent()
[linux-2.6-omap-h63xx.git] / fs / exportfs / expfs.c
index 7b0f75dcf800ca1d8b54695d647a973859e05dcf..890e018288171e90d9991b47e7077dfbaf9c7cf8 100644 (file)
@@ -94,9 +94,8 @@ find_disconnected_root(struct dentry *dentry)
  * It may already be, as the flag isn't always updated when connection happens.
  */
 static int
-reconnect_path(struct vfsmount *mnt, struct dentry *target_dir)
+reconnect_path(struct vfsmount *mnt, struct dentry *target_dir, char *nbuf)
 {
-       char nbuf[NAME_MAX+1];
        int noprogress = 0;
        int err = -ESTALE;
 
@@ -281,13 +280,14 @@ static int get_name(struct vfsmount *mnt, struct dentry *dentry,
                int old_seq = buffer.sequence;
 
                error = vfs_readdir(file, filldir_one, &buffer);
+               if (buffer.found) {
+                       error = 0;
+                       break;
+               }
 
                if (error < 0)
                        break;
 
-               error = 0;
-               if (buffer.found)
-                       break;
                error = -ENOENT;
                if (old_seq == buffer.sequence)
                        break;
@@ -360,12 +360,15 @@ struct dentry *exportfs_decode_fh(struct vfsmount *mnt, struct fid *fid,
 {
        const struct export_operations *nop = mnt->mnt_sb->s_export_op;
        struct dentry *result, *alias;
+       char nbuf[NAME_MAX+1];
        int err;
 
        /*
         * Try to get any dentry for the given file handle from the filesystem.
         */
        result = nop->fh_to_dentry(mnt->mnt_sb, fid, fh_len, fileid_type);
+       if (!result)
+               result = ERR_PTR(-ESTALE);
        if (IS_ERR(result))
                return result;
 
@@ -379,7 +382,7 @@ struct dentry *exportfs_decode_fh(struct vfsmount *mnt, struct fid *fid,
                 * filesystem root.
                 */
                if (result->d_flags & DCACHE_DISCONNECTED) {
-                       err = reconnect_path(mnt, result);
+                       err = reconnect_path(mnt, result, nbuf);
                        if (err)
                                goto err_result;
                }
@@ -395,7 +398,6 @@ struct dentry *exportfs_decode_fh(struct vfsmount *mnt, struct fid *fid,
                 * It's not a directory.  Life is a little more complicated.
                 */
                struct dentry *target_dir, *nresult;
-               char nbuf[NAME_MAX+1];
 
                /*
                 * See if either the dentry we just got from the filesystem
@@ -420,6 +422,8 @@ struct dentry *exportfs_decode_fh(struct vfsmount *mnt, struct fid *fid,
 
                target_dir = nop->fh_to_parent(mnt->mnt_sb, fid,
                                fh_len, fileid_type);
+               if (!target_dir)
+                       goto err_result;
                err = PTR_ERR(target_dir);
                if (IS_ERR(target_dir))
                        goto err_result;
@@ -429,7 +433,7 @@ struct dentry *exportfs_decode_fh(struct vfsmount *mnt, struct fid *fid,
                 * connected to the filesystem root.  The VFS really doesn't
                 * like disconnected directories..
                 */
-               err = reconnect_path(mnt, target_dir);
+               err = reconnect_path(mnt, target_dir, nbuf);
                if (err) {
                        dput(target_dir);
                        goto err_result;