本文整理汇总了C++中dget函数的典型用法代码示例。如果您正苦于以下问题:C++ dget函数的具体用法?C++ dget怎么用?C++ dget使用的例子?那么恭喜您, 这里精选的函数代码示例或许可以为您提供帮助。
在下文中一共展示了dget函数的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: lock_hdir_lkup_wh
//.........这里部分代码省略.........
struct dentry *h_src_dentry;
struct mutex *h_mtx;
struct file *h_file;
di_read_lock_parent(a->src_parent, AuLock_IR);
err = au_test_and_cpup_dirs(src_dentry, a->bdst);
if (unlikely(err))
goto out;
h_src_dentry = au_h_dptr(src_dentry, a->bsrc);
h_mtx = &h_src_dentry->d_inode->i_mutex;
err = au_pin(&a->pin, src_dentry, a->bdst,
au_opt_udba(src_dentry->d_sb),
AuPin_DI_LOCKED | AuPin_MNT_WRITE);
if (unlikely(err))
goto out;
mutex_lock_nested(h_mtx, AuLsc_I_CHILD);
h_file = au_h_open_pre(src_dentry, a->bsrc);
if (IS_ERR(h_file)) {
err = PTR_ERR(h_file);
h_file = NULL;
} else
err = au_sio_cpup_simple(src_dentry, a->bdst, a->bsrc,
AuCpup_DTIME /* | AuCpup_KEEPLINO */);
mutex_unlock(h_mtx);
au_h_open_post(src_dentry, a->bsrc, h_file);
au_unpin(&a->pin);
out:
di_read_unlock(a->src_parent, AuLock_IR);
return err;
}
static int au_cpup_or_link(struct dentry *src_dentry, struct au_link_args *a)
{
int err;
unsigned char plink;
struct inode *h_inode, *inode;
struct dentry *h_src_dentry;
struct super_block *sb;
struct file *h_file;
plink = 0;
h_inode = NULL;
sb = src_dentry->d_sb;
inode = src_dentry->d_inode;
if (au_ibstart(inode) <= a->bdst)
h_inode = au_h_iptr(inode, a->bdst);
if (!h_inode || !h_inode->i_nlink) {
/* copyup src_dentry as the name of dentry. */
au_set_dbstart(src_dentry, a->bdst);
au_set_h_dptr(src_dentry, a->bdst, dget(a->h_path.dentry));
h_inode = au_h_dptr(src_dentry, a->bsrc)->d_inode;
mutex_lock_nested(&h_inode->i_mutex, AuLsc_I_CHILD);
h_file = au_h_open_pre(src_dentry, a->bsrc);
if (IS_ERR(h_file)) {
err = PTR_ERR(h_file);
h_file = NULL;
} else
err = au_sio_cpup_single(src_dentry, a->bdst, a->bsrc,
-1, AuCpup_KEEPLINO,
a->parent);
mutex_unlock(&h_inode->i_mutex);
au_h_open_post(src_dentry, a->bsrc, h_file);
au_set_h_dptr(src_dentry, a->bdst, NULL);
au_set_dbstart(src_dentry, a->bsrc);
} else {
/* the inode of src_dentry already exists on a.bdst branch */
h_src_dentry = d_find_alias(h_inode);
if (!h_src_dentry && au_plink_test(inode)) {
plink = 1;
h_src_dentry = au_plink_lkup(inode, a->bdst);
err = PTR_ERR(h_src_dentry);
if (IS_ERR(h_src_dentry))
goto out;
if (unlikely(!h_src_dentry->d_inode)) {
dput(h_src_dentry);
h_src_dentry = NULL;
}
}
if (h_src_dentry) {
err = vfsub_link(h_src_dentry, au_pinned_h_dir(&a->pin),
&a->h_path);
dput(h_src_dentry);
} else {
AuIOErr("no dentry found for hi%lu on b%d\n",
h_inode->i_ino, a->bdst);
err = -EIO;
}
}
if (!err && !plink)
au_plink_append(inode, a->bdst, a->h_path.dentry);
out:
AuTraceErr(err);
return err;
}
示例2: nfsd_lookup_dentry
__be32
nfsd_lookup_dentry(struct svc_rqst *rqstp, struct svc_fh *fhp,
const char *name, unsigned int len,
struct svc_export **exp_ret, struct dentry **dentry_ret)
{
struct svc_export *exp;
struct dentry *dparent;
struct dentry *dentry;
__be32 err;
int host_err;
dprintk("nfsd: nfsd_lookup(fh %s, %.*s)\n", SVCFH_fmt(fhp), len,name);
/* Obtain dentry and export. */
err = fh_verify(rqstp, fhp, S_IFDIR, MAY_EXEC);
if (err)
return err;
dparent = fhp->fh_dentry;
exp = fhp->fh_export;
exp_get(exp);
/* Lookup the name, but don't follow links */
if (isdotent(name, len)) {
if (len==1)
dentry = dget(dparent);
else if (dparent != exp->ex_path.dentry)
dentry = dget_parent(dparent);
else if (!EX_NOHIDE(exp))
dentry = dget(dparent); /* .. == . just like at / */
else {
/* checking mountpoint crossing is very different when stepping up */
struct svc_export *exp2 = NULL;
struct dentry *dp;
struct vfsmount *mnt = mntget(exp->ex_path.mnt);
dentry = dget(dparent);
while(dentry == mnt->mnt_root && follow_up(&mnt, &dentry))
;
dp = dget_parent(dentry);
dput(dentry);
dentry = dp;
exp2 = rqst_exp_parent(rqstp, mnt, dentry);
if (PTR_ERR(exp2) == -ENOENT) {
dput(dentry);
dentry = dget(dparent);
} else if (IS_ERR(exp2)) {
host_err = PTR_ERR(exp2);
dput(dentry);
mntput(mnt);
goto out_nfserr;
} else {
exp_put(exp);
exp = exp2;
}
mntput(mnt);
}
} else {
fh_lock(fhp);
dentry = lookup_one_len(name, dparent, len);
host_err = PTR_ERR(dentry);
if (IS_ERR(dentry))
goto out_nfserr;
/*
* check if we have crossed a mount point ...
*/
if (d_mountpoint(dentry)) {
if ((host_err = nfsd_cross_mnt(rqstp, &dentry, &exp))) {
dput(dentry);
goto out_nfserr;
}
}
}
*dentry_ret = dentry;
*exp_ret = exp;
return 0;
out_nfserr:
exp_put(exp);
return nfserrno(host_err);
}
示例3: S_ISDIR
/**
* securityfs_create_file - create a file in the securityfs filesystem
*
* @name: a pointer to a string containing the name of the file to create.
* @mode: the permission that the file should have
* @parent: a pointer to the parent dentry for this file. This should be a
* directory dentry if set. If this parameter is %NULL, then the
* file will be created in the root of the securityfs filesystem.
* @data: a pointer to something that the caller will want to get to later
* on. The inode.i_private pointer will point to this value on
* the open() call.
* @fops: a pointer to a struct file_operations that should be used for
* this file.
*
* This is the basic "create a file" function for securityfs. It allows for a
* wide range of flexibility in creating a file, or a directory (if you
* want to create a directory, the securityfs_create_dir() function is
* recommended to be used instead).
*
* This function returns a pointer to a dentry if it succeeds. This
* pointer must be passed to the securityfs_remove() function when the file is
* to be removed (no automatic cleanup happens if your module is unloaded,
* you are responsible here). If an error occurs, the function will return
* the error value (via ERR_PTR).
*
* If securityfs is not enabled in the kernel, the value %-ENODEV is
* returned.
*/
struct dentry *securityfs_create_file(const char *name, umode_t mode,
struct dentry *parent, void *data,
const struct file_operations *fops)
{
struct dentry *dentry;
int is_dir = S_ISDIR(mode);
struct inode *dir, *inode;
int error;
if (!is_dir) {
BUG_ON(!fops);
mode = (mode & S_IALLUGO) | S_IFREG;
}
pr_debug("securityfs: creating file '%s'\n",name);
error = simple_pin_fs(&fs_type, &mount, &mount_count);
if (error)
return ERR_PTR(error);
if (!parent)
parent = mount->mnt_root;
dir = d_inode(parent);
inode_lock(dir);
dentry = lookup_one_len(name, parent, strlen(name));
if (IS_ERR(dentry))
goto out;
if (d_really_is_positive(dentry)) {
error = -EEXIST;
goto out1;
}
inode = new_inode(dir->i_sb);
if (!inode) {
error = -ENOMEM;
goto out1;
}
inode->i_ino = get_next_ino();
inode->i_mode = mode;
inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
inode->i_private = data;
if (is_dir) {
inode->i_op = &simple_dir_inode_operations;
inode->i_fop = &simple_dir_operations;
inc_nlink(inode);
inc_nlink(dir);
} else {
inode->i_fop = fops;
}
d_instantiate(dentry, inode);
dget(dentry);
inode_unlock(dir);
return dentry;
out1:
dput(dentry);
dentry = ERR_PTR(error);
out:
inode_unlock(dir);
simple_release_fs(&mount, &mount_count);
return dentry;
}
示例4: cr_mknod
/* cr_mknod - based on linux/fs/namei.c:sys_mknod
*
* Creates regular files or fifos (no devices) making them anonymous (unlinked)
* if desired.
* Returns a dentry for the resulting filesystem objects, and the corresponding
* vfsmnt can be obtained in nd->mnt. Together these two can be passed
* to dentry_open() or cr_dentry_open(), even for an unlinked inode.
* In the event of an error, no dput() or cr_path_release() is required,
* otherwise they are.
*
* In the event that an object exists with the given name, it will be
* check for the proper mode prior to return, yielding -EEXIST on conflict.
*/
struct dentry *
cr_mknod(cr_errbuf_t *eb, struct nameidata *nd, const char *name, int mode, unsigned long unlinked_id)
{
struct dentry * dentry;
int err;
if (unlinked_id) {
/* Generate a replacement name which we will use instead of the original one. */
name = cr_anonymous_rename(eb, name, unlinked_id);
if (!name) {
CR_ERR_EB(eb, "cr_mknod - failed to rename unlinked object");
err = -ENOMEM;
goto out;
}
}
/* Prior to 2.6.26, lookup_create() would return an exisiting dentry.
* Since 2.6.26, it returns -EEXIST if the dentry exists. So, we first
* check for an existing dentry. For older kernels this is not required,
* but is still correct.
*/
err = path_lookup(name, LOOKUP_FOLLOW, nd);
if (!err) {
dentry = dget(nd->nd_dentry);
err = -EEXIST; /* Forces mode validation below */
goto have_it;
}
err = path_lookup(name, LOOKUP_PARENT, nd);
if (err) {
CR_KTRACE_UNEXPECTED("Couldn't path_lookup for mknod %s. err=%d.", name, err);
goto out_free;
}
dentry = cr_lookup_create(nd, 0);
if (IS_ERR(dentry)) {
err = PTR_ERR(dentry);
CR_KTRACE_UNEXPECTED("Couldn't lookup_create for mknod %s. err=%d.", name, err);
goto out_release;
}
switch (mode & S_IFMT) {
case S_IFREG:
err = vfs_create(nd->nd_dentry->d_inode, dentry, mode, nd);
break;
case S_IFIFO:
err = cr_vfs_mknod(nd->nd_dentry->d_inode, dentry, nd->nd_mnt, mode, 0 /* ignored */);
break;
default:
CR_ERR_EB(eb, "Unknown/invalid type %d passed to cr_mknod %s.", (mode&S_IFMT), name);
err = -EINVAL;
}
if (unlinked_id && !err) { /* Note that we don't unlink if we failed to create */
dget(dentry); /* ensure unlink doesn't destroy the dentry */
/* Note possibility of silent failure here: */
(void)cr_vfs_unlink(nd->nd_dentry->d_inode, dentry, nd->nd_mnt);
dput(dentry);
}
cr_inode_unlock(nd->nd_dentry->d_inode);
have_it:
if ((err == -EEXIST) && !((dentry->d_inode->i_mode ^ mode) & S_IFMT)) {
/* We fall through and return the dentry */
} else if (err) {
CR_KTRACE_UNEXPECTED("Couldn't cr_mknod %s. err=%d.", name, err);
goto out_put;
}
if (unlinked_id) {
__putname(name);
}
return dentry;
out_put:
dput(dentry);
out_release:
cr_path_release(nd);
out_free:
if (unlinked_id) {
__putname(name);
}
out:
return (struct dentry *)ERR_PTR(err);
}
示例5: ceph_atomic_open
/*
* Do a lookup + open with a single request. If we get a non-existent
* file or symlink, return 1 so the VFS can retry.
*/
int ceph_atomic_open(struct inode *dir, struct dentry *dentry,
struct file *file, unsigned flags, umode_t mode,
int *opened)
{
struct ceph_fs_client *fsc = ceph_sb_to_client(dir->i_sb);
struct ceph_mds_client *mdsc = fsc->mdsc;
struct ceph_mds_request *req;
struct dentry *dn;
int err;
dout("atomic_open %p dentry %p '%.*s' %s flags %d mode 0%o\n",
dir, dentry, dentry->d_name.len, dentry->d_name.name,
d_unhashed(dentry) ? "unhashed" : "hashed", flags, mode);
if (dentry->d_name.len > NAME_MAX)
return -ENAMETOOLONG;
err = ceph_init_dentry(dentry);
if (err < 0)
return err;
/* do the open */
req = prepare_open_request(dir->i_sb, flags, mode);
if (IS_ERR(req))
return PTR_ERR(req);
req->r_dentry = dget(dentry);
req->r_num_caps = 2;
if (flags & O_CREAT) {
req->r_dentry_drop = CEPH_CAP_FILE_SHARED;
req->r_dentry_unless = CEPH_CAP_FILE_EXCL;
}
req->r_locked_dir = dir; /* caller holds dir->i_mutex */
err = ceph_mdsc_do_request(mdsc,
(flags & (O_CREAT|O_TRUNC)) ? dir : NULL,
req);
if (err)
goto out_err;
err = ceph_handle_snapdir(req, dentry, err);
if (err == 0 && (flags & O_CREAT) && !req->r_reply_info.head->is_dentry)
err = ceph_handle_notrace_create(dir, dentry);
if (d_unhashed(dentry)) {
dn = ceph_finish_lookup(req, dentry, err);
if (IS_ERR(dn))
err = PTR_ERR(dn);
} else {
/* we were given a hashed negative dentry */
dn = NULL;
}
if (err)
goto out_err;
if (dn || dentry->d_inode == NULL || S_ISLNK(dentry->d_inode->i_mode)) {
/* make vfs retry on splice, ENOENT, or symlink */
dout("atomic_open finish_no_open on dn %p\n", dn);
err = finish_no_open(file, dn);
} else {
dout("atomic_open finish_open on dn %p\n", dn);
if (req->r_op == CEPH_MDS_OP_CREATE && req->r_reply_info.has_create_ino) {
*opened |= FILE_CREATED;
}
err = finish_open(file, dentry, ceph_open, opened);
}
out_err:
ceph_mdsc_put_request(req);
dout("atomic_open result=%d\n", err);
return err;
}
示例6: inode_doinit_with_dentry
/* The inode's security attributes must be initialized before first use. */
static int inode_doinit_with_dentry(struct inode *inode,
struct dentry *opt_dentry)
{
struct inode_security_struct *isec = inode->i_security;
struct dentry *dentry;
char *context = NULL;
unsigned len = 0;
int rc = 0;
if (isec && isec->initialized)
return rc;
mutex_lock(&isec->lock);
if (!inode->i_op->getxattr) {
/* no getxattr iop, so init */
pr_debug("no xattr iop when init\n");
isec->task_sid = current_uid();
init_mlevel(&isec->mlevel);
isec->ilevel.level_value = 0;
goto out;
}
/* Need a dentry, since the xattr API requires one.
Life would be simpler if we could just pass the inode. */
if (opt_dentry)
/* Called from d_instantiate or d_splice_alias. */
dentry = dget(opt_dentry);
if (!dentry) {
/*
* this is can be hit on boot when a file is accessed
* inode_doinit with a dentry, before these inodes could
* be used again by userspace.
*/
goto out;
}
/* Query for the right size. */
rc = inode->i_op->getxattr(dentry, XATTR_NAME_KSE,
NULL, 0);
if (rc < 0) {
dput(dentry);
goto out;
}
len = rc;
context = kmalloc(len+1, GFP_NOFS);
if (!context) {
rc = -ENOMEM;
dput(dentry);
goto out;
}
context[len] = '\0';
rc = inode->i_op->getxattr(dentry, XATTR_NAME_KSE,
context, len);
if (rc == -ERANGE) {
kfree(context);
/* Need a larger buffer. Query for the right size. */
rc = inode->i_op->getxattr(dentry, XATTR_NAME_KSE,
NULL, 0);
if (rc < 0) {
dput(dentry);
goto out;
}
len = rc;
context = kmalloc(len+1, GFP_NOFS);
if (!context) {
rc = -ENOMEM;
dput(dentry);
goto out;
}
context[len] = '\0';
rc = inode->i_op->getxattr(dentry,
XATTR_NAME_KSE,
context, len);
}
dput(dentry);
if (rc < 0) {
if (rc != -ENODATA) {
printk(KERN_INFO "KUXSE: %s: getxattr returned "
"%d for dev=%s ino=%ld\n", __func__,
-rc, inode->i_sb->s_id, inode->i_ino);
kfree(context);
goto out;
}
/* NODATA just init */
rc = 0;
pr_debug("no xattr data when init\n");
isec->task_sid = current_uid();
init_mlevel(&isec->mlevel);
isec->ilevel.level_value = 0;
} else {
/* getxattr succeeded */
ssize_t sclen = strlen(context);
rc = context_to_iss(&isec->mlevel, &isec->ilevel,
(const void **)&context, &sclen);
if (rc) {
printk(KERN_INFO "KUXSE: unable to map value '%s' "
"to context for (%s, %lu), rc=%d, size=%ld\n",
//.........这里部分代码省略.........
示例7: spin_lock
/*
* Find an eligible tree to time-out
* A tree is eligible if :-
* - it is unused by any user process
* - it has been unused for exp_timeout time
*/
static struct dentry *autofs4_expire_indirect(struct super_block *sb,
struct vfsmount *mnt,
struct autofs_sb_info *sbi,
int how)
{
unsigned long timeout;
struct dentry *root = sb->s_root;
struct dentry *expired = NULL;
struct list_head *next;
int do_now = how & AUTOFS_EXP_IMMEDIATE;
int exp_leaves = how & AUTOFS_EXP_LEAVES;
if (!root)
return NULL;
now = jiffies;
timeout = sbi->exp_timeout;
spin_lock(&dcache_lock);
next = root->d_subdirs.next;
/* On exit from the loop expire is set to a dgot dentry
* to expire or it's NULL */
while ( next != &root->d_subdirs ) {
struct dentry *dentry = list_entry(next, struct dentry, d_u.d_child);
/* Negative dentry - give up */
if (!simple_positive(dentry)) {
next = next->next;
continue;
}
dentry = dget(dentry);
spin_unlock(&dcache_lock);
/*
* Case 1: (i) indirect mount or top level pseudo direct mount
* (autofs-4.1).
* (ii) indirect mount with offset mount, check the "/"
* offset (autofs-5.0+).
*/
if (d_mountpoint(dentry)) {
DPRINTK("checking mountpoint %p %.*s",
dentry, (int)dentry->d_name.len, dentry->d_name.name);
/* Can we umount this guy */
if (autofs4_mount_busy(mnt, dentry))
goto next;
/* Can we expire this guy */
if (autofs4_can_expire(dentry, timeout, do_now)) {
expired = dentry;
break;
}
goto next;
}
if (simple_empty(dentry))
goto next;
/* Case 2: tree mount, expire iff entire tree is not busy */
if (!exp_leaves) {
/* Lock the tree as we must expire as a whole */
spin_lock(&sbi->fs_lock);
if (!autofs4_tree_busy(mnt, dentry, timeout, do_now)) {
struct autofs_info *inf = autofs4_dentry_ino(dentry);
/* Set this flag early to catch sys_chdir and the like */
inf->flags |= AUTOFS_INF_EXPIRING;
spin_unlock(&sbi->fs_lock);
expired = dentry;
break;
}
spin_unlock(&sbi->fs_lock);
/*
* Case 3: pseudo direct mount, expire individual leaves
* (autofs-4.1).
*/
} else {
expired = autofs4_check_leaves(mnt, dentry, timeout, do_now);
if (expired) {
dput(dentry);
break;
}
}
next:
dput(dentry);
spin_lock(&dcache_lock);
next = next->next;
}
if (expired) {
DPRINTK("returning %p %.*s",
expired, (int)expired->d_name.len, expired->d_name.name);
//.........这里部分代码省略.........
示例8: ovl_permission
int ovl_permission(struct inode *inode, int mask)
{
struct ovl_entry *oe;
struct dentry *alias = NULL;
struct inode *realinode;
struct dentry *realdentry;
bool is_upper;
int err;
if (S_ISDIR(inode->i_mode)) {
oe = inode->i_private;
} else if (mask & MAY_NOT_BLOCK) {
return -ECHILD;
} else {
/*
* For non-directories find an alias and get the info
* from there.
*/
spin_lock(&inode->i_lock);
if (WARN_ON(list_empty(&inode->i_dentry))) {
spin_unlock(&inode->i_lock);
return -ENOENT;
}
alias = list_entry(inode->i_dentry.next,
struct dentry, d_u.d_alias);
dget(alias);
spin_unlock(&inode->i_lock);
oe = alias->d_fsdata;
}
realdentry = ovl_entry_real(oe, &is_upper);
/* Careful in RCU walk mode */
realinode = ACCESS_ONCE(realdentry->d_inode);
if (!realinode) {
WARN_ON(!(mask & MAY_NOT_BLOCK));
err = -ENOENT;
goto out_dput;
}
if (mask & MAY_WRITE) {
umode_t mode = realinode->i_mode;
/*
* Writes will always be redirected to upper layer, so
* ignore lower layer being read-only.
*
* If the overlay itself is read-only then proceed
* with the permission check, don't return EROFS.
* This will only happen if this is the lower layer of
* another overlayfs.
*
* If upper fs becomes read-only after the overlay was
* constructed return EROFS to prevent modification of
* upper layer.
*/
err = -EROFS;
if (is_upper && !IS_RDONLY(inode) && IS_RDONLY(realinode) &&
(S_ISREG(mode) || S_ISDIR(mode) || S_ISLNK(mode)))
goto out_dput;
}
err = inode_only_permission(realinode, mask);
out_dput:
dput(alias);
return err;
}
示例9: copy_namei
static inline void copy_namei(struct nameidata *dest, const struct nameidata *src) {
mntget(src->mnt); dget(src->dentry);
*dest = *src;
}
示例10: autofs4_tree_busy
/* Check a directory tree of mount points for busyness
* The tree is not busy iff no mountpoints are busy
*/
static int autofs4_tree_busy(struct vfsmount *mnt,
struct dentry *top,
unsigned long timeout,
int do_now)
{
struct autofs_info *top_ino = autofs4_dentry_ino(top);
struct dentry *p;
DPRINTK("top %p %.*s",
top, (int)top->d_name.len, top->d_name.name);
/* Negative dentry - give up */
if (!simple_positive(top))
return 1;
spin_lock(&dcache_lock);
for (p = top; p; p = next_dentry(p, top)) {
/* Negative dentry - give up */
if (!simple_positive(p))
continue;
DPRINTK("dentry %p %.*s",
p, (int) p->d_name.len, p->d_name.name);
p = dget(p);
spin_unlock(&dcache_lock);
/*
* Is someone visiting anywhere in the subtree ?
* If there's no mount we need to check the usage
* count for the autofs dentry.
* If the fs is busy update the expiry counter.
*/
if (d_mountpoint(p)) {
if (autofs4_mount_busy(mnt, p)) {
top_ino->last_used = jiffies;
dput(p);
return 1;
}
} else {
struct autofs_info *ino = autofs4_dentry_ino(p);
unsigned int ino_count = atomic_read(&ino->count);
/*
* Clean stale dentries below that have not been
* invalidated after a mount fail during lookup
*/
d_invalidate(p);
/* allow for dget above and top is already dgot */
if (p == top)
ino_count += 2;
else
ino_count++;
if (atomic_read(&p->d_count) > ino_count) {
top_ino->last_used = jiffies;
dput(p);
return 1;
}
}
dput(p);
spin_lock(&dcache_lock);
}
spin_unlock(&dcache_lock);
/* Timeout of a tree mount is ultimately determined by its top dentry */
if (!autofs4_can_expire(top, timeout, do_now))
return 1;
return 0;
}
示例11: redirect_namei
void redirect_namei(struct nameidata *dest, const struct nameidata *src) {
mntget(src->mnt); dget(src->dentry);
mntput(dest->mnt); dput(dest->dentry);
*dest = *src;
}
示例12: check_empty
/* Is a directory logically empty? */
int check_empty(struct dentry *dentry, struct dentry *parent,
struct unionfs_dir_state **namelist)
{
int err = 0;
struct dentry *lower_dentry = NULL;
struct vfsmount *mnt;
struct super_block *sb;
struct file *lower_file;
struct unionfs_rdutil_callback *buf = NULL;
int bindex, bstart, bend, bopaque;
sb = dentry->d_sb;
BUG_ON(!S_ISDIR(dentry->d_inode->i_mode));
err = unionfs_partial_lookup(dentry, parent);
if (err)
goto out;
bstart = dbstart(dentry);
bend = dbend(dentry);
bopaque = dbopaque(dentry);
if (0 <= bopaque && bopaque < bend)
bend = bopaque;
buf = kmalloc(sizeof(struct unionfs_rdutil_callback), GFP_KERNEL);
if (unlikely(!buf)) {
err = -ENOMEM;
goto out;
}
buf->err = 0;
buf->mode = RD_CHECK_EMPTY;
buf->rdstate = alloc_rdstate(dentry->d_inode, bstart);
if (unlikely(!buf->rdstate)) {
err = -ENOMEM;
goto out;
}
/* Process the lower directories with rdutil_callback as a filldir. */
for (bindex = bstart; bindex <= bend; bindex++) {
lower_dentry = unionfs_lower_dentry_idx(dentry, bindex);
if (!lower_dentry)
continue;
if (!lower_dentry->d_inode)
continue;
if (!S_ISDIR(lower_dentry->d_inode->i_mode))
continue;
dget(lower_dentry);
mnt = unionfs_mntget(dentry, bindex);
branchget(sb, bindex);
lower_file = dentry_open(lower_dentry, mnt, O_RDONLY);
if (IS_ERR(lower_file)) {
err = PTR_ERR(lower_file);
branchput(sb, bindex);
goto out;
}
do {
buf->filldir_called = 0;
buf->rdstate->bindex = bindex;
err = vfs_readdir(lower_file,
readdir_util_callback, buf);
if (buf->err)
err = buf->err;
} while ((err >= 0) && buf->filldir_called);
/* fput calls dput for lower_dentry */
fput(lower_file);
branchput(sb, bindex);
if (err < 0)
goto out;
}
out:
if (buf) {
if (namelist && !err)
*namelist = buf->rdstate;
else if (buf->rdstate)
free_rdstate(buf->rdstate);
kfree(buf);
}
return err;
}
示例13: au_refresh_by_dinfo
/*
* By adding a dirty branch, a cached dentry may be affected in various ways.
*
* a dirty branch is added
* - on the top of layers
* - in the middle of layers
* - to the bottom of layers
*
* on the added branch there exists
* - a whiteout
* - a diropq
* - a same named entry
* + exist
* * negative --> positive
* * positive --> positive
* - type is unchanged
* - type is changed
* + doesn't exist
* * negative --> negative
* * positive --> negative (rejected by au_br_del() for non-dir case)
* - none
*/
static int au_refresh_by_dinfo(struct dentry *dentry, struct au_dinfo *dinfo,
struct au_dinfo *tmp)
{
int err;
aufs_bindex_t bindex, bend;
struct {
struct dentry *dentry;
struct inode *inode;
mode_t mode;
} orig_h, tmp_h;
struct au_hdentry *hd;
struct inode *inode, *h_inode;
struct dentry *h_dentry;
err = 0;
AuDebugOn(dinfo->di_bstart < 0);
orig_h.dentry = dinfo->di_hdentry[dinfo->di_bstart].hd_dentry;
orig_h.inode = orig_h.dentry->d_inode;
orig_h.mode = 0;
if (orig_h.inode)
orig_h.mode = orig_h.inode->i_mode & S_IFMT;
memset(&tmp_h, 0, sizeof(tmp_h));
if (tmp->di_bstart >= 0) {
tmp_h.dentry = tmp->di_hdentry[tmp->di_bstart].hd_dentry;
tmp_h.inode = tmp_h.dentry->d_inode;
if (tmp_h.inode)
tmp_h.mode = tmp_h.inode->i_mode & S_IFMT;
}
inode = dentry->d_inode;
if (!orig_h.inode) {
AuDbg("nagative originally\n");
if (inode) {
au_hide(dentry);
goto out;
}
AuDebugOn(inode);
AuDebugOn(dinfo->di_bstart != dinfo->di_bend);
AuDebugOn(dinfo->di_bdiropq != -1);
if (!tmp_h.inode) {
AuDbg("negative --> negative\n");
/* should have only one negative lower */
if (tmp->di_bstart >= 0
&& tmp->di_bstart < dinfo->di_bstart) {
AuDebugOn(tmp->di_bstart != tmp->di_bend);
AuDebugOn(dinfo->di_bstart != dinfo->di_bend);
au_set_h_dptr(dentry, dinfo->di_bstart, NULL);
au_di_cp(dinfo, tmp);
hd = tmp->di_hdentry + tmp->di_bstart;
au_set_h_dptr(dentry, tmp->di_bstart,
dget(hd->hd_dentry));
}
au_dbg_verify_dinode(dentry);
} else {
AuDbg("negative --> positive\n");
/*
* similar to the behaviour of creating with bypassing
* aufs.
* unhash it in order to force an error in the
* succeeding create operation.
* we should not set S_DEAD here.
*/
d_drop(dentry);
/* au_di_swap(tmp, dinfo); */
au_dbg_verify_dinode(dentry);
}
} else {
AuDbg("positive originally\n");
/* inode may be NULL */
AuDebugOn(inode && (inode->i_mode & S_IFMT) != orig_h.mode);
if (!tmp_h.inode) {
AuDbg("positive --> negative\n");
/* or bypassing aufs */
au_hide(dentry);
if (tmp->di_bwh >= 0 && tmp->di_bwh <= dinfo->di_bstart)
dinfo->di_bwh = tmp->di_bwh;
if (inode)
//.........这里部分代码省略.........
示例14: cifs_dfs_follow_mountpoint
static void*
cifs_dfs_follow_mountpoint(struct dentry *dentry, struct nameidata *nd)
{
struct dfs_info3_param *referrals = NULL;
unsigned int num_referrals = 0;
struct cifs_sb_info *cifs_sb;
struct cifsSesInfo *ses;
char *full_path = NULL;
int xid, i;
int rc = 0;
struct vfsmount *mnt = ERR_PTR(-ENOENT);
cFYI(1, ("in %s", __func__));
BUG_ON(IS_ROOT(dentry));
xid = GetXid();
dput(nd->dentry);
nd->dentry = dget(dentry);
cifs_sb = CIFS_SB(dentry->d_inode->i_sb);
ses = cifs_sb->tcon->ses;
if (!ses) {
rc = -EINVAL;
goto out_err;
}
/*
* The MSDFS spec states that paths in DFS referral requests and
* responses must be prefixed by a single '\' character instead of
* the double backslashes usually used in the UNC. This function
* gives us the latter, so we must adjust the result.
*/
full_path = build_path_from_dentry(dentry);
if (full_path == NULL) {
rc = -ENOMEM;
goto out_err;
}
rc = get_dfs_path(xid, ses , full_path + 1, cifs_sb->local_nls,
&num_referrals, &referrals,
cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
for (i = 0; i < num_referrals; i++) {
int len;
dump_referral(referrals+i);
/* connect to a node */
len = strlen(referrals[i].node_name);
if (len < 2) {
cERROR(1, ("%s: Net Address path too short: %s",
__func__, referrals[i].node_name));
rc = -EINVAL;
goto out_err;
}
mnt = cifs_dfs_do_refmount(nd->mnt,
nd->dentry, referrals + i);
cFYI(1, ("%s: cifs_dfs_do_refmount:%s , mnt:%p", __func__,
referrals[i].node_name, mnt));
/* complete mount procedure if we accured submount */
if (!IS_ERR(mnt))
break;
}
/* we need it cause for() above could exit without valid submount */
rc = PTR_ERR(mnt);
if (IS_ERR(mnt))
goto out_err;
rc = add_mount_helper(mnt, nd, &cifs_dfs_automount_list);
out:
FreeXid(xid);
free_dfs_info_array(referrals, num_referrals);
kfree(full_path);
cFYI(1, ("leaving %s" , __func__));
return ERR_PTR(rc);
out_err:
path_release(nd);
goto out;
}
示例15: create_sto_dir
/* create the sto dir, setup states */
int create_sto_dir(dentry_t *dentry, int mode)
{
int err = 0;
inode_t *dir;
dentry_t *hidden_sto_dentry;
dentry_t *hidden_sto_dir_dentry;
/* had to take the "!S_ISDIR(mode))" check out, because it failed */
if(exists_in_storage(dentry)) {
printk(KERN_CRIT "mini_fo: create_sto_dir: wrong type or state.\\
n");
err = -EINVAL;
goto out;
}
err = get_neg_sto_dentry(dentry);
if(err) {
err = -EINVAL;
goto out;
}
dir = dentry->d_parent->d_inode;
hidden_sto_dentry = dtohd2(dentry);
/* was: hidden_sto_dir_dentry = lock_parent(hidden_sto_dentry); */
hidden_sto_dir_dentry = dget(hidden_sto_dentry->d_parent);
err = PTR_ERR(hidden_sto_dir_dentry);
if (IS_ERR(hidden_sto_dir_dentry))
goto out;
err = vfs_mkdir(hidden_sto_dir_dentry->d_inode,
hidden_sto_dentry,
mode);
if(err) {
printk(KERN_CRIT "mini_fo: create_sto_dir: ERROR creating sto dir.\n");
goto out_lock;
}
if(!dtohd2(dentry)->d_inode) {
printk(KERN_CRIT "mini_fo: create_sto_dir: ERROR creating sto dir [2].\n");
err = -EINVAL;
goto out_lock;
}
/* interpose the new inode */
if(dtost(dentry) == DELETED) {
dtost(dentry) = DEL_REWRITTEN;
err = mini_fo_tri_interpose(NULL, hidden_sto_dentry, dentry, dir->i_sb, 0);
if(err)
goto out_lock;
}
else if(dtopd(dentry)->state == NON_EXISTANT) {
dtopd(dentry)->state = CREATED;
err = mini_fo_tri_interpose(dtohd(dentry), hidden_sto_dentry, dentry, dir->i_sb, 0);
if(err)
goto out_lock;
}
else if(dtopd(dentry)->state == UNMODIFIED) {
dtopd(dentry)->state = MODIFIED;
/* interpose on new inode */
if(itohi2(dentry->d_inode) != NULL) {
printk(KERN_CRIT "mini_fo: create_sto_dir: ERROR, invalid inode detected.\n");
err = -EINVAL;
goto out_lock;
}
itohi2(dentry->d_inode) = igrab(dtohd2(dentry)->d_inode);
}
fist_copy_attr_timesizes(dir, hidden_sto_dir_dentry->d_inode);
/* initalize the wol list */
itopd(dentry->d_inode)->deleted_list_size = -1;
itopd(dentry->d_inode)->renamed_list_size = -1;
meta_build_lists(dentry);
out_lock:
/* was: unlock_dir(hidden_sto_dir_dentry); */
dput(hidden_sto_dir_dentry);
out:
return err;
}