2
* Copyright (c) 2013-2018 Red Hat, Inc. <http://www.redhat.com>
3
* This file is part of GlusterFS.
5
* This file is licensed to you under your choice of the GNU Lesser
6
* General Public License, version 3 or any later version (LGPLv3 or
7
* later), or the GNU General Public License, version 2 (GPLv2), in all
8
* cases as published by the Free Software Foundation.
11
#include "glfs-internal.h"
12
#include "glfs-mem-types.h"
14
#include "gfapi-messages.h"
17
glfs_listxattr_process(void *value, size_t size, dict_t *xattr);
20
glfs_iatt_from_stat(struct stat *stat, int valid, struct iatt *iatt,
23
/* validate in args */
24
if ((stat == NULL) || (iatt == NULL) || (glvalid == NULL)) {
31
if (valid & GFAPI_SET_ATTR_MODE) {
32
iatt->ia_prot = ia_prot_from_st_mode(stat->st_mode);
33
*glvalid |= GF_SET_ATTR_MODE;
36
if (valid & GFAPI_SET_ATTR_UID) {
37
iatt->ia_uid = stat->st_uid;
38
*glvalid |= GF_SET_ATTR_UID;
41
if (valid & GFAPI_SET_ATTR_GID) {
42
iatt->ia_gid = stat->st_gid;
43
*glvalid |= GF_SET_ATTR_GID;
46
if (valid & GFAPI_SET_ATTR_ATIME) {
47
iatt->ia_atime = stat->st_atime;
48
iatt->ia_atime_nsec = ST_ATIM_NSEC(stat);
49
*glvalid |= GF_SET_ATTR_ATIME;
52
if (valid & GFAPI_SET_ATTR_MTIME) {
53
iatt->ia_mtime = stat->st_mtime;
54
iatt->ia_mtime_nsec = ST_MTIM_NSEC(stat);
55
*glvalid |= GF_SET_ATTR_MTIME;
61
GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_lookupat, 3.7.4)
63
pub_glfs_h_lookupat(struct glfs *fs, struct glfs_object *parent,
64
const char *path, struct stat *stat, int follow)
67
xlator_t *subvol = NULL;
68
inode_t *inode = NULL;
72
struct glfs_object *object = NULL;
79
/* validate in args */
85
__GLFS_ENTRY_VALIDATE_FS(fs, invalid_fs);
87
/* get the active volume */
88
subvol = glfs_active_subvol(fs);
94
/* get/refresh the in arg objects inode in correlation to the xlator */
96
inode = glfs_resolve_inode(fs, subvol, parent);
104
ret = glfs_resolve_at(fs, subvol, inode, path, &loc, &iatt, follow, 0);
106
/* populate out args */
109
glfs_iatt_to_stat(fs, &iatt, stat);
111
ret = glfs_create_object(&loc, &object);
120
glfs_subvol_done(fs, subvol);
128
GFAPI_SYMVER_PUBLIC(glfs_h_lookupat34, glfs_h_lookupat, 3.4.2)
130
pub_glfs_h_lookupat34(struct glfs *fs, struct glfs_object *parent,
131
const char *path, struct stat *stat)
133
return pub_glfs_h_lookupat(fs, parent, path, stat, 0);
136
GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_statfs, 3.7.0)
138
pub_glfs_h_statfs(struct glfs *fs, struct glfs_object *object,
139
struct statvfs *statvfs)
142
xlator_t *subvol = NULL;
143
inode_t *inode = NULL;
150
/* validate in args */
151
if ((fs == NULL) || (object == NULL || statvfs == NULL)) {
156
__GLFS_ENTRY_VALIDATE_FS(fs, invalid_fs);
158
/* get the active volume */
159
subvol = glfs_active_subvol(fs);
166
/* get/refresh the in arg objects inode in correlation to the xlator */
167
inode = glfs_resolve_inode(fs, subvol, object);
174
GLFS_LOC_FILL_INODE(inode, loc, out);
177
ret = syncop_statfs(subvol, &loc, statvfs, NULL, NULL);
178
DECODE_SYNCOP_ERR(ret);
186
glfs_subvol_done(fs, subvol);
194
GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_stat, 3.4.2)
196
pub_glfs_h_stat(struct glfs *fs, struct glfs_object *object, struct stat *stat)
199
xlator_t *subvol = NULL;
200
inode_t *inode = NULL;
210
/* validate in args */
211
if ((fs == NULL) || (object == NULL)) {
216
__GLFS_ENTRY_VALIDATE_FS(fs, invalid_fs);
218
/* get the active volume */
219
subvol = glfs_active_subvol(fs);
226
/* get/refresh the in arg objects inode in correlation to the xlator */
227
inode = glfs_resolve_inode(fs, subvol, object);
234
GLFS_LOC_FILL_INODE(inode, loc, out);
238
ret = syncop_stat(subvol, &loc, &iatt, NULL, NULL);
240
/* populate out args */
241
glfs_iatt_to_stat(fs, &iatt, stat);
243
ret = syncop_stat(subvol, &loc, NULL, NULL, NULL);
244
DECODE_SYNCOP_ERR(ret);
252
glfs_subvol_done(fs, subvol);
260
GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_getattrs, 3.4.2)
262
pub_glfs_h_getattrs(struct glfs *fs, struct glfs_object *object,
266
xlator_t *subvol = NULL;
267
inode_t *inode = NULL;
272
/* validate in args */
273
if ((fs == NULL) || (object == NULL)) {
279
__GLFS_ENTRY_VALIDATE_FS(fs, invalid_fs);
281
/* get the active volume */
282
subvol = glfs_active_subvol(fs);
289
/* get/refresh the in arg objects inode in correlation to the xlator */
290
inode = glfs_resolve_inode(fs, subvol, object);
299
ret = glfs_resolve_base(fs, subvol, inode, &iatt);
300
/* populate out args */
302
glfs_iatt_to_stat(fs, &iatt, stat);
305
ret = glfs_resolve_base(fs, subvol, inode, NULL);
311
glfs_subvol_done(fs, subvol);
320
glfs_h_getxattrs_common(struct glfs *fs, struct glfs_object *object,
321
dict_t **xattr, const char *name,
322
gf_boolean_t is_listxattr)
325
xlator_t *subvol = NULL;
326
inode_t *inode = NULL;
331
/* validate in args */
332
if ((fs == NULL) || (object == NULL)) {
338
if (!name || *name == '\0') {
343
if (strlen(name) > GF_XATTR_NAME_MAX) {
344
errno = ENAMETOOLONG;
348
/* get the active volume */
349
subvol = glfs_active_subvol(fs);
356
/* get/refresh the in arg objects inode in correlation to the xlator */
357
inode = glfs_resolve_inode(fs, subvol, object);
364
GLFS_LOC_FILL_INODE(inode, loc, out);
366
ret = syncop_getxattr(subvol, &loc, xattr, name, NULL, NULL);
367
DECODE_SYNCOP_ERR(ret);
375
glfs_subvol_done(fs, subvol);
380
GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_getxattrs, 3.5.1)
382
pub_glfs_h_getxattrs(struct glfs *fs, struct glfs_object *object,
383
const char *name, void *value, size_t size)
386
dict_t *xattr = NULL;
388
/* validate in args */
389
if ((fs == NULL) || (object == NULL)) {
395
__GLFS_ENTRY_VALIDATE_FS(fs, invalid_fs);
397
ret = glfs_h_getxattrs_common(fs, object, &xattr, name, (name == NULL));
401
/* If @name is NULL, means get all the xattrs (i.e listxattr). */
403
ret = glfs_getxattr_process(value, size, xattr, name);
405
ret = glfs_listxattr_process(value, size, xattr);
417
GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_setattrs, 3.4.2)
419
pub_glfs_h_setattrs(struct glfs *fs, struct glfs_object *object,
420
struct stat *stat, int valid)
423
xlator_t *subvol = NULL;
424
inode_t *inode = NULL;
433
/* validate in args */
434
if ((fs == NULL) || (object == NULL) || (stat == NULL)) {
440
__GLFS_ENTRY_VALIDATE_FS(fs, invalid_fs);
442
/* get the active volume */
443
subvol = glfs_active_subvol(fs);
450
/* get/refresh the in arg objects inode in correlation to the xlator */
451
inode = glfs_resolve_inode(fs, subvol, object);
457
/* map valid masks from in args */
458
glfs_iatt_from_stat(stat, valid, &iatt, &glvalid);
461
GLFS_LOC_FILL_INODE(inode, loc, out);
464
ret = syncop_setattr(subvol, &loc, &iatt, glvalid, 0, 0, NULL, NULL);
465
DECODE_SYNCOP_ERR(ret);
472
glfs_subvol_done(fs, subvol);
480
GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_setxattrs, 3.5.0)
482
pub_glfs_h_setxattrs(struct glfs *fs, struct glfs_object *object,
483
const char *name, const void *value, size_t size,
487
xlator_t *subvol = NULL;
488
inode_t *inode = NULL;
492
dict_t *xattr = NULL;
493
void *value_cp = NULL;
495
/* validate in args */
496
if ((fs == NULL) || (object == NULL) || (name == NULL) || (value == NULL)) {
501
if (!name || *name == '\0') {
506
if (strlen(name) > GF_XATTR_NAME_MAX) {
507
errno = ENAMETOOLONG;
512
__GLFS_ENTRY_VALIDATE_FS(fs, invalid_fs);
514
/* get the active volume */
515
subvol = glfs_active_subvol(fs);
522
/* get/refresh the in arg objects inode in correlation to the xlator */
523
inode = glfs_resolve_inode(fs, subvol, object);
529
value_cp = gf_memdup(value, size);
530
GF_CHECK_ALLOC_AND_LOG(subvol->name, value_cp, ret,
532
" duplicate setxattr value",
535
xattr = dict_for_key_value(name, value_cp, size, _gf_false);
544
GLFS_LOC_FILL_INODE(inode, loc, out);
547
ret = syncop_setxattr(subvol, &loc, xattr, flags, NULL, NULL);
548
DECODE_SYNCOP_ERR(ret);
559
glfs_subvol_done(fs, subvol);
567
GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_removexattrs, 3.5.1)
569
pub_glfs_h_removexattrs(struct glfs *fs, struct glfs_object *object,
573
xlator_t *subvol = NULL;
574
inode_t *inode = NULL;
579
/* validate in args */
580
if ((fs == NULL) || (object == NULL) || (name == NULL)) {
586
__GLFS_ENTRY_VALIDATE_FS(fs, invalid_fs);
588
/* get the active volume */
589
subvol = glfs_active_subvol(fs);
596
/* get/refresh the in arg objects inode in correlation to the xlator */
597
inode = glfs_resolve_inode(fs, subvol, object);
604
GLFS_LOC_FILL_INODE(inode, loc, out);
607
ret = syncop_removexattr(subvol, &loc, name, NULL, NULL);
608
DECODE_SYNCOP_ERR(ret);
616
glfs_subvol_done(fs, subvol);
624
GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_open, 3.4.2)
626
pub_glfs_h_open(struct glfs *fs, struct glfs_object *object, int flags)
629
struct glfs_fd *glfd = NULL;
630
xlator_t *subvol = NULL;
631
inode_t *inode = NULL;
635
dict_t *fop_attr = NULL;
637
/* validate in args */
638
if ((fs == NULL) || (object == NULL)) {
644
__GLFS_ENTRY_VALIDATE_FS(fs, invalid_fs);
646
/* get the active volume */
647
subvol = glfs_active_subvol(fs);
653
/* get/refresh the in arg objects inode in correlation to the xlator */
654
inode = glfs_resolve_inode(fs, subvol, object);
660
ret = validate_open_flags(flags, inode->ia_type);
664
glfd = glfs_fd_new(fs);
671
glfd->fd = fd_create(inode, getpid());
677
glfd->fd->flags = flags;
680
GLFS_LOC_FILL_INODE(inode, loc, out);
683
ret = get_fop_attr_thrd_key(&fop_attr);
685
gf_msg_debug("gfapi", 0, "Getting leaseid from thread failed");
687
if (IA_ISDIR(inode->ia_type))
688
ret = syncop_opendir(subvol, &loc, glfd->fd, NULL, NULL);
690
ret = syncop_open(subvol, &loc, flags, glfd->fd, fop_attr, NULL);
692
DECODE_SYNCOP_ERR(ret);
694
glfd->fd->flags = flags;
702
dict_unref(fop_attr);
708
glfd_set_state_bind(glfd);
711
glfs_subvol_done(fs, subvol);
719
GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_creat, 3.4.2)
721
pub_glfs_h_creat(struct glfs *fs, struct glfs_object *parent, const char *path,
722
int flags, mode_t mode, struct stat *stat)
726
xlator_t *subvol = NULL;
727
inode_t *inode = NULL;
735
dict_t *xattr_req = NULL;
736
struct glfs_object *object = NULL;
738
/* validate in args */
739
if ((fs == NULL) || (parent == NULL) || (path == NULL)) {
745
__GLFS_ENTRY_VALIDATE_FS(fs, invalid_fs);
747
/* get the active volume */
748
subvol = glfs_active_subvol(fs);
755
/* get/refresh the in arg objects inode in correlation to the xlator */
756
inode = glfs_resolve_inode(fs, subvol, parent);
763
xattr_req = dict_new();
770
gf_uuid_generate(gfid);
771
ret = dict_set_gfuuid(xattr_req, "gfid-req", gfid, true);
778
GLFS_LOC_FILL_PINODE(inode, loc, ret, errno, out, path);
780
fd = fd_create(loc.inode, getpid());
789
ret = syncop_create(subvol, &loc, flags, mode, fd, &iatt, xattr_req, NULL);
790
DECODE_SYNCOP_ERR(ret);
792
/* populate out args */
794
ret = glfs_loc_link(&loc, &iatt);
800
glfs_iatt_to_stat(fs, &iatt, stat);
802
ret = glfs_create_object(&loc, &object);
806
if (ret && object != NULL) {
807
/* Release the held reference */
808
glfs_h_close(object);
818
dict_unref(xattr_req);
823
glfs_subvol_done(fs, subvol);
831
GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_creat_open, 6.6)
833
pub_glfs_h_creat_open(struct glfs *fs, struct glfs_object *parent,
834
const char *path, int flags, mode_t mode,
835
struct stat *stat, struct glfs_fd **out_fd)
838
struct glfs_fd *glfd = NULL;
839
xlator_t *subvol = NULL;
840
inode_t *inode = NULL;
848
dict_t *xattr_req = NULL;
849
struct glfs_object *object = NULL;
850
dict_t *fop_attr = NULL;
852
/* validate in args */
853
if ((fs == NULL) || (parent == NULL) || (path == NULL) ||
860
__GLFS_ENTRY_VALIDATE_FS(fs, invalid_fs);
862
/* get the active volume */
863
subvol = glfs_active_subvol(fs);
869
/* get/refresh the in arg objects inode in correlation to the xlator */
870
inode = glfs_resolve_inode(fs, subvol, parent);
876
xattr_req = dict_new();
883
gf_uuid_generate(gfid);
884
ret = dict_set_gfuuid(xattr_req, "gfid-req", gfid, true);
891
GLFS_LOC_FILL_PINODE(inode, loc, ret, errno, out, path);
893
glfd = glfs_fd_new(fs);
900
glfd->fd = fd_create(loc.inode, getpid());
906
glfd->fd->flags = flags;
908
ret = get_fop_attr_thrd_key(&fop_attr);
910
gf_msg_debug("gfapi", 0, "Getting leaseid from thread failed");
913
ret = syncop_create(subvol, &loc, flags, mode, glfd->fd, &iatt, xattr_req,
915
DECODE_SYNCOP_ERR(ret);
917
/* populate out args */
919
glfd->fd->flags = flags;
921
ret = glfs_loc_link(&loc, &iatt);
927
glfs_iatt_to_stat(fs, &iatt, stat);
929
ret = glfs_create_object(&loc, &object);
933
if (ret && object != NULL) {
934
/* Release the held reference */
935
glfs_h_close(object);
945
dict_unref(fop_attr);
948
dict_unref(xattr_req);
953
glfd_set_state_bind(glfd);
957
glfs_subvol_done(fs, subvol);
965
GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_mkdir, 3.4.2)
967
pub_glfs_h_mkdir(struct glfs *fs, struct glfs_object *parent, const char *path,
968
mode_t mode, struct stat *stat)
971
xlator_t *subvol = NULL;
972
inode_t *inode = NULL;
980
dict_t *xattr_req = NULL;
981
struct glfs_object *object = NULL;
983
/* validate in args */
984
if ((fs == NULL) || (parent == NULL) || (path == NULL)) {
990
__GLFS_ENTRY_VALIDATE_FS(fs, invalid_fs);
992
/* get the active volume */
993
subvol = glfs_active_subvol(fs);
1000
/* get/refresh the in arg objects inode in correlation to the xlator */
1001
inode = glfs_resolve_inode(fs, subvol, parent);
1007
xattr_req = dict_new();
1014
gf_uuid_generate(gfid);
1015
ret = dict_set_gfuuid(xattr_req, "gfid-req", gfid, true);
1022
GLFS_LOC_FILL_PINODE(inode, loc, ret, errno, out, path);
1025
ret = syncop_mkdir(subvol, &loc, mode, &iatt, xattr_req, NULL);
1026
DECODE_SYNCOP_ERR(ret);
1028
/* populate out args */
1030
ret = glfs_loc_link(&loc, &iatt);
1036
glfs_iatt_to_stat(fs, &iatt, stat);
1038
ret = glfs_create_object(&loc, &object);
1042
if (ret && object != NULL) {
1043
glfs_h_close(object);
1053
dict_unref(xattr_req);
1055
glfs_subvol_done(fs, subvol);
1063
GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_mknod, 3.4.2)
1065
pub_glfs_h_mknod(struct glfs *fs, struct glfs_object *parent, const char *path,
1066
mode_t mode, dev_t dev, struct stat *stat)
1069
xlator_t *subvol = NULL;
1070
inode_t *inode = NULL;
1074
struct iatt iatt = {
1078
dict_t *xattr_req = NULL;
1079
struct glfs_object *object = NULL;
1081
/* validate in args */
1082
if ((fs == NULL) || (parent == NULL) || (path == NULL)) {
1088
__GLFS_ENTRY_VALIDATE_FS(fs, invalid_fs);
1090
/* get the active volume */
1091
subvol = glfs_active_subvol(fs);
1098
/* get/refresh the in arg objects inode in correlation to the xlator */
1099
inode = glfs_resolve_inode(fs, subvol, parent);
1105
xattr_req = dict_new();
1112
gf_uuid_generate(gfid);
1113
ret = dict_set_gfuuid(xattr_req, "gfid-req", gfid, true);
1120
GLFS_LOC_FILL_PINODE(inode, loc, ret, errno, out, path);
1123
ret = syncop_mknod(subvol, &loc, mode, dev, &iatt, xattr_req, NULL);
1124
DECODE_SYNCOP_ERR(ret);
1126
/* populate out args */
1128
ret = glfs_loc_link(&loc, &iatt);
1134
glfs_iatt_to_stat(fs, &iatt, stat);
1136
ret = glfs_create_object(&loc, &object);
1139
if (ret && object != NULL) {
1140
glfs_h_close(object);
1150
dict_unref(xattr_req);
1152
glfs_subvol_done(fs, subvol);
1160
GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_unlink, 3.4.2)
1162
pub_glfs_h_unlink(struct glfs *fs, struct glfs_object *parent, const char *path)
1165
xlator_t *subvol = NULL;
1166
inode_t *inode = NULL;
1171
/* validate in args */
1172
if ((fs == NULL) || (parent == NULL) || (path == NULL)) {
1178
__GLFS_ENTRY_VALIDATE_FS(fs, invalid_fs);
1180
/* get the active volume */
1181
subvol = glfs_active_subvol(fs);
1188
/* get/refresh the in arg objects inode in correlation to the xlator */
1189
inode = glfs_resolve_inode(fs, subvol, parent);
1195
ret = glfs_resolve_at(fs, subvol, inode, path, &loc, NULL, 0, 0);
1200
if (!IA_ISDIR(loc.inode->ia_type)) {
1201
ret = syncop_unlink(subvol, &loc, NULL, NULL);
1202
DECODE_SYNCOP_ERR(ret);
1207
ret = syncop_rmdir(subvol, &loc, 0, NULL, NULL);
1208
DECODE_SYNCOP_ERR(ret);
1215
ret = glfs_loc_unlink(&loc);
1223
glfs_subvol_done(fs, subvol);
1231
GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_opendir, 3.4.2)
1233
pub_glfs_h_opendir(struct glfs *fs, struct glfs_object *object)
1236
struct glfs_fd *glfd = NULL;
1237
xlator_t *subvol = NULL;
1238
inode_t *inode = NULL;
1243
/* validate in args */
1244
if ((fs == NULL) || (object == NULL)) {
1250
__GLFS_ENTRY_VALIDATE_FS(fs, invalid_fs);
1252
/* get the active volume */
1253
subvol = glfs_active_subvol(fs);
1260
/* get/refresh the in arg objects inode in correlation to the xlator */
1261
inode = glfs_resolve_inode(fs, subvol, object);
1267
if (!IA_ISDIR(inode->ia_type)) {
1273
glfd = glfs_fd_new(fs);
1277
INIT_LIST_HEAD(&glfd->entries);
1279
glfd->fd = fd_create(inode, getpid());
1286
GLFS_LOC_FILL_INODE(inode, loc, out);
1289
ret = syncop_opendir(subvol, &loc, glfd->fd, NULL, NULL);
1290
DECODE_SYNCOP_ERR(ret);
1302
glfd_set_state_bind(glfd);
1305
glfs_subvol_done(fs, subvol);
1313
GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_access, 3.6.0)
1315
pub_glfs_h_access(struct glfs *fs, struct glfs_object *object, int mask)
1318
xlator_t *subvol = NULL;
1319
inode_t *inode = NULL;
1326
/* validate in args */
1327
if ((fs == NULL) || (object == NULL)) {
1332
__GLFS_ENTRY_VALIDATE_FS(fs, invalid_fs);
1334
/* get the active volume */
1335
subvol = glfs_active_subvol(fs);
1342
/* get/refresh the in arg objects inode in correlation to the xlator */
1343
inode = glfs_resolve_inode(fs, subvol, object);
1349
GLFS_LOC_FILL_INODE(inode, loc, out);
1353
ret = syncop_access(subvol, &loc, mask, NULL, NULL);
1354
DECODE_SYNCOP_ERR(ret);
1362
glfs_subvol_done(fs, subvol);
1370
GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_extract_handle, 3.4.2)
1372
pub_glfs_h_extract_handle(struct glfs_object *object, unsigned char *handle,
1377
/* validate in args */
1378
if (object == NULL) {
1383
if (!handle || !len) {
1384
ret = GFAPI_HANDLE_LENGTH;
1388
if (len < GFAPI_HANDLE_LENGTH) {
1393
memcpy(handle, object->gfid, GFAPI_HANDLE_LENGTH);
1395
ret = GFAPI_HANDLE_LENGTH;
1401
GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_create_from_handle, 3.4.2)
1403
pub_glfs_h_create_from_handle(struct glfs *fs, unsigned char *handle, int len,
1410
struct iatt iatt = {
1413
inode_t *newinode = NULL;
1414
xlator_t *subvol = NULL;
1415
struct glfs_object *object = NULL;
1416
uint64_t ctx_value = LOOKUP_NOT_NEEDED;
1417
gf_boolean_t lookup_needed = _gf_false;
1419
/* validate in args */
1420
if ((fs == NULL) || (handle == NULL) || (len != GFAPI_HANDLE_LENGTH)) {
1426
__GLFS_ENTRY_VALIDATE_FS(fs, invalid_fs);
1428
/* get the active volume */
1429
subvol = glfs_active_subvol(fs);
1435
memcpy(loc.gfid, handle, GFAPI_HANDLE_LENGTH);
1437
/* make sure the gfid received is valid */
1438
GF_VALIDATE_OR_GOTO("glfs_h_create_from_handle",
1439
!(gf_uuid_is_null(loc.gfid)), out);
1441
newinode = inode_find(subvol->itable, loc.gfid);
1443
if (!stat) /* No need of lookup */
1446
lookup_needed = inode_needs_lookup(newinode, THIS);
1447
if (lookup_needed) {
1448
loc.inode = newinode;
1451
GLFS_LOC_FILL_INODE(newinode, loc, fill_out);
1454
ret = syncop_stat(subvol, &loc, &iatt, NULL, NULL);
1455
DECODE_SYNCOP_ERR(ret);
1459
/* Drop the reference hold in inode_find */
1460
inode_unref(newinode);
1464
glfs_iatt_to_stat(fs, &iatt, stat);
1468
loc.inode = inode_new(subvol->itable);
1475
ret = syncop_lookup(subvol, &loc, &iatt, 0, 0, 0);
1476
DECODE_SYNCOP_ERR(ret);
1478
gf_smsg(subvol->name, GF_LOG_WARNING, errno,
1479
API_MSG_INODE_REFRESH_FAILED, "gfid=%s", uuid_utoa(loc.gfid),
1480
"error=%s", strerror(errno), NULL);
1484
newinode = inode_link(loc.inode, 0, 0, &iatt);
1486
if (newinode == loc.inode) {
1487
inode_ctx_set(newinode, THIS, &ctx_value);
1489
inode_lookup(newinode);
1491
gf_smsg(subvol->name, GF_LOG_WARNING, errno, API_MSG_INODE_LINK_FAILED,
1492
"gfid=%s", uuid_utoa(loc.gfid), NULL);
1498
glfs_iatt_to_stat(fs, &iatt, stat);
1501
object = GF_CALLOC(1, sizeof(struct glfs_object), glfs_mt_glfs_object_t);
1502
if (object == NULL) {
1508
/* populate the return object */
1509
object->inode = newinode;
1510
gf_uuid_copy(object->gfid, object->inode->gfid);
1513
/* TODO: Check where the inode ref is being held? */
1516
glfs_subvol_done(fs, subvol);
1524
GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_close, 3.4.2)
1526
pub_glfs_h_close(struct glfs_object *object)
1528
/* since glfs_h_* objects hold a reference to inode
1529
* it is safe to keep lookup count to '0' */
1530
inode_forget(object->inode, 0);
1531
inode_unref(object->inode);
1537
GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_truncate, 3.4.2)
1539
pub_glfs_h_truncate(struct glfs *fs, struct glfs_object *object, off_t offset)
1545
xlator_t *subvol = NULL;
1546
inode_t *inode = NULL;
1550
/* validate in args */
1551
if (object == NULL) {
1556
__GLFS_ENTRY_VALIDATE_FS(fs, invalid_fs);
1558
/* get the active volume */
1559
subvol = glfs_active_subvol(fs);
1566
/* get/refresh the in arg objects inode in correlation to the xlator */
1567
inode = glfs_resolve_inode(fs, subvol, object);
1573
GLFS_LOC_FILL_INODE(inode, loc, out);
1576
ret = syncop_truncate(subvol, &loc, (off_t)offset, NULL, NULL);
1577
DECODE_SYNCOP_ERR(ret);
1579
/* populate out args */
1581
ret = glfs_loc_unlink(&loc);
1589
glfs_subvol_done(fs, subvol);
1597
GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_symlink, 3.4.2)
1599
pub_glfs_h_symlink(struct glfs *fs, struct glfs_object *parent,
1600
const char *name, const char *data, struct stat *stat)
1603
xlator_t *subvol = NULL;
1604
inode_t *inode = NULL;
1608
struct iatt iatt = {
1612
dict_t *xattr_req = NULL;
1613
struct glfs_object *object = NULL;
1617
/* validate in args */
1618
if ((parent == NULL) || (name == NULL) || (data == NULL)) {
1623
__GLFS_ENTRY_VALIDATE_FS(fs, invalid_fs);
1625
/* get the active volume */
1626
subvol = glfs_active_subvol(fs);
1633
/* get/refresh the in arg objects inode in correlation to the xlator */
1634
inode = glfs_resolve_inode(fs, subvol, parent);
1640
xattr_req = dict_new();
1647
gf_uuid_generate(gfid);
1648
ret = dict_set_gfuuid(xattr_req, "gfid-req", gfid, true);
1655
GLFS_LOC_FILL_PINODE(inode, loc, ret, errno, out, name);
1658
ret = syncop_symlink(subvol, &loc, data, &iatt, xattr_req, NULL);
1659
DECODE_SYNCOP_ERR(ret);
1661
/* populate out args */
1663
ret = glfs_loc_link(&loc, &iatt);
1669
glfs_iatt_to_stat(fs, &iatt, stat);
1671
ret = glfs_create_object(&loc, &object);
1675
if (ret && object != NULL) {
1676
pub_glfs_h_close(object);
1686
dict_unref(xattr_req);
1688
glfs_subvol_done(fs, subvol);
1696
GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_readlink, 3.4.2)
1698
pub_glfs_h_readlink(struct glfs *fs, struct glfs_object *object, char *buf,
1705
xlator_t *subvol = NULL;
1706
inode_t *inode = NULL;
1707
char *linkval = NULL;
1711
/* validate in args */
1712
if ((object == NULL) || (buf == NULL)) {
1717
__GLFS_ENTRY_VALIDATE_FS(fs, invalid_fs);
1719
/* get the active volume */
1720
subvol = glfs_active_subvol(fs);
1727
/* get/refresh the in arg objects inode in correlation to the xlator */
1728
inode = glfs_resolve_inode(fs, subvol, object);
1734
GLFS_LOC_FILL_INODE(inode, loc, out);
1737
ret = syncop_readlink(subvol, &loc, &linkval, bufsiz, NULL, NULL);
1738
DECODE_SYNCOP_ERR(ret);
1740
/* populate out args */
1742
memcpy(buf, linkval, ret);
1753
glfs_subvol_done(fs, subvol);
1761
GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_link, 3.4.2)
1763
pub_glfs_h_link(struct glfs *fs, struct glfs_object *linksrc,
1764
struct glfs_object *parent, const char *name)
1767
xlator_t *subvol = NULL;
1768
inode_t *inode = NULL;
1769
inode_t *pinode = NULL;
1776
struct iatt iatt = {
1782
/* validate in args */
1783
if ((linksrc == NULL) || (parent == NULL) || (name == NULL)) {
1788
__GLFS_ENTRY_VALIDATE_FS(fs, invalid_fs);
1790
/* get the active volume */
1791
subvol = glfs_active_subvol(fs);
1798
/* get/refresh the in arg objects inode in correlation to the xlator */
1799
inode = glfs_resolve_inode(fs, subvol, linksrc);
1805
if (inode->ia_type == IA_IFDIR) {
1811
GLFS_LOC_FILL_INODE(inode, oldloc, out);
1813
/* get/refresh the in arg objects inode in correlation to the xlator */
1814
pinode = glfs_resolve_inode(fs, subvol, parent);
1820
/* setup newloc based on parent */
1821
newloc.parent = inode_ref(pinode);
1823
ret = glfs_loc_touchup(&newloc);
1829
/* Filling the inode of the hard link to be same as that of the
1832
newloc.inode = inode_ref(inode);
1835
ret = syncop_link(subvol, &oldloc, &newloc, &iatt, NULL, NULL);
1836
DECODE_SYNCOP_ERR(ret);
1839
ret = glfs_loc_link(&newloc, &iatt);
1848
inode_unref(pinode);
1850
glfs_subvol_done(fs, subvol);
1858
GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_rename, 3.4.2)
1860
pub_glfs_h_rename(struct glfs *fs, struct glfs_object *olddir,
1861
const char *oldname, struct glfs_object *newdir,
1862
const char *newname)
1865
xlator_t *subvol = NULL;
1866
inode_t *oldpinode = NULL;
1867
inode_t *newpinode = NULL;
1874
struct iatt oldiatt = {
1877
struct iatt newiatt = {
1883
/* validate in args */
1884
if ((olddir == NULL) || (oldname == NULL) || (newdir == NULL) ||
1885
(newname == NULL)) {
1890
__GLFS_ENTRY_VALIDATE_FS(fs, invalid_fs);
1892
/* get the active volume */
1893
subvol = glfs_active_subvol(fs);
1900
/* get/refresh the in arg objects inode in correlation to the xlator */
1901
oldpinode = glfs_resolve_inode(fs, subvol, olddir);
1907
ret = glfs_resolve_at(fs, subvol, oldpinode, oldname, &oldloc, &oldiatt, 0,
1913
/* get/refresh the in arg objects inode in correlation to the xlator */
1914
newpinode = glfs_resolve_inode(fs, subvol, newdir);
1920
ret = glfs_resolve_at(fs, subvol, newpinode, newname, &newloc, &newiatt, 0,
1923
if (ret && errno != ENOENT && newloc.parent)
1926
if (newiatt.ia_type != IA_INVAL) {
1927
if ((oldiatt.ia_type == IA_IFDIR) != (newiatt.ia_type == IA_IFDIR)) {
1928
/* Either both old and new must be dirs,
1929
* or both must be non-dirs. Else, fail.
1937
/* TODO: check if new or old is a prefix of the other, and fail EINVAL */
1939
ret = syncop_rename(subvol, &oldloc, &newloc, NULL, NULL);
1940
DECODE_SYNCOP_ERR(ret);
1943
inode_rename(oldloc.parent->table, oldloc.parent, oldloc.name,
1944
newloc.parent, newloc.name, oldloc.inode, &oldiatt);
1946
if (newloc.inode && !inode_has_dentry(newloc.inode))
1947
inode_forget(newloc.inode, 0);
1955
inode_unref(oldpinode);
1958
inode_unref(newpinode);
1960
glfs_subvol_done(fs, subvol);
1969
* Given a handle/gfid, find if the corresponding inode is present in
1970
* the inode table. If yes create and return the corresponding glfs_object.
1973
glfs_h_find_handle(struct glfs *fs, unsigned char *handle, int len)
1975
inode_t *newinode = NULL;
1976
xlator_t *subvol = NULL;
1977
struct glfs_object *object = NULL;
1980
/* validate in args */
1981
if ((fs == NULL) || (handle == NULL) || (len != GFAPI_HANDLE_LENGTH)) {
1987
__GLFS_ENTRY_VALIDATE_FS(fs, invalid_fs);
1989
/* get the active volume */
1990
subvol = glfs_active_subvol(fs);
1996
memcpy(gfid, handle, GFAPI_HANDLE_LENGTH);
1998
/* make sure the gfid received is valid */
1999
GF_VALIDATE_OR_GOTO("glfs_h_find_handle", !(gf_uuid_is_null(gfid)), out);
2001
newinode = inode_find(subvol->itable, gfid);
2006
object = GF_CALLOC(1, sizeof(struct glfs_object), glfs_mt_glfs_object_t);
2007
if (object == NULL) {
2012
/* populate the return object. The ref taken here
2013
* is un'refed when the application does glfs_h_close() */
2014
object->inode = inode_ref(newinode);
2015
gf_uuid_copy(object->gfid, object->inode->gfid);
2018
/* inode_find takes a reference. Unref it. */
2020
inode_unref(newinode);
2022
glfs_subvol_done(fs, subvol);
2031
glfs_free_upcall_inode(void *to_free)
2033
struct glfs_upcall_inode *arg = to_free;
2039
glfs_h_close(arg->object);
2041
glfs_h_close(arg->p_object);
2042
if (arg->oldp_object)
2043
glfs_h_close(arg->oldp_object);
2049
glfs_h_poll_cache_invalidation(struct glfs *fs, struct glfs_upcall *up_arg,
2050
struct gf_upcall *upcall_data)
2053
struct glfs_object *p_object = NULL;
2054
struct glfs_object *oldp_object = NULL;
2055
struct glfs_object *object = NULL;
2056
struct gf_upcall_cache_invalidation *ca_data = NULL;
2057
struct glfs_upcall_inode *up_inode_arg = NULL;
2059
ca_data = upcall_data->data;
2060
GF_VALIDATE_OR_GOTO("glfs_h_poll_cache_invalidation", ca_data, out);
2062
object = glfs_h_find_handle(fs, upcall_data->gfid, GFAPI_HANDLE_LENGTH);
2064
/* The reason handle creation will fail is because we
2065
* couldn't find the inode in the gfapi inode table.
2067
* But since application would have taken inode_ref, the
2068
* only case when this can happen is when it has closed
2069
* the handle and hence will no more be interested in
2070
* the upcall for this particular gfid.
2072
gf_smsg(THIS->name, GF_LOG_DEBUG, errno, API_MSG_CREATE_HANDLE_FAILED,
2073
"gfid=%s", uuid_utoa(upcall_data->gfid), NULL);
2078
up_inode_arg = GF_CALLOC(1, sizeof(struct glfs_upcall_inode),
2079
glfs_mt_upcall_inode_t);
2080
GF_VALIDATE_OR_GOTO("glfs_h_poll_cache_invalidation", up_inode_arg, out);
2082
up_inode_arg->object = object;
2083
up_inode_arg->flags = ca_data->flags;
2084
up_inode_arg->expire_time_attr = ca_data->expire_time_attr;
2086
/* XXX: Update stat as well in case of UP_*_TIMES.
2087
* This will be addressed as part of INODE_UPDATE */
2088
if (ca_data->flags & GFAPI_INODE_UPDATE_FLAGS) {
2089
glfs_iatt_to_stat(fs, &ca_data->stat, &up_inode_arg->buf);
2092
if (ca_data->flags & GFAPI_UP_PARENT_TIMES) {
2093
p_object = glfs_h_find_handle(fs, ca_data->p_stat.ia_gfid,
2094
GFAPI_HANDLE_LENGTH);
2096
gf_smsg(THIS->name, GF_LOG_DEBUG, errno,
2097
API_MSG_CREATE_HANDLE_FAILED, "gfid=%s",
2098
uuid_utoa(ca_data->p_stat.ia_gfid), NULL);
2103
glfs_iatt_to_stat(fs, &ca_data->p_stat, &up_inode_arg->p_buf);
2105
up_inode_arg->p_object = p_object;
2107
/* In case of RENAME, update old parent as well */
2108
if (ca_data->flags & GFAPI_UP_RENAME) {
2109
oldp_object = glfs_h_find_handle(fs, ca_data->oldp_stat.ia_gfid,
2110
GFAPI_HANDLE_LENGTH);
2112
gf_smsg(THIS->name, GF_LOG_DEBUG, errno,
2113
API_MSG_CREATE_HANDLE_FAILED, "gfid=%s",
2114
uuid_utoa(ca_data->oldp_stat.ia_gfid), NULL);
2116
/* By the time we receive upcall old parent_dir may
2117
* have got removed. We still need to send upcall
2118
* for the file/dir and current parent handles. */
2119
up_inode_arg->oldp_object = NULL;
2123
glfs_iatt_to_stat(fs, &ca_data->oldp_stat, &up_inode_arg->oldp_buf);
2125
up_inode_arg->oldp_object = oldp_object;
2127
up_arg->reason = GLFS_UPCALL_INODE_INVALIDATE;
2128
up_arg->event = up_inode_arg;
2129
up_arg->free_event = glfs_free_upcall_inode;
2135
/* Close p_object and oldp_object as well if being referenced.*/
2137
glfs_h_close(object);
2139
/* Set reason to prevent applications from using ->event */
2140
up_arg->reason = GLFS_UPCALL_EVENT_NULL;
2141
GF_FREE(up_inode_arg);
2147
glfs_release_upcall(void *ptr)
2149
struct glfs_upcall *to_free = ptr;
2152
to_free->free_event(to_free->event);
2156
* This API is used to poll for upcall events stored in the upcall list.
2157
* Current users of this API is NFS-Ganesha. In case of any event received, it
2158
* will be mapped appropriately into 'glfs_upcall' along with the handle object
2159
* to be passed to NFS-Ganesha.
2161
* On success, applications need to check if up_arg is not-NULL or errno is not
2162
* ENOENT. glfs_upcall_get_reason() can be used to decide what kind of event
2163
* has been received.
2165
* Current supported upcall_events:
2166
* GLFS_UPCALL_INODE_INVALIDATE
2168
* After processing the event, applications need to free 'up_arg' by calling
2171
* Also similar to I/Os, the application should ideally stop polling before
2172
* calling glfs_fini(..). Hence making an assumption that 'fs' & ctx structures
2173
* cannot be freed while in this routine.
2175
GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_poll_upcall, 3.7.16)
2177
pub_glfs_h_poll_upcall(struct glfs *fs, struct glfs_upcall **up_arg)
2179
upcall_entry *u_list = NULL;
2180
upcall_entry *tmp = NULL;
2181
xlator_t *subvol = NULL;
2182
glusterfs_ctx_t *ctx = NULL;
2184
struct gf_upcall *upcall_data = NULL;
2193
__GLFS_ENTRY_VALIDATE_FS(fs, err);
2195
/* get the active volume */
2196
subvol = glfs_active_subvol(fs);
2202
/* Ideally applications should stop polling before calling
2203
* 'glfs_fini'. Yet cross check if cleanup has started. */
2204
pthread_mutex_lock(&fs->mutex);
2208
if (ctx->cleanup_started) {
2209
pthread_mutex_unlock(&fs->mutex);
2215
/* once we call this function, the applications seems to be
2216
* interested in events, enable caching them */
2217
fs->cache_upcalls = _gf_true;
2219
pthread_mutex_unlock(&fs->mutex);
2221
pthread_mutex_lock(&fs->upcall_list_mutex);
2223
list_for_each_entry_safe(u_list, tmp, &fs->upcall_list, upcall_list)
2225
list_del_init(&u_list->upcall_list);
2226
upcall_data = &u_list->upcall_data;
2230
/* No other thread can delete this entry. So unlock it */
2231
pthread_mutex_unlock(&fs->upcall_list_mutex);
2234
switch (upcall_data->event_type) {
2235
case GF_UPCALL_CACHE_INVALIDATION:
2236
*up_arg = GLFS_CALLOC(1, sizeof(struct gf_upcall),
2237
glfs_release_upcall,
2238
glfs_mt_upcall_entry_t);
2241
break; /* goto free u_list */
2244
/* XXX: Need to revisit this to support
2245
* GLFS_UPCALL_INODE_UPDATE if required. */
2246
ret = glfs_h_poll_cache_invalidation(fs, *up_arg, upcall_data);
2247
if (ret || (*up_arg)->reason == GLFS_UPCALL_EVENT_NULL) {
2248
/* It could so happen that the file which got
2249
* upcall notification may have got deleted by
2250
* the same client. Irrespective of the error,
2251
* return with an error or success+ENOENT. */
2252
if ((*up_arg)->reason == GLFS_UPCALL_EVENT_NULL)
2259
case GF_UPCALL_RECALL_LEASE:
2260
gf_log("glfs_h_poll_upcall", GF_LOG_DEBUG,
2261
"UPCALL_RECALL_LEASE is not implemented yet");
2262
/* fallthrough till we support leases */
2263
case GF_UPCALL_EVENT_NULL:
2264
/* no 'default:' label, to force handling all upcall events */
2269
GF_FREE(u_list->upcall_data.data);
2272
/* fs->upcall_list was empty, no upcall events cached */
2279
pthread_mutex_lock(&fs->mutex);
2283
pthread_mutex_unlock(&fs->mutex);
2285
glfs_subvol_done(fs, subvol);
2293
static gf_boolean_t log_upcall370 = _gf_true; /* log once */
2295
/* The old glfs_h_poll_upcall interface requires intimate knowledge of the
2296
* structures that are returned to the calling application. This is not
2297
* recommended, as the returned structures need to returned correctly (handles
2298
* closed, memory free'd with the unavailable GF_FREE(), and possibly more.)
2300
* To the best of our knowledge, only NFS-Ganesha uses the upcall events
2301
* through gfapi. We keep this backwards compatibility function around so that
2302
* applications using the existing implementation do not break.
2304
* WARNING: this function will be removed in the future.
2306
GFAPI_SYMVER_PUBLIC(glfs_h_poll_upcall370, glfs_h_poll_upcall, 3.7.0)
2308
pub_glfs_h_poll_upcall370(struct glfs *fs, struct glfs_callback_arg *up_arg)
2310
struct glfs_upcall *upcall = NULL;
2313
if (log_upcall370) {
2314
log_upcall370 = _gf_false;
2315
gf_log(THIS->name, GF_LOG_WARNING,
2316
"this application is "
2317
"compiled against an old version of libgfapi, it "
2318
"should use glfs_free() to release the structure "
2319
"returned by glfs_h_poll_upcall() - for more details, "
2320
"see http://review.gluster.org/14701");
2323
ret = pub_glfs_h_poll_upcall(fs, &upcall);
2326
if ((errno == ENOENT) || !upcall || !upcall->event) {
2327
up_arg->reason = GLFS_UPCALL_EVENT_NULL;
2331
up_arg->reason = upcall->reason;
2333
if (upcall->reason == GLFS_UPCALL_INODE_INVALIDATE) {
2334
struct glfs_callback_inode_arg *cb_inode = NULL;
2335
struct glfs_upcall_inode *up_inode = NULL;
2337
cb_inode = GF_CALLOC(1, sizeof(struct glfs_callback_inode_arg),
2338
glfs_mt_upcall_inode_t);
2345
up_inode = upcall->event;
2347
/* copy attributes one by one, the memory layout might
2348
* be different between the old glfs_callback_inode_arg
2349
* and new glfs_upcall_inode */
2350
cb_inode->object = up_inode->object;
2351
cb_inode->flags = up_inode->flags;
2352
memcpy(&cb_inode->buf, &up_inode->buf, sizeof(struct stat));
2353
cb_inode->expire_time_attr = up_inode->expire_time_attr;
2354
cb_inode->p_object = up_inode->p_object;
2355
memcpy(&cb_inode->p_buf, &up_inode->p_buf, sizeof(struct stat));
2356
cb_inode->oldp_object = up_inode->oldp_object;
2357
memcpy(&cb_inode->oldp_buf, &up_inode->oldp_buf,
2358
sizeof(struct stat));
2360
up_arg->event_arg = cb_inode;
2366
/* we can not use glfs_free() here, objects need to stay */
2367
GF_FREE(upcall->event);
2374
#ifdef HAVE_ACL_LIBACL_H
2375
#include <glusterfs/glusterfs-acl.h>
2376
#include <acl/libacl.h>
2378
GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_acl_set, 3.7.0)
2380
pub_glfs_h_acl_set(struct glfs *fs, struct glfs_object *object,
2381
const acl_type_t type, const acl_t acl)
2385
const char *acl_key = NULL;
2386
struct glfs_object *new_object = NULL;
2390
if (!object || !acl) {
2395
__GLFS_ENTRY_VALIDATE_FS(fs, invalid_fs);
2397
acl_key = gf_posix_acl_get_key(type);
2401
acl_s = acl_to_any_text(acl, NULL, ',', TEXT_ABBREVIATE | TEXT_NUMERIC_IDS);
2405
if (IA_ISLNK(object->inode->ia_type)) {
2406
new_object = glfs_h_resolve_symlink(fs, object);
2407
if (new_object == NULL)
2410
new_object = object;
2412
ret = pub_glfs_h_setxattrs(fs, new_object, acl_key, acl_s,
2413
strlen(acl_s) + 1, 0);
2418
if (IA_ISLNK(object->inode->ia_type) && new_object)
2419
glfs_h_close(new_object);
2427
GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_acl_get, 3.7.0)
2429
pub_glfs_h_acl_get(struct glfs *fs, struct glfs_object *object,
2430
const acl_type_t type)
2435
dict_t *xattr = NULL;
2436
const char *acl_key = NULL;
2437
struct glfs_object *new_object = NULL;
2446
__GLFS_ENTRY_VALIDATE_FS(fs, invalid_fs);
2448
acl_key = gf_posix_acl_get_key(type);
2452
if (IA_ISLNK(object->inode->ia_type)) {
2453
new_object = glfs_h_resolve_symlink(fs, object);
2454
if (new_object == NULL)
2457
new_object = object;
2459
ret = glfs_h_getxattrs_common(fs, new_object, &xattr, acl_key, _gf_false);
2463
ret = dict_get_str(xattr, (char *)acl_key, &acl_s);
2467
acl = acl_from_text(acl_s);
2473
if (IA_ISLNK(object->inode->ia_type) && new_object)
2474
glfs_h_close(new_object);
2481
#else /* !HAVE_ACL_LIBACL_H */
2482
GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_acl_get, 3.7.0)
2484
pub_glfs_h_acl_get(struct glfs *fs, struct glfs_object *object,
2485
const acl_type_t type)
2491
GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_acl_set, 3.7.0)
2493
pub_glfs_h_acl_set(struct glfs *fs, struct glfs_object *object,
2494
const acl_type_t type, const acl_t acl)
2501
/* The API to perform read using anonymous fd */
2502
GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_anonymous_read, 3.7.0)
2504
pub_glfs_h_anonymous_read(struct glfs *fs, struct glfs_object *object,
2505
const void *buf, size_t count, off_t offset)
2507
struct iovec iov = {
2512
/* validate in args */
2513
if ((fs == NULL) || (object == NULL)) {
2518
iov.iov_base = (void *)buf;
2519
iov.iov_len = count;
2521
ret = glfs_anonymous_preadv(fs, object, &iov, 1, offset, 0);
2526
/* The API to perform write using anonymous fd */
2527
GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_anonymous_write, 3.7.0)
2529
pub_glfs_h_anonymous_write(struct glfs *fs, struct glfs_object *object,
2530
const void *buf, size_t count, off_t offset)
2532
struct iovec iov = {
2537
/* validate in args */
2538
if ((fs == NULL) || (object == NULL)) {
2543
iov.iov_base = (void *)buf;
2544
iov.iov_len = count;
2546
ret = glfs_anonymous_pwritev(fs, object, &iov, 1, offset, 0);
2551
GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_object_copy, 3.11.0)
2553
pub_glfs_object_copy(struct glfs_object *src)
2555
struct glfs_object *object = NULL;
2557
GF_VALIDATE_OR_GOTO("glfs_dup_object", src, out);
2559
object = GF_CALLOC(1, sizeof(struct glfs_object), glfs_mt_glfs_object_t);
2560
if (object == NULL) {
2562
gf_smsg(THIS->name, GF_LOG_WARNING, errno, API_MSG_CREATE_HANDLE_FAILED,
2563
"glfs_dup_object gfid=%s", uuid_utoa(src->inode->gfid), NULL);
2567
object->inode = inode_ref(src->inode);
2568
gf_uuid_copy(object->gfid, src->inode->gfid);
2574
GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_xreaddirplus_get_object, 3.11.0)
2576
pub_glfs_xreaddirplus_get_object(struct glfs_xreaddirp_stat *xstat)
2578
GF_VALIDATE_OR_GOTO("glfs_xreaddirplus_get_object", xstat, out);
2580
if (!(xstat->flags_handled & GFAPI_XREADDIRP_HANDLE))
2581
gf_smsg(THIS->name, GF_LOG_ERROR, errno, API_MSG_HANDLE_NOT_SET,
2582
"GFAPI_XREADDIRP_HANDLE xstat=%p", xstat, "handle=%x",
2583
xstat->flags_handled, NULL);
2585
return xstat->object;
2591
GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_lease, 4.0.0)
2593
pub_glfs_h_lease(struct glfs *fs, struct glfs_object *object,
2594
struct glfs_lease *lease)
2597
xlator_t *subvol = NULL;
2598
inode_t *inode = NULL;
2602
struct gf_lease gf_lease = {
2606
/* validate in args */
2607
if ((fs == NULL) || (object == NULL)) {
2613
__GLFS_ENTRY_VALIDATE_FS(fs, invalid_fs);
2615
/* get the active volume */
2616
subvol = glfs_active_subvol(fs);
2623
/* get/refresh the in arg objects inode in correlation to the xlator */
2624
inode = glfs_resolve_inode(fs, subvol, object);
2631
GLFS_LOC_FILL_INODE(inode, loc, out);
2633
glfs_lease_to_gf_lease(lease, &gf_lease);
2635
ret = syncop_lease(subvol, &loc, &gf_lease, NULL, NULL);
2636
DECODE_SYNCOP_ERR(ret);
2638
gf_lease_to_glfs_lease(&gf_lease, lease);
2646
glfs_subvol_done(fs, subvol);