summaryrefslogtreecommitdiffstats
path: root/api
diff options
context:
space:
mode:
Diffstat (limited to 'api')
-rw-r--r--api/src/glfs-fops.c237
-rw-r--r--api/src/glfs-internal.h4
-rw-r--r--api/src/glfs-resolve.c67
3 files changed, 248 insertions, 60 deletions
diff --git a/api/src/glfs-fops.c b/api/src/glfs-fops.c
index 61c524eaf78..fe230e6a9bf 100644
--- a/api/src/glfs-fops.c
+++ b/api/src/glfs-fops.c
@@ -14,6 +14,17 @@
#include "syncop.h"
#include "glfs.h"
+#define DEFAULT_REVAL_COUNT 1
+
+#define ESTALE_RETRY(ret,errno,reval,loc,label) do { \
+ if (ret == -1 && errno == ESTALE) { \
+ if (reval < DEFAULT_REVAL_COUNT) { \
+ reval++; \
+ loc_wipe (loc); \
+ goto label; \
+ } \
+ } \
+ } while (0)
struct glfs_fd *
glfs_open (struct glfs *fs, const char *path, int flags)
@@ -23,6 +34,7 @@ glfs_open (struct glfs *fs, const char *path, int flags)
xlator_t *subvol = NULL;
loc_t loc = {0, };
struct iatt iatt = {0, };
+ int reval = 0;
__glfs_entry_fs (fs);
@@ -37,7 +49,11 @@ glfs_open (struct glfs *fs, const char *path, int flags)
if (!glfd)
goto out;
- ret = glfs_resolve (fs, subvol, path, &loc, &iatt);
+retry:
+ ret = glfs_resolve (fs, subvol, path, &loc, &iatt, reval);
+
+ ESTALE_RETRY (ret, errno, reval, &loc, retry);
+
if (ret)
goto out;
@@ -53,6 +69,11 @@ glfs_open (struct glfs *fs, const char *path, int flags)
goto out;
}
+ if (glfd->fd) {
+ fd_unref (glfd->fd);
+ glfd->fd = NULL;
+ }
+
glfd->fd = fd_create (loc.inode, getpid());
if (!glfd->fd) {
ret = -1;
@@ -61,6 +82,8 @@ glfs_open (struct glfs *fs, const char *path, int flags)
}
ret = syncop_open (subvol, &loc, flags, glfd->fd);
+
+ ESTALE_RETRY (ret, errno, reval, &loc, retry);
out:
loc_wipe (&loc);
@@ -98,6 +121,7 @@ glfs_lstat (struct glfs *fs, const char *path, struct stat *stat)
xlator_t *subvol = NULL;
loc_t loc = {0, };
struct iatt iatt = {0, };
+ int reval = 0;
__glfs_entry_fs (fs);
@@ -107,8 +131,10 @@ glfs_lstat (struct glfs *fs, const char *path, struct stat *stat)
errno = EIO;
goto out;
}
+retry:
+ ret = glfs_lresolve (fs, subvol, path, &loc, &iatt, reval);
- ret = glfs_lresolve (fs, subvol, path, &loc, &iatt);
+ ESTALE_RETRY (ret, errno, reval, &loc, retry);
if (ret == 0 && stat)
iatt_to_stat (&iatt, stat);
@@ -126,6 +152,7 @@ glfs_stat (struct glfs *fs, const char *path, struct stat *stat)
xlator_t *subvol = NULL;
loc_t loc = {0, };
struct iatt iatt = {0, };
+ int reval = 0;
__glfs_entry_fs (fs);
@@ -135,8 +162,10 @@ glfs_stat (struct glfs *fs, const char *path, struct stat *stat)
errno = EIO;
goto out;
}
+retry:
+ ret = glfs_resolve (fs, subvol, path, &loc, &iatt, reval);
- ret = glfs_resolve (fs, subvol, path, &loc, &iatt);
+ ESTALE_RETRY (ret, errno, reval, &loc, retry);
if (ret == 0 && stat)
iatt_to_stat (&iatt, stat);
@@ -182,6 +211,7 @@ glfs_creat (struct glfs *fs, const char *path, int flags, mode_t mode)
struct iatt iatt = {0, };
uuid_t gfid;
dict_t *xattr_req = NULL;
+ int reval = 0;
__glfs_entry_fs (fs);
@@ -216,7 +246,11 @@ glfs_creat (struct glfs *fs, const char *path, int flags, mode_t mode)
is a danging symlink must create the dangling
destinataion.
*/
- ret = glfs_resolve (fs, subvol, path, &loc, &iatt);
+retry:
+ ret = glfs_resolve (fs, subvol, path, &loc, &iatt, reval);
+
+ ESTALE_RETRY (ret, errno, reval, &loc, retry);
+
if (ret == -1 && errno != ENOENT)
/* Any other type of error is fatal */
goto out;
@@ -256,6 +290,11 @@ glfs_creat (struct glfs *fs, const char *path, int flags, mode_t mode)
}
}
+ if (glfd->fd) {
+ fd_unref (glfd->fd);
+ glfd->fd = NULL;
+ }
+
glfd->fd = fd_create (loc.inode, getpid());
if (!glfd->fd) {
ret = -1;
@@ -264,6 +303,8 @@ glfs_creat (struct glfs *fs, const char *path, int flags, mode_t mode)
}
ret = syncop_create (subvol, &loc, flags, mode, glfd->fd, xattr_req);
+
+ ESTALE_RETRY (ret, errno, reval, &loc, retry);
out:
loc_wipe (&loc);
@@ -866,6 +907,7 @@ glfs_access (struct glfs *fs, const char *path, int mode)
xlator_t *subvol = NULL;
loc_t loc = {0, };
struct iatt iatt = {0, };
+ int reval = 0;
__glfs_entry_fs (fs);
@@ -875,12 +917,17 @@ glfs_access (struct glfs *fs, const char *path, int mode)
errno = EIO;
goto out;
}
+retry:
+ ret = glfs_resolve (fs, subvol, path, &loc, &iatt, reval);
+
+ ESTALE_RETRY (ret, errno, reval, &loc, retry);
- ret = glfs_resolve (fs, subvol, path, &loc, &iatt);
if (ret)
goto out;
ret = syncop_access (subvol, &loc, mode);
+
+ ESTALE_RETRY (ret, errno, reval, &loc, retry);
out:
loc_wipe (&loc);
@@ -897,6 +944,7 @@ glfs_symlink (struct glfs *fs, const char *data, const char *path)
struct iatt iatt = {0, };
uuid_t gfid;
dict_t *xattr_req = NULL;
+ int reval = 0;
__glfs_entry_fs (fs);
@@ -921,8 +969,10 @@ glfs_symlink (struct glfs *fs, const char *data, const char *path)
errno = ENOMEM;
goto out;
}
+retry:
+ ret = glfs_lresolve (fs, subvol, path, &loc, &iatt, reval);
- ret = glfs_lresolve (fs, subvol, path, &loc, &iatt);
+ ESTALE_RETRY (ret, errno, reval, &loc, retry);
if (loc.inode) {
errno = EEXIST;
@@ -949,6 +999,8 @@ glfs_symlink (struct glfs *fs, const char *data, const char *path)
}
ret = syncop_symlink (subvol, &loc, data, xattr_req);
+
+ ESTALE_RETRY (ret, errno, reval, &loc, retry);
out:
loc_wipe (&loc);
@@ -966,6 +1018,7 @@ glfs_readlink (struct glfs *fs, const char *path, char *buf, size_t bufsiz)
xlator_t *subvol = NULL;
loc_t loc = {0, };
struct iatt iatt = {0, };
+ int reval = 0;
__glfs_entry_fs (fs);
@@ -975,8 +1028,11 @@ glfs_readlink (struct glfs *fs, const char *path, char *buf, size_t bufsiz)
errno = EIO;
goto out;
}
+retry:
+ ret = glfs_lresolve (fs, subvol, path, &loc, &iatt, reval);
+
+ ESTALE_RETRY (ret, errno, reval, &loc, retry);
- ret = glfs_lresolve (fs, subvol, path, &loc, &iatt);
if (ret)
goto out;
@@ -987,6 +1043,8 @@ glfs_readlink (struct glfs *fs, const char *path, char *buf, size_t bufsiz)
}
ret = syncop_readlink (subvol, &loc, &buf, bufsiz);
+
+ ESTALE_RETRY (ret, errno, reval, &loc, retry);
out:
loc_wipe (&loc);
@@ -1003,6 +1061,7 @@ glfs_mknod (struct glfs *fs, const char *path, mode_t mode, dev_t dev)
struct iatt iatt = {0, };
uuid_t gfid;
dict_t *xattr_req = NULL;
+ int reval = 0;
__glfs_entry_fs (fs);
@@ -1027,8 +1086,10 @@ glfs_mknod (struct glfs *fs, const char *path, mode_t mode, dev_t dev)
errno = ENOMEM;
goto out;
}
+retry:
+ ret = glfs_lresolve (fs, subvol, path, &loc, &iatt, reval);
- ret = glfs_lresolve (fs, subvol, path, &loc, &iatt);
+ ESTALE_RETRY (ret, errno, reval, &loc, retry);
if (loc.inode) {
errno = EEXIST;
@@ -1055,6 +1116,8 @@ glfs_mknod (struct glfs *fs, const char *path, mode_t mode, dev_t dev)
}
ret = syncop_mknod (subvol, &loc, mode, dev, xattr_req);
+
+ ESTALE_RETRY (ret, errno, reval, &loc, retry);
out:
loc_wipe (&loc);
@@ -1074,6 +1137,7 @@ glfs_mkdir (struct glfs *fs, const char *path, mode_t mode)
struct iatt iatt = {0, };
uuid_t gfid;
dict_t *xattr_req = NULL;
+ int reval = 0;
__glfs_entry_fs (fs);
@@ -1098,8 +1162,10 @@ glfs_mkdir (struct glfs *fs, const char *path, mode_t mode)
errno = ENOMEM;
goto out;
}
+retry:
+ ret = glfs_lresolve (fs, subvol, path, &loc, &iatt, reval);
- ret = glfs_lresolve (fs, subvol, path, &loc, &iatt);
+ ESTALE_RETRY (ret, errno, reval, &loc, retry);
if (loc.inode) {
errno = EEXIST;
@@ -1126,6 +1192,8 @@ glfs_mkdir (struct glfs *fs, const char *path, mode_t mode)
}
ret = syncop_mkdir (subvol, &loc, mode, xattr_req);
+
+ ESTALE_RETRY (ret, errno, reval, &loc, retry);
out:
loc_wipe (&loc);
@@ -1143,6 +1211,7 @@ glfs_unlink (struct glfs *fs, const char *path)
xlator_t *subvol = NULL;
loc_t loc = {0, };
struct iatt iatt = {0, };
+ int reval = 0;
__glfs_entry_fs (fs);
@@ -1152,8 +1221,11 @@ glfs_unlink (struct glfs *fs, const char *path)
errno = EIO;
goto out;
}
+retry:
+ ret = glfs_lresolve (fs, subvol, path, &loc, &iatt, reval);
+
+ ESTALE_RETRY (ret, errno, reval, &loc, retry);
- ret = glfs_lresolve (fs, subvol, path, &loc, &iatt);
if (ret)
goto out;
@@ -1164,6 +1236,8 @@ glfs_unlink (struct glfs *fs, const char *path)
}
ret = syncop_unlink (subvol, &loc);
+
+ ESTALE_RETRY (ret, errno, reval, &loc, retry);
out:
loc_wipe (&loc);
@@ -1178,6 +1252,7 @@ glfs_rmdir (struct glfs *fs, const char *path)
xlator_t *subvol = NULL;
loc_t loc = {0, };
struct iatt iatt = {0, };
+ int reval = 0;
__glfs_entry_fs (fs);
@@ -1187,8 +1262,11 @@ glfs_rmdir (struct glfs *fs, const char *path)
errno = EIO;
goto out;
}
+retry:
+ ret = glfs_lresolve (fs, subvol, path, &loc, &iatt, reval);
+
+ ESTALE_RETRY (ret, errno, reval, &loc, retry);
- ret = glfs_lresolve (fs, subvol, path, &loc, &iatt);
if (ret)
goto out;
@@ -1199,6 +1277,8 @@ glfs_rmdir (struct glfs *fs, const char *path)
}
ret = syncop_rmdir (subvol, &loc);
+
+ ESTALE_RETRY (ret, errno, reval, &loc, retry);
out:
loc_wipe (&loc);
@@ -1215,6 +1295,7 @@ glfs_rename (struct glfs *fs, const char *oldpath, const char *newpath)
loc_t newloc = {0, };
struct iatt oldiatt = {0, };
struct iatt newiatt = {0, };
+ int reval = 0;
__glfs_entry_fs (fs);
@@ -1224,12 +1305,18 @@ glfs_rename (struct glfs *fs, const char *oldpath, const char *newpath)
errno = EIO;
goto out;
}
+retry:
+ ret = glfs_lresolve (fs, subvol, oldpath, &oldloc, &oldiatt, reval);
+
+ ESTALE_RETRY (ret, errno, reval, &oldloc, retry);
- ret = glfs_lresolve (fs, subvol, oldpath, &oldloc, &oldiatt);
if (ret)
goto out;
+retrynew:
+ ret = glfs_lresolve (fs, subvol, newpath, &newloc, &newiatt, reval);
+
+ ESTALE_RETRY (ret, errno, reval, &newloc, retrynew);
- ret = glfs_lresolve (fs, subvol, newpath, &newloc, &newiatt);
if (ret && errno != ENOENT && newloc.parent)
goto out;
@@ -1245,6 +1332,15 @@ glfs_rename (struct glfs *fs, const char *oldpath, const char *newpath)
/* TODO: check if new or old is a prefix of the other, and fail EINVAL */
ret = syncop_rename (subvol, &oldloc, &newloc);
+
+ if (ret == -1 && errno == ESTALE) {
+ if (reval < DEFAULT_REVAL_COUNT) {
+ reval++;
+ loc_wipe (&oldloc);
+ loc_wipe (&newloc);
+ goto retry;
+ }
+ }
out:
loc_wipe (&oldloc);
loc_wipe (&newloc);
@@ -1262,6 +1358,7 @@ glfs_link (struct glfs *fs, const char *oldpath, const char *newpath)
loc_t newloc = {0, };
struct iatt oldiatt = {0, };
struct iatt newiatt = {0, };
+ int reval = 0;
__glfs_entry_fs (fs);
@@ -1271,12 +1368,18 @@ glfs_link (struct glfs *fs, const char *oldpath, const char *newpath)
errno = EIO;
goto out;
}
+retry:
+ ret = glfs_lresolve (fs, subvol, oldpath, &oldloc, &oldiatt, reval);
+
+ ESTALE_RETRY (ret, errno, reval, &oldloc, retry);
- ret = glfs_lresolve (fs, subvol, oldpath, &oldloc, &oldiatt);
if (ret)
goto out;
+retrynew:
+ ret = glfs_lresolve (fs, subvol, newpath, &newloc, &newiatt, reval);
+
+ ESTALE_RETRY (ret, errno, reval, &newloc, retrynew);
- ret = glfs_lresolve (fs, subvol, newpath, &newloc, &newiatt);
if (ret == 0) {
ret = -1;
errno = EEXIST;
@@ -1290,6 +1393,14 @@ glfs_link (struct glfs *fs, const char *oldpath, const char *newpath)
}
ret = syncop_link (subvol, &oldloc, &newloc);
+
+ if (ret == -1 && errno == ESTALE) {
+ loc_wipe (&oldloc);
+ loc_wipe (&newloc);
+ if (reval--)
+ goto retry;
+ }
+
out:
loc_wipe (&oldloc);
loc_wipe (&newloc);
@@ -1306,6 +1417,7 @@ glfs_opendir (struct glfs *fs, const char *path)
xlator_t *subvol = NULL;
loc_t loc = {0, };
struct iatt iatt = {0, };
+ int reval = 0;
__glfs_entry_fs (fs);
@@ -1319,9 +1431,13 @@ glfs_opendir (struct glfs *fs, const char *path)
glfd = glfs_fd_new (fs);
if (!glfd)
goto out;
+
INIT_LIST_HEAD (&glfd->entries);
+retry:
+ ret = glfs_resolve (fs, subvol, path, &loc, &iatt, reval);
+
+ ESTALE_RETRY (ret, errno, reval, &loc, retry);
- ret = glfs_resolve (fs, subvol, path, &loc, &iatt);
if (ret)
goto out;
@@ -1331,6 +1447,11 @@ glfs_opendir (struct glfs *fs, const char *path)
goto out;
}
+ if (glfd->fd) {
+ fd_unref (glfd->fd);
+ glfd->fd = NULL;
+ }
+
glfd->fd = fd_create (loc.inode, getpid());
if (!glfd->fd) {
ret = -1;
@@ -1339,6 +1460,8 @@ glfs_opendir (struct glfs *fs, const char *path)
}
ret = syncop_opendir (subvol, &loc, glfd->fd);
+
+ ESTALE_RETRY (ret, errno, reval, &loc, retry);
out:
loc_wipe (&loc);
@@ -1538,6 +1661,7 @@ glfs_statvfs (struct glfs *fs, const char *path, struct statvfs *buf)
xlator_t *subvol = NULL;
loc_t loc = {0, };
struct iatt iatt = {0, };
+ int reval = 0;
__glfs_entry_fs (fs);
@@ -1547,12 +1671,17 @@ glfs_statvfs (struct glfs *fs, const char *path, struct statvfs *buf)
errno = EIO;
goto out;
}
+retry:
+ ret = glfs_resolve (fs, subvol, path, &loc, &iatt, reval);
+
+ ESTALE_RETRY (ret, errno, reval, &loc, retry);
- ret = glfs_resolve (fs, subvol, path, &loc, &iatt);
if (ret)
goto out;
ret = syncop_statfs (subvol, &loc, buf);
+
+ ESTALE_RETRY (ret, errno, reval, &loc, retry);
out:
loc_wipe (&loc);
@@ -1568,6 +1697,7 @@ glfs_setattr (struct glfs *fs, const char *path, struct iatt *iatt,
xlator_t *subvol = NULL;
loc_t loc = {0, };
struct iatt riatt = {0, };
+ int reval = 0;
__glfs_entry_fs (fs);
@@ -1577,16 +1707,20 @@ glfs_setattr (struct glfs *fs, const char *path, struct iatt *iatt,
errno = EIO;
goto out;
}
-
+retry:
if (follow)
- ret = glfs_resolve (fs, subvol, path, &loc, &riatt);
+ ret = glfs_resolve (fs, subvol, path, &loc, &riatt, reval);
else
- ret = glfs_lresolve (fs, subvol, path, &loc, &riatt);
+ ret = glfs_lresolve (fs, subvol, path, &loc, &riatt, reval);
+
+ ESTALE_RETRY (ret, errno, reval, &loc, retry);
if (ret)
goto out;
ret = syncop_setattr (subvol, &loc, iatt, valid, 0, 0);
+
+ ESTALE_RETRY (ret, errno, reval, &loc, retry);
out:
loc_wipe (&loc);
@@ -1799,6 +1933,7 @@ glfs_getxattr_common (struct glfs *fs, const char *path, const char *name,
loc_t loc = {0, };
struct iatt iatt = {0, };
dict_t *xattr = NULL;
+ int reval = 0;
__glfs_entry_fs (fs);
@@ -1808,15 +1943,21 @@ glfs_getxattr_common (struct glfs *fs, const char *path, const char *name,
errno = EIO;
goto out;
}
-
+retry:
if (follow)
- ret = glfs_resolve (fs, subvol, path, &loc, &iatt);
+ ret = glfs_resolve (fs, subvol, path, &loc, &iatt, reval);
else
- ret = glfs_lresolve (fs, subvol, path, &loc, &iatt);
+ ret = glfs_lresolve (fs, subvol, path, &loc, &iatt, reval);
+
+ ESTALE_RETRY (ret, errno, reval, &loc, retry);
+
if (ret)
goto out;
ret = syncop_getxattr (subvol, &loc, &xattr, name);
+
+ ESTALE_RETRY (ret, errno, reval, &loc, retry);
+
if (ret)
goto out;
@@ -1904,6 +2045,7 @@ glfs_listxattr_common (struct glfs *fs, const char *path, void *value,
loc_t loc = {0, };
struct iatt iatt = {0, };
dict_t *xattr = NULL;
+ int reval = 0;
__glfs_entry_fs (fs);
@@ -1914,14 +2056,21 @@ glfs_listxattr_common (struct glfs *fs, const char *path, void *value,
goto out;
}
+retry:
if (follow)
- ret = glfs_resolve (fs, subvol, path, &loc, &iatt);
+ ret = glfs_resolve (fs, subvol, path, &loc, &iatt, reval);
else
- ret = glfs_lresolve (fs, subvol, path, &loc, &iatt);
+ ret = glfs_lresolve (fs, subvol, path, &loc, &iatt, reval);
+
+ ESTALE_RETRY (ret, errno, reval, &loc, retry);
+
if (ret)
goto out;
ret = syncop_getxattr (subvol, &loc, &xattr, NULL);
+
+ ESTALE_RETRY (ret, errno, reval, &loc, retry);
+
if (ret)
goto out;
@@ -2002,6 +2151,7 @@ glfs_setxattr_common (struct glfs *fs, const char *path, const char *name,
loc_t loc = {0, };
struct iatt iatt = {0, };
dict_t *xattr = NULL;
+ int reval = 0;
__glfs_entry_fs (fs);
@@ -2011,11 +2161,14 @@ glfs_setxattr_common (struct glfs *fs, const char *path, const char *name,
errno = EIO;
goto out;
}
-
+retry:
if (follow)
- ret = glfs_resolve (fs, subvol, path, &loc, &iatt);
+ ret = glfs_resolve (fs, subvol, path, &loc, &iatt, reval);
else
- ret = glfs_lresolve (fs, subvol, path, &loc, &iatt);
+ ret = glfs_lresolve (fs, subvol, path, &loc, &iatt, reval);
+
+ ESTALE_RETRY (ret, errno, reval, &loc, retry);
+
if (ret)
goto out;
@@ -2027,6 +2180,9 @@ glfs_setxattr_common (struct glfs *fs, const char *path, const char *name,
}
ret = syncop_setxattr (subvol, &loc, xattr, flags);
+
+ ESTALE_RETRY (ret, errno, reval, &loc, retry);
+
out:
loc_wipe (&loc);
if (xattr)
@@ -2093,6 +2249,7 @@ glfs_removexattr_common (struct glfs *fs, const char *path, const char *name,
xlator_t *subvol = NULL;
loc_t loc = {0, };
struct iatt iatt = {0, };
+ int reval = 0;
__glfs_entry_fs (fs);
@@ -2102,15 +2259,21 @@ glfs_removexattr_common (struct glfs *fs, const char *path, const char *name,
errno = EIO;
goto out;
}
-
+retry:
if (follow)
- ret = glfs_resolve (fs, subvol, path, &loc, &iatt);
+ ret = glfs_resolve (fs, subvol, path, &loc, &iatt, reval);
else
- ret = glfs_lresolve (fs, subvol, path, &loc, &iatt);
+ ret = glfs_lresolve (fs, subvol, path, &loc, &iatt, reval);
+
+ ESTALE_RETRY (ret, errno, reval, &loc, retry);
+
if (ret)
goto out;
ret = syncop_removexattr (subvol, &loc, name);
+
+ ESTALE_RETRY (ret, errno, reval, &loc, retry);
+
out:
loc_wipe (&loc);
@@ -2172,6 +2335,7 @@ glfs_chdir (struct glfs *fs, const char *path)
xlator_t *subvol = NULL;
loc_t loc = {0, };
struct iatt iatt = {0, };
+ int reval = 0;
__glfs_entry_fs (fs);
@@ -2181,8 +2345,11 @@ glfs_chdir (struct glfs *fs, const char *path)
errno = EIO;
goto out;
}
+retry:
+ ret = glfs_resolve (fs, subvol, path, &loc, &iatt, reval);
+
+ ESTALE_RETRY (ret, errno, reval, &loc, retry);
- ret = glfs_resolve (fs, subvol, path, &loc, &iatt);
if (ret)
goto out;
@@ -2233,6 +2400,7 @@ glfs_realpath (struct glfs *fs, const char *path, char *resolved_path)
xlator_t *subvol = NULL;
loc_t loc = {0, };
struct iatt iatt = {0, };
+ int reval = 0;
__glfs_entry_fs (fs);
@@ -2253,8 +2421,11 @@ glfs_realpath (struct glfs *fs, const char *path, char *resolved_path)
errno = EIO;
goto out;
}
+retry:
+ ret = glfs_resolve (fs, subvol, path, &loc, &iatt, reval);
+
+ ESTALE_RETRY (ret, errno, reval, &loc, retry);
- ret = glfs_resolve (fs, subvol, path, &loc, &iatt);
if (ret)
goto out;
diff --git a/api/src/glfs-internal.h b/api/src/glfs-internal.h
index 082b8fa5c9a..7c622637da0 100644
--- a/api/src/glfs-internal.h
+++ b/api/src/glfs-internal.h
@@ -57,9 +57,9 @@ int glfs_mgmt_init (struct glfs *fs);
void glfs_init_done (struct glfs *fs, int ret);
int glfs_process_volfp (struct glfs *fs, FILE *fp);
int glfs_resolve (struct glfs *fs, xlator_t *subvol, const char *path, loc_t *loc,
- struct iatt *iatt);
+ struct iatt *iatt, int reval);
int glfs_lresolve (struct glfs *fs, xlator_t *subvol, const char *path, loc_t *loc,
- struct iatt *iatt);
+ struct iatt *iatt, int reval);
void glfs_first_lookup (xlator_t *subvol);
static inline void
diff --git a/api/src/glfs-resolve.c b/api/src/glfs-resolve.c
index 17cf19d0fdc..07fc1b7c56a 100644
--- a/api/src/glfs-resolve.c
+++ b/api/src/glfs-resolve.c
@@ -136,7 +136,8 @@ out:
inode_t *
glfs_resolve_component (struct glfs *fs, xlator_t *subvol, inode_t *parent,
- const char *component, struct iatt *iatt)
+ const char *component, struct iatt *iatt,
+ int force_lookup)
{
loc_t loc = {0, };
inode_t *inode = NULL;
@@ -152,17 +153,6 @@ glfs_resolve_component (struct glfs *fs, xlator_t *subvol, inode_t *parent,
loc.parent = inode_ref (parent);
uuid_copy (loc.pargfid, parent->gfid);
- xattr_req = dict_new ();
- if (!xattr_req) {
- errno = ENOMEM;
- goto out;
- }
-
- ret = dict_set_static_bin (xattr_req, "gfid-req", gfid, 16);
- if (ret) {
- errno = ENOMEM;
- goto out;
- }
if (strcmp (component, ".") == 0)
loc.inode = inode_ref (parent);
@@ -174,6 +164,12 @@ glfs_resolve_component (struct glfs *fs, xlator_t *subvol, inode_t *parent,
if (loc.inode) {
uuid_copy (loc.gfid, loc.inode->gfid);
reval = 1;
+
+ if (!force_lookup) {
+ inode = inode_ref (loc.inode);
+ ciatt.ia_type = inode->ia_type;
+ goto found;
+ }
} else {
uuid_generate (gfid);
loc.inode = inode_new (parent->table);
@@ -182,20 +178,35 @@ glfs_resolve_component (struct glfs *fs, xlator_t *subvol, inode_t *parent,
if (!loc.inode)
goto out;
-
glret = glfs_loc_touchup (&loc);
if (glret < 0) {
ret = -1;
goto out;
}
- ret = syncop_lookup (subvol, &loc, xattr_req, &ciatt, NULL, NULL);
+ ret = syncop_lookup (subvol, &loc, NULL, &ciatt, NULL, NULL);
if (ret && reval) {
inode_unref (loc.inode);
loc.inode = inode_new (parent->table);
- if (!loc.inode)
+ if (!loc.inode) {
+ errno = ENOMEM;
goto out;
+ }
+
+ xattr_req = dict_new ();
+ if (!xattr_req) {
+ errno = ENOMEM;
+ goto out;
+ }
+
uuid_generate (gfid);
+
+ ret = dict_set_static_bin (xattr_req, "gfid-req", gfid, 16);
+ if (ret) {
+ errno = ENOMEM;
+ goto out;
+ }
+
ret = syncop_lookup (subvol, &loc, xattr_req, &ciatt,
NULL, NULL);
}
@@ -203,6 +214,7 @@ glfs_resolve_component (struct glfs *fs, xlator_t *subvol, inode_t *parent,
goto out;
inode = inode_link (loc.inode, loc.parent, component, &ciatt);
+found:
if (inode)
inode_lookup (inode);
if (iatt)
@@ -220,7 +232,7 @@ out:
int
glfs_resolve_at (struct glfs *fs, xlator_t *subvol, inode_t *at,
const char *origpath, loc_t *loc, struct iatt *iatt,
- int follow)
+ int follow, int reval)
{
inode_t *inode = NULL;
inode_t *parent = NULL;
@@ -260,7 +272,12 @@ glfs_resolve_at (struct glfs *fs, xlator_t *subvol, inode_t *at,
parent = inode;
inode = glfs_resolve_component (fs, subvol, parent,
- component, &ciatt);
+ component, &ciatt,
+ /* force hard lookup on the last
+ component, as the caller
+ wants proper iatt filled
+ */
+ (reval || !next_component));
if (!inode)
break;
@@ -287,7 +304,7 @@ glfs_resolve_at (struct glfs *fs, xlator_t *subvol, inode_t *at,
/* always recurisvely follow while
following symlink
*/
- 1);
+ 1, reval);
if (ret == 0)
inode = inode_ref (sym_loc.inode);
loc_wipe (&sym_loc);
@@ -344,16 +361,16 @@ out:
int
glfs_resolve_path (struct glfs *fs, xlator_t *subvol, const char *origpath,
- loc_t *loc, struct iatt *iatt, int follow)
+ loc_t *loc, struct iatt *iatt, int follow, int reval)
{
int ret = -1;
if (origpath[0] == '/')
ret = glfs_resolve_at (fs, subvol, NULL, origpath, loc, iatt,
- follow);
+ follow, reval);
else
ret = glfs_resolve_at (fs, subvol, fs->cwd, origpath, loc, iatt,
- follow);
+ follow, reval);
return ret;
}
@@ -361,11 +378,11 @@ glfs_resolve_path (struct glfs *fs, xlator_t *subvol, const char *origpath,
int
glfs_resolve (struct glfs *fs, xlator_t *subvol, const char *origpath,
- loc_t *loc, struct iatt *iatt)
+ loc_t *loc, struct iatt *iatt, int reval)
{
int ret = -1;
- ret = glfs_resolve_path (fs, subvol, origpath, loc, iatt, 1);
+ ret = glfs_resolve_path (fs, subvol, origpath, loc, iatt, 1, reval);
return ret;
}
@@ -373,11 +390,11 @@ glfs_resolve (struct glfs *fs, xlator_t *subvol, const char *origpath,
int
glfs_lresolve (struct glfs *fs, xlator_t *subvol, const char *origpath,
- loc_t *loc, struct iatt *iatt)
+ loc_t *loc, struct iatt *iatt, int reval)
{
int ret = -1;
- ret = glfs_resolve_path (fs, subvol, origpath, loc, iatt, 0);
+ ret = glfs_resolve_path (fs, subvol, origpath, loc, iatt, 0, reval);
return ret;
}