mirror of
https://github.com/torvalds/linux.git
synced 2026-05-26 16:12:59 +02:00
Merge patch series "Change inode_operations.mkdir to return struct dentry *"
NeilBrown <neilb@suse.de> says: This revised series contains a few clean-ups as requested by various people but no substantial changes. I reviewed the mkdir functions in many (all?) filesystems and found a few that use d_instantiate() on an unlocked inode (after unlock_new_inode()) and also support export_operations. These could potentially call d_instantiate() on a directory inode which is already attached to a dentry, though making that happen would usually require guessing the filehandle correctly. I haven't tried to address those here, (this patch set doesn't make that situation any worse) but I may in the future. * patches from https://lore.kernel.org/r/20250227013949.536172-2-neilb@suse.de: VFS: Change vfs_mkdir() to return the dentry. nfs: change mkdir inode_operation to return alternate dentry if needed. fuse: return correct dentry for ->mkdir ceph: return the correct dentry on mkdir hostfs: store inode in dentry after mkdir if possible. Change inode_operations.mkdir to return struct dentry * Link: https://lore.kernel.org/r/20250227013949.536172-2-neilb@suse.de Signed-off-by: Christian Brauner <brauner@kernel.org>
This commit is contained in:
commit
21432f9b5e
|
|
@ -66,7 +66,7 @@ prototypes::
|
|||
int (*link) (struct dentry *,struct inode *,struct dentry *);
|
||||
int (*unlink) (struct inode *,struct dentry *);
|
||||
int (*symlink) (struct mnt_idmap *, struct inode *,struct dentry *,const char *);
|
||||
int (*mkdir) (struct mnt_idmap *, struct inode *,struct dentry *,umode_t);
|
||||
struct dentry *(*mkdir) (struct mnt_idmap *, struct inode *,struct dentry *,umode_t);
|
||||
int (*rmdir) (struct inode *,struct dentry *);
|
||||
int (*mknod) (struct mnt_idmap *, struct inode *,struct dentry *,umode_t,dev_t);
|
||||
int (*rename) (struct mnt_idmap *, struct inode *, struct dentry *,
|
||||
|
|
|
|||
|
|
@ -1178,3 +1178,22 @@ these conditions don't require explicit checks:
|
|||
|
||||
LOOKUP_EXCL now means "target must not exist". It can be combined with
|
||||
LOOK_CREATE or LOOKUP_RENAME_TARGET.
|
||||
|
||||
---
|
||||
|
||||
** mandatory**
|
||||
|
||||
->mkdir() now returns a 'struct dentry *'. If the created inode is
|
||||
found to already be in cache and have a dentry (often IS_ROOT()), it will
|
||||
need to be spliced into the given name in place of the given dentry.
|
||||
That dentry now needs to be returned. If the original dentry is used,
|
||||
NULL should be returned. Any error should be returned with
|
||||
ERR_PTR().
|
||||
|
||||
In general, filesystems which use d_instantiate_new() to install the new
|
||||
inode can safely return NULL. Filesystems which may not have an I_NEW inode
|
||||
should use d_drop();d_splice_alias() and return the result of the latter.
|
||||
|
||||
If a positive dentry cannot be returned for some reason, in-kernel
|
||||
clients such as cachefiles, nfsd, smb/server may not perform ideally but
|
||||
will fail-safe.
|
||||
|
|
|
|||
|
|
@ -495,7 +495,7 @@ As of kernel 2.6.22, the following members are defined:
|
|||
int (*link) (struct dentry *,struct inode *,struct dentry *);
|
||||
int (*unlink) (struct inode *,struct dentry *);
|
||||
int (*symlink) (struct mnt_idmap *, struct inode *,struct dentry *,const char *);
|
||||
int (*mkdir) (struct mnt_idmap *, struct inode *,struct dentry *,umode_t);
|
||||
struct dentry *(*mkdir) (struct mnt_idmap *, struct inode *,struct dentry *,umode_t);
|
||||
int (*rmdir) (struct inode *,struct dentry *);
|
||||
int (*mknod) (struct mnt_idmap *, struct inode *,struct dentry *,umode_t,dev_t);
|
||||
int (*rename) (struct mnt_idmap *, struct inode *, struct dentry *,
|
||||
|
|
@ -562,7 +562,26 @@ otherwise noted.
|
|||
``mkdir``
|
||||
called by the mkdir(2) system call. Only required if you want
|
||||
to support creating subdirectories. You will probably need to
|
||||
call d_instantiate() just as you would in the create() method
|
||||
call d_instantiate_new() just as you would in the create() method.
|
||||
|
||||
If d_instantiate_new() is not used and if the fh_to_dentry()
|
||||
export operation is provided, or if the storage might be
|
||||
accessible by another path (e.g. with a network filesystem)
|
||||
then more care may be needed. Importantly d_instantate()
|
||||
should not be used with an inode that is no longer I_NEW if there
|
||||
any chance that the inode could already be attached to a dentry.
|
||||
This is because of a hard rule in the VFS that a directory must
|
||||
only ever have one dentry.
|
||||
|
||||
For example, if an NFS filesystem is mounted twice the new directory
|
||||
could be visible on the other mount before it is on the original
|
||||
mount, and a pair of name_to_handle_at(), open_by_handle_at()
|
||||
calls could instantiate the directory inode with an IS_ROOT()
|
||||
dentry before the first mkdir returns.
|
||||
|
||||
If there is any chance this could happen, then the new inode
|
||||
should be d_drop()ed and attached with d_splice_alias(). The
|
||||
returned dentry (if any) should be returned by ->mkdir().
|
||||
|
||||
``rmdir``
|
||||
called by the rmdir(2) system call. Only required if you want
|
||||
|
|
|
|||
|
|
@ -160,18 +160,17 @@ static int dev_mkdir(const char *name, umode_t mode)
|
|||
{
|
||||
struct dentry *dentry;
|
||||
struct path path;
|
||||
int err;
|
||||
|
||||
dentry = kern_path_create(AT_FDCWD, name, &path, LOOKUP_DIRECTORY);
|
||||
if (IS_ERR(dentry))
|
||||
return PTR_ERR(dentry);
|
||||
|
||||
err = vfs_mkdir(&nop_mnt_idmap, d_inode(path.dentry), dentry, mode);
|
||||
if (!err)
|
||||
dentry = vfs_mkdir(&nop_mnt_idmap, d_inode(path.dentry), dentry, mode);
|
||||
if (!IS_ERR(dentry))
|
||||
/* mark as kernel-created inode */
|
||||
d_inode(dentry)->i_private = &thread;
|
||||
done_path_create(&path, dentry);
|
||||
return err;
|
||||
return PTR_ERR_OR_ZERO(dentry);
|
||||
}
|
||||
|
||||
static int create_path(const char *nodepath)
|
||||
|
|
|
|||
|
|
@ -669,8 +669,8 @@ v9fs_vfs_create(struct mnt_idmap *idmap, struct inode *dir,
|
|||
*
|
||||
*/
|
||||
|
||||
static int v9fs_vfs_mkdir(struct mnt_idmap *idmap, struct inode *dir,
|
||||
struct dentry *dentry, umode_t mode)
|
||||
static struct dentry *v9fs_vfs_mkdir(struct mnt_idmap *idmap, struct inode *dir,
|
||||
struct dentry *dentry, umode_t mode)
|
||||
{
|
||||
int err;
|
||||
u32 perm;
|
||||
|
|
@ -692,8 +692,7 @@ static int v9fs_vfs_mkdir(struct mnt_idmap *idmap, struct inode *dir,
|
|||
|
||||
if (fid)
|
||||
p9_fid_put(fid);
|
||||
|
||||
return err;
|
||||
return ERR_PTR(err);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -350,9 +350,9 @@ v9fs_vfs_atomic_open_dotl(struct inode *dir, struct dentry *dentry,
|
|||
*
|
||||
*/
|
||||
|
||||
static int v9fs_vfs_mkdir_dotl(struct mnt_idmap *idmap,
|
||||
struct inode *dir, struct dentry *dentry,
|
||||
umode_t omode)
|
||||
static struct dentry *v9fs_vfs_mkdir_dotl(struct mnt_idmap *idmap,
|
||||
struct inode *dir, struct dentry *dentry,
|
||||
umode_t omode)
|
||||
{
|
||||
int err;
|
||||
struct v9fs_session_info *v9ses;
|
||||
|
|
@ -417,7 +417,7 @@ static int v9fs_vfs_mkdir_dotl(struct mnt_idmap *idmap,
|
|||
p9_fid_put(fid);
|
||||
v9fs_put_acl(dacl, pacl);
|
||||
p9_fid_put(dfid);
|
||||
return err;
|
||||
return ERR_PTR(err);
|
||||
}
|
||||
|
||||
static int
|
||||
|
|
|
|||
|
|
@ -168,7 +168,7 @@ extern struct dentry *affs_lookup(struct inode *dir, struct dentry *dentry, unsi
|
|||
extern int affs_unlink(struct inode *dir, struct dentry *dentry);
|
||||
extern int affs_create(struct mnt_idmap *idmap, struct inode *dir,
|
||||
struct dentry *dentry, umode_t mode, bool);
|
||||
extern int affs_mkdir(struct mnt_idmap *idmap, struct inode *dir,
|
||||
extern struct dentry *affs_mkdir(struct mnt_idmap *idmap, struct inode *dir,
|
||||
struct dentry *dentry, umode_t mode);
|
||||
extern int affs_rmdir(struct inode *dir, struct dentry *dentry);
|
||||
extern int affs_link(struct dentry *olddentry, struct inode *dir,
|
||||
|
|
|
|||
|
|
@ -273,7 +273,7 @@ affs_create(struct mnt_idmap *idmap, struct inode *dir,
|
|||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
struct dentry *
|
||||
affs_mkdir(struct mnt_idmap *idmap, struct inode *dir,
|
||||
struct dentry *dentry, umode_t mode)
|
||||
{
|
||||
|
|
@ -285,7 +285,7 @@ affs_mkdir(struct mnt_idmap *idmap, struct inode *dir,
|
|||
|
||||
inode = affs_new_inode(dir);
|
||||
if (!inode)
|
||||
return -ENOSPC;
|
||||
return ERR_PTR(-ENOSPC);
|
||||
|
||||
inode->i_mode = S_IFDIR | mode;
|
||||
affs_mode_to_prot(inode);
|
||||
|
|
@ -298,9 +298,9 @@ affs_mkdir(struct mnt_idmap *idmap, struct inode *dir,
|
|||
clear_nlink(inode);
|
||||
mark_inode_dirty(inode);
|
||||
iput(inode);
|
||||
return error;
|
||||
return ERR_PTR(error);
|
||||
}
|
||||
return 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int
|
||||
|
|
|
|||
12
fs/afs/dir.c
12
fs/afs/dir.c
|
|
@ -33,8 +33,8 @@ static bool afs_lookup_filldir(struct dir_context *ctx, const char *name, int nl
|
|||
loff_t fpos, u64 ino, unsigned dtype);
|
||||
static int afs_create(struct mnt_idmap *idmap, struct inode *dir,
|
||||
struct dentry *dentry, umode_t mode, bool excl);
|
||||
static int afs_mkdir(struct mnt_idmap *idmap, struct inode *dir,
|
||||
struct dentry *dentry, umode_t mode);
|
||||
static struct dentry *afs_mkdir(struct mnt_idmap *idmap, struct inode *dir,
|
||||
struct dentry *dentry, umode_t mode);
|
||||
static int afs_rmdir(struct inode *dir, struct dentry *dentry);
|
||||
static int afs_unlink(struct inode *dir, struct dentry *dentry);
|
||||
static int afs_link(struct dentry *from, struct inode *dir,
|
||||
|
|
@ -1315,8 +1315,8 @@ static const struct afs_operation_ops afs_mkdir_operation = {
|
|||
/*
|
||||
* create a directory on an AFS filesystem
|
||||
*/
|
||||
static int afs_mkdir(struct mnt_idmap *idmap, struct inode *dir,
|
||||
struct dentry *dentry, umode_t mode)
|
||||
static struct dentry *afs_mkdir(struct mnt_idmap *idmap, struct inode *dir,
|
||||
struct dentry *dentry, umode_t mode)
|
||||
{
|
||||
struct afs_operation *op;
|
||||
struct afs_vnode *dvnode = AFS_FS_I(dir);
|
||||
|
|
@ -1328,7 +1328,7 @@ static int afs_mkdir(struct mnt_idmap *idmap, struct inode *dir,
|
|||
op = afs_alloc_operation(NULL, dvnode->volume);
|
||||
if (IS_ERR(op)) {
|
||||
d_drop(dentry);
|
||||
return PTR_ERR(op);
|
||||
return ERR_CAST(op);
|
||||
}
|
||||
|
||||
fscache_use_cookie(afs_vnode_cache(dvnode), true);
|
||||
|
|
@ -1344,7 +1344,7 @@ static int afs_mkdir(struct mnt_idmap *idmap, struct inode *dir,
|
|||
op->ops = &afs_mkdir_operation;
|
||||
ret = afs_do_sync_operation(op);
|
||||
afs_dir_unuse_cookie(dvnode, ret);
|
||||
return ret;
|
||||
return ERR_PTR(ret);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -15,8 +15,8 @@ static int autofs_dir_symlink(struct mnt_idmap *, struct inode *,
|
|||
struct dentry *, const char *);
|
||||
static int autofs_dir_unlink(struct inode *, struct dentry *);
|
||||
static int autofs_dir_rmdir(struct inode *, struct dentry *);
|
||||
static int autofs_dir_mkdir(struct mnt_idmap *, struct inode *,
|
||||
struct dentry *, umode_t);
|
||||
static struct dentry *autofs_dir_mkdir(struct mnt_idmap *, struct inode *,
|
||||
struct dentry *, umode_t);
|
||||
static long autofs_root_ioctl(struct file *, unsigned int, unsigned long);
|
||||
#ifdef CONFIG_COMPAT
|
||||
static long autofs_root_compat_ioctl(struct file *,
|
||||
|
|
@ -720,9 +720,9 @@ static int autofs_dir_rmdir(struct inode *dir, struct dentry *dentry)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int autofs_dir_mkdir(struct mnt_idmap *idmap,
|
||||
struct inode *dir, struct dentry *dentry,
|
||||
umode_t mode)
|
||||
static struct dentry *autofs_dir_mkdir(struct mnt_idmap *idmap,
|
||||
struct inode *dir, struct dentry *dentry,
|
||||
umode_t mode)
|
||||
{
|
||||
struct autofs_sb_info *sbi = autofs_sbi(dir->i_sb);
|
||||
struct autofs_info *ino = autofs_dentry_ino(dentry);
|
||||
|
|
@ -739,7 +739,7 @@ static int autofs_dir_mkdir(struct mnt_idmap *idmap,
|
|||
|
||||
inode = autofs_get_inode(dir->i_sb, S_IFDIR | mode);
|
||||
if (!inode)
|
||||
return -ENOMEM;
|
||||
return ERR_PTR(-ENOMEM);
|
||||
d_add(dentry, inode);
|
||||
|
||||
if (sbi->version < 5)
|
||||
|
|
@ -751,7 +751,7 @@ static int autofs_dir_mkdir(struct mnt_idmap *idmap,
|
|||
inc_nlink(dir);
|
||||
inode_set_mtime_to_ts(dir, inode_set_ctime_current(dir));
|
||||
|
||||
return 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Get/set timeout ioctl() operation */
|
||||
|
|
|
|||
|
|
@ -58,10 +58,10 @@ static int bad_inode_symlink(struct mnt_idmap *idmap,
|
|||
return -EIO;
|
||||
}
|
||||
|
||||
static int bad_inode_mkdir(struct mnt_idmap *idmap, struct inode *dir,
|
||||
struct dentry *dentry, umode_t mode)
|
||||
static struct dentry *bad_inode_mkdir(struct mnt_idmap *idmap, struct inode *dir,
|
||||
struct dentry *dentry, umode_t mode)
|
||||
{
|
||||
return -EIO;
|
||||
return ERR_PTR(-EIO);
|
||||
}
|
||||
|
||||
static int bad_inode_rmdir (struct inode *dir, struct dentry *dentry)
|
||||
|
|
|
|||
|
|
@ -858,10 +858,10 @@ static int bch2_symlink(struct mnt_idmap *idmap,
|
|||
return bch2_err_class(ret);
|
||||
}
|
||||
|
||||
static int bch2_mkdir(struct mnt_idmap *idmap,
|
||||
struct inode *vdir, struct dentry *dentry, umode_t mode)
|
||||
static struct dentry *bch2_mkdir(struct mnt_idmap *idmap,
|
||||
struct inode *vdir, struct dentry *dentry, umode_t mode)
|
||||
{
|
||||
return bch2_mknod(idmap, vdir, dentry, mode|S_IFDIR, 0);
|
||||
return ERR_PTR(bch2_mknod(idmap, vdir, dentry, mode|S_IFDIR, 0));
|
||||
}
|
||||
|
||||
static int bch2_rename2(struct mnt_idmap *idmap,
|
||||
|
|
|
|||
|
|
@ -6739,18 +6739,18 @@ static int btrfs_link(struct dentry *old_dentry, struct inode *dir,
|
|||
return err;
|
||||
}
|
||||
|
||||
static int btrfs_mkdir(struct mnt_idmap *idmap, struct inode *dir,
|
||||
struct dentry *dentry, umode_t mode)
|
||||
static struct dentry *btrfs_mkdir(struct mnt_idmap *idmap, struct inode *dir,
|
||||
struct dentry *dentry, umode_t mode)
|
||||
{
|
||||
struct inode *inode;
|
||||
|
||||
inode = new_inode(dir->i_sb);
|
||||
if (!inode)
|
||||
return -ENOMEM;
|
||||
return ERR_PTR(-ENOMEM);
|
||||
inode_init_owner(idmap, inode, dir, S_IFDIR | mode);
|
||||
inode->i_op = &btrfs_dir_inode_operations;
|
||||
inode->i_fop = &btrfs_dir_file_operations;
|
||||
return btrfs_create_common(dir, dentry, inode);
|
||||
return ERR_PTR(btrfs_create_common(dir, dentry, inode));
|
||||
}
|
||||
|
||||
static noinline int uncompress_inline(struct btrfs_path *path,
|
||||
|
|
|
|||
|
|
@ -128,18 +128,19 @@ struct dentry *cachefiles_get_directory(struct cachefiles_cache *cache,
|
|||
ret = security_path_mkdir(&path, subdir, 0700);
|
||||
if (ret < 0)
|
||||
goto mkdir_error;
|
||||
ret = cachefiles_inject_write_error();
|
||||
if (ret == 0)
|
||||
ret = vfs_mkdir(&nop_mnt_idmap, d_inode(dir), subdir, 0700);
|
||||
if (ret < 0) {
|
||||
subdir = ERR_PTR(cachefiles_inject_write_error());
|
||||
if (!IS_ERR(subdir))
|
||||
subdir = vfs_mkdir(&nop_mnt_idmap, d_inode(dir), subdir, 0700);
|
||||
ret = PTR_ERR(subdir);
|
||||
if (IS_ERR(subdir)) {
|
||||
trace_cachefiles_vfs_error(NULL, d_inode(dir), ret,
|
||||
cachefiles_trace_mkdir_error);
|
||||
goto mkdir_error;
|
||||
}
|
||||
trace_cachefiles_mkdir(dir, subdir);
|
||||
|
||||
if (unlikely(d_unhashed(subdir))) {
|
||||
cachefiles_put_directory(subdir);
|
||||
if (unlikely(d_unhashed(subdir) || d_is_negative(subdir))) {
|
||||
dput(subdir);
|
||||
goto retry;
|
||||
}
|
||||
ASSERT(d_backing_inode(subdir));
|
||||
|
|
@ -195,7 +196,8 @@ struct dentry *cachefiles_get_directory(struct cachefiles_cache *cache,
|
|||
|
||||
mkdir_error:
|
||||
inode_unlock(d_inode(dir));
|
||||
dput(subdir);
|
||||
if (!IS_ERR(subdir))
|
||||
dput(subdir);
|
||||
pr_err("mkdir %s failed with error %d\n", dirname, ret);
|
||||
return ERR_PTR(ret);
|
||||
|
||||
|
|
|
|||
|
|
@ -1092,19 +1092,20 @@ static int ceph_symlink(struct mnt_idmap *idmap, struct inode *dir,
|
|||
return err;
|
||||
}
|
||||
|
||||
static int ceph_mkdir(struct mnt_idmap *idmap, struct inode *dir,
|
||||
struct dentry *dentry, umode_t mode)
|
||||
static struct dentry *ceph_mkdir(struct mnt_idmap *idmap, struct inode *dir,
|
||||
struct dentry *dentry, umode_t mode)
|
||||
{
|
||||
struct ceph_mds_client *mdsc = ceph_sb_to_mdsc(dir->i_sb);
|
||||
struct ceph_client *cl = mdsc->fsc->client;
|
||||
struct ceph_mds_request *req;
|
||||
struct ceph_acl_sec_ctx as_ctx = {};
|
||||
struct dentry *ret;
|
||||
int err;
|
||||
int op;
|
||||
|
||||
err = ceph_wait_on_conflict_unlink(dentry);
|
||||
if (err)
|
||||
return err;
|
||||
return ERR_PTR(err);
|
||||
|
||||
if (ceph_snap(dir) == CEPH_SNAPDIR) {
|
||||
/* mkdir .snap/foo is a MKSNAP */
|
||||
|
|
@ -1116,32 +1117,32 @@ static int ceph_mkdir(struct mnt_idmap *idmap, struct inode *dir,
|
|||
ceph_vinop(dir), dentry, dentry, mode);
|
||||
op = CEPH_MDS_OP_MKDIR;
|
||||
} else {
|
||||
err = -EROFS;
|
||||
ret = ERR_PTR(-EROFS);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (op == CEPH_MDS_OP_MKDIR &&
|
||||
ceph_quota_is_max_files_exceeded(dir)) {
|
||||
err = -EDQUOT;
|
||||
ret = ERR_PTR(-EDQUOT);
|
||||
goto out;
|
||||
}
|
||||
if ((op == CEPH_MDS_OP_MKSNAP) && IS_ENCRYPTED(dir) &&
|
||||
!fscrypt_has_encryption_key(dir)) {
|
||||
err = -ENOKEY;
|
||||
ret = ERR_PTR(-ENOKEY);
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
||||
req = ceph_mdsc_create_request(mdsc, op, USE_AUTH_MDS);
|
||||
if (IS_ERR(req)) {
|
||||
err = PTR_ERR(req);
|
||||
ret = ERR_CAST(req);
|
||||
goto out;
|
||||
}
|
||||
|
||||
mode |= S_IFDIR;
|
||||
req->r_new_inode = ceph_new_inode(dir, dentry, &mode, &as_ctx);
|
||||
if (IS_ERR(req->r_new_inode)) {
|
||||
err = PTR_ERR(req->r_new_inode);
|
||||
ret = ERR_CAST(req->r_new_inode);
|
||||
req->r_new_inode = NULL;
|
||||
goto out_req;
|
||||
}
|
||||
|
|
@ -1165,15 +1166,22 @@ static int ceph_mkdir(struct mnt_idmap *idmap, struct inode *dir,
|
|||
!req->r_reply_info.head->is_target &&
|
||||
!req->r_reply_info.head->is_dentry)
|
||||
err = ceph_handle_notrace_create(dir, dentry);
|
||||
ret = ERR_PTR(err);
|
||||
out_req:
|
||||
if (!IS_ERR(ret) && req->r_dentry != dentry)
|
||||
/* Some other dentry was spliced in */
|
||||
ret = dget(req->r_dentry);
|
||||
ceph_mdsc_put_request(req);
|
||||
out:
|
||||
if (!err)
|
||||
if (!IS_ERR(ret)) {
|
||||
if (ret)
|
||||
dentry = ret;
|
||||
ceph_init_inode_acls(d_inode(dentry), &as_ctx);
|
||||
else
|
||||
} else {
|
||||
d_drop(dentry);
|
||||
}
|
||||
ceph_release_acl_sec_ctx(&as_ctx);
|
||||
return err;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int ceph_link(struct dentry *old_dentry, struct inode *dir,
|
||||
|
|
|
|||
|
|
@ -166,8 +166,8 @@ static int coda_create(struct mnt_idmap *idmap, struct inode *dir,
|
|||
return error;
|
||||
}
|
||||
|
||||
static int coda_mkdir(struct mnt_idmap *idmap, struct inode *dir,
|
||||
struct dentry *de, umode_t mode)
|
||||
static struct dentry *coda_mkdir(struct mnt_idmap *idmap, struct inode *dir,
|
||||
struct dentry *de, umode_t mode)
|
||||
{
|
||||
struct inode *inode;
|
||||
struct coda_vattr attrs;
|
||||
|
|
@ -177,14 +177,14 @@ static int coda_mkdir(struct mnt_idmap *idmap, struct inode *dir,
|
|||
struct CodaFid newfid;
|
||||
|
||||
if (is_root_inode(dir) && coda_iscontrol(name, len))
|
||||
return -EPERM;
|
||||
return ERR_PTR(-EPERM);
|
||||
|
||||
attrs.va_mode = mode;
|
||||
error = venus_mkdir(dir->i_sb, coda_i2f(dir),
|
||||
error = venus_mkdir(dir->i_sb, coda_i2f(dir),
|
||||
name, len, &newfid, &attrs);
|
||||
if (error)
|
||||
goto err_out;
|
||||
|
||||
|
||||
inode = coda_iget(dir->i_sb, &newfid, &attrs);
|
||||
if (IS_ERR(inode)) {
|
||||
error = PTR_ERR(inode);
|
||||
|
|
@ -195,10 +195,10 @@ static int coda_mkdir(struct mnt_idmap *idmap, struct inode *dir,
|
|||
coda_dir_inc_nlink(dir);
|
||||
coda_dir_update_mtime(dir);
|
||||
d_instantiate(de, inode);
|
||||
return 0;
|
||||
return NULL;
|
||||
err_out:
|
||||
d_drop(de);
|
||||
return error;
|
||||
return ERR_PTR(error);
|
||||
}
|
||||
|
||||
/* try to make de an entry in dir_inodde linked to source_de */
|
||||
|
|
|
|||
|
|
@ -1280,8 +1280,8 @@ int configfs_depend_item_unlocked(struct configfs_subsystem *caller_subsys,
|
|||
}
|
||||
EXPORT_SYMBOL(configfs_depend_item_unlocked);
|
||||
|
||||
static int configfs_mkdir(struct mnt_idmap *idmap, struct inode *dir,
|
||||
struct dentry *dentry, umode_t mode)
|
||||
static struct dentry *configfs_mkdir(struct mnt_idmap *idmap, struct inode *dir,
|
||||
struct dentry *dentry, umode_t mode)
|
||||
{
|
||||
int ret = 0;
|
||||
int module_got = 0;
|
||||
|
|
@ -1461,7 +1461,7 @@ static int configfs_mkdir(struct mnt_idmap *idmap, struct inode *dir,
|
|||
put_fragment(frag);
|
||||
|
||||
out:
|
||||
return ret;
|
||||
return ERR_PTR(ret);
|
||||
}
|
||||
|
||||
static int configfs_rmdir(struct inode *dir, struct dentry *dentry)
|
||||
|
|
|
|||
|
|
@ -503,18 +503,24 @@ static int ecryptfs_symlink(struct mnt_idmap *idmap,
|
|||
return rc;
|
||||
}
|
||||
|
||||
static int ecryptfs_mkdir(struct mnt_idmap *idmap, struct inode *dir,
|
||||
struct dentry *dentry, umode_t mode)
|
||||
static struct dentry *ecryptfs_mkdir(struct mnt_idmap *idmap, struct inode *dir,
|
||||
struct dentry *dentry, umode_t mode)
|
||||
{
|
||||
int rc;
|
||||
struct dentry *lower_dentry;
|
||||
struct inode *lower_dir;
|
||||
|
||||
rc = lock_parent(dentry, &lower_dentry, &lower_dir);
|
||||
if (!rc)
|
||||
rc = vfs_mkdir(&nop_mnt_idmap, lower_dir,
|
||||
lower_dentry, mode);
|
||||
if (rc || d_really_is_negative(lower_dentry))
|
||||
if (rc)
|
||||
goto out;
|
||||
|
||||
lower_dentry = vfs_mkdir(&nop_mnt_idmap, lower_dir,
|
||||
lower_dentry, mode);
|
||||
rc = PTR_ERR(lower_dentry);
|
||||
if (IS_ERR(lower_dentry))
|
||||
goto out;
|
||||
rc = 0;
|
||||
if (d_unhashed(lower_dentry))
|
||||
goto out;
|
||||
rc = ecryptfs_interpose(lower_dentry, dentry, dir->i_sb);
|
||||
if (rc)
|
||||
|
|
@ -526,7 +532,7 @@ static int ecryptfs_mkdir(struct mnt_idmap *idmap, struct inode *dir,
|
|||
inode_unlock(lower_dir);
|
||||
if (d_really_is_negative(dentry))
|
||||
d_drop(dentry);
|
||||
return rc;
|
||||
return ERR_PTR(rc);
|
||||
}
|
||||
|
||||
static int ecryptfs_rmdir(struct inode *dir, struct dentry *dentry)
|
||||
|
|
|
|||
|
|
@ -835,8 +835,8 @@ static int exfat_unlink(struct inode *dir, struct dentry *dentry)
|
|||
return err;
|
||||
}
|
||||
|
||||
static int exfat_mkdir(struct mnt_idmap *idmap, struct inode *dir,
|
||||
struct dentry *dentry, umode_t mode)
|
||||
static struct dentry *exfat_mkdir(struct mnt_idmap *idmap, struct inode *dir,
|
||||
struct dentry *dentry, umode_t mode)
|
||||
{
|
||||
struct super_block *sb = dir->i_sb;
|
||||
struct inode *inode;
|
||||
|
|
@ -846,7 +846,7 @@ static int exfat_mkdir(struct mnt_idmap *idmap, struct inode *dir,
|
|||
loff_t size = i_size_read(dir);
|
||||
|
||||
if (unlikely(exfat_forced_shutdown(sb)))
|
||||
return -EIO;
|
||||
return ERR_PTR(-EIO);
|
||||
|
||||
mutex_lock(&EXFAT_SB(sb)->s_lock);
|
||||
exfat_set_volume_dirty(sb);
|
||||
|
|
@ -877,7 +877,7 @@ static int exfat_mkdir(struct mnt_idmap *idmap, struct inode *dir,
|
|||
|
||||
unlock:
|
||||
mutex_unlock(&EXFAT_SB(sb)->s_lock);
|
||||
return err;
|
||||
return ERR_PTR(err);
|
||||
}
|
||||
|
||||
static int exfat_check_dir_empty(struct super_block *sb,
|
||||
|
|
|
|||
|
|
@ -225,15 +225,16 @@ static int ext2_link (struct dentry * old_dentry, struct inode * dir,
|
|||
return err;
|
||||
}
|
||||
|
||||
static int ext2_mkdir(struct mnt_idmap * idmap,
|
||||
struct inode * dir, struct dentry * dentry, umode_t mode)
|
||||
static struct dentry *ext2_mkdir(struct mnt_idmap * idmap,
|
||||
struct inode * dir, struct dentry * dentry,
|
||||
umode_t mode)
|
||||
{
|
||||
struct inode * inode;
|
||||
int err;
|
||||
|
||||
err = dquot_initialize(dir);
|
||||
if (err)
|
||||
return err;
|
||||
return ERR_PTR(err);
|
||||
|
||||
inode_inc_link_count(dir);
|
||||
|
||||
|
|
@ -258,7 +259,7 @@ static int ext2_mkdir(struct mnt_idmap * idmap,
|
|||
|
||||
d_instantiate_new(dentry, inode);
|
||||
out:
|
||||
return err;
|
||||
return ERR_PTR(err);
|
||||
|
||||
out_fail:
|
||||
inode_dec_link_count(inode);
|
||||
|
|
|
|||
|
|
@ -3004,19 +3004,19 @@ int ext4_init_new_dir(handle_t *handle, struct inode *dir,
|
|||
return err;
|
||||
}
|
||||
|
||||
static int ext4_mkdir(struct mnt_idmap *idmap, struct inode *dir,
|
||||
struct dentry *dentry, umode_t mode)
|
||||
static struct dentry *ext4_mkdir(struct mnt_idmap *idmap, struct inode *dir,
|
||||
struct dentry *dentry, umode_t mode)
|
||||
{
|
||||
handle_t *handle;
|
||||
struct inode *inode;
|
||||
int err, err2 = 0, credits, retries = 0;
|
||||
|
||||
if (EXT4_DIR_LINK_MAX(dir))
|
||||
return -EMLINK;
|
||||
return ERR_PTR(-EMLINK);
|
||||
|
||||
err = dquot_initialize(dir);
|
||||
if (err)
|
||||
return err;
|
||||
return ERR_PTR(err);
|
||||
|
||||
credits = (EXT4_DATA_TRANS_BLOCKS(dir->i_sb) +
|
||||
EXT4_INDEX_EXTRA_TRANS_BLOCKS + 3);
|
||||
|
|
@ -3066,7 +3066,7 @@ static int ext4_mkdir(struct mnt_idmap *idmap, struct inode *dir,
|
|||
out_retry:
|
||||
if (err == -ENOSPC && ext4_should_retry_alloc(dir->i_sb, &retries))
|
||||
goto retry;
|
||||
return err;
|
||||
return ERR_PTR(err);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -684,23 +684,23 @@ static int f2fs_symlink(struct mnt_idmap *idmap, struct inode *dir,
|
|||
return err;
|
||||
}
|
||||
|
||||
static int f2fs_mkdir(struct mnt_idmap *idmap, struct inode *dir,
|
||||
struct dentry *dentry, umode_t mode)
|
||||
static struct dentry *f2fs_mkdir(struct mnt_idmap *idmap, struct inode *dir,
|
||||
struct dentry *dentry, umode_t mode)
|
||||
{
|
||||
struct f2fs_sb_info *sbi = F2FS_I_SB(dir);
|
||||
struct inode *inode;
|
||||
int err;
|
||||
|
||||
if (unlikely(f2fs_cp_error(sbi)))
|
||||
return -EIO;
|
||||
return ERR_PTR(-EIO);
|
||||
|
||||
err = f2fs_dquot_initialize(dir);
|
||||
if (err)
|
||||
return err;
|
||||
return ERR_PTR(err);
|
||||
|
||||
inode = f2fs_new_inode(idmap, dir, S_IFDIR | mode, NULL);
|
||||
if (IS_ERR(inode))
|
||||
return PTR_ERR(inode);
|
||||
return ERR_CAST(inode);
|
||||
|
||||
inode->i_op = &f2fs_dir_inode_operations;
|
||||
inode->i_fop = &f2fs_dir_operations;
|
||||
|
|
@ -722,12 +722,12 @@ static int f2fs_mkdir(struct mnt_idmap *idmap, struct inode *dir,
|
|||
f2fs_sync_fs(sbi->sb, 1);
|
||||
|
||||
f2fs_balance_fs(sbi, true);
|
||||
return 0;
|
||||
return NULL;
|
||||
|
||||
out_fail:
|
||||
clear_inode_flag(inode, FI_INC_LINK);
|
||||
f2fs_handle_failed_inode(inode);
|
||||
return err;
|
||||
return ERR_PTR(err);
|
||||
}
|
||||
|
||||
static int f2fs_rmdir(struct inode *dir, struct dentry *dentry)
|
||||
|
|
|
|||
|
|
@ -339,8 +339,8 @@ static int msdos_rmdir(struct inode *dir, struct dentry *dentry)
|
|||
}
|
||||
|
||||
/***** Make a directory */
|
||||
static int msdos_mkdir(struct mnt_idmap *idmap, struct inode *dir,
|
||||
struct dentry *dentry, umode_t mode)
|
||||
static struct dentry *msdos_mkdir(struct mnt_idmap *idmap, struct inode *dir,
|
||||
struct dentry *dentry, umode_t mode)
|
||||
{
|
||||
struct super_block *sb = dir->i_sb;
|
||||
struct fat_slot_info sinfo;
|
||||
|
|
@ -389,13 +389,13 @@ static int msdos_mkdir(struct mnt_idmap *idmap, struct inode *dir,
|
|||
|
||||
mutex_unlock(&MSDOS_SB(sb)->s_lock);
|
||||
fat_flush_inodes(sb, dir, inode);
|
||||
return 0;
|
||||
return NULL;
|
||||
|
||||
out_free:
|
||||
fat_free_clusters(dir, cluster);
|
||||
out:
|
||||
mutex_unlock(&MSDOS_SB(sb)->s_lock);
|
||||
return err;
|
||||
return ERR_PTR(err);
|
||||
}
|
||||
|
||||
/***** Unlink a file */
|
||||
|
|
|
|||
|
|
@ -841,8 +841,8 @@ static int vfat_unlink(struct inode *dir, struct dentry *dentry)
|
|||
return err;
|
||||
}
|
||||
|
||||
static int vfat_mkdir(struct mnt_idmap *idmap, struct inode *dir,
|
||||
struct dentry *dentry, umode_t mode)
|
||||
static struct dentry *vfat_mkdir(struct mnt_idmap *idmap, struct inode *dir,
|
||||
struct dentry *dentry, umode_t mode)
|
||||
{
|
||||
struct super_block *sb = dir->i_sb;
|
||||
struct inode *inode;
|
||||
|
|
@ -877,13 +877,13 @@ static int vfat_mkdir(struct mnt_idmap *idmap, struct inode *dir,
|
|||
d_instantiate(dentry, inode);
|
||||
|
||||
mutex_unlock(&MSDOS_SB(sb)->s_lock);
|
||||
return 0;
|
||||
return NULL;
|
||||
|
||||
out_free:
|
||||
fat_free_clusters(dir, cluster);
|
||||
out:
|
||||
mutex_unlock(&MSDOS_SB(sb)->s_lock);
|
||||
return err;
|
||||
return ERR_PTR(err);
|
||||
}
|
||||
|
||||
static int vfat_get_dotdot_de(struct inode *inode, struct buffer_head **bh,
|
||||
|
|
|
|||
|
|
@ -781,9 +781,9 @@ static int fuse_atomic_open(struct inode *dir, struct dentry *entry,
|
|||
/*
|
||||
* Code shared between mknod, mkdir, symlink and link
|
||||
*/
|
||||
static int create_new_entry(struct mnt_idmap *idmap, struct fuse_mount *fm,
|
||||
struct fuse_args *args, struct inode *dir,
|
||||
struct dentry *entry, umode_t mode)
|
||||
static struct dentry *create_new_entry(struct mnt_idmap *idmap, struct fuse_mount *fm,
|
||||
struct fuse_args *args, struct inode *dir,
|
||||
struct dentry *entry, umode_t mode)
|
||||
{
|
||||
struct fuse_entry_out outarg;
|
||||
struct inode *inode;
|
||||
|
|
@ -792,11 +792,11 @@ static int create_new_entry(struct mnt_idmap *idmap, struct fuse_mount *fm,
|
|||
struct fuse_forget_link *forget;
|
||||
|
||||
if (fuse_is_bad(dir))
|
||||
return -EIO;
|
||||
return ERR_PTR(-EIO);
|
||||
|
||||
forget = fuse_alloc_forget();
|
||||
if (!forget)
|
||||
return -ENOMEM;
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
memset(&outarg, 0, sizeof(outarg));
|
||||
args->nodeid = get_node_id(dir);
|
||||
|
|
@ -826,29 +826,43 @@ static int create_new_entry(struct mnt_idmap *idmap, struct fuse_mount *fm,
|
|||
&outarg.attr, ATTR_TIMEOUT(&outarg), 0, 0);
|
||||
if (!inode) {
|
||||
fuse_queue_forget(fm->fc, forget, outarg.nodeid, 1);
|
||||
return -ENOMEM;
|
||||
return ERR_PTR(-ENOMEM);
|
||||
}
|
||||
kfree(forget);
|
||||
|
||||
d_drop(entry);
|
||||
d = d_splice_alias(inode, entry);
|
||||
if (IS_ERR(d))
|
||||
return PTR_ERR(d);
|
||||
return d;
|
||||
|
||||
if (d) {
|
||||
if (d)
|
||||
fuse_change_entry_timeout(d, &outarg);
|
||||
dput(d);
|
||||
} else {
|
||||
else
|
||||
fuse_change_entry_timeout(entry, &outarg);
|
||||
}
|
||||
fuse_dir_changed(dir);
|
||||
return 0;
|
||||
return d;
|
||||
|
||||
out_put_forget_req:
|
||||
if (err == -EEXIST)
|
||||
fuse_invalidate_entry(entry);
|
||||
kfree(forget);
|
||||
return err;
|
||||
return ERR_PTR(err);
|
||||
}
|
||||
|
||||
static int create_new_nondir(struct mnt_idmap *idmap, struct fuse_mount *fm,
|
||||
struct fuse_args *args, struct inode *dir,
|
||||
struct dentry *entry, umode_t mode)
|
||||
{
|
||||
/*
|
||||
* Note that when creating anything other than a directory we
|
||||
* can be sure create_new_entry() will NOT return an alternate
|
||||
* dentry as d_splice_alias() only returns an alternate dentry
|
||||
* for directories. So we don't need to check for that case
|
||||
* when passing back the result.
|
||||
*/
|
||||
WARN_ON_ONCE(S_ISDIR(mode));
|
||||
|
||||
return PTR_ERR(create_new_entry(idmap, fm, args, dir, entry, mode));
|
||||
}
|
||||
|
||||
static int fuse_mknod(struct mnt_idmap *idmap, struct inode *dir,
|
||||
|
|
@ -871,7 +885,7 @@ static int fuse_mknod(struct mnt_idmap *idmap, struct inode *dir,
|
|||
args.in_args[0].value = &inarg;
|
||||
args.in_args[1].size = entry->d_name.len + 1;
|
||||
args.in_args[1].value = entry->d_name.name;
|
||||
return create_new_entry(idmap, fm, &args, dir, entry, mode);
|
||||
return create_new_nondir(idmap, fm, &args, dir, entry, mode);
|
||||
}
|
||||
|
||||
static int fuse_create(struct mnt_idmap *idmap, struct inode *dir,
|
||||
|
|
@ -898,8 +912,8 @@ static int fuse_tmpfile(struct mnt_idmap *idmap, struct inode *dir,
|
|||
return err;
|
||||
}
|
||||
|
||||
static int fuse_mkdir(struct mnt_idmap *idmap, struct inode *dir,
|
||||
struct dentry *entry, umode_t mode)
|
||||
static struct dentry *fuse_mkdir(struct mnt_idmap *idmap, struct inode *dir,
|
||||
struct dentry *entry, umode_t mode)
|
||||
{
|
||||
struct fuse_mkdir_in inarg;
|
||||
struct fuse_mount *fm = get_fuse_mount(dir);
|
||||
|
|
@ -934,7 +948,7 @@ static int fuse_symlink(struct mnt_idmap *idmap, struct inode *dir,
|
|||
args.in_args[1].value = entry->d_name.name;
|
||||
args.in_args[2].size = len;
|
||||
args.in_args[2].value = link;
|
||||
return create_new_entry(idmap, fm, &args, dir, entry, S_IFLNK);
|
||||
return create_new_nondir(idmap, fm, &args, dir, entry, S_IFLNK);
|
||||
}
|
||||
|
||||
void fuse_flush_time_update(struct inode *inode)
|
||||
|
|
@ -1131,7 +1145,7 @@ static int fuse_link(struct dentry *entry, struct inode *newdir,
|
|||
args.in_args[0].value = &inarg;
|
||||
args.in_args[1].size = newent->d_name.len + 1;
|
||||
args.in_args[1].value = newent->d_name.name;
|
||||
err = create_new_entry(&invalid_mnt_idmap, fm, &args, newdir, newent, inode->i_mode);
|
||||
err = create_new_nondir(&invalid_mnt_idmap, fm, &args, newdir, newent, inode->i_mode);
|
||||
if (!err)
|
||||
fuse_update_ctime_in_cache(inode);
|
||||
else if (err == -EINTR)
|
||||
|
|
|
|||
|
|
@ -1248,14 +1248,15 @@ static int gfs2_symlink(struct mnt_idmap *idmap, struct inode *dir,
|
|||
* @dentry: The dentry of the new directory
|
||||
* @mode: The mode of the new directory
|
||||
*
|
||||
* Returns: errno
|
||||
* Returns: the dentry, or ERR_PTR(errno)
|
||||
*/
|
||||
|
||||
static int gfs2_mkdir(struct mnt_idmap *idmap, struct inode *dir,
|
||||
struct dentry *dentry, umode_t mode)
|
||||
static struct dentry *gfs2_mkdir(struct mnt_idmap *idmap, struct inode *dir,
|
||||
struct dentry *dentry, umode_t mode)
|
||||
{
|
||||
unsigned dsize = gfs2_max_stuffed_size(GFS2_I(dir));
|
||||
return gfs2_create_inode(dir, dentry, NULL, S_IFDIR | mode, 0, NULL, dsize, 0);
|
||||
|
||||
return ERR_PTR(gfs2_create_inode(dir, dentry, NULL, S_IFDIR | mode, 0, NULL, dsize, 0));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
10
fs/hfs/dir.c
10
fs/hfs/dir.c
|
|
@ -219,26 +219,26 @@ static int hfs_create(struct mnt_idmap *idmap, struct inode *dir,
|
|||
* in a directory, given the inode for the parent directory and the
|
||||
* name (and its length) of the new directory.
|
||||
*/
|
||||
static int hfs_mkdir(struct mnt_idmap *idmap, struct inode *dir,
|
||||
struct dentry *dentry, umode_t mode)
|
||||
static struct dentry *hfs_mkdir(struct mnt_idmap *idmap, struct inode *dir,
|
||||
struct dentry *dentry, umode_t mode)
|
||||
{
|
||||
struct inode *inode;
|
||||
int res;
|
||||
|
||||
inode = hfs_new_inode(dir, &dentry->d_name, S_IFDIR | mode);
|
||||
if (!inode)
|
||||
return -ENOMEM;
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
res = hfs_cat_create(inode->i_ino, dir, &dentry->d_name, inode);
|
||||
if (res) {
|
||||
clear_nlink(inode);
|
||||
hfs_delete_inode(inode);
|
||||
iput(inode);
|
||||
return res;
|
||||
return ERR_PTR(res);
|
||||
}
|
||||
d_instantiate(dentry, inode);
|
||||
mark_inode_dirty(inode);
|
||||
return 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -523,10 +523,10 @@ static int hfsplus_create(struct mnt_idmap *idmap, struct inode *dir,
|
|||
return hfsplus_mknod(&nop_mnt_idmap, dir, dentry, mode, 0);
|
||||
}
|
||||
|
||||
static int hfsplus_mkdir(struct mnt_idmap *idmap, struct inode *dir,
|
||||
struct dentry *dentry, umode_t mode)
|
||||
static struct dentry *hfsplus_mkdir(struct mnt_idmap *idmap, struct inode *dir,
|
||||
struct dentry *dentry, umode_t mode)
|
||||
{
|
||||
return hfsplus_mknod(&nop_mnt_idmap, dir, dentry, mode | S_IFDIR, 0);
|
||||
return ERR_PTR(hfsplus_mknod(&nop_mnt_idmap, dir, dentry, mode | S_IFDIR, 0));
|
||||
}
|
||||
|
||||
static int hfsplus_rename(struct mnt_idmap *idmap,
|
||||
|
|
|
|||
|
|
@ -679,17 +679,25 @@ static int hostfs_symlink(struct mnt_idmap *idmap, struct inode *ino,
|
|||
return err;
|
||||
}
|
||||
|
||||
static int hostfs_mkdir(struct mnt_idmap *idmap, struct inode *ino,
|
||||
struct dentry *dentry, umode_t mode)
|
||||
static struct dentry *hostfs_mkdir(struct mnt_idmap *idmap, struct inode *ino,
|
||||
struct dentry *dentry, umode_t mode)
|
||||
{
|
||||
struct inode *inode;
|
||||
char *file;
|
||||
int err;
|
||||
|
||||
if ((file = dentry_name(dentry)) == NULL)
|
||||
return -ENOMEM;
|
||||
return ERR_PTR(-ENOMEM);
|
||||
err = do_mkdir(file, mode);
|
||||
if (err) {
|
||||
dentry = ERR_PTR(err);
|
||||
} else {
|
||||
inode = hostfs_iget(dentry->d_sb, file);
|
||||
d_drop(dentry);
|
||||
dentry = d_splice_alias(inode, dentry);
|
||||
}
|
||||
__putname(file);
|
||||
return err;
|
||||
return dentry;
|
||||
}
|
||||
|
||||
static int hostfs_rmdir(struct inode *ino, struct dentry *dentry)
|
||||
|
|
|
|||
|
|
@ -19,8 +19,8 @@ static void hpfs_update_directory_times(struct inode *dir)
|
|||
hpfs_write_inode_nolock(dir);
|
||||
}
|
||||
|
||||
static int hpfs_mkdir(struct mnt_idmap *idmap, struct inode *dir,
|
||||
struct dentry *dentry, umode_t mode)
|
||||
static struct dentry *hpfs_mkdir(struct mnt_idmap *idmap, struct inode *dir,
|
||||
struct dentry *dentry, umode_t mode)
|
||||
{
|
||||
const unsigned char *name = dentry->d_name.name;
|
||||
unsigned len = dentry->d_name.len;
|
||||
|
|
@ -35,7 +35,7 @@ static int hpfs_mkdir(struct mnt_idmap *idmap, struct inode *dir,
|
|||
int r;
|
||||
struct hpfs_dirent dee;
|
||||
int err;
|
||||
if ((err = hpfs_chk_name(name, &len))) return err==-ENOENT ? -EINVAL : err;
|
||||
if ((err = hpfs_chk_name(name, &len))) return ERR_PTR(err==-ENOENT ? -EINVAL : err);
|
||||
hpfs_lock(dir->i_sb);
|
||||
err = -ENOSPC;
|
||||
fnode = hpfs_alloc_fnode(dir->i_sb, hpfs_i(dir)->i_dno, &fno, &bh);
|
||||
|
|
@ -112,7 +112,7 @@ static int hpfs_mkdir(struct mnt_idmap *idmap, struct inode *dir,
|
|||
hpfs_update_directory_times(dir);
|
||||
d_instantiate(dentry, result);
|
||||
hpfs_unlock(dir->i_sb);
|
||||
return 0;
|
||||
return NULL;
|
||||
bail3:
|
||||
iput(result);
|
||||
bail2:
|
||||
|
|
@ -123,7 +123,7 @@ static int hpfs_mkdir(struct mnt_idmap *idmap, struct inode *dir,
|
|||
hpfs_free_sectors(dir->i_sb, fno, 1);
|
||||
bail:
|
||||
hpfs_unlock(dir->i_sb);
|
||||
return err;
|
||||
return ERR_PTR(err);
|
||||
}
|
||||
|
||||
static int hpfs_create(struct mnt_idmap *idmap, struct inode *dir,
|
||||
|
|
|
|||
|
|
@ -991,14 +991,14 @@ static int hugetlbfs_mknod(struct mnt_idmap *idmap, struct inode *dir,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int hugetlbfs_mkdir(struct mnt_idmap *idmap, struct inode *dir,
|
||||
struct dentry *dentry, umode_t mode)
|
||||
static struct dentry *hugetlbfs_mkdir(struct mnt_idmap *idmap, struct inode *dir,
|
||||
struct dentry *dentry, umode_t mode)
|
||||
{
|
||||
int retval = hugetlbfs_mknod(idmap, dir, dentry,
|
||||
mode | S_IFDIR, 0);
|
||||
if (!retval)
|
||||
inc_nlink(dir);
|
||||
return retval;
|
||||
return ERR_PTR(retval);
|
||||
}
|
||||
|
||||
static int hugetlbfs_create(struct mnt_idmap *idmap,
|
||||
|
|
|
|||
|
|
@ -230,9 +230,12 @@ int __init init_mkdir(const char *pathname, umode_t mode)
|
|||
return PTR_ERR(dentry);
|
||||
mode = mode_strip_umask(d_inode(path.dentry), mode);
|
||||
error = security_path_mkdir(&path, dentry, mode);
|
||||
if (!error)
|
||||
error = vfs_mkdir(mnt_idmap(path.mnt), path.dentry->d_inode,
|
||||
if (!error) {
|
||||
dentry = vfs_mkdir(mnt_idmap(path.mnt), path.dentry->d_inode,
|
||||
dentry, mode);
|
||||
if (IS_ERR(dentry))
|
||||
error = PTR_ERR(dentry);
|
||||
}
|
||||
done_path_create(&path, dentry);
|
||||
return error;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -32,8 +32,8 @@ static int jffs2_link (struct dentry *,struct inode *,struct dentry *);
|
|||
static int jffs2_unlink (struct inode *,struct dentry *);
|
||||
static int jffs2_symlink (struct mnt_idmap *, struct inode *,
|
||||
struct dentry *, const char *);
|
||||
static int jffs2_mkdir (struct mnt_idmap *, struct inode *,struct dentry *,
|
||||
umode_t);
|
||||
static struct dentry *jffs2_mkdir (struct mnt_idmap *, struct inode *,struct dentry *,
|
||||
umode_t);
|
||||
static int jffs2_rmdir (struct inode *,struct dentry *);
|
||||
static int jffs2_mknod (struct mnt_idmap *, struct inode *,struct dentry *,
|
||||
umode_t,dev_t);
|
||||
|
|
@ -446,8 +446,8 @@ static int jffs2_symlink (struct mnt_idmap *idmap, struct inode *dir_i,
|
|||
}
|
||||
|
||||
|
||||
static int jffs2_mkdir (struct mnt_idmap *idmap, struct inode *dir_i,
|
||||
struct dentry *dentry, umode_t mode)
|
||||
static struct dentry *jffs2_mkdir (struct mnt_idmap *idmap, struct inode *dir_i,
|
||||
struct dentry *dentry, umode_t mode)
|
||||
{
|
||||
struct jffs2_inode_info *f, *dir_f;
|
||||
struct jffs2_sb_info *c;
|
||||
|
|
@ -464,7 +464,7 @@ static int jffs2_mkdir (struct mnt_idmap *idmap, struct inode *dir_i,
|
|||
|
||||
ri = jffs2_alloc_raw_inode();
|
||||
if (!ri)
|
||||
return -ENOMEM;
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
c = JFFS2_SB_INFO(dir_i->i_sb);
|
||||
|
||||
|
|
@ -477,7 +477,7 @@ static int jffs2_mkdir (struct mnt_idmap *idmap, struct inode *dir_i,
|
|||
|
||||
if (ret) {
|
||||
jffs2_free_raw_inode(ri);
|
||||
return ret;
|
||||
return ERR_PTR(ret);
|
||||
}
|
||||
|
||||
inode = jffs2_new_inode(dir_i, mode, ri);
|
||||
|
|
@ -485,7 +485,7 @@ static int jffs2_mkdir (struct mnt_idmap *idmap, struct inode *dir_i,
|
|||
if (IS_ERR(inode)) {
|
||||
jffs2_free_raw_inode(ri);
|
||||
jffs2_complete_reservation(c);
|
||||
return PTR_ERR(inode);
|
||||
return ERR_CAST(inode);
|
||||
}
|
||||
|
||||
inode->i_op = &jffs2_dir_inode_operations;
|
||||
|
|
@ -584,11 +584,11 @@ static int jffs2_mkdir (struct mnt_idmap *idmap, struct inode *dir_i,
|
|||
jffs2_complete_reservation(c);
|
||||
|
||||
d_instantiate_new(dentry, inode);
|
||||
return 0;
|
||||
return NULL;
|
||||
|
||||
fail:
|
||||
iget_failed(inode);
|
||||
return ret;
|
||||
return ERR_PTR(ret);
|
||||
}
|
||||
|
||||
static int jffs2_rmdir (struct inode *dir_i, struct dentry *dentry)
|
||||
|
|
|
|||
|
|
@ -187,13 +187,13 @@ static int jfs_create(struct mnt_idmap *idmap, struct inode *dip,
|
|||
* dentry - dentry of child directory
|
||||
* mode - create mode (rwxrwxrwx).
|
||||
*
|
||||
* RETURN: Errors from subroutines
|
||||
* RETURN: ERR_PTR() of errors from subroutines.
|
||||
*
|
||||
* note:
|
||||
* EACCES: user needs search+write permission on the parent directory
|
||||
*/
|
||||
static int jfs_mkdir(struct mnt_idmap *idmap, struct inode *dip,
|
||||
struct dentry *dentry, umode_t mode)
|
||||
static struct dentry *jfs_mkdir(struct mnt_idmap *idmap, struct inode *dip,
|
||||
struct dentry *dentry, umode_t mode)
|
||||
{
|
||||
int rc = 0;
|
||||
tid_t tid; /* transaction id */
|
||||
|
|
@ -308,7 +308,7 @@ static int jfs_mkdir(struct mnt_idmap *idmap, struct inode *dip,
|
|||
out1:
|
||||
|
||||
jfs_info("jfs_mkdir: rc:%d", rc);
|
||||
return rc;
|
||||
return ERR_PTR(rc);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -1230,24 +1230,24 @@ static struct dentry *kernfs_iop_lookup(struct inode *dir,
|
|||
return d_splice_alias(inode, dentry);
|
||||
}
|
||||
|
||||
static int kernfs_iop_mkdir(struct mnt_idmap *idmap,
|
||||
struct inode *dir, struct dentry *dentry,
|
||||
umode_t mode)
|
||||
static struct dentry *kernfs_iop_mkdir(struct mnt_idmap *idmap,
|
||||
struct inode *dir, struct dentry *dentry,
|
||||
umode_t mode)
|
||||
{
|
||||
struct kernfs_node *parent = dir->i_private;
|
||||
struct kernfs_syscall_ops *scops = kernfs_root(parent)->syscall_ops;
|
||||
int ret;
|
||||
|
||||
if (!scops || !scops->mkdir)
|
||||
return -EPERM;
|
||||
return ERR_PTR(-EPERM);
|
||||
|
||||
if (!kernfs_get_active(parent))
|
||||
return -ENODEV;
|
||||
return ERR_PTR(-ENODEV);
|
||||
|
||||
ret = scops->mkdir(parent, dentry->d_name.name, mode);
|
||||
|
||||
kernfs_put_active(parent);
|
||||
return ret;
|
||||
return ERR_PTR(ret);
|
||||
}
|
||||
|
||||
static int kernfs_iop_rmdir(struct inode *dir, struct dentry *dentry)
|
||||
|
|
|
|||
|
|
@ -104,15 +104,15 @@ static int minix_link(struct dentry * old_dentry, struct inode * dir,
|
|||
return add_nondir(dentry, inode);
|
||||
}
|
||||
|
||||
static int minix_mkdir(struct mnt_idmap *idmap, struct inode *dir,
|
||||
struct dentry *dentry, umode_t mode)
|
||||
static struct dentry *minix_mkdir(struct mnt_idmap *idmap, struct inode *dir,
|
||||
struct dentry *dentry, umode_t mode)
|
||||
{
|
||||
struct inode * inode;
|
||||
int err;
|
||||
|
||||
inode = minix_new_inode(dir, S_IFDIR | mode);
|
||||
if (IS_ERR(inode))
|
||||
return PTR_ERR(inode);
|
||||
return ERR_CAST(inode);
|
||||
|
||||
inode_inc_link_count(dir);
|
||||
minix_set_inode(inode, 0);
|
||||
|
|
@ -128,7 +128,7 @@ static int minix_mkdir(struct mnt_idmap *idmap, struct inode *dir,
|
|||
|
||||
d_instantiate(dentry, inode);
|
||||
out:
|
||||
return err;
|
||||
return ERR_PTR(err);
|
||||
|
||||
out_fail:
|
||||
inode_dec_link_count(inode);
|
||||
|
|
|
|||
48
fs/namei.c
48
fs/namei.c
|
|
@ -4128,7 +4128,8 @@ EXPORT_SYMBOL(kern_path_create);
|
|||
|
||||
void done_path_create(struct path *path, struct dentry *dentry)
|
||||
{
|
||||
dput(dentry);
|
||||
if (!IS_ERR(dentry))
|
||||
dput(dentry);
|
||||
inode_unlock(path->dentry->d_inode);
|
||||
mnt_drop_write(path->mnt);
|
||||
path_put(path);
|
||||
|
|
@ -4274,7 +4275,7 @@ SYSCALL_DEFINE3(mknod, const char __user *, filename, umode_t, mode, unsigned, d
|
|||
}
|
||||
|
||||
/**
|
||||
* vfs_mkdir - create directory
|
||||
* vfs_mkdir - create directory returning correct dentry if possible
|
||||
* @idmap: idmap of the mount the inode was found from
|
||||
* @dir: inode of the parent directory
|
||||
* @dentry: dentry of the child directory
|
||||
|
|
@ -4287,32 +4288,51 @@ SYSCALL_DEFINE3(mknod, const char __user *, filename, umode_t, mode, unsigned, d
|
|||
* care to map the inode according to @idmap before checking permissions.
|
||||
* On non-idmapped mounts or if permission checking is to be performed on the
|
||||
* raw inode simply pass @nop_mnt_idmap.
|
||||
*
|
||||
* In the event that the filesystem does not use the *@dentry but leaves it
|
||||
* negative or unhashes it and possibly splices a different one returning it,
|
||||
* the original dentry is dput() and the alternate is returned.
|
||||
*
|
||||
* In case of an error the dentry is dput() and an ERR_PTR() is returned.
|
||||
*/
|
||||
int vfs_mkdir(struct mnt_idmap *idmap, struct inode *dir,
|
||||
struct dentry *dentry, umode_t mode)
|
||||
struct dentry *vfs_mkdir(struct mnt_idmap *idmap, struct inode *dir,
|
||||
struct dentry *dentry, umode_t mode)
|
||||
{
|
||||
int error;
|
||||
unsigned max_links = dir->i_sb->s_max_links;
|
||||
struct dentry *de;
|
||||
|
||||
error = may_create(idmap, dir, dentry);
|
||||
if (error)
|
||||
return error;
|
||||
goto err;
|
||||
|
||||
error = -EPERM;
|
||||
if (!dir->i_op->mkdir)
|
||||
return -EPERM;
|
||||
goto err;
|
||||
|
||||
mode = vfs_prepare_mode(idmap, dir, mode, S_IRWXUGO | S_ISVTX, 0);
|
||||
error = security_inode_mkdir(dir, dentry, mode);
|
||||
if (error)
|
||||
return error;
|
||||
goto err;
|
||||
|
||||
error = -EMLINK;
|
||||
if (max_links && dir->i_nlink >= max_links)
|
||||
return -EMLINK;
|
||||
goto err;
|
||||
|
||||
error = dir->i_op->mkdir(idmap, dir, dentry, mode);
|
||||
if (!error)
|
||||
fsnotify_mkdir(dir, dentry);
|
||||
return error;
|
||||
de = dir->i_op->mkdir(idmap, dir, dentry, mode);
|
||||
error = PTR_ERR(de);
|
||||
if (IS_ERR(de))
|
||||
goto err;
|
||||
if (de) {
|
||||
dput(dentry);
|
||||
dentry = de;
|
||||
}
|
||||
fsnotify_mkdir(dir, dentry);
|
||||
return dentry;
|
||||
|
||||
err:
|
||||
dput(dentry);
|
||||
return ERR_PTR(error);
|
||||
}
|
||||
EXPORT_SYMBOL(vfs_mkdir);
|
||||
|
||||
|
|
@ -4332,8 +4352,10 @@ int do_mkdirat(int dfd, struct filename *name, umode_t mode)
|
|||
error = security_path_mkdir(&path, dentry,
|
||||
mode_strip_umask(path.dentry->d_inode, mode));
|
||||
if (!error) {
|
||||
error = vfs_mkdir(mnt_idmap(path.mnt), path.dentry->d_inode,
|
||||
dentry = vfs_mkdir(mnt_idmap(path.mnt), path.dentry->d_inode,
|
||||
dentry, mode);
|
||||
if (IS_ERR(dentry))
|
||||
error = PTR_ERR(dentry);
|
||||
}
|
||||
done_path_create(&path, dentry);
|
||||
if (retry_estale(error, lookup_flags)) {
|
||||
|
|
|
|||
17
fs/nfs/dir.c
17
fs/nfs/dir.c
|
|
@ -2422,11 +2422,11 @@ EXPORT_SYMBOL_GPL(nfs_mknod);
|
|||
/*
|
||||
* See comments for nfs_proc_create regarding failed operations.
|
||||
*/
|
||||
int nfs_mkdir(struct mnt_idmap *idmap, struct inode *dir,
|
||||
struct dentry *dentry, umode_t mode)
|
||||
struct dentry *nfs_mkdir(struct mnt_idmap *idmap, struct inode *dir,
|
||||
struct dentry *dentry, umode_t mode)
|
||||
{
|
||||
struct iattr attr;
|
||||
int error;
|
||||
struct dentry *ret;
|
||||
|
||||
dfprintk(VFS, "NFS: mkdir(%s/%lu), %pd\n",
|
||||
dir->i_sb->s_id, dir->i_ino, dentry);
|
||||
|
|
@ -2435,14 +2435,9 @@ int nfs_mkdir(struct mnt_idmap *idmap, struct inode *dir,
|
|||
attr.ia_mode = mode | S_IFDIR;
|
||||
|
||||
trace_nfs_mkdir_enter(dir, dentry);
|
||||
error = NFS_PROTO(dir)->mkdir(dir, dentry, &attr);
|
||||
trace_nfs_mkdir_exit(dir, dentry, error);
|
||||
if (error != 0)
|
||||
goto out_err;
|
||||
return 0;
|
||||
out_err:
|
||||
d_drop(dentry);
|
||||
return error;
|
||||
ret = NFS_PROTO(dir)->mkdir(dir, dentry, &attr);
|
||||
trace_nfs_mkdir_exit(dir, dentry, PTR_ERR_OR_ZERO(ret));
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nfs_mkdir);
|
||||
|
||||
|
|
|
|||
|
|
@ -400,8 +400,8 @@ struct dentry *nfs_lookup(struct inode *, struct dentry *, unsigned int);
|
|||
void nfs_d_prune_case_insensitive_aliases(struct inode *inode);
|
||||
int nfs_create(struct mnt_idmap *, struct inode *, struct dentry *,
|
||||
umode_t, bool);
|
||||
int nfs_mkdir(struct mnt_idmap *, struct inode *, struct dentry *,
|
||||
umode_t);
|
||||
struct dentry *nfs_mkdir(struct mnt_idmap *, struct inode *, struct dentry *,
|
||||
umode_t);
|
||||
int nfs_rmdir(struct inode *, struct dentry *);
|
||||
int nfs_unlink(struct inode *, struct dentry *);
|
||||
int nfs_symlink(struct mnt_idmap *, struct inode *, struct dentry *,
|
||||
|
|
|
|||
|
|
@ -578,13 +578,13 @@ nfs3_proc_symlink(struct inode *dir, struct dentry *dentry, struct folio *folio,
|
|||
return status;
|
||||
}
|
||||
|
||||
static int
|
||||
static struct dentry *
|
||||
nfs3_proc_mkdir(struct inode *dir, struct dentry *dentry, struct iattr *sattr)
|
||||
{
|
||||
struct posix_acl *default_acl, *acl;
|
||||
struct nfs3_createdata *data;
|
||||
struct dentry *d_alias;
|
||||
int status = -ENOMEM;
|
||||
struct dentry *ret = ERR_PTR(-ENOMEM);
|
||||
int status;
|
||||
|
||||
dprintk("NFS call mkdir %pd\n", dentry);
|
||||
|
||||
|
|
@ -592,8 +592,9 @@ nfs3_proc_mkdir(struct inode *dir, struct dentry *dentry, struct iattr *sattr)
|
|||
if (data == NULL)
|
||||
goto out;
|
||||
|
||||
status = posix_acl_create(dir, &sattr->ia_mode, &default_acl, &acl);
|
||||
if (status)
|
||||
ret = ERR_PTR(posix_acl_create(dir, &sattr->ia_mode,
|
||||
&default_acl, &acl));
|
||||
if (IS_ERR(ret))
|
||||
goto out;
|
||||
|
||||
data->msg.rpc_proc = &nfs3_procedures[NFS3PROC_MKDIR];
|
||||
|
|
@ -602,25 +603,27 @@ nfs3_proc_mkdir(struct inode *dir, struct dentry *dentry, struct iattr *sattr)
|
|||
data->arg.mkdir.len = dentry->d_name.len;
|
||||
data->arg.mkdir.sattr = sattr;
|
||||
|
||||
d_alias = nfs3_do_create(dir, dentry, data);
|
||||
status = PTR_ERR_OR_ZERO(d_alias);
|
||||
ret = nfs3_do_create(dir, dentry, data);
|
||||
|
||||
if (status != 0)
|
||||
if (IS_ERR(ret))
|
||||
goto out_release_acls;
|
||||
|
||||
if (d_alias)
|
||||
dentry = d_alias;
|
||||
if (ret)
|
||||
dentry = ret;
|
||||
|
||||
status = nfs3_proc_setacls(d_inode(dentry), acl, default_acl);
|
||||
if (status) {
|
||||
dput(ret);
|
||||
ret = ERR_PTR(status);
|
||||
}
|
||||
|
||||
dput(d_alias);
|
||||
out_release_acls:
|
||||
posix_acl_release(acl);
|
||||
posix_acl_release(default_acl);
|
||||
out:
|
||||
nfs3_free_createdata(data);
|
||||
dprintk("NFS reply mkdir: %d\n", status);
|
||||
return status;
|
||||
dprintk("NFS reply mkdir: %d\n", PTR_ERR_OR_ZERO(ret));
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
|
|
|
|||
|
|
@ -5133,9 +5133,6 @@ static int nfs4_do_create(struct inode *dir, struct dentry *dentry, struct nfs4_
|
|||
&data->arg.seq_args, &data->res.seq_res, 1);
|
||||
if (status == 0) {
|
||||
spin_lock(&dir->i_lock);
|
||||
/* Creating a directory bumps nlink in the parent */
|
||||
if (data->arg.ftype == NF4DIR)
|
||||
nfs4_inc_nlink_locked(dir);
|
||||
nfs4_update_changeattr_locked(dir, &data->res.dir_cinfo,
|
||||
data->res.fattr->time_start,
|
||||
NFS_INO_INVALID_DATA);
|
||||
|
|
@ -5145,6 +5142,25 @@ static int nfs4_do_create(struct inode *dir, struct dentry *dentry, struct nfs4_
|
|||
return status;
|
||||
}
|
||||
|
||||
static struct dentry *nfs4_do_mkdir(struct inode *dir, struct dentry *dentry,
|
||||
struct nfs4_createdata *data)
|
||||
{
|
||||
int status = nfs4_call_sync(NFS_SERVER(dir)->client, NFS_SERVER(dir), &data->msg,
|
||||
&data->arg.seq_args, &data->res.seq_res, 1);
|
||||
|
||||
if (status)
|
||||
return ERR_PTR(status);
|
||||
|
||||
spin_lock(&dir->i_lock);
|
||||
/* Creating a directory bumps nlink in the parent */
|
||||
nfs4_inc_nlink_locked(dir);
|
||||
nfs4_update_changeattr_locked(dir, &data->res.dir_cinfo,
|
||||
data->res.fattr->time_start,
|
||||
NFS_INO_INVALID_DATA);
|
||||
spin_unlock(&dir->i_lock);
|
||||
return nfs_add_or_obtain(dentry, data->res.fh, data->res.fattr);
|
||||
}
|
||||
|
||||
static void nfs4_free_createdata(struct nfs4_createdata *data)
|
||||
{
|
||||
nfs4_label_free(data->fattr.label);
|
||||
|
|
@ -5201,32 +5217,34 @@ static int nfs4_proc_symlink(struct inode *dir, struct dentry *dentry,
|
|||
return err;
|
||||
}
|
||||
|
||||
static int _nfs4_proc_mkdir(struct inode *dir, struct dentry *dentry,
|
||||
struct iattr *sattr, struct nfs4_label *label)
|
||||
static struct dentry *_nfs4_proc_mkdir(struct inode *dir, struct dentry *dentry,
|
||||
struct iattr *sattr,
|
||||
struct nfs4_label *label)
|
||||
{
|
||||
struct nfs4_createdata *data;
|
||||
int status = -ENOMEM;
|
||||
struct dentry *ret = ERR_PTR(-ENOMEM);
|
||||
|
||||
data = nfs4_alloc_createdata(dir, &dentry->d_name, sattr, NF4DIR);
|
||||
if (data == NULL)
|
||||
goto out;
|
||||
|
||||
data->arg.label = label;
|
||||
status = nfs4_do_create(dir, dentry, data);
|
||||
ret = nfs4_do_mkdir(dir, dentry, data);
|
||||
|
||||
nfs4_free_createdata(data);
|
||||
out:
|
||||
return status;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int nfs4_proc_mkdir(struct inode *dir, struct dentry *dentry,
|
||||
struct iattr *sattr)
|
||||
static struct dentry *nfs4_proc_mkdir(struct inode *dir, struct dentry *dentry,
|
||||
struct iattr *sattr)
|
||||
{
|
||||
struct nfs_server *server = NFS_SERVER(dir);
|
||||
struct nfs4_exception exception = {
|
||||
.interruptible = true,
|
||||
};
|
||||
struct nfs4_label l, *label;
|
||||
struct dentry *alias;
|
||||
int err;
|
||||
|
||||
label = nfs4_label_init_security(dir, dentry, sattr, &l);
|
||||
|
|
@ -5234,14 +5252,15 @@ static int nfs4_proc_mkdir(struct inode *dir, struct dentry *dentry,
|
|||
if (!(server->attr_bitmask[2] & FATTR4_WORD2_MODE_UMASK))
|
||||
sattr->ia_mode &= ~current_umask();
|
||||
do {
|
||||
err = _nfs4_proc_mkdir(dir, dentry, sattr, label);
|
||||
alias = _nfs4_proc_mkdir(dir, dentry, sattr, label);
|
||||
err = PTR_ERR_OR_ZERO(alias);
|
||||
trace_nfs4_mkdir(dir, &dentry->d_name, err);
|
||||
err = nfs4_handle_exception(NFS_SERVER(dir), err,
|
||||
&exception);
|
||||
} while (exception.retry);
|
||||
nfs4_label_release_security(label);
|
||||
|
||||
return err;
|
||||
return alias;
|
||||
}
|
||||
|
||||
static int _nfs4_proc_readdir(struct nfs_readdir_arg *nr_arg,
|
||||
|
|
|
|||
|
|
@ -446,13 +446,14 @@ nfs_proc_symlink(struct inode *dir, struct dentry *dentry, struct folio *folio,
|
|||
return status;
|
||||
}
|
||||
|
||||
static int
|
||||
static struct dentry *
|
||||
nfs_proc_mkdir(struct inode *dir, struct dentry *dentry, struct iattr *sattr)
|
||||
{
|
||||
struct nfs_createdata *data;
|
||||
struct rpc_message msg = {
|
||||
.rpc_proc = &nfs_procedures[NFSPROC_MKDIR],
|
||||
};
|
||||
struct dentry *alias = NULL;
|
||||
int status = -ENOMEM;
|
||||
|
||||
dprintk("NFS call mkdir %pd\n", dentry);
|
||||
|
|
@ -464,12 +465,15 @@ nfs_proc_mkdir(struct inode *dir, struct dentry *dentry, struct iattr *sattr)
|
|||
|
||||
status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0);
|
||||
nfs_mark_for_revalidate(dir);
|
||||
if (status == 0)
|
||||
status = nfs_instantiate(dentry, data->res.fh, data->res.fattr);
|
||||
if (status == 0) {
|
||||
alias = nfs_add_or_obtain(dentry, data->res.fh, data->res.fattr);
|
||||
status = PTR_ERR_OR_ZERO(alias);
|
||||
} else
|
||||
alias = ERR_PTR(status);
|
||||
nfs_free_createdata(data);
|
||||
out:
|
||||
dprintk("NFS reply mkdir: %d\n", status);
|
||||
return status;
|
||||
return alias;
|
||||
}
|
||||
|
||||
static int
|
||||
|
|
|
|||
|
|
@ -233,9 +233,12 @@ nfsd4_create_clid_dir(struct nfs4_client *clp)
|
|||
* as well be forgiving and just succeed silently.
|
||||
*/
|
||||
goto out_put;
|
||||
status = vfs_mkdir(&nop_mnt_idmap, d_inode(dir), dentry, S_IRWXU);
|
||||
dentry = vfs_mkdir(&nop_mnt_idmap, d_inode(dir), dentry, S_IRWXU);
|
||||
if (IS_ERR(dentry))
|
||||
status = PTR_ERR(dentry);
|
||||
out_put:
|
||||
dput(dentry);
|
||||
if (!status)
|
||||
dput(dentry);
|
||||
out_unlock:
|
||||
inode_unlock(d_inode(dir));
|
||||
if (status == 0) {
|
||||
|
|
|
|||
|
|
@ -1461,7 +1461,7 @@ nfsd_create_locked(struct svc_rqst *rqstp, struct svc_fh *fhp,
|
|||
struct inode *dirp;
|
||||
struct iattr *iap = attrs->na_iattr;
|
||||
__be32 err;
|
||||
int host_err;
|
||||
int host_err = 0;
|
||||
|
||||
dentry = fhp->fh_dentry;
|
||||
dirp = d_inode(dentry);
|
||||
|
|
@ -1488,25 +1488,15 @@ nfsd_create_locked(struct svc_rqst *rqstp, struct svc_fh *fhp,
|
|||
nfsd_check_ignore_resizing(iap);
|
||||
break;
|
||||
case S_IFDIR:
|
||||
host_err = vfs_mkdir(&nop_mnt_idmap, dirp, dchild, iap->ia_mode);
|
||||
if (!host_err && unlikely(d_unhashed(dchild))) {
|
||||
struct dentry *d;
|
||||
d = lookup_one_len(dchild->d_name.name,
|
||||
dchild->d_parent,
|
||||
dchild->d_name.len);
|
||||
if (IS_ERR(d)) {
|
||||
host_err = PTR_ERR(d);
|
||||
break;
|
||||
}
|
||||
if (unlikely(d_is_negative(d))) {
|
||||
dput(d);
|
||||
err = nfserr_serverfault;
|
||||
goto out;
|
||||
}
|
||||
dchild = vfs_mkdir(&nop_mnt_idmap, dirp, dchild, iap->ia_mode);
|
||||
if (IS_ERR(dchild)) {
|
||||
host_err = PTR_ERR(dchild);
|
||||
} else if (d_is_negative(dchild)) {
|
||||
err = nfserr_serverfault;
|
||||
goto out;
|
||||
} else if (unlikely(dchild != resfhp->fh_dentry)) {
|
||||
dput(resfhp->fh_dentry);
|
||||
resfhp->fh_dentry = dget(d);
|
||||
dput(dchild);
|
||||
dchild = d;
|
||||
resfhp->fh_dentry = dget(dchild);
|
||||
}
|
||||
break;
|
||||
case S_IFCHR:
|
||||
|
|
@ -1527,7 +1517,8 @@ nfsd_create_locked(struct svc_rqst *rqstp, struct svc_fh *fhp,
|
|||
err = nfsd_create_setattr(rqstp, fhp, resfhp, attrs);
|
||||
|
||||
out:
|
||||
dput(dchild);
|
||||
if (!IS_ERR(dchild))
|
||||
dput(dchild);
|
||||
return err;
|
||||
|
||||
out_nfserr:
|
||||
|
|
|
|||
|
|
@ -218,8 +218,8 @@ static int nilfs_link(struct dentry *old_dentry, struct inode *dir,
|
|||
return err;
|
||||
}
|
||||
|
||||
static int nilfs_mkdir(struct mnt_idmap *idmap, struct inode *dir,
|
||||
struct dentry *dentry, umode_t mode)
|
||||
static struct dentry *nilfs_mkdir(struct mnt_idmap *idmap, struct inode *dir,
|
||||
struct dentry *dentry, umode_t mode)
|
||||
{
|
||||
struct inode *inode;
|
||||
struct nilfs_transaction_info ti;
|
||||
|
|
@ -227,7 +227,7 @@ static int nilfs_mkdir(struct mnt_idmap *idmap, struct inode *dir,
|
|||
|
||||
err = nilfs_transaction_begin(dir->i_sb, &ti, 1);
|
||||
if (err)
|
||||
return err;
|
||||
return ERR_PTR(err);
|
||||
|
||||
inc_nlink(dir);
|
||||
|
||||
|
|
@ -258,7 +258,7 @@ static int nilfs_mkdir(struct mnt_idmap *idmap, struct inode *dir,
|
|||
else
|
||||
nilfs_transaction_abort(dir->i_sb);
|
||||
|
||||
return err;
|
||||
return ERR_PTR(err);
|
||||
|
||||
out_fail:
|
||||
drop_nlink(inode);
|
||||
|
|
|
|||
|
|
@ -201,11 +201,11 @@ static int ntfs_symlink(struct mnt_idmap *idmap, struct inode *dir,
|
|||
/*
|
||||
* ntfs_mkdir- inode_operations::mkdir
|
||||
*/
|
||||
static int ntfs_mkdir(struct mnt_idmap *idmap, struct inode *dir,
|
||||
struct dentry *dentry, umode_t mode)
|
||||
static struct dentry *ntfs_mkdir(struct mnt_idmap *idmap, struct inode *dir,
|
||||
struct dentry *dentry, umode_t mode)
|
||||
{
|
||||
return ntfs_create_inode(idmap, dir, dentry, NULL, S_IFDIR | mode, 0,
|
||||
NULL, 0, NULL);
|
||||
return ERR_PTR(ntfs_create_inode(idmap, dir, dentry, NULL, S_IFDIR | mode, 0,
|
||||
NULL, 0, NULL));
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -402,10 +402,10 @@ static struct inode *dlmfs_get_inode(struct inode *parent,
|
|||
* File creation. Allocate an inode, and we're done..
|
||||
*/
|
||||
/* SMP-safe */
|
||||
static int dlmfs_mkdir(struct mnt_idmap * idmap,
|
||||
struct inode * dir,
|
||||
struct dentry * dentry,
|
||||
umode_t mode)
|
||||
static struct dentry *dlmfs_mkdir(struct mnt_idmap * idmap,
|
||||
struct inode * dir,
|
||||
struct dentry * dentry,
|
||||
umode_t mode)
|
||||
{
|
||||
int status;
|
||||
struct inode *inode = NULL;
|
||||
|
|
@ -448,7 +448,7 @@ static int dlmfs_mkdir(struct mnt_idmap * idmap,
|
|||
bail:
|
||||
if (status < 0)
|
||||
iput(inode);
|
||||
return status;
|
||||
return ERR_PTR(status);
|
||||
}
|
||||
|
||||
static int dlmfs_create(struct mnt_idmap *idmap,
|
||||
|
|
|
|||
|
|
@ -644,10 +644,10 @@ static int ocfs2_mknod_locked(struct ocfs2_super *osb,
|
|||
suballoc_loc, suballoc_bit);
|
||||
}
|
||||
|
||||
static int ocfs2_mkdir(struct mnt_idmap *idmap,
|
||||
struct inode *dir,
|
||||
struct dentry *dentry,
|
||||
umode_t mode)
|
||||
static struct dentry *ocfs2_mkdir(struct mnt_idmap *idmap,
|
||||
struct inode *dir,
|
||||
struct dentry *dentry,
|
||||
umode_t mode)
|
||||
{
|
||||
int ret;
|
||||
|
||||
|
|
@ -657,7 +657,7 @@ static int ocfs2_mkdir(struct mnt_idmap *idmap,
|
|||
if (ret)
|
||||
mlog_errno(ret);
|
||||
|
||||
return ret;
|
||||
return ERR_PTR(ret);
|
||||
}
|
||||
|
||||
static int ocfs2_create(struct mnt_idmap *idmap,
|
||||
|
|
|
|||
|
|
@ -279,10 +279,10 @@ static int omfs_add_node(struct inode *dir, struct dentry *dentry, umode_t mode)
|
|||
return err;
|
||||
}
|
||||
|
||||
static int omfs_mkdir(struct mnt_idmap *idmap, struct inode *dir,
|
||||
struct dentry *dentry, umode_t mode)
|
||||
static struct dentry *omfs_mkdir(struct mnt_idmap *idmap, struct inode *dir,
|
||||
struct dentry *dentry, umode_t mode)
|
||||
{
|
||||
return omfs_add_node(dir, dentry, mode | S_IFDIR);
|
||||
return ERR_PTR(omfs_add_node(dir, dentry, mode | S_IFDIR));
|
||||
}
|
||||
|
||||
static int omfs_create(struct mnt_idmap *idmap, struct inode *dir,
|
||||
|
|
|
|||
|
|
@ -300,8 +300,8 @@ static int orangefs_symlink(struct mnt_idmap *idmap,
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int orangefs_mkdir(struct mnt_idmap *idmap, struct inode *dir,
|
||||
struct dentry *dentry, umode_t mode)
|
||||
static struct dentry *orangefs_mkdir(struct mnt_idmap *idmap, struct inode *dir,
|
||||
struct dentry *dentry, umode_t mode)
|
||||
{
|
||||
struct orangefs_inode_s *parent = ORANGEFS_I(dir);
|
||||
struct orangefs_kernel_op_s *new_op;
|
||||
|
|
@ -312,7 +312,7 @@ static int orangefs_mkdir(struct mnt_idmap *idmap, struct inode *dir,
|
|||
|
||||
new_op = op_alloc(ORANGEFS_VFS_OP_MKDIR);
|
||||
if (!new_op)
|
||||
return -ENOMEM;
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
new_op->upcall.req.mkdir.parent_refn = parent->refn;
|
||||
|
||||
|
|
@ -366,7 +366,7 @@ static int orangefs_mkdir(struct mnt_idmap *idmap, struct inode *dir,
|
|||
__orangefs_setattr(dir, &iattr);
|
||||
out:
|
||||
op_release(new_op);
|
||||
return ret;
|
||||
return ERR_PTR(ret);
|
||||
}
|
||||
|
||||
static int orangefs_rename(struct mnt_idmap *idmap,
|
||||
|
|
|
|||
|
|
@ -138,37 +138,6 @@ int ovl_cleanup_and_whiteout(struct ovl_fs *ofs, struct inode *dir,
|
|||
goto out;
|
||||
}
|
||||
|
||||
int ovl_mkdir_real(struct ovl_fs *ofs, struct inode *dir,
|
||||
struct dentry **newdentry, umode_t mode)
|
||||
{
|
||||
int err;
|
||||
struct dentry *d, *dentry = *newdentry;
|
||||
|
||||
err = ovl_do_mkdir(ofs, dir, dentry, mode);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
if (likely(!d_unhashed(dentry)))
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* vfs_mkdir() may succeed and leave the dentry passed
|
||||
* to it unhashed and negative. If that happens, try to
|
||||
* lookup a new hashed and positive dentry.
|
||||
*/
|
||||
d = ovl_lookup_upper(ofs, dentry->d_name.name, dentry->d_parent,
|
||||
dentry->d_name.len);
|
||||
if (IS_ERR(d)) {
|
||||
pr_warn("failed lookup after mkdir (%pd2, err=%i).\n",
|
||||
dentry, err);
|
||||
return PTR_ERR(d);
|
||||
}
|
||||
dput(dentry);
|
||||
*newdentry = d;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct dentry *ovl_create_real(struct ovl_fs *ofs, struct inode *dir,
|
||||
struct dentry *newdentry, struct ovl_cattr *attr)
|
||||
{
|
||||
|
|
@ -191,7 +160,8 @@ struct dentry *ovl_create_real(struct ovl_fs *ofs, struct inode *dir,
|
|||
|
||||
case S_IFDIR:
|
||||
/* mkdir is special... */
|
||||
err = ovl_mkdir_real(ofs, dir, &newdentry, attr->mode);
|
||||
newdentry = ovl_do_mkdir(ofs, dir, newdentry, attr->mode);
|
||||
err = PTR_ERR_OR_ZERO(newdentry);
|
||||
break;
|
||||
|
||||
case S_IFCHR:
|
||||
|
|
@ -219,7 +189,8 @@ struct dentry *ovl_create_real(struct ovl_fs *ofs, struct inode *dir,
|
|||
}
|
||||
out:
|
||||
if (err) {
|
||||
dput(newdentry);
|
||||
if (!IS_ERR(newdentry))
|
||||
dput(newdentry);
|
||||
return ERR_PTR(err);
|
||||
}
|
||||
return newdentry;
|
||||
|
|
@ -282,7 +253,8 @@ static int ovl_instantiate(struct dentry *dentry, struct inode *inode,
|
|||
* XXX: if we ever use ovl_obtain_alias() to decode directory
|
||||
* file handles, need to use ovl_get_inode_locked() and
|
||||
* d_instantiate_new() here to prevent from creating two
|
||||
* hashed directory inode aliases.
|
||||
* hashed directory inode aliases. We then need to return
|
||||
* the obtained alias to ovl_mkdir().
|
||||
*/
|
||||
inode = ovl_get_inode(dentry->d_sb, &oip);
|
||||
if (IS_ERR(inode))
|
||||
|
|
@ -687,10 +659,10 @@ static int ovl_create(struct mnt_idmap *idmap, struct inode *dir,
|
|||
return ovl_create_object(dentry, (mode & 07777) | S_IFREG, 0, NULL);
|
||||
}
|
||||
|
||||
static int ovl_mkdir(struct mnt_idmap *idmap, struct inode *dir,
|
||||
struct dentry *dentry, umode_t mode)
|
||||
static struct dentry *ovl_mkdir(struct mnt_idmap *idmap, struct inode *dir,
|
||||
struct dentry *dentry, umode_t mode)
|
||||
{
|
||||
return ovl_create_object(dentry, (mode & 07777) | S_IFDIR, 0, NULL);
|
||||
return ERR_PTR(ovl_create_object(dentry, (mode & 07777) | S_IFDIR, 0, NULL));
|
||||
}
|
||||
|
||||
static int ovl_mknod(struct mnt_idmap *idmap, struct inode *dir,
|
||||
|
|
|
|||
|
|
@ -241,13 +241,14 @@ static inline int ovl_do_create(struct ovl_fs *ofs,
|
|||
return err;
|
||||
}
|
||||
|
||||
static inline int ovl_do_mkdir(struct ovl_fs *ofs,
|
||||
struct inode *dir, struct dentry *dentry,
|
||||
umode_t mode)
|
||||
static inline struct dentry *ovl_do_mkdir(struct ovl_fs *ofs,
|
||||
struct inode *dir,
|
||||
struct dentry *dentry,
|
||||
umode_t mode)
|
||||
{
|
||||
int err = vfs_mkdir(ovl_upper_mnt_idmap(ofs), dir, dentry, mode);
|
||||
pr_debug("mkdir(%pd2, 0%o) = %i\n", dentry, mode, err);
|
||||
return err;
|
||||
dentry = vfs_mkdir(ovl_upper_mnt_idmap(ofs), dir, dentry, mode);
|
||||
pr_debug("mkdir(%pd2, 0%o) = %i\n", dentry, mode, PTR_ERR_OR_ZERO(dentry));
|
||||
return dentry;
|
||||
}
|
||||
|
||||
static inline int ovl_do_mknod(struct ovl_fs *ofs,
|
||||
|
|
@ -838,8 +839,6 @@ struct ovl_cattr {
|
|||
|
||||
#define OVL_CATTR(m) (&(struct ovl_cattr) { .mode = (m) })
|
||||
|
||||
int ovl_mkdir_real(struct ovl_fs *ofs, struct inode *dir,
|
||||
struct dentry **newdentry, umode_t mode);
|
||||
struct dentry *ovl_create_real(struct ovl_fs *ofs,
|
||||
struct inode *dir, struct dentry *newdentry,
|
||||
struct ovl_cattr *attr);
|
||||
|
|
|
|||
|
|
@ -327,9 +327,10 @@ static struct dentry *ovl_workdir_create(struct ovl_fs *ofs,
|
|||
goto retry;
|
||||
}
|
||||
|
||||
err = ovl_mkdir_real(ofs, dir, &work, attr.ia_mode);
|
||||
if (err)
|
||||
goto out_dput;
|
||||
work = ovl_do_mkdir(ofs, dir, work, attr.ia_mode);
|
||||
err = PTR_ERR(work);
|
||||
if (IS_ERR(work))
|
||||
goto out_err;
|
||||
|
||||
/* Weird filesystem returning with hashed negative (kernfs)? */
|
||||
err = -EINVAL;
|
||||
|
|
|
|||
|
|
@ -119,13 +119,13 @@ ramfs_mknod(struct mnt_idmap *idmap, struct inode *dir,
|
|||
return error;
|
||||
}
|
||||
|
||||
static int ramfs_mkdir(struct mnt_idmap *idmap, struct inode *dir,
|
||||
struct dentry *dentry, umode_t mode)
|
||||
static struct dentry *ramfs_mkdir(struct mnt_idmap *idmap, struct inode *dir,
|
||||
struct dentry *dentry, umode_t mode)
|
||||
{
|
||||
int retval = ramfs_mknod(&nop_mnt_idmap, dir, dentry, mode | S_IFDIR, 0);
|
||||
if (!retval)
|
||||
inc_nlink(dir);
|
||||
return retval;
|
||||
return ERR_PTR(retval);
|
||||
}
|
||||
|
||||
static int ramfs_create(struct mnt_idmap *idmap, struct inode *dir,
|
||||
|
|
|
|||
|
|
@ -59,8 +59,8 @@ extern int cifs_unlink(struct inode *dir, struct dentry *dentry);
|
|||
extern int cifs_hardlink(struct dentry *, struct inode *, struct dentry *);
|
||||
extern int cifs_mknod(struct mnt_idmap *, struct inode *, struct dentry *,
|
||||
umode_t, dev_t);
|
||||
extern int cifs_mkdir(struct mnt_idmap *, struct inode *, struct dentry *,
|
||||
umode_t);
|
||||
extern struct dentry *cifs_mkdir(struct mnt_idmap *, struct inode *, struct dentry *,
|
||||
umode_t);
|
||||
extern int cifs_rmdir(struct inode *, struct dentry *);
|
||||
extern int cifs_rename2(struct mnt_idmap *, struct inode *,
|
||||
struct dentry *, struct inode *, struct dentry *,
|
||||
|
|
|
|||
|
|
@ -2207,8 +2207,8 @@ cifs_posix_mkdir(struct inode *inode, struct dentry *dentry, umode_t mode,
|
|||
}
|
||||
#endif /* CONFIG_CIFS_ALLOW_INSECURE_LEGACY */
|
||||
|
||||
int cifs_mkdir(struct mnt_idmap *idmap, struct inode *inode,
|
||||
struct dentry *direntry, umode_t mode)
|
||||
struct dentry *cifs_mkdir(struct mnt_idmap *idmap, struct inode *inode,
|
||||
struct dentry *direntry, umode_t mode)
|
||||
{
|
||||
int rc = 0;
|
||||
unsigned int xid;
|
||||
|
|
@ -2224,10 +2224,10 @@ int cifs_mkdir(struct mnt_idmap *idmap, struct inode *inode,
|
|||
|
||||
cifs_sb = CIFS_SB(inode->i_sb);
|
||||
if (unlikely(cifs_forced_shutdown(cifs_sb)))
|
||||
return -EIO;
|
||||
return ERR_PTR(-EIO);
|
||||
tlink = cifs_sb_tlink(cifs_sb);
|
||||
if (IS_ERR(tlink))
|
||||
return PTR_ERR(tlink);
|
||||
return ERR_CAST(tlink);
|
||||
tcon = tlink_tcon(tlink);
|
||||
|
||||
xid = get_xid();
|
||||
|
|
@ -2283,7 +2283,7 @@ int cifs_mkdir(struct mnt_idmap *idmap, struct inode *inode,
|
|||
free_dentry_path(page);
|
||||
free_xid(xid);
|
||||
cifs_put_tlink(tlink);
|
||||
return rc;
|
||||
return ERR_PTR(rc);
|
||||
}
|
||||
|
||||
int cifs_rmdir(struct inode *inode, struct dentry *direntry)
|
||||
|
|
|
|||
|
|
@ -206,8 +206,8 @@ int ksmbd_vfs_mkdir(struct ksmbd_work *work, const char *name, umode_t mode)
|
|||
{
|
||||
struct mnt_idmap *idmap;
|
||||
struct path path;
|
||||
struct dentry *dentry;
|
||||
int err;
|
||||
struct dentry *dentry, *d;
|
||||
int err = 0;
|
||||
|
||||
dentry = ksmbd_vfs_kern_path_create(work, name,
|
||||
LOOKUP_NO_SYMLINKS | LOOKUP_DIRECTORY,
|
||||
|
|
@ -222,27 +222,15 @@ int ksmbd_vfs_mkdir(struct ksmbd_work *work, const char *name, umode_t mode)
|
|||
|
||||
idmap = mnt_idmap(path.mnt);
|
||||
mode |= S_IFDIR;
|
||||
err = vfs_mkdir(idmap, d_inode(path.dentry), dentry, mode);
|
||||
if (!err && d_unhashed(dentry)) {
|
||||
struct dentry *d;
|
||||
d = dentry;
|
||||
dentry = vfs_mkdir(idmap, d_inode(path.dentry), dentry, mode);
|
||||
if (IS_ERR(dentry))
|
||||
err = PTR_ERR(dentry);
|
||||
else if (d_is_negative(dentry))
|
||||
err = -ENOENT;
|
||||
if (!err && dentry != d)
|
||||
ksmbd_vfs_inherit_owner(work, d_inode(path.dentry), d_inode(dentry));
|
||||
|
||||
d = lookup_one(idmap, dentry->d_name.name, dentry->d_parent,
|
||||
dentry->d_name.len);
|
||||
if (IS_ERR(d)) {
|
||||
err = PTR_ERR(d);
|
||||
goto out_err;
|
||||
}
|
||||
if (unlikely(d_is_negative(d))) {
|
||||
dput(d);
|
||||
err = -ENOENT;
|
||||
goto out_err;
|
||||
}
|
||||
|
||||
ksmbd_vfs_inherit_owner(work, d_inode(path.dentry), d_inode(d));
|
||||
dput(d);
|
||||
}
|
||||
|
||||
out_err:
|
||||
done_path_create(&path, dentry);
|
||||
if (err)
|
||||
pr_err("mkdir(%s): creation failed (err:%d)\n", name, err);
|
||||
|
|
|
|||
|
|
@ -110,8 +110,8 @@ static int sysv_link(struct dentry * old_dentry, struct inode * dir,
|
|||
return add_nondir(dentry, inode);
|
||||
}
|
||||
|
||||
static int sysv_mkdir(struct mnt_idmap *idmap, struct inode *dir,
|
||||
struct dentry *dentry, umode_t mode)
|
||||
static struct dentry *sysv_mkdir(struct mnt_idmap *idmap, struct inode *dir,
|
||||
struct dentry *dentry, umode_t mode)
|
||||
{
|
||||
struct inode * inode;
|
||||
int err;
|
||||
|
|
@ -137,7 +137,7 @@ static int sysv_mkdir(struct mnt_idmap *idmap, struct inode *dir,
|
|||
|
||||
d_instantiate(dentry, inode);
|
||||
out:
|
||||
return err;
|
||||
return ERR_PTR(err);
|
||||
|
||||
out_fail:
|
||||
inode_dec_link_count(inode);
|
||||
|
|
|
|||
|
|
@ -109,9 +109,9 @@ static char *get_dname(struct dentry *dentry)
|
|||
return name;
|
||||
}
|
||||
|
||||
static int tracefs_syscall_mkdir(struct mnt_idmap *idmap,
|
||||
struct inode *inode, struct dentry *dentry,
|
||||
umode_t mode)
|
||||
static struct dentry *tracefs_syscall_mkdir(struct mnt_idmap *idmap,
|
||||
struct inode *inode, struct dentry *dentry,
|
||||
umode_t mode)
|
||||
{
|
||||
struct tracefs_inode *ti;
|
||||
char *name;
|
||||
|
|
@ -119,7 +119,7 @@ static int tracefs_syscall_mkdir(struct mnt_idmap *idmap,
|
|||
|
||||
name = get_dname(dentry);
|
||||
if (!name)
|
||||
return -ENOMEM;
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
/*
|
||||
* This is a new directory that does not take the default of
|
||||
|
|
@ -141,7 +141,7 @@ static int tracefs_syscall_mkdir(struct mnt_idmap *idmap,
|
|||
|
||||
kfree(name);
|
||||
|
||||
return ret;
|
||||
return ERR_PTR(ret);
|
||||
}
|
||||
|
||||
static int tracefs_syscall_rmdir(struct inode *inode, struct dentry *dentry)
|
||||
|
|
|
|||
|
|
@ -1002,8 +1002,8 @@ static int ubifs_rmdir(struct inode *dir, struct dentry *dentry)
|
|||
return err;
|
||||
}
|
||||
|
||||
static int ubifs_mkdir(struct mnt_idmap *idmap, struct inode *dir,
|
||||
struct dentry *dentry, umode_t mode)
|
||||
static struct dentry *ubifs_mkdir(struct mnt_idmap *idmap, struct inode *dir,
|
||||
struct dentry *dentry, umode_t mode)
|
||||
{
|
||||
struct inode *inode;
|
||||
struct ubifs_inode *dir_ui = ubifs_inode(dir);
|
||||
|
|
@ -1023,7 +1023,7 @@ static int ubifs_mkdir(struct mnt_idmap *idmap, struct inode *dir,
|
|||
|
||||
err = ubifs_budget_space(c, &req);
|
||||
if (err)
|
||||
return err;
|
||||
return ERR_PTR(err);
|
||||
|
||||
err = ubifs_prepare_create(dir, dentry, &nm);
|
||||
if (err)
|
||||
|
|
@ -1060,7 +1060,7 @@ static int ubifs_mkdir(struct mnt_idmap *idmap, struct inode *dir,
|
|||
ubifs_release_budget(c, &req);
|
||||
d_instantiate(dentry, inode);
|
||||
fscrypt_free_filename(&nm);
|
||||
return 0;
|
||||
return NULL;
|
||||
|
||||
out_cancel:
|
||||
dir->i_size -= sz_change;
|
||||
|
|
@ -1074,7 +1074,7 @@ static int ubifs_mkdir(struct mnt_idmap *idmap, struct inode *dir,
|
|||
fscrypt_free_filename(&nm);
|
||||
out_budg:
|
||||
ubifs_release_budget(c, &req);
|
||||
return err;
|
||||
return ERR_PTR(err);
|
||||
}
|
||||
|
||||
static int ubifs_mknod(struct mnt_idmap *idmap, struct inode *dir,
|
||||
|
|
|
|||
|
|
@ -419,8 +419,8 @@ static int udf_mknod(struct mnt_idmap *idmap, struct inode *dir,
|
|||
return udf_add_nondir(dentry, inode);
|
||||
}
|
||||
|
||||
static int udf_mkdir(struct mnt_idmap *idmap, struct inode *dir,
|
||||
struct dentry *dentry, umode_t mode)
|
||||
static struct dentry *udf_mkdir(struct mnt_idmap *idmap, struct inode *dir,
|
||||
struct dentry *dentry, umode_t mode)
|
||||
{
|
||||
struct inode *inode;
|
||||
struct udf_fileident_iter iter;
|
||||
|
|
@ -430,7 +430,7 @@ static int udf_mkdir(struct mnt_idmap *idmap, struct inode *dir,
|
|||
|
||||
inode = udf_new_inode(dir, S_IFDIR | mode);
|
||||
if (IS_ERR(inode))
|
||||
return PTR_ERR(inode);
|
||||
return ERR_CAST(inode);
|
||||
|
||||
iinfo = UDF_I(inode);
|
||||
inode->i_op = &udf_dir_inode_operations;
|
||||
|
|
@ -439,7 +439,7 @@ static int udf_mkdir(struct mnt_idmap *idmap, struct inode *dir,
|
|||
if (err) {
|
||||
clear_nlink(inode);
|
||||
discard_new_inode(inode);
|
||||
return err;
|
||||
return ERR_PTR(err);
|
||||
}
|
||||
set_nlink(inode, 2);
|
||||
iter.fi.icb.extLength = cpu_to_le32(inode->i_sb->s_blocksize);
|
||||
|
|
@ -456,7 +456,7 @@ static int udf_mkdir(struct mnt_idmap *idmap, struct inode *dir,
|
|||
if (err) {
|
||||
clear_nlink(inode);
|
||||
discard_new_inode(inode);
|
||||
return err;
|
||||
return ERR_PTR(err);
|
||||
}
|
||||
iter.fi.icb.extLength = cpu_to_le32(inode->i_sb->s_blocksize);
|
||||
iter.fi.icb.extLocation = cpu_to_lelb(iinfo->i_location);
|
||||
|
|
@ -471,7 +471,7 @@ static int udf_mkdir(struct mnt_idmap *idmap, struct inode *dir,
|
|||
mark_inode_dirty(dir);
|
||||
d_instantiate_new(dentry, inode);
|
||||
|
||||
return 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int empty_dir(struct inode *dir)
|
||||
|
|
|
|||
|
|
@ -166,8 +166,8 @@ static int ufs_link (struct dentry * old_dentry, struct inode * dir,
|
|||
return error;
|
||||
}
|
||||
|
||||
static int ufs_mkdir(struct mnt_idmap * idmap, struct inode * dir,
|
||||
struct dentry * dentry, umode_t mode)
|
||||
static struct dentry *ufs_mkdir(struct mnt_idmap * idmap, struct inode * dir,
|
||||
struct dentry * dentry, umode_t mode)
|
||||
{
|
||||
struct inode * inode;
|
||||
int err;
|
||||
|
|
@ -194,7 +194,7 @@ static int ufs_mkdir(struct mnt_idmap * idmap, struct inode * dir,
|
|||
goto out_fail;
|
||||
|
||||
d_instantiate_new(dentry, inode);
|
||||
return 0;
|
||||
return NULL;
|
||||
|
||||
out_fail:
|
||||
inode_dec_link_count(inode);
|
||||
|
|
@ -202,7 +202,7 @@ static int ufs_mkdir(struct mnt_idmap * idmap, struct inode * dir,
|
|||
discard_new_inode(inode);
|
||||
out_dir:
|
||||
inode_dec_link_count(dir);
|
||||
return err;
|
||||
return ERR_PTR(err);
|
||||
}
|
||||
|
||||
static int ufs_unlink(struct inode *dir, struct dentry *dentry)
|
||||
|
|
|
|||
|
|
@ -303,11 +303,11 @@ static int vboxsf_dir_mkfile(struct mnt_idmap *idmap,
|
|||
return vboxsf_dir_create(parent, dentry, mode, false, excl, NULL);
|
||||
}
|
||||
|
||||
static int vboxsf_dir_mkdir(struct mnt_idmap *idmap,
|
||||
struct inode *parent, struct dentry *dentry,
|
||||
umode_t mode)
|
||||
static struct dentry *vboxsf_dir_mkdir(struct mnt_idmap *idmap,
|
||||
struct inode *parent, struct dentry *dentry,
|
||||
umode_t mode)
|
||||
{
|
||||
return vboxsf_dir_create(parent, dentry, mode, true, true, NULL);
|
||||
return ERR_PTR(vboxsf_dir_create(parent, dentry, mode, true, true, NULL));
|
||||
}
|
||||
|
||||
static int vboxsf_dir_atomic_open(struct inode *parent, struct dentry *dentry,
|
||||
|
|
|
|||
|
|
@ -167,10 +167,11 @@ xrep_orphanage_create(
|
|||
* directory to control access to a file we put in here.
|
||||
*/
|
||||
if (d_really_is_negative(orphanage_dentry)) {
|
||||
error = vfs_mkdir(&nop_mnt_idmap, root_inode, orphanage_dentry,
|
||||
0750);
|
||||
if (error)
|
||||
goto out_dput_orphanage;
|
||||
orphanage_dentry = vfs_mkdir(&nop_mnt_idmap, root_inode,
|
||||
orphanage_dentry, 0750);
|
||||
error = PTR_ERR(orphanage_dentry);
|
||||
if (IS_ERR(orphanage_dentry))
|
||||
goto out_unlock_root;
|
||||
}
|
||||
|
||||
/* Not a directory? Bail out. */
|
||||
|
|
|
|||
|
|
@ -298,14 +298,14 @@ xfs_vn_create(
|
|||
return xfs_generic_create(idmap, dir, dentry, mode, 0, NULL);
|
||||
}
|
||||
|
||||
STATIC int
|
||||
STATIC struct dentry *
|
||||
xfs_vn_mkdir(
|
||||
struct mnt_idmap *idmap,
|
||||
struct inode *dir,
|
||||
struct dentry *dentry,
|
||||
umode_t mode)
|
||||
{
|
||||
return xfs_generic_create(idmap, dir, dentry, mode | S_IFDIR, 0, NULL);
|
||||
return ERR_PTR(xfs_generic_create(idmap, dir, dentry, mode | S_IFDIR, 0, NULL));
|
||||
}
|
||||
|
||||
STATIC struct dentry *
|
||||
|
|
|
|||
|
|
@ -1981,8 +1981,8 @@ bool inode_owner_or_capable(struct mnt_idmap *idmap,
|
|||
*/
|
||||
int vfs_create(struct mnt_idmap *, struct inode *,
|
||||
struct dentry *, umode_t, bool);
|
||||
int vfs_mkdir(struct mnt_idmap *, struct inode *,
|
||||
struct dentry *, umode_t);
|
||||
struct dentry *vfs_mkdir(struct mnt_idmap *, struct inode *,
|
||||
struct dentry *, umode_t);
|
||||
int vfs_mknod(struct mnt_idmap *, struct inode *, struct dentry *,
|
||||
umode_t, dev_t);
|
||||
int vfs_symlink(struct mnt_idmap *, struct inode *,
|
||||
|
|
@ -2211,8 +2211,8 @@ struct inode_operations {
|
|||
int (*unlink) (struct inode *,struct dentry *);
|
||||
int (*symlink) (struct mnt_idmap *, struct inode *,struct dentry *,
|
||||
const char *);
|
||||
int (*mkdir) (struct mnt_idmap *, struct inode *,struct dentry *,
|
||||
umode_t);
|
||||
struct dentry *(*mkdir) (struct mnt_idmap *, struct inode *,
|
||||
struct dentry *, umode_t);
|
||||
int (*rmdir) (struct inode *,struct dentry *);
|
||||
int (*mknod) (struct mnt_idmap *, struct inode *,struct dentry *,
|
||||
umode_t,dev_t);
|
||||
|
|
|
|||
|
|
@ -1802,7 +1802,7 @@ struct nfs_rpc_ops {
|
|||
int (*link) (struct inode *, struct inode *, const struct qstr *);
|
||||
int (*symlink) (struct inode *, struct dentry *, struct folio *,
|
||||
unsigned int, struct iattr *);
|
||||
int (*mkdir) (struct inode *, struct dentry *, struct iattr *);
|
||||
struct dentry *(*mkdir) (struct inode *, struct dentry *, struct iattr *);
|
||||
int (*rmdir) (struct inode *, const struct qstr *);
|
||||
int (*readdir) (struct nfs_readdir_arg *, struct nfs_readdir_res *);
|
||||
int (*mknod) (struct inode *, struct dentry *, struct iattr *,
|
||||
|
|
|
|||
|
|
@ -150,14 +150,14 @@ static void bpf_dentry_finalize(struct dentry *dentry, struct inode *inode,
|
|||
inode_set_mtime_to_ts(dir, inode_set_ctime_current(dir));
|
||||
}
|
||||
|
||||
static int bpf_mkdir(struct mnt_idmap *idmap, struct inode *dir,
|
||||
struct dentry *dentry, umode_t mode)
|
||||
static struct dentry *bpf_mkdir(struct mnt_idmap *idmap, struct inode *dir,
|
||||
struct dentry *dentry, umode_t mode)
|
||||
{
|
||||
struct inode *inode;
|
||||
|
||||
inode = bpf_get_inode(dir->i_sb, dir, mode | S_IFDIR);
|
||||
if (IS_ERR(inode))
|
||||
return PTR_ERR(inode);
|
||||
return ERR_CAST(inode);
|
||||
|
||||
inode->i_op = &bpf_dir_iops;
|
||||
inode->i_fop = &simple_dir_operations;
|
||||
|
|
@ -166,7 +166,7 @@ static int bpf_mkdir(struct mnt_idmap *idmap, struct inode *dir,
|
|||
inc_nlink(dir);
|
||||
|
||||
bpf_dentry_finalize(dentry, inode, dir);
|
||||
return 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct map_iter {
|
||||
|
|
|
|||
|
|
@ -3889,16 +3889,16 @@ shmem_tmpfile(struct mnt_idmap *idmap, struct inode *dir,
|
|||
return error;
|
||||
}
|
||||
|
||||
static int shmem_mkdir(struct mnt_idmap *idmap, struct inode *dir,
|
||||
struct dentry *dentry, umode_t mode)
|
||||
static struct dentry *shmem_mkdir(struct mnt_idmap *idmap, struct inode *dir,
|
||||
struct dentry *dentry, umode_t mode)
|
||||
{
|
||||
int error;
|
||||
|
||||
error = shmem_mknod(idmap, dir, dentry, mode | S_IFDIR, 0);
|
||||
if (error)
|
||||
return error;
|
||||
return ERR_PTR(error);
|
||||
inc_nlink(dir);
|
||||
return 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int shmem_create(struct mnt_idmap *idmap, struct inode *dir,
|
||||
|
|
|
|||
|
|
@ -1795,8 +1795,8 @@ int __aafs_profile_mkdir(struct aa_profile *profile, struct dentry *parent)
|
|||
return error;
|
||||
}
|
||||
|
||||
static int ns_mkdir_op(struct mnt_idmap *idmap, struct inode *dir,
|
||||
struct dentry *dentry, umode_t mode)
|
||||
static struct dentry *ns_mkdir_op(struct mnt_idmap *idmap, struct inode *dir,
|
||||
struct dentry *dentry, umode_t mode)
|
||||
{
|
||||
struct aa_ns *ns, *parent;
|
||||
/* TODO: improve permission check */
|
||||
|
|
@ -1808,7 +1808,7 @@ static int ns_mkdir_op(struct mnt_idmap *idmap, struct inode *dir,
|
|||
AA_MAY_LOAD_POLICY);
|
||||
end_current_label_crit_section(label);
|
||||
if (error)
|
||||
return error;
|
||||
return ERR_PTR(error);
|
||||
|
||||
parent = aa_get_ns(dir->i_private);
|
||||
AA_BUG(d_inode(ns_subns_dir(parent)) != dir);
|
||||
|
|
@ -1843,7 +1843,7 @@ static int ns_mkdir_op(struct mnt_idmap *idmap, struct inode *dir,
|
|||
mutex_unlock(&parent->lock);
|
||||
aa_put_ns(parent);
|
||||
|
||||
return error;
|
||||
return ERR_PTR(error);
|
||||
}
|
||||
|
||||
static int ns_rmdir_op(struct inode *dir, struct dentry *dentry)
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user