Skip to content

Commit d4758df

Browse files
author
Charles L. Hedrick
committed
add get_name implementation for exports
Signed-off-by: Charles Hedrick <[email protected]>
1 parent baa5031 commit d4758df

File tree

3 files changed

+75
-0
lines changed

3 files changed

+75
-0
lines changed

include/os/linux/zfs/sys/zfs_vnops_os.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ extern int zfs_write_simple(znode_t *zp, const void *data, size_t len,
4444
loff_t pos, size_t *resid);
4545
extern int zfs_lookup(znode_t *dzp, char *nm, znode_t **zpp, int flags,
4646
cred_t *cr, int *direntflags, pathname_t *realpnp);
47+
extern int zfs_get_name(znode_t *dzp, char *name, znode_t *zp);
4748
extern int zfs_create(znode_t *dzp, char *name, vattr_t *vap, int excl,
4849
int mode, znode_t **zpp, cred_t *cr, int flag, vsecattr_t *vsecp,
4950
zidmap_t *mnt_ns);

module/os/linux/zfs/zfs_vnops_os.c

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -526,6 +526,48 @@ zfs_lookup(znode_t *zdp, char *nm, znode_t **zpp, int flags, cred_t *cr,
526526
return (error);
527527
}
528528

529+
/*
530+
* Perform a linear search in directory for the name of specific inode.
531+
* Note we don't pass in the buffer size of name because it's hardcoded to
532+
* NAME_MAX+1(256) in Linux.
533+
*
534+
* IN: dzp - znode of directory to search.
535+
* zp - znode of the target
536+
*
537+
* OUT: name - dentry name of the target
538+
*
539+
* RETURN: 0 on success, error code on failure.
540+
*/
541+
int
542+
zfs_get_name(znode_t *dzp, char *name, znode_t *zp)
543+
{
544+
zfsvfs_t *zfsvfs = ZTOZSB(dzp);
545+
int error = 0;
546+
547+
if ((error = zfs_enter_verify_zp(zfsvfs, dzp, FTAG)) != 0)
548+
return (error);
549+
550+
if ((error = zfs_verify_zp(zp)) != 0) {
551+
zfs_exit(zfsvfs, FTAG);
552+
return (error);
553+
}
554+
555+
/* ctldir should have got their name in zfs_vget */
556+
if (dzp->z_is_ctldir || zp->z_is_ctldir) {
557+
zfs_exit(zfsvfs, FTAG);
558+
return (ENOENT);
559+
}
560+
561+
/* buffer len is hardcoded to 256 in Linux kernel */
562+
error = zap_value_search(zfsvfs->z_os, dzp->z_id, zp->z_id,
563+
ZFS_DIRENT_OBJ(-1ULL), name);
564+
565+
zfs_exit(zfsvfs, FTAG);
566+
return (error);
567+
}
568+
569+
570+
529571
/*
530572
* Attempt to create a new entry in a directory. If the entry
531573
* already exists, truncate the file if permissible, else return

module/os/linux/zfs/zpl_export.c

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
*/
2525

2626

27+
#include <sys/file.h>
2728
#include <sys/zfs_znode.h>
2829
#include <sys/zfs_vnops.h>
2930
#include <sys/zfs_ctldir.h>
@@ -109,6 +110,36 @@ zpl_fh_to_dentry(struct super_block *sb, struct fid *fh,
109110
return (d_obtain_alias(ip));
110111
}
111112

113+
/*
114+
* In case the filesystem contains name longer than 255, we need to override
115+
* the default get_name so we don't get buffer overflow. Unfortunately, since
116+
* the buffer size is hardcoded in Linux, we will get ESTALE error in this
117+
* case.
118+
*/
119+
static int
120+
zpl_get_name(struct dentry *parent, char *name, struct dentry *child)
121+
{
122+
cred_t *cr = CRED();
123+
fstrans_cookie_t cookie;
124+
struct inode *dir = parent->d_inode;
125+
struct inode *ip = child->d_inode;
126+
int error;
127+
128+
if (!dir || !S_ISDIR(dir->i_mode))
129+
return (-ENOTDIR);
130+
131+
crhold(cr);
132+
cookie = spl_fstrans_mark();
133+
spl_inode_lock_shared(dir);
134+
error = -zfs_get_name(ITOZ(dir), name, ITOZ(ip));
135+
spl_inode_unlock_shared(dir);
136+
spl_fstrans_unmark(cookie);
137+
crfree(cr);
138+
139+
return (error);
140+
}
141+
142+
112143
static struct dentry *
113144
zpl_get_parent(struct dentry *child)
114145
{
@@ -153,6 +184,7 @@ zpl_commit_metadata(struct inode *inode)
153184
const struct export_operations zpl_export_operations = {
154185
.encode_fh = zpl_encode_fh,
155186
.fh_to_dentry = zpl_fh_to_dentry,
187+
.get_name = zpl_get_name,
156188
.get_parent = zpl_get_parent,
157189
.commit_metadata = zpl_commit_metadata,
158190
};

0 commit comments

Comments
 (0)