Whamcloud - gitweb
LU-11546 utils: enable large_dir for ldiskfs
[fs/lustre-release.git] / lustre / utils / liblustreapi_lease.c
1 /*
2  * LGPL HEADER START
3  *
4  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5  *
6  * (C) Copyright 2014 Commissariat a l'energie atomique et aux energies
7  *     alternatives
8  *
9  * Copyright (c) 2017, Intel Corporation.
10  *
11  * All rights reserved. This program and the accompanying materials
12  * are made available under the terms of the GNU Lesser General Public License
13  * (LGPL) version 2.1 or (at your discretion) any later version.
14  * (LGPL) version 2.1 accompanies this distribution, and is available at
15  * http://www.gnu.org/licenses/lgpl-2.1.html
16  *
17  * This library is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20  * Lesser General Public License for more details.
21  *
22  * LGPL HEADER END
23  */
24 /*
25  * lustre/utils/liblustreapi_lease.c
26  *
27  * lustreapi library for file leases
28  *
29  * Author: Henri Doreau <henri.doreau@cea.fr>
30  */
31
32 #include <unistd.h>
33 #include <fcntl.h>
34 #include <sys/ioctl.h>
35 #include <errno.h>
36 #include <lustre/lustreapi.h>
37 #include "lustreapi_internal.h"
38
39 static inline const char *lease_mode2str(enum ll_lease_mode mode)
40 {
41         switch (mode) {
42         case LL_LEASE_WRLCK: return "WRITE";
43         case LL_LEASE_RDLCK: return "READ";
44         case LL_LEASE_UNLCK: return "UNLOCK";
45         }
46         return "???";
47 }
48
49 /**
50  * Extend lease set support.
51  *
52  * \param fd    File to set lease on.
53  * \param data  ll_ioc_lease data.
54  *
55  * For setting lease lock, it will return zero for success. For unlock, it will
56  * return the lock type it owned for succuess.
57  *
58  * \retval >= 0 on success.
59  * \retval -errno on error.
60  */
61 int llapi_lease_set(int fd, const struct ll_ioc_lease *data)
62 {
63         int rc;
64
65         rc = ioctl(fd, LL_IOC_SET_LEASE, data);
66         if (rc < 0) {
67                 rc = -errno;
68
69                 llapi_error(LLAPI_MSG_ERROR, rc, "cannot get %s lease, ext %x",
70                             lease_mode2str(data->lil_mode), data->lil_flags);
71         }
72         return rc;
73 }
74
75 /**
76  * Acquire a lease on an open file.
77  *
78  * \param fd    File to get the lease on.
79  * \param mode  Lease mode, either LL_LEASE_RDLCK or LL_LEASE_WRLCK.
80  *
81  * \see llapi_lease_release().
82  *
83  * \retval >= 0 on success.
84  * \retval -errno on error.
85  */
86 int llapi_lease_acquire(int fd, enum ll_lease_mode mode)
87 {
88         struct ll_ioc_lease data = { .lil_mode = mode };
89         int rc;
90
91         if (mode != LL_LEASE_RDLCK && mode != LL_LEASE_WRLCK)
92                 return -EINVAL;
93
94         rc = llapi_lease_set(fd, &data);
95         if (rc == -ENOTTY) {
96                 rc = ioctl(fd, LL_IOC_SET_LEASE_OLD, mode);
97                 if (rc < 0)
98                         rc = -errno;
99         }
100
101         return rc;
102 }
103
104 /**
105  * Release a lease.
106  *
107  * \param fd    File to remove the lease from.
108  *
109  * \retval type of the lease that was removed (LL_LEASE_READ or LL_LEASE_WRITE).
110  * \retval 0 if no lease was present.
111  * \retval -errno on error.
112  */
113 int llapi_lease_release(int fd)
114 {
115         struct ll_ioc_lease data = { .lil_mode = LL_LEASE_UNLCK };
116
117         return llapi_lease_set(fd, &data);
118 }
119
120 /**
121  * Release a lease with intent operation. This API will release the lease
122  * and execute the intent operation atomically.
123  *
124  * \param fd    File to remove the lease from.
125  *
126  * \retval type of the lease that was removed (LL_LEASE_READ or LL_LEASE_WRITE).
127  * \retval 0 if no lease was present.
128  * \retval -EBUSY lease broken, intent operation not executed.
129  * \retval -errno on error.
130  */
131 int llapi_lease_release_intent(int fd, struct ll_ioc_lease *data)
132 {
133         if (data->lil_mode != LL_LEASE_UNLCK)
134                 return -EINVAL;
135
136         return llapi_lease_set(fd, data);
137 }
138
139 /**
140  * Check if a lease is still set on a file.
141  *
142  * \param fd    File to check the lease on.
143  *
144  * \retval lease type if present (LL_LEASE_READ or LL_LEASE_WRITE).
145  * \retval 0 if no lease is present.
146  * \retval -errno on error.
147  */
148 int llapi_lease_check(int fd)
149 {
150         int rc;
151
152         rc = ioctl(fd, LL_IOC_GET_LEASE);
153         if (rc < 0) {
154                 rc = -errno;
155                 llapi_error(LLAPI_MSG_ERROR, rc, "cannot check lease");
156         }
157         return rc;
158 }
159
160 /**
161  * XXX: This is an obsoleted API - do not use it any more.
162  */
163 int llapi_lease_get(int fd, int mode)
164 {
165         int rc;
166
167         if (mode != LL_LEASE_RDLCK && mode != LL_LEASE_WRLCK)
168                 return -EINVAL;
169
170         rc = ioctl(fd, LL_IOC_SET_LEASE_OLD, mode);
171         if (rc < 0)
172                 rc = -errno;
173
174         return rc;
175 }
176
177 /**
178  * XXX: This is an obsoleted API - do not use it any more.
179  */
180 int llapi_lease_put(int fd)
181 {
182         int rc;
183
184         rc = ioctl(fd, LL_IOC_SET_LEASE_OLD, LL_LEASE_UNLCK);
185         if (rc < 0)
186                 rc = -errno;
187
188         return rc;
189 }