コード例 #1
0
ファイル: cpup.c プロジェクト: wosigh/patches
void au_dtime_revert(struct au_dtime *dt)
{
	struct iattr attr;
	int err;
	struct au_hin_ignore ign[2];
	struct vfsub_args vargs;

	LKTRTrace("%.*s\n", AuDLNPair(dt->dt_dentry));

	attr.ia_atime = dt->dt_atime;
	attr.ia_mtime = dt->dt_mtime;
	attr.ia_valid = ATTR_FORCE | ATTR_MTIME | ATTR_MTIME_SET
		| ATTR_ATIME | ATTR_ATIME_SET;

	vfsub_args_init(&vargs, ign,
			au_test_dlgt(au_mntflags(dt->dt_dentry->d_sb)), 0);
	/*
	 * IN_ATTRIB should be divided into
	 * IN_ATTRIB_ATIME, IN_ATTRIB_MTIME ...,
	 * and define all ORed new IN_ATTRIB macro.
	 */
	vfsub_ign_hinode(&vargs, IN_ATTRIB, dt->dt_hinode);
	vfsub_ign_hinode(&vargs, IN_ATTRIB, dt->dt_hdir);
	err = vfsub_notify_change(dt->dt_h_dentry, &attr, &vargs);
	if (unlikely(err))
		AuWarn("restoring timestamps failed(%d). ignored\n", err);
}
コード例 #2
0
int aufs_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *st)
{
	int err;
	aufs_bindex_t bindex;
	struct inode *inode;
	struct dentry *h_dentry;
	struct super_block *sb;
	unsigned int mnt_flags;

	LKTRTrace("%.*s\n", AuDLNPair(dentry));

	inode = dentry->d_inode;
	sb = dentry->d_sb;
	aufs_read_lock(dentry, AuLock_FLUSH | AuLock_IR);

	/* todo: refine it */
	mnt_flags = au_mntflags(sb);
	if (au_opt_test(mnt_flags, PLINK) && au_plink_test(sb, inode))
		goto plinked;

	h_dentry = au_h_dget_any(dentry, &bindex);
	err = PTR_ERR(h_dentry);
	if (IS_ERR(h_dentry))
		goto out;

	err = -ENOENT;
	if (h_dentry->d_inode)
		err = vfsub_getattr(au_sbr_mnt(sb, bindex), h_dentry, st,
				    au_test_dlgt(mnt_flags));
	dput(h_dentry);
	if (!err) {
		au_cpup_attr_all(inode);
	plinked:
		generic_fillattr(inode, st);
	}

 out:
	aufs_read_unlock(dentry, AuLock_IR);
	AuTraceErr(err);
	return err;
}
コード例 #3
0
ファイル: i_op_add.c プロジェクト: wosigh/patches
/*
 * final procedure of adding a new entry, except link(2).
 * remove whiteout, instantiate, copyup the parent dir's times and size
 * and update version.
 * if it failed, re-create the removed whiteout.
 */
static int epilog(struct inode *dir, aufs_bindex_t bindex,
		  struct dentry *wh_dentry, struct dentry *dentry)
{
	int err, rerr;
	aufs_bindex_t bwh;
	struct inode *inode, *h_dir;
	struct dentry *wh;
	struct au_ndx ndx;
	struct super_block *sb;

	LKTRTrace("wh %p, %.*s\n", wh_dentry, AuDLNPair(dentry));

	sb = dentry->d_sb;
	bwh = -1;
	if (wh_dentry) {
		h_dir = wh_dentry->d_parent->d_inode; /* dir inode is locked */
		IMustLock(h_dir);
		AuDebugOn(au_h_iptr(dir, bindex) != h_dir);
		bwh = au_dbwh(dentry);
		err = au_wh_unlink_dentry(au_hi(dir, bindex), wh_dentry, dentry,
					  /*dlgt*/0);
		if (unlikely(err))
			goto out;
	}

	inode = au_new_inode(dentry, /*must_new*/1);
	if (!IS_ERR(inode)) {
		d_instantiate(dentry, inode);
		dir = dentry->d_parent->d_inode; /* dir inode is locked */
		IMustLock(dir);
		/* or always cpup dir mtime? */
		if (au_ibstart(dir) == au_dbstart(dentry))
			au_cpup_attr_timesizes(dir);
		dir->i_version++;
		return 0; /* success */
	}

	err = PTR_ERR(inode);
	if (!wh_dentry)
		goto out;

	/* revert */
	ndx.flags = 0;
	if (au_test_dlgt(au_mntflags(sb)))
		au_fset_ndx(ndx.flags, DLGT);
	ndx.nfsmnt = au_nfsmnt(sb, bwh);
	ndx.nd = NULL;
	/* ndx.br = NULL; */
	/* dir inode is locked */
	wh = au_wh_create(dentry, bwh, wh_dentry->d_parent, &ndx);
	rerr = PTR_ERR(wh);
	if (IS_ERR(wh)) {
		AuIOErr("%.*s reverting whiteout failed(%d, %d)\n",
			AuDLNPair(dentry), err, rerr);
		err = -EIO;
	} else
		dput(wh);

 out:
	AuTraceErr(err);
	return err;
}
コード例 #4
0
ファイル: i_op_add.c プロジェクト: wosigh/patches
/*
 * initial procedure of adding a new entry.
 * prepare writable branch and the parent dir, lock it,
 * lookup whiteout for the new entry.
 */
static struct dentry*
lock_hdir_lkup_wh(struct dentry *dentry, struct au_dtime *dt,
		  struct dentry *src_dentry, struct au_pin *pin,
		  struct au_wr_dir_args *wr_dir_args)
{
	struct dentry *wh_dentry, *h_parent;
	struct super_block *sb;
	int err;
	unsigned int mnt_flags;
	unsigned char pin_flags;
	aufs_bindex_t bstart, bcpup;
	struct au_ndx ndx;

	LKTRTrace("%.*s, src %p\n", AuDLNPair(dentry), src_dentry);

	bstart = au_dbstart(dentry);
	err = au_wr_dir(dentry, src_dentry, wr_dir_args);
	bcpup = err;
	wh_dentry = ERR_PTR(err);
	if (unlikely(err < 0))
		goto out;

	sb = dentry->d_sb;
	mnt_flags = au_mntflags(sb);
	pin_flags = AuPin_DI_LOCKED | AuPin_MNT_WRITE;
	if (dt && au_opt_test(mnt_flags, UDBA_INOTIFY))
		au_fset_pin(pin_flags, DO_GPARENT);
	err = au_pin(pin, dentry, bcpup, pin_flags);
	wh_dentry = ERR_PTR(err);
	if (unlikely(err))
		goto out;

	ndx.nfsmnt = au_nfsmnt(sb, bcpup);
	ndx.flags = 0;
	if (au_test_dlgt(mnt_flags))
		au_fset_ndx(ndx.flags, DLGT);
	ndx.nd = NULL;
	/* ndx.br = NULL; */
	/* ndx.nd_file = NULL; */

	h_parent = au_pinned_h_parent(pin);
	if (!au_opt_test(mnt_flags, UDBA_NONE) && au_dbstart(dentry) == bcpup) {
		struct nameidata nd;

		if (ndx.nfsmnt) {
			/* todo: dirty? */
			ndx.nd = &nd;
			ndx.br = au_sbr(sb, bcpup);
			memset(&nd, 0, sizeof(nd));
			nd.flags = LOOKUP_CREATE;
			nd.intent.open.flags = O_EXCL;
		}
		err = au_may_add(dentry, bcpup, h_parent,
				 au_ftest_wrdir(wr_dir_args->flags, ISDIR),
				 &ndx);
		wh_dentry = ERR_PTR(err);
		if (unlikely(err))
			goto out_unpin;
		ndx.nd = NULL;
		ndx.br = NULL;
	}

	if (dt)
		au_dtime_store(dt, au_pinned_parent(pin), h_parent,
			       au_pinned_hdir(pin), au_pinned_hgdir(pin));

	wh_dentry = NULL;
	if (/* bcpup != bstart || */ bcpup != au_dbwh(dentry))
		goto out; /* success */

	wh_dentry = au_wh_lkup(h_parent, &dentry->d_name, &ndx);

 out_unpin:
	if (IS_ERR(wh_dentry))
		au_unpin(pin);
 out:
	AuTraceErrPtr(wh_dentry);
	return wh_dentry;
}