Skip to content

Commit

Permalink
[AFS]: Add "directory write" support.
Browse files Browse the repository at this point in the history
Add support for the create, link, symlink, unlink, mkdir, rmdir and
rename VFS operations to the in-kernel AFS filesystem.

Also:

 (1) Fix dentry and inode revalidation.  d_revalidate should only look at
     state of the dentry.  Revalidation of the contents of an inode pointed to
     by a dentry is now separate.

 (2) Fix afs_lookup() to hash negative dentries as well as positive ones.

Signed-off-by: David Howells <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
  • Loading branch information
dhowells authored and davem330 committed Apr 26, 2007
1 parent c35eccb commit 260a980
Show file tree
Hide file tree
Showing 14 changed files with 1,778 additions and 268 deletions.
26 changes: 22 additions & 4 deletions fs/afs/afs.h
Original file line number Diff line number Diff line change
Expand Up @@ -106,18 +106,36 @@ struct afs_file_status {

afs_file_type_t type; /* file type */
unsigned nlink; /* link count */
size_t size; /* file size */
u64 size; /* file size */
afs_dataversion_t data_version; /* current data version */
unsigned author; /* author ID */
unsigned owner; /* owner ID */
u32 author; /* author ID */
u32 owner; /* owner ID */
u32 group; /* group ID */
afs_access_t caller_access; /* access rights for authenticated caller */
afs_access_t anon_access; /* access rights for unauthenticated caller */
umode_t mode; /* UNIX mode */
struct afs_fid parent; /* parent file ID */
struct afs_fid parent; /* parent dir ID for non-dirs only */
time_t mtime_client; /* last time client changed data */
time_t mtime_server; /* last time server changed data */
};

/*
* AFS file status change request
*/
struct afs_store_status {
u32 mask; /* which bits of the struct are set */
u32 mtime_client; /* last time client changed data */
u32 owner; /* owner ID */
u32 group; /* group ID */
umode_t mode; /* UNIX mode */
};

#define AFS_SET_MTIME 0x01 /* set the mtime */
#define AFS_SET_OWNER 0x02 /* set the owner ID */
#define AFS_SET_GROUP 0x04 /* set the group ID (unsupported?) */
#define AFS_SET_MODE 0x08 /* set the UNIX mode */
#define AFS_SET_SEG_SIZE 0x10 /* set the segment size (unsupported) */

/*
* AFS volume synchronisation information
*/
Expand Down
11 changes: 9 additions & 2 deletions fs/afs/afs_fs.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,19 @@
#define FS_SERVICE 1 /* AFS File Service ID */

enum AFS_FS_Operations {
FSFETCHSTATUS = 132, /* AFS Fetch file status */
FSFETCHDATA = 130, /* AFS Fetch file data */
FSFETCHSTATUS = 132, /* AFS Fetch file status */
FSREMOVEFILE = 136, /* AFS Remove a file */
FSCREATEFILE = 137, /* AFS Create a file */
FSRENAME = 138, /* AFS Rename or move a file or directory */
FSSYMLINK = 139, /* AFS Create a symbolic link */
FSLINK = 140, /* AFS Create a hard link */
FSMAKEDIR = 141, /* AFS Create a directory */
FSREMOVEDIR = 142, /* AFS Remove a directory */
FSGIVEUPCALLBACKS = 147, /* AFS Discard callback promises */
FSGETVOLUMEINFO = 148, /* AFS Get root volume information */
FSGETROOTVOLUME = 151, /* AFS Get root volume name */
FSLOOKUP = 161 /* AFS lookup file in directory */
FSLOOKUP = 161, /* AFS lookup file in directory */
};

enum AFS_FS_Errors {
Expand Down
36 changes: 32 additions & 4 deletions fs/afs/callback.c
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,8 @@ void afs_init_callback_state(struct afs_server *server)
while (!RB_EMPTY_ROOT(&server->cb_promises)) {
vnode = rb_entry(server->cb_promises.rb_node,
struct afs_vnode, cb_promise);
printk("\nUNPROMISE on %p\n", vnode);
_debug("UNPROMISE { vid=%x vn=%u uq=%u}",
vnode->fid.vid, vnode->fid.vnode, vnode->fid.unique);
rb_erase(&vnode->cb_promise, &server->cb_promises);
vnode->cb_promised = false;
}
Expand All @@ -68,7 +69,7 @@ void afs_broken_callback_work(struct work_struct *work)

/* we're only interested in dealing with a broken callback on *this*
* vnode and only if no-one else has dealt with it yet */
if (!mutex_trylock(&vnode->cb_broken_lock))
if (!mutex_trylock(&vnode->validate_lock))
return; /* someone else is dealing with it */

if (test_bit(AFS_VNODE_CB_BROKEN, &vnode->flags)) {
Expand All @@ -84,13 +85,14 @@ void afs_broken_callback_work(struct work_struct *work)
/* if the vnode's data version number changed then its contents
* are different */
if (test_and_clear_bit(AFS_VNODE_ZAP_DATA, &vnode->flags)) {
_debug("zap data");
_debug("zap data {%x:%u}",
vnode->fid.vid, vnode->fid.vnode);
invalidate_remote_inode(&vnode->vfs_inode);
}
}

out:
mutex_unlock(&vnode->cb_broken_lock);
mutex_unlock(&vnode->validate_lock);

/* avoid the potential race whereby the mutex_trylock() in this
* function happens again between the clear_bit() and the
Expand Down Expand Up @@ -251,6 +253,32 @@ static void afs_do_give_up_callback(struct afs_server *server,
_leave("");
}

/*
* discard the callback on a deleted item
*/
void afs_discard_callback_on_delete(struct afs_vnode *vnode)
{
struct afs_server *server = vnode->server;

_enter("%d", vnode->cb_promised);

if (!vnode->cb_promised) {
_leave(" [not promised]");
return;
}

ASSERT(server != NULL);

spin_lock(&server->cb_lock);
if (vnode->cb_promised) {
ASSERT(server->cb_promises.rb_node != NULL);
rb_erase(&vnode->cb_promise, &server->cb_promises);
vnode->cb_promised = false;
}
spin_unlock(&server->cb_lock);
_leave("");
}

/*
* give up the callback registered for a vnode on the file server when the
* inode is being cleared
Expand Down
Loading

0 comments on commit 260a980

Please sign in to comment.