Commit fcb5e3fa authored by Chuck Lever's avatar Chuck Lever
Browse files

NFSD: Move fill_pre_wcc() and fill_post_wcc()



These functions are related to file handle processing and have
nothing to do with XDR encoding or decoding. Also they are no longer
NFSv3-specific. As a clean-up, move their definitions to a more
appropriate location. WCC is also an NFSv3-specific term, so rename
them as general-purpose helpers.

Signed-off-by: default avatarChuck Lever <chuck.lever@oracle.com>
parent 58f258f6
Loading
Loading
Loading
Loading
+0 −55
Original line number Diff line number Diff line
@@ -487,61 +487,6 @@ svcxdr_encode_wcc_data(struct svc_rqst *rqstp, struct xdr_stream *xdr,
	return true;
}

/*
 * Fill in the pre_op attr for the wcc data
 */
void fill_pre_wcc(struct svc_fh *fhp)
{
	struct inode    *inode;
	struct kstat	stat;
	bool v4 = (fhp->fh_maxsize == NFS4_FHSIZE);
	__be32 err;

	if (fhp->fh_no_wcc || fhp->fh_pre_saved)
		return;
	inode = d_inode(fhp->fh_dentry);
	err = fh_getattr(fhp, &stat);
	if (err) {
		/* Grab the times from inode anyway */
		stat.mtime = inode->i_mtime;
		stat.ctime = inode->i_ctime;
		stat.size  = inode->i_size;
	}
	if (v4)
		fhp->fh_pre_change = nfsd4_change_attribute(&stat, inode);

	fhp->fh_pre_mtime = stat.mtime;
	fhp->fh_pre_ctime = stat.ctime;
	fhp->fh_pre_size  = stat.size;
	fhp->fh_pre_saved = true;
}

/*
 * Fill in the post_op attr for the wcc data
 */
void fill_post_wcc(struct svc_fh *fhp)
{
	bool v4 = (fhp->fh_maxsize == NFS4_FHSIZE);
	struct inode *inode = d_inode(fhp->fh_dentry);
	__be32 err;

	if (fhp->fh_no_wcc)
		return;

	if (fhp->fh_post_saved)
		printk("nfsd: inode locked twice during operation.\n");

	err = fh_getattr(fhp, &fhp->fh_post_attr);
	if (err) {
		fhp->fh_post_saved = false;
		fhp->fh_post_attr.ctime = inode->i_ctime;
	} else
		fhp->fh_post_saved = true;
	if (v4)
		fhp->fh_post_change =
			nfsd4_change_attribute(&fhp->fh_post_attr, inode);
}

/*
 * XDR decode functions
 */
+1 −1
Original line number Diff line number Diff line
@@ -2530,7 +2530,7 @@ nfsd4_proc_compound(struct svc_rqst *rqstp)
			goto encode_op;
		}

		fh_clear_wcc(current_fh);
		fh_clear_pre_post_attrs(current_fh);

		/* If op is non-idempotent */
		if (op->opdesc->op_flags & OP_MODIFIES_SOMETHING) {
+65 −1
Original line number Diff line number Diff line
@@ -611,6 +611,70 @@ fh_update(struct svc_fh *fhp)
	return nfserr_serverfault;
}

#ifdef CONFIG_NFSD_V3

/**
 * fh_fill_pre_attrs - Fill in pre-op attributes
 * @fhp: file handle to be updated
 *
 */
void fh_fill_pre_attrs(struct svc_fh *fhp)
{
	bool v4 = (fhp->fh_maxsize == NFS4_FHSIZE);
	struct inode *inode;
	struct kstat stat;
	__be32 err;

	if (fhp->fh_no_wcc || fhp->fh_pre_saved)
		return;

	inode = d_inode(fhp->fh_dentry);
	err = fh_getattr(fhp, &stat);
	if (err) {
		/* Grab the times from inode anyway */
		stat.mtime = inode->i_mtime;
		stat.ctime = inode->i_ctime;
		stat.size  = inode->i_size;
	}
	if (v4)
		fhp->fh_pre_change = nfsd4_change_attribute(&stat, inode);

	fhp->fh_pre_mtime = stat.mtime;
	fhp->fh_pre_ctime = stat.ctime;
	fhp->fh_pre_size  = stat.size;
	fhp->fh_pre_saved = true;
}

/**
 * fh_fill_post_attrs - Fill in post-op attributes
 * @fhp: file handle to be updated
 *
 */
void fh_fill_post_attrs(struct svc_fh *fhp)
{
	bool v4 = (fhp->fh_maxsize == NFS4_FHSIZE);
	struct inode *inode = d_inode(fhp->fh_dentry);
	__be32 err;

	if (fhp->fh_no_wcc)
		return;

	if (fhp->fh_post_saved)
		printk("nfsd: inode locked twice during operation.\n");

	err = fh_getattr(fhp, &fhp->fh_post_attr);
	if (err) {
		fhp->fh_post_saved = false;
		fhp->fh_post_attr.ctime = inode->i_ctime;
	} else
		fhp->fh_post_saved = true;
	if (v4)
		fhp->fh_post_change =
			nfsd4_change_attribute(&fhp->fh_post_attr, inode);
}

#endif /* CONFIG_NFSD_V3 */

/*
 * Release a file handle.
 */
@@ -623,7 +687,7 @@ fh_put(struct svc_fh *fhp)
		fh_unlock(fhp);
		fhp->fh_dentry = NULL;
		dput(dentry);
		fh_clear_wcc(fhp);
		fh_clear_pre_post_attrs(fhp);
	}
	fh_drop_write(fhp);
	if (exp) {
+26 −14
Original line number Diff line number Diff line
@@ -284,12 +284,13 @@ static inline u32 knfsd_fh_hash(const struct knfsd_fh *fh)
#endif

#ifdef CONFIG_NFSD_V3
/*
 * The wcc data stored in current_fh should be cleared
 * between compound ops.

/**
 * fh_clear_pre_post_attrs - Reset pre/post attributes
 * @fhp: file handle to be updated
 *
 */
static inline void
fh_clear_wcc(struct svc_fh *fhp)
static inline void fh_clear_pre_post_attrs(struct svc_fh *fhp)
{
	fhp->fh_post_saved = false;
	fhp->fh_pre_saved = false;
@@ -323,13 +324,24 @@ static inline u64 nfsd4_change_attribute(struct kstat *stat,
		return time_to_chattr(&stat->ctime);
}

extern void fill_pre_wcc(struct svc_fh *fhp);
extern void fill_post_wcc(struct svc_fh *fhp);
#else
#define fh_clear_wcc(ignored)
#define fill_pre_wcc(ignored)
#define fill_post_wcc(notused)
#endif /* CONFIG_NFSD_V3 */
extern void fh_fill_pre_attrs(struct svc_fh *fhp);
extern void fh_fill_post_attrs(struct svc_fh *fhp);

#else /* !CONFIG_NFSD_V3 */

static inline void fh_clear_pre_post_attrs(struct svc_fh *fhp)
{
}

static inline void fh_fill_pre_attrs(struct svc_fh *fhp)
{
}

static inline void fh_fill_post_attrs(struct svc_fh *fhp)
{
}

#endif /* !CONFIG_NFSD_V3 */


/*
@@ -355,7 +367,7 @@ fh_lock_nested(struct svc_fh *fhp, unsigned int subclass)

	inode = d_inode(dentry);
	inode_lock_nested(inode, subclass);
	fill_pre_wcc(fhp);
	fh_fill_pre_attrs(fhp);
	fhp->fh_locked = true;
}

@@ -372,7 +384,7 @@ static inline void
fh_unlock(struct svc_fh *fhp)
{
	if (fhp->fh_locked) {
		fill_post_wcc(fhp);
		fh_fill_post_attrs(fhp);
		inode_unlock(d_inode(fhp->fh_dentry));
		fhp->fh_locked = false;
	}
+4 −4
Original line number Diff line number Diff line
@@ -1755,8 +1755,8 @@ nfsd_rename(struct svc_rqst *rqstp, struct svc_fh *ffhp, char *fname, int flen,
	 * so do it by hand */
	trap = lock_rename(tdentry, fdentry);
	ffhp->fh_locked = tfhp->fh_locked = true;
	fill_pre_wcc(ffhp);
	fill_pre_wcc(tfhp);
	fh_fill_pre_attrs(ffhp);
	fh_fill_pre_attrs(tfhp);

	odentry = lookup_one_len(fname, fdentry, flen);
	host_err = PTR_ERR(odentry);
@@ -1816,8 +1816,8 @@ nfsd_rename(struct svc_rqst *rqstp, struct svc_fh *ffhp, char *fname, int flen,
	 * were the same, so again we do it by hand.
	 */
	if (!close_cached) {
		fill_post_wcc(ffhp);
		fill_post_wcc(tfhp);
		fh_fill_post_attrs(ffhp);
		fh_fill_post_attrs(tfhp);
	}
	unlock_rename(tdentry, fdentry);
	ffhp->fh_locked = tfhp->fh_locked = false;