diff options
| -rw-r--r-- | xlators/nfs/server/src/nfs3-helpers.c | 82 | ||||
| -rw-r--r-- | xlators/nfs/server/src/nfs3-helpers.h | 9 | ||||
| -rw-r--r-- | xlators/nfs/server/src/nfs3.c | 44 | 
3 files changed, 96 insertions, 39 deletions
diff --git a/xlators/nfs/server/src/nfs3-helpers.c b/xlators/nfs/server/src/nfs3-helpers.c index feab7b5e8be..95e8601627d 100644 --- a/xlators/nfs/server/src/nfs3-helpers.c +++ b/xlators/nfs/server/src/nfs3-helpers.c @@ -702,11 +702,64 @@ nfs3_prep_readdir3args (readdir3args *ra, struct nfs3_fh *fh)  } +int +nfs3_is_dot_entry (char *entry) +{ +        int     ret = 0; + +        if (!entry) +                return 0; + +        if (strcmp (entry, ".") == 0) +                ret = 1; + +        return ret; +} + + +int +nfs3_is_parentdir_entry (char *entry) +{ +        int     ret = 0; + +        if (!entry) +                return 0; + +        if (strcmp (entry, "..") == 0) +                ret = 1; + +        return ret; +} + + +void +nfs3_funge_root_dotdot_dirent (gf_dirent_t *ent, struct nfs3_fh *dfh) +{ +        if ((!ent) || (!dfh)) +                return; + +        if (nfs3_fh_is_root_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; +        } + +} + +  entry3 * -nfs3_fill_entry3 (gf_dirent_t *entry) +nfs3_fill_entry3 (gf_dirent_t *entry, struct nfs3_fh *dfh)  {          entry3          *ent = NULL; -        if (!entry) +        if ((!entry) || (!dfh))                  return NULL;          ent = GF_CALLOC (1, sizeof (*ent), gf_nfs_mt_entry3); @@ -714,6 +767,14 @@ nfs3_fill_entry3 (gf_dirent_t *entry)                  return NULL;          gf_log (GF_NFS3, GF_LOG_TRACE, "Entry: %s", entry->d_name); + +        /* 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 +         * command: "stat /.." +         */ +        nfs3_funge_root_dotdot_dirent (entry, dfh);          ent->fileid = entry->d_ino;          ent->cookie = entry->d_off;          ent->name = GF_CALLOC ((strlen (entry->d_name) + 1), sizeof (char), @@ -775,6 +836,13 @@ nfs3_fill_entryp3 (gf_dirent_t *entry, struct nfs3_fh *dirfh)          if ((!entry) || (!dirfh))                  return NULL; +        /* 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 +         * command: "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);          ent = GF_CALLOC (1, sizeof (*ent), gf_nfs_mt_entryp3); @@ -802,9 +870,9 @@ err:  void -nfs3_fill_readdir3res (readdir3res *res, nfsstat3 stat, uint64_t cverf, -                       struct iatt *dirstat, gf_dirent_t *entries, count3 count, -                       int is_eof, uint16_t xlid) +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)  {          post_op_attr    dirattr;          entry3          *ent = NULL; @@ -818,7 +886,7 @@ nfs3_fill_readdir3res (readdir3res *res, nfsstat3 stat, uint64_t cverf,          if (stat != NFS3_OK)                  return; -        nfs3_map_xlid_to_statdev (dirstat, xlid); +        nfs3_map_xlid_to_statdev (dirstat, dirfh->xlatorid);          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; @@ -834,7 +902,7 @@ nfs3_fill_readdir3res (readdir3res *res, nfsstat3 stat, uint64_t cverf,                      (strcmp (entries->d_name, "..") == 0))                          goto nextentry;                          */ -                ent = nfs3_fill_entry3 (entries); +                ent = nfs3_fill_entry3 (entries, dirfh);                  if (!ent)                          break; diff --git a/xlators/nfs/server/src/nfs3-helpers.h b/xlators/nfs/server/src/nfs3-helpers.h index 26bc11f6ce2..db76b5cce77 100644 --- a/xlators/nfs/server/src/nfs3-helpers.h +++ b/xlators/nfs/server/src/nfs3-helpers.h @@ -111,9 +111,9 @@ extern void  nfs3_prep_readdir3args (readdir3args *ra, struct nfs3_fh *fh);  extern void -nfs3_fill_readdir3res (readdir3res *res, nfsstat3 stat, uint64_t cverf, -                       struct iatt *dirstat, gf_dirent_t *entries,count3 count, -                       int is_eof, uint16_t xlid); +nfs3_fill_readdir3res (readdir3res *res, nfsstat3 stat, struct nfs3_fh *dfh, +                       uint64_t cverf, struct iatt *dirstat, +                       gf_dirent_t *entries, count3 count, int is_eof);  extern void  nfs3_prep_readdirp3args (readdirp3args *ra, struct nfs3_fh *fh); @@ -339,4 +339,7 @@ nfs3_verify_dircookie (struct nfs3_state *nfs3, fd_t *dirfd, cookie3 cookie,  extern int  nfs3_fdcache_remove (struct nfs3_state *nfs3, fd_t *fd); + +extern int +nfs3_is_parentdir_entry (char *entry);  #endif diff --git a/xlators/nfs/server/src/nfs3.c b/xlators/nfs/server/src/nfs3.c index 385a4a3747b..f09ed95d9da 100644 --- a/xlators/nfs/server/src/nfs3.c +++ b/xlators/nfs/server/src/nfs3.c @@ -993,21 +993,6 @@ nfs3err:  int -nfs3_is_parentdir_entry (char *entry) -{ -        int     ret = 0; - -        if (!entry) -                return 0; - -        if (strcmp (entry, "..") == 0) -                ret = 1; - -        return ret; -} - - -int  nfs3_lookup (rpcsvc_request_t *req, struct nfs3_fh *fh, int fhlen, char *name)  {          xlator_t                        *vol = NULL; @@ -3627,16 +3612,14 @@ nfs3_readdirp_reply (rpcsvc_request_t *req, nfsstat3 stat,struct nfs3_fh *dirfh,  int -nfs3_readdir_reply (rpcsvc_request_t *req, nfsstat3 stat, uint64_t cverf, -                    struct iatt *dirstat, gf_dirent_t *entries, count3 count, -                    int is_eof) +nfs3_readdir_reply (rpcsvc_request_t *req, nfsstat3 stat, struct nfs3_fh *dirfh, +                    uint64_t cverf, struct iatt *dirstat, gf_dirent_t *entries, +                    count3 count, int is_eof)  {          readdir3res     res = {0, }; -        uint16_t        xlid = 0; -        xlid = nfs3_request_xlator_id (req); -        nfs3_fill_readdir3res (&res, stat, cverf, dirstat, entries, count, -                               is_eof, xlid); +        nfs3_fill_readdir3res (&res, stat, dirfh, cverf, dirstat, entries, count +                               , is_eof);          nfs3svc_submit_reply (req, (void *)&res,                                (nfs3_serializer) xdr_serialize_readdir3res);          nfs3_free_readdir3res (&res); @@ -3673,9 +3656,9 @@ nfs3err:                  nfs3_log_readdir_res (rpcsvc_request_xid (cs->req), stat,                                        op_errno, (uintptr_t)cs->fd,                                        cs->dircount, is_eof); -                nfs3_readdir_reply (cs->req, stat, (uintptr_t)cs->fd, -                                    buf, &cs->entries, cs->dircount, -                                    is_eof); +                nfs3_readdir_reply (cs->req, stat, &cs->parent, +                                    (uintptr_t)cs->fd, buf, &cs->entries, +                                    cs->dircount, is_eof);          } else {                  nfs3_log_readdirp_res (rpcsvc_request_xid (cs->req), stat,                                         op_errno, (uintptr_t)cs->fd, @@ -3730,7 +3713,7 @@ err:          if (cs->maxcount == 0) {                  nfs3_log_common_res (rpcsvc_request_xid (cs->req), "READDIR",                                       stat, op_errno); -                nfs3_readdir_reply (cs->req, stat, 0, NULL, NULL, 0, 0); +                nfs3_readdir_reply (cs->req, stat, NULL, 0, NULL, NULL, 0, 0);          } else {                  nfs3_log_common_res (rpcsvc_request_xid (cs->req), "READDIRP"                                       , stat, op_errno); @@ -3791,7 +3774,8 @@ nfs3err:                  if (cs->maxcount == 0) {                          nfs3_log_common_res (rpcsvc_request_xid (cs->req),                                               "READDIR", stat, -ret); -                        nfs3_readdir_reply (cs->req, stat, 0, NULL, NULL, 0, 0); +                        nfs3_readdir_reply (cs->req, stat, NULL, 0, NULL, NULL, +                                            0, 0);                  } else {                          nfs3_log_common_res (rpcsvc_request_xid (cs->req),                                               "READDIRP", stat, -ret); @@ -3826,7 +3810,8 @@ nfs3err:                  if (cs->maxcount == 0) {                          nfs3_log_common_res (rpcsvc_request_xid (cs->req),                                               "READDIR", stat, -ret); -                        nfs3_readdir_reply (cs->req, stat, 0, NULL, NULL, 0, 0); +                        nfs3_readdir_reply (cs->req, stat, NULL, 0, NULL, NULL, +                                            0, 0);                  } else {                          nfs3_log_common_res (rpcsvc_request_xid (cs->req),                                               "READDIRP", stat, -ret); @@ -3877,7 +3862,8 @@ nfs3err:                  if (maxcount == 0) {                          nfs3_log_common_res (rpcsvc_request_xid (req), "READDIR"                                               , stat, -ret); -                        nfs3_readdir_reply (req, stat, 0, NULL, NULL, 0, 0); +                        nfs3_readdir_reply (req, stat, NULL, 0, NULL, NULL, 0, +                                            0);                  } else {                          nfs3_log_common_res (rpcsvc_request_xid (req),"READDIRP"                                               , stat, -ret);  | 
