mirror of
https://github.com/torvalds/linux.git
synced 2024-11-21 19:41:42 +00:00
fs/9p changes for the 6.9 merge window
This pull request includes a number of patches addressing improvements in the cache portions of the 9p client. The biggest improvements have to do with fixing handling of inodes and eliminating duplicate structures and unnecessary allocation/release of inode structures and many associated unnecessary protocol traffic. This also dramatically reduced code complexity across the code and sets us up to add proper temporal cache capabilities. Signed-off-by: Eric Van Hensbergen <ericvh@kernel.org> -----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEElpbw0ZalkJikytFRiP/V+0pf/5gFAmX0XX0ACgkQiP/V+0pf /5jdgg//UCY+RTB9UNr/B1I5sj1m36l0BfFB/jaAMApH5/bQPF2mgtjD1jQL2qk2 gbAvR25erDdKiggRAbNU6OGVBIKXHiUPnL5d6UNgeyQQu1wSzStCejTfoQ/mwgTl 1N2Uge63zz5L0XgJm31gPcKSlJAD1r70UgsPw0ldkimEPqiBQjQu5VQqUWKgrkBe hcdXbuZbmXBLfZv9i0XI9BmwIeaSRwY2qx/JUr2eCoAXrDRNfwBRVMAfqpJ6L6I0 56C5Q2EDjipUnYp1Z3fqg80IUa+MnoF3rbMyMj54JBWxAPyMspamUBltYlZb5pRv zvjSJk3Uof8Wzc+beVVbyV2NmC6gC/cm2MnSYZBTX1KWTMl46eiloSrFz+Pv1/O1 8rcZFQuw8uAox9/4qc1lPCAC0hZVUFelj8NpCPN8aHS3cF0eN/MCQ3qfBkFgo8um jMYTUiai1tjdxWUWrUSpSKFHzBcL986+1bnE7qwI3qPXrxrnB9kOhzSilDJSuHnV Ei6zinvMEUBmKYLdNaCQ9N1KTKPr0bqXIlEvk4LDaGLGkZbI7eKuN5mCxZB0DXCc 65WSc5G9NYux9QjobR+TUwwLdiQH84w/3zYS41r/as7VqABcj/X/2b2ZfQ6/WBuF I0CmSWz2gfcpQQc642dzZJk7UP4wOVtsW3F2JAQ1GPq/D5UOmWU= =1LU1 -----END PGP SIGNATURE----- Merge tag '9p-for-6.9' of git://git.kernel.org/pub/scm/linux/kernel/git/ericvh/v9fs Pull 9p updates from Eric Van Hensbergen: "This includes a number of patches addressing improvements in the cache portions of the 9p client. The biggest improvements have to do with fixing handling of inodes and eliminating duplicate structures and unnecessary allocation/release of inode structures and many associated unnecessary protocol traffic. This also dramatically reduced code complexity across the code and sets us up to add proper temporal cache capabilities" * tag '9p-for-6.9' of git://git.kernel.org/pub/scm/linux/kernel/git/ericvh/v9fs: fs/9p: fix dups even in uncached mode fs/9p: simplify iget to remove unnecessary paths fs/9p: rework qid2ino logic fs/9p: Eliminate now unused v9fs_get_inode fs/9p: Eliminate redundant non-cache path in mknod fs/9p: remove walk and inode allocation from symlink fs/9p: convert mkdir to use get_new_inode fs/9p: switch vfsmount to use v9fs_get_new_inode
This commit is contained in:
commit
c442a42363
31
fs/9p/v9fs.h
31
fs/9p/v9fs.h
@ -179,16 +179,13 @@ extern int v9fs_vfs_rename(struct mnt_idmap *idmap,
|
||||
struct inode *old_dir, struct dentry *old_dentry,
|
||||
struct inode *new_dir, struct dentry *new_dentry,
|
||||
unsigned int flags);
|
||||
extern struct inode *v9fs_inode_from_fid(struct v9fs_session_info *v9ses,
|
||||
struct p9_fid *fid,
|
||||
struct super_block *sb, int new);
|
||||
extern struct inode *v9fs_fid_iget(struct super_block *sb, struct p9_fid *fid);
|
||||
extern const struct inode_operations v9fs_dir_inode_operations_dotl;
|
||||
extern const struct inode_operations v9fs_file_inode_operations_dotl;
|
||||
extern const struct inode_operations v9fs_symlink_inode_operations_dotl;
|
||||
extern const struct netfs_request_ops v9fs_req_ops;
|
||||
extern struct inode *v9fs_inode_from_fid_dotl(struct v9fs_session_info *v9ses,
|
||||
struct p9_fid *fid,
|
||||
struct super_block *sb, int new);
|
||||
extern struct inode *v9fs_fid_iget_dotl(struct super_block *sb,
|
||||
struct p9_fid *fid);
|
||||
|
||||
/* other default globals */
|
||||
#define V9FS_PORT 564
|
||||
@ -230,27 +227,9 @@ v9fs_get_inode_from_fid(struct v9fs_session_info *v9ses, struct p9_fid *fid,
|
||||
struct super_block *sb)
|
||||
{
|
||||
if (v9fs_proto_dotl(v9ses))
|
||||
return v9fs_inode_from_fid_dotl(v9ses, fid, sb, 0);
|
||||
return v9fs_fid_iget_dotl(sb, fid);
|
||||
else
|
||||
return v9fs_inode_from_fid(v9ses, fid, sb, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* v9fs_get_new_inode_from_fid - Helper routine to populate an inode by
|
||||
* issuing a attribute request
|
||||
* @v9ses: session information
|
||||
* @fid: fid to issue attribute request for
|
||||
* @sb: superblock on which to create inode
|
||||
*
|
||||
*/
|
||||
static inline struct inode *
|
||||
v9fs_get_new_inode_from_fid(struct v9fs_session_info *v9ses, struct p9_fid *fid,
|
||||
struct super_block *sb)
|
||||
{
|
||||
if (v9fs_proto_dotl(v9ses))
|
||||
return v9fs_inode_from_fid_dotl(v9ses, fid, sb, 1);
|
||||
else
|
||||
return v9fs_inode_from_fid(v9ses, fid, sb, 1);
|
||||
return v9fs_fid_iget(sb, fid);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -40,13 +40,16 @@ extern struct kmem_cache *v9fs_inode_cache;
|
||||
|
||||
struct inode *v9fs_alloc_inode(struct super_block *sb);
|
||||
void v9fs_free_inode(struct inode *inode);
|
||||
struct inode *v9fs_get_inode(struct super_block *sb, umode_t mode,
|
||||
dev_t rdev);
|
||||
void v9fs_set_netfs_context(struct inode *inode);
|
||||
int v9fs_init_inode(struct v9fs_session_info *v9ses,
|
||||
struct inode *inode, umode_t mode, dev_t rdev);
|
||||
struct inode *inode, struct p9_qid *qid, umode_t mode, dev_t rdev);
|
||||
void v9fs_evict_inode(struct inode *inode);
|
||||
ino_t v9fs_qid2ino(struct p9_qid *qid);
|
||||
#if (BITS_PER_LONG == 32)
|
||||
#define QID2INO(q) ((ino_t) (((q)->path+2) ^ (((q)->path) >> 32)))
|
||||
#else
|
||||
#define QID2INO(q) ((ino_t) ((q)->path+2))
|
||||
#endif
|
||||
|
||||
void v9fs_stat2inode(struct p9_wstat *stat, struct inode *inode,
|
||||
struct super_block *sb, unsigned int flags);
|
||||
void v9fs_stat2inode_dotl(struct p9_stat_dotl *stat, struct inode *inode,
|
||||
|
@ -127,7 +127,7 @@ static int v9fs_dir_readdir(struct file *file, struct dir_context *ctx)
|
||||
}
|
||||
|
||||
over = !dir_emit(ctx, st.name, strlen(st.name),
|
||||
v9fs_qid2ino(&st.qid), dt_type(&st));
|
||||
QID2INO(&st.qid), dt_type(&st));
|
||||
p9stat_free(&st);
|
||||
if (over)
|
||||
return 0;
|
||||
@ -184,7 +184,7 @@ static int v9fs_dir_readdir_dotl(struct file *file, struct dir_context *ctx)
|
||||
|
||||
if (!dir_emit(ctx, curdirent.d_name,
|
||||
strlen(curdirent.d_name),
|
||||
v9fs_qid2ino(&curdirent.qid),
|
||||
QID2INO(&curdirent.qid),
|
||||
curdirent.d_type))
|
||||
return 0;
|
||||
|
||||
|
@ -253,9 +253,12 @@ void v9fs_set_netfs_context(struct inode *inode)
|
||||
}
|
||||
|
||||
int v9fs_init_inode(struct v9fs_session_info *v9ses,
|
||||
struct inode *inode, umode_t mode, dev_t rdev)
|
||||
struct inode *inode, struct p9_qid *qid, umode_t mode, dev_t rdev)
|
||||
{
|
||||
int err = 0;
|
||||
struct v9fs_inode *v9inode = V9FS_I(inode);
|
||||
|
||||
memcpy(&v9inode->qid, qid, sizeof(struct p9_qid));
|
||||
|
||||
inode_init_owner(&nop_mnt_idmap, inode, NULL, mode);
|
||||
inode->i_blocks = 0;
|
||||
@ -331,36 +334,6 @@ error:
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* v9fs_get_inode - helper function to setup an inode
|
||||
* @sb: superblock
|
||||
* @mode: mode to setup inode with
|
||||
* @rdev: The device numbers to set
|
||||
*/
|
||||
|
||||
struct inode *v9fs_get_inode(struct super_block *sb, umode_t mode, dev_t rdev)
|
||||
{
|
||||
int err;
|
||||
struct inode *inode;
|
||||
struct v9fs_session_info *v9ses = sb->s_fs_info;
|
||||
|
||||
p9_debug(P9_DEBUG_VFS, "super block: %p mode: %ho\n", sb, mode);
|
||||
|
||||
inode = new_inode(sb);
|
||||
if (!inode) {
|
||||
pr_warn("%s (%d): Problem allocating inode\n",
|
||||
__func__, task_pid_nr(current));
|
||||
return ERR_PTR(-ENOMEM);
|
||||
}
|
||||
err = v9fs_init_inode(v9ses, inode, mode, rdev);
|
||||
if (err) {
|
||||
iput(inode);
|
||||
return ERR_PTR(err);
|
||||
}
|
||||
v9fs_set_netfs_context(inode);
|
||||
return inode;
|
||||
}
|
||||
|
||||
/**
|
||||
* v9fs_evict_inode - Remove an inode from the inode cache
|
||||
* @inode: inode to release
|
||||
@ -384,82 +357,40 @@ void v9fs_evict_inode(struct inode *inode)
|
||||
#endif
|
||||
}
|
||||
|
||||
static int v9fs_test_inode(struct inode *inode, void *data)
|
||||
{
|
||||
int umode;
|
||||
dev_t rdev;
|
||||
struct v9fs_inode *v9inode = V9FS_I(inode);
|
||||
struct p9_wstat *st = (struct p9_wstat *)data;
|
||||
struct v9fs_session_info *v9ses = v9fs_inode2v9ses(inode);
|
||||
|
||||
umode = p9mode2unixmode(v9ses, st, &rdev);
|
||||
/* don't match inode of different type */
|
||||
if (inode_wrong_type(inode, umode))
|
||||
return 0;
|
||||
|
||||
/* compare qid details */
|
||||
if (memcmp(&v9inode->qid.version,
|
||||
&st->qid.version, sizeof(v9inode->qid.version)))
|
||||
return 0;
|
||||
|
||||
if (v9inode->qid.type != st->qid.type)
|
||||
return 0;
|
||||
|
||||
if (v9inode->qid.path != st->qid.path)
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int v9fs_test_new_inode(struct inode *inode, void *data)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int v9fs_set_inode(struct inode *inode, void *data)
|
||||
{
|
||||
struct v9fs_inode *v9inode = V9FS_I(inode);
|
||||
struct p9_wstat *st = (struct p9_wstat *)data;
|
||||
|
||||
memcpy(&v9inode->qid, &st->qid, sizeof(st->qid));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct inode *v9fs_qid_iget(struct super_block *sb,
|
||||
struct p9_qid *qid,
|
||||
struct p9_wstat *st,
|
||||
int new)
|
||||
struct inode *v9fs_fid_iget(struct super_block *sb, struct p9_fid *fid)
|
||||
{
|
||||
dev_t rdev;
|
||||
int retval;
|
||||
umode_t umode;
|
||||
unsigned long i_ino;
|
||||
struct inode *inode;
|
||||
struct p9_wstat *st;
|
||||
struct v9fs_session_info *v9ses = sb->s_fs_info;
|
||||
int (*test)(struct inode *inode, void *data);
|
||||
|
||||
if (new)
|
||||
test = v9fs_test_new_inode;
|
||||
else
|
||||
test = v9fs_test_inode;
|
||||
|
||||
i_ino = v9fs_qid2ino(qid);
|
||||
inode = iget5_locked(sb, i_ino, test, v9fs_set_inode, st);
|
||||
if (!inode)
|
||||
inode = iget_locked(sb, QID2INO(&fid->qid));
|
||||
if (unlikely(!inode))
|
||||
return ERR_PTR(-ENOMEM);
|
||||
if (!(inode->i_state & I_NEW))
|
||||
return inode;
|
||||
|
||||
/*
|
||||
* initialize the inode with the stat info
|
||||
* FIXME!! we may need support for stale inodes
|
||||
* later.
|
||||
*/
|
||||
inode->i_ino = i_ino;
|
||||
st = p9_client_stat(fid);
|
||||
if (IS_ERR(st)) {
|
||||
retval = PTR_ERR(st);
|
||||
goto error;
|
||||
}
|
||||
|
||||
umode = p9mode2unixmode(v9ses, st, &rdev);
|
||||
retval = v9fs_init_inode(v9ses, inode, umode, rdev);
|
||||
retval = v9fs_init_inode(v9ses, inode, &fid->qid, umode, rdev);
|
||||
v9fs_stat2inode(st, inode, sb, 0);
|
||||
p9stat_free(st);
|
||||
kfree(st);
|
||||
if (retval)
|
||||
goto error;
|
||||
|
||||
v9fs_stat2inode(st, inode, sb, 0);
|
||||
v9fs_set_netfs_context(inode);
|
||||
v9fs_cache_inode_get_cookie(inode);
|
||||
unlock_new_inode(inode);
|
||||
@ -470,23 +401,6 @@ error:
|
||||
|
||||
}
|
||||
|
||||
struct inode *
|
||||
v9fs_inode_from_fid(struct v9fs_session_info *v9ses, struct p9_fid *fid,
|
||||
struct super_block *sb, int new)
|
||||
{
|
||||
struct p9_wstat *st;
|
||||
struct inode *inode = NULL;
|
||||
|
||||
st = p9_client_stat(fid);
|
||||
if (IS_ERR(st))
|
||||
return ERR_CAST(st);
|
||||
|
||||
inode = v9fs_qid_iget(sb, &st->qid, st, new);
|
||||
p9stat_free(st);
|
||||
kfree(st);
|
||||
return inode;
|
||||
}
|
||||
|
||||
/**
|
||||
* v9fs_at_to_dotl_flags- convert Linux specific AT flags to
|
||||
* plan 9 AT flag.
|
||||
@ -633,7 +547,7 @@ v9fs_create(struct v9fs_session_info *v9ses, struct inode *dir,
|
||||
/*
|
||||
* instantiate inode and assign the unopened fid to the dentry
|
||||
*/
|
||||
inode = v9fs_get_new_inode_from_fid(v9ses, fid, dir->i_sb);
|
||||
inode = v9fs_get_inode_from_fid(v9ses, fid, dir->i_sb);
|
||||
if (IS_ERR(inode)) {
|
||||
err = PTR_ERR(inode);
|
||||
p9_debug(P9_DEBUG_VFS,
|
||||
@ -761,10 +675,8 @@ struct dentry *v9fs_vfs_lookup(struct inode *dir, struct dentry *dentry,
|
||||
inode = NULL;
|
||||
else if (IS_ERR(fid))
|
||||
inode = ERR_CAST(fid);
|
||||
else if (v9ses->cache & (CACHE_META|CACHE_LOOSE))
|
||||
inode = v9fs_get_inode_from_fid(v9ses, fid, dir->i_sb);
|
||||
else
|
||||
inode = v9fs_get_new_inode_from_fid(v9ses, fid, dir->i_sb);
|
||||
inode = v9fs_get_inode_from_fid(v9ses, fid, dir->i_sb);
|
||||
/*
|
||||
* If we had a rename on the server and a parallel lookup
|
||||
* for the new name, then make sure we instantiate with
|
||||
@ -1186,26 +1098,6 @@ v9fs_stat2inode(struct p9_wstat *stat, struct inode *inode,
|
||||
v9inode->cache_validity &= ~V9FS_INO_INVALID_ATTR;
|
||||
}
|
||||
|
||||
/**
|
||||
* v9fs_qid2ino - convert qid into inode number
|
||||
* @qid: qid to hash
|
||||
*
|
||||
* BUG: potential for inode number collisions?
|
||||
*/
|
||||
|
||||
ino_t v9fs_qid2ino(struct p9_qid *qid)
|
||||
{
|
||||
u64 path = qid->path + 2;
|
||||
ino_t i = 0;
|
||||
|
||||
if (sizeof(ino_t) == sizeof(path))
|
||||
memcpy(&i, &path, sizeof(ino_t));
|
||||
else
|
||||
i = (ino_t) (path ^ (path >> 32));
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
/**
|
||||
* v9fs_vfs_get_link - follow a symlink path
|
||||
* @dentry: dentry for symlink
|
||||
|
@ -52,78 +52,33 @@ static kgid_t v9fs_get_fsgid_for_create(struct inode *dir_inode)
|
||||
return current_fsgid();
|
||||
}
|
||||
|
||||
static int v9fs_test_inode_dotl(struct inode *inode, void *data)
|
||||
{
|
||||
struct v9fs_inode *v9inode = V9FS_I(inode);
|
||||
struct p9_stat_dotl *st = (struct p9_stat_dotl *)data;
|
||||
|
||||
/* don't match inode of different type */
|
||||
if (inode_wrong_type(inode, st->st_mode))
|
||||
return 0;
|
||||
|
||||
if (inode->i_generation != st->st_gen)
|
||||
return 0;
|
||||
|
||||
/* compare qid details */
|
||||
if (memcmp(&v9inode->qid.version,
|
||||
&st->qid.version, sizeof(v9inode->qid.version)))
|
||||
return 0;
|
||||
|
||||
if (v9inode->qid.type != st->qid.type)
|
||||
return 0;
|
||||
|
||||
if (v9inode->qid.path != st->qid.path)
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Always get a new inode */
|
||||
static int v9fs_test_new_inode_dotl(struct inode *inode, void *data)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int v9fs_set_inode_dotl(struct inode *inode, void *data)
|
||||
{
|
||||
struct v9fs_inode *v9inode = V9FS_I(inode);
|
||||
struct p9_stat_dotl *st = (struct p9_stat_dotl *)data;
|
||||
|
||||
memcpy(&v9inode->qid, &st->qid, sizeof(st->qid));
|
||||
inode->i_generation = st->st_gen;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct inode *v9fs_qid_iget_dotl(struct super_block *sb,
|
||||
struct p9_qid *qid,
|
||||
struct p9_fid *fid,
|
||||
struct p9_stat_dotl *st,
|
||||
int new)
|
||||
struct inode *v9fs_fid_iget_dotl(struct super_block *sb, struct p9_fid *fid)
|
||||
{
|
||||
int retval;
|
||||
unsigned long i_ino;
|
||||
struct inode *inode;
|
||||
struct p9_stat_dotl *st;
|
||||
struct v9fs_session_info *v9ses = sb->s_fs_info;
|
||||
int (*test)(struct inode *inode, void *data);
|
||||
|
||||
if (new)
|
||||
test = v9fs_test_new_inode_dotl;
|
||||
else
|
||||
test = v9fs_test_inode_dotl;
|
||||
|
||||
i_ino = v9fs_qid2ino(qid);
|
||||
inode = iget5_locked(sb, i_ino, test, v9fs_set_inode_dotl, st);
|
||||
if (!inode)
|
||||
inode = iget_locked(sb, QID2INO(&fid->qid));
|
||||
if (unlikely(!inode))
|
||||
return ERR_PTR(-ENOMEM);
|
||||
if (!(inode->i_state & I_NEW))
|
||||
return inode;
|
||||
|
||||
/*
|
||||
* initialize the inode with the stat info
|
||||
* FIXME!! we may need support for stale inodes
|
||||
* later.
|
||||
*/
|
||||
inode->i_ino = i_ino;
|
||||
retval = v9fs_init_inode(v9ses, inode,
|
||||
st = p9_client_getattr_dotl(fid, P9_STATS_BASIC | P9_STATS_GEN);
|
||||
if (IS_ERR(st)) {
|
||||
retval = PTR_ERR(st);
|
||||
goto error;
|
||||
}
|
||||
|
||||
retval = v9fs_init_inode(v9ses, inode, &fid->qid,
|
||||
st->st_mode, new_decode_dev(st->st_rdev));
|
||||
kfree(st);
|
||||
if (retval)
|
||||
goto error;
|
||||
|
||||
@ -135,6 +90,7 @@ static struct inode *v9fs_qid_iget_dotl(struct super_block *sb,
|
||||
goto error;
|
||||
|
||||
unlock_new_inode(inode);
|
||||
|
||||
return inode;
|
||||
error:
|
||||
iget_failed(inode);
|
||||
@ -142,22 +98,6 @@ error:
|
||||
|
||||
}
|
||||
|
||||
struct inode *
|
||||
v9fs_inode_from_fid_dotl(struct v9fs_session_info *v9ses, struct p9_fid *fid,
|
||||
struct super_block *sb, int new)
|
||||
{
|
||||
struct p9_stat_dotl *st;
|
||||
struct inode *inode = NULL;
|
||||
|
||||
st = p9_client_getattr_dotl(fid, P9_STATS_BASIC | P9_STATS_GEN);
|
||||
if (IS_ERR(st))
|
||||
return ERR_CAST(st);
|
||||
|
||||
inode = v9fs_qid_iget_dotl(sb, &st->qid, fid, st, new);
|
||||
kfree(st);
|
||||
return inode;
|
||||
}
|
||||
|
||||
struct dotl_openflag_map {
|
||||
int open_flag;
|
||||
int dotl_flag;
|
||||
@ -307,7 +247,7 @@ v9fs_vfs_atomic_open_dotl(struct inode *dir, struct dentry *dentry,
|
||||
p9_debug(P9_DEBUG_VFS, "p9_client_walk failed %d\n", err);
|
||||
goto out;
|
||||
}
|
||||
inode = v9fs_get_new_inode_from_fid(v9ses, fid, dir->i_sb);
|
||||
inode = v9fs_fid_iget_dotl(dir->i_sb, fid);
|
||||
if (IS_ERR(inode)) {
|
||||
err = PTR_ERR(inode);
|
||||
p9_debug(P9_DEBUG_VFS, "inode creation failed %d\n", err);
|
||||
@ -402,32 +342,17 @@ static int v9fs_vfs_mkdir_dotl(struct mnt_idmap *idmap,
|
||||
}
|
||||
|
||||
/* instantiate inode and assign the unopened fid to the dentry */
|
||||
if (v9ses->cache & (CACHE_META|CACHE_LOOSE)) {
|
||||
inode = v9fs_get_new_inode_from_fid(v9ses, fid, dir->i_sb);
|
||||
if (IS_ERR(inode)) {
|
||||
err = PTR_ERR(inode);
|
||||
p9_debug(P9_DEBUG_VFS, "inode creation failed %d\n",
|
||||
err);
|
||||
goto error;
|
||||
}
|
||||
v9fs_fid_add(dentry, &fid);
|
||||
v9fs_set_create_acl(inode, fid, dacl, pacl);
|
||||
d_instantiate(dentry, inode);
|
||||
err = 0;
|
||||
} else {
|
||||
/*
|
||||
* Not in cached mode. No need to populate
|
||||
* inode with stat. We need to get an inode
|
||||
* so that we can set the acl with dentry
|
||||
*/
|
||||
inode = v9fs_get_inode(dir->i_sb, mode, 0);
|
||||
if (IS_ERR(inode)) {
|
||||
err = PTR_ERR(inode);
|
||||
goto error;
|
||||
}
|
||||
v9fs_set_create_acl(inode, fid, dacl, pacl);
|
||||
d_instantiate(dentry, inode);
|
||||
inode = v9fs_fid_iget_dotl(dir->i_sb, fid);
|
||||
if (IS_ERR(inode)) {
|
||||
err = PTR_ERR(inode);
|
||||
p9_debug(P9_DEBUG_VFS, "inode creation failed %d\n",
|
||||
err);
|
||||
goto error;
|
||||
}
|
||||
v9fs_fid_add(dentry, &fid);
|
||||
v9fs_set_create_acl(inode, fid, dacl, pacl);
|
||||
d_instantiate(dentry, inode);
|
||||
err = 0;
|
||||
inc_nlink(dir);
|
||||
v9fs_invalidate_inode_attr(dir);
|
||||
error:
|
||||
@ -709,14 +634,11 @@ v9fs_vfs_symlink_dotl(struct mnt_idmap *idmap, struct inode *dir,
|
||||
kgid_t gid;
|
||||
const unsigned char *name;
|
||||
struct p9_qid qid;
|
||||
struct inode *inode;
|
||||
struct p9_fid *dfid;
|
||||
struct p9_fid *fid = NULL;
|
||||
struct v9fs_session_info *v9ses;
|
||||
|
||||
name = dentry->d_name.name;
|
||||
p9_debug(P9_DEBUG_VFS, "%lu,%s,%s\n", dir->i_ino, name, symname);
|
||||
v9ses = v9fs_inode2v9ses(dir);
|
||||
|
||||
dfid = v9fs_parent_fid(dentry);
|
||||
if (IS_ERR(dfid)) {
|
||||
@ -736,36 +658,6 @@ v9fs_vfs_symlink_dotl(struct mnt_idmap *idmap, struct inode *dir,
|
||||
}
|
||||
|
||||
v9fs_invalidate_inode_attr(dir);
|
||||
if (v9ses->cache & (CACHE_META|CACHE_LOOSE)) {
|
||||
/* Now walk from the parent so we can get an unopened fid. */
|
||||
fid = p9_client_walk(dfid, 1, &name, 1);
|
||||
if (IS_ERR(fid)) {
|
||||
err = PTR_ERR(fid);
|
||||
p9_debug(P9_DEBUG_VFS, "p9_client_walk failed %d\n",
|
||||
err);
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* instantiate inode and assign the unopened fid to dentry */
|
||||
inode = v9fs_get_new_inode_from_fid(v9ses, fid, dir->i_sb);
|
||||
if (IS_ERR(inode)) {
|
||||
err = PTR_ERR(inode);
|
||||
p9_debug(P9_DEBUG_VFS, "inode creation failed %d\n",
|
||||
err);
|
||||
goto error;
|
||||
}
|
||||
v9fs_fid_add(dentry, &fid);
|
||||
d_instantiate(dentry, inode);
|
||||
err = 0;
|
||||
} else {
|
||||
/* Not in cached mode. No need to populate inode with stat */
|
||||
inode = v9fs_get_inode(dir->i_sb, S_IFLNK, 0);
|
||||
if (IS_ERR(inode)) {
|
||||
err = PTR_ERR(inode);
|
||||
goto error;
|
||||
}
|
||||
d_instantiate(dentry, inode);
|
||||
}
|
||||
|
||||
error:
|
||||
p9_fid_put(fid);
|
||||
@ -888,33 +780,17 @@ v9fs_vfs_mknod_dotl(struct mnt_idmap *idmap, struct inode *dir,
|
||||
err);
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* instantiate inode and assign the unopened fid to the dentry */
|
||||
if (v9ses->cache & (CACHE_META|CACHE_LOOSE)) {
|
||||
inode = v9fs_get_new_inode_from_fid(v9ses, fid, dir->i_sb);
|
||||
if (IS_ERR(inode)) {
|
||||
err = PTR_ERR(inode);
|
||||
p9_debug(P9_DEBUG_VFS, "inode creation failed %d\n",
|
||||
err);
|
||||
goto error;
|
||||
}
|
||||
v9fs_set_create_acl(inode, fid, dacl, pacl);
|
||||
v9fs_fid_add(dentry, &fid);
|
||||
d_instantiate(dentry, inode);
|
||||
err = 0;
|
||||
} else {
|
||||
/*
|
||||
* Not in cached mode. No need to populate inode with stat.
|
||||
* socket syscall returns a fd, so we need instantiate
|
||||
*/
|
||||
inode = v9fs_get_inode(dir->i_sb, mode, rdev);
|
||||
if (IS_ERR(inode)) {
|
||||
err = PTR_ERR(inode);
|
||||
goto error;
|
||||
}
|
||||
v9fs_set_create_acl(inode, fid, dacl, pacl);
|
||||
d_instantiate(dentry, inode);
|
||||
inode = v9fs_fid_iget_dotl(dir->i_sb, fid);
|
||||
if (IS_ERR(inode)) {
|
||||
err = PTR_ERR(inode);
|
||||
p9_debug(P9_DEBUG_VFS, "inode creation failed %d\n",
|
||||
err);
|
||||
goto error;
|
||||
}
|
||||
v9fs_set_create_acl(inode, fid, dacl, pacl);
|
||||
v9fs_fid_add(dentry, &fid);
|
||||
d_instantiate(dentry, inode);
|
||||
err = 0;
|
||||
error:
|
||||
p9_fid_put(fid);
|
||||
v9fs_put_acl(dacl, pacl);
|
||||
|
@ -110,7 +110,6 @@ static struct dentry *v9fs_mount(struct file_system_type *fs_type, int flags,
|
||||
struct inode *inode = NULL;
|
||||
struct dentry *root = NULL;
|
||||
struct v9fs_session_info *v9ses = NULL;
|
||||
umode_t mode = 0777 | S_ISVTX;
|
||||
struct p9_fid *fid;
|
||||
int retval = 0;
|
||||
|
||||
@ -140,7 +139,7 @@ static struct dentry *v9fs_mount(struct file_system_type *fs_type, int flags,
|
||||
else
|
||||
sb->s_d_op = &v9fs_dentry_operations;
|
||||
|
||||
inode = v9fs_get_inode(sb, S_IFDIR | mode, 0);
|
||||
inode = v9fs_get_inode_from_fid(v9ses, fid, sb);
|
||||
if (IS_ERR(inode)) {
|
||||
retval = PTR_ERR(inode);
|
||||
goto release_sb;
|
||||
@ -152,32 +151,6 @@ static struct dentry *v9fs_mount(struct file_system_type *fs_type, int flags,
|
||||
goto release_sb;
|
||||
}
|
||||
sb->s_root = root;
|
||||
if (v9fs_proto_dotl(v9ses)) {
|
||||
struct p9_stat_dotl *st = NULL;
|
||||
|
||||
st = p9_client_getattr_dotl(fid, P9_STATS_BASIC);
|
||||
if (IS_ERR(st)) {
|
||||
retval = PTR_ERR(st);
|
||||
goto release_sb;
|
||||
}
|
||||
d_inode(root)->i_ino = v9fs_qid2ino(&st->qid);
|
||||
v9fs_stat2inode_dotl(st, d_inode(root), 0);
|
||||
kfree(st);
|
||||
} else {
|
||||
struct p9_wstat *st = NULL;
|
||||
|
||||
st = p9_client_stat(fid);
|
||||
if (IS_ERR(st)) {
|
||||
retval = PTR_ERR(st);
|
||||
goto release_sb;
|
||||
}
|
||||
|
||||
d_inode(root)->i_ino = v9fs_qid2ino(&st->qid);
|
||||
v9fs_stat2inode(st, d_inode(root), sb, 0);
|
||||
|
||||
p9stat_free(st);
|
||||
kfree(st);
|
||||
}
|
||||
retval = v9fs_get_acl(inode, fid);
|
||||
if (retval)
|
||||
goto release_sb;
|
||||
@ -271,21 +244,6 @@ done:
|
||||
return res;
|
||||
}
|
||||
|
||||
static int v9fs_drop_inode(struct inode *inode)
|
||||
{
|
||||
struct v9fs_session_info *v9ses;
|
||||
|
||||
v9ses = v9fs_inode2v9ses(inode);
|
||||
if (v9ses->cache & (CACHE_META|CACHE_LOOSE))
|
||||
return generic_drop_inode(inode);
|
||||
/*
|
||||
* in case of non cached mode always drop the
|
||||
* inode because we want the inode attribute
|
||||
* to always match that on the server.
|
||||
*/
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int v9fs_write_inode(struct inode *inode,
|
||||
struct writeback_control *wbc)
|
||||
{
|
||||
@ -320,7 +278,6 @@ static const struct super_operations v9fs_super_ops_dotl = {
|
||||
.alloc_inode = v9fs_alloc_inode,
|
||||
.free_inode = v9fs_free_inode,
|
||||
.statfs = v9fs_statfs,
|
||||
.drop_inode = v9fs_drop_inode,
|
||||
.evict_inode = v9fs_evict_inode,
|
||||
.show_options = v9fs_show_options,
|
||||
.umount_begin = v9fs_umount_begin,
|
||||
|
Loading…
Reference in New Issue
Block a user