/*
** looks up the dentry of the parent directory for child.
** taken from ext2_get_parent
*/
struct dentry *reiserfs_get_parent(struct dentry *child)
{
	int retval;
	struct inode *inode = NULL;
	struct reiserfs_dir_entry de;
	INITIALIZE_PATH(path_to_entry);
	struct inode *dir = child->d_inode;

	if (dir->i_nlink == 0) {
		return ERR_PTR(-ENOENT);
	}
	de.de_gen_number_bit_string = NULL;

	reiserfs_write_lock(dir->i_sb);
	retval = reiserfs_find_entry(dir, "..", 2, &path_to_entry, &de);
	pathrelse(&path_to_entry);
	if (retval != NAME_FOUND) {
		reiserfs_write_unlock(dir->i_sb);
		return ERR_PTR(-ENOENT);
	}
	inode = reiserfs_iget(dir->i_sb, (struct cpu_key *)&(de.de_dir_id));
	reiserfs_write_unlock(dir->i_sb);

	return d_obtain_alias(inode);
}
Beispiel #2
0
/* 
** looks up the dentry of the parent directory for child.
** taken from ext2_get_parent
*/
struct dentry *reiserfs_get_parent(struct dentry *child)
{
    int retval;
    struct inode * inode = NULL;
    struct reiserfs_dir_entry de;
    INITIALIZE_PATH (path_to_entry);
    struct dentry *parent;
    struct inode *dir = child->d_inode ;


    if (dir->i_nlink == 0) {
	return ERR_PTR(-ENOENT);
    }
    de.de_gen_number_bit_string = NULL;

    reiserfs_write_lock(dir->i_sb);
    retval = reiserfs_find_entry (dir, "..", 2, &path_to_entry, &de);
    pathrelse (&path_to_entry);
    if (retval != NAME_FOUND) {
	reiserfs_write_unlock(dir->i_sb);
	return ERR_PTR(-ENOENT);
    }
    inode = reiserfs_iget (dir->i_sb, (struct cpu_key *)&(de.de_dir_id));
    reiserfs_write_unlock(dir->i_sb);

    if (!inode || IS_ERR(inode)) {
	return ERR_PTR(-EACCES);
    }
    parent = d_alloc_anon(inode);
    if (!parent) {
	iput(inode);
	parent = ERR_PTR(-ENOMEM);
    }
    return parent;
}
Beispiel #3
0
static struct dentry *reiserfs_lookup(struct inode *dir, struct dentry *dentry,
				      struct nameidata *nd)
{
	int retval;
	struct inode *inode = NULL;
	struct reiserfs_dir_entry de;
	INITIALIZE_PATH(path_to_entry);

	if (REISERFS_MAX_NAME(dir->i_sb->s_blocksize) < dentry->d_name.len)
		return ERR_PTR(-ENAMETOOLONG);

	reiserfs_write_lock(dir->i_sb);
	de.de_gen_number_bit_string = NULL;
	retval =
	    reiserfs_find_entry(dir, dentry->d_name.name, dentry->d_name.len,
				&path_to_entry, &de);
	pathrelse(&path_to_entry);
	if (retval == NAME_FOUND) {
		/* Hide the .reiserfs_priv directory */
		if (reiserfs_xattrs(dir->i_sb) &&
		    !old_format_only(dir->i_sb) &&
		    REISERFS_SB(dir->i_sb)->priv_root &&
		    REISERFS_SB(dir->i_sb)->priv_root->d_inode &&
		    de.de_objectid ==
		    le32_to_cpu(INODE_PKEY
				(REISERFS_SB(dir->i_sb)->priv_root->d_inode)->
				k_objectid)) {
			reiserfs_write_unlock(dir->i_sb);
			return ERR_PTR(-EACCES);
		}

		inode =
		    reiserfs_iget(dir->i_sb, (struct cpu_key *)&(de.de_dir_id));
		if (!inode || IS_ERR(inode)) {
			reiserfs_write_unlock(dir->i_sb);
			return ERR_PTR(-EACCES);
		}

		/* Propogate the priv_object flag so we know we're in the priv tree */
		if (is_reiserfs_priv_object(dir))
			reiserfs_mark_inode_private(inode);
	}
	reiserfs_write_unlock(dir->i_sb);
	if (retval == IO_ERROR) {
		return ERR_PTR(-EIO);
	}

	return d_splice_alias(inode, dentry);
}
Beispiel #4
0
/*
 * Return the root of a filesystem.
 */ 
static int
reiserfs_root(struct mount *mp, int flags, struct vnode **vpp)
{
	int error;
	struct vnode *vp;
	struct cpu_key rootkey;

	rootkey.on_disk_key.k_dir_id = REISERFS_ROOT_PARENT_OBJECTID;
	rootkey.on_disk_key.k_objectid = REISERFS_ROOT_OBJECTID;

	error = reiserfs_iget(mp, &rootkey, &vp, curthread);

	if (error == 0)
		*vpp = vp;
	return (error);
}
Beispiel #5
0
/*
 * File handle to vnode
 *
 * Have to be really careful about stale file handles:
 * - check that the inode key is valid
 * - call ffs_vget() to get the locked inode
 * - check for an unallocated inode (i_mode == 0)
 * - check that the given client host has export rights and return
 *   those rights via. exflagsp and credanonp
 */
static int
reiserfs_fhtovp(struct mount *mp, struct fid *fhp, int flags,
    struct vnode **vpp)
{
	int error;
	struct rfid *rfhp;
	struct vnode *nvp;
	struct cpu_key key;
	struct reiserfs_node *ip;
	struct reiserfs_sb_info *sbi;
	struct thread *td = curthread;

	rfhp = (struct rfid *)fhp;
	sbi  = VFSTOREISERFS(mp)->rm_reiserfs;

	/* Check that the key is valid */
	if (rfhp->rfid_dirid < REISERFS_ROOT_PARENT_OBJECTID &&
	    rfhp->rfid_objectid < REISERFS_ROOT_OBJECTID)
		return (ESTALE);

	reiserfs_log(LOG_DEBUG,
	    "file handle key is (dirid=%d, objectid=%d)\n",
	    rfhp->rfid_dirid, rfhp->rfid_objectid);
	key.on_disk_key.k_dir_id   = rfhp->rfid_dirid;
	key.on_disk_key.k_objectid = rfhp->rfid_objectid;

	reiserfs_log(LOG_DEBUG, "read this inode\n");
	error = reiserfs_iget(mp, &key, &nvp, td);
	if (error) {
		*vpp = NULLVP;
		return (error);
	}

	reiserfs_log(LOG_DEBUG, "check validity\n");
	ip = VTOI(nvp);
	if (ip->i_mode == 0 || ip->i_generation != rfhp->rfid_gen) {
		vput(nvp);
		*vpp = NULLVP;
		return (ESTALE);
	}

	reiserfs_log(LOG_DEBUG, "return it\n");
	*vpp = nvp;
	return (0);
}
static struct dentry *reiserfs_lookup(struct inode *dir, struct dentry *dentry,
				      struct nameidata *nd)
{
	int retval;
	int lock_depth;
	struct inode *inode = NULL;
	struct reiserfs_dir_entry de;
	INITIALIZE_PATH(path_to_entry);

	if (REISERFS_MAX_NAME(dir->i_sb->s_blocksize) < dentry->d_name.len)
		return ERR_PTR(-ENAMETOOLONG);

	/*
	 * Might be called with or without the write lock, must be careful
	 * to not recursively hold it in case we want to release the lock
	 * before rescheduling.
	 */
	lock_depth = reiserfs_write_lock_once(dir->i_sb);

	de.de_gen_number_bit_string = NULL;
	retval =
	    reiserfs_find_entry(dir, dentry->d_name.name, dentry->d_name.len,
				&path_to_entry, &de);
	pathrelse(&path_to_entry);
	if (retval == NAME_FOUND) {
		inode = reiserfs_iget(dir->i_sb,
				      (struct cpu_key *)&(de.de_dir_id));
		if (!inode || IS_ERR(inode)) {
			reiserfs_write_unlock_once(dir->i_sb, lock_depth);
			return ERR_PTR(-EACCES);
		}

		/* Propagate the private flag so we know we're
		 * in the priv tree */
		if (IS_PRIVATE(dir))
			inode->i_flags |= S_PRIVATE;
	}
	reiserfs_write_unlock_once(dir->i_sb, lock_depth);
	if (retval == IO_ERROR) {
		return ERR_PTR(-EIO);
	}

	return d_splice_alias(inode, dentry);
}
Beispiel #7
0
struct dentry * reiserfs_lookup (struct inode * dir, struct dentry * dentry)
{
  struct inode * inode = 0;
  struct reiserfs_dir_entry de;
  struct path path_to_entry;
  int error;

  init_path (&path_to_entry);

  de.de_gen_number_bit_string = 0;
  error = reiserfs_find_entry (dir, dentry->d_name.name, dentry->d_name.len, &path_to_entry, &de);
  pathrelse (&path_to_entry);
  if (error == POSITION_FOUND) {
    inode = reiserfs_iget (dir->i_sb, (struct key *)&(de.de_dir_id));
    if (!inode)
      return ERR_PTR(-EACCES);
  }

  d_add(dentry, inode);
  return NULL;
}
Beispiel #8
0
static struct dentry *reiserfs_lookup(struct inode *dir, struct dentry *dentry,
				      unsigned int flags)
{
	int retval;
	struct inode *inode = NULL;
	struct reiserfs_dir_entry de;
	INITIALIZE_PATH(path_to_entry);

	if (REISERFS_MAX_NAME(dir->i_sb->s_blocksize) < dentry->d_name.len)
		return ERR_PTR(-ENAMETOOLONG);

	reiserfs_write_lock(dir->i_sb);

	de.de_gen_number_bit_string = NULL;
	retval =
	    reiserfs_find_entry(dir, dentry->d_name.name, dentry->d_name.len,
				&path_to_entry, &de);
	pathrelse(&path_to_entry);
	if (retval == NAME_FOUND) {
		inode = reiserfs_iget(dir->i_sb,
				      (struct cpu_key *)&de.de_dir_id);
		if (!inode || IS_ERR(inode)) {
			reiserfs_write_unlock(dir->i_sb);
			return ERR_PTR(-EACCES);
		}

		/*
		 * Propagate the private flag so we know we're
		 * in the priv tree
		 */
		if (IS_PRIVATE(dir))
			inode->i_flags |= S_PRIVATE;
	}
	reiserfs_write_unlock(dir->i_sb);
	if (retval == IO_ERROR) {
		return ERR_PTR(-EIO);
	}

	return d_splice_alias(inode, dentry);
}
int
reiserfs_lookup(struct vop_cachedlookup_args *ap)
{
	int error, retval;
	struct vnode *vdp         = ap->a_dvp;
	struct vnode **vpp        = ap->a_vpp;
	struct componentname *cnp = ap->a_cnp;

	int flags         = cnp->cn_flags;
	struct thread *td = cnp->cn_thread;
	struct cpu_key *saved_ino;

	struct vnode *vp;
	struct vnode *pdp;  /* Saved dp during symlink work */
	struct reiserfs_node *dp;
	struct reiserfs_dir_entry de;
	INITIALIZE_PATH(path_to_entry);

	char c = cnp->cn_nameptr[cnp->cn_namelen];
	cnp->cn_nameptr[cnp->cn_namelen] = '\0';
	reiserfs_log(LOG_DEBUG, "looking for `%s', %ld (%s)\n",
	    cnp->cn_nameptr, cnp->cn_namelen, cnp->cn_pnbuf);
	cnp->cn_nameptr[cnp->cn_namelen] = c;

	vp = NULL;
	dp = VTOI(vdp);

	if (REISERFS_MAX_NAME(dp->i_reiserfs->s_blocksize) < cnp->cn_namelen)
		return (ENAMETOOLONG);

	reiserfs_log(LOG_DEBUG, "searching entry\n");
	de.de_gen_number_bit_string = 0;
	retval = reiserfs_find_entry(dp, cnp->cn_nameptr, cnp->cn_namelen,
	    &path_to_entry, &de);
	pathrelse(&path_to_entry);

	if (retval == NAME_FOUND) {
		reiserfs_log(LOG_DEBUG, "found\n");
	} else {
		reiserfs_log(LOG_DEBUG, "not found\n");
	}

	if (retval == NAME_FOUND) {
#if 0
		/* Hide the .reiserfs_priv directory */
		if (reiserfs_xattrs(dp->i_reiserfs) &&
		    !old_format_only(dp->i_reiserfs) &&
		    REISERFS_SB(dp->i_reiserfs)->priv_root &&
		    REISERFS_SB(dp->i_reiserfs)->priv_root->d_inode &&
		    de.de_objectid == le32toh(INODE_PKEY(REISERFS_SB(
		    dp->i_reiserfs)->priv_root->d_inode)->k_objectid)) {
			return (EACCES);
		}
#endif

		reiserfs_log(LOG_DEBUG, "reading vnode\n");
		pdp = vdp;
		if (flags & ISDOTDOT) {
			saved_ino = (struct cpu_key *)&(de.de_dir_id);
			VOP_UNLOCK(pdp, 0);
			error = reiserfs_iget(vdp->v_mount,
			    saved_ino, &vp, td);
			vn_lock(pdp, LK_EXCLUSIVE | LK_RETRY);
			if (error != 0)
				return (error);
			*vpp = vp;
		} else if (de.de_objectid == dp->i_number &&
		    de.de_dir_id == dp->i_ino) {
			VREF(vdp); /* We want ourself, ie "." */
			*vpp = vdp;
		} else {
			if ((error = reiserfs_iget(vdp->v_mount,
			    (struct cpu_key *)&(de.de_dir_id), &vp, td)) != 0)
				return (error);
			*vpp = vp;
		}

		/*
		 * Propogate the priv_object flag so we know we're in the
		 * priv tree
		 */
		/*if (is_reiserfs_priv_object(dir))
			REISERFS_I(inode)->i_flags |= i_priv_object;*/
	} else {
		if (retval == IO_ERROR) {
			reiserfs_log(LOG_DEBUG, "IO error\n");
			return (EIO);
		}

		return (ENOENT);
	}

	/* Insert name into cache if appropriate. */
	if (cnp->cn_flags & MAKEENTRY)
		cache_enter(vdp, *vpp, cnp);

	reiserfs_log(LOG_DEBUG, "done\n");
	return (0);
}
Beispiel #10
0
/* look for uncompleted unlinks and truncates and complete them */
static void finish_unfinished (struct super_block * s)
{
    INITIALIZE_PATH (path);
    struct cpu_key max_cpu_key, obj_key;
    struct key save_link_key;
    int retval;
    struct item_head * ih;
    struct buffer_head * bh;
    int item_pos;
    char * item;
    int done;
    struct inode * inode;
    int truncate;
 
 
    /* compose key to look for "save" links */
    max_cpu_key.version = KEY_FORMAT_3_5;
    max_cpu_key.on_disk_key = MAX_KEY;
    max_cpu_key.key_length = 3;
 
    done = 0;
    s -> u.reiserfs_sb.s_is_unlinked_ok = 1;
    while (1) {
        retval = search_item (s, &max_cpu_key, &path);
        if (retval != ITEM_NOT_FOUND) {
            reiserfs_warning ("vs-2140: finish_unfinished: search_by_key returned %d\n",
                              retval);
            break;
        }
        
        bh = get_last_bh (&path);
        item_pos = get_item_pos (&path);
        if (item_pos != B_NR_ITEMS (bh)) {
            reiserfs_warning ("vs-2060: finish_unfinished: wrong position found\n");
            break;
        }
        item_pos --;
        ih = B_N_PITEM_HEAD (bh, item_pos);
 
        if (le32_to_cpu (ih->ih_key.k_dir_id) != MAX_KEY_OBJECTID)
            /* there are no "save" links anymore */
            break;
 
        save_link_key = ih->ih_key;
        if (is_indirect_le_ih (ih))
            truncate = 1;
        else
            truncate = 0;
 
        /* reiserfs_iget needs k_dirid and k_objectid only */
        item = B_I_PITEM (bh, ih);
        obj_key.on_disk_key.k_dir_id = le32_to_cpu (*(__u32 *)item);
        obj_key.on_disk_key.k_objectid = le32_to_cpu (ih->ih_key.k_objectid);
	obj_key.on_disk_key.u.k_offset_v1.k_offset = 0;
	obj_key.on_disk_key.u.k_offset_v1.k_uniqueness = 0;
	
        pathrelse (&path);
 
        inode = reiserfs_iget (s, &obj_key);
        if (!inode) {
            /* the unlink almost completed, it just did not manage to remove
	       "save" link and release objectid */
            reiserfs_warning ("vs-2180: finish_unfinished: iget failed for %K\n",
                              &obj_key);
            remove_save_link_only (s, &save_link_key, 1);
            continue;
        }

	if (!truncate && inode->i_nlink) {
	    /* file is not unlinked */
            reiserfs_warning ("vs-2185: finish_unfinished: file %K is not unlinked\n",
                              &obj_key);
            remove_save_link_only (s, &save_link_key, 0);
            continue;
	}

	if (truncate && S_ISDIR (inode->i_mode) ) {
	    /* We got a truncate request for a dir which is impossible.
	       The only imaginable way is to execute unfinished truncate request
	       then boot into old kernel, remove the file and create dir with
	       the same key. */
	    reiserfs_warning("green-2101: impossible truncate on a directory %k. Please report\n", INODE_PKEY (inode));
	    remove_save_link_only (s, &save_link_key, 0);
	    truncate = 0;
	    iput (inode); 
	    continue;
	}
 
        if (truncate) {
            inode -> u.reiserfs_i.i_flags |= i_link_saved_truncate_mask;
            /* not completed truncate found. New size was committed together
	       with "save" link */
            reiserfs_warning ("Truncating %k to %Ld ..",
                              INODE_PKEY (inode), inode->i_size);
            reiserfs_truncate_file (inode, 0/*don't update modification time*/);
            remove_save_link (inode, truncate);
        } else {
            inode -> u.reiserfs_i.i_flags |= i_link_saved_unlink_mask;
            /* not completed unlink (rmdir) found */
            reiserfs_warning ("Removing %k..", INODE_PKEY (inode));
            /* removal gets completed in iput */
        }
 
        iput (inode);
        printk ("done\n");
        done ++;
    }
    s -> u.reiserfs_sb.s_is_unlinked_ok = 0;
     
    pathrelse (&path);
    if (done)
        reiserfs_warning ("There were %d uncompleted unlinks/truncates. "
                          "Completed\n", done);
}