diff options
Diffstat (limited to 'xlators/nfs/server/src/nfs3-helpers.c')
| -rw-r--r-- | xlators/nfs/server/src/nfs3-helpers.c | 3157 |
1 files changed, 1971 insertions, 1186 deletions
diff --git a/xlators/nfs/server/src/nfs3-helpers.c b/xlators/nfs/server/src/nfs3-helpers.c index 5a5a0b29d..9059fc341 100644 --- a/xlators/nfs/server/src/nfs3-helpers.c +++ b/xlators/nfs/server/src/nfs3-helpers.c @@ -1,20 +1,11 @@ /* - Copyright (c) 2010 Gluster, Inc. <http://www.gluster.com> + 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 @@ -35,8 +26,16 @@ #include "nfs3-helpers.h" #include "nfs-mem-types.h" #include "iatt.h" +#include "common-utils.h" #include <string.h> +extern int +nfs3_set_root_looked_up (struct nfs3_state *nfs3, struct nfs3_fh *rootfh); + +extern int +nfs3_is_root_looked_up (struct nfs3_state *nfs3, struct nfs3_fh *rootfh); + + #define nfs3_call_resume(cst) \ do { \ if (((cst)) && (cst)->resume_fn) \ @@ -91,13 +90,34 @@ struct nfs3stat_strerror nfs3stat_strerror_table[] = { }; +uint64_t +nfs3_iatt_gfid_to_ino (struct iatt *buf) +{ + uint64_t ino = 0; + + if (!buf) + return 0; + + if (gf_nfs_enable_ino32()) { + ino = (uint32_t )nfs_hash_gfid (buf->ia_gfid); + goto hashout; + } + + /* from posix its guaranteed to send unique ino */ + ino = buf->ia_ino; + +hashout: + return ino; +} + + void -nfs3_map_xlid_to_statdev (struct iatt *ia, uint16_t xlid) +nfs3_map_deviceid_to_statdev (struct iatt *ia, uint64_t deviceid) { if (!ia) return; - ia->ia_dev = xlid; + ia->ia_dev = deviceid; } @@ -220,6 +240,14 @@ nfs3_errno_to_nfsstat3 (int errnum) stat = NFS3ERR_STALE; break; + case ENOTCONN: + stat = NFS3ERR_IO; + break; + + case EDQUOT: + stat = NFS3ERR_DQUOT; + break; + default: stat = NFS3ERR_SERVERFAULT; break; @@ -228,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, @@ -247,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)) @@ -305,27 +350,18 @@ nfs3_stat_to_fattr3 (struct iatt *buf) } fa.fsid = buf->ia_dev; - fa.fileid = buf->ia_ino; - /* FIXME: Handle time resolutions for sub-second granularity */ - if (buf->ia_atime == 9669) { - fa.mtime.seconds = 0; - fa.mtime.nseconds = 0; - fa.atime.seconds = 0; - fa.atime.nseconds = 0; - } else { - fa.mtime.seconds = buf->ia_mtime; - fa.mtime.nseconds = 0; - fa.atime.seconds = buf->ia_atime; - fa.atime.seconds = 0; - fa.atime.nseconds = 0; - } + fa.fileid = nfs3_iatt_gfid_to_ino (buf); fa.atime.seconds = buf->ia_atime; - fa.atime.nseconds = 0; + fa.atime.nseconds = buf->ia_atime_nsec; fa.ctime.seconds = buf->ia_ctime; - fa.ctime.nseconds = 0; + fa.ctime.nseconds = buf->ia_ctime_nsec; + fa.mtime.seconds = buf->ia_mtime; + fa.mtime.nseconds = buf->ia_mtime_nsec; + +out: return fa; } @@ -368,11 +404,10 @@ nfs3_stat_to_pre_op_attr (struct iatt *pre) poa.attributes_follow = TRUE; poa.pre_op_attr_u.attributes.size = pre->ia_size; - if (pre->ia_atime == 9669) - poa.pre_op_attr_u.attributes.mtime.seconds = 0; - else - poa.pre_op_attr_u.attributes.mtime.seconds = pre->ia_mtime; + poa.pre_op_attr_u.attributes.mtime.seconds = pre->ia_mtime; + poa.pre_op_attr_u.attributes.mtime.nseconds = pre->ia_mtime_nsec; poa.pre_op_attr_u.attributes.ctime.seconds = pre->ia_ctime; + poa.pre_op_attr_u.attributes.ctime.nseconds = pre->ia_ctime_nsec; out: return poa; @@ -395,15 +430,8 @@ nfs3_fill_lookup3res_success (lookup3res *res, nfsstat3 stat, obj.attributes_follow = FALSE; dir.attributes_follow = FALSE; - if (buf && fh) { - nfs3_map_xlid_to_statdev (buf, fh->xlatorid); - obj = nfs3_stat_to_post_op_attr (buf); - } - - if (postparent && fh) { - nfs3_map_xlid_to_statdev (postparent, fh->xlatorid); - dir = nfs3_stat_to_post_op_attr (postparent); - } + obj = nfs3_stat_to_post_op_attr (buf); + dir = nfs3_stat_to_post_op_attr (postparent); res->lookup3res_u.resok.obj_attributes = obj; res->lookup3res_u.resok.dir_attributes = dir; @@ -412,10 +440,13 @@ nfs3_fill_lookup3res_success (lookup3res *res, nfsstat3 stat, void nfs3_fill_lookup3res (lookup3res *res, nfsstat3 stat, struct nfs3_fh *newfh, - struct iatt *buf, struct iatt *postparent) + struct iatt *buf, struct iatt *postparent, + uint64_t deviceid) { memset (res, 0, sizeof (*res)); + nfs3_map_deviceid_to_statdev (buf, deviceid); + nfs3_map_deviceid_to_statdev (postparent, deviceid); if (stat != NFS3_OK) nfs3_fill_lookup3res_error (res, stat, postparent); else @@ -432,7 +463,7 @@ nfs3_extract_getattr_fh (getattr3args *args) void nfs3_fill_getattr3res (getattr3res *res, nfsstat3 stat, struct iatt *buf, - uint16_t xlid) + uint64_t deviceid) { memset (res, 0, sizeof (*res)); @@ -440,7 +471,7 @@ nfs3_fill_getattr3res (getattr3res *res, nfsstat3 stat, struct iatt *buf, if (stat != NFS3_OK) return; - nfs3_map_xlid_to_statdev (buf, xlid); + nfs3_map_deviceid_to_statdev (buf, deviceid); res->getattr3res_u.resok.obj_attributes = nfs3_stat_to_fattr3 (buf); } @@ -455,7 +486,7 @@ nfs3_extract_fsinfo_fh (fsinfo3args *args) void nfs3_fill_fsinfo3res (struct nfs3_state *nfs3, fsinfo3res *res, - nfsstat3 status, struct iatt *fsroot, uint16_t xlid) + nfsstat3 status, struct iatt *fsroot, uint64_t deviceid) { fsinfo3resok resok = {{0}, }; nfstime3 tdelta = GF_NFS3_TIMEDELTA_SECS; @@ -465,7 +496,7 @@ nfs3_fill_fsinfo3res (struct nfs3_state *nfs3, fsinfo3res *res, if (status != NFS3_OK) return; - nfs3_map_xlid_to_statdev (fsroot, xlid); + nfs3_map_deviceid_to_statdev (fsroot, deviceid); resok.obj_attributes = nfs3_stat_to_post_op_attr (fsroot); resok.rtmax = nfs3->readsize; resok.rtpref = nfs3->readsize; @@ -474,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; @@ -529,157 +560,49 @@ nfs3_prep_access3args (access3args *args, struct nfs3_fh *fh) args->object.data.data_val = (void *)fh; } +#define POSIX_READ 4 +#define POSIX_WRITE 2 +#define POSIX_EXEC 1 uint32_t -nfs3_owner_accessbits (ia_prot_t prot, ia_type_t type, uint32_t request) -{ - uint32_t accresult = 0; - - if (IA_PROT_RUSR (prot) && (request & ACCESS3_READ)) - accresult |= ACCESS3_READ; - - if (request & ACCESS3_LOOKUP) - if ((IA_ISDIR (type)) && (IA_PROT_XUSR (prot))) - accresult |= ACCESS3_LOOKUP; - - if ((IA_PROT_WUSR (prot) && (request & ACCESS3_MODIFY))) - accresult |= ACCESS3_MODIFY; - - if ((IA_PROT_WUSR (prot) && (request & ACCESS3_EXTEND))) - accresult |= ACCESS3_EXTEND; - - /* ACCESS3_DELETE is ignored for now since that requires - * knowing the permissions on the parent directory. - */ - - if (request & ACCESS3_EXECUTE) - if (IA_PROT_XUSR (prot) && (!IA_ISDIR (type))) - accresult |= ACCESS3_EXECUTE; - - return accresult; -} - - -uint32_t -nfs3_group_accessbits (ia_prot_t prot, ia_type_t type, uint32_t request) +nfs3_accessbits (int32_t accbits) { - uint32_t accresult = 0; - - if (IA_PROT_RGRP (prot) && (request & ACCESS3_READ)) - accresult |= ACCESS3_READ; - - if (request & ACCESS3_LOOKUP) - if ((IA_ISDIR (type)) && IA_PROT_RGRP (prot)) - accresult |= ACCESS3_LOOKUP; - - if (IA_PROT_WGRP (prot) && (request & ACCESS3_MODIFY)) - accresult |= ACCESS3_MODIFY; - - if (IA_PROT_WGRP (prot) && (request & ACCESS3_EXTEND)) - accresult |= ACCESS3_EXTEND; - - /* ACCESS3_DELETE is ignored for now since that requires - * knowing the permissions on the parent directory. - */ - - if (request & ACCESS3_EXECUTE) - if (IA_PROT_XGRP (prot) && (!IA_ISDIR (type))) - accresult |= ACCESS3_EXECUTE; - - return accresult; -} - - -uint32_t -nfs3_other_accessbits (ia_prot_t prot, ia_type_t type, uint32_t request) -{ - uint32_t accresult = 0; + uint32_t accresult = 0; - if (IA_PROT_ROTH (prot) && (request & ACCESS3_READ)) + if (accbits & POSIX_READ) accresult |= ACCESS3_READ; - if (request & ACCESS3_LOOKUP) - if (IA_ISDIR (type) && IA_PROT_ROTH (prot)) - accresult |= ACCESS3_LOOKUP; + if (accbits & POSIX_WRITE) + accresult |= (ACCESS3_MODIFY | ACCESS3_EXTEND | ACCESS3_DELETE); - if (IA_PROT_WOTH (prot) && (request & ACCESS3_MODIFY)) - accresult |= ACCESS3_MODIFY; - - if (IA_PROT_WOTH (prot) && (request & ACCESS3_EXTEND)) - accresult |= ACCESS3_EXTEND; - - /* ACCESS3_DELETE is ignored for now since that requires - * knowing the permissions on the parent directory. - */ - - if (request & ACCESS3_EXECUTE) - if (IA_PROT_XOTH (prot) && (!IA_ISDIR (type))) - accresult |= ACCESS3_EXECUTE; + /* lookup on directory allowed only in case of execute permission */ + if (accbits & POSIX_EXEC) + accresult |= (ACCESS3_EXECUTE | ACCESS3_LOOKUP); return accresult; } - uint32_t -nfs3_superuser_accessbits (ia_prot_t prot, ia_type_t type, uint32_t request) +nfs3_request_to_accessbits (int32_t accbits) { - uint32_t accresult = 0; - - if (request & ACCESS3_READ) - accresult |= ACCESS3_READ; - - if (request & ACCESS3_LOOKUP) - if (IA_ISDIR (type)) - accresult |= ACCESS3_LOOKUP; + uint32_t acc_request = 0; - if (request & ACCESS3_MODIFY) - accresult |= ACCESS3_MODIFY; - - if (request & ACCESS3_EXTEND) - accresult |= ACCESS3_EXTEND; - - /* ACCESS3_DELETE is ignored for now since that requires - * knowing the permissions on the parent directory. - */ - - if (request & ACCESS3_EXECUTE) - if ((IA_PROT_XOTH (prot) || IA_PROT_XUSR (prot) || - IA_PROT_XGRP (prot)) && (!IA_ISDIR (type))) - accresult |= ACCESS3_EXECUTE; - - return accresult; -} - - -uint32_t -nfs3_stat_to_accessbits (struct iatt *buf, uint32_t request, uid_t uid, - gid_t gid) -{ - uint32_t accresult = 0; - ia_prot_t prot = {0, }; - ia_type_t type = 0; + if (accbits & ACCESS3_READ) + acc_request |= POSIX_READ; - prot = buf->ia_prot; - type = buf->ia_type; + if (accbits & (ACCESS3_MODIFY | ACCESS3_EXTEND | ACCESS3_DELETE)) + acc_request |= POSIX_WRITE; - if (uid == 0) - accresult = nfs3_superuser_accessbits (prot, type, request); - else if (buf->ia_uid == uid) - accresult = nfs3_owner_accessbits (prot, type, request); - else if (buf->ia_gid == gid) - accresult = nfs3_group_accessbits (prot, type, request); - else - accresult = nfs3_other_accessbits (prot, type, request); + /* For lookup on directory check for execute permission */ + if (accbits & (ACCESS3_EXECUTE | ACCESS3_LOOKUP)) + acc_request |= POSIX_EXEC; - return accresult; + return acc_request; } - - void -nfs3_fill_access3res (access3res *res, nfsstat3 status, struct iatt *buf, - uint32_t accbits, uid_t uid, gid_t gid, uint16_t xlid) +nfs3_fill_access3res (access3res *res, nfsstat3 status, int32_t accbits, + int32_t reqaccbits) { - post_op_attr objattr; uint32_t accres = 0; memset (res, 0, sizeof (*res)); @@ -687,12 +610,10 @@ nfs3_fill_access3res (access3res *res, nfsstat3 status, struct iatt *buf, if (status != NFS3_OK) return; - nfs3_map_xlid_to_statdev (buf, xlid); - objattr = nfs3_stat_to_post_op_attr (buf); - accres = nfs3_stat_to_accessbits (buf, accbits, uid, gid); + accres = nfs3_accessbits (accbits); - res->access3res_u.resok.obj_attributes = objattr; - res->access3res_u.resok.access = accres; + /* do not answer what was not asked */ + res->access3res_u.resok.access = accres & reqaccbits; } void @@ -743,14 +664,12 @@ nfs3_funge_root_dotdot_dirent (gf_dirent_t *ent, struct nfs3_fh *dfh) nfs3_is_parentdir_entry (ent->d_name)) { ent->d_ino = 1; ent->d_stat.ia_ino = 1; - ent->d_stat.ia_gen = 0; } if (nfs3_fh_is_root_fh (dfh) && nfs3_is_dot_entry (ent->d_name)) { ent->d_ino = 1; ent->d_stat.ia_ino = 1; - ent->d_stat.ia_gen = 0; } } @@ -772,9 +691,10 @@ nfs3_fill_entry3 (gf_dirent_t *entry, struct nfs3_fh *dfh) /* If the entry is . or .., we need to replace the physical ino and gen * with 1 and 0 respectively if the directory is root. This funging is * needed because there is no parent directory of the root. In that - * sense the behavious we provide is similar to the output of the + * sense the behavior we provide is similar to the output of the * command: "stat /.." */ + entry->d_ino = nfs3_iatt_gfid_to_ino (&entry->d_stat); nfs3_funge_root_dotdot_dirent (entry, dfh); ent->fileid = entry->d_ino; ent->cookie = entry->d_off; @@ -829,7 +749,7 @@ nfs3_fh_to_post_op_fh3 (struct nfs3_fh *fh) entryp3 * -nfs3_fill_entryp3 (gf_dirent_t *entry, struct nfs3_fh *dirfh) +nfs3_fill_entryp3 (gf_dirent_t *entry, struct nfs3_fh *dirfh, uint64_t devid) { entryp3 *ent = NULL; struct nfs3_fh newfh = {{0}, }; @@ -840,9 +760,10 @@ nfs3_fill_entryp3 (gf_dirent_t *entry, struct nfs3_fh *dirfh) /* If the entry is . or .., we need to replace the physical ino and gen * with 1 and 0 respectively if the directory is root. This funging is * needed because there is no parent directory of the root. In that - * sense the behavious we provide is similar to the output of the + * sense the behavior we provide is similar to the output of the * command: "stat /.." */ + entry->d_ino = nfs3_iatt_gfid_to_ino (&entry->d_stat); nfs3_funge_root_dotdot_dirent (entry, dirfh); gf_log (GF_NFS3, GF_LOG_TRACE, "Entry: %s, ino: %"PRIu64, entry->d_name, entry->d_ino); @@ -862,7 +783,7 @@ nfs3_fill_entryp3 (gf_dirent_t *entry, struct nfs3_fh *dirfh) strcpy (ent->name, entry->d_name); nfs3_fh_build_child_fh (dirfh, &entry->d_stat, &newfh); - nfs3_map_xlid_to_statdev (&entry->d_stat, dirfh->xlatorid); + nfs3_map_deviceid_to_statdev (&entry->d_stat, devid); ent->name_attributes = nfs3_stat_to_post_op_attr (&entry->d_stat); ent->name_handle = nfs3_fh_to_post_op_fh3 (&newfh); err: @@ -873,7 +794,8 @@ err: void nfs3_fill_readdir3res (readdir3res *res, nfsstat3 stat, struct nfs3_fh *dirfh, uint64_t cverf, struct iatt *dirstat, - gf_dirent_t *entries, count3 count, int is_eof) + gf_dirent_t *entries, count3 count, int is_eof, + uint64_t deviceid) { post_op_attr dirattr; entry3 *ent = NULL; @@ -887,7 +809,7 @@ nfs3_fill_readdir3res (readdir3res *res, nfsstat3 stat, struct nfs3_fh *dirfh, if (stat != NFS3_OK) return; - nfs3_map_xlid_to_statdev (dirstat, dirfh->xlatorid); + nfs3_map_deviceid_to_statdev (dirstat, deviceid); dirattr = nfs3_stat_to_post_op_attr (dirstat); res->readdir3res_u.resok.dir_attributes = dirattr; res->readdir3res_u.resok.reply.eof = (bool_t)is_eof; @@ -928,10 +850,11 @@ nfs3_fill_readdir3res (readdir3res *res, nfsstat3 stat, struct nfs3_fh *dirfh, void -nfs3_fill_readdirp3res (readdirp3res *res, nfsstat3 stat, struct nfs3_fh *dirfh, - uint64_t cverf, struct iatt *dirstat, - gf_dirent_t *entries, count3 dircount, count3 maxcount, - int is_eof) +nfs3_fill_readdirp3res (readdirp3res *res, nfsstat3 stat, + struct nfs3_fh *dirfh, uint64_t cverf, + struct iatt *dirstat, gf_dirent_t *entries, + count3 dircount, count3 maxcount, int is_eof, + uint64_t deviceid) { post_op_attr dirattr; entryp3 *ent = NULL; @@ -946,7 +869,7 @@ nfs3_fill_readdirp3res (readdirp3res *res, nfsstat3 stat, struct nfs3_fh *dirfh, if (stat != NFS3_OK) return; - nfs3_map_xlid_to_statdev (dirstat, dirfh->xlatorid); + nfs3_map_deviceid_to_statdev (dirstat, deviceid); dirattr = nfs3_stat_to_post_op_attr (dirstat); res->readdirp3res_u.resok.dir_attributes = dirattr; res->readdirp3res_u.resok.reply.eof = (bool_t)is_eof; @@ -964,7 +887,7 @@ nfs3_fill_readdirp3res (readdirp3res *res, nfsstat3 stat, struct nfs3_fh *dirfh, (strcmp (entries->d_name, "..") == 0)) goto nextentry; */ - ent = nfs3_fill_entryp3 (entries, dirfh); + ent = nfs3_fill_entryp3 (entries, dirfh, deviceid); if (!ent) break; @@ -1050,7 +973,7 @@ nfs3_prep_fsstat3args (fsstat3args *args, struct nfs3_fh *fh) void nfs3_fill_fsstat3res (fsstat3res *res, nfsstat3 stat, struct statvfs *fsbuf, - struct iatt *postbuf, uint16_t xlid) + struct iatt *postbuf, uint64_t deviceid) { post_op_attr poa; fsstat3resok resok; @@ -1060,11 +983,11 @@ nfs3_fill_fsstat3res (fsstat3res *res, nfsstat3 stat, struct statvfs *fsbuf, if (stat != NFS3_OK) return; - nfs3_map_xlid_to_statdev (postbuf, xlid); + nfs3_map_deviceid_to_statdev (postbuf, deviceid); poa = nfs3_stat_to_post_op_attr (postbuf); resok.tbytes = (size3)(fsbuf->f_frsize * fsbuf->f_blocks); - resok.fbytes = (size3)(fsbuf->f_bsize * fsbuf->f_bfree); - resok.abytes = (size3)(fsbuf->f_bsize * fsbuf->f_bavail); + resok.fbytes = (size3)(fsbuf->f_frsize * fsbuf->f_bfree); + resok.abytes = (size3)(fsbuf->f_frsize * fsbuf->f_bavail); resok.tfiles = (size3)(fsbuf->f_files); resok.ffiles = (size3)(fsbuf->f_ffree); resok.afiles = (size3)(fsbuf->f_favail); @@ -1209,7 +1132,7 @@ nfs3_stat_to_wcc_data (struct iatt *pre, struct iatt *post) void nfs3_fill_create3res (create3res *res, nfsstat3 stat, struct nfs3_fh *newfh, struct iatt *newbuf, struct iatt *preparent, - struct iatt *postparent) + struct iatt *postparent, uint64_t deviceid) { post_op_attr poa = {0, }; wcc_data dirwcc = {{0}, }; @@ -1220,14 +1143,12 @@ nfs3_fill_create3res (create3res *res, nfsstat3 stat, struct nfs3_fh *newfh, return; nfs3_fill_post_op_fh3 (newfh, &res->create3res_u.resok.obj); - nfs3_map_xlid_to_statdev (newbuf, newfh->xlatorid); + nfs3_map_deviceid_to_statdev (newbuf, deviceid); poa = nfs3_stat_to_post_op_attr (newbuf); res->create3res_u.resok.obj_attributes = poa; - if (preparent) { - nfs3_map_xlid_to_statdev (preparent, newfh->xlatorid); - nfs3_map_xlid_to_statdev (postparent, newfh->xlatorid); - dirwcc = nfs3_stat_to_wcc_data (preparent, postparent); - } + nfs3_map_deviceid_to_statdev (preparent, deviceid); + nfs3_map_deviceid_to_statdev (postparent, deviceid); + dirwcc = nfs3_stat_to_wcc_data (preparent, postparent); res->create3res_u.resok.dir_wcc = dirwcc; } @@ -1251,7 +1172,7 @@ nfs3_prep_setattr3args (setattr3args *args, struct nfs3_fh *fh) void nfs3_fill_setattr3res (setattr3res *res, nfsstat3 stat, struct iatt *preop, - struct iatt *postop, uint16_t xlid) + struct iatt *postop, uint64_t deviceid) { wcc_data wcc; memset (res, 0, sizeof (*res)); @@ -1259,8 +1180,8 @@ nfs3_fill_setattr3res (setattr3res *res, nfsstat3 stat, struct iatt *preop, if (stat != NFS3_OK) return; - nfs3_map_xlid_to_statdev (preop, xlid); - nfs3_map_xlid_to_statdev (postop, xlid); + nfs3_map_deviceid_to_statdev (preop, deviceid); + nfs3_map_deviceid_to_statdev (postop, deviceid); wcc = nfs3_stat_to_wcc_data (preop, postop); res->setattr3res_u.resok.obj_wcc = wcc; } @@ -1279,7 +1200,7 @@ nfs3_prep_mkdir3args (mkdir3args *args, struct nfs3_fh *dirfh, char *name) void nfs3_fill_mkdir3res (mkdir3res *res, nfsstat3 stat, struct nfs3_fh *fh, struct iatt *buf, struct iatt *preparent, - struct iatt *postparent) + struct iatt *postparent, uint64_t deviceid) { wcc_data dirwcc; post_op_attr poa; @@ -1290,10 +1211,10 @@ nfs3_fill_mkdir3res (mkdir3res *res, nfsstat3 stat, struct nfs3_fh *fh, return; nfs3_fill_post_op_fh3 (fh, &res->mkdir3res_u.resok.obj); - nfs3_map_xlid_to_statdev (buf, fh->xlatorid); + nfs3_map_deviceid_to_statdev (buf, deviceid); poa = nfs3_stat_to_post_op_attr (buf); - nfs3_map_xlid_to_statdev (preparent, fh->xlatorid); - nfs3_map_xlid_to_statdev (postparent, fh->xlatorid); + nfs3_map_deviceid_to_statdev (preparent, deviceid); + nfs3_map_deviceid_to_statdev (postparent, deviceid); dirwcc = nfs3_stat_to_wcc_data (preparent, postparent); res->mkdir3res_u.resok.obj_attributes = poa; res->mkdir3res_u.resok.dir_wcc = dirwcc; @@ -1315,7 +1236,7 @@ nfs3_prep_symlink3args (symlink3args *args, struct nfs3_fh *dirfh, char *name, void nfs3_fill_symlink3res (symlink3res *res, nfsstat3 stat, struct nfs3_fh *fh, struct iatt *buf, struct iatt *preparent, - struct iatt *postparent) + struct iatt *postparent, uint64_t deviceid) { wcc_data dirwcc; post_op_attr poa; @@ -1326,10 +1247,10 @@ nfs3_fill_symlink3res (symlink3res *res, nfsstat3 stat, struct nfs3_fh *fh, return; nfs3_fill_post_op_fh3 (fh, &res->symlink3res_u.resok.obj); - nfs3_map_xlid_to_statdev (buf, fh->xlatorid); + nfs3_map_deviceid_to_statdev (buf, deviceid); poa = nfs3_stat_to_post_op_attr (buf); - nfs3_map_xlid_to_statdev (postparent, fh->xlatorid); - nfs3_map_xlid_to_statdev (preparent, fh->xlatorid); + nfs3_map_deviceid_to_statdev (postparent, deviceid); + nfs3_map_deviceid_to_statdev (preparent, deviceid); dirwcc = nfs3_stat_to_wcc_data (preparent, postparent); res->symlink3res_u.resok.obj_attributes = poa; res->symlink3res_u.resok.dir_wcc = dirwcc; @@ -1348,7 +1269,7 @@ nfs3_prep_readlink3args (readlink3args *args, struct nfs3_fh *fh) void nfs3_fill_readlink3res (readlink3res *res, nfsstat3 stat, char *path, - struct iatt *buf, uint16_t xlid) + struct iatt *buf, uint64_t deviceid) { post_op_attr poa; @@ -1358,7 +1279,7 @@ nfs3_fill_readlink3res (readlink3res *res, nfsstat3 stat, char *path, if (stat != NFS3_OK) return; - nfs3_map_xlid_to_statdev (buf, xlid); + nfs3_map_deviceid_to_statdev (buf, deviceid); poa = nfs3_stat_to_post_op_attr (buf); res->readlink3res_u.resok.data = (void *)path; res->readlink3res_u.resok.symlink_attributes = poa; @@ -1377,7 +1298,7 @@ nfs3_prep_mknod3args (mknod3args *args, struct nfs3_fh *fh, char *name) void nfs3_fill_mknod3res (mknod3res *res, nfsstat3 stat, struct nfs3_fh *fh, struct iatt *buf, struct iatt *preparent, - struct iatt *postparent) + struct iatt *postparent, uint64_t deviceid) { post_op_attr poa; wcc_data wccdir; @@ -1388,10 +1309,10 @@ nfs3_fill_mknod3res (mknod3res *res, nfsstat3 stat, struct nfs3_fh *fh, return; nfs3_fill_post_op_fh3 (fh, &res->mknod3res_u.resok.obj); - nfs3_map_xlid_to_statdev (buf, fh->xlatorid); + nfs3_map_deviceid_to_statdev (buf, deviceid); poa = nfs3_stat_to_post_op_attr (buf); - nfs3_map_xlid_to_statdev (preparent, fh->xlatorid); - nfs3_map_xlid_to_statdev (postparent, fh->xlatorid); + nfs3_map_deviceid_to_statdev (preparent, deviceid); + nfs3_map_deviceid_to_statdev (postparent, deviceid); wccdir = nfs3_stat_to_wcc_data (preparent, postparent); res->mknod3res_u.resok.obj_attributes = poa; res->mknod3res_u.resok.dir_wcc = wccdir; @@ -1401,7 +1322,7 @@ nfs3_fill_mknod3res (mknod3res *res, nfsstat3 stat, struct nfs3_fh *fh, void nfs3_fill_remove3res (remove3res *res, nfsstat3 stat, struct iatt *preparent, - struct iatt *postparent, uint16_t xlid) + struct iatt *postparent, uint64_t deviceid) { wcc_data dirwcc; @@ -1410,8 +1331,8 @@ nfs3_fill_remove3res (remove3res *res, nfsstat3 stat, struct iatt *preparent, if (stat != NFS3_OK) return; - nfs3_map_xlid_to_statdev (preparent, xlid); - nfs3_map_xlid_to_statdev (postparent, xlid); + nfs3_map_deviceid_to_statdev (preparent, deviceid); + nfs3_map_deviceid_to_statdev (postparent, deviceid); dirwcc = nfs3_stat_to_wcc_data (preparent, postparent); res->remove3res_u.resok.dir_wcc = dirwcc; } @@ -1437,7 +1358,7 @@ nfs3_prep_rmdir3args (rmdir3args *args, struct nfs3_fh *fh, char *name) void nfs3_fill_rmdir3res (rmdir3res *res, nfsstat3 stat, struct iatt *preparent, - struct iatt *postparent, uint16_t xlid) + struct iatt *postparent, uint64_t deviceid) { wcc_data dirwcc; memset (res, 0, sizeof (*res)); @@ -1446,8 +1367,8 @@ nfs3_fill_rmdir3res (rmdir3res *res, nfsstat3 stat, struct iatt *preparent, if (stat != NFS3_OK) return; - nfs3_map_xlid_to_statdev (postparent, xlid); - nfs3_map_xlid_to_statdev (preparent, xlid); + nfs3_map_deviceid_to_statdev (postparent, deviceid); + nfs3_map_deviceid_to_statdev (preparent, deviceid); dirwcc = nfs3_stat_to_wcc_data (preparent, postparent); res->rmdir3res_u.resok.dir_wcc = dirwcc; } @@ -1467,7 +1388,7 @@ nfs3_prep_link3args (link3args *args, struct nfs3_fh *target, void nfs3_fill_link3res (link3res *res, nfsstat3 stat, struct iatt *buf, struct iatt *preparent, struct iatt *postparent, - uint16_t xlid) + uint64_t deviceid) { post_op_attr poa; wcc_data dirwcc; @@ -1477,9 +1398,9 @@ nfs3_fill_link3res (link3res *res, nfsstat3 stat, struct iatt *buf, if (stat != NFS3_OK) return; - nfs3_map_xlid_to_statdev (preparent, xlid); - nfs3_map_xlid_to_statdev (postparent, xlid); - nfs3_map_xlid_to_statdev (buf, xlid); + nfs3_map_deviceid_to_statdev (preparent, deviceid); + nfs3_map_deviceid_to_statdev (postparent, deviceid); + nfs3_map_deviceid_to_statdev (buf,deviceid); poa = nfs3_stat_to_post_op_attr (buf); dirwcc = nfs3_stat_to_wcc_data (preparent, postparent); res->link3res_u.resok.file_attributes = poa; @@ -1506,7 +1427,7 @@ void nfs3_fill_rename3res (rename3res *res, nfsstat3 stat, struct iatt *buf, struct iatt *preoldparent, struct iatt *postoldparent, struct iatt *prenewparent, struct iatt *postnewparent, - uint16_t xlid) + uint64_t deviceid) { wcc_data dirwcc; @@ -1516,11 +1437,11 @@ nfs3_fill_rename3res (rename3res *res, nfsstat3 stat, struct iatt *buf, if (stat != NFS3_OK) return; - nfs3_map_xlid_to_statdev (preoldparent, xlid); - nfs3_map_xlid_to_statdev (postoldparent, xlid); - nfs3_map_xlid_to_statdev (prenewparent, xlid); - nfs3_map_xlid_to_statdev (postnewparent, xlid); - nfs3_map_xlid_to_statdev (buf, xlid); + nfs3_map_deviceid_to_statdev (preoldparent, deviceid); + nfs3_map_deviceid_to_statdev (postoldparent, deviceid); + nfs3_map_deviceid_to_statdev (prenewparent, deviceid); + nfs3_map_deviceid_to_statdev (postnewparent, deviceid); + nfs3_map_deviceid_to_statdev (buf, deviceid); dirwcc = nfs3_stat_to_wcc_data (preoldparent, postoldparent); res->rename3res_u.resok.fromdir_wcc = dirwcc; dirwcc = nfs3_stat_to_wcc_data (prenewparent, postnewparent); @@ -1539,7 +1460,7 @@ nfs3_prep_write3args (write3args *args, struct nfs3_fh *fh) void nfs3_fill_write3res (write3res *res, nfsstat3 stat, count3 count, stable_how stable, uint64_t wverf, struct iatt *prestat, - struct iatt *poststat, uint16_t xlid) + struct iatt *poststat, uint64_t deviceid) { write3resok resok; memset (res, 0, sizeof (*res)); @@ -1547,8 +1468,8 @@ nfs3_fill_write3res (write3res *res, nfsstat3 stat, count3 count, if (stat != NFS3_OK) return; - nfs3_map_xlid_to_statdev (prestat, xlid); - nfs3_map_xlid_to_statdev (poststat, xlid); + nfs3_map_deviceid_to_statdev (prestat, deviceid); + nfs3_map_deviceid_to_statdev (poststat, deviceid); resok.file_wcc = nfs3_stat_to_wcc_data (prestat, poststat); resok.count = count; resok.committed = stable; @@ -1568,15 +1489,16 @@ nfs3_prep_commit3args (commit3args *args, struct nfs3_fh *fh) void nfs3_fill_commit3res (commit3res *res, nfsstat3 stat, uint64_t wverf, - struct iatt *prestat, struct iatt *poststat,uint16_t xlid) + struct iatt *prestat, struct iatt *poststat, + uint64_t deviceid) { memset (res, 0, sizeof (*res)); res->status = stat; if (stat != NFS3_OK) return; - nfs3_map_xlid_to_statdev (poststat, xlid); - nfs3_map_xlid_to_statdev (prestat, xlid); + nfs3_map_deviceid_to_statdev (poststat, deviceid); + nfs3_map_deviceid_to_statdev (prestat, deviceid); res->commit3res_u.resok.file_wcc = nfs3_stat_to_wcc_data (prestat, poststat); memcpy (res->commit3res_u.resok.verf, &wverf, sizeof (wverf)); @@ -1584,7 +1506,7 @@ nfs3_fill_commit3res (commit3res *res, nfsstat3 stat, uint64_t wverf, void nfs3_fill_read3res (read3res *res, nfsstat3 stat, count3 count, - struct iatt *poststat, int is_eof, uint16_t xlid) + struct iatt *poststat, int is_eof, uint64_t deviceid) { post_op_attr poa; @@ -1593,7 +1515,7 @@ nfs3_fill_read3res (read3res *res, nfsstat3 stat, count3 count, if (stat != NFS3_OK) return; - nfs3_map_xlid_to_statdev (poststat, xlid); + nfs3_map_deviceid_to_statdev (poststat, deviceid); poa = nfs3_stat_to_post_op_attr (poststat); res->read3res_u.resok.file_attributes = poa; res->read3res_u.resok.count = count; @@ -1612,7 +1534,7 @@ nfs3_prep_read3args (read3args *args, struct nfs3_fh *fh) void nfs3_fill_pathconf3res (pathconf3res *res, nfsstat3 stat, struct iatt *buf, - uint16_t xlid) + uint64_t deviceid) { pathconf3resok resok; @@ -1621,7 +1543,7 @@ nfs3_fill_pathconf3res (pathconf3res *res, nfsstat3 stat, struct iatt *buf, if (stat != NFS3_OK) return; - nfs3_map_xlid_to_statdev (buf, xlid); + nfs3_map_deviceid_to_statdev (buf, deviceid); resok.obj_attributes = nfs3_stat_to_post_op_attr (buf); resok.linkmax = 256; resok.name_max = NFS_NAME_MAX; @@ -1692,680 +1614,1805 @@ err: } -/* When remove a file, we need to unref the cached fd for an inode but this - * needs to happen only when the file was in fact opened. However, it is - * possible that fd_lookup on a file returns an fd because the file was in - * process of being created(which also returns an fd) but since this fd was not - * opened through this path, in the NFS3 remove path, we'll end up removing the - * reference that belongs to someone else. That means, nfs3 remove path should - * not unref unless it is sure that the file was cached open also. If it was, - * only then perform the fd_unref, else not. - * - * We determine that using a flag in the inode context. - */ -int -nfs3_set_inode_opened (xlator_t *nfsxl, inode_t *inode) +void +nfs3_stat_to_errstr (uint32_t xid, char *op, nfsstat3 stat, int pstat, + char *errstr, size_t len) { - if ((!nfsxl) || (!inode)) - return -1; + if ((!op) || (!errstr)) + return; - inode_ctx_put (inode, nfsxl, GF_NFS3_FD_CACHED); + snprintf (errstr, len, "XID: %x, %s: NFS: %d(%s), POSIX: %d(%s)", + xid, op,stat, nfsstat3_strerror (stat), pstat, + strerror (pstat)); +} - return 0; +void +nfs3_log_common_call (uint32_t xid, char *op, struct nfs3_fh *fh) +{ + char fhstr[1024]; + + 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", xid, op, + fhstr); } -/* Returns 1 if inode was cached open, otherwise 0 */ -int -nfs3_cached_inode_opened (xlator_t *nfsxl, inode_t *inode) +void +nfs3_log_fh_entry_call (uint32_t xid, char *op, struct nfs3_fh *fh, + char *name) { - int ret = -1; - uint64_t cflag = 0; + char fhstr[1024]; - if ((!nfsxl) || (!inode)) - return -1; + 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); +} - ret = inode_ctx_get (inode, nfsxl, &cflag); - if (ret == -1) - ret = 0; - else if (cflag == GF_NFS3_FD_CACHED) - ret = 1; - return ret; +void +nfs3_log_rename_call (uint32_t xid, struct nfs3_fh *src, char *sname, + struct nfs3_fh *dst, char *dname) +{ + char sfhstr[1024]; + char dfhstr[1024]; + + 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); } -int32_t -nfs3_dir_open_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno, fd_t *fd) + +void +nfs3_log_create_call (uint32_t xid, struct nfs3_fh *fh, char *name, + createmode3 mode) { - nfs3_call_state_t *cs = NULL; + char fhstr[1024]; + char *modestr = NULL; + char exclmode[] = "EXCLUSIVE"; + char unchkd[] = "UNCHECKED"; + char guarded[] = "GUARDED"; - cs = frame->local; - if (op_ret == -1) { - cs->resolve_ret = -1; - cs->resolve_errno = op_errno; - nfs3_call_resume (cs); - goto err; - } + 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) + modestr = guarded; + else + modestr = unchkd; - cs->fd = fd_ref (fd); - nfs3_set_inode_opened (cs->nfsx, cs->resolvedloc.inode); - gf_log (GF_NFS3, GF_LOG_TRACE, "FD_REF: %d", fd->refcount); - nfs3_call_resume (cs); -err: - return 0; + gf_log (GF_NFS3, GF_LOG_DEBUG, "XID: %x, CREATE: args: %s, name: %s," + " mode: %s", xid, fhstr, name, modestr); } -int -__nfs3_dir_open_and_resume (nfs3_call_state_t *cs) +void +nfs3_log_mknod_call (uint32_t xid, struct nfs3_fh *fh, char *name, int type) { - nfs_user_t nfu = {0, }; - int ret = -EFAULT; + char fhstr[1024]; + char *modestr = NULL; + char chr[] = "CHAR"; + char blk[] = "BLK"; + char sock[] = "SOCK"; + char fifo[] = "FIFO"; - if (!cs) - return ret; + 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) + modestr = blk; + else if (type == NF3SOCK) + modestr = sock; + else + modestr = fifo; - nfs_user_root_create (&nfu); - ret = nfs_opendir (cs->nfsx, cs->vol, &nfu, &cs->resolvedloc, - nfs3_dir_open_cbk, cs); - return ret; + gf_log (GF_NFS3, GF_LOG_DEBUG, "XID: %x, MKNOD: args: %s, name: %s," + " type: %s", xid, fhstr, name, modestr); } -int -nfs3_dir_open_and_resume (nfs3_call_state_t *cs, nfs3_resume_fn_t resume) + +void +nfs3_log_symlink_call (uint32_t xid, struct nfs3_fh *fh, char *name, char *tgt) { - fd_t *fd = NULL; - int ret = -EFAULT; + char fhstr[1024]; - if ((!cs)) - return ret; + 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); +} - cs->resume_fn = resume; - gf_log (GF_NFS3, GF_LOG_TRACE, "Opening: %s", cs->resolvedloc.path); - fd = fd_lookup (cs->resolvedloc.inode, 0); - if (fd) { - gf_log (GF_NFS3, GF_LOG_TRACE, "fd found in state: ref: %d", fd->refcount); - cs->fd = fd; /* Gets unrefd when the call state is wiped. */ - cs->resolve_ret = 0; - nfs3_call_resume (cs); - ret = 0; - goto err; - } - ret = __nfs3_dir_open_and_resume (cs); +void +nfs3_log_link_call (uint32_t xid, struct nfs3_fh *fh, char *name, + struct nfs3_fh *tgt) +{ + char dfhstr[1024]; + char tfhstr[1024]; -err: - return ret; + 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); } -int -nfs3_flush_call_state (nfs3_call_state_t *cs, fd_t *openedfd) +void +nfs3_log_rw_call (uint32_t xid, char *op, struct nfs3_fh *fh, offset3 offt, + count3 count, int stablewrite) { - if ((!cs) || (!openedfd)) - return -1; + char fhstr[1024]; - gf_log (GF_NFS3, GF_LOG_TRACE, "Calling resume"); - cs->resolve_ret = 0; - gf_log (GF_NFS3, GF_LOG_TRACE, "Opening uncached fd done: %d", - openedfd->refcount); - cs->fd = fd_ref (openedfd); - list_del (&cs->openwait_q); - nfs3_call_resume (cs); + 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, + count); + else + gf_log (GF_NFS3, GF_LOG_DEBUG, "XID: %x, %s: args: %s, offset:" + " %"PRIu64", count: %"PRIu32", %s", xid, op, fhstr, + offt, count, + (stablewrite == UNSTABLE)?"UNSTABLE":"STABLE"); - return 0; } int -nfs3_flush_inode_queue (struct inode_op_queue *inode_q, fd_t *openedfd) -{ - nfs3_call_state_t *cstmp = NULL; - nfs3_call_state_t *cs = NULL; +nfs3_getattr_loglevel (nfsstat3 stat) { - if ((!openedfd) || (!inode_q)) - return -1; + int ll = GF_LOG_DEBUG; - list_for_each_entry_safe (cs, cstmp, &inode_q->opq, openwait_q) - nfs3_flush_call_state (cs, openedfd); + switch (stat) { - return 0; + case NFS3ERR_PERM: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_NOENT: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_ACCES: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_EXIST: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_XDEV: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_NODEV: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_IO: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_NXIO: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_NOTDIR: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_ISDIR: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_INVAL: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_NOSPC: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_ROFS: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_FBIG: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_MLINK: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_NAMETOOLONG: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_NOTEMPTY: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_SERVERFAULT: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_NOTSUPP: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_BADHANDLE: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_STALE: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_DQUOT: + ll = GF_LOG_WARNING; + break; + + default: + ll = GF_LOG_DEBUG; + break; + } + + return ll; } int -nfs3_flush_open_wait_call_states (nfs3_call_state_t *cs, fd_t *openedfd) -{ - struct inode_op_queue *inode_q = NULL; - uint64_t ctxaddr = 0; - int ret = 0; +nfs3_setattr_loglevel (nfsstat3 stat) { - if (!cs) - return -1; + int ll = GF_LOG_DEBUG; - gf_log (GF_NFS3, GF_LOG_TRACE, "Flushing call state"); - ret = inode_ctx_get (cs->resolvedloc.inode, cs->nfsx, &ctxaddr); - if (ret == -1) { - gf_log (GF_NFS3, GF_LOG_TRACE, "No inode queue present"); - goto out; - } + switch (stat) { - inode_q = (struct inode_op_queue *)(long)ctxaddr; - if (!inode_q) - goto out; + case NFS3ERR_NOENT: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_EXIST: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_XDEV: + ll = GF_LOG_WARNING; + break; - pthread_mutex_lock (&inode_q->qlock); - { - nfs3_flush_inode_queue (inode_q, openedfd); + case NFS3ERR_NODEV: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_IO: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_NXIO: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_NOTDIR: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_ISDIR: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_INVAL: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_NOSPC: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_ROFS: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_FBIG: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_MLINK: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_NAMETOOLONG: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_NOTEMPTY: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_SERVERFAULT: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_NOTSUPP: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_BADHANDLE: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_STALE: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_DQUOT: + ll = GF_LOG_WARNING; + break; + + default: + ll = GF_LOG_DEBUG; + break; } - pthread_mutex_unlock (&inode_q->qlock); -out: - return 0; + return ll; } int -__nfs3_fdcache_update_entry (struct nfs3_state *nfs3, fd_t *fd) -{ - uint64_t ctxaddr = 0; - struct nfs3_fd_entry *fde = NULL; +nfs3_lookup_loglevel (nfsstat3 stat) { - if ((!nfs3) || (!fd)) - return -1; + int ll = GF_LOG_DEBUG; + + switch (stat) { + + case NFS3ERR_PERM: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_ACCES: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_EXIST: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_XDEV: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_NODEV: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_IO: + ll = GF_LOG_WARNING; + break; - gf_log (GF_NFS3, GF_LOG_TRACE, "Updating fd: 0x%lx", (long int)fd); - fd_ctx_get (fd, nfs3->nfsx, &ctxaddr); - fde = (struct nfs3_fd_entry *)(long)ctxaddr; - if (fde) { - list_del (&fde->list); - list_add_tail (&fde->list, &nfs3->fdlru); + case NFS3ERR_NXIO: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_NOTDIR: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_ISDIR: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_INVAL: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_NOSPC: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_ROFS: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_FBIG: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_MLINK: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_NAMETOOLONG: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_NOTEMPTY: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_SERVERFAULT: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_NOTSUPP: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_BADHANDLE: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_STALE: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_DQUOT: + ll = GF_LOG_WARNING; + break; + + default: + ll = GF_LOG_DEBUG; + break; } - return 0; + return ll; } int -nfs3_fdcache_update (struct nfs3_state *nfs3, fd_t *fd) -{ - if ((!nfs3) || (!fd)) - return -1; +nfs3_access_loglevel (nfsstat3 stat) { + + int ll = GF_LOG_DEBUG; + + switch (stat) { + + case NFS3ERR_NOENT: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_EXIST: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_XDEV: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_NODEV: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_IO: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_NXIO: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_NOTDIR: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_ISDIR: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_INVAL: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_NOSPC: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_ROFS: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_FBIG: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_MLINK: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_NAMETOOLONG: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_NOTEMPTY: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_SERVERFAULT: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_NOTSUPP: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_BADHANDLE: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_STALE: + ll = GF_LOG_WARNING; + break; - LOCK (&nfs3->fdlrulock); - { - __nfs3_fdcache_update_entry (nfs3, fd); + case NFS3ERR_DQUOT: + ll = GF_LOG_WARNING; + break; + + default: + ll = GF_LOG_DEBUG; + break; } - UNLOCK (&nfs3->fdlrulock); - return 0; + return ll; } int -__nfs3_fdcache_remove_entry (struct nfs3_state *nfs3, struct nfs3_fd_entry *fde) -{ - if ((!fde) || (!nfs3)) - return 0; +nfs3_readlink_loglevel (nfsstat3 stat) { - gf_log (GF_NFS3, GF_LOG_TRACE, "Removing fd: 0x%lx: %d", - (long int)fde->cachedfd, fde->cachedfd->refcount); - list_del (&fde->list); - fd_ctx_del (fde->cachedfd, nfs3->nfsx, NULL); - fd_unref (fde->cachedfd); - GF_FREE (fde); - --nfs3->fdcount; + int ll = GF_LOG_DEBUG; - return 0; -} + switch (stat) { + + case NFS3ERR_EXIST: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_XDEV: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_NODEV: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_IO: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_NXIO: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_NOTDIR: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_ISDIR: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_INVAL: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_NOSPC: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_ROFS: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_FBIG: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_MLINK: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_NOTEMPTY: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_SERVERFAULT: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_NOTSUPP: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_BADHANDLE: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_STALE: + ll = GF_LOG_WARNING; + break; + case NFS3ERR_DQUOT: + ll = GF_LOG_WARNING; + break; + + default: + ll = GF_LOG_DEBUG; + break; + } + + return ll; +} int -nfs3_fdcache_remove (struct nfs3_state *nfs3, fd_t *fd) -{ - struct nfs3_fd_entry *fde = NULL; - uint64_t ctxaddr = 0; +nfs3_read_loglevel (nfsstat3 stat) { - if ((!nfs3) || (!fd)) - return -1; + int ll = GF_LOG_DEBUG; + + switch (stat) { + + case NFS3ERR_NOENT: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_EXIST: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_XDEV: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_NODEV: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_IO: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_NXIO: + ll = GF_LOG_WARNING; + break; - LOCK (&nfs3->fdlrulock); - { - fd_ctx_get (fd, nfs3->nfsx, &ctxaddr); - fde = (struct nfs3_fd_entry *)(long)ctxaddr; - __nfs3_fdcache_remove_entry (nfs3, fde); + case NFS3ERR_NOTDIR: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_ISDIR: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_INVAL: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_NOSPC: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_ROFS: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_FBIG: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_MLINK: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_NAMETOOLONG: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_NOTEMPTY: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_SERVERFAULT: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_NOTSUPP: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_BADHANDLE: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_STALE: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_DQUOT: + ll = GF_LOG_WARNING; + break; + + default: + ll = GF_LOG_DEBUG; + break; } - UNLOCK (&nfs3->fdlrulock); - return 0; + return ll; } int -__nfs3_fdcache_replace (struct nfs3_state *nfs3) -{ - struct nfs3_fd_entry *fde = NULL; - struct nfs3_fd_entry *tmp = NULL; +nfs3_write_loglevel (nfsstat3 stat) { - if (!nfs3) - return -1; + int ll = GF_LOG_DEBUG; - if (nfs3->fdcount <= GF_NFS3_FDCACHE_SIZE) - return 0; + switch (stat) { - list_for_each_entry_safe (fde, tmp, &nfs3->fdlru, list) + case NFS3ERR_NOENT: + ll = GF_LOG_WARNING; break; - __nfs3_fdcache_remove_entry (nfs3, fde); + case NFS3ERR_EXIST: + ll = GF_LOG_WARNING; + break; - return 0; -} + case NFS3ERR_XDEV: + ll = GF_LOG_WARNING; + break; + case NFS3ERR_NODEV: + ll = GF_LOG_WARNING; + break; + case NFS3ERR_IO: + ll = GF_LOG_WARNING; + break; -int -nfs3_fdcache_add (struct nfs3_state *nfs3, fd_t *fd) -{ - struct nfs3_fd_entry *fde = NULL; - int ret = -1; + case NFS3ERR_NXIO: + ll = GF_LOG_WARNING; + break; - if ((!nfs3) || (!fd)) - return -1; + case NFS3ERR_NOTDIR: + ll = GF_LOG_WARNING; + break; - fde = GF_CALLOC (1, sizeof (*fd), gf_nfs_mt_nfs3_fd_entry); - if (!fde) { - gf_log (GF_NFS3, GF_LOG_ERROR, "fd entry allocation failed"); - goto out; - } + case NFS3ERR_ISDIR: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_INVAL: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_NOSPC: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_ROFS: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_FBIG: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_MLINK: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_NAMETOOLONG: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_NOTEMPTY: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_SERVERFAULT: + ll = GF_LOG_WARNING; + break; - /* Already refd by caller. */ - fde->cachedfd = fd; - INIT_LIST_HEAD (&fde->list); - - LOCK (&nfs3->fdlrulock); - { - gf_log (GF_NFS3, GF_LOG_TRACE, "Adding fd: 0x%lx", - (long int) fd); - fd_ctx_set (fd, nfs3->nfsx, (uintptr_t)fde); - fd_bind (fd); - list_add_tail (&fde->list, &nfs3->fdlru); - ++nfs3->fdcount; - __nfs3_fdcache_replace (nfs3); + case NFS3ERR_NOTSUPP: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_BADHANDLE: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_STALE: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_DQUOT: + ll = GF_LOG_WARNING; + break; + + default: + ll = GF_LOG_DEBUG; + break; } - UNLOCK (&nfs3->fdlrulock); -out: - return ret; + return ll; } -int32_t -nfs3_file_open_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno, fd_t *fd) -{ - nfs3_call_state_t *cs = NULL; - struct nfs3_state *nfs3 = NULL; +int +nfs3_create_loglevel (nfsstat3 stat) { - cs = frame->local; - if (op_ret == -1) { - gf_log (GF_NFS3, GF_LOG_TRACE, "Opening uncached fd failed"); - cs->resolve_ret = -1; - cs->resolve_errno = op_errno; - fd = NULL; - } else { - gf_log (GF_NFS3, GF_LOG_TRACE, "Opening uncached fd done: %d", - fd->refcount); + int ll = GF_LOG_DEBUG; + + switch (stat) { + + case NFS3ERR_NOENT: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_EXIST: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_XDEV: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_NODEV: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_IO: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_NXIO: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_NOTDIR: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_ISDIR: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_INVAL: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_FBIG: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_MLINK: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_NOTEMPTY: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_SERVERFAULT: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_NOTSUPP: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_BADHANDLE: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_STALE: + ll = GF_LOG_WARNING; + break; + + default: + ll = GF_LOG_DEBUG; + break; } - nfs3 = nfs_rpcsvc_request_program_private (cs->req); - nfs3_flush_open_wait_call_states (cs, fd); - nfs3_fdcache_add (nfs3, fd); - return 0; + return ll; } -struct inode_op_queue * -__nfs3_get_inode_queue (nfs3_call_state_t *cs) -{ - struct inode_op_queue *inode_q = NULL; - int ret = -1; - uint64_t ctxaddr = 0; +int +nfs3_mkdir_loglevel (nfsstat3 stat) { - ret = __inode_ctx_get (cs->resolvedloc.inode, cs->nfsx, &ctxaddr); - if (ret == 0) { - inode_q = (struct inode_op_queue *)(long)ctxaddr; - gf_log (GF_NFS3, GF_LOG_TRACE, "Inode queue already inited"); - goto err; - } + int ll = GF_LOG_DEBUG; - inode_q = GF_CALLOC (1, sizeof (*inode_q), gf_nfs_mt_inode_q); - if (!inode_q) { - gf_log (GF_NFS3, GF_LOG_ERROR, "Memory allocation failed"); - goto err; - } + switch (stat) { - gf_log (GF_NFS3, GF_LOG_TRACE, "Initing inode queue"); - INIT_LIST_HEAD (&inode_q->opq); - pthread_mutex_init (&inode_q->qlock, NULL); - __inode_ctx_put (cs->resolvedloc.inode, cs->nfsx, (uintptr_t)inode_q); + case NFS3ERR_NOENT: + ll = GF_LOG_WARNING; + break; -err: - return inode_q; -} + case NFS3ERR_XDEV: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_NODEV: + ll = GF_LOG_WARNING; + break; + case NFS3ERR_IO: + ll = GF_LOG_WARNING; + break; -struct inode_op_queue * -nfs3_get_inode_queue (nfs3_call_state_t *cs) -{ - struct inode_op_queue *inode_q = NULL; + case NFS3ERR_NXIO: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_NOTDIR: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_ISDIR: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_INVAL: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_FBIG: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_MLINK: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_NOTEMPTY: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_SERVERFAULT: + ll = GF_LOG_WARNING; + break; - LOCK (&cs->resolvedloc.inode->lock); - { - inode_q = __nfs3_get_inode_queue (cs); + case NFS3ERR_NOTSUPP: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_BADHANDLE: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_STALE: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_DQUOT: + ll = GF_LOG_WARNING; + break; + + default: + ll = GF_LOG_DEBUG; + break; } - UNLOCK (&cs->resolvedloc.inode->lock); - return inode_q; + return ll; } -#define GF_NFS3_FD_OPEN_INPROGRESS 1 -#define GF_NFS3_FD_NEEDS_OPEN 0 +int +nfs3_symlink_loglevel (nfsstat3 stat) { + int ll = GF_LOG_DEBUG; -int -__nfs3_queue_call_state (struct inode_op_queue *inode_q, nfs3_call_state_t *cs) -{ - int ret = -1; + switch (stat) { - if (!inode_q) - goto err; + case NFS3ERR_XDEV: + ll = GF_LOG_WARNING; + break; - pthread_mutex_lock (&inode_q->qlock); - { - if (list_empty (&inode_q->opq)) { - gf_log (GF_NFS3, GF_LOG_TRACE, "First call in queue"); - ret = GF_NFS3_FD_NEEDS_OPEN; - } else - ret = GF_NFS3_FD_OPEN_INPROGRESS; + case NFS3ERR_NODEV: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_IO: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_NXIO: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_NOTDIR: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_ISDIR: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_INVAL: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_FBIG: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_MLINK: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_NOTEMPTY: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_SERVERFAULT: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_NOTSUPP: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_BADHANDLE: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_STALE: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_DQUOT: + ll = GF_LOG_WARNING; + break; - gf_log (GF_NFS3, GF_LOG_TRACE, "Queueing call state"); - list_add_tail (&cs->openwait_q, &inode_q->opq); + default: + ll = GF_LOG_DEBUG; + break; } - pthread_mutex_unlock (&inode_q->qlock); -err: - return ret; + return ll; } -/* Returns GF_NFS3_FD_NEEDS_OPEN if the current call is the first one to be - * queued. If so, the caller will need to send the open fop. If this is a - * non-first call to be queued, it means the fd opening is in progress and - * GF_NFS3_FD_OPEN_INPROGRESS is returned. - * - * Returns -1 on error. - */ int -nfs3_queue_call_state (nfs3_call_state_t *cs) -{ - struct inode_op_queue *inode_q = NULL; - int ret = -1; +nfs3_mknod_loglevel (nfsstat3 stat) { - inode_q = nfs3_get_inode_queue (cs); - if (!inode_q) { - gf_log (GF_NFS3, GF_LOG_ERROR, "Failed to get inode op queue"); - goto err; + int ll = GF_LOG_DEBUG; + + switch (stat) { + + case NFS3ERR_NOENT: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_XDEV: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_NODEV: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_IO: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_NXIO: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_NOTDIR: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_ISDIR: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_INVAL: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_FBIG: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_MLINK: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_NOTEMPTY: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_SERVERFAULT: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_NOTSUPP: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_BADHANDLE: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_STALE: + ll = GF_LOG_WARNING; + break; + + default: + ll = GF_LOG_DEBUG; + break; } - ret = __nfs3_queue_call_state (inode_q, cs); + return ll; +} + +int +nfs3_remove_loglevel (nfsstat3 stat) { -err: - return ret; + int ll = GF_LOG_DEBUG; + + switch (stat) { + + case NFS3ERR_EXIST: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_XDEV: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_NODEV: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_IO: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_NXIO: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_NOTDIR: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_INVAL: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_NOSPC: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_FBIG: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_MLINK: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_SERVERFAULT: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_NOTSUPP: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_BADHANDLE: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_STALE: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_DQUOT: + ll = GF_LOG_WARNING; + break; + + default: + ll = GF_LOG_DEBUG; + break; + } + + return ll; } int -__nfs3_file_open_and_resume (nfs3_call_state_t *cs) -{ - nfs_user_t nfu = {0, }; - int ret = -EFAULT; +nfs3_rmdir_loglevel (nfsstat3 stat) { - if (!cs) - return ret; + int ll = GF_LOG_DEBUG; - ret = nfs3_queue_call_state (cs); - if (ret == -1) { - gf_log (GF_NFS3, GF_LOG_ERROR, "Error queueing call state"); - ret = -EFAULT; - goto out; - } else if (ret == GF_NFS3_FD_OPEN_INPROGRESS) { - gf_log (GF_NFS3, GF_LOG_TRACE, "Open in progress. Will wait."); - ret = 0; - goto out; + switch (stat) { + + case NFS3ERR_EXIST: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_XDEV: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_NODEV: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_IO: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_NXIO: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_NOTDIR: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_INVAL: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_NOSPC: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_FBIG: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_MLINK: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_SERVERFAULT: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_NOTSUPP: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_BADHANDLE: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_STALE: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_DQUOT: + ll = GF_LOG_WARNING; + break; + + default: + ll = GF_LOG_DEBUG; + break; } - nfs_user_root_create (&nfu); - gf_log (GF_NFS3, GF_LOG_TRACE, "Opening uncached fd"); - ret = nfs_open (cs->nfsx, cs->vol, &nfu, &cs->resolvedloc, O_RDWR, - nfs3_file_open_cbk, cs); -out: - return ret; + return ll; } -fd_t * -nfs3_fdcache_getfd (struct nfs3_state *nfs3, inode_t *inode) -{ - fd_t *fd = NULL; +int +nfs3_rename_loglevel (nfsstat3 stat) { - if ((!nfs3) || (!inode)) - return NULL; + int ll = GF_LOG_DEBUG; - fd = fd_lookup (inode, 0); - if (fd) { - /* Already refd by fd_lookup, so no need to ref again. */ - gf_log (GF_NFS3, GF_LOG_TRACE, "fd found in state: %d", - fd->refcount); - nfs3_fdcache_update (nfs3, fd); - } else - gf_log (GF_NFS3, GF_LOG_TRACE, "fd not found in state"); + switch (stat) { - return fd; -} + case NFS3ERR_XDEV: + ll = GF_LOG_WARNING; + break; + case NFS3ERR_NODEV: + ll = GF_LOG_WARNING; + break; + case NFS3ERR_IO: + ll = GF_LOG_WARNING; + break; -int -nfs3_file_open_and_resume (nfs3_call_state_t *cs, nfs3_resume_fn_t resume) -{ - fd_t *fd = NULL; - int ret = -EFAULT; + case NFS3ERR_NXIO: + ll = GF_LOG_WARNING; + break; - if (!cs) - return ret; + case NFS3ERR_NOTDIR: + ll = GF_LOG_WARNING; + break; - cs->resume_fn = resume; - gf_log (GF_NFS3, GF_LOG_TRACE, "Opening: %s", cs->resolvedloc.path); - fd = nfs3_fdcache_getfd (cs->nfs3state, cs->resolvedloc.inode); - if (fd) { - cs->fd = fd; /* Gets unrefd when the call state is wiped. */ - cs->resolve_ret = 0; - nfs3_call_resume (cs); - ret = 0; - goto err; - } + case NFS3ERR_ISDIR: + ll = GF_LOG_WARNING; + break; - ret = __nfs3_file_open_and_resume (cs); + case NFS3ERR_INVAL: + ll = GF_LOG_WARNING; + break; -err: - return ret; -} + case NFS3ERR_NOSPC: + ll = GF_LOG_WARNING; + break; + case NFS3ERR_FBIG: + ll = GF_LOG_WARNING; + break; -void -nfs3_stat_to_errstr (uint32_t xid, char *op, nfsstat3 stat, int pstat, - char *errstr) -{ - if ((!op) || (!errstr)) - return; + case NFS3ERR_MLINK: + ll = GF_LOG_WARNING; + break; - sprintf (errstr, "XID: %x, %s: NFS: %d(%s), POSIX: %d(%s)", xid, op, - stat, nfsstat3_strerror (stat), pstat, strerror (pstat)); -} + case NFS3ERR_NOTEMPTY: + ll = GF_LOG_WARNING; + break; -void -nfs3_log_common_call (uint32_t xid, char *op, struct nfs3_fh *fh) -{ - char fhstr[1024]; + case NFS3ERR_SERVERFAULT: + ll = GF_LOG_WARNING; + break; - nfs3_fh_to_str (fh, fhstr); - gf_log (GF_NFS3, GF_LOG_DEBUG, "XID: %x, %s: args: %s", xid, op, - fhstr); -} + case NFS3ERR_NOTSUPP: + ll = GF_LOG_WARNING; + break; + case NFS3ERR_BADHANDLE: + ll = GF_LOG_WARNING; + break; -void -nfs3_log_fh_entry_call (uint32_t xid, char *op, struct nfs3_fh *fh, - char *name) -{ - char fhstr[1024]; + case NFS3ERR_STALE: + ll = GF_LOG_WARNING; + break; - nfs3_fh_to_str (fh, fhstr); - gf_log (GF_NFS3, GF_LOG_DEBUG, "XID: %x, %s: args: %s, name: %s", xid, - op, fhstr, name); + case NFS3ERR_DQUOT: + ll = GF_LOG_WARNING; + break; + + default: + ll = GF_LOG_DEBUG; + break; + } + + return ll; } -void -nfs3_log_rename_call (uint32_t xid, struct nfs3_fh *src, char *sname, - struct nfs3_fh *dst, char *dname) -{ - char sfhstr[1024]; - char dfhstr[1024]; +int +nfs3_link_loglevel (nfsstat3 stat) { - nfs3_fh_to_str (src, sfhstr); - nfs3_fh_to_str (dst, 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); -} + int ll = GF_LOG_DEBUG; + switch (stat) { + case NFS3ERR_XDEV: + ll = GF_LOG_WARNING; + break; -void -nfs3_log_create_call (uint32_t xid, struct nfs3_fh *fh, char *name, - createmode3 mode) -{ - char fhstr[1024]; - char *modestr = NULL; - char exclmode[] = "EXCLUSIVE"; - char unchkd[] = "UNCHECKED"; - char guarded[] = "GUARDED"; + case NFS3ERR_NODEV: + ll = GF_LOG_WARNING; + break; - nfs3_fh_to_str (fh, fhstr); - if (mode == EXCLUSIVE) - modestr = exclmode; - else if (mode == GUARDED) - modestr = guarded; - else - modestr = unchkd; + case NFS3ERR_IO: + ll = GF_LOG_WARNING; + break; - gf_log (GF_NFS3, GF_LOG_DEBUG, "XID: %x, CREATE: args: %s, name: %s," - " mode: %s", xid, fhstr, name, modestr); -} + case NFS3ERR_NXIO: + ll = GF_LOG_WARNING; + break; + case NFS3ERR_INVAL: + ll = GF_LOG_WARNING; + break; -void -nfs3_log_mknod_call (uint32_t xid, struct nfs3_fh *fh, char *name, int type) -{ - char fhstr[1024]; - char *modestr = NULL; - char chr[] = "CHAR"; - char blk[] = "BLK"; - char sock[] = "SOCK"; - char fifo[] = "FIFO"; + case NFS3ERR_FBIG: + ll = GF_LOG_WARNING; + break; - nfs3_fh_to_str (fh, fhstr); - if (type == NF3CHR) - modestr = chr; - else if (type == NF3BLK) - modestr = blk; - else if (type == NF3SOCK) - modestr = sock; - else - modestr = fifo; + case NFS3ERR_MLINK: + ll = GF_LOG_WARNING; + break; - gf_log (GF_NFS3, GF_LOG_DEBUG, "XID: %x, MKNOD: args: %s, name: %s," - " type: %s", xid, fhstr, name, modestr); -} + case NFS3ERR_NOTEMPTY: + ll = GF_LOG_WARNING; + break; + case NFS3ERR_SERVERFAULT: + ll = GF_LOG_WARNING; + break; + case NFS3ERR_NOTSUPP: + ll = GF_LOG_WARNING; + break; -void -nfs3_log_symlink_call (uint32_t xid, struct nfs3_fh *fh, char *name, char *tgt) -{ - char fhstr[1024]; + case NFS3ERR_BADHANDLE: + ll = GF_LOG_WARNING; + break; - nfs3_fh_to_str (fh, fhstr); - gf_log (GF_NFS3, GF_LOG_DEBUG, "XID: %x, SYMLINK: args: %s, name: %s," - " target: %s", xid, fhstr, name, tgt); + case NFS3ERR_STALE: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_DQUOT: + ll = GF_LOG_WARNING; + break; + + default: + ll = GF_LOG_DEBUG; + break; + } + + return ll; } -void -nfs3_log_link_call (uint32_t xid, struct nfs3_fh *fh, char *name, - struct nfs3_fh *tgt) -{ - char dfhstr[1024]; - char tfhstr[1024]; +int +nfs3_readdir_loglevel (nfsstat3 stat) { - nfs3_fh_to_str (fh, dfhstr); - nfs3_fh_to_str (tgt, tfhstr); - gf_log (GF_NFS3, GF_LOG_DEBUG, "XID: %x, LINK: args: %s, name: %s," - " target: %s", xid, dfhstr, name, tfhstr); + int ll = GF_LOG_DEBUG; + + switch (stat) { + + case NFS3ERR_NOENT: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_EXIST: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_XDEV: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_NODEV: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_IO: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_NXIO: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_NOTDIR: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_ISDIR: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_INVAL: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_NOSPC: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_ROFS: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_FBIG: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_MLINK: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_NAMETOOLONG: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_NOTEMPTY: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_SERVERFAULT: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_NOTSUPP: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_BADHANDLE: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_STALE: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_DQUOT: + ll = GF_LOG_WARNING; + break; + + default: + ll = GF_LOG_DEBUG; + break; + } + + return ll; } -void -nfs3_log_rw_call (uint32_t xid, char *op, struct nfs3_fh *fh, offset3 offt, - count3 count, int stablewrite) -{ - char fhstr[1024]; +int +nfs3_fsstat_loglevel (nfsstat3 stat) { - nfs3_fh_to_str (fh, fhstr); - if (stablewrite == -1) - gf_log (GF_NFS3, GF_LOG_DEBUG, "XID: %x, %s: args: %s, offset:" - " %"PRIu64", count: %"PRIu32, xid, op, fhstr, offt, - count); - else - gf_log (GF_NFS3, GF_LOG_DEBUG, "XID: %x, %s: args: %s, offset:" - " %"PRIu64", count: %"PRIu32", %s", xid, op, fhstr, - offt, count, - (stablewrite == UNSTABLE)?"UNSTABLE":"STABLE"); + int ll = GF_LOG_DEBUG; + + switch (stat) { + + case NFS3ERR_PERM: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_NOENT: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_ACCES: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_EXIST: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_XDEV: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_NODEV: + ll = GF_LOG_WARNING; + break; + case NFS3ERR_IO: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_NXIO: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_NOTDIR: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_ISDIR: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_INVAL: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_NOSPC: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_ROFS: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_FBIG: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_MLINK: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_NAMETOOLONG: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_NOTEMPTY: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_SERVERFAULT: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_NOTSUPP: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_BADHANDLE: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_STALE: + ll = GF_LOG_WARNING; + break; + + case NFS3ERR_DQUOT: + ll = GF_LOG_WARNING; + break; + + default: + ll = GF_LOG_DEBUG; + break; + } + + return ll; } +struct nfs3op_str { + int op; + char str[100]; +}; + +struct nfs3op_str nfs3op_strings[] = { + { NFS3_NULL, "NULL"}, + { NFS3_GETATTR, "GETATTR"}, + { NFS3_SETATTR, "SETATTR"}, + { NFS3_LOOKUP, "LOOKUP"}, + { NFS3_ACCESS, "ACCESS"}, + { NFS3_READLINK, "READLINK"}, + { NFS3_READ, "READ"}, + { NFS3_WRITE, "WRITE"}, + { NFS3_CREATE, "CREATE"}, + { NFS3_MKDIR, "MKDIR"}, + { NFS3_SYMLINK, "SYMLINK"}, + { NFS3_MKNOD, "MKNOD"}, + { NFS3_REMOVE, "REMOVE"}, + { NFS3_RMDIR, "RMDIR"}, + { NFS3_RENAME, "RENAME"}, + { NFS3_LINK, "LINK"}, + { NFS3_READDIR, "READDIR"}, + { NFS3_READDIRP, "READDIRP"}, + { NFS3_FSSTAT, "FSSTAT"}, + { NFS3_FSINFO, "FSINFO"}, + { NFS3_PATHCONF, "PATHCONF"}, + { NFS3_COMMIT, "COMMIT"}, +}; + +int +nfs3_loglevel (int nfs_op, nfsstat3 stat) { + + int ll = GF_LOG_DEBUG; + + switch (nfs_op) { + case NFS3_GETATTR: + ll = nfs3_getattr_loglevel (stat); + break; + + case NFS3_SETATTR: + ll = nfs3_setattr_loglevel (stat); + break; + + case NFS3_LOOKUP: + ll = nfs3_lookup_loglevel (stat); + break; + + case NFS3_ACCESS: + ll = nfs3_access_loglevel (stat); + break; + + case NFS3_READLINK: + ll = nfs3_readlink_loglevel (stat); + break; + + case NFS3_READ: + ll = nfs3_read_loglevel (stat); + break; + + case NFS3_WRITE: + ll = nfs3_write_loglevel (stat); + break; + + case NFS3_CREATE: + ll = nfs3_create_loglevel (stat); + break; + + case NFS3_MKDIR: + ll = nfs3_mkdir_loglevel (stat); + break; + + case NFS3_SYMLINK: + ll = nfs3_symlink_loglevel (stat); + break; + + case NFS3_MKNOD: + ll = nfs3_mknod_loglevel (stat); + break; + + case NFS3_REMOVE: + ll = nfs3_remove_loglevel (stat); + break; + + case NFS3_RMDIR: + ll = nfs3_rmdir_loglevel (stat); + break; + + case NFS3_RENAME: + ll = nfs3_rename_loglevel (stat); + break; + + case NFS3_LINK: + ll = nfs3_link_loglevel (stat); + break; + + case NFS3_READDIR: + ll = nfs3_readdir_loglevel (stat); + break; + + case NFS3_READDIRP: + ll = nfs3_readdir_loglevel (stat); + break; + + case NFS3_FSSTAT: + ll = nfs3_fsstat_loglevel (stat); + break; + + case NFS3_FSINFO: + ll = nfs3_fsstat_loglevel (stat); + break; + + case NFS3_PATHCONF: + ll = nfs3_fsstat_loglevel (stat); + break; + + case NFS3_COMMIT: + ll = nfs3_write_loglevel (stat); + break; + + default: + ll = GF_LOG_DEBUG; + break; + } + + return ll; +} void -nfs3_log_common_res (uint32_t xid, char *op, nfsstat3 stat, int pstat) +nfs3_log_common_res (uint32_t xid, int op, nfsstat3 stat, int pstat) { char errstr[1024]; + int ll = nfs3_loglevel (op, stat); - nfs3_stat_to_errstr (xid, op, stat, pstat, errstr); - gf_log (GF_NFS3, GF_LOG_DEBUG, "%s", 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); } void nfs3_log_readlink_res (uint32_t xid, nfsstat3 stat, int pstat, char *linkpath) { char errstr[1024]; + int ll = nfs3_loglevel (NFS3_READLINK, stat); + + if (THIS->ctx->log.loglevel < ll) + return; - nfs3_stat_to_errstr (xid, "READLINK", stat, pstat, errstr); - gf_log (GF_NFS3, GF_LOG_DEBUG, "%s, target: %s", errstr, linkpath); + nfs3_stat_to_errstr (xid, "READLINK", stat, pstat, errstr, sizeof (errstr)); + gf_log (GF_NFS3, ll, "%s, target: %s", + errstr, linkpath); } @@ -2374,14 +3421,18 @@ 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; - nfs3_stat_to_errstr (xid, "READ", stat, pstat, errstr); + ll = nfs3_loglevel (NFS3_READ, stat); + if (THIS->ctx->log.loglevel < ll) + return; + nfs3_stat_to_errstr (xid, "READ", stat, pstat, errstr, sizeof (errstr)); if (vec) - gf_log (GF_NFS3, GF_LOG_DEBUG, "%s, count: %"PRIu32", is_eof:" + gf_log (GF_NFS3, ll, "%s, count: %"PRIu32", is_eof:" " %d, vector: count: %d, len: %zd", errstr, count, is_eof, veccount, vec->iov_len); else - gf_log (GF_NFS3, GF_LOG_DEBUG, "%s, count: %"PRIu32", is_eof:" + gf_log (GF_NFS3, ll, "%s, count: %"PRIu32", is_eof:" " %d", errstr, count, is_eof); } @@ -2391,25 +3442,32 @@ 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); + + if (THIS->ctx->log.loglevel < ll) + return; - nfs3_stat_to_errstr (xid, "WRITE", stat, pstat, errstr); - gf_log (GF_NFS3, GF_LOG_DEBUG, "%s, count: %"PRIu32", %s,wverf: %"PRIu64 + 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); } void -nfs3_log_newfh_res (uint32_t xid, char *op, nfsstat3 stat, int pstat, +nfs3_log_newfh_res (uint32_t xid, int op, nfsstat3 stat, int pstat, struct nfs3_fh *newfh) { char errstr[1024]; char fhstr[1024]; + int ll = nfs3_loglevel (op, stat); - nfs3_stat_to_errstr (xid, op, 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, GF_LOG_DEBUG, "%s, %s", errstr, fhstr); + gf_log (GF_NFS3, nfs3_loglevel (op, stat), "%s, %s", errstr, fhstr); } @@ -2418,9 +3476,12 @@ 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); - nfs3_stat_to_errstr (xid, "READDIR", stat, pstat, errstr); - gf_log (GF_NFS3, GF_LOG_DEBUG, "%s, count: %"PRIu32", cverf: %"PRIu64 + 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); } @@ -2430,9 +3491,12 @@ nfs3_log_readdirp_res (uint32_t xid, nfsstat3 stat, int pstat, uint64_t cverf, count3 dircount, count3 maxcount, int is_eof) { char errstr[1024]; + int ll = nfs3_loglevel (NFS3_READDIRP, stat); - nfs3_stat_to_errstr (xid, "READDIRPLUS", stat, pstat, errstr); - gf_log (GF_NFS3, GF_LOG_DEBUG, "%s, dircount: %"PRIu32", maxcount: %" + 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); } @@ -2442,9 +3506,12 @@ void nfs3_log_commit_res (uint32_t xid, nfsstat3 stat, int pstat, uint64_t wverf) { char errstr[1024]; + int ll = nfs3_loglevel (NFS3_COMMIT, stat); - nfs3_stat_to_errstr (xid, "COMMIT", stat, pstat, errstr); - gf_log (GF_NFS3, GF_LOG_DEBUG, "%s, wverf: %"PRIu64, errstr, wverf); + 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); } @@ -2454,7 +3521,10 @@ nfs3_log_readdir_call (uint32_t xid, struct nfs3_fh *fh, count3 dircount, { char fhstr[1024]; - nfs3_fh_to_str (fh, fhstr); + if (THIS->ctx->log.loglevel < GF_LOG_DEBUG) + return; + + nfs3_fh_to_str (fh, fhstr, sizeof (fhstr)); if (maxcount == 0) gf_log (GF_NFS3, GF_LOG_DEBUG, "XID: %x, READDIR: args: %s," @@ -2475,9 +3545,11 @@ nfs3_fh_resolve_inode_done (nfs3_call_state_t *cs, inode_t *inode) return ret; gf_log (GF_NFS3, GF_LOG_TRACE, "FH inode resolved"); - ret = nfs_inode_loc_fill (inode, &cs->resolvedloc); - if (ret < 0) + ret = nfs_inode_loc_fill (inode, &cs->resolvedloc, NFS_RESOLVE_EXIST); + if (ret < 0) { + gf_log (GF_NFS3, GF_LOG_ERROR, "inode loc fill failed"); goto err; + } nfs3_call_resume (cs); @@ -2485,54 +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 ((ia->ia_gen == fh->gen) && (ia->ia_ino == fh->ino)) { - gf_log (GF_NFS3, GF_LOG_TRACE, "Found entry: gen: %"PRId64 - " ino: %"PRId64", name: %s, hashcount %d", ia->ia_gen, - ia->ia_ino, 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_ino, ia->ia_gen)) { - 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, @@ -2542,401 +3566,82 @@ nfs3_fh_resolve_entry_lookup_cbk (call_frame_t *frame, void *cookie, 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, GF_LOG_TRACE, "Lookup failed: %s: %s", + gf_log (GF_NFS3, (op_errno == ENOENT ? GF_LOG_TRACE : GF_LOG_ERROR), + "Lookup failed: %s: %s", cs->resolvedloc.path, strerror (op_errno)); goto err; } else gf_log (GF_NFS3, GF_LOG_TRACE, "Entry looked up: %s", cs->resolvedloc.path); - inode_link (inode, cs->resolvedloc.parent, cs->resolvedloc.name, buf); + memcpy (&cs->stbuf, buf, sizeof (*buf)); + memcpy (&cs->postparent, postparent, sizeof (*postparent)); + linked_inode = inode_link (inode, cs->resolvedloc.parent, + cs->resolvedloc.name, buf); + if (linked_inode) { + inode_lookup (linked_inode); + inode_unref (cs->resolvedloc.inode); + cs->resolvedloc.inode = linked_inode; + } err: nfs3_call_resume (cs); return 0; } - int32_t -nfs3_fh_resolve_readdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno, - gf_dirent_t *entries); - -int -nfs3_fh_resolve_found_entry (nfs3_call_state_t *cs, gf_dirent_t *candidate) -{ - uint64_t dirino = 0; - uint64_t dirgen = 0; - int ret = 0; - nfs_user_t nfu = {0, }; - - if ((!cs) || (!candidate)) - return -EFAULT; - - dirino = cs->resolvedloc.inode->ino; - - nfs_loc_wipe (&cs->resolvedloc); - ret = nfs_entry_loc_fill (cs->vol->itable, dirino, dirgen, - 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, +nfs3_fh_resolve_inode_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, GF_LOG_TRACE, "Lookup failed: %s: %s", + 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); - - inode_link (inode, cs->resolvedloc.parent, cs->resolvedloc.name, buf); - nfs3_fh_resolve_entry_hard (cs); - -err: - return 0; -} - - -int -nfs3_fh_resolve_found_parent (nfs3_call_state_t *cs, gf_dirent_t *candidate) -{ - uint64_t dirino = 0; - uint64_t dirgen = 0; - int ret = 0; - nfs_user_t nfu = {0, }; - - if ((!cs) || (!candidate)) - return -EFAULT; - - dirino = cs->resolvedloc.inode->ino; - - nfs_loc_wipe (&cs->resolvedloc); - ret = nfs_entry_loc_fill (cs->vol->itable, dirino, dirgen, - 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_opendir_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno, fd_t *fd) -{ - nfs3_call_state_t *cs = NULL; - int ret = -EFAULT; - nfs_user_t nfu = {0, }; - - cs = frame->local; - cs->resolve_ret = op_ret; - cs->resolve_errno = op_errno; - - if (op_ret == -1) { - gf_log (GF_NFS3, GF_LOG_TRACE, "Dir open failed: %s: %s", - cs->resolvedloc.path, strerror (op_errno)); - nfs3_call_resume (cs); - goto err; - } else - gf_log (GF_NFS3, GF_LOG_TRACE, "Reading directory: %s", - cs->resolvedloc.path); + memcpy (&cs->stbuf, buf, sizeof(*buf)); + memcpy (&cs->postparent, buf, sizeof(*postparent)); + linked_inode = inode_link (inode, cs->resolvedloc.parent, + cs->resolvedloc.name, buf); + if (linked_inode) { + inode_lookup (linked_inode); + inode_unref (cs->resolvedloc.inode); + cs->resolvedloc.inode = linked_inode; + } - nfs_user_root_create (&nfu); - /* Keep this directory fd_t around till we have either: - * a. found the entry, - * b. exhausted all the entries, - * c. decide to step into a child directory. - * - * This decision is made in nfs3_fh_resolve_check_response. + /* If it is an entry lookup and we landed in the callback for hard + * inode resolution, it means the parent inode was not available and + * had to be resolved first. Now that is done, lets head back into + * entry resolution. */ - cs->resolve_dir_fd = fd; - gf_log (GF_NFS3, GF_LOG_TRACE, "resolve new fd refed: 0x%lx, ref: %d", - (long)cs->resolve_dir_fd, cs->resolve_dir_fd->refcount); - ret = nfs_readdirp (cs->nfsx, cs->vol, &nfu, fd, GF_NFS3_DTPREF, 0, - nfs3_fh_resolve_readdir_cbk, cs); - -err: - return ret; -} - -int32_t -nfs3_fh_resolve_dir_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; - nfs_user_t nfu = {0, }; - - cs = frame->local; - cs->resolve_ret = op_ret; - cs->resolve_errno = op_errno; - - if (op_ret == -1) { - gf_log (GF_NFS3, GF_LOG_TRACE, "Lookup failed: %s: %s", - cs->resolvedloc.path, strerror (op_errno)); - nfs3_call_resume (cs); - goto err; - } else - gf_log (GF_NFS3, GF_LOG_TRACE, "Dir will be opened: %s", - cs->resolvedloc.path); - - nfs_user_root_create (&nfu); - inode_link (inode, cs->resolvedloc.parent, cs->resolvedloc.name, buf); - nfs_opendir (cs->nfsx, cs->vol, &nfu, &cs->resolvedloc, - nfs3_fh_resolve_opendir_cbk, cs); - + if (cs->resolventry) + nfs3_fh_resolve_entry_hard (cs); + else + nfs3_call_resume (cs); err: return 0; } -/* 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; -} - - -int -nfs3_fh_resolve_dir_hard (nfs3_call_state_t *cs, uint64_t ino, uint64_t gen, - char *entry) -{ - int ret = -EFAULT; - nfs_user_t nfu = {0, }; - - if (!cs) - return ret; - - cs->hashidx++; - nfs_loc_wipe (&cs->resolvedloc); - if (!nfs3_fh_resolve_validate_dirdepth (cs)) { - gf_log (GF_NFS3, GF_LOG_TRACE, "Dir depth validation failed"); - nfs3_call_resume_estale (cs); - ret = 0; - goto out; - } - - nfs_user_root_create (&nfu); - gf_log (GF_NFS3, GF_LOG_TRACE, "FH hard dir resolution: ino:" - " %"PRIu64", gen: %"PRIu64", entry: %s, next hashcount: %d", - ino, gen, entry, cs->hashidx); - ret = nfs_entry_loc_fill (cs->vol->itable, ino, gen, entry, - &cs->resolvedloc, NFS_RESOLVE_CREATE); - - if (ret == 0) { - gf_log (GF_NFS3, GF_LOG_TRACE, "Dir will be opened: %s", - cs->resolvedloc.path); - ret = nfs_opendir (cs->nfsx, cs->vol, &nfu, &cs->resolvedloc, - nfs3_fh_resolve_opendir_cbk, cs); - } else if (ret == -ENOENT) { - gf_log (GF_NFS3, GF_LOG_TRACE, "Dir needs lookup: %s", - cs->resolvedloc.path); - ret = nfs_lookup (cs->nfsx, cs->vol, &nfu, &cs->resolvedloc, - nfs3_fh_resolve_dir_lookup_cbk, cs); - } -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_check_response (nfs3_call_state_t *cs, gf_dirent_t *candidate, - int response, off_t last_offt) -{ - uint64_t dirino = 0; - uint64_t dirgen = 0; - int ret = -EFAULT; - nfs_user_t nfu = {0, }; - - if (!cs) - return ret; - - dirino = cs->resolvedloc.inode->ino; - - switch (response) { - - case GF_NFS3_FHRESOLVE_DIRFOUND: - nfs3_fh_resolve_close_cwd (cs); - nfs3_fh_resolve_dir_hard (cs, dirino, dirgen, - candidate->d_name); - break; - - case GF_NFS3_FHRESOLVE_FOUND: - nfs3_fh_resolve_close_cwd (cs); - nfs3_fh_resolve_found (cs, candidate); - break; - - case GF_NFS3_FHRESOLVE_NOTFOUND: - nfs_user_root_create (&nfu); - nfs_readdirp (cs->nfsx, cs->vol, &nfu, cs->resolve_dir_fd, - GF_NFS3_DTPREF, last_offt, - nfs3_fh_resolve_readdir_cbk, cs); - break; - } - - return 0; -} - -int -nfs3_fh_resolve_search_dir (nfs3_call_state_t *cs, gf_dirent_t *entries) -{ - gf_dirent_t *candidate = NULL; - int ret = GF_NFS3_FHRESOLVE_NOTFOUND; - off_t lastoff = 0; - - if ((!cs) || (!entries)) - return -EFAULT; - - if (list_empty (&entries->list)) - goto not_found; - - list_for_each_entry (candidate, &entries->list, list) { - lastoff = candidate->d_off; - gf_log (GF_NFS3, GF_LOG_TRACE, "Candidate: %s, ino: %"PRIu64 - ", gen: %"PRIu64, candidate->d_name, candidate->d_ino, - candidate->d_stat.ia_gen); - ret = nfs3_fh_resolve_check_entry (&cs->resolvefh, candidate, - cs->hashidx); - if (ret != GF_NFS3_FHRESOLVE_NOTFOUND) - break; - } - -not_found: - nfs3_fh_resolve_check_response (cs, candidate, ret, lastoff); - return ret; -} - - -int32_t -nfs3_fh_resolve_readdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno, - gf_dirent_t *entries) -{ - nfs3_call_state_t *cs = NULL; - - cs = frame->local; - if (op_ret <= 0) { - gf_log (GF_NFS3, GF_LOG_TRACE, "Directory read done: %s: %s", - cs->resolvedloc.path, strerror (op_ret)); - cs->resolve_ret = -1; - cs->resolve_errno = ESTALE; - nfs3_call_resume (cs); - goto err; - } - - nfs3_fh_resolve_search_dir (cs, entries); - -err: - return 0; -} /* 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. @@ -2950,33 +3655,21 @@ nfs3_fh_resolve_inode_hard (nfs3_call_state_t *cs) if (!cs) return ret; - cs->hashidx++; + gf_log (GF_NFS3, GF_LOG_TRACE, "FH hard resolution for: gfid 0x%s", + uuid_utoa (cs->resolvefh.gfid)); + cs->hardresolved = 1; nfs_loc_wipe (&cs->resolvedloc); - if (!nfs3_fh_resolve_validate_dirdepth (cs)) { - gf_log (GF_NFS3, GF_LOG_TRACE, "Dir depth validation failed"); - nfs3_call_resume_estale (cs); - ret = 0; + ret = nfs_gfid_loc_fill (cs->vol->itable, cs->resolvefh.gfid, + &cs->resolvedloc, NFS_RESOLVE_CREATE); + if (ret < 0) { + gf_log (GF_NFS3, GF_LOG_ERROR, "Failed to fill loc using gfid: " + "%s", strerror (-ret)); goto out; } nfs_user_root_create (&nfu); - gf_log (GF_NFS3, GF_LOG_TRACE, "FH hard resolution for: ino:" - " %"PRIu64", gen: %"PRIu64", hashcount: %d, current hashidx " - "%d", cs->resolvefh.ino, cs->resolvefh.gen, - cs->resolvefh.hashcount, cs->hashidx); - ret = nfs_ino_loc_fill (cs->vol->itable, 1, 0, &cs->resolvedloc); - - if (ret == 0) { - gf_log (GF_NFS3, GF_LOG_TRACE, "Dir will be opened: %s", - cs->resolvedloc.path); - ret = nfs_opendir (cs->nfsx, cs->vol, &nfu, &cs->resolvedloc, - nfs3_fh_resolve_opendir_cbk, cs); - } else if (ret == -ENOENT) { - gf_log (GF_NFS3, GF_LOG_TRACE, "Dir needs lookup: %s", - cs->resolvedloc.path); - ret = nfs_lookup (cs->nfsx, cs->vol, &nfu, &cs->resolvedloc, - nfs3_fh_resolve_dir_lookup_cbk, cs); - } + ret = nfs_lookup (cs->nfsx, cs->vol, &nfu, &cs->resolvedloc, + nfs3_fh_resolve_inode_lookup_cbk, cs); out: return ret; @@ -2994,20 +3687,33 @@ nfs3_fh_resolve_entry_hard (nfs3_call_state_t *cs) nfs_loc_wipe (&cs->resolvedloc); nfs_user_root_create (&nfu); - gf_log (GF_NFS3, GF_LOG_TRACE, "FH hard resolution: ino:" - " %"PRIu64", gen: %"PRIu64", entry: %s, hashidx: %d", - cs->resolvefh.ino, cs->resolvefh.gen, cs->resolventry, - cs->hashidx); + gf_log (GF_NFS3, GF_LOG_TRACE, "FH hard resolution: gfid: %s " + ", entry: %s", uuid_utoa (cs->resolvefh.gfid), + cs->resolventry); - ret = nfs_entry_loc_fill (cs->vol->itable, cs->resolvefh.ino, - cs->resolvefh.gen, cs->resolventry, - &cs->resolvedloc, NFS_RESOLVE_CREATE); + ret = nfs_entry_loc_fill (cs->vol->itable, cs->resolvefh.gfid, + cs->resolventry, &cs->resolvedloc, + NFS_RESOLVE_CREATE); if (ret == -2) { gf_log (GF_NFS3, GF_LOG_TRACE, "Entry needs lookup: %s", cs->resolvedloc.path); - nfs_lookup (cs->nfsx, cs->vol, &nfu, &cs->resolvedloc, - nfs3_fh_resolve_entry_lookup_cbk, cs); + /* If the NFS op is lookup, let the resume callback + * handle the sending of the lookup fop. Similarly, + * if the NFS op is create, let the create call + * go ahead in the resume callback so that an EEXIST gets + * handled at posix without an extra fop at this point. + */ + if (nfs3_lookup_op (cs) || + (nfs3_create_op (cs) && !nfs3_create_exclusive_op (cs))) { + cs->lookuptype = GF_NFS3_FRESH; + cs->resolve_ret = 0; + nfs3_call_resume (cs); + } else { + cs->hardresolved = 1; + nfs_lookup (cs->nfsx, cs->vol, &nfu, &cs->resolvedloc, + nfs3_fh_resolve_entry_lookup_cbk, cs); + } ret = 0; } else if (ret == -1) { gf_log (GF_NFS3, GF_LOG_TRACE, "Entry needs parent lookup: %s", @@ -3031,8 +3737,8 @@ nfs3_fh_resolve_inode (nfs3_call_state_t *cs) return ret; gf_log (GF_NFS3, GF_LOG_TRACE, "FH needs inode resolution"); - inode = inode_get (cs->vol->itable, cs->resolvefh.ino, - cs->resolvefh.gen); + uuid_copy (cs->resolvedloc.gfid, cs->resolvefh.gfid); + inode = inode_find (cs->vol->itable, cs->resolvefh.gfid); if (!inode) ret = nfs3_fh_resolve_inode_hard (cs); else @@ -3052,13 +3758,97 @@ nfs3_fh_resolve_entry (nfs3_call_state_t *cs) if (!cs) return ret; - ret = nfs3_fh_resolve_entry_hard (cs); - if (ret < 0) - nfs3_call_resume_estale (cs); + return nfs3_fh_resolve_entry_hard (cs); +} + + +int +nfs3_fh_resolve_resume (nfs3_call_state_t *cs) +{ + int ret = -EFAULT; + + if (!cs) + return ret; + + if (cs->resolve_ret < 0) + goto err_resume_call; + if (!cs->resolventry) + ret = nfs3_fh_resolve_inode (cs); + else + ret = nfs3_fh_resolve_entry (cs); + +err_resume_call: + if (ret < 0) { + cs->resolve_ret = -1; + cs->resolve_errno = EFAULT; + nfs3_call_resume (cs); + ret = 0; + } + + return ret; +} + + +int32_t +nfs3_fh_resolve_root_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; + + cs = frame->local; + cs->resolve_ret = op_ret; + cs->resolve_errno = op_errno; + + if (op_ret == -1) { + gf_log (GF_NFS3, GF_LOG_ERROR, "Root lookup failed: %s", + strerror (op_errno)); + goto err; + } else + gf_log (GF_NFS3, GF_LOG_TRACE, "Root looked up: %s", + cs->resolvedloc.path); + + nfs3_set_root_looked_up (cs->nfs3state, &cs->resolvefh); +err: + nfs3_fh_resolve_resume (cs); return 0; } + +int +nfs3_fh_resolve_root (nfs3_call_state_t *cs) +{ + int ret = -EFAULT; + nfs_user_t nfu = {0, }; + + if (!cs) + return ret; + + if (nfs3_is_root_looked_up (cs->nfs3state, &cs->resolvefh)) { + ret = nfs3_fh_resolve_resume (cs); + goto out; + } + + nfs_user_root_create (&nfu); + gf_log (GF_NFS3, GF_LOG_TRACE, "Root needs lookup"); + ret = nfs_root_loc_fill (cs->vol->itable, &cs->resolvedloc); + if (ret < 0) { + gf_log (GF_NFS3, GF_LOG_ERROR, "Failed to lookup root from itable: %s", + strerror (-ret)); + goto out; + } + + ret = nfs_lookup (cs->nfsx, cs->vol, &nfu, &cs->resolvedloc, + nfs3_fh_resolve_root_lookup_cbk, cs); + +out: + return ret; +} + + int nfs3_fh_resolve_and_resume (nfs3_call_state_t *cs, struct nfs3_fh *fh, char *entry, nfs3_resume_fn_t resum_fn) @@ -3079,18 +3869,13 @@ nfs3_fh_resolve_and_resume (nfs3_call_state_t *cs, struct nfs3_fh *fh, * * b. (fh, basename) resolution */ - if (!entry) /* a */ - ret = nfs3_fh_resolve_inode (cs); - else { /* b */ + if (entry) { /* b */ cs->resolventry = gf_strdup (entry); if (!cs->resolventry) goto err; - - ret = nfs3_fh_resolve_entry (cs); } + ret = nfs3_fh_resolve_root (cs); err: return ret; } - - |
