Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

staging/lustre/hsm: Implementation of exclusive open

Proposed way to do exclusive open:

0. First of all, we have to perform most of the work in kernel space;

1. Client exclusively opens the file with IT_RELEASE_OPEN.
1.1 exclusive open means the open will fail if the file is being opened by somebody else;

2. the MDT will handle IT_RELEASE as follows:
2.1 Revoke OPEN_LOCK on this file, just request EX mode of MDS_INODELOCK_OPEN lock and
release it;
2.2 Acquire a rwsem, say open_rwsem, with write mode before trying to the file; for the
normal open, it should acquire read mode of open_rwsem;
2.3 Check if the file is already being opened by others, if not return with -EBUSY;
2.4 Check if the file can be released;
2.5 Set a special flag in struct mdt_file_data to mark this open is exclusive;
2.5 Release open rwsem.

>From now on, if the file is opened by others, it will mark mdt_file_data that the
exclusive open is broken.

3. Client: if IT_RELEASE_OPEN is finished successfully, and do followings:
3.1 Acquire full PW or EX extent lock to flush dirty cache;
3.2 Pack the handle of layout lock, data version and other attars;
3.3 Close the file with IT_RELEASE_CLOSE.

4. Back to MDT to handle IT_RELEASE CLOSE:
4.1 Grab the open_rwsem
4.2 Check if the exclusive open has ever been broken, in that case, the RELEASE process
will fail;
4.3 Verify the data version matches archive;
4.4 Grab EX layout lock
4.5 Swap the layout
4.6 Release EX layout lock
4.7 Close the exclusive open

Basically we avoid granting EX layout lock back to client and introduce exclusive open so
that we know it if the file has ever being accessed. I hope this can simplify things
a little bit. Also, exclusive open can be used to implement file lease.

In this patch, a framework of lease is implemented. However,
only exclusive lease is supported right now.

To apply a lease, MDS_OPEN_LEASE must be set to open the file, EX
mode open lock is returned to the client side to hold a lease. From
that time on, if this file is opened again by other processes, the
open lock will be revoked so the client who holds the lease will
know the lease is already broken by checking that open lock.

To release a lease, normal close is used. The client will revoke the
open lock before sending CLOSE request.

Lease can be applied in two ways. ll_lease_open()/close() can be
called directly if the lease holder is in kernel space; or if the
lease holder lives in user space, it has to open the file first and
then use ioctl() with command LL_IOC_SET_LEASE to apply a lease. The
lease holder has to poll the lease status itself.

Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-2919
Lustre-change: http://review.whamcloud.com/6730


Signed-off-by: default avatarJinshan Xiong <jinshan.xiong@intel.com>
Signed-off-by: default avatarJohn L. Hammond <john.hammond@intel.com>
Reviewed-by: default avatarAndreas Dilger <andreas.dilger@intel.com>
Reviewed-by: default avatarOleg Drokin <oleg.drokin@intel.com>
Signed-off-by: default avatarPeng Tao <bergwolf@gmail.com>
Signed-off-by: default avatarAndreas Dilger <andreas.dilger@intel.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 86c17c0b
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -52,8 +52,8 @@ struct lustre_intent_data {

struct lookup_intent {
	int     it_op;
	int     it_flags;
	int     it_create_mode;
	__u64   it_flags;
	union {
		struct lustre_intent_data lustre;
	} d;
+5 −0
Original line number Diff line number Diff line
@@ -2120,6 +2120,7 @@ extern void lustre_swab_generic_32s (__u32 *val);
#define DISP_ENQ_OPEN_REF    0x00800000
#define DISP_ENQ_CREATE_REF  0x01000000
#define DISP_OPEN_LOCK       0x02000000
#define DISP_OPEN_LEASE      0x04000000

/* INODE LOCK PARTS */
#define MDS_INODELOCK_LOOKUP 0x000001       /* dentry, mode, owner, group */
@@ -2373,6 +2374,10 @@ extern void lustre_swab_mdt_rec_setattr (struct mdt_rec_setattr *sa);
					      * hsm restore) */
#define MDS_OPEN_VOLATILE   0400000000000ULL /* File is volatile = created
						unlinked */
#define MDS_OPEN_LEASE	   01000000000000ULL /* Open the file and grant lease
					      * delegation, succeed if it's not
					      * being opened with conflict mode.
					      */

/* permission for create non-directory file */
#define MAY_CREATE      (1 << 7)
+3 −0
Original line number Diff line number Diff line
@@ -245,6 +245,9 @@ struct ost_id {
#define LL_IOC_LMV_GETSTRIPE	    _IOWR('f', 241, struct lmv_user_md)
#define LL_IOC_REMOVE_ENTRY	    _IOWR('f', 242, __u64)

#define LL_IOC_SET_LEASE		_IOWR('f', 243, long)
#define LL_IOC_GET_LEASE		_IO('f', 244)

#define LL_STATFS_LMV	   1
#define LL_STATFS_LOV	   2
#define LL_STATFS_NODELAY	4
+10 −2
Original line number Diff line number Diff line
@@ -35,7 +35,7 @@
#ifndef LDLM_ALL_FLAGS_MASK

/** l_flags bits marked as "all_flags" bits */
#define LDLM_FL_ALL_FLAGS_MASK          0x007FFFFFC08F132FULL
#define LDLM_FL_ALL_FLAGS_MASK          0x00FFFFFFC08F132FULL

/** l_flags bits marked as "ast" bits */
#define LDLM_FL_AST_MASK                0x0000000080000000ULL
@@ -53,7 +53,7 @@
#define LDLM_FL_INHERIT_MASK            0x0000000000800000ULL

/** l_flags bits marked as "local_only" bits */
#define LDLM_FL_LOCAL_ONLY_MASK         0x007FFFFF00000000ULL
#define LDLM_FL_LOCAL_ONLY_MASK         0x00FFFFFF00000000ULL

/** l_flags bits marked as "on_wire" bits */
#define LDLM_FL_ON_WIRE_MASK            0x00000000C08F132FULL
@@ -358,6 +358,12 @@
#define ldlm_set_ns_srv(_l)             LDLM_SET_FLAG((  _l), 1ULL << 54)
#define ldlm_clear_ns_srv(_l)           LDLM_CLEAR_FLAG((_l), 1ULL << 54)

/** Flag whether this lock can be reused. Used by exclusive open. */
#define LDLM_FL_EXCL                    0x0080000000000000ULL /* bit  55 */
#define ldlm_is_excl(_l)                LDLM_TEST_FLAG((_l), 1ULL << 55)
#define ldlm_set_excl(_l)               LDLM_SET_FLAG((_l), 1ULL << 55)
#define ldlm_clear_excl(_l)             LDLM_CLEAR_FLAG((_l), 1ULL << 55)

/** test for ldlm_lock flag bit set */
#define LDLM_TEST_FLAG(_l, _b)        (((_l)->l_flags & (_b)) != 0)

@@ -414,6 +420,7 @@ static int hf_lustre_ldlm_fl_server_lock = -1;
static int hf_lustre_ldlm_fl_res_locked          = -1;
static int hf_lustre_ldlm_fl_waited              = -1;
static int hf_lustre_ldlm_fl_ns_srv              = -1;
static int hf_lustre_ldlm_fl_excl                = -1;

const value_string lustre_ldlm_flags_vals[] = {
  {LDLM_FL_LOCK_CHANGED,        "LDLM_FL_LOCK_CHANGED"},
@@ -454,6 +461,7 @@ const value_string lustre_ldlm_flags_vals[] = {
  {LDLM_FL_RES_LOCKED,          "LDLM_FL_RES_LOCKED"},
  {LDLM_FL_WAITED,              "LDLM_FL_WAITED"},
  {LDLM_FL_NS_SRV,              "LDLM_FL_NS_SRV"},
  {LDLM_FL_EXCL,                "LDLM_FL_EXCL"},
  { 0, NULL }
};
#endif /*  WIRESHARK_COMPILE */
+6 −5
Original line number Diff line number Diff line
@@ -84,6 +84,7 @@ struct obd_client_handle {
	struct lustre_handle	 och_fh;
	struct lu_fid		 och_fid;
	struct md_open_data	*och_mod;
	struct lustre_handle	 och_lease_handle; /* open lock for lease */
	__u32			 och_magic;
	fmode_t			 och_flags;
};
Loading