Commit 219c0c45 authored by Jinshan Xiong's avatar Jinshan Xiong Committed by Greg Kroah-Hartman
Browse files

staging: lustre: llite: clear LLIF_DATA_MODIFIED in atomic



This flag should be cleared atomically after the op_data flag
MDS_DATA_MODIFIED is packed. Otherwise, if there exists an
operation to dirty the file again, the state may be missed on
the MDT.

Stop using spin lock lli_lock to protect operations of changing
file flags; using bit operations instead.

Signed-off-by: default avatarJinshan Xiong <jinshan.xiong@intel.com>
Signed-off-by: default avatarJames Simmons <uja.ornl@yahoo.com>
Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-6377
Reviewed-on: http://review.whamcloud.com/14100


Reviewed-by: default avatarJohn L. Hammond <john.hammond@intel.com>
Reviewed-by: default avatarOleg Drokin <oleg.drokin@intel.com>
Signed-off-by: default avatarJames Simmons <jsimmons@infradead.org>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 9aa7c90d
Loading
Loading
Loading
Loading
+23 −38
Original line number Diff line number Diff line
@@ -76,42 +76,36 @@ static void ll_file_data_put(struct ll_file_data *fd)
		kmem_cache_free(ll_file_data_slab, fd);
}

void ll_pack_inode2opdata(struct inode *inode, struct md_op_data *op_data,
			  struct lustre_handle *fh)
/**
 * Packs all the attributes into @op_data for the CLOSE rpc.
 */
static void ll_prepare_close(struct inode *inode, struct md_op_data *op_data,
			     struct obd_client_handle *och)
{
	op_data->op_fid1 = ll_i2info(inode)->lli_fid;
	struct ll_inode_info *lli = ll_i2info(inode);

	ll_prep_md_op_data(op_data, inode, NULL, NULL,
			   0, 0, LUSTRE_OPC_ANY, NULL);

	op_data->op_attr.ia_mode = inode->i_mode;
	op_data->op_attr.ia_atime = inode->i_atime;
	op_data->op_attr.ia_mtime = inode->i_mtime;
	op_data->op_attr.ia_ctime = inode->i_ctime;
	op_data->op_attr.ia_size = i_size_read(inode);
	op_data->op_attr.ia_valid |= ATTR_MODE | ATTR_ATIME | ATTR_ATIME_SET |
				     ATTR_MTIME | ATTR_MTIME_SET |
				     ATTR_CTIME | ATTR_CTIME_SET;
	op_data->op_attr_blocks = inode->i_blocks;
	op_data->op_attr_flags = ll_inode_to_ext_flags(inode->i_flags);
	if (fh)
		op_data->op_handle = *fh;

	if (ll_i2info(inode)->lli_flags & LLIF_DATA_MODIFIED)
		op_data->op_bias |= MDS_DATA_MODIFIED;
}
	op_data->op_handle = och->och_fh;

/**
 * Packs all the attributes into @op_data for the CLOSE rpc.
	/*
	 * For HSM: if inode data has been modified, pack it so that
	 * MDT can set data dirty flag in the archive.
	 */
static void ll_prepare_close(struct inode *inode, struct md_op_data *op_data,
			     struct obd_client_handle *och)
{
	op_data->op_attr.ia_valid = ATTR_MODE | ATTR_ATIME | ATTR_ATIME_SET |
					ATTR_MTIME | ATTR_MTIME_SET |
					ATTR_CTIME | ATTR_CTIME_SET;

	if (!(och->och_flags & FMODE_WRITE))
		goto out;

	op_data->op_attr.ia_valid |= ATTR_SIZE | ATTR_BLOCKS;
out:
	ll_pack_inode2opdata(inode, op_data, &och->och_fh);
	ll_prep_md_op_data(op_data, inode, NULL, NULL,
			   0, 0, LUSTRE_OPC_ANY, NULL);
	if (och->och_flags & FMODE_WRITE &&
	    test_and_clear_bit(LLIF_DATA_MODIFIED, &lli->lli_flags))
		op_data->op_bias |= MDS_DATA_MODIFIED;
}

/**
@@ -182,17 +176,6 @@ static int ll_close_inode_openhandle(struct obd_export *md_exp,
		       PFID(ll_inode2fid(inode)), rc);
	}

	/* DATA_MODIFIED flag was successfully sent on close, cancel data
	 * modification flag.
	 */
	if (rc == 0 && (op_data->op_bias & MDS_DATA_MODIFIED)) {
		struct ll_inode_info *lli = ll_i2info(inode);

		spin_lock(&lli->lli_lock);
		lli->lli_flags &= ~LLIF_DATA_MODIFIED;
		spin_unlock(&lli->lli_lock);
	}

	if (op_data->op_bias & (MDS_HSM_RELEASE | MDS_CLOSE_LAYOUT_SWAP) &&
	    !rc) {
		struct mdt_body *body;
@@ -2889,6 +2872,8 @@ static int ll_inode_revalidate(struct dentry *dentry, __u64 ibits)
		LTIME_S(inode->i_mtime) = ll_i2info(inode)->lli_mtime;
		LTIME_S(inode->i_ctime) = ll_i2info(inode)->lli_ctime;
	} else {
		struct ll_inode_info *lli = ll_i2info(inode);

		/* In case of restore, the MDT has the right size and has
		 * already send it back without granting the layout lock,
		 * inode is up-to-date so glimpse is useless.
@@ -2896,7 +2881,7 @@ static int ll_inode_revalidate(struct dentry *dentry, __u64 ibits)
		 * restore the MDT holds the layout lock so the glimpse will
		 * block up to the end of restore (getattr will block)
		 */
		if (!(ll_i2info(inode)->lli_flags & LLIF_FILE_RESTORING))
		if (!test_bit(LLIF_FILE_RESTORING, &lli->lli_flags))
			rc = ll_glimpse_size(inode);
	}
	return rc;
+5 −7
Original line number Diff line number Diff line
@@ -97,20 +97,20 @@ struct ll_grouplock {
	unsigned long	 lg_gid;
};

enum lli_flags {
enum ll_file_flags {
	/* File data is modified. */
	LLIF_DATA_MODIFIED	= BIT(0),
	LLIF_DATA_MODIFIED	= 0,
	/* File is being restored */
	LLIF_FILE_RESTORING	= BIT(1),
	LLIF_FILE_RESTORING	= 1,
	/* Xattr cache is attached to the file */
	LLIF_XATTR_CACHE	= BIT(2),
	LLIF_XATTR_CACHE	= 2,
};

struct ll_inode_info {
	__u32				lli_inode_magic;
	__u32				lli_flags;

	spinlock_t			lli_lock;
	unsigned long			lli_flags;
	struct posix_acl		*lli_posix_acl;

	/* identifying fields for both metadata and data stacks. */
@@ -740,8 +740,6 @@ int ll_file_open(struct inode *inode, struct file *file);
int ll_file_release(struct inode *inode, struct file *file);
int ll_release_openhandle(struct inode *, struct lookup_intent *);
int ll_md_real_close(struct inode *inode, fmode_t fmode);
void ll_pack_inode2opdata(struct inode *inode, struct md_op_data *op_data,
			  struct lustre_handle *fh);
int ll_getattr(struct vfsmount *mnt, struct dentry *de, struct kstat *stat);
struct posix_acl *ll_get_acl(struct inode *inode, int type);
int ll_migrate(struct inode *parent, struct file *file, int mdtidx,
+1 −17
Original line number Diff line number Diff line
@@ -1532,9 +1532,6 @@ int ll_setattr_raw(struct dentry *dentry, struct iattr *attr, bool hsm_import)
			 * modified, flag it.
			 */
			attr->ia_valid |= MDS_OPEN_OWNEROVERRIDE;
			spin_lock(&lli->lli_lock);
			lli->lli_flags |= LLIF_DATA_MODIFIED;
			spin_unlock(&lli->lli_lock);
			op_data->op_bias |= MDS_DATA_MODIFIED;
		}
	}
@@ -1545,13 +1542,6 @@ int ll_setattr_raw(struct dentry *dentry, struct iattr *attr, bool hsm_import)
	if (rc)
		goto out;

	/* RPC to MDT is sent, cancel data modification flag */
	if (op_data->op_bias & MDS_DATA_MODIFIED) {
		spin_lock(&lli->lli_lock);
		lli->lli_flags &= ~LLIF_DATA_MODIFIED;
		spin_unlock(&lli->lli_lock);
	}

	if (!S_ISREG(inode->i_mode) || file_is_released) {
		rc = 0;
		goto out;
@@ -1822,7 +1812,7 @@ int ll_update_inode(struct inode *inode, struct lustre_md *md)

	if (body->mbo_valid & OBD_MD_TSTATE) {
		if (body->mbo_t_state & MS_RESTORE)
			lli->lli_flags |= LLIF_FILE_RESTORING;
			set_bit(LLIF_FILE_RESTORING, &lli->lli_flags);
	}

	return 0;
@@ -2331,8 +2321,6 @@ struct md_op_data *ll_prep_md_op_data(struct md_op_data *op_data,
	op_data->op_fsuid = from_kuid(&init_user_ns, current_fsuid());
	op_data->op_fsgid = from_kgid(&init_user_ns, current_fsgid());
	op_data->op_cap = cfs_curproc_cap_pack();
	op_data->op_bias = 0;
	op_data->op_cli_flags = 0;
	if ((opc == LUSTRE_OPC_CREATE) && name &&
	    filename_is_volatile(name, namelen, &op_data->op_mds))
		op_data->op_bias |= MDS_CREATE_VOLATILE;
@@ -2340,10 +2328,6 @@ struct md_op_data *ll_prep_md_op_data(struct md_op_data *op_data,
		op_data->op_mds = 0;
	op_data->op_data = data;

	/* When called by ll_setattr_raw, file is i1. */
	if (ll_i2info(i1)->lli_flags & LLIF_DATA_MODIFIED)
		op_data->op_bias |= MDS_DATA_MODIFIED;

	return op_data;
}

+2 −5
Original line number Diff line number Diff line
@@ -215,11 +215,8 @@ static int ll_page_mkwrite0(struct vm_area_struct *vma, struct page *vmpage,
			result = -EAGAIN;
		}

		if (result == 0) {
			spin_lock(&lli->lli_lock);
			lli->lli_flags |= LLIF_DATA_MODIFIED;
			spin_unlock(&lli->lli_lock);
		}
		if (!result)
			set_bit(LLIF_DATA_MODIFIED, &lli->lli_flags);
	}

out_io:
+3 −7
Original line number Diff line number Diff line
@@ -329,8 +329,8 @@ static void vvp_io_fini(const struct lu_env *env, const struct cl_io_slice *ios)
			       vio->vui_layout_gen, gen);
			/* today successful restore is the only possible case */
			/* restore was done, clear restoring state */
			ll_i2info(vvp_object_inode(obj))->lli_flags &=
				~LLIF_FILE_RESTORING;
			clear_bit(LLIF_FILE_RESTORING,
				  &ll_i2info(inode)->lli_flags);
		}
	}
}
@@ -982,11 +982,7 @@ static int vvp_io_write_start(const struct lu_env *env,
		}
	}
	if (result > 0) {
		struct ll_inode_info *lli = ll_i2info(inode);

		spin_lock(&lli->lli_lock);
		lli->lli_flags |= LLIF_DATA_MODIFIED;
		spin_unlock(&lli->lli_lock);
		set_bit(LLIF_DATA_MODIFIED, &(ll_i2info(inode))->lli_flags);

		if (result < cnt)
			io->ci_continue = 0;
Loading