diff options
Diffstat (limited to 'xlators/nfs/server/src/nfs3-helpers.c')
| -rw-r--r-- | xlators/nfs/server/src/nfs3-helpers.c | 432 |
1 files changed, 103 insertions, 329 deletions
diff --git a/xlators/nfs/server/src/nfs3-helpers.c b/xlators/nfs/server/src/nfs3-helpers.c index 7075b3e6c..9059fc341 100644 --- a/xlators/nfs/server/src/nfs3-helpers.c +++ b/xlators/nfs/server/src/nfs3-helpers.c @@ -2,19 +2,10 @@ Copyright (c) 2010-2011 Gluster, Inc. <http://www.gluster.com> This file is part of GlusterFS. - GlusterFS is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published - by the Free Software Foundation; either version 3 of the License, - or (at your option) any later version. - - GlusterFS is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see - <http://www.gnu.org/licenses/>. + This file is licensed to you under your choice of the GNU Lesser + General Public License, version 3 or any later version (LGPLv3 or + later), or the GNU General Public License, version 2 (GPLv2), in all + cases as published by the Free Software Foundation. */ #ifndef _CONFIG_H @@ -102,21 +93,18 @@ struct nfs3stat_strerror nfs3stat_strerror_table[] = { uint64_t nfs3_iatt_gfid_to_ino (struct iatt *buf) { - uuid_t gfid = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}; - uint64_t ino = 0; + uint64_t ino = 0; if (!buf) return 0; - if ((buf->ia_ino != 1) && (uuid_compare (buf->ia_gfid, gfid) != 0)) { - if (gf_nfs_enable_ino32()) { - ino = (uint32_t )nfs_hash_gfid (buf->ia_gfid); - goto hashout; - } + if (gf_nfs_enable_ino32()) { + ino = (uint32_t )nfs_hash_gfid (buf->ia_gfid); + goto hashout; + } - memcpy (&ino, &buf->ia_gfid[8], sizeof (uint64_t)); - } else - ino = 1; + /* from posix its guaranteed to send unique ino */ + ino = buf->ia_ino; hashout: return ino; @@ -268,6 +256,20 @@ nfs3_errno_to_nfsstat3 (int errnum) return stat; } +/* + * Special case: If op_ret is -1, it's very unusual op_errno being + * 0 which means something came wrong from upper layer(s). If it + * happens by any means, then set NFS3 status to NFS3ERR_SERVERFAULT. + */ +inline nfsstat3 +nfs3_cbk_errno_status (int32_t op_ret, int32_t op_errno) +{ + if ((op_ret == -1) && (op_errno == 0)) { + return NFS3ERR_SERVERFAULT; + } + + return nfs3_errno_to_nfsstat3 (op_errno); +} void nfs3_fill_lookup3res_error (lookup3res *res, nfsstat3 stat, @@ -287,6 +289,9 @@ nfs3_stat_to_fattr3 (struct iatt *buf) { fattr3 fa = {0, }; + if (buf == NULL) + goto out; + if (IA_ISDIR (buf->ia_type)) fa.type = NF3DIR; else if (IA_ISREG (buf->ia_type)) @@ -356,6 +361,7 @@ nfs3_stat_to_fattr3 (struct iatt *buf) fa.mtime.seconds = buf->ia_mtime; fa.mtime.nseconds = buf->ia_mtime_nsec; +out: return fa; } @@ -499,7 +505,7 @@ nfs3_fill_fsinfo3res (struct nfs3_state *nfs3, fsinfo3res *res, resok.wtpref = nfs3->writesize; resok.wtmult = GF_NFS3_WTMULT; resok.dtpref = nfs3->readdirsize; - resok.maxfilesize = GF_NFS3_MAXFILE; + resok.maxfilesize = GF_NFS3_MAXFILESIZE; resok.time_delta = tdelta; resok.properties = GF_NFS3_FS_PROP; @@ -567,7 +573,7 @@ nfs3_accessbits (int32_t accbits) accresult |= ACCESS3_READ; if (accbits & POSIX_WRITE) - accresult |= (ACCESS3_MODIFY | ACCESS3_EXTEND); + accresult |= (ACCESS3_MODIFY | ACCESS3_EXTEND | ACCESS3_DELETE); /* lookup on directory allowed only in case of execute permission */ if (accbits & POSIX_EXEC) @@ -584,7 +590,7 @@ nfs3_request_to_accessbits (int32_t accbits) if (accbits & ACCESS3_READ) acc_request |= POSIX_READ; - if (accbits & (ACCESS3_MODIFY | ACCESS3_EXTEND)) + if (accbits & (ACCESS3_MODIFY | ACCESS3_EXTEND | ACCESS3_DELETE)) acc_request |= POSIX_WRITE; /* For lookup on directory check for execute permission */ @@ -594,7 +600,8 @@ nfs3_request_to_accessbits (int32_t accbits) return acc_request; } void -nfs3_fill_access3res (access3res *res, nfsstat3 status, int32_t accbits) +nfs3_fill_access3res (access3res *res, nfsstat3 status, int32_t accbits, + int32_t reqaccbits) { uint32_t accres = 0; @@ -605,7 +612,8 @@ nfs3_fill_access3res (access3res *res, nfsstat3 status, int32_t accbits) accres = nfs3_accessbits (accbits); - res->access3res_u.resok.access = accres; + /* do not answer what was not asked */ + res->access3res_u.resok.access = accres & reqaccbits; } void @@ -1608,13 +1616,14 @@ err: void nfs3_stat_to_errstr (uint32_t xid, char *op, nfsstat3 stat, int pstat, - char *errstr) + char *errstr, size_t len) { if ((!op) || (!errstr)) return; - sprintf (errstr, "XID: %x, %s: NFS: %d(%s), POSIX: %d(%s)", xid, op, - stat, nfsstat3_strerror (stat), pstat, strerror (pstat)); + snprintf (errstr, len, "XID: %x, %s: NFS: %d(%s), POSIX: %d(%s)", + xid, op,stat, nfsstat3_strerror (stat), pstat, + strerror (pstat)); } void @@ -1622,10 +1631,10 @@ nfs3_log_common_call (uint32_t xid, char *op, struct nfs3_fh *fh) { char fhstr[1024]; - if (gf_log_loglevel < GF_LOG_DEBUG) - return; + if (THIS->ctx->log.loglevel < GF_LOG_DEBUG) + return; - nfs3_fh_to_str (fh, fhstr); + nfs3_fh_to_str (fh, fhstr, sizeof (fhstr)); gf_log (GF_NFS3, GF_LOG_DEBUG, "XID: %x, %s: args: %s", xid, op, fhstr); } @@ -1637,9 +1646,9 @@ nfs3_log_fh_entry_call (uint32_t xid, char *op, struct nfs3_fh *fh, { char fhstr[1024]; - if (gf_log_loglevel < GF_LOG_DEBUG) - return; - nfs3_fh_to_str (fh, fhstr); + if (THIS->ctx->log.loglevel < GF_LOG_DEBUG) + return; + nfs3_fh_to_str (fh, fhstr, sizeof (fhstr)); gf_log (GF_NFS3, GF_LOG_DEBUG, "XID: %x, %s: args: %s, name: %s", xid, op, fhstr, name); } @@ -1652,10 +1661,10 @@ nfs3_log_rename_call (uint32_t xid, struct nfs3_fh *src, char *sname, char sfhstr[1024]; char dfhstr[1024]; - if (gf_log_loglevel < GF_LOG_DEBUG) - return; - nfs3_fh_to_str (src, sfhstr); - nfs3_fh_to_str (dst, dfhstr); + if (THIS->ctx->log.loglevel < GF_LOG_DEBUG) + return; + nfs3_fh_to_str (src, sfhstr, sizeof (sfhstr)); + nfs3_fh_to_str (dst, dfhstr, sizeof (dfhstr)); gf_log (GF_NFS3, GF_LOG_DEBUG, "XID: %x, RENAME: args: Src: %s, " "name: %s, Dst: %s, name: %s", xid, sfhstr, sname, dfhstr, dname); @@ -1673,9 +1682,9 @@ nfs3_log_create_call (uint32_t xid, struct nfs3_fh *fh, char *name, char unchkd[] = "UNCHECKED"; char guarded[] = "GUARDED"; - if (gf_log_loglevel < GF_LOG_DEBUG) - return; - nfs3_fh_to_str (fh, fhstr); + if (THIS->ctx->log.loglevel < GF_LOG_DEBUG) + return; + nfs3_fh_to_str (fh, fhstr, sizeof (fhstr)); if (mode == EXCLUSIVE) modestr = exclmode; else if (mode == GUARDED) @@ -1698,9 +1707,9 @@ nfs3_log_mknod_call (uint32_t xid, struct nfs3_fh *fh, char *name, int type) char sock[] = "SOCK"; char fifo[] = "FIFO"; - if (gf_log_loglevel < GF_LOG_DEBUG) - return; - nfs3_fh_to_str (fh, fhstr); + if (THIS->ctx->log.loglevel < GF_LOG_DEBUG) + return; + nfs3_fh_to_str (fh, fhstr, sizeof (fhstr)); if (type == NF3CHR) modestr = chr; else if (type == NF3BLK) @@ -1721,9 +1730,9 @@ nfs3_log_symlink_call (uint32_t xid, struct nfs3_fh *fh, char *name, char *tgt) { char fhstr[1024]; - if (gf_log_loglevel < GF_LOG_DEBUG) - return; - nfs3_fh_to_str (fh, fhstr); + if (THIS->ctx->log.loglevel < GF_LOG_DEBUG) + return; + nfs3_fh_to_str (fh, fhstr, sizeof (fhstr)); gf_log (GF_NFS3, GF_LOG_DEBUG, "XID: %x, SYMLINK: args: %s, name: %s," " target: %s", xid, fhstr, name, tgt); } @@ -1736,10 +1745,10 @@ nfs3_log_link_call (uint32_t xid, struct nfs3_fh *fh, char *name, char dfhstr[1024]; char tfhstr[1024]; - if (gf_log_loglevel < GF_LOG_DEBUG) - return; - nfs3_fh_to_str (fh, dfhstr); - nfs3_fh_to_str (tgt, tfhstr); + if (THIS->ctx->log.loglevel < GF_LOG_DEBUG) + return; + nfs3_fh_to_str (fh, dfhstr, sizeof (dfhstr)); + nfs3_fh_to_str (tgt, tfhstr, sizeof (tfhstr)); gf_log (GF_NFS3, GF_LOG_DEBUG, "XID: %x, LINK: args: %s, name: %s," " target: %s", xid, dfhstr, name, tfhstr); } @@ -1751,9 +1760,9 @@ nfs3_log_rw_call (uint32_t xid, char *op, struct nfs3_fh *fh, offset3 offt, { char fhstr[1024]; - if (gf_log_loglevel < GF_LOG_DEBUG) - return; - nfs3_fh_to_str (fh, fhstr); + if (THIS->ctx->log.loglevel < GF_LOG_DEBUG) + return; + nfs3_fh_to_str (fh, fhstr, sizeof (fhstr)); if (stablewrite == -1) gf_log (GF_NFS3, GF_LOG_DEBUG, "XID: %x, %s: args: %s, offset:" " %"PRIu64", count: %"PRIu32, xid, op, fhstr, offt, @@ -3384,11 +3393,11 @@ void nfs3_log_common_res (uint32_t xid, int op, nfsstat3 stat, int pstat) { char errstr[1024]; - int ll = nfs3_loglevel (op, stat); + int ll = nfs3_loglevel (op, stat); - if (gf_log_loglevel < ll) - return; - nfs3_stat_to_errstr (xid, nfs3op_strings[op].str, stat, pstat, errstr); + if (THIS->ctx->log.loglevel < ll) + return; + nfs3_stat_to_errstr (xid, nfs3op_strings[op].str, stat, pstat, errstr, sizeof (errstr)); gf_log (GF_NFS3, ll, "%s", errstr); } @@ -3396,14 +3405,14 @@ void nfs3_log_readlink_res (uint32_t xid, nfsstat3 stat, int pstat, char *linkpath) { char errstr[1024]; - int ll = nfs3_loglevel (NFS3_READLINK, stat); + int ll = nfs3_loglevel (NFS3_READLINK, stat); - if (gf_log_loglevel < ll) - return; + if (THIS->ctx->log.loglevel < ll) + return; - nfs3_stat_to_errstr (xid, "READLINK", stat, pstat, errstr); + nfs3_stat_to_errstr (xid, "READLINK", stat, pstat, errstr, sizeof (errstr)); gf_log (GF_NFS3, ll, "%s, target: %s", - errstr, linkpath); + errstr, linkpath); } @@ -3412,12 +3421,12 @@ nfs3_log_read_res (uint32_t xid, nfsstat3 stat, int pstat, count3 count, int is_eof, struct iovec *vec, int32_t veccount) { char errstr[1024]; - int ll = GF_LOG_DEBUG; + int ll = GF_LOG_DEBUG; ll = nfs3_loglevel (NFS3_READ, stat); - if (gf_log_loglevel < ll) - return; - nfs3_stat_to_errstr (xid, "READ", stat, pstat, errstr); + if (THIS->ctx->log.loglevel < ll) + return; + nfs3_stat_to_errstr (xid, "READ", stat, pstat, errstr, sizeof (errstr)); if (vec) gf_log (GF_NFS3, ll, "%s, count: %"PRIu32", is_eof:" " %d, vector: count: %d, len: %zd", errstr, count, @@ -3433,12 +3442,12 @@ nfs3_log_write_res (uint32_t xid, nfsstat3 stat, int pstat, count3 count, int stable, uint64_t wverf) { char errstr[1024]; - int ll = nfs3_loglevel (NFS3_WRITE, stat); + int ll = nfs3_loglevel (NFS3_WRITE, stat); - if (gf_log_loglevel < ll) - return; + if (THIS->ctx->log.loglevel < ll) + return; - nfs3_stat_to_errstr (xid, "WRITE", stat, pstat, errstr); + nfs3_stat_to_errstr (xid, "WRITE", stat, pstat, errstr, sizeof (errstr)); gf_log (GF_NFS3, ll, "%s, count: %"PRIu32", %s,wverf: %"PRIu64 , errstr, count, (stable == UNSTABLE)?"UNSTABLE":"STABLE", wverf); @@ -3451,12 +3460,12 @@ nfs3_log_newfh_res (uint32_t xid, int op, nfsstat3 stat, int pstat, { char errstr[1024]; char fhstr[1024]; - int ll = nfs3_loglevel (op, stat); + int ll = nfs3_loglevel (op, stat); - if (gf_log_loglevel < ll) - return; - nfs3_stat_to_errstr (xid, nfs3op_strings[op].str, stat, pstat, errstr); - nfs3_fh_to_str (newfh, fhstr); + if (THIS->ctx->log.loglevel < ll) + return; + nfs3_stat_to_errstr (xid, nfs3op_strings[op].str, stat, pstat, errstr, sizeof (errstr)); + nfs3_fh_to_str (newfh, fhstr, sizeof (fhstr)); gf_log (GF_NFS3, nfs3_loglevel (op, stat), "%s, %s", errstr, fhstr); } @@ -3467,11 +3476,11 @@ nfs3_log_readdir_res (uint32_t xid, nfsstat3 stat, int pstat, uint64_t cverf, count3 count, int is_eof) { char errstr[1024]; - int ll = nfs3_loglevel (NFS3_READDIR, stat); + int ll = nfs3_loglevel (NFS3_READDIR, stat); - if (gf_log_loglevel < ll) - return; - nfs3_stat_to_errstr (xid, "READDIR", stat, pstat, errstr); + if (THIS->ctx->log.loglevel < ll) + return; + nfs3_stat_to_errstr (xid, "READDIR", stat, pstat, errstr, sizeof (errstr)); gf_log (GF_NFS3, ll, "%s, count: %"PRIu32", cverf: %"PRIu64 ", is_eof: %d", errstr, count, cverf, is_eof); } @@ -3484,9 +3493,9 @@ nfs3_log_readdirp_res (uint32_t xid, nfsstat3 stat, int pstat, uint64_t cverf, char errstr[1024]; int ll = nfs3_loglevel (NFS3_READDIRP, stat); - if (gf_log_loglevel < ll) - return; - nfs3_stat_to_errstr (xid, "READDIRPLUS", stat, pstat, errstr); + if (THIS->ctx->log.loglevel < ll) + return; + nfs3_stat_to_errstr (xid, "READDIRPLUS", stat, pstat, errstr, sizeof (errstr)); gf_log (GF_NFS3, ll, "%s, dircount: %"PRIu32", maxcount: %" PRIu32", cverf: %"PRIu64", is_eof: %d", errstr, dircount, maxcount, cverf, is_eof); @@ -3499,9 +3508,9 @@ nfs3_log_commit_res (uint32_t xid, nfsstat3 stat, int pstat, uint64_t wverf) char errstr[1024]; int ll = nfs3_loglevel (NFS3_COMMIT, stat); - if (gf_log_loglevel < ll) - return; - nfs3_stat_to_errstr (xid, "COMMIT", stat, pstat, errstr); + if (THIS->ctx->log.loglevel < ll) + return; + nfs3_stat_to_errstr (xid, "COMMIT", stat, pstat, errstr, sizeof (errstr)); gf_log (GF_NFS3, ll, "%s, wverf: %"PRIu64, errstr, wverf); } @@ -3512,10 +3521,10 @@ nfs3_log_readdir_call (uint32_t xid, struct nfs3_fh *fh, count3 dircount, { char fhstr[1024]; - if (gf_log_loglevel < GF_LOG_DEBUG) - return; + if (THIS->ctx->log.loglevel < GF_LOG_DEBUG) + return; - nfs3_fh_to_str (fh, fhstr); + nfs3_fh_to_str (fh, fhstr, sizeof (fhstr)); if (maxcount == 0) gf_log (GF_NFS3, GF_LOG_DEBUG, "XID: %x, READDIR: args: %s," @@ -3548,55 +3557,6 @@ err: return ret; } -#define GF_NFS3_FHRESOLVE_FOUND 1 -#define GF_NFS3_FHRESOLVE_NOTFOUND 2 -#define GF_NFS3_FHRESOLVE_DIRFOUND 3 - -int -nfs3_fh_resolve_check_entry (struct nfs3_fh *fh, gf_dirent_t *candidate, - int hashidx) -{ - struct iatt *ia = NULL; - int ret = GF_NFS3_FHRESOLVE_NOTFOUND; - nfs3_hash_entry_t entryhash = 0; - - if ((!fh) || (!candidate)) - return ret; - - if ((strcmp (candidate->d_name, ".") == 0) || - (strcmp (candidate->d_name, "..") == 0)) - goto found_entry; - - ia = &candidate->d_stat; - if ((uuid_compare (candidate->d_stat.ia_gfid, fh->gfid)) == 0) { - gf_log (GF_NFS3, GF_LOG_TRACE, "Found entry: gfid: %s, " - "name: %s, hashcount %d", - uuid_utoa (candidate->d_stat.ia_gfid), - candidate->d_name, hashidx); - ret = GF_NFS3_FHRESOLVE_FOUND; - goto found_entry; - } - - /* This condition ensures that we never have to be afraid of having - * a directory hash conflict with a file hash. The consequence of - * this condition is that we can now have unlimited files in a directory - * and upto 65536 sub-directories in a directory. - */ - if (!IA_ISDIR (candidate->d_stat.ia_type)) - goto found_entry; - entryhash = fh->entryhash[hashidx]; - if (entryhash == nfs3_fh_hash_entry (ia->ia_gfid)) { - gf_log (GF_NFS3, GF_LOG_TRACE, "Found hash match: %s: %d, " - "hashidx: %d", candidate->d_name, entryhash, hashidx); - ret = GF_NFS3_FHRESOLVE_DIRFOUND; - goto found_entry; - } - -found_entry: - - return ret; -} - int32_t nfs3_fh_resolve_entry_lookup_cbk (call_frame_t *frame, void *cookie, @@ -3627,7 +3587,8 @@ nfs3_fh_resolve_entry_lookup_cbk (call_frame_t *frame, void *cookie, cs->resolvedloc.name, buf); if (linked_inode) { inode_lookup (linked_inode); - inode_unref (linked_inode); + inode_unref (cs->resolvedloc.inode); + cs->resolvedloc.inode = linked_inode; } err: nfs3_call_resume (cs); @@ -3635,119 +3596,6 @@ err: } -int -nfs3_fh_resolve_found_entry (nfs3_call_state_t *cs, gf_dirent_t *candidate) -{ - int ret = 0; - nfs_user_t nfu = {0, }; - uuid_t gfid = {0, }; - - if ((!cs) || (!candidate)) - return -EFAULT; - - uuid_copy (gfid, cs->resolvedloc.inode->gfid); - nfs_loc_wipe (&cs->resolvedloc); - ret = nfs_entry_loc_fill (cs->vol->itable, gfid, candidate->d_name, - &cs->resolvedloc, NFS_RESOLVE_CREATE); - if (ret == -ENOENT) { - gf_log (GF_NFS3, GF_LOG_TRACE, "Entry not in itable, needs" - " lookup"); - nfs_user_root_create (&nfu); - ret = nfs_lookup (cs->nfsx, cs->vol, &nfu, &cs->resolvedloc, - nfs3_fh_resolve_entry_lookup_cbk, - cs); - } else { - gf_log (GF_NFS3, GF_LOG_TRACE, "Entry got from itable"); - nfs3_call_resume (cs); - } - - return ret; -} - - -int32_t -nfs3_fh_resolve_parent_lookup_cbk (call_frame_t *frame, void *cookie, - xlator_t *this, int32_t op_ret, - int32_t op_errno, inode_t *inode, - struct iatt *buf, dict_t *xattr, - struct iatt *postparent) -{ - nfs3_call_state_t *cs = NULL; - inode_t *linked_inode = NULL; - - cs = frame->local; - cs->resolve_ret = op_ret; - cs->resolve_errno = op_errno; - - if (op_ret == -1) { - gf_log (GF_NFS3, (op_errno == ENOENT ? GF_LOG_TRACE : GF_LOG_ERROR), - "Lookup failed: %s: %s", - cs->resolvedloc.path, strerror (op_errno)); - nfs3_call_resume (cs); - goto err; - } else - gf_log (GF_NFS3, GF_LOG_TRACE, "Entry looked up: %s", - cs->resolvedloc.path); - - linked_inode = inode_link (inode, cs->resolvedloc.parent, - cs->resolvedloc.name, buf); - if (linked_inode) { - inode_lookup (linked_inode); - inode_unref (linked_inode); - } - nfs3_fh_resolve_entry_hard (cs); - -err: - return 0; -} - - -int -nfs3_fh_resolve_found_parent (nfs3_call_state_t *cs, gf_dirent_t *candidate) -{ - int ret = 0; - nfs_user_t nfu = {0, }; - uuid_t gfid = {0, }; - - if ((!cs) || (!candidate)) - return -EFAULT; - - uuid_copy (gfid, cs->resolvedloc.inode->gfid); - nfs_loc_wipe (&cs->resolvedloc); - ret = nfs_entry_loc_fill (cs->vol->itable, gfid, candidate->d_name, - &cs->resolvedloc, NFS_RESOLVE_CREATE); - if (ret == -ENOENT) { - nfs_user_root_create (&nfu); - ret = nfs_lookup (cs->nfsx, cs->vol, &nfu, &cs->resolvedloc, - nfs3_fh_resolve_parent_lookup_cbk, - cs); - } else - nfs3_fh_resolve_entry_hard (cs); - - return ret; -} - - -int -nfs3_fh_resolve_found (nfs3_call_state_t *cs, gf_dirent_t *candidate) -{ - int ret = 0; - - if ((!cs) || (!candidate)) - return -EFAULT; - - if (!cs->resolventry) { - gf_log (GF_NFS3, GF_LOG_TRACE, "Candidate entry was found"); - ret = nfs3_fh_resolve_found_entry (cs, candidate); - } else { - gf_log (GF_NFS3, GF_LOG_TRACE, "Entry's parent was found"); - ret = nfs3_fh_resolve_found_parent (cs, candidate); - } - - return ret; -} - - int32_t nfs3_fh_resolve_inode_lookup_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, @@ -3794,80 +3642,6 @@ err: } -/* Validate the depth of the dir such that we do not end up opening and - * reading directories beyond those that are needed for resolving the file - * handle. - * Returns 1 if fh resolution can continue, 0 otherwise. - */ -int -nfs3_fh_resolve_validate_dirdepth (nfs3_call_state_t *cs) -{ - int ret = 1; - - if (!cs) - return 0; - - /* This condition will generally never be hit because the - * hash-matching scheme will prevent us from going into a - * directory that is not part of the hash-array. - */ - if (nfs3_fh_hash_index_is_beyond (&cs->resolvefh, cs->hashidx)) { - gf_log (GF_NFS3, GF_LOG_TRACE, "Hash index is beyond: idx %d," - " fh idx: %d", cs->hashidx, cs->resolvefh.hashcount); - ret = 0; - goto out; - } - - if (cs->hashidx >= GF_NFSFH_MAXHASHES) { - gf_log (GF_NFS3, GF_LOG_TRACE, "Hash index beyond max hashes:" - " hashidx %d, max: %d", cs->hashidx, - GF_NFSFH_MAXHASHES); - ret = 0; - goto out; - } - -out: - return ret; -} - - -/* - * Called in a recursive code path, so if another - * directory was opened in an earlier call during fh resolution, we must unref - * through this reference before opening another fd_t. - */ -#define nfs3_fh_resolve_close_cwd(cst) \ - do { \ - if ((cst)->resolve_dir_fd) { \ - gf_log (GF_NFS3, GF_LOG_TRACE, "resolve fd " \ - "unrefing: 0x%lx, ref: %d", \ - (long)(cst)->resolve_dir_fd, \ - (cst)->resolve_dir_fd->refcount); \ - fd_unref ((cst)->resolve_dir_fd); \ - } \ - } while (0) \ - - -int -nfs3_fh_resolve_determine_response (nfs3_call_state_t *cs) { - - int response = GF_NFS3_FHRESOLVE_NOTFOUND; - - if (!cs) - return response; - - if ((cs->hashmatch) && (cs->entrymatch)) - response = GF_NFS3_FHRESOLVE_FOUND; - else if ((cs->hashmatch) && (!cs->entrymatch)) - response = GF_NFS3_FHRESOLVE_DIRFOUND; - else if ((!cs->hashmatch) && (cs->entrymatch)) - response = GF_NFS3_FHRESOLVE_FOUND; - else if ((!cs->hashmatch) && (!cs->entrymatch)) - response = GF_NFS3_FHRESOLVE_NOTFOUND; - - return response; -} - /* Needs no extra argument since it knows that the fh to be resolved is in * resolvefh and that it needs to start looking from the root. |
