st->st_nlink = inode.nlink;
st->st_uid = inode.uid;
st->st_gid = inode.gid;
- st->st_ctime = inode.ctime;
+ st->st_ctime = MAX(inode.ctime, inode.mtime);
st->st_atime = inode.atime;
st->st_mtime = inode.mtime;
st->st_size = inode.size;
st->st_gid = inode.gid;
#ifndef DARWIN
// FIXME what's going on here with darwin?
- st->st_ctime = inode.ctime;
+ st->st_ctime = MAX(inode.ctime, inode.mtime);
st->st_atime = inode.atime;
st->st_mtime = inode.mtime;
#endif
#define FILE_MODE_RW (1|2)
#define FILE_MODE_LAZY 4
-#define INODE_MASK_BASE 1 // ino, ctime, nlink
+#define INODE_MASK_BASE 1 // ino, nlink
#define INODE_MASK_PERM 2 // uid, gid, mode
#define INODE_MASK_SIZE 4 // size, blksize, blocks
-#define INODE_MASK_MTIME 8 // mtime
-#define INODE_MASK_ATIME 16 // atime
+#define INODE_MASK_CTIME 8 // ctime
+#define INODE_MASK_MTIME 16 // mtime
+#define INODE_MASK_ATIME 32 // atime
#define INODE_MASK_ALL_STAT (INODE_MASK_BASE|INODE_MASK_PERM|INODE_MASK_SIZE|INODE_MASK_MTIME)
//#define INODE_MASK_ALL_STAT (INODE_MASK_BASE|INODE_MASK_PERM|INODE_MASK_SIZE|INODE_MASK_MTIME|INODE_MASK_ATIME)
struct inode_t {
// base (immutable)
inodeno_t ino; // NOTE: ino _must_ come first for MDStore.cc to behave!!
- time_t ctime;
- // other
+ // other.
FileLayout layout; // ?immutable?
int nlink; // base,
+ time_t ctime; // inode change time
// hard/perm (namespace permissions)
mode_t mode;
// file (data access)
off_t size;
- time_t atime, mtime; // maybe atime different? "lazy"?
-
+ time_t mtime; // file data modify time.
+ time_t atime; // file data access time.
+
int mask;
// special stuff
* AUTH PINS
*/
-void CDir::auth_pin() {
+void CDir::auth_pin()
+{
if (auth_pins == 0)
get(PIN_AUTHPIN);
auth_pins++;
dout(7) << "auth_pin on " << *this << " count now " << auth_pins << " + " << nested_auth_pins << endl;
-
- inode->nested_auth_pins++;
- if (inode->parent)
- inode->parent->dir->adjust_nested_auth_pins( 1 );
+
+ // nest pins?
+ if (!is_subtree_root()) {
+ assert(!is_import());
+ inode->nested_auth_pins++;
+ if (inode->parent)
+ inode->parent->dir->adjust_nested_auth_pins( 1 );
+ }
}
-void CDir::auth_unpin() {
+void CDir::auth_unpin()
+{
auth_pins--;
if (auth_pins == 0)
put(PIN_AUTHPIN);
if (auth_pins + nested_auth_pins == 0)
on_freezeable();
- inode->nested_auth_pins--;
- if (inode->parent)
- inode->parent->dir->adjust_nested_auth_pins( -1 );
+ // nest?
+ if (!is_subtree_root()) {
+ inode->nested_auth_pins--;
+ if (inode->parent)
+ inode->parent->dir->adjust_nested_auth_pins( -1 );
+ }
}
void CDir::adjust_nested_auth_pins(int inc)
void set_dir_auth(int d, int d2=CDIR_AUTH_UNKNOWN);
void set_dir_auth_pending(int d2);
+ bool is_subtree_root() {
+ if (dir_auth != CDIR_AUTH_PARENT ||
+ dir_auth_pending != CDIR_AUTH_PARENT)
+ return true;
+ else
+ return false;
+ }
+
// for giving to clients
// -- auth pins --
bool can_auth_pin() { return !(is_frozen() || is_freezing()); }
int is_auth_pinned() { return auth_pins; }
+ int get_cum_auth_pins() { return auth_pins + nested_auth_pins; }
void auth_pin();
void auth_unpin();
void adjust_nested_auth_pins(int inc);
return true;
}
-void CInode::auth_pin() {
+void CInode::auth_pin()
+{
if (auth_pins == 0)
get(PIN_AUTHPIN);
auth_pins++;
dout(7) << "auth_pin on " << *this << " count now " << auth_pins << " + " << nested_auth_pins << endl;
-
+
if (parent)
parent->dir->adjust_nested_auth_pins( 1 );
}
-void CInode::auth_unpin() {
+void CInode::auth_unpin()
+{
auth_pins--;
if (auth_pins == 0)
put(PIN_AUTHPIN);
-
+
dout(7) << "auth_unpin on " << *this << " count now " << auth_pins << " + " << nested_auth_pins << endl;
-
+
assert(auth_pins >= 0);
-
+
if (parent)
parent->dir->adjust_nested_auth_pins( -1 );
}
private:
- // lock nesting
+ // auth pin
int auth_pins;
int nested_auth_pins;
// make it up (FIXME)
root->inode.mode = 0755 | INODE_MODE_DIR;
root->inode.size = 0;
- root->inode.ctime = 0;
- root->inode.mtime = g_clock.gettime();
+ root->inode.ctime =
+ root->inode.mtime = g_clock.gettime();
root->inode.nlink = 1;
root->inode.layout = g_OSD_MDDirLayout;
assert(export_bounds.count(dir) == 1);
assert(export_data.count(dir) == 0);
+ assert(dir->get_cum_auth_pins() == 0);
+
// update imports/exports
CDir *containing_import = cache->get_auth_container(dir);
if (dir != im)
dout(10) << " under " << *im << endl;
+ assert(dir->get_cum_auth_pins() == 0);
+
// bounds
for (set<CDir*>::iterator p = bounds.begin();
p != bounds.end();
if (dir != im)
dout(10) << " under " << *im << endl;
+ assert(dir->get_cum_auth_pins() == 0);
+
// bounds
for (list<inodeno_t>::iterator it = m->get_exports().begin();
it != m->get_exports().end();
++q)
mds->mdcache->nested_exports[im].insert(*q);
mds->mdcache->nested_exports.erase(bd);
+
+ // adjust nested auth pins
+ bdi->adjust_nested_auth_pins(bd->get_cum_auth_pins());
} else {
// not me anymore. now an export.
mds->mdcache->exports.insert(bd);
inode_t *pi = le->metablob.add_dentry(cur->parent, true);
pi->mtime = mtime;
pi->atime = mtime;
+ pi->ctime = g_clock.gettime();
pi->version = pdv;
mdlog->submit_entry(le);
inode_t *pi = le->metablob.add_dentry(cur->parent, true);
pi->mode = mode;
pi->version = pdv;
+ pi->ctime = g_clock.gettime();
mdlog->submit_entry(le);
mdlog->wait_for_sync(fin);
if (uid >= 0) pi->uid = uid;
if (gid >= 0) pi->gid = gid;
pi->version = pdv;
+ pi->ctime = g_clock.gettime();
mdlog->submit_entry(le);
mdlog->wait_for_sync(fin);