Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 175027
b: refs/heads/master
c: a16bbc3
h: refs/heads/master
i:
  175025: 4b46e2c
  175023: b0bfe43
v: v3
  • Loading branch information
Eric W. Biederman authored and Greg Kroah-Hartman committed Dec 11, 2009
1 parent 7ac4477 commit 4471d35
Show file tree
Hide file tree
Showing 3 changed files with 5 additions and 90 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 06fc0d66f7ed3a3b08e8fcf8c325ecf0b8f93fea
refs/heads/master: a16bbc3430ed94b543222f4c8ef68025f8493e93
91 changes: 4 additions & 87 deletions trunk/fs/sysfs/dir.c
Original file line number Diff line number Diff line change
Expand Up @@ -386,60 +386,27 @@ struct sysfs_dirent *sysfs_new_dirent(const char *name, umode_t mode, int type)
return NULL;
}

static int sysfs_ilookup_test(struct inode *inode, void *arg)
{
struct sysfs_dirent *sd = arg;
return inode->i_ino == sd->s_ino;
}

/**
* sysfs_addrm_start - prepare for sysfs_dirent add/remove
* @acxt: pointer to sysfs_addrm_cxt to be used
* @parent_sd: parent sysfs_dirent
*
* This function is called when the caller is about to add or
* remove sysfs_dirent under @parent_sd. This function acquires
* sysfs_mutex, grabs inode for @parent_sd if available and lock
* i_mutex of it. @acxt is used to keep and pass context to
* sysfs_mutex. @acxt is used to keep and pass context to
* other addrm functions.
*
* LOCKING:
* Kernel thread context (may sleep). sysfs_mutex is locked on
* return. i_mutex of parent inode is locked on return if
* available.
* return.
*/
void sysfs_addrm_start(struct sysfs_addrm_cxt *acxt,
struct sysfs_dirent *parent_sd)
{
struct inode *inode;

memset(acxt, 0, sizeof(*acxt));
acxt->parent_sd = parent_sd;

/* Lookup parent inode. inode initialization is protected by
* sysfs_mutex, so inode existence can be determined by
* looking up inode while holding sysfs_mutex.
*/
mutex_lock(&sysfs_mutex);

inode = ilookup5(sysfs_sb, parent_sd->s_ino, sysfs_ilookup_test,
parent_sd);
if (inode) {
WARN_ON(inode->i_state & I_NEW);

/* parent inode available */
acxt->parent_inode = inode;

/* sysfs_mutex is below i_mutex in lock hierarchy.
* First, trylock i_mutex. If fails, unlock
* sysfs_mutex and lock them in order.
*/
if (!mutex_trylock(&inode->i_mutex)) {
mutex_unlock(&sysfs_mutex);
mutex_lock(&inode->i_mutex);
mutex_lock(&sysfs_mutex);
}
}
}

/**
Expand Down Expand Up @@ -471,11 +438,6 @@ int __sysfs_add_one(struct sysfs_addrm_cxt *acxt, struct sysfs_dirent *sd)

sd->s_parent = sysfs_get(acxt->parent_sd);

if (sysfs_type(sd) == SYSFS_DIR && acxt->parent_inode)
inc_nlink(acxt->parent_inode);

acxt->cnt++;

sysfs_link_sibling(sd);

/* Update timestamps on the parent */
Expand Down Expand Up @@ -579,40 +541,6 @@ void sysfs_remove_one(struct sysfs_addrm_cxt *acxt, struct sysfs_dirent *sd)
sd->s_flags |= SYSFS_FLAG_REMOVED;
sd->s_sibling = acxt->removed;
acxt->removed = sd;

if (sysfs_type(sd) == SYSFS_DIR && acxt->parent_inode)
drop_nlink(acxt->parent_inode);

acxt->cnt++;
}

/**
* sysfs_dec_nlink - Decrement link count for the specified sysfs_dirent
* @sd: target sysfs_dirent
*
* Decrement nlink for @sd. @sd must have been unlinked from its
* parent on entry to this function such that it can't be looked
* up anymore.
*/
static void sysfs_dec_nlink(struct sysfs_dirent *sd)
{
struct inode *inode;

inode = ilookup(sysfs_sb, sd->s_ino);
if (!inode)
return;

/* adjust nlink and update timestamp */
mutex_lock(&inode->i_mutex);

inode->i_ctime = CURRENT_TIME;
drop_nlink(inode);
if (sysfs_type(sd) == SYSFS_DIR)
drop_nlink(inode);

mutex_unlock(&inode->i_mutex);

iput(inode);
}

/**
Expand All @@ -621,25 +549,15 @@ static void sysfs_dec_nlink(struct sysfs_dirent *sd)
*
* Finish up sysfs_dirent add/remove. Resources acquired by
* sysfs_addrm_start() are released and removed sysfs_dirents are
* cleaned up. Timestamps on the parent inode are updated.
* cleaned up.
*
* LOCKING:
* All mutexes acquired by sysfs_addrm_start() are released.
* sysfs_mutex is released.
*/
void sysfs_addrm_finish(struct sysfs_addrm_cxt *acxt)
{
/* release resources acquired by sysfs_addrm_start() */
mutex_unlock(&sysfs_mutex);
if (acxt->parent_inode) {
struct inode *inode = acxt->parent_inode;

/* if added/removed, update timestamps on the parent */
if (acxt->cnt)
inode->i_ctime = inode->i_mtime = CURRENT_TIME;

mutex_unlock(&inode->i_mutex);
iput(inode);
}

/* kill removed sysfs_dirents */
while (acxt->removed) {
Expand All @@ -648,7 +566,6 @@ void sysfs_addrm_finish(struct sysfs_addrm_cxt *acxt)
acxt->removed = sd->s_sibling;
sd->s_sibling = NULL;

sysfs_dec_nlink(sd);
sysfs_deactivate(sd);
unmap_bin_file(sd);
sysfs_put(sd);
Expand Down
2 changes: 0 additions & 2 deletions trunk/fs/sysfs/sysfs.h
Original file line number Diff line number Diff line change
Expand Up @@ -89,9 +89,7 @@ static inline unsigned int sysfs_type(struct sysfs_dirent *sd)
*/
struct sysfs_addrm_cxt {
struct sysfs_dirent *parent_sd;
struct inode *parent_inode;
struct sysfs_dirent *removed;
int cnt;
};

/*
Expand Down

0 comments on commit 4471d35

Please sign in to comment.